RDT1C/CommonModules/ирОбщий/Ext/Module.bsl
Администратор bc00d53d5b Общее
*Исправлено наложение пользовательского отбора при открытии управляемых форм списков из инструментов
    Форма выбора метаданных
        *После нажатия ENTER в поле фильтра теперь снова активизируется дерево
    Загрузка табличных данных
        *Исправлены ошибки при выполнении команды "Выбрать" в контекстном меню ячейки табличного документа в конфигурациях с управляемыми формами
    Форма двоичных данных
        *Исправлена ошибка при сохранении в файл без расширения
2018-06-12 21:32:00 +03:00

25711 lines
1.7 MiB
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

////////////////////////////////////////////////////////////////////////////////
// Подсистема "Инструменты разработчика"
// Авторское право (с) 2007-2017, Старых С.А.
// Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме,
// с модификациями или без, при соблюдении следующих условий:
// - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском
// праве, этот список условий и нижеследующий отказ от гарантий.
// - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об
// авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других
// материалах, поставляемых при распространении.
//
// ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ"
// БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ,
// ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ,
// ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ
// ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО
// РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ
// ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
// НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА
// ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ
// ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
////////////////////////////////////////////////////////////////////////////////
// ОТЛАДКА
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
//
// Параметры:
// П1 Произвольный параметр1;
// П2 Произвольный параметр2;
//
// Возвращаемое значение:
// П2 Не используется.
//
Функция ПрЛкс(п1, п2 = Неопределено) Экспорт
п1 = п2;
Возврат п1;
КонецФункции // Присвоить()
// Выполняет программный код, переданный как параметр.
// Остальные Параметры могут участвовать в теле этого кода.
// Удобно использовать в отладчике.
//
// Параметры:
// П1 Произвольный параметр1;
// П2 Произвольный параметр2;
// П3 Произвольный параметр3;
// П4 Произвольный параметр4;
//
// Возвращаемое значение:
// Неопределено Не используется.
//
Функция ДуЛкс(Знач ТекстПрограммы, п1 = 0, п2 = 0, п3 = 0, п4 = 0) Экспорт
Перем Р;
Попытка
Выполнить(ТекстПрограммы);
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;
Возврат Р;
КонецФункции // Ду()
// На клиенте открывает консоль кода с передачей туда всех своих параметров. На сервере сразу выполняет код.
// Изменения параметров возвращаются в вызывающий контекст в модальном режиме.
//
// Параметры:
// ТекстПрограммы - Строка - программный код для передачи в консоль кода или выполнения;
// РежимОперации Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
// СтрокаИменПараметров Строка - имена параметров для консоли кода через запятую, если не указаны, то будут оригинальные П*;
// П* Произвольный - параметры для использования при выполнении программного кода;
//
// Возвращаемое значение:
// Строка - описание ошибок.
//
Функция ОперироватьЛкс(Знач ТекстПрограммы = "", Знач РежимОперации = 0, СтрокаИменПараметров= "",
П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
#Если Сервер И Не Клиент Тогда
РежимОперации = 2;
#КонецЕсли
МассивИмен = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаИменПараметров, ",", Истина);
Если МассивИмен.Количество() > 0 Тогда
Если МассивИмен[0] = "" Тогда
МассивИмен.Удалить(0);
КонецЕсли;
КонецЕсли;
ЧислоПараметров = 9;
ПереданныеПараметры = Новый СписокЗначений;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
ЗначениеПараметра = Вычислить(ИмяПараметра);
Если Ложь
Или ЗначениеПараметра <> Null // Опасный трюк в интерактивном режиме. Отрезает параметры, переданные, но имеющие значение Null.
Или РежимОперации = 2
Тогда
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ПереданныеПараметры.Добавить(ЗначениеПараметра, ПсевдонимПараметра);
КонецЕсли;
КонецЦикла;
Если РежимОперации < 2 Тогда
#Если Клиент Тогда
ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма", , , Новый УникальныйИдентификатор);
ФормаОтладки.мРежимРедактора = Истина;
ФормаОтладки.мСписокВнешнихПараметров = ПереданныеПараметры;
ФормаОтладки.ПараметрТекст = ТекстПрограммы;
Если РежимОперации = 0 Тогда
ФормаОтладки.Открыть();
Возврат Неопределено;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
#КонецЕсли
Иначе
ТекстПрограммы = ТекстПрограммы + ";";
Для Индекс = 0 По ПереданныеПараметры.Количество() - 1 Цикл
ВнешнийПараметр = ПереданныеПараметры[Индекс];
ТекстПрограммы = ВнешнийПараметр.Представление + "=" + "_АлгоритмОбъект[" + Индекс + "].Значение;" + Символы.ПС + ТекстПрограммы;
ТекстПрограммы = ТекстПрограммы + Символы.ПС + "_АлгоритмОбъект[" + Индекс + "].Значение = " + ВнешнийПараметр.Представление + ";";
КонецЦикла;
ВыполнитьАлгоритм(ТекстПрограммы, ПереданныеПараметры);
ПолученныеПараметры = ПереданныеПараметры;
КонецЕсли;
ОписаниеОшибок = "";
НовоеЗначение = Неопределено;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
НовоеЗначение = Неопределено;
Если ПолученныеПараметры.Количество() > Счетчик - 1 Тогда
НовоеЗначение = ПолученныеПараметры[Счетчик - 1].Значение;
КонецЕсли;
Если Вычислить(ИмяПараметра) <> НовоеЗначение Тогда
Попытка
Выполнить(ИмяПараметра + " = НовоеЗначение");
Исключение
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ОписаниеОшибки = "Ошибка возвращения параметра " + ПсевдонимПараметра + ": " + ОписаниеОшибки();
ОписаниеОшибок = ОписаниеОшибок + ОписаниеОшибки;
Сообщить(ОписаниеОшибки);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Возврат ОписаниеОшибок;
КонецФункции // РП()
// Подготавливает строку для помещения всех переменных в структуру с целью ее дальнейшего вычисления в отладчике "Вычислить(Пер())".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для анализа, берется из буфера обмена если пустой.
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция ПерЛкс(Знач ТекстПрограммы = "") Экспорт
Параметры = ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(ТекстПрограммы);
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Новый Структура(""" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Функция получает таблицу значений из указанной временной таблицы из менеджера временных таблиц,
// либо структуру из всех входящих в запрос временных таблиц.
// Используется для просмотра временных таблиц серверного менеджера временных таблиц в отладчике.
// Параметры:
// ЗапросИлиМенеджерВременныхТаблиц - Запрос, МенеджерВременныхТаблиц
// ИменаВременныхТаблиц - Строка, *"" - имена существующих, но возможно не используемых в тексте запроса временных таблиц через запятую
// ДопустимоеЧислоСтрок - Число, *500000 - выбирать из временной таблицы не более этого числа строк
//
// Результат - ТаблицаЗначений, Структура
//
Функция ПолВТЛкс(ЗапросИлиМенеджерВременныхТаблиц, Знач ИменаВременныхТаблиц = "", ДопустимоеЧислоСтрок = 500000) Экспорт
МассивИмен = ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(ЗапросИлиМенеджерВременныхТаблиц, ИменаВременныхТаблиц);
Результат = Новый Структура();
Запрос = Новый Запрос;
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц;
Иначе
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц;
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ДопустимоеЧислоСтрок) + "
| *
|ИЗ
| ИмяВременнойТаблицы
|";
Для Каждого ИмяВременнойТаблицы Из МассивИмен Цикл
Если Не ЛиИмяПеременнойЛкс(ИмяВременнойТаблицы) Тогда
Продолжить;
КонецЕсли;
Если Результат.Свойство(ИмяВременнойТаблицы) Тогда
Продолжить;
КонецЕсли;
Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяВременнойТаблицы", ИмяВременнойТаблицы);
Попытка
РезультатЗапроса = Запрос.Выполнить();
Исключение
Продолжить;
КонецПопытки;
Результат.Вставить(ИмяВременнойТаблицы, РезультатЗапроса.Выгрузить());
КонецЦикла;
Возврат Результат;
КонецФункции
// Начать трассу в технологическом журнале. Сам технологический журнал надо заранее включить.
Функция ТехНЛкс() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.НачатьТрассу("Отладчик") Тогда
Возврат "Трасса техножурнала начата";
Иначе
Возврат "Техножурнал не включен. Невозможно начать трассу.";
КонецЕсли;
КонецФункции
// Кончить трассу в технологическом журнале и показать ее анализ
Функция ТехКЛкс() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.КончитьТрассу() Тогда
//АнализТехножурнала.ПоказатьТрассу();
Возврат "Трасса техножурнала кончена. Для ее анализа откройте в режиме предприятия ""Анализ техножурнала""";
Иначе
Возврат "Трасса техножурнала не была начата ранее.";
КонецЕсли;
КонецФункции
#Если Клиент Тогда
// Подготавливает строку для вызова Оперировать() в отладчике. Вызвается путем вычисления "Вычислить(Поп())".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для передачи в консоль кода или выполнения, берется из буфера обмена если пустой;
// РежимОперации Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция ПопЛкс(Знач ТекстПрограммы = "", РежимОперации = 1) Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс();
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой");
#Если Сервер И Не Сервер Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
Пока Истина Цикл
ИнформацияОбОшибке = ПолеВстроенногоЯзыка.ПолучитьИнформациюОбОшибке(ТекстПрограммы);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
НеопределеннаяПеременная = ирКэш.Получить().ПолучитьИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке);
Если Не ЗначениеЗаполнено(НеопределеннаяПеременная) Тогда
Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Если Не Параметры.Свойство(НеопределеннаяПеременная) Тогда
Параметры.Вставить(НеопределеннаяПеременная);
ПолеВстроенногоЯзыка.ДобавитьСловоЛокальногоКонтекста(НеопределеннаяПеременная);
КонецЕсли;
КонецЦикла;
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Оперировать(" + НовыйТекст + ", " + РежимОперации + ", " + """" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Обертка Оперировать. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// П* Произвольный;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОпЛкс(П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null) Экспорт
Возврат ОперироватьЛкс(, Истина, , П1, П2, П3, П4, П5);
КонецФункции // Оп()
// Открывает консоль кода с передачей туда структуры параметров.
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка;
// Модально Булево - открывать окно модально;
// СтруктураПараметров Структура - ключи соответсвуют именам параметов, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОперироватьСтруктуройЛкс(Знач ТекстПрограммы = "", Модально = Ложь, СтруктураПараметров = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
Если Истина
И ПустаяСтрока(ТекстПрограммы)
И СтруктураПараметров <> Неопределено
И СтруктураПараметров.Количество() = 1
Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ТекстПрограммы = КлючИЗначение.Ключ;
КонецЦикла;
КонецЕсли;
ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма",,, Новый УникальныйИдентификатор);
//ФормаОтладки.мСписокВнешнихПараметров = СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураПараметров);
ПередаваемыеПараметры = Новый СписокЗначений;
Если СтруктураПараметров <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ПередаваемыеПараметры.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ);
КонецЦикла;
ФормаОтладки.мСписокВнешнихПараметров = ПередаваемыеПараметры;
КонецЕсли;
ФормаОтладки.мРежимРедактора = Истина;
ФормаОтладки.ПараметрТекст = ТекстПрограммы;
Если Не Модально Тогда
ФормаОтладки.Открыть();
Возврат ФормаОтладки;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если СтруктураПараметров <> Неопределено Тогда
//ЗаполнитьЗначенияСвойств(СтруктураПараметров, ПолученныеПараметры);
Для Каждого ПолученныйПараметр Из ПолученныеПараметры Цикл
СтруктураПараметров.Вставить(ПолученныйПараметр.Представление, ПолученныйПараметр.Значение);
КонецЦикла;
КонецЕсли;
Возврат Неопределено;
КонецФункции // РП()
// Обертка ОперироватьСтруктурой. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// СтруктураПараметров Структура - ключи соответсвуют именам параметов, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОпсЛкс(СтруктураПараметров) Экспорт
Возврат ОперироватьСтруктуройЛкс(, Истина, СтруктураПараметров);
КонецФункции // Опс()
// Выводит в окно сообщений переданное значение вместе с типом и заданным представлением.
//
// Параметры:
// Значение - Произвольный;
// *Представление Строка, *"" - представление наблюдаемого значения.
//
Процедура НаблюдатьЛкс(Значение, Представление = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Строка = Представление + " = " + "<" + ТипЗнч(Значение) + ">" + "[" + Значение + "]";
Сообщить(Строка);
КонецПроцедуры // Наблюдать()
#КонецЕсли
// Открывает нужную консоль для редактирования сложного объекта.
// Варианты использования в зависимости от типа параметра Объект:
// Запрос, COMОбъект - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
// МакетКомпоновкиДанных - открытвает запросы макета компоновки в консоли запросов
//
// Параметры:
// Объект Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, МакетКомпоновкиДанных, ОтчетОбъект, COMОбъект.ADODB.Command - исследуемый объект;
// Модально Булево - открывать окно модально, должно быть Истина для использования функции в отладчике;
// НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц - НастройкиКомпоновкиДанных, Строка, *Неопределено -
// если первый параметр СхемаКомпоновкиДанных, то настройки компоновки,
// если первый параметр WMI или ADODB.Connection, то текст запроса,
// если первый параметр Запрос, имена временных таблиц разделенных запятыми;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки - Число, *500000 - допустимое количество строк во всех временных таблицах запроса
// для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате;
// Наименование - Строка - наименование сохраняемого объекта отложенной отладки;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОтладитьЛкс(Объект, Модально = Ложь, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, ВнешниеНаборыДанных = Неопределено,
ОтложенноеВыполнение = Ложь, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000, выхОбъектДляОтладки = Неопределено, Наименование = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Модально) <> Тип("Булево") Тогда
ВызватьИсключение "Неправильный тип второго параметра (Модально) метода Отладить. Должен быть Булево";
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если Ложь
Или ТипЗнч(Объект) = Тип("Запрос")
Или ТипЗнч(Объект) = Тип("COMОбъект")
Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект, , , Модально, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьПоМакетуКомпоновки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
КонсольПостроителейОтчетов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольПостроителейОтчетов");
#Если Сервер И Не Сервер Тогда
КонсольПостроителейОтчетов = Обработки.ирКонсольПостроителейОтчетов.Создать();
#КонецЕсли
Результат = КонсольПостроителейОтчетов.ОткрытьДляОтладки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
КонсольКомпоновокДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Отчеты.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
Результат = КонсольКомпоновокДанных.ОткрытьДляОтладки(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, Модально);
ИначеЕсли Истина
И ОбъектМД <> Неопределено
И Метаданные.Отчеты.Индекс(ОбъектМД) <> -1
Тогда
КонсольКомпоновокДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирКонсольКомпоновокДанных");
#Если Сервер И Не Сервер Тогда
КонсольКомпоновокДанных = Отчеты.ирКонсольКомпоновокДанных.Создать();
Объект = КонсольКомпоновокДанных;
#КонецЕсли
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
КонецЕсли;
Результат = КонсольКомпоновокДанных.ОткрытьДляОтладки(Объект.СхемаКомпоновкиДанных, Объект.КомпоновщикНастроек.ПолучитьНастройки(), ВнешниеНаборыДанных, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
Возврат "Отладка динамического списка доступна только на сервере";
Иначе
Возврат "Не поддерживаемый тип """ + ТипЗнч(Объект) + """ первого параметра";
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, НастройкаКомпоновки, ВнешниеНаборыДанных", , Модально);
Результат = Неопределено;
Если ТипЗнч(Объект) = Тип("Запрос") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
ВременныеТаблицы = Неопределено;
Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда
ВременныеТаблицы = ПолВТЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Результат = "";
Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
Результат = Результат + КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
Если Результат <> "" Тогда
Результат = "Временные таблицы " + Результат + " были сохранены частично!";
КонецЕсли;
СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
КонецЕсли;
СтруктураЗапроса.Текст = Объект.Текст;
СтруктураЗапроса.ТипЗапроса = "Обычный";
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Объект.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("COMОбъект") Тогда
Попытка
Пустышка = Объект.CommandText;
ЭтоКомандаADO = Истина;
Исключение
ЭтоКомандаADO = Ложь;
Попытка
Пустышка = Объект.ConnectionString;
ЭтоСоединениеADO = Истина;
Исключение
ЭтоСоединениеADO = Ложь;
КонецПопытки;
КонецПопытки;
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
Если Ложь
Или ЭтоКомандаADO
Или ЭтоСоединениеADO
Тогда
Если ЭтоСоединениеADO Тогда
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц;
Иначе
СтруктураЗапроса.Текст = Объект.CommandText;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ПолучитьКопиюОбъектаЛкс(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого Parameter Из Объект.Parameters Цикл
КлючПараметра = Parameter.Name;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = "_" + КлючПараметра;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = КлючПараметра + XMLСтрока(СтруктураЗапроса.Параметры.Количество());
КонецЕсли;
Если СтруктураЗапроса.Параметры.Свойство(КлючПараметра) Тогда
ВызватьИсключение "Не удалось назначить параметру уникальное имя";
КонецЕсли;
СтруктураЗапроса.Параметры.Вставить(КлючПараметра, ЗначениеВСтрокуВнутр(Parameter.Value));
КонецЦикла;
КонецЕсли;
СтруктураЗапроса.ТипЗапроса = "ADO";
//ВременныеТаблицы = Неопределено;
//ВременныеТаблицы = ПолВТ(Объект, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
//Результат = "";
//Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
// Если Результат <> "" Тогда
// Результат = Результат + ", ";
// КонецЕсли;
// Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
// Результат = Результат + КлючИЗначение.Ключ;
// КонецЕсли;
//КонецЦикла;
//Если Результат <> "" Тогда
// Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
//КонецЕсли;
//СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
СтруктураПараметров.Объект = СтруктураЗапроса;
Иначе
СтруктураЗапроса.ТипЗапроса = "WQL";
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц;
КонецЕсли;
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры");
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос());
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(СтруктураЗапроса.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = "Отложенная отладка построителя отчета не поддерживается";
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
#Если Не Сервер Тогда
Возврат "Отладка динамического списка доступна только на сервере";
#КонецЕсли
НастройкаКомпоновки = Неопределено;
Схема = Неопределено;
ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Объект, НастройкаКомпоновки, Схема);
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект));
Если ОбъектМД <> Неопределено Тогда
Если Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда
Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда
Возврат "У отчета не установлена схема компоновки данных";
Иначе
СтруктураПараметров.Вставить("Объект", Объект.СхемаКомпоновкиДанных);
СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект.КомпоновщикНастроек.ПолучитьНастройки());
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СтруктураПараметров.Объект <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Отладить");
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Если Результат = Неопределено Тогда
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Обертка ирОбщий.ОтЛкс(). Модально (на клиенте) или отложенно (на сервере) открывает нужную консоль для редактирования/отладки объекта.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ОтЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь, Наименование = "") Экспорт
Результат = ОтладитьЛкс(Объект, Истина, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, ОтложеннаяОтладка,,, Наименование);
Возврат Результат;
КонецФункции // ОО()
// Открывает исследователь объектов.
//
// Параметры:
// Объект Произвольный, *Неопределено - объект, который будет исследован;
// Модально Булево - открывать окно модально;
// КакКоллекцию Булево, *Ложь - исследовать как коллекцию вместо объекта.
//
// Возвращаемое значение:
// Сам объект.
//
Функция ИсследоватьЛкс(Объект = Неопределено, Модально = Ложь, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
ИсследовательОбъектов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИсследовательОбъектов");
#Если Сервер И Не Сервер Тогда
ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать();
#КонецЕсли
Если КакКоллекцию Тогда
Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально);
Иначе
Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально);
КонецЕсли;
Если Результат <> Неопределено Тогда
Объект = Результат;
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию", Объект, Модально, КакКоллекцию);
Попытка
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
Если ОбъектXDTO <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Исследовать");
выхОбъектДляОтладки = Неопределено;
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки);
Иначе
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // Исследовать()
// Обертка Исследовать. Модально открывает объект в исследователе объектов
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ИсЛкс(Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Возврат ИсследоватьЛкс(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение);
КонецФункции // Ис()
// Возвращает текст из файла
Функция ФайлЛкс(Знач ИмяФайла) Экспорт
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ИмяФайла);
Результат = Текст.ПолучитьТекст();
Возврат Результат;
КонецФункции
#КонецЕсли
// ОТЛАДКА
////////////////////////////////////////////////////////////////////////////////
// Выполняет текст алгоритма.
//
// Параметры:
// ТекстДляВыполнения Строка;
// _АлгоритмОбъект - СправочникОбъект
// *СтруктураПараметров - Структура, *Неопределено.
//
Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null,
_П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт
Перем Результат;
Выполнить(_ТекстДляВыполнения);
Возврат Результат;
КонецФункции
Процедура ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт
Выполнить(_ТекстДляВыполнения);
КонецПроцедуры
Функция ВычислитьВыражение(Выражение, Параметры = Неопределено) Экспорт
Возврат Вычислить(Выражение);
КонецФункции
Функция ПолучитьПриглашениеОткрытьОтладчикЛкс() Экспорт
Возврат "Нажмите кнопку ""Подробно"", а затем ""Конфигуратор"", чтобы начать отладку!";
КонецФункции
Процедура ОткрытьОтладчикЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#Иначе
ВызватьИсключение ПолучитьПриглашениеОткрытьОтладчикЛкс();
#КонецЕсли
КонецПроцедуры
Процедура ОбработкаПолученияФормыЛкс(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка) Экспорт
#Если Сервер Тогда
Если Не Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении Тогда
Сообщить("Для использования инструмента запустите обычное приложение либо в свойствах конфигурации установите флажок ""Использовать обычные формы в управляемом приложении""
| доступный в режиме ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
#КонецЕсли
Если Не ирОбщий.СтрокиРавныЛкс(ирКэш.ТекущийСеансЛкс().ИмяПриложения, "1CV8") Тогда
ВыбраннаяФорма = "Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьОписаниеТиповОдногоТипаИзОписанияТиповЛкс(Тип, ОписаниеТипов) Экспорт
#Если Сервер И Не Сервер Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Массив = Новый Массив;
Массив.Добавить(Тип);
Результат = Новый ОписаниеТипов(Массив, ОписаниеТипов.КвалификаторыЧисла, ОписаниеТипов.КвалификаторыСтроки, ОписаниеТипов.КвалификаторыДаты, ОписаниеТипов.КвалификаторыДвоичныхДанных);
Возврат Результат;
КонецФункции
// Функция разбивает строку разделителем.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП.
// *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция ПолучитьМассивИзСтрокиСРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Знач ОбрезатьНепечатныеСимволы = Ложь, Знач ОставлятьПустуюСтроку = Истина) Экспорт
МассивСтрок = Новый Массив;
Если Истина
И Не ОставлятьПустуюСтроку
И ПустаяСтрока(Стр)
Тогда
Возврат МассивСтрок;
КонецЕсли;
//Если Найти(Стр, Символы.ПС) = 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);
Если пЛиВключатьМаркеры Тогда
Если пНачальныйМаркер <> Неопределено Тогда
Результат = пНачальныйМаркер + Результат;
КонецЕсли;
Если пКонечныйМаркер <> Неопределено Тогда
Результат = Результат + пКонечныйМаркер;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСтрокуМеждуМаркерамиЛкс()
Функция ЭтоИмяЛокальногоСервераЛкс(ИмяКомпьютера) Экспорт
Результат = Ложь
Или Не ЗначениеЗаполнено(ИмяКомпьютера)
Или ИмяКомпьютера = "."
Или СтрокиРавныЛкс(ИмяКомпьютера, "localhost")
Или ИмяКомпьютера = "127.0.0.1"
#Если Не ВебКлиент Тогда
Или СтрокиРавныЛкс(ИмяКомпьютера, ИмяКомпьютера())
#КонецЕсли
;
Возврат Результат;
КонецФункции
Функция ИмяКомпьютераКластераЛкс() Экспорт
Результат = ирОбщий.ПолучитьПервыйФрагментЛкс(НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr"), ":");
Возврат Результат;
КонецФункции
Процедура ТребоватьТипЛкс(Значение, Тип1, Тип2 = Неопределено, Тип3 = Неопределено, Тип4 = Неопределено, Тип5 = Неопределено, Тип6 = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если ТипЗначения = Тип1 Тогда
Возврат;
КонецЕсли;
Если ТипЗначения = Тип2 Тогда
Возврат;
КонецЕсли;
Если ТипЗначения = Тип3 Тогда
Возврат;
КонецЕсли;
Если ТипЗначения = Тип4 Тогда
Возврат;
КонецЕсли;
Если ТипЗначения = Тип5 Тогда
Возврат;
КонецЕсли;
Если ТипЗначения = Тип6 Тогда
Возврат;
КонецЕсли;
Массив = Новый Массив;
Массив.Добавить(Тип1);
Массив.Добавить(Тип2);
Массив.Добавить(Тип3);
Массив.Добавить(Тип4);
Массив.Добавить(Тип5);
Массив.Добавить(Тип6);
СтрокаТипов = "";
Для Каждого Тип Из Массив Цикл
Если ТипЗначения = Тип Тогда
Возврат;
КонецЕсли;
Если Тип = Неопределено Тогда
Прервать;
КонецЕсли;
Если СтрокаТипов <> "" Тогда
СтрокаТипов = СтрокаТипов + ", ";
КонецЕсли;
СтрокаТипов = СтрокаТипов + Тип;
КонецЦикла;
ВызватьИсключение "Получено значение типа """ + ТипЗначения + """ вместо ожидаемых типов: " + СтрокаТипов + ".";
КонецПроцедуры
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
Функция ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, выхВремяНачала = Неопределено, ПеременнаяСтрока = Неопределено) Экспорт
#Если Сервер И Не Клиент Тогда
Файл = Новый Файл(ИмяФайлаВнешнейОбработки);
Если Не Файл.Существует() Тогда
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
ВызватьИсключение "файл внешней обработки алгоритма не доступен на сервере. Рекомендуется в общих настройках инструментов задать сетевой каталог объектов для отладки.";
КонецЕсли;
КонецЕсли;
#КонецЕсли
// Баг 8.3.11.2700. При повторном создании с одним именем файла используются метаданные первой обработки в сеансе.
ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки, Ложь);
ОбщиеМодули = ПолучитьСтруктуруОсновныхОбщихМодулейЛкс();
выхВремяНачала = ирОбщий.ПолучитьТекущееВремяВМиллисекундахЛкс();
ВнешняяОбработка.мМетод(СтруктураПараметров, ОбщиеМодули);
//Возврат Результат;
КонецФункции
Функция ПолучитьСтруктуруОсновныхОбщихМодулейЛкс() Экспорт
ОбщиеМодули = Новый Структура;
ОбщиеМодули.Вставить("ирОбщий", ирОбщий);
ОбщиеМодули.Вставить("ирКэш", ирКэш);
ОбщиеМодули.Вставить("ирСервер", ирСервер);
Возврат ОбщиеМодули;
КонецФункции // ВыполнитьЛокально()
Процедура ОбновитьТипЗначенияВСтрокеТаблицыЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиИлиОписаниеТипов = "ОписаниеТипов",
Знач ИмяКолонкиТипаЗначения = "ТипЗначения", Знач ИмяКолонкиИмяТипаЗначения = "ИмяТипаЗначения", Знач Колонки = Неопределено) Экспорт
Если Колонки = Неопределено Тогда
Колонки = ТекущаяСтрока.Владелец().Колонки;
Иначе
ТребоватьТипЛкс(Колонки, Тип("ТаблицаЗначений"), Тип("КоллекцияКолонокТаблицыЗначений"), Тип("КоллекцияКолонокДереваЗначений"), Тип("КоллекцияКолонокРезультатаЗапроса"), , Тип("КоллекцияОбъектовМетаданных"));
#Если Сервер И Не Сервер Тогда
Колонки = Новый ТаблицаЗначений;
Колонки = Колонки.Колонки;
#КонецЕсли
КонецЕсли;
ТипЗначения = ТипЗнч(ТекущаяСтрока[ИмяКолонкиЗначения]);
Если ТипЗнч(ИмяКолонкиИлиОписаниеТипов) <> Тип("ОписаниеТипов") Тогда
КолонкаОписанияТипов = Колонки.Найти(ИмяКолонкиИлиОписаниеТипов);
Если КолонкаОписанияТипов <> Неопределено Тогда
ИмяКолонкиИлиОписаниеТипов = ТекущаяСтрока[ИмяКолонкиИлиОписаниеТипов];
Иначе
ИмяКолонкиИлиОписаниеТипов = Неопределено;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда
ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения, "Имя") <> Неопределено;
Иначе
ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения) <> Неопределено;
КонецЕсли;
Если ЕстьКолонкаТипЗначения Тогда
ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Ложь);
КонецЕсли;
Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда
ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения, "Имя") <> Неопределено;
Иначе
ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения) <> Неопределено;
КонецЕсли;
Если ЕстьКолонкаИмяТипаЗначения Тогда
ТекущаяСтрока[ИмяКолонкиИмяТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Истина);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(Знач ИмяПользователяИнфобазы = "", Знач ПарольПользователяИнфобазы = "", КодРазрешения = "", РежимКонфигуратора = Ложь,
РежимЗапуска = "ОбычноеПриложение", РазрешитьОтладку = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Ложь, ДополнительныеПараметры = "", СообщитьСтрокуПараметров = Истина,
СтрокаСоединения = "", ОткрытьПортативныеИнструменты = Ложь, РежимИнтерфейсаТакси = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь) Экспорт
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПараметрыЗапуска = "";
Если РежимКонфигуратора Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " CONFIG";
Иначе
ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
Если ЗначениеЗаполнено(ИмяПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /N""" + ИмяПользователяИнфобазы + """";
КонецЕсли;
Если ОтключитьАутентификациюОС Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /WA-";
КонецЕсли;
Если ЗначениеЗаполнено(ПарольПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /P""" + ПарольПользователяИнфобазы + """";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """";
Если РазрешитьОтладку Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС();
ПараметрыЗапускаДляОтладки = ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчикуЛкс(ИдентификаторПроцессаОС);
ПараметрыЗапуска = ПараметрыЗапуска + " " + ПараметрыЗапускаДляОтладки;
КонецЕсли;
Если ОчисткаКэшаКлиентСерверныхВызовов Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /ClearCache";
КонецЕсли;
Если РежимИнтерфейсаТакси Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /iTaxi";
КонецЕсли;
Если ЗначениеЗаполнено(РазделениеДанных) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Z""" + РазделениеДанных + """";
КонецЕсли;
Если ОткрытьПортативныеИнструменты И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
КонецЕсли;
Если ЗначениеЗаполнено(ДополнительныеПараметры) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " " + ДополнительныеПараметры;
КонецЕсли;
Если СтрокиРавныЛкс(РежимЗапуска, "Авто") Тогда
// Из-за этого иногда долго стартует почему то
ПараметрыЗапуска = ПараметрыЗапуска + " /AppAutoCheckMode"; // Автоматический выбор типа приложения для запуска
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "ОбычноеПриложение") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТолстый") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТонкий") Тогда
//ПараметрыЗапуска = ПараметрыЗапуска + "/IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
КонецЕсли;
Если СообщитьСтрокуПараметров Тогда
Сообщить(ПараметрыЗапуска);
КонецЕсли;
Возврат ПараметрыЗапуска;
КонецФункции
Функция СоздатьСсылочныйОбъектПоМетаданнымЛкс(ОбъектИлиИмяМД, ЭтоГруппаДляНового = Ложь, ИдентификаторСсылки = Неопределено) Экспорт
Если ЭтоГруппаДляНового Тогда
Менеджер = ПолучитьМенеджерЛкс(ОбъектИлиИмяМД);
Объект = Менеджер.СоздатьГруппу();
Иначе
Если ТипЗнч(ОбъектИлиИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиИмяМД);
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД, "Объект");
Объект = Новый (ИмяТипа);
КонецЕсли;
//Если ПолучитьПервыйФрагментЛкс(ПолноеИмяМД) <> "ВнешнийИсточникДанных" Тогда
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор();
КонецЕсли;
Объект = ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки);
//КонецЕсли;
Возврат Объект;
КонецФункции
Функция ИмяТипаИзПолногоИмениМДЛкс(Знач ПолноеИмяИлиОбъектМД, Знач Подтип = "Ссылка") Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) <> Тип("Строка") Тогда
ПолноеИмяИлиОбъектМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяИлиОбъектМД);
Если Фрагменты.Количество() = 3 Тогда
ИмяТипа = ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяИлиОбъектМД);
Иначе
ПервоеСлово = "";
ИменаМД = "";
Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл
ПервоеСлово = ПервоеСлово + Фрагменты[(Счетчик - 1) * 2];
ИменаМД = ИменаМД + "." + Фрагменты[(Счетчик - 1) * 2 + 1];
КонецЦикла;
ИмяТипа = ПервоеСлово + Подтип + ИменаМД;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, Знач Подтип = "Ссылка") Экспорт
ОписаниеТаблицыБД = ПолучитьОписаниеТаблицыБДИис(ИмяТаблицыБД);
Если Истина
И ОписаниеТаблицыБД <> Неопределено
И ОписаниеТаблицыБД.Тип = "Точки"
Тогда
Если Подтип = "Ссылка" Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяТаблицыБД);
Результат = "ТочкаМаршрутаБизнесПроцессаСсылка." + Фрагменты[1];
КонецЕсли;
Иначе
ПолноеИмяМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицыБД);
Если ПолноеИмяМД <> Неопределено Тогда
Результат = ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД, Подтип);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда
Возврат Объект.ЗаменитьИдентификаторОбъекта();
КонецЕсли;
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор;
КонецЕсли;
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=967697#967697
//Объект = СериализаторXDTO.ЗаписатьXDTO(Объект);
//Объект.Ref = ИдентификаторСсылки;
//Объект.IsFolder = ЭтоГруппаДляНового;
//Объект = СериализаторXDTO.ПрочитатьXDTO(Объект);
//
// Этот метод опасный, т.к. может привести к нежелательным изменениям в объекте!
ЗаписьХмл = Новый ЗаписьXML;
ЗаписьХмл.УстановитьСтроку();
ЗаписатьXML(ЗаписьХмл, Объект);
СтрокаХмл = ЗаписьХмл.Закрыть();
Попытка
ТекущийИДСсылки = XMLСтрока(Объект.Ссылка);
Исключение
// Внешний источник данных
ТекущийИДСсылки = "";
КонецПопытки;
Если ЗначениеЗаполнено(ТекущийИДСсылки) Тогда
ИмяЭлементаСсылки = "Ref";
СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаСсылки + ">" + ТекущийИДСсылки + "</" + ИмяЭлементаСсылки + ">",
"<" + ИмяЭлементаСсылки + ">" + XMLСтрока(ИдентификаторСсылки) + "</" + ИмяЭлементаСсылки + ">");
//ИмяЭлементаЭтоГруппа = "IsFolder";
//Если Найти(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">") > 0 Тогда
// СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(Объект.IsFolder) + "</" + ИмяЭлементаЭтоГруппа + ">",
// "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(ЭтоГруппаДляНового) + "</" + ИмяЭлементаЭтоГруппа + ">");
//КонецЕсли;
КонецЕсли;
ЧтениеХмл = Новый ЧтениеXML;
ЧтениеХмл.УстановитьСтроку(СтрокаХмл);
Объект = ПрочитатьXML(ЧтениеХмл);
Возврат Объект;
КонецФункции
Функция НедоступноИзменениеПоляСсылочногоОбъектаЛкс(Знач ИмяПоля) Экспорт
НедоступноИзменениеПоля = Ложь
Или Нрег(ИмяПоля) = Нрег("Ссылка")
Или Нрег(ИмяПоля) = Нрег("ВерсияДанных")
Или Нрег(ИмяПоля) = Нрег("ЭтоГруппа")
//Или Нрег(ИмяПоля) = Нрег("ЭтотУзел") // ошибочно помечен как нередактируемый в синтакс-помощнике
Или Нрег(ИмяПоля) = Нрег("Предопределенный");
Возврат НедоступноИзменениеПоля;
КонецФункции
Функция ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс() Экспорт
Результат = Истина
И (Ложь
Или Не ирКэш.ЛиПортативныйРежимЛкс()
Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
Возврат Результат;
КонецФункции
Функция СкопироватьКолонкиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоИсточник = Новый ДеревоЗначений;
#КонецЕсли
Если ДеревоПриемник = Неопределено Тогда
ДеревоПриемник = Новый ДеревоЗначений;
КонецЕсли;
Для Каждого КолонкаДерева Из ДеревоИсточник.Колонки Цикл
ДеревоПриемник.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина);
КонецЦикла;
Возврат ДеревоПриемник;
КонецФункции
// ПропускатьДвиженияВнеПланаОбмена - Булево - при РегистрироватьДвиженияВместеСДокументом = Истина позволяет управлять поведением для тех движений, которые не входят в план обмена,
// Если Истина, то такие движения пропускаются, иначе вызывается исключение
Функция ПланыОбменаИзменитьРегистрациюЛкс(УзелИлиМассив, КлючОбъекта, НовоеЗначение = Истина, ОбъектыНаСервере = Ложь, РегистрироватьДвиженияВместеСДокументом = Ложь, ДвиженияВместеСПоследовательностями = Ложь,
ПропускатьДвиженияВнеПланаОбмена = Истина, ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла = Ложь) Экспорт
Если КлючОбъекта = Неопределено Тогда
ВызватьИсключение "Изменение регистрации всех данных недопустимо";
КонецЕсли;
Если ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = КлючОбъекта;
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(КлючОбъекта));
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом Тогда
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ЭтоДокумент = ЛиКорневойТипДокументаЛкс(ПолучитьПервыйФрагментЛкс(ПолноеИмяМД));
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент И ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ " + ПолноеИмяМД + " КАК Т");
МассивОбъектов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МассивОбъектов.Количество(), "Изменение регистрации");
Иначе
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(КлючОбъекта);
КонецЕсли;
Если ТипЗнч(УзелИлиМассив) = Тип("Массив") Тогда
Если УзелИлиМассив.Количество() > 0 Тогда
ОдинУзелОбмена = УзелИлиМассив[0];
Иначе
ОдинУзелОбмена = Неопределено;
КонецЕсли;
МассивУзлов = УзелИлиМассив;
Иначе
ОдинУзелОбмена = УзелИлиМассив;
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(УзелИлиМассив);
КонецЕсли;
Если Не ЗначениеЗаполнено(ОдинУзелОбмена) Тогда
Сообщить("Не указан узел для регистрации изменений");
Возврат Ложь;
КонецЕсли;
Если ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла Тогда
УзлыДляРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов);
Если УзлыДляРегистрации.Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
Иначе
УзлыДляРегистрации = МассивУзлов;
КонецЕсли;
Успех = Истина;
НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Для Каждого Объект Из МассивОбъектов Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Объект = Объект.Методы;
КонецЕсли;
ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, Объект, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы);
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина);
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда
Если ПропускатьДвиженияВнеПланаОбмена Тогда
Продолжить;
Иначе
ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя;
КонецЕсли;
КонецЕсли;
ИмяТаблицыБДРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(МетаРегистр);
ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ИмяТаблицыБДРегистра, Новый Структура(ИмяПоляОтбора, Объект.Ссылка),, Ложь, ОбъектыНаСервере);
ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, СтруктураНабораЗаписей.Методы, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Успех;
КонецФункции
Процедура ИзменитьРегистрациюОбъектаДляУзлаЛкс(Знач УзлыДляРегистрации, Знач Объект, Знач НовоеЗначение, Знач ОдинУзелОбменаДляПроверки, Знач НомерВерсииПлатформы = "") Экспорт
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
Объект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 Тогда
Возврат Результат;
КонецЕсли;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда
Результат = Ложь;
Сообщить("Имя параметра """ + СтрокаПараметра.Имя + """ не отвечает правилам формирования имен встроенного языка",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЦикла;
НеуникальныеИмена = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя");
Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл
Сообщить("Параметр """ + НеуникальноеИмя + """ встречается более одного раза", СтатусСообщения.Внимание);
Результат = Ложь;
КонецЦикла;
Возврат Результат;
КонецФункции // ПараметрыКорректны()
// Возможно нужно объединить с ПолучитьМетаданныеЛкс
Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт
Объект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
Результат = Объект.Метаданные();
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МЕТАДАННЫМИ И ТИПАМИ
// Получает тип из описания типов, типа или значения.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Тип - найденный тип.
//
Функция ПолучитьТипОбъектаЛкс(пОбъект)
ТипОбъекта = Тип("Неопределено");
ТипПараметра = ТипЗнч(пОбъект);
Если ТипПараметра = Тип("ОписаниеТипов") Тогда
Если пОбъект.Типы().Количество() > 0 Тогда
ТипОбъекта = пОбъект.Типы()[0];
КонецЕсли;
ИначеЕсли ТипПараметра <> Тип("Тип") Тогда
ТипОбъекта = ТипПараметра;
Иначе
ТипОбъекта = пОбъект;
КонецЕсли;
Возврат ТипОбъекта;
КонецФункции // ПолучитьТипОбъектаЛкс()
// Проверяет, является ли строка именем корневого типа объекта БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина тип является корневым типом объекта БД;
// Ложь иначе.
//
Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(Знач КорневойТип) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПолучитьПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
ИЛИ КорневойТип = "Задача"
ИЛИ КорневойТип = "Документ"
ИЛИ КорневойТип = "ПланВидовРасчета"
ИЛИ КорневойТип = "ПланВидовХарактеристик"
ИЛИ КорневойТип = "ПланОбмена"
ИЛИ КорневойТип = "ПланСчетов"
ИЛИ КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКонстантыЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Константа"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПланаОбменаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "ПланОбмена"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипДокументаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Документ"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа ссылки.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина тип является корневым типом ссылки;
// Ложь иначе.
//
Функция ЛиКорневойТипСсылкиЛкс(Знач КорневойТип, ИсключаяСсылкиМетаданных = Ложь) Экспорт
Если Найти(КорневойТип, ".") > 0 Тогда
КорневойТип = ПолучитьПервыйФрагментЛкс(КорневойТип);
КонецЕсли;
Если Ложь
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Перечисление"
ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Точки" // Грязно
ИЛИ КорневойТип = "ВнешнийИсточникДанных" // Грязно
ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипСсылкиЛкс()
// Проверяет, является ли строка именем корневого типа регистра БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина тип является корневым типом регистра БД;
// Ложь иначе.
//
Функция ЛиКорневойТипРегистраБДЛкс(КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
ИЛИ КорневойТип = "РегистрНакопления"
ИЛИ КорневойТип = "РегистрБухгалтерии"
ИЛИ КорневойТип = "ДвиженияССубконто"
ИЛИ КорневойТип = "РегистрРасчета"
ИЛИ КорневойТип = "Перерасчет"
ИЛИ (Истина
И СчитатьПоследовательностьРегистром
И КорневойТип = "Последовательность")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Перечисление"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "Перечисление"
ИЛИ ТипТаблицы = "Точки"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Последовательность"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "ЖурналДокументов"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "КритерийОтбора"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МЕТАДАННЫМИ И ТИПАМИ
Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип) Экспорт
Если Ложь
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем типа вложенной таблицы БД.
//
// Параметры:
// ТипТаблицы - Строка, Неопределено - имя типа таблицы.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "ТабличнаяЧасть"
ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипВложеннойТаблицыБДЛкс()
Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "ВидыСубконто"
ИЛИ ТипТаблицы = "БазовыеВидыРасчета"
ИЛИ ТипТаблицы = "ВедущиеВидыРасчета"
ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипВложеннойТаблицыБДЛкс()
// Проверяет, корневой тип на наличие реквизита "Код".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина реквизит "Код" имеется;
// Ложь иначе.
//
Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт
Если Ложь
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланОбмена"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланРасчета"
Или КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс()
// Проверяет, корневой тип на наличие реквизита "Предопределенный".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина реквизит "Предопределенный" имеется;
// Ложь иначе.
//
Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт
Если Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланВидовРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина метаданные с иерархией;
// Ложь иначе.
//
Функция ЛиМетаданныеИерархическогоОбъектаЛкс(пМетаданныеТипа) Экспорт
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа);
Если Ложь
Или КорневойТип = "ПланСчетов"
Или (Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И пМетаданныеТипа.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина метаданные с иерархией;
// Ложь иначе.
//
Функция ЛиМетаданныеПодчиненногоОбъектаЛкс(пМетаданныеТипа) Экспорт
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа);
Если Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И пМетаданныеТипа.Владельцы.Количество() > 0
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию с группами.
// Иначе говоря проверяется начилие реквизита "ЭтоГруппа".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина метаданные с иерархией групп;
// Ложь иначе.
//
Функция ЛиМетаданныеОбъектаСГруппамиЛкс(пМетаданныеТипа) Экспорт
//ТипТаблицы = ПолучитьТипТаблицыБДЛкс(пМетаданныеТипа);
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа, Истина);
Если Ложь
Или (Истина
И КорневойТип = "Справочник"
И пМетаданныеТипа.Иерархический
И пМетаданныеТипа.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов)
Или (Истина
И КорневойТип = "ПланВидовХарактеристик"
И пМетаданныеТипа.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеОбъектаСГруппамиЛкс()
// Проверяет, является ли значение ссылкой на объект БД.
//
// Параметры:
// пЗначение ОбъектМетаданных, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина значение является ссылкой на объект БД;
// Ложь значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаОбъектБДЛкс(пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт
//Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьКорневойТипКонфигурацииЛкс(пЗначение, Истина));
Результат = ЛиТипСсылкиБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных);
Возврат Результат;
КонецФункции // ЛиСсылкаНаОбъектБДЛкс
Функция ЛиТипСсылкиБДЛкс(Тип, ИсключаяСсылкиМетаданных = Истина) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда
Если Ложь
Или Не ИсключаяСсылкиМетаданных
Или (Истина
И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0
И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0)
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипОбъектаБДЛкс(Тип) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Ложь
Или Найти(ХмлТип.ИмяТипа, "Object.") > 0
Или Найти(ХмлТип.ИмяТипа, "RecordSet.") > 0
Или Найти(ХмлТип.ИмяТипа, "ValueManager.") > 0
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Получить структуру отбора по связям И параметрам выбора
//
// Параметры:
// ЭтаФорма - <тип> -
// ПолеФормыИлиРеквизитМетаданных - <тип> -
// ДляОчистки - <тип>, Ложь -
//
// Возвращаемое значение:
//
Функция ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ЭтотОбъект, ПолеФормыИлиРеквизитМетаданных, ОбъектВладелец = Неопределено, ДляОчистки = Ложь) Экспорт
Попытка
СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора;
Исключение
Возврат Новый Структура();
КонецПопытки;
ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора;
Отбор = Новый Структура();
МаркерОтбора = НРег("Отбор.");
Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл
#Если Сервер И Не Сервер Тогда
СвязьПараметраВыбора = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Истина
И ДляОчистки
И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять
Тогда
Продолжить;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(СвязьПараметраВыбора.ПутьКДанным);
ИмяРеквизита = Фрагменты[Фрагменты.ВГраница()];
Если Фрагменты.Количество() = 1 Тогда
Если ОбъектВладелец = Неопределено Тогда
ОбъектДляРеквизита = ЭтотОбъект;
Иначе
ОбъектДляРеквизита = ОбъектВладелец;
КонецЕсли;
Иначе
ОбъектДляРеквизита = ЭтотОбъект;
КонецЕсли;
Попытка
ЗначениеДанных = Вычислить("ОбъектДляРеквизита." + ИмяРеквизита);
Исключение
// Например поле таблицы или на сервере текущая строка таблицы
Продолжить;
КонецПопытки;
Если Найти(НРег(СвязьПараметраВыбора.Имя), МаркерОтбора) <> 1 Тогда
// Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор"
Продолжить;
КонецЕсли;
Отбор.Вставить(Сред(СвязьПараметраВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ЗначениеДанных);
КонецЦикла;
Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл
#Если Сервер И Не Сервер Тогда
ПараметрВыбора = Новый ПараметрВыбора;
#КонецЕсли
Если Найти(НРег(ПараметрВыбора.Имя), МаркерОтбора) <> 1 Тогда
// Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор"
Продолжить;
КонецЕсли;
Отбор.Вставить(Сред(ПараметрВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ПараметрВыбора.Значение);
КонецЦикла;
Возврат Отбор;
КонецФункции
// Проверяет, является ли значение ссылкой на значение перечисления.
//
// Параметры:
// пЗначение Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина значение является ссылкой на объект БД;
// Ложь значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт
Возврат (ПолучитьКорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление");
КонецФункции // ЛиСсылкаНаПеречислениеЛкс()
// Проверяет, является ли ключом записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип ключа записи регистра подтвержден;
// Ложь тип ключа записи регистра не подтвержден.
//
Функция ЛиКлючЗаписиРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "ключ записи:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКлючЗаписиРегистраЛкс()
// Проверяет, является ли записью регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип записи регистра подтвержден;
// Ложь тип записи регистра не подтвержден.
//
Функция ЛиЗаписьРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "запись:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛксЛиКлючЗаписиБД()
// Проверяет, является ли набором записей регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип набора записей регистра подтвержден;
// Ложь тип набора записей регистра не подтвержден.
//
Функция ЛиНаборЗаписейРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "набор записей:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиНаборЗаписейРегистраЛкс()
// Проверяет, является ли субконтом описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип субконто подтвержден;
// Ложь тип субконто не подтвержден.
//
Функция ЛиСубконтоЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "субконто:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиСубконтоЛкс()
// Проверяет, является ли менеджером записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип менеджер записи регистра подтвержден;
// Ложь тип менеджер записи регистра не подтвержден.
//
Функция ЛиМенеджерЗаписиРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "менеджер записи:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМенеджерЗаписиРегистраЛкс()
// Проверяет, является ли значение табличной частью внешней обработки.
//
// Параметры:
// пЗначение Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина значение является табличной частью внешней обработки;
// Ложь значение не является табличной частью внешней обработки.
//
Функция ЛиТабличнаяЧастьВнешнейОбработкиЛкс(пЗначение) Экспорт
СтрокаТипЗначения = ПолучитьПервыйФрагментЛкс(Строка(пЗначение));
Возврат (СтрокаТипЗначения = "ВнешняяОбработкаТабличнаяЧасть");
КонецФункции // ЛксЛиВнешняяОбработка()
// Получает ссылочный тип по метаданным.
//
// Параметры:
// пМетаданные ОбъектМетаданных.
//
// Возвращаемое значение:
// Тип - ссылочный;
// Неопределено тип нельзя получить.
//
Функция ПолучитьСсылочныйТипПоМетаданнымЛкс(пМетаданные) Экспорт
Результат = Неопределено;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданные, Истина);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСсылочныйТипПоМетаданнымЛкс()
// Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем метаданные.
//
// Возвращаемое значение:
// Метаданные - полученные;
// Неопределено - не удалось получить метаданные.
//
Функция ПолучитьМетаданныеЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("Строка") Тогда
Если ПустаяСтрока(пОбъект) Тогда
Результат = Неопределено;
Иначе
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(пОбъект);
Если Фрагменты.Количество() = 3 Тогда
// ВидыСубконто, Изменения
ПолноеИмяМД = Фрагменты[0] + "." + Фрагменты[1];
Иначе
ПолноеИмяМД = пОбъект;
КонецЕсли;
Результат = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД);
КонецЕсли;
Возврат Результат;
КонецЕсли;
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Результат = Метаданные.НайтиПоТипу(ТипОбъекта);
Возврат Результат;
КонецФункции // ПолучитьМетаданныеЛкс()
// Получает метаданные списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
//
// Параметры:
// пОбъект Произвольное проверяемое значение.
//
// Возвращаемое значение:
// Метаданные - списка;
// Неопределено значение не является списком.
//
Функция ПолучитьМетаданныеСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
МаркерСписка = "список:";
Если Найти(Строка(ТипОбъекта), МаркерСписка) > 0 Тогда
Возврат ПолучитьМетаданныеЛкс(ТипОбъекта);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьМетаданныеСпискаЛкс()
// Определяет корневой тип конфигурации по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем метаданные;
// *пЛиТолькоДляКорневого - Булево, *Ложь - возвращать только для объекта корневого типа.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено - не удалось получить имя типа.
//
Функция ПолучитьКорневойТипКонфигурацииЛкс(пОбъект, пЛиТолькоДляКорневого = Ложь) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Результат = Неопределено;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
Если пЛиТолькоДляКорневого Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если МассивФрагментов.Количество() = 2 Тогда
Результат = МассивФрагментов[0];
КонецЕсли;
Иначе
Результат = ПолучитьПервыйФрагментЛкс(ПолноеИмя);
КонецЕсли;
//Если Результат = "ВнешнийИсточникДанных" Тогда
// Результат = Результат + "Таблица";
//КонецЕсли;
КонецЕсли;
Если Результат = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьКорневойТипКонфигурацииЛкс()
// Определяет имя корневого типа строки табличной части по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "табличная часть строка:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс()
// Определяет имя корневого типа табличной части по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего определяем корневой тип.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипТабличнойЧастиЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Истина
И МассивФрагментов.Количество() >= 4
И МассивФрагментов[2] = "ТабличнаяЧасть"
Тогда
Возврат МассивФрагментов[2];
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипТабличнойЧастиЛкс()
// Определяет имя корневого типа списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является списком.
//
Функция ПолучитьКорневойТипСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "список:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСпискаЛкс()
// Определяет имя табличной части по ее метаданным.
//
// Параметры:
// пМетаданные ОбъектМетаданных который проверяем.
//
// Возвращаемое значение:
// - Строка имя табличной части;
// Неопределено это метаданные не табличной части.
//
Функция ПолучитьИмяТабличнойЧастиЛкс(пМетаданные) Экспорт
Если пМетаданные <> Неопределено Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пМетаданные.ПолноеИмя());
Если МассивФрагментов.ВГраница() >= 2 Тогда
Если МассивФрагментов[2] = "ТабличнаяЧасть" Тогда
Возврат МассивФрагментов[3];
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьИмяТабличнойЧастиЛкс()
// Получает менеджер по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем менеджер.
//
// Возвращаемое значение:
// МенеджерОбъекта - для ссылки или ссылочного типа;
// Неопределено - не удалось получить.
//
Функция ПолучитьМенеджерЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеОбъекта = пОбъект;
Иначе
МетаданныеОбъекта = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеОбъекта = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(МетаданныеОбъекта.ПолноеИмя());
КорневойТип = МассивФрагментов[0];
Менеджер = Неопределено;
Если Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
ИмяТипаМенеджера = МассивФрагментов[0] + "ТаблицаМенеджер." + МассивФрагментов[1] + "." + МассивФрагментов[3];
Иначе
//КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеОбъекта, Истина); // Изменил 02.03.2012
Если КорневойТип <> Неопределено Тогда
ИмяТипаМенеджера = КорневойТип + "Менеджер." + МетаданныеОбъекта.Имя;
Иначе
ИмяТипаМенеджера = "Неопределено";
КонецЕсли;
КонецЕсли;
Попытка
Менеджер = Новый (ИмяТипаМенеджера);
Исключение
КонецПопытки;
Возврат Менеджер;
КонецФункции // ПолучитьМенеджерЛкс()
// Получает запись регистра по ключу записи.
//
// Параметры:
// пКлючЗаписи КлючЗаписиРегистра идентифицирующий запись.
//
// Возвращаемое значение:
// ЗаписьРегистра найденная запись.
//
Функция ПолучитьЗаписьРегистраПоКлючуЛкс(пКлючЗаписи) Экспорт
МенеджерЗначения = ПолучитьМенеджерЛкс(пКлючЗаписи);
МенеджерЗаписи = МенеджерЗначения.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, пКлючЗаписи);
МенеджерЗаписи.Прочитать();
Возврат МенеджерЗаписи;
КонецФункции // ПолучитьЗаписьРегистраПоКлючуЛкс()
// Больше не используется. Кандидат на удаление.
// Получает список реквизитов объекта БД.
//
// Параметры:
// пОбъект определитель объекта метаданных;
// *ЛиВключатьТолькоЧитаемые - Булево, *Ложь - включать ли в список только читаемые реквизиты;
// *ЛиВключатьНедоступные - Булево, *Ложь - включать ли в список недоступные (группы/элементы) реквизиты;
// *ЛиСортировать - Булево, *Ложь - отсортировать ли по представлению;
// *ЛиСКартинками - Булево, *Ложь - добавлять ли картинки;
// *ЛиСТабличнымиЧастями - Булево, *Ложь - включать ли в список табличные части.
//
// Возвращаемое значение:
// СписокЗначений содержащий в качестве значений имена реквизитов.
//
Функция ПолучитьСписокРеквизитовОбъектаБДЛкс(пОбъект, ЛиВключатьТолькоЧитаемые = Ложь,
ЛиВключатьНедоступные = Ложь, ЛиСортировать = Ложь, ЛиСКартинками = Ложь, ЛиСТабличнымиЧастями = Ложь) Экспорт
СписокРеквизитов = Новый СписокЗначений;
Если пОбъект = Неопределено Тогда
Возврат СписокРеквизитов;
КонецЕсли;
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
ОбъектМетаданных = пОбъект;
Иначе
ОбъектМетаданных = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМетаданных);
ИерархияГрупп = Ложь;
КартинкаРеквизита = Неопределено;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.СлужебныйРеквизит;
КонецЕсли;
#КонецЕсли
Если КорневойТип = "Задача" Тогда
СписокРеквизитов.Добавить("БизнесПроцесс", "Бизнес процесс", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
СписокРеквизитов.Добавить("ТочкаМаршрута", "Точка маршрута", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Выполнена", "Выполнена", , КартинкаРеквизита);
Для Каждого Рекв из ОбъектМетаданных.РеквизитыАдресации Цикл
СписокРеквизитов.Добавить(Рекв.Имя, Рекв.Представление(), , КартинкаРеквизита);
КонецЦикла;
КонецЕсли;
Если КорневойТип = "Документ" Тогда
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Проведен", "Проведен", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если КорневойТип = "Справочник" Тогда
Если ОбъектМетаданных.Владельцы.Количество() > 0 Тогда
СписокРеквизитов.Добавить("Владелец", "Владелец", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
ЭтоГруппа = Ложь;
Если ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Тогда
Если ОбъектМетаданных.ДлинаКода > 0 Тогда
СписокРеквизитов.Добавить("Код", "Код", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита);
Если ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМетаданных) Тогда
ИерархияГрупп = Истина;
Если Не ЛиВключатьНедоступные Тогда
ЭтоГруппа = пОбъект.ЭтоГруппа;
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита);
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.Реквизит;
КонецЕсли;
#КонецЕсли
Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
Если ирКэш.НомерРежимаСовместимостиЛкс() >= 802014 Тогда
Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСТабличнымиЧастями Тогда
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть;
КонецЕсли;
#КонецЕсли
Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСортировать Тогда
СписокРеквизитов.СортироватьПоПредставлению();
КонецЕсли;
Возврат СписокРеквизитов;
КонецФункции // ПолучитьСписокРеквизитовОбъектаБДЛкс()
// Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр".
//
// Параметры:
// Порядок Порядок.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаЛкс(Порядок) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из Порядок Цикл
Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " ";
Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда
Строка = Строка + "возр";
Иначе
Строка = Строка + "убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 2);
КонецФункции // ПолучитьСтрокуПорядкаЛкс()
// Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода.
// Безопасность заключается в том, что нет свойств локального контекста
// и недоступны доопределенные Свойства глобального контекста.
//
// Параметры:
// ТекстДляВыполнения Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Выполнить(ТекстДляВыполнения);
КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс()
// Получает копию произвольного объекта. Копирование производится через сериализацию.
//
// Параметры:
// пОбъект Произвольное сохраняемое значение;
//
// Возвращаемое значение:
// Произвольный - копия объекта.
//
Функция ПолучитьКопиюОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт
Если ИспользоватьXDTO Тогда
НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект));
Иначе
НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект));
КонецЕсли;
Возврат НовыйОбъект;
КонецФункции // ПолучитьКопиюОбъектаЛкс()
// Находит элемент коллекции по свойству "ПутьКДанным".
//
// Параметры:
// пКоллекция Коллекция все элементы которой имеют свойство "ПутьКДанным";
// пПутьКДанным Строка искомое значение.
//
// Возвращаемое значение:
// ЭлементКоллекции;
// Неопределено - не найден.
//
Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт
СуществующаяСтрока = Неопределено;
Для Каждого ЭлементКоллеции Из пКоллекция Цикл
Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда
СуществующаяСтрока = ЭлементКоллеции;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат СуществующаяСтрока;
КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс()
// Находит поле настройки по пути к данным.
//
// Параметры:
// пПоляНастройки ПоляНастройки;
// пПутьКДанным Строка путь к данным поля в виде разыменовывания;
// *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю.
//
// Возвращаемое значение:
// ПолеНастройки найденное поле;
// Неопределено - иначе.
//
Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт
ПоляНастройки = пПоляНастройки;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пПутьКДанным);
ТекущееПоле = Неопределено;
Для Каждого Фрагмент Из МассивФрагментов Цикл
пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент;
ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю);
Если ТекущееПоле = Неопределено Тогда
Прервать;
КонецЕсли;
ПоляНастройки = ТекущееПоле.Поля;
КонецЦикла;
Возврат ТекущееПоле;
КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс()
// Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно.
//
// Параметры:
// пЭлементОтбораПриемник ЭлементОтбора куда копируем;
// пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем.
//
Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт
ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование");
МассивСвойствЭлементаОтбора = Новый Массив;
МассивСвойствЭлементаОтбора.Добавить("ВидСравнения");
МассивСвойствЭлементаОтбора.Добавить("Значение");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеС");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо");
Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл
Значение = пЭлементОтбораИсточник[Свойство];
Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда
пЭлементОтбораПриемник[Свойство] = Значение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СкопироватьЭлементОтбораЛкс()
Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено,
Знач ПроверятьДоступностьПолей = Ложь, Знач ДоступныеПоляОтбора = Неопределено, ТолькоИспользуемые = Истина, ОчищатьПриемник = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый НастройкиКомпоновкиДанных;
ОтборКомпоновкиДанных = Пустышка.Отбор;
#КонецЕсли
Если СоответствиеИмен = Неопределено Тогда
СоответствиеИмен = Новый ТаблицаЗначений();
СоответствиеИмен.Колонки.Добавить("Источник");
//СоответствиеИмен.Колонки.Добавить("Приемник");
КонецЕсли;
Если ДоступныеПоляОтбора = Неопределено Тогда
ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора;
КонецЕсли;
Если ОчищатьПриемник Тогда
ОтборКомпоновкиДанных.Элементы.Очистить();
КонецЕсли;
ИндексГраницы = ЭлементыОтбора.Количество() - 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 Тогда
ОписаниеПолей = ОписаниеПолей + "НЕОПРЕДЕЛЕНО";
ИначеЕсли МассивТипов.Количество() = 1 Тогда
ТипПоля = МассивТипов[0];
ОписаниеПолей = ОписаниеПолей + ПолучитьКонстантуТипаЗапросаЛкс(ТипПоля, Колонка.ТипЗначения);
Иначе
ОписаниеПолей = ОписаниеПолей + "ВЫБОР";
Для Каждого ТипПоля Из МассивТипов Цикл
ОписаниеПолей = ОписаниеПолей + " КОГДА ЛОЖЬ ТОГДА " + ПолучитьКонстантуТипаЗапросаЛкс(ТипПоля, Колонка.ТипЗначения);
КонецЦикла;
ОписаниеПолей = ОписаниеПолей + " КОНЕЦ";
КонецЕсли;
ОписаниеПолей = ОписаниеПолей + " КАК " + Колонка.Имя; // запрещенные имена например "Соединение" так вызывают ошибку?
КонецЦикла;
Результат = "ВЫБРАТЬ " + Сред(ОписаниеПолей, 3);
Возврат Результат;
КонецФункции // ПолучитьЗапросИмитаторКоллекцииПолейЛкс()
// Присваивает первому параметру второй в случае их неравенства.
// Удобно использовать для избежания установки признака модифицированности
// объекта в случае присвоения реквизиту объекта его же значения.
//
// Параметры:
// Переменная Произвольный переменная, которой нужно присвоить значение;
// Значение Произвольный присваиваемое значение;
//
// Возвращаемое значение:
// Переменная Произвольный - конечное значение переменной.
//
Функция ПрисвоитьЕслиНеРавноЛкс(Переменная, Значение, Модифицированность = Неопределено) Экспорт
Если Переменная <> Значение Тогда
Переменная = Значение;
Модифицированность = Истина;
КонецЕсли;
Возврат Переменная;
КонецФункции
// Получает индекс картинки отражающей корневой тип и статус ссылки.
// Индекс потом используется с общей картинкой ЛксСостояниеСсылки.
//
// Параметры:
// пСсылка Ссылка целевая;
// *пЛиОпределятьСтатусСсылки - Булево, *Неопределено - признак необходимости определения статуса.
//
// Возвращаемое значение:
// Число индекс картинки.
//
Функция ПолучитьИндексКартинкиСсылкиЛкс(пСсылка, пЛиОпределятьСтатусСсылки = Неопределено, ЗначенияРеквизитов = Неопределено) Экспорт
Если пЛиОпределятьСтатусСсылки = Неопределено Тогда
//пЛиОпределятьСтатусСсылки = ПараметрыСеанса.ЛксОпределятьСтатусСсылкиПриВыводе;
пЛиОпределятьСтатусСсылки = Ложь;
КонецЕсли;
Если ЗначенияРеквизитов = Неопределено Тогда
ЗначенияРеквизитов = пСсылка;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пСсылка);
ИндексКартинки = -1;
Если КорневойТип = "Документ" Тогда
ИндексКартинки = 0;
Если пЛиОпределятьСтатусСсылки Тогда
Попытка
Проведен = ЗначенияРеквизитов.Проведен;
Исключение
Проведен = Ложь;
КонецПопытки;
Попытка
ПометкаУдаления = ЗначенияРеквизитов.ПометкаУдаления;
Исключение
ПометкаУдаления = Ложь;
КонецПопытки;
Если Проведен = Истина Тогда
ИндексКартинки = 0;
ИначеЕсли ПометкаУдаления = Истина Тогда
ИндексКартинки = 1;
Иначе
ИндексКартинки = 2;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 3;
Если пЛиОпределятьСтатусСсылки Тогда
Попытка
ЭтоГруппа = ЗначенияРеквизитов.ЭтоГруппа;
Исключение
ЭтоГруппа = Ложь;
КонецПопытки;
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = ?(ЭтоГруппа = Истина, 6, 4);
Иначе
ИндексКартинки = ?(ЭтоГруппа = Истина, 5, 3);
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 7;
Если пЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 8;
Иначе
ИндексКартинки = 7;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 9;
Если пЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 10;
Иначе
ИндексКартинки = 9;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "ПланОбмена" Тогда
ИндексКартинки = 15;
Если пЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 16;
Иначе
ИндексКартинки = 15;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 19;
//Если пЛиОпределятьСтатусСсылки Тогда
// Если ЗначенияРеквизитов.ПометкаУдаления Тогда
// ИндексКартинки = 20;
// Иначе
// ИндексКартинки = 19;
// КонецЕсли;
//КонецЕсли;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 17;
Если пЛиОпределятьСтатусСсылки Тогда
Если ЗначенияРеквизитов.ПометкаУдаления Тогда
ИндексКартинки = 18;
Иначе
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "Константа" Тогда
ИндексКартинки = 14;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции // ПолучитьИндексКартинкиСсылкиЛкс()
// Добавляет в таблицу значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник,
СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт
СтрокаСовпадающихКолонок = "";
Разделитель = ",";
Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда
КолонкиИсточника = ТаблицаИсточник.Колонки;
Иначе
КолонкиИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаИсточник)).Реквизиты;
КонецЕсли;
ЛиПриемникТЧ = ТипЗнч(ТаблицаПриемник) <> Тип("ТаблицаЗначений");
Если ЛиПриемникТЧ Тогда
КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки;
Иначе
КолонкиПриемника = ТаблицаПриемник.Колонки;
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для каждого Колонка Из КолонкиПриемника Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если Истина
И (Ложь
Или Не ЛиПриемникТЧ
Или Колонка.Имя <> "НомерСтроки")
И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено
Тогда
СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для каждого Колонка Из КолонкиПриемника Цикл   Если СтруктураНовыхЗначений <> Неопределено Тогда   Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда   Продолжить;   КонецЕсли;   КонецЕсли;   Если Истина   И (Ложь   Или Не ЛиПриемникТЧ   Или Колонка.Имя <> "НомерСтроки")   И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено   Тогда   СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;   КонецЕсли;   КонецЦикла;  
СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1);
Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл
СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок);
//Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл
// СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива];
//КонецЦикла;
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ЗагрузитьВТаблицуЗначенийЛкс()
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВДеревоЗначенийЛкс(ДеревоИсточник, ДеревоПриемник,
СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоИсточник = Новый ДеревоЗначений;
ДеревоПриемник = Новый ДеревоЗначений;
#КонецЕсли
СтрокаСовпадающихКолонок = "";
Разделитель = ",";
КолонкиИсточника = ДеревоИсточник.Колонки;
Для каждого Колонка Из ДеревоПриемник.Колонки Цикл
Если СтруктураНовыхЗначений <> Неопределено Тогда
Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда
СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;
КонецЕсли;
КонецЦикла;
СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1);
ЗагрузитьВСтрокиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и
// в них значения колонок с совпадающими наименованиями.
//
// Параметры:
// ТаблицаИсточник - таблица значений, откуда берутся значения;
// ТаблицаПриемник - таблица значений, куда добавляются строки;
// *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк;
// *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет.
//
Процедура ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаРодительИсточника, СтрокаРодительПриемника,
СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт
СтрокиПриемника = СтрокаРодительПриемника.Строки;
Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл
СтрокаПриемника = СтрокиПриемника.Добавить();
Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию);
КонецЕсли;
// Заполним значения в совпадающих колонках.
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок);
Если СтруктураНовыхЗначений <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений);
КонецЕсли;
ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию,
СтруктураНовыхЗначений, СтрокаСовпадающихКолонок);
КонецЦикла;
КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс()
// Выводит сообщение пользователю. Способ вывода определяется модальным режимом.
// В модальном режиме используется Предупреждение(), в немодальном Сообщить().
//
// Параметры:
// ТекстСообщения Строка;
// МодальныйРежим Булево, *Ложь;
// *Статус - СтатусСообщения, *Неопределено.
//
Процедура СообщитьСУчетомМодальностиЛкс(ТекстСообщения, МодальныйРежим = Ложь, Статус = Неопределено) Экспорт
Если Статус = Неопределено Тогда
Статус = СтатусСообщения.Обычное;
КонецЕсли;;
#Если Клиент Тогда
Если МодальныйРежим Тогда
Предупреждение(ТекстСообщения);
Иначе
#КонецЕсли
Сообщить(ТекстСообщения, Статус);
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
КонецПроцедуры // СообщитьСУчетомМодальностиЛкс()
// Сообщает итог индикации (длительность).
//
// Параметры:
// Индикатор Структура индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс.
//
Процедура СообщитьИтогИндикацииЛкс(Индикатор) Экспорт
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
//Часов = Цел(ПрошлоВремени / 3600);
//Осталось = ПрошлоВремени - (Часов * 3600);
//Минут = Цел(ПрошлоВремени / 60);
//Секунд = Цел(Цел(ПрошлоВремени - (Минут * 60)));
//ПрошлоВремениСтрока = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
// + Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":"
// + Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН=");
ПрошлоВремениСтрока = формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП=");
ТекстСообщения = Индикатор.ПредставлениеПроцесса + " завершено, обработано " + Индикатор.Счетчик + " элементов за " + ПрошлоВремениСтрока + " (" + ПрошлоВремени + " сек).";
Если Индикатор.Счетчик > 0 Тогда
ТекстСообщения = ТекстСообщения + " Грубое среднее время обработки элемента - " + Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН=") + " мс";
КонецЕсли;
Сообщить(ТекстСообщения);
КонецПроцедуры // ОбработатьИндикаторЛкс()
// Получает более подробное представление значения, чем штатное приведение к строковому типу.
//
// Параметры:
// Значение Произвольный что нужно представить.
//
// Возвращаемое значение:
// Строка представление.
//
Функция РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля = Неопределено, ДобавлятьПредставлениеТипа = Ложь, РасширенноеПредставлениеХранилищЗначений = Ложь) Экспорт
Результат = "";
Разделитель = ", ";
КоличествоЭлементов = ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение);
Если КоличествоЭлементов <> Неопределено Тогда
Результат = "(" + КоличествоЭлементов + ")";
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Граница") Тогда
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение;
ИначеЕсли ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Значение)) Тогда
Результат = "" + Значение;
Если Не ЗначениеЗаполнено(Результат) Тогда
Результат = "(" + Значение.Имя + ")";
КонецЕсли;
ИначеЕсли ТипЗнч(Значение) = Тип("ОписаниеТипов") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ОписаниеТипов;
#КонецЕсли
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Коллекция = Значение.Типы();
Для Каждого Тип Из Коллекция Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + ПредставлениеТипаЛкс(Тип, Значение);
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если Коллекция.Количество() > 1 Тогда
Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")";
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Массив")
Или ТипЗнч(Значение) = Тип("ФиксированныйМассив")
Или ТипЗнч(Значение) = Тип("СписокЗначений")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Для Каждого ЭлементМассива Из Значение Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + ЭлементМассива;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли ТипЗнч(Значение) = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
Значение = Новый ТабличныйДокумент;
#КонецЕсли
Результат = "" + ТипЗнч(Значение) + "(" + Значение.ВысотаТаблицы + ")";
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Структура")
Или ТипЗнч(Значение) = Тип("Соответствие")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Для Каждого КлючИЗначение Из Значение Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
ирПлатформа = ирКэш.Получить();
ИмяОбщегоТипа = ирПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(Значение);
ПолноеИмяОсновногоКласса = ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", "");
Результат = Результат + ИмяОбщегоТипа;
ИначеЕсли Истина
И РасширенноеПредставлениеХранилищЗначений
И ТипЗнч(Значение) = Тип("ХранилищеЗначения")
Тогда
Результат = Результат + ТипЗнч(Значение);
ВложенноеЗначение = Значение.Получить();
Результат = Результат + ": " + ВложенноеЗначение;
ИначеЕсли ТипЗнч(Значение) = Тип("Файл") Тогда
Результат = Результат + ТипЗнч(Значение);
Результат = Результат + ": " + Значение.ПолноеИмя;
//ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
// Результат = Результат + """" + Значение + """";
Иначе
СтрокаФормата = "";
Если КолонкаТабличногоПоля <> Неопределено Тогда
СтрокаФормата = КолонкаТабличногоПоля.Формат;
// Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался
//Если Истина
// И ПустаяСтрока(СтрокаФормата)
// И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода")
//Тогда
// КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла;
// СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти;
//КонецЕсли;
КонецЕсли;
Результат = Результат + Формат(Значение, СтрокаФормата);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПредставлениеСвязейПараметровВыбораЛкс(Связи) Экспорт
#Если Сервер И Не Сервер Тогда
Связи = Новый ФиксированныйМассив();
#КонецЕсли
Результат = "";
Для Каждого Связь Из Связи Цикл
#Если Сервер И Не Сервер Тогда
Связь = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Результат = Результат + Связь.ПутьКДанным;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПредставлениеТипаЛкс(Знач Тип, Знач ОписаниеТипов = Неопределено, ИспользоватьИмя = Ложь)
Если ИспользоватьИмя Тогда
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
ПредставлениеТипа = мПлатформа.ПолучитьСтрокуКонкретногоТипа(СтруктураТипа);
Иначе
ПредставлениеТипа = "" + Тип;
КонецЕсли;
Если ОписаниеТипов <> Неопределено Тогда
Если Тип = Тип("Число") Тогда
ПредставлениеТипа = ПредставлениеТипа + "(" + ОписаниеТипов.КвалификаторыЧисла.Разрядность + "," + ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")";
ИначеЕсли Тип = Тип("Строка") Тогда
ПредставлениеТипа = ПредставлениеТипа + "(" + XMLСтрока(ОписаниеТипов.КвалификаторыСтроки.Длина) + ")";
ИначеЕсли Тип = Тип("Дата") Тогда
Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеКвалификатора = "В";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеКвалификатора = "ДВ";
ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеКвалификатора = "Д";
КонецЕсли;
ПредставлениеТипа = ПредставлениеТипа + "(" + ПредставлениеКвалификатора + ")";
КонецЕсли;
КонецЕсли;
Возврат ПредставлениеТипа;
КонецФункции // ЛксПолучитьПредставлениеЗначение()
// Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств.
// Отсутствие свойства приравнивается к значению Неопределено.
//
// Параметры:
// Первый Произвольный первый объект для сравнения;
// Второй Произвольный первый объект для сравнения;
// СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения.
//
// Возвращаемое значение:
// Булево Равны ли значения всех указанных свойств.
//
Функция СравнитьЗначенияСвойствЛкс(Первый, Второй, СвойстваДляСравнения) Экспорт
Структура1 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура1, Первый);
Структура2 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура2, Второй);
Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2);
Возврат Результат;
КонецФункции // СравнитьЗначенияСвойствЛкс()
Функция КоличествоОшибокВЖурналеЛкс(Знач Начало, Знач Конец, Знач СтруктураОтбора, Знач МаксимальныйРазмерВыгрузки = Неопределено) Экспорт
АнализЖурналаРегистрации = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализЖурналаРегистрации");
#Если Сервер И Не Сервер Тогда
АнализЖурналаРегистрации = Обработки.ирАнализЖурналаРегистрации.Создать();
#КонецЕсли
СобытияЗадания = АнализЖурналаРегистрации.ПолучитьДанные(Начало, Конец, СтруктураОтбора, МаксимальныйРазмерВыгрузки);
КоличествоОшибокВЖурнале = СобытияЗадания.Количество();
Возврат КоличествоОшибокВЖурнале;
КонецФункции
#Если Клиент Тогда
Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина);
лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина);
лСтруктураПараметров.Вставить("МножественныйВыбор", Истина);
лДоступныеОбъекты = ТаблицаЗначенийИзТабличногоПоляЛкс(ТабличноеПоле);
лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД);
лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД);
Если ЭтоКолонкаПолногоИмениМД Тогда
ДоступныеОбъекты = Новый Массив;
Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл
СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ДоступныеОбъекты.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
//лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина);
//лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина);
ДоступныеОбъекты = лДоступныеОбъекты;
КонецЕсли;
ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД];
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Тогда
лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения();
Если ЭтоКолонкаПолногоИмениМД Тогда
НачальноеЗначениеВыбора = Новый Массив;
Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл
СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
НачальноеЗначениеВыбора.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора;
КонецЕсли;
Иначе
НачальноеЗначениеВыбора = ДоступныеОбъекты;
КонецЕсли;
мПлатформа = ирКэш.Получить();
Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных");
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ЗначениеВыбора <> Неопределено Тогда
Если ЭтоКолонкаПолногоИмениМД Тогда
ТаблицаВсехТаблицБД = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
МассивИменМД = Новый Массив;
Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл
СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя");
Если СтрокаОписанияТаблицы <> Неопределено Тогда
МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД);
Иначе
МассивИменМД.Добавить(СреднееИмяМД);
КонецЕсли;
КонецЦикла;
Иначе
МассивИменМД = ЗначениеВыбора;
КонецЕсли;
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(МассивИменМД);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокЗначений;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт
ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Объект");
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов");
НачатьТранзакцию();
Попытка
Для Каждого Объект Из Объекты Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КопияОбъекта = Объект.Ссылка.ПолучитьОбъект();
ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта);
Попытка
КопияОбъекта.ОбменДанными.Загрузка = Истина;
Исключение
Сообщить("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается");
Возврат;
КонецПопытки;
КопияОбъекта.Записать();
СтрокаГруппы = Дерево.Строки.Добавить();
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = КопияОбъекта.Ссылка;
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = Объект;
КонецЦикла;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ЗафиксироватьТранзакцию();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь);
ФормаОбработки.ОтключатьКонтрольЗаписи = Истина;
ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь;
КонецПроцедуры // ПередОткрытием()
// Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно.
// Иными словам колонка отображает данные, хранимые отдельно.
//
// Параметры:
// ОформлениеЯчейки ОформлениеЯчейки
// Значение - Произвольный - значение для отображения.
//
Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт
Если Значение = Неопределено Тогда
Значение = ОформлениеЯчейки.Значение;
КонецЕсли;
Если ВыводитьПиктограммуТипа Тогда
ТипЗначения = ТипЗнч(Значение);
Если Истина
И ТипЗначения = Тип("Булево")
И ОформлениеЯчейки.ОтображатьФлажок
Тогда
//
Иначе
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
РасширенноеПредставление = РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля);
Если Ложь
Или ОформлениеЯчейки.Текст = РасширенноеПредставление
Тогда
Возврат;
КонецЕсли;
//ОформлениеЯчейки.ТолькоПросмотр = Истина;
//ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление);
КонецПроцедуры // ОформитьЯчейкуСРасширеннымЗначениемЛкс()
// Находит файлы в иерархии заданного каталога локальной файловой системы.
//
// Параметры:
// Путь Строка;
// Маска Строка.
//
// Возвращаемое значение:
// Массив элементы типа Файл.
//
Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт
НайденныеКаталоги = НайтиФайлы(Путь, "*.*");
МассивРезультатов = Новый Массив;
Для каждого НайденныйФайл Из НайденныеКаталоги Цикл
Если НайденныйФайл.ЭтоКаталог() Тогда
МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска));
КонецЕсли;
КонецЦикла;
МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска));
Результат = Новый Массив;
Для Каждого ЭлементРезультат Из МассивРезультатов Цикл
Для Каждого Файл Из ЭлементРезультат Цикл
Результат.Добавить(Файл);
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции // НайтиФайлыВИерархииЛкс()
// Проверяет, является ли тип типом элемента формы.
//
// Параметры:
// пТип Тип проверяемый тип.
//
// Возвращаемое значение:
// Истина тип элемента формы подтвержден;
// Ложь тип элемента формы не подтвержден.
//
Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт
Если Ложь
ИЛИ пТип = Тип("Индикатор")
ИЛИ пТип = Тип("Кнопка")
ИЛИ пТип = Тип("КоманднаяПанель")
ИЛИ пТип = Тип("Надпись")
ИЛИ пТип = Тип("Панель")
ИЛИ пТип = Тип("Переключатель")
ИЛИ пТип = Тип("ПолеВвода")
ИЛИ пТип = Тип("ПолеВыбора")
ИЛИ пТип = Тип("ПолеСписка")
ИЛИ пТип = Тип("ПолеТекстовогоДокумента")
ИЛИ пТип = Тип("ПолеТабличногоДокумента")
ИЛИ пТип = Тип("ПолосаРегулирования")
ИЛИ пТип = Тип("ТабличноеПоле")
ИЛИ пТип = Тип("РамкаГруппы")
ИЛИ пТип = Тип("Флажок")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипЭлементаФормыЛкс()
// Получает структуру свойств объекта по имени типа или объекту.
// Свойства должны располагаться в порядке:
// - общие,
// - ролевые в порядке невлияния на предшествующие.
//
// Параметры:
// пОбъект - Произвольный - имя типа или сам объект;
// пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения.
//
// Возвращаемое значение:
// Структура свойств.
//
Функция ПолучитьСтруктуруСвойствОбъектаЛкс(пОбъект, пЛиДляСохранения = Ложь) Экспорт
СтруктураСвойств = Новый Структура;
ТипОбъекта = ТипЗнч(пОбъект);
МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта);
Если МетаОбъект <> Неопределено Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект, Истина);
Если Ложь
ИЛИ КорневойТип = "Обработка"
ИЛИ КорневойТип = "Отчет"
Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если Истина
И ТипОбъекта <> Тип("Тип")
И ТипОбъекта <> Тип("ОписаниеТипов")
И ТипОбъекта <> Тип("ОбъектМетаданных")
Тогда
Если ПолучитьКорневойТипСпискаЛкс(ТипОбъекта) <> Неопределено Тогда
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Отбор");
ИначеЕсли ЛиНаборЗаписейРегистраЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Отбор");
КонецЕсли;
КонецЕсли;
//ИначеЕсли Ложь
// ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели")
// ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля")
// ИЛИ ТипОбъекта = Тип("СтраницыПанели")
// ИЛИ ТипОбъекта = Тип("ЭлементыФормы")
// ИЛИ ТипОбъекта = Тип("ПоляНастройки")
//Тогда
// Для Каждого Элемент Из пОбъект Цикл
// СтруктураСвойств.Вставить(Элемент.Имя);
// КонецЦикла;
//
ИначеЕсли Ложь
Или ТипОбъекта = Тип("СтрокаТаблицыЗначений")
Или ТипОбъекта = Тип("СтрокаДереваЗначений")
Тогда
Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
ИначеЕсли ЛиТипЭлементаФормыЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("ПервыйВГруппе");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КонтекстноеМеню");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Лево");
СтруктураСвойств.Вставить("Верх");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Ширина");
КонецЕсли;
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("ПорядокОтображения");
СтруктураСвойств.Вставить("ПрозрачныйФон");
СтруктураСвойств.Вставить("Рамка");
Если ТипОбъекта = Тип("Кнопка") Тогда
СтруктураСвойств.Вставить("РежимМеню");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ПоложениеКартинки");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("Кнопки");
ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда
СтруктураСвойств.Вставить("АвтоЗаполнение");
СтруктураСвойств.Вставить("Вспомогательная");
СтруктураСвойств.Вставить("ВыравниваниеКнопок");
СтруктураСвойств.Вставить("ИсточникДействий");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Ориентация");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда
СтруктураСвойств.Вставить("БегущаяСтрока");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Панель") Тогда
СтруктураСвойств.Вставить("Страницы");
СтруктураСвойств.Вставить("АвтоПорядокОбхода");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ОтображениеЗакладок");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("РаспределятьПоСтраницам");
СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ТекущаяСтраница");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыбираемоеЗначение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОграничениеТипа");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("РежимВыбораИзСписка");
СтруктураСвойств.Вставить("КнопкаСпискаВыбора");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("АвтоВыборНезаполненного");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("АвтоПереносСтрок");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("БыстрыйВыбор");
СтруктураСвойств.Вставить("ВыбиратьТип");
СтруктураСвойств.Вставить("ВыборГруппИЭлементов");
СтруктураСвойств.Вставить("ВыборНезаполненного");
СтруктураСвойств.Вставить("ВыборПоВладельцу");
СтруктураСвойств.Вставить("ВыделенныйТекст");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("МаксимальноеЗначение");
СтруктураСвойств.Вставить("Маска");
СтруктураСвойств.Вставить("МинимальноеЗначение");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ОтметкаНезаполненного");
СтруктураСвойств.Вставить("РасширенноеРедактирование");
СтруктураСвойств.Вставить("РедактированиеТекста");
СтруктураСвойств.Вставить("РежимВыбораНезаполненного");
СтруктураСвойств.Вставить("РежимПароля");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("ЭлементСвязиПоТипу");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОтображатьКартинку");
СтруктураСвойств.Вставить("ОтображатьПометку");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ТекущаяСтрока");
ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда
// **** Доделать
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("АвтоВводНовойСтроки");
СтруктураСвойств.Вставить("АвтоКонтекстноеМеню");
СтруктураСвойств.Вставить("АвтоОбновление");
СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию");
СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку");
СтруктураСвойств.Вставить("Дерево");
СтруктураСвойств.Вставить("ИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьАвтоОбновление");
СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьСпособРедактирования");
СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя");
СтруктураСвойств.Вставить("ПериодАвтоОбновления");
СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки");
СтруктураСвойств.Вставить("РодительВерхнегоУровня");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимВыделения");
СтруктураСвойств.Вставить("РежимВыделенияСтроки");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СпособРедактирования");
СтруктураСвойств.Вставить("ТекущийРодитель");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("НастройкаОтбора");
СтруктураСвойств.Вставить("НастройкаПорядка");
СтруктураСвойств.Вставить("ТекущаяКолонка");
СтруктураСвойств.Вставить("ТекущаяСтрока");
СтруктураСвойств.Вставить("ТекущиеДанные");
СтруктураСвойств.Вставить("ВыделенныеСтроки");
// ****
//ВертикальнаяПолосаПрокрутки
//ВертикальныеЛинии
//Вывод
//ВысотаПодвала
//ВысотаШапки
//ГоризонтальнаяПолосаПрокрутки
//ГоризонтальныеЛинии
//ИзменятьНастройкуКолонок
//ИзменятьПозициюКолонок
//ИзменятьПорядокСтрок
//ИзменятьСоставСтрок
//НачальноеОтображениеДерева
//НачальноеОтображениеСписка
//Подвал
//ПропускатьПриВводе
//РазрешитьНачалоПеретаскивания
//РазрешитьПеретаскивание
//РежимВводаСтрок
//ФиксацияСлева
//ФиксацияСправа
//ЦветТекста
//ЦветТекстаВыделения
//ЦветТекстаКнопки
//ЦветТекстаПодвала
//ЦветТекстаШапки
//ЦветФона
//ЦветФонаВыделения
//ЦветФонаКнопки
//ЦветФонаПодвала
//ЦветФонаЧередованияСтрок
//ЦветФонаШапки
//ЧередованиеЦветовСтрок
//Шапка
//Ширина
//Шрифт
//ШрифтПодвала
//ШрифтШапки
ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ОтображатьВыделение");
СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания");
СтруктураСвойств.Вставить("РазрешитьПеретаскивание");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ЦветРамки");
ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда
СтруктураСвойств.Вставить("ТриСостояния");
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
КонецЕсли;
ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда
СтруктураСвойств.Вставить("ТипКнопки");
СтруктураСвойств.Вставить("Действие");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КнопкаПоУмолчанию");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Отображение");
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("Пометка");
СтруктураСвойств.Вставить("ПорядокКнопок");
СтруктураСвойств.Вставить("Пояснение");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Текст");
ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("Раскрыта");
ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда
СтруктураСвойств.Вставить("АвтоВысотаЯчейки");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаЯчейки");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ДанныеФлажка");
СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаПодвала");
СтруктураСвойств.Вставить("КартинкаШапки");
СтруктураСвойств.Вставить("КартинкиСтрок");
СтруктураСвойств.Вставить("ОтображатьВПодвале");
СтруктураСвойств.Вставить("ОтображатьВШапке");
СтруктураСвойств.Вставить("ОтображатьИерархию");
СтруктураСвойств.Вставить("ПодсказкаВШапке");
СтруктураСвойств.Вставить("Положение");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("РежимРедактирования");
СтруктураСвойств.Вставить("ТекстПодвала");
СтруктураСвойств.Вставить("ТекстШапки");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ТриСостоянияФлажка");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветТекстаПодвала");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветТекстаШапки");
СтруктураСвойств.Вставить("ЦветФонаПодвала");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ЦветФонаШапки");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ШрифтПодвала");
СтруктураСвойств.Вставить("ШрифтТекста");
СтруктураСвойств.Вставить("ШрифтШапки");
СтруктураСвойств.Вставить("ЭлементУправления");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьВидимость");
СтруктураСвойств.Вставить("ИзменятьНастройку");
СтруктураСвойств.Вставить("ИзменятьПозицию");
ИначеЕсли ТипОбъекта = Тип("Форма") Тогда
СтруктураСвойств.Вставить("АвтоЗаголовок");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЗакрыватьПриВыборе");
СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна");
СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("КлючУникальности");
СтруктураСвойств.Вставить("МножественныйВыбор");
СтруктураСвойств.Вставить("Модифицированность");
СтруктураСвойств.Вставить("НачальноеЗначениеВыбора");
СтруктураСвойств.Вставить("Панель");
СтруктураСвойств.Вставить("ПоведениеКлавишиEnter");
СтруктураСвойств.Вставить("ПоложениеОкна");
СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна");
СтруктураСвойств.Вставить("РазрешитьСоединятьОкно");
СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся");
СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимРабочегоСтола");
СтруктураСвойств.Вставить("СоединяемоеОкно");
СтруктураСвойств.Вставить("СостояниеОкна");
СтруктураСвойств.Вставить("СпособОтображенияОкна");
СтруктураСвойств.Вставить("Стиль");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ЭлементыФормы");
СтруктураСвойств.Вставить("ТекущийЭлемент");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("ВладелецФормы");
СтруктураСвойств.Вставить("МодальныйРежим");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПостроительОтчета")
ИЛИ пОбъект = "ПостроительОтчета"
Тогда
СтруктураСвойств.Вставить("Текст");
СтруктураСвойств.Вставить("ДоступныеПоля");
СтруктураСвойств.Вставить("ВыбранныеПоля");
СтруктураСвойств.Вставить("ИзмеренияКолонки");
СтруктураСвойств.Вставить("ИзмеренияСтроки");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Параметры");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеНастройки")
ИЛИ пОбъект = "ПолеНастройки"
Тогда
СтруктураСвойств.Вставить("Измерение");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Поле");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("СписокЗначений");
СтруктураСвойств.Вставить("ТипЗначения");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Поля");
СтруктураСвойств.Вставить("Родитель");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета")
ИЛИ пОбъект = "ИзмерениеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипИзмерения");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета")
ИЛИ пОбъект = "ПолеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ЭлементОтбора")
ИЛИ пОбъект = "ЭлементОтбора"
Тогда
СтруктураСвойств.Вставить("ВидСравнения");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ЗначениеПо");
СтруктураСвойств.Вставить("ЗначениеС");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Использование");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипЗначения");
КонецЕсли;
Возврат СтруктураСвойств;
КонецФункции // ПолучитьСтруктуруСвойствОбъектаЛкс()
// Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно.
//
// Параметры:
// *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено;
// *СтартоваяСтрока - Число, *0 - стартовое смещение строки;
// *СтартоваяКолонка - Число, *0 - стартовое смещение колонки;
// *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса;
// *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо Сообщить().
// *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено;
// *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка.
//
// Возвращаемое значение:
// Строка истинное описание ошибки.
//
Функция ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента = Неопределено,
СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено,
ИмяМодуля = Неопределено, ПредставлениеКонтекста = "") Экспорт
НомерСтроки = 0;
Если ИмяМодуля <> Неопределено Тогда
Вступление = Символы.Таб;
Иначе
Вступление = "";
КонецЕсли;
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(ОписаниеОшибки, Истина, ЛиМодально);
Если Истина
И ЯзыкПрограммы = 0
И ИмяМодуля <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ОписаниеОшибки;
КонецЕсли;
Если ЯзыкПрограммы = 2 Тогда
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Выражение = "";
Если Выражение = "" Тогда
Маркер = "Ошибка в выражении """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3);
КонецЕсли;
КонецЕсли;
Если Выражение = "" Тогда
Маркер = "Поле не найдено """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
МаркерНайден = Истина;
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1);
КонецЕсли;
КонецЕсли;
Если Выражение <> "" Тогда
ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст();
ПозицияВыражения = Найти(ТекстПоля, Выражение);
Если ПозицияВыражения > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение));
Пустышка = 0;
НомерСтроки = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ФигурноеОписаниеОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь);
Если ФигурноеОписаниеОшибки <> Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
МаксимальныйНомерСтроки = 100000;
Если ПолеТекстовогоДокумента <> Неопределено Тогда
МаксимальныйНомерСтроки = ПолеТекстовогоДокумента.КоличествоСтрок();
КонецЕсли;
ФигурноеОписаниеОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Описание, "{", "}", Ложь);
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если НомерСтроки = 0 Тогда
НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда
СтрокаКоординатыОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ФигурноеОписаниеОшибки, "(", ")", Ложь);
Если СтрокаКоординатыОшибки <> Неопределено Тогда
НомерКолонки = 0;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаКоординатыОшибки, ",");
СтрокаНомерСтроки = МассивФрагментов[0];
Попытка
НомерСтроки = Число(СтрокаНомерСтроки);
Исключение
КонецПопытки;
НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если МассивФрагментов.Количество() > 1 Тогда
СтрокаНомерКолонки = МассивФрагментов[1];
Попытка
НомерКолонки = Число(СтрокаНомерКолонки);
Исключение
КонецПопытки;
НомерКолонки = НомерКолонки + СтартоваяКолонка;
КонецЕсли;
Если НомерСтроки = 0 Тогда
НомерКолонки = 1;
НомерСтроки = 1;
КонецЕсли;
ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И НомерСтроки <= 0
Тогда
Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки;
Иначе
ОписаниеОшибки = "Ошибка без описания";
КонецЕсли;
Иначе
ОписаниеОшибки = "Строка кода " + НомерСтроки + ": " + ОписаниеОшибки;
КонецЕсли;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ТекстСообщения = "";
Если ПолеТекстовогоДокумента <> Неопределено Тогда
Если НомерСтроки > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 1000);
КонецЕсли;
ТекстСообщения = ТекстСообщения + ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста;
ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки;
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
Иначе
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ОписаниеОшибки);
Иначе
Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат ПолныйТекстСообщения;
КонецФункции
Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт
Результат = Ложь;
Если Истина
//И (Ложь
// Или Не ирКэш.ЛиПортативныйРежимЛкс()
// Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Найти(ОписаниеОшибки, "мутабельн") > 0
И Найти(ОписаниеОшибки, "Записать") > 0
Тогда
ТекстСообщения = "Чтобы избежать ошибки передачи мутабельного значения при записи объектов, используйте ";
Если ЭтоПроизвольныйАлгоритм Тогда
ТекстСообщения = ТекстСообщения + "функцию ""ирОбщий.ЗаписатьОбъектЛкс(Объект, Истина)""";
Иначе
ТекстСообщения = ТекстСообщения + "опцию ""Запись на сервере"" инструмента";
КонецЕсли;
Если ирКэш.ЛиПортативныйРежимЛкс() И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс() Тогда
ТекстСообщения = ТекстСообщения + ", которая станет доступной после указания пользователя внешнего соединения в настройках инструментов";
КонецЕсли;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
Сообщить(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции // ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс()
// Рассчитыват и устанавливает ширину колонок табличного документа. Ориентирована на обработку
// результата построителя отчета.
//
// Параметры:
// ТабличныйДокумент ТабличныйДокумент;
// *ЛиМинимальный Булево, *Ложь признак установки необходимой ширины, иначе достаточной;
// *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием;
// *ШиринаОбластиПолей - Число, *0 - ширина области полей (не показателей);
// *РассчитыватьШиринуКолонкиПоНазванию - Булево, *Истина - признак расчета ширины колонки по названию;
// *МинимальнаяШиринаКолонкиПоказатель - Число, *10 - минимальная ширина колонки показателя;
// *ПорогКоличестваЯчеекДляАнализа - Число, *100000 - пороговое количество ячеек для анализа (усечение по высоте).
//
Процедура УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(ТабличныйДокумент, ЛиМинимальный = Ложь,
ЛиИгнорироватьОбрезание = Ложь, ШиринаОбластиПолей = 0, РассчитыватьШиринуКолонкиПоНазванию = Ложь,
МинимальнаяШиринаКолонкиПоказатель = 10, ПорогКоличестваЯчеекДляАнализа = 10000) Экспорт
Перем МаксимальнаяШиринаКолонки;
Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных;
Перем ОбластьШапки, ОбластьПодвала;
Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста;
Перем КоличествоУровнейГруппировокСтрок, Отступ;
Перем ШириныКолонок;
СтрокаСостояния = "Расчет ширины колонок табличного документа ";
КоличествоОбновленийСостояния = 10;
// Ограничение максимальной ширины колонки
МаксимальнаяШиринаКолонки = 50;
// Массив, в который будут помещаться ширины колонок
ШириныКолонок = Новый Массив;
// Получим количество уровней группировок в отчете для учета автоматического отступа
КоличествоУровнейГруппировокСтрок = ТабличныйДокумент.КоличествоУровнейГруппировокСтрок();
// Инициализируем начальные строки
НачальнаяСтрока = 0;
НачалоДанных = 0;
// Найдем в результирующем документе область шапки таблицы
ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаТаблицы");
Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины
НачальнаяСтрока = ОбластьШапки.Верх;
НачалоДанных = ОбластьШапки.Низ + 1;
Иначе
// Если область шапки таблицы не найдена, найдем область шапки строк
ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаСтрок");
Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины
НачальнаяСтрока = ОбластьШапки.Верх;
НачалоДанных = ОбластьШапки.Низ + 1;
КонецЕсли;
КонецЕсли;
// Получим область подвала отчета и вычислим конечную строку расчета
ОбластьПодвала = ТабличныйДокумент.Области.Найти("Подвал");
Если ТипЗнч(ОбластьПодвала) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
// Область подвала найдена
КонечнаяСтрока = ОбластьПодвала.Верх - 1;
Иначе
// Область подвала не найдена
КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы;
КонецЕсли;
СтарыйПрогресс = 0;
КоличествоЯчеекПоказателейДляРасчета = (КонечнаяСтрока - НачальнаяСтрока) * (ТабличныйДокумент.ШиринаТаблицы - 1);
Если КоличествоЯчеекПоказателейДляРасчета > ПорогКоличестваЯчеекДляАнализа Тогда
КонечнаяСтрока = Мин(КонечнаяСтрока, ПорогКоличестваЯчеекДляАнализа / (ТабличныйДокумент.ШиринаТаблицы - 1));
КонецЕсли;
// Переберем все колонки отчета
Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
ПрогрессКолонок = ТекущаяКолонка / ТабличныйДокумент.ШиринаТаблицы / КонечнаяСтрока;
АвтоОтступ = 0;
// Переберем строки, которые будут использованы для расчета ширин колонок
Для ТекущаяСтрока = НачальнаяСтрока По КонечнаяСтрока Цикл
ОбработкаПрерыванияПользователя();
Прогресс = КоличествоОбновленийСостояния * ПрогрессКолонок * ТекущаяСтрока;
Если Прогресс - СтарыйПрогресс >= 1 Тогда
СтарыйПрогресс = Прогресс;
СостояниеЛкс(СтрокаСостояния + Цел(100 * ПрогрессКолонок * ТекущаяСтрока) + "%");
КонецЕсли;
ШиринаКолонки = 0;
// Получим область текущей ячейки
ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка);
Если ОбластьЯчейки.Лево <> ТекущаяКолонка Или ОбластьЯчейки.Верх <> ТекущаяСтрока Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
// Данная ячейка обрезает текст
Если Истина
И ЛиИгнорироватьОбрезание
И ОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Обрезать
Тогда
Продолжить;
КонецЕсли;
Если КоличествоУровнейГруппировокСтрок > 0 И ТекущаяСтрока = НачалоДанных Тогда
// Для первой строки с данными получим значение автоотступа
АвтоОтступ = ОбластьЯчейки.АвтоОтступ;
КонецЕсли;
// Получим текст ячейки
ТекстЯчейки = ОбластьЯчейки.Текст;
КоличествоСтрокВТекстеЯчейки = СтрЧислоСтрок(ТекстЯчейки);
ТекстЯчейкиТД = Новый ТекстовыйДокумент;
ТекстЯчейкиТД.УстановитьТекст(ТекстЯчейки);
// Для каждой строки из текста ячейки рассчитаем количество символов в строке
Для НомерСтрокиТекста = 1 По КоличествоСтрокВТекстеЯчейки Цикл
ШиринаТекстаЯчейки = СтрДлина(ТекстЯчейкиТД.ПолучитьСтроку(НомерСтрокиТекста));
Если Истина
И НЕ РассчитыватьШиринуКолонкиПоНазванию
И ТекущаяСтрока < НачалоДанных
И ШиринаТекстаЯчейки > 0
Тогда
ШиринаТекстаЯчейки = МинимальнаяШиринаКолонкиПоказатель;
КонецЕсли;
// Если используется автоотступ, то прибавим к ширине ячейки его величину
Если АвтоОтступ <> Неопределено И АвтоОтступ > 0 Тогда
ШиринаТекстаЯчейки = ШиринаТекстаЯчейки + КоличествоУровнейГруппировокСтрок * АвтоОтступ;
КонецЕсли;
ШиринаКолонки = Макс(ШиринаКолонки, ШиринаТекстаЯчейки);
КонецЦикла;
Если ШиринаКолонки > МаксимальнаяШиринаКолонки Тогда
// Ограничим ширину колонки
ШиринаКолонки = МаксимальнаяШиринаКолонки;
КонецЕсли;
Если ШиринаКолонки <> 0 Тогда
// Ширина колонки рассчитана
// Определим, сколько ячеек по ширине используется в области для текущей ячейки
КоличествоКолонок = ОбластьЯчейки.Право - ОбластьЯчейки.Лево;
// Переберем все ячейки, расположенные в области
Для НомерКолонки = 0 По КоличествоКолонок Цикл
Если ШириныКолонок.ВГраница() >= ТекущаяКолонка - 1 + НомерКолонки Тогда
// В массиве ширин колонок уже был элемент для текущей колонки
Если ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Неопределено Тогда
// Значение ширины колонки еще не было установлено
ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = ШиринаКолонки / (КоличествоКолонок + 1);
Иначе
// Значение ширины колонки уже было установлено
// Вычислим максимум ширины колонки
ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] =
Макс(ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки], ШиринаКолонки / (КоличествоКолонок + 1));
КонецЕсли;
Иначе
// В массиве ширин колонок еще не было элемента для данной колонки
// Добавим элемент в массив ширин колонок
ШириныКолонок.Вставить(ТекущаяКолонка - 1 + НомерКолонки, ШиринаКолонки / (КоличествоКолонок + 1));
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла; // Конец цикла перебора строк
КонецЦикла; // Конец цикла перебора колонок
// Переберем все элементы в массиве вычисленных ширин колонок
Для ТекущаяКолонка = 0 По ШириныКолонок.ВГраница() Цикл
Если ШиринаОбластиПолей >= ТекущаяКолонка Тогда
УстановитьМинимальнуюШирину = Ложь;
Иначе
УстановитьМинимальнуюШирину = ЛиМинимальный;
КонецЕсли;
Если ШириныКолонок[ТекущаяКолонка] <> Неопределено Тогда
ОбластьКолонки = ТабличныйДокумент.Область(, ТекущаяКолонка + 1, НачалоДанных, ТекущаяКолонка + 1);
// Ширина колонок установлена
// Установим ширину области ячеек
Если УстановитьМинимальнуюШирину Тогда
ОбластьКолонки.ШиринаКолонки = Макс(ШириныКолонок[ТекущаяКолонка] + 1, МинимальнаяШиринаКолонкиПоказатель);
Иначе
ОбластьКолонки.ШиринаКолонки = ШириныКолонок[ТекущаяКолонка] + 1;
КонецЕсли;
КонецЕсли;
КонецЦикла;
СостояниеЛкс("");
КонецПроцедуры // УстановитьАвтоширинуКолонокТабличногоДокументаЛкс()
// Устанавливает отбор построителя по расшифровке, содержащей NULL'ы.
// Устанавливает значение каждого NULL элемента отбора в "<Отсутствует>" и вид сравнения в "Равно".
// Для измерений, которые могут содержать значенение "NULL" в запросах в секции условий построителя следует
// писать "ЕСТЬNULL(ПутьКДаннымИзмерения, "<Отсутствует>") КАК ИмяИзмерения".
//
// Параметры:
// пПостроительОтчета ПостроительОтчета чей отбор обрабатываем;
// пРасшифровка - Структура - расшифровка.
//
Процедура УстановитьОтборПостроителяПриРасшифровкеЛкс(пПостроительОтчета, пРасшифровка) Экспорт
Для каждого ЭлементРасшифровки Из пРасшифровка Цикл
Если ЭлементРасшифровки.Значение = NULL Тогда
ЭлементОтбора = пПостроительОтчета.Отбор[ЭлементРасшифровки.Ключ];
Если ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ЭлементОтбора.Значение = "<Отсутствует>";
Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
КонецЕсли;
Иначе
Сообщить("Запрос не поддерживает расшифровку по отсутствующему значению элемента отбора """ + ЭлементОтбора.Представление + """!");
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УстановитьОтборПостроителяПриРасшифровкеЛкс()
// Получает копию построителя отчетов.
//
// Параметры:
// Оригинал ПостроительОтчета.
//
// Возвращаемое значение:
// <Тип.Вид> <описание значения>
// <продолжение описания значения>;
// <Значение2> <Тип.Вид> <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьКопиюПостроителяОтчетаЛкс(Оригинал, ВосстанавливатьНастройки = Истина) Экспорт
Копия = Новый ПостроительОтчета;
Для Каждого ДоступноеПоле Из Оригинал.ДоступныеПоля Цикл
ЗаполнитьЗначенияСвойств(Копия.ДоступныеПоля.Добавить(ДоступноеПоле.Имя, ДоступноеПоле.Представление), ДоступноеПоле);
КонецЦикла;
Если ВосстанавливатьНастройки Тогда
Копия.Текст = Оригинал.Текст;
Копия.ЗаполнитьНастройки(); // Баг платформы. Без этого почему то иногда измерения не восстанавливаются!
Копия.УстановитьНастройки(Оригинал.ПолучитьНастройки());
КонецЕсли;
Возврат Копия;
КонецФункции // ПолучитьКопиюПостроителяОтчетаЛкс()
// Возвращает менеджер временных таблиц, в котором создана временная таблица по переданному источнику.
//
// Параметры:
// ВнешнийИсточник ТаблицаЗначений;
// ИмяТаблицы Строка;
// *МенеджерВременныхТаблиц МенеджерВременныхТаблиц, *Неопределено.
//
// Возвращаемое значение:
// МенеджерВременныхТаблиц.
//
Функция ПолучитьВременнуюТаблицуЛкс(ВнешнийИсточник, ИмяТаблицы, МенеджерВременныхТаблиц = Неопределено) Экспорт
Если МенеджерВременныхТаблиц = Неопределено Тогда
МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КонецЕсли;
ТекстВЫБРАТЬ = "";
Для Каждого Колонка Из ВнешнийИсточник.Колонки Цикл
ТекстВЫБРАТЬ = ТекстВЫБРАТЬ + ", " + Колонка.Имя;
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ " + Сред(ТекстВЫБРАТЬ, 3);
ТекстЗапроса = ТекстЗапроса + " ПОМЕСТИТЬ " + ИмяТаблицы;
ТекстЗапроса = ТекстЗапроса + " ИЗ &ВнешнийИсточник КАК ВнешнийИсточник";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ВнешнийИсточник", ВнешнийИсточник);
Запрос.Выполнить();
Возврат МенеджерВременныхТаблиц;
КонецФункции // ПолучитьВременнуюТаблицуЛкс()
Функция ПолучитьТекстСостоянияИндикатораЛкс(Индикатор) Экспорт
Счетчик = Индикатор.Счетчик;
Если Истина
И Индикатор.ЛиВыводитьВремя
И Счетчик > 0
И Счетчик < Индикатор.КоличествоПроходов
Тогда
ТекущаяДата = ТекущаяДата();
ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса;
Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1);
ОсталосьДней = Цел(Осталось / (24*60*60));
ТекстОсталось = ", Осталось: ~";
Если ОсталосьДней > 0 Тогда
ТекстОсталось = ТекстОсталось + ОсталосьДней + "д";
КонецЕсли;
ТекстОсталось = ТекстОсталось + формат(Дата(1,1,1) + Осталось, "ДЛФ=T");
Иначе
ТекстОсталось = "";
КонецЕсли;
Если Индикатор.КоличествоПроходов > 0 Тогда
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": "
+ Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось;
Иначе
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
КонецЕсли;
Возврат ТекстСостояния;
КонецФункции // ПолучитьТекстСостоянияИндикатораЛкс()
// Открывает справку по первой подсистеме метаданных переданного объекта
//
// Параметры:
// Объект - любой объект, имеющий метаданные.
//
Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт
Если Ложь
Или ТипЗнч(Объект) = Тип("Неопределено")
Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения")
Тогда
//
ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда
ПолноеИмяМД = СлужебныеДанныеФормыЛкс(Объект).ИмяФормы;
ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда
ПолноеИмяМД = Объект.ИмяФормы;
Иначе
Если ТипЗнч(Объект) = Тип("Тип") Тогда
ОбъектМД = Метаданные.НайтиПоТипу(Объект);
Иначе
ОбъектМД = Объект.Метаданные();
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешняяОбработка.", "Обработка.");
ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешнийОтчет.", "Отчет.");
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("ОПодсистеме",, ПолноеИмяМД);
Форма.Открыть();
КонецПроцедуры // ОткрытьСправкуПоПодсистемеЛкс()
Процедура ПанельИнструментовОПодсистемеЛкс() Экспорт
ОткрытьСправкуПоПодсистемеЛкс();
КонецПроцедуры
// Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицой или деревом значений.
//
Процедура ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ТабличноеПоле) Экспорт
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ФормаОбработки = ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
СписокВыбора = Новый СписокЗначений;
СписокВыбора.Добавить(0, "Создать группы дублей из пар неправильных значений текущей и правильных значений следующей колонок");
СписокВыбора.Добавить(1, "Создать одну группу дублей из значений текущей колонки выделенных строк");
//СписокВыбора.Добавить(2, "Создать правила замены значений из текущей колонки на значения следующей колонки");
ВыбранныйВариант = СписокВыбора.ВыбратьЭлемент("Выберите вариант");
Если ВыбранныйВариант = Неопределено Тогда
Возврат;
КонецЕсли;
Если ВыбранныйВариант.Значение = 1 Тогда
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок,, 0);
ИначеЕсли ВыбранныйВариант.Значение = 0 Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если Ложь
Или ТекущаяКолонка = Неопределено
Или ТекущаяКолонка.Данные = ""
Тогда
Возврат;
КонецЕсли;
ИндексКолонки = ТабличноеПоле.Колонки.Индекс(ТекущаяКолонка);
Если ТабличноеПоле.Колонки.Количество() = ИндексКолонки + 1 Тогда
Возврат;
КонецЕсли;
СледующаяКолонка = ТабличноеПоле.Колонки[ИндексКолонки + 1];
Если СледующаяКолонка.Данные = "" Тогда
Возврат;
КонецЕсли;
ФормаОбработки.ОткрытьСЗаполнениемГруппДублейПоТаблицеПар(ТабличноеПоле.Значение, ТекущаяКолонка.Данные, СледующаяКолонка.Данные);
КонецЕсли;
ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя);
КонецЕсли;
КонецПроцедуры // ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс()
////////////////////////////////////////////////////////////////////////////////
// ТЕХНОЛОГИЯ КОМПОНЕНТ
// Возвращает кнопку командной панели компоненты по ее имени из макета.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КраткоеИмяКнопки Строка - имя кнопки из макета компоненты;
// *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей.
//
// Возвращаемое значение:
// Кнопка.
//
Функция ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки,
Знач КоманднаяПанель = Неопределено) Экспорт
Если КоманднаяПанель = Неопределено Тогда
КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель;
КонецЕсли;
ПолноеИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяКнопки);
Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки);
Если Кнопка = Неопределено Тогда
Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл
Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда
Продолжить;
КонецЕсли;
Кнопка = ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю);
Если Кнопка <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Кнопка;
КонецФункции // ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс()
// Формирует имя элемента управления экземпляра компоненты.
//
// Параметры:
// ИмяКласса Строка;
// ИмяЭкземпляра - Строка;
// КраткоеИмяЭлементаУправления Строка.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяЭлементаУправления) Экспорт
Возврат ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) + КраткоеИмяЭлементаУправления;
КонецФункции
Функция ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) Экспорт
Возврат ОбъектКомпоненты.ИмяКласса + "_" + ОбъектКомпоненты.Имя + "_";
КонецФункции // СформироватьИмяЭлементаУправленияЭкземпляраЛкс()
// <Описание функции>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// <Тип.Вид> <описание значения>
// <продолжение описания значения>;
// <Значение2> <Тип.Вид> <описание значения>
// <продолжение описания значения>.
//
Функция ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() Экспорт
ТаблицаСобытий = Новый ТаблицаЗначений;
ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта");
ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма");
ТаблицаСобытий.Колонки.Добавить("ИмяСобытия");
ТаблицаСобытий.Колонки.Добавить("Компонента");
ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика");
Возврат ТаблицаСобытий;
КонецФункции // ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс()
// Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника.
//
// Параметры:
// ОбъектКомпоненты - ОбработкаОбъект - компонента;
// КнопкиМакета КоллекцияКнопокКоманднойПанели источник;
// КнопкиПриемника КоллекцияКнопокКоманднойПанели приемник;
// *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено;
//
Процедура ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника,
ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено) Экспорт
КнопкиПриемника = КнопкаПриемника.Кнопки;
ИмяКласса = ОбъектКомпоненты.ИмяКласса;
Если ДействияКнопокКомпонент = Неопределено Тогда
ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие");
Иначе
ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель"));
ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей;
ДопКнопкиКоманднойПанели = Новый Массив;
ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели);
ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие")
КонецЕсли;
ИмяЭкземпляра = ОбъектКомпоненты.Имя;
Для Каждого КнопкаМакета Из КнопкиМакета Цикл
Кнопка = Неопределено;
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда
Если Истина
И Строка(КнопкаМакета.Действие) = ""
Тогда
// Это пустое действие
Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки);
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
//Попытка
Кнопка.Действие = ДействиеТранслятор;
//Исключение
// ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
// Возврат;
//КонецПопытки;
Если ДействияКнопокКомпонент <> Неопределено Тогда
СтрокаДействия = ДействияКнопокКомпонент.Добавить();
СтрокаДействия.Кнопка = Кнопка;
СтрокаДействия.Компонента = ОбъектКомпоненты;
ВызовОбработчика = "Действие_";
Если ОбщийПриемник = Неопределено Тогда
ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя;
Иначе
ВызовОбработчика = ВызовОбработчика + ОбщийПриемник;
КонецЕсли;
СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)";
КонецЕсли;
Иначе
Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие);
// Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые
Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда
Кнопка.Картинка = КнопкаМакета.Картинка;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Картинка");
КонецЕсли;
КонецЕсли;
Если Кнопка = Неопределено Тогда
Кнопка = КнопкиПриемника.Добавить();
ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя");
Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя);
Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник);
КонецЕсли;
КонецЕсли;
Если Истина
И ДействияКнопокКомпонент <> Неопределено
И ЭтоКоманднаяПанель
Тогда
ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс()
// Возвращает имя экземляра компоненты, которой принадлежит элемент управления.
//
// Параметры:
// ЭлементУправления ЭлементУправления.
//
// Возвращаемое значение:
// Строка - имя.
//
Функция ПолучитьИмяЭкземпляраЛкс(ЭлементУправления) Экспорт
Результат = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЭлементУправления.Имя, "_")[1];
Возврат Результат;
КонецФункции // ПолучитьИмяЭкземпляраЛкс()
// Устанавливает свойство у элементов именованной коллекции.
//
// Параметры:
// Коллекция Любая индексированная коллекция;
// МассивИлиСтрока Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр;
// Свойство Строка - имя Свойства которое нужно установить;
// ЗначениеСвойства Произвольный.
//
Процедура УстановитьСвойствоВКоллекцииЛкс(Коллекция, МассивИлиСтрока = Неопределено, Свойство, ЗначениеСвойства) Экспорт
ДоступенИндексСвойств = Лев(Свойство, 1) <> "-";
Если МассивИлиСтрока <> Неопределено Тогда
Если ТипЗнч(МассивИлиСтрока) = Тип("Строка") Тогда
МассивИндексов = ПолучитьМассивИзСтрокиСРазделителемЛкс(МассивИлиСтрока, ",", Истина);
Иначе
МассивИндексов = МассивИлиСтрока;
КонецЕсли;
Для Каждого ИмяЭлемента Из МассивИндексов Цикл
ЭлементКоллекции = Коллекция[ИмяЭлемента];
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если ДоступенИндексСвойств Тогда
ЭлементКоллекции[Свойство] = ЗначениеСвойства;
Иначе
Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства");
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры // УстановитьСвойствоВКоллекцииЛкс()
Процедура ПриПолученииДанныхТабличногоПоляКолонокЛкс(ОформленияСтрок, ИмяКолонкиОписанияТипов = "ТипЗначения") Экспорт
Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки[ИмяКолонкиОписанияТипов]);
Если ИндексКартинки <> Неопределено Тогда
ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ОтображатьКартинку = Истина;
ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс()
////////////////////////////////////////////////////////////////////////////////
// КОМПОНОВКА
// Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки.
//
// Параметры:
// ОформленияСтрок ОформленияСтрок.
//
Процедура ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс(ОформленияСтрок) Экспорт
Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл
ИндексКартинки = Неопределено;
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Попытка
ЭтоПапка = ДанныеСтроки.Папка;
ЭтоРесурс = ДанныеСтроки.Ресурс;
Исключение
ЭтоПапка = Ложь;
ЭтоРесурс = Ложь;
КонецПопытки;
Если ЭтоПапка Тогда
ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0;
Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл
Если Не ДоступноеПоле.Ресурс Тогда
ПапкаСРесурсами = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПапкаСРесурсами Тогда
ИндексКартинки = 17;
КонецЕсли;
КонецЕсли;
Если Не ЭтоРесурс И Не ЭтоПапка Тогда
ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки.ТипЗначения);
КонецЕсли;
Если ИндексКартинки <> Неопределено Тогда
ОформлениеСтроки.Ячейки[0].ОтображатьКартинку = Истина;
ОформлениеСтроки.Ячейки[0].ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс()
// Подключает обработчики событий для табличного поля отбора компоновки данных.
//
// Параметры:
// ТабличноеПоле ТабличноеПоле отбора компоновки.
//
Процедура ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс(ТабличноеПоле) Экспорт
ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей"));
ТабличноеПоле.Колонки[0].КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирТипыДоступныхПолейКомпоновки");
КонецПроцедуры // ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс()
// Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом.
// Содержит рекурсивный вызов.
//
// Параметры:
// НаборыДанных НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных;
// *СтруктураНаборовДанных Структура, *Неопрелено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных"))
//
// Возвращаемое значение:
// Структура.
//
Функция ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт
Если СтруктураНаборовДанных = Неопределено Тогда
СтруктураНаборовДанных = Новый Структура;
КонецЕсли;
Для каждого НаборДанных Из НаборыДанных Цикл
Если Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда
// Платформа генерит такие наборы для служебных целей
ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
Иначе
ИмяНабора = НаборДанных.Имя;
КонецЕсли;
СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных));
ИначеЕсли Ложь
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных")
Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных")
Тогда
ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(НаборДанных.Элементы, СтруктураНаборовДанных);
КонецЕсли;
КонецЦикла;
Возврат СтруктураНаборовДанных;
КонецФункции // ПолучитьСтруктуруНаборовДанныхЗапросовЛкс()
// Получает макет компоновки данных по схеме с использованием временных таблиц.
//
// Параметры:
// Схема СхемаКомпоновкиДанных;
// Настройки - НастройкиКомпоновкиДанных;
// *ВнешниеНаборыДанных Структура, *Неопределено - туда добавляются временные таблицы;
// *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено;
// *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов.
//
// Возвращаемое значение:
// МакетКомпоновкиДанных.
//
Функция ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс(Схема, Настройки, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено, ПроверятьДоступностьПолей = Ложь) Экспорт
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.IgnoreCase = Истина;
// Допустим 1 уровень скобок.
шСкобки = "\([^\)\(]*?\)";
RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(.*?)""\)";
Если ВнешниеНаборыДанных = Неопределено Тогда
ВнешниеНаборыДанных = Новый Структура;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
// Выполним создание всех временных таблиц. Временной таблицей считаем набор данных запрос,
// имя которого начинается с "@". Наборы данных временных таблиц удаляются из предварительной схемы.
ПредварительнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема));
НаборыДанныхСхемы = ПредварительнаяСхема.НаборыДанных;
ЕстьВременныеТаблицы = Ложь;
НачальноеКоличество = НаборыДанныхСхемы.Количество();
Для СчетчикНаборыДанныхСхемы = 1 По НачальноеКоличество Цикл
НаборДанных = НаборыДанныхСхемы[НачальноеКоличество - СчетчикНаборыДанныхСхемы];
Если Истина
И Лев(НаборДанных.Имя, 1) = "@"
И ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")
Тогда
ВременнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема));
// Кривое копирование набора данных в новую схемы, где он будет один.
ВременнаяСхема.СвязиНаборовДанных.Очистить();
НаборыДанныхВременнойСхемы = ВременнаяСхема.НаборыДанных;
НаборыДанныхВременнойСхемыВГраница = НаборыДанныхВременнойСхемы.Количество() - 1;
Для СчетчикВременнойСхемы = 0 По НаборыДанныхВременнойСхемыВГраница Цикл
НаборДанныхВременнойСхемы = НаборыДанныхВременнойСхемы[НаборыДанныхВременнойСхемыВГраница - СчетчикВременнойСхемы];
Если НаборДанныхВременнойСхемы.Имя <> НаборДанных.Имя Тогда
НаборыДанныхВременнойСхемы.Удалить(НаборДанныхВременнойСхемы);
КонецЕсли;
КонецЦикла;
Для Каждого ПолеНабора Из НаборыДанныхВременнойСхемы[0].Поля Цикл
ПолеНабора.ОграничениеИспользования.Поле = Ложь;
ПолеНабора.ВыражениеПредставления = ПолеНабора.ПутьКДанным;
КонецЦикла;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ВременнаяСхема));
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КомпоновщикНастроек.Настройки.Структура.Очистить();
КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить();
КомпоновщикНастроек.Восстановить();
ВременныеНастройки = КомпоновщикНастроек.Настройки;
// Установим использование параметров
Для Каждого ЭлементПараметра Из ВременныеНастройки.ПараметрыДанных.Элементы Цикл
ЭлементПараметра.Использование = Истина;
КонецЦикла;
// Установим структуру и выбранные поля
ЭлементСтруктуры = ВременныеНастройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Для Каждого ДоступноеПоле Из ВременныеНастройки.ДоступныеПоляВыбора.Элементы Цикл
// Чтобы пропустить системные папки
Если Не ДоступноеПоле.Папка Тогда
НовоеВыбранноеПоле = ВременныеНастройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле;
НовоеВыбранноеПоле.Использование = Истина;
КонецЕсли;
КонецЦикла;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ВременнаяСхема, ВременныеНастройки,,,, ПроверятьДоступностьПолей);
Запрос.Текст = МакетКомпоновкиДанных.НаборыДанных[0].Запрос;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1");
ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
//// Недоступные поля набора данных цепляются в настройках при совпадаении имен с выбранными полями
//// http://partners.v8.1c.ru/forum/thread.jsp?id=514094
//Для Каждого Поле Из НаборДанных.Поля Цикл
// Поле.ПутьКДанным = "_поле_" + Поле.ПутьКДанным;
//КонецЦикла;
НаборыДанныхСхемы.Удалить(НаборДанных);
ЕстьВременныеТаблицы = Истина;
КонецЕсли;
КонецЦикла;
Если Не ЕстьВременныеТаблицы Тогда
Если ЛиОтладка Тогда
ВремяНачалаКомпоновкиМакета = ПолучитьТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, Настройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей);
Если ЛиОтладка Тогда
Сообщить("Компоновка макета - "
+ Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс");
КонецЕсли;
Иначе
// Выполним получение результата предварительного запроса
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПредварительнаяСхема));
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КомпоновщикНастроек.Восстановить();
ПредварительныеНастройки = КомпоновщикНастроек.Настройки;
Если ЛиОтладка Тогда
ВремяНачалаКомпоновкиМакета = ПолучитьТекущееВремяВМиллисекундахЛкс();
КонецЕсли;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, ПредварительныеНастройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей);
Если ЛиОтладка Тогда
Сообщить("Компоновка макета - "
+ Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс");
КонецЕсли;
Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл
Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение);
КонецЦикла;
СтруктураНаборовДанныхЗапросовМакета = ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(МакетКомпоновкиДанных.НаборыДанных);
Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл
НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных;
Запрос.Текст = НаборДанных.Запрос;
Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1");
РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса);
КонецЦикла;
// Получение конечного макета
Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл
КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец;
НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных;
НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных"));
// Копируем Свойства набора данных запроса в набор данных объекта
ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос);
НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя;
Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл
ПолеРезультата = НаборДанныхОбъект.Поля.Добавить();
ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала);
ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль);
КонецЦикла;
КоллекцияВладелец.Удалить(НаборДанныхЗапрос);
КонецЦикла;
КонецЕсли;
// Баг платформы. Пустая дата превращается в Неопределено.
Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл
Если ПараметрСхемы.ОграничениеИспользования Тогда
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя);
ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат МакетКомпоновкиДанных;
КонецФункции // ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс()
// Выводит результат СКД с установкой вертикальной автофиксации.
// Параметры:
// Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет;
// ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных;
// ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных;
// МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей;
// РазрешитьПрерывание - Булево, *Истина.
//
Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки,
Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Таб);
ПроцессорВывода.НачатьВывод();
ФиксацияВыполнена = Ложь;
Если МассивИгнорируемыхПолей = Неопределено Тогда
МассивИгнорируемыхПолей = Новый Массив;
КонецЕсли;
Пока Истина Цикл
Если РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
Прервать;
КонецЕсли;
// Автофиксация
Если Истина
И Автофиксация
И Не ФиксацияВыполнена
Тогда
Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл
Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();
Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл
Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда
Таб.ФиксацияСверху = Таб.ВысотаТаблицы;
ФиксацияВыполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФиксацияВыполнена Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);
Если Истина
И выхЭлементыРезультата <> Неопределено
И выхЭлементыРезультата.Количество() < 10000
Тогда
выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();   Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда   Прервать;   КонецЕсли;     Если Истина   И Автофиксация   И Не ФиксацияВыполнена   Тогда   Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл   Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда   ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();   Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл   Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда   Таб.ФиксацияСверху = Таб.ВысотаТаблицы;   ФиксацияВыполнена = Истина;   Прервать;   КонецЕсли;   КонецЦикла;   Если ФиксацияВыполнена Тогда   Прервать;   КонецЕсли;   КонецЕсли;   КонецЦикла;   КонецЕсли;   ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);   Если Истина   И выхЭлементыРезультата <> Неопределено   И выхЭлементыРезультата.Количество() < 10000   Тогда   выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);   КонецЕсли;  
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры // ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс
#КонецЕсли
// Переустанавливает значения недоступных параметров из схемы (антибаг платформы).
//
// Параметры:
// СхемаКомпоновкиДанных СхемаКомпоновкиДанных;
// КомпоновщикНастроек КомпоновщикНастроекКомпоновкиДанных.
//
Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр);
Если Истина
И ПараметрСхемы <> Неопределено
И ПараметрСхемы.ОграничениеИспользования
Тогда
//Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда
// Попытка
// ЗначениеПараметра.Значение = Вычислить();
// Исключение
// КонецПопытки;
//Иначе
ЗначениеПараметра.Значение = ПараметрСхемы.Значение;
//КонецЕсли;
//ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс()
Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт
ПолеКоличества = "КоличествоСтрокАвто";
ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
ВычисляемоеПоле.Выражение = "1";
ВычисляемоеПоле.Заголовок = "Количество строк (авто)";
ВычисляемоеПоле.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей.Выражение = "Сумма(1)";
КонецПроцедуры
// Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений.
//
// Параметры:
// СтруктураТаблиц Структура <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь,
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл
КолонкиНабора = КолонкиИсточникаДанныхЛкс(КлючИЗначение.Значение);
СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КолонкиНабора, КлючИЗначение.Ключ, СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей);
КонецЦикла;
Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Возврат СхемаКомпоновкиДанных;
КонецФункции
Функция КолонкиИсточникаДанныхЛкс(Знач ИсточникДанных)
Если Ложь
Или ТипЗнч(ИсточникДанных) = Тип("ДеревоЗначений")
Или ТипЗнч(ИсточникДанных) = Тип("ТаблицаЗначений")
Тогда
КолонкиНабора = ИсточникДанных.Колонки;
Иначе
КолонкиНабора = ИсточникДанных.ВыгрузитьКолонки().Колонки;
КонецЕсли;
Возврат КолонкиНабора;
КонецФункции // СоздатьСхемуПоТаблицамЗначенийЛкс()
// Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки.
//
// Параметры:
// ПоляНастройки ПоляНастройки <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "НаборДанных1") Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабора;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
НаборДанных.ИмяОбъекта = ИмяНабора;
Для Каждого ПолеНастройки Из ПоляНастройки Цикл
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.ПутьКДанным = ПолеНастройки.Имя;
Поле.Поле = ПолеНастройки.ПутьКДанным;
Поле.Заголовок = ПолеНастройки.Представление;
Поле.ТипЗначения = ПолеНастройки.ТипЗначения;
ОграничениеИспользования = Поле.ОграничениеИспользования;
ОграничениеИспользования.Поле = Не ПолеНастройки.Поле;
ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор;
ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок;
ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение;
ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0;
ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов;
ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения;
КонецЦикла;
Возврат СхемаКомпоновкиДанных;
КонецФункции // СоздатьСхемуПоПолямНастройкиЛкс()
// Параметры:
// Поле -
// Доступность -
// ПрименитьГруппировка -
// ПрименитьПоле -
// ПрименитьПорядок -
// ПрименитьУсловие -
// Возвращаемое значение:
//
Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач Поле, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина,
Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт
МассивГруппОграничений = Новый Массив;
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования);
Попытка
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов);
Исключение
КонецПопытки;
Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл
Если ПрименитьГруппировка Тогда
ОграничениеИспользования.Группировка = Ограничивать;
КонецЕсли;
Если ПрименитьПоле Тогда
ОграничениеИспользования.Поле = Ограничивать;
КонецЕсли;
Если ПрименитьПорядок Тогда
ОграничениеИспользования.Порядок = Ограничивать;
КонецЕсли;
Если ПрименитьУсловие Тогда
ОграничениеИспользования.Условие = Ограничивать;
КонецЕсли;
КонецЦикла;
КонецФункции
// Функция добавляет в схему компоновки источник данных с типом "Local"
Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";
Возврат ИсточникДанных;
КонецФункции
// Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных
Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "НаборДанных1") Экспорт
НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабораДанных;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
Возврат НаборДанных;
КонецФункции
// Устаревшее! Новая - ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.ПолучитьВыражениеПорядкаКомпоновкиНаЯзыке
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки ПорядокКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаКомпоновкиЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + "Возр";
Иначе
Строка = Строка + "Убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс()
// Конструктор массива через Параметры.
//
// Параметры:
// *п... Произвольный элементы массива.
//
// Возвращаемое значение:
// Массив - полученный массив.
//
Функция БыстрыйМассивЛкс(
п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено,
п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено,
п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено,
п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено
) Экспорт
Перем М;
М = Новый Массив();
Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли;
Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли;
Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли;
Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли;
Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли;
Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли;
Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли;
Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли;
Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли;
Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли;
Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли;
Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли;
Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли;
Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли;
Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли;
Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли;
Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли;
Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли;
Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли;
Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли;
Возврат М;
КонецФункции // БыстрыйМассивЛкс()
////////////////////////////////////////////////////////////////////////////////
// РАБОТА СО СТРОКАМИ
// <Описание функции>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// Строка - путь к файлу.
//
Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Ложь
Или ТипЗнч(Значение) = Тип("ТабличныйДокумент")
Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент")
Тогда
Документ = Значение;
Иначе
Документ = Новый ТекстовыйДокумент;
Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда
Значение = Значение.Получить();
КонецЕсли;
Если ТипЗнч(Значение) <> Тип("Строка") И ПолучатьXMLПредставлениеДляНеизвестныхТипов Тогда
Представление = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение);
Иначе
Представление = Значение;
КонецЕсли;
Документ.УстановитьТекст(ДекодироватьТекстИзXMLЛкс(Представление));
КонецЕсли;
Путь = ПолучитьИмяВременногоФайла(Название);
Документ.Записать(Путь);
Возврат Путь;
КонецФункции // ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс()
// Получает строку путем отсечения заданного числа последних символов.
//
// Параметры:
// пСтрока Строка исходная;
// пДлинаКонца - Число, *1 - количество отсекаемых символов;
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьСтрокуБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт
Если СтрДлина(пСтрока) < пДлинаКонца Тогда
Возврат "";
Иначе
Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца);
КонецЕсли;
КонецФункции // ПолучитьСтрокуБезКонцаЛкс()
// Функция собирает строку из элементов массива с разделителем.
//
// Параметры:
// пМассив - Массив - из которого формируем строку;
// *пРазделитель - Строка - символ-разделитель.
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьСтрокуСРазделителемИзМассиваЛкс(пМассив, пРазделитель = ", ") Экспорт
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
Пустая = Истина;
Для Каждого Элемент Из пМассив Цикл
Если Не Пустая Тогда
ЗаписьXML.ЗаписатьБезОбработки(пРазделитель);
Иначе
Пустая = Ложь;
КонецЕсли;
ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент));
КонецЦикла;
Результат = ЗаписьXML.Закрыть();
Возврат Результат;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
ЗаписьXML = Новый ЗаписьXML;   ЗаписьXML.УстановитьСтроку();   Пустая = Истина;   Для Каждого Элемент Из пМассив Цикл   Если Не Пустая Тогда   ЗаписьXML.ЗаписатьБезОбработки(пРазделитель);   Иначе   Пустая = Ложь;   КонецЕсли;   ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент));   КонецЦикла;   Результат = ЗаписьXML.Закрыть();   Возврат Результат;  
КонецФункции // ПолучитьСтрокуСРазделителемИзМассиваЛкс()
// Получает представление из идентификатора по правилу
// "ДебиторкаоонтрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства".
// После символа "_" регистр не меняется, а сам символ заменяется на " ".
//
// Параметры:
// ИсходнаяСтрока Строка идентификатор.
//
// Возвращаемое значение:
// Строка представление.
//
Функция ПолучитьПредставлениеИзИдентификатораЛкс(ИсходнаяСтрока) Экспорт
СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1);
Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл
ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1);
ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1);
СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1);
ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1);
Если ТекущийСимвол = "_" Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Продолжить;
ИначеЕсли Истина
И ВРЕГ(ТекущийСимвол) = ТекущийСимвол
// В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку.
//И ПредыдущийСимвол <> " "
Тогда
Если Ложь
ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол
ИЛИ (Истина
И ПредыдущийСимвол <> "_"
И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол
И ВРЕГ(СледующийСимвол) <> СледующийСимвол)
Тогда
СтрокаВозврата = СтрокаВозврата + " ";
Если Ложь
ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол
ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол
Тогда
ТекущийСимвол = НРЕГ(ТекущийСимвол);
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтрокаВозврата = СтрокаВозврата + ТекущийСимвол;
КонецЦикла;
Возврат СтрокаВозврата;
КонецФункции // ПолучитьПредставлениеИзИдентификатораЛкс()
// Преобразует строку для использования в регулярных выражениях.
// Производится
//
// Параметры:
// пТекст Строка.
//
// Возвращаемое значение:
// Строка для вставки в регулярные выражения.
//
Функция ПреобразоватьТекстДляРегулярныхВыраженийЛкс(пТекст) Экспорт
Текст = пТекст;
СтрокаСлужебныхСимволов = "\[]^$()?*+.|"; // "\" должен быть первым
Для Счетчик = 1 По СтрДлина(СтрокаСлужебныхСимволов) Цикл
СпецСимвол = Сред(СтрокаСлужебныхСимволов, Счетчик, 1);
Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол);
КонецЦикла;
Возврат Текст;
КонецФункции // ПреобразоватьТекстДляРегулярныхВыраженийЛкс()
Функция НайтиРегулярноеВыражениеЛкс(Знач Текст, Знач Шаблон, Знач ИменаПодгрупп = "", Знач ИскатьВсеВхождения = Истина, Знач ИгнорироватьРегистрБукв = Истина,
Знач МногострочныйРежим = Ложь, ВызыватьИсключение = Истина) Экспорт
//Вычислитель = Новый COMОбъект("VBScript.RegExp");
Вычислитель = ирКэш.ВычислительРегулярныхВыраженийЛкс();
Вычислитель.IgnoreCase = ИгнорироватьРегистрБукв;
Вычислитель.Global = ИскатьВсеВхождения;
Вычислитель.Multiline = МногострочныйРежим;
Вычислитель.Pattern = Шаблон;
Попытка
Вхождения = Вычислитель.Execute(Текст);
Исключение
Если Не ВызыватьИсключение Тогда
Возврат ОписаниеОшибки();
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ТекстВхождения");
Результат.Колонки.Добавить("ПозицияВхождения");
Результат.Колонки.Добавить("ДлинаВхождения");
Результат.Колонки.Добавить("Подгруппы");
#Если Сервер И Не Сервер Тогда
Результат = Обработки.ирТаблицыДляКонтекстнойПодсказки.Создать().ВхожденияРегулярногоВыражения;
#КонецЕсли
ИндексПервойКолонкиПодгруппы = Результат.Колонки.Количество();
ИменаПодгруппМассив = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаПодгрупп, ",", Истина, Ложь);
Для Каждого ИмяПодгруппы Из ИменаПодгруппМассив Цикл
Если Результат.Колонки.Найти(ИмяПодгруппы) <> Неопределено Тогда
ВызватьИсключение "Имя """ + ИмяПодгруппы + """ добавляемой колонки подгруппы результатов поиска не уникально";
КонецЕсли;
Результат.Колонки.Добавить(ИмяПодгруппы);
КонецЦикла;
КоличествоИменПодгрупп = ИменаПодгруппМассив.Количество();
Для Каждого Вхождение Из Вхождения Цикл
//Если Результат.Количество() = 0 Тогда
// Для ИндексПодгруппы = ИменаПодгруппМассив.Количество() По Вхождение.SubMatches.Count - 1 Цикл
// Результат.Колонки.Добавить("Подгруппа" + XMLСтрока(ИндексПодгруппы));
// КонецЦикла;
//КонецЕсли;
СтрокаРезультата = Результат.Добавить();
СтрокаРезультата.ТекстВхождения = Вхождение.Value;
СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex;
СтрокаРезультата.ДлинаВхождения = Вхождение.Length;
Подгруппы = Новый Массив;
Для ИндексПодгруппы = 0 По Вхождение.SubMatches.Count - 1 Цикл
Если ИндексПодгруппы < КоличествоИменПодгрупп Тогда
СтрокаРезультата[ИндексПервойКолонкиПодгруппы + ИндексПодгруппы] = Вхождение.SubMatches(ИндексПодгруппы);
КонецЕсли;
Подгруппы.Добавить(Вхождение.SubMatches(ИндексПодгруппы));
КонецЦикла;
СтрокаРезультата.Подгруппы = Подгруппы;
КонецЦикла;
Возврат Результат;
КонецФункции
// Преобразует строку для правого операнда оператора ПОДОБНО языка запросов.
//
// Параметры:
// пТекст Строка.
//
// Возвращаемое значение:
// Строка.
//
Функция ПреобразоватьСтрокуДляПОДОБНОЛкс(Знач Результат, Спецсимвол = "~") Экспорт
ЗарезервированныеСимволы = Новый Массив;
ЗарезервированныеСимволы.Добавить("~");
//ЗарезервированныеСимволы.Добавить("%");
ЗарезервированныеСимволы.Добавить("_");
ЗарезервированныеСимволы.Добавить("[");
ЗарезервированныеСимволы.Добавить("-");
ЗарезервированныеСимволы.Добавить("]");
Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл
Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол);
КонецЦикла;
Возврат Результат;
КонецФункции // ПреобразоватьСтрокуДляПОДОБНОЛкс()
// Получает строку путем повтора переданной строки заданное количество раз.
//
// Параметры:
// СтрокаДляПовтора Строка;
// ЧислоПовторов Число.
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьСтрокуПовторомЛкс(СтрокаДляПовтора, ЧислоПовторов) Экспорт
Результат = "";
Для Счетчик = 1 По ЧислоПовторов Цикл
Результат = Результат + СтрокаДляПовтора;
КонецЦикла;
Возврат Результат;
КонецФункции // ПолучитьСтрокуПовторомЛкс()
// Обновляет в строковом свойстве объекта часть, которая следует за маркером.
// Если маркер не находится, то он добавляется.
//
// Параметры:
// пОбъект Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке;
// *пИмяСвойства Строка, *"" имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке;
// пНовыйТекст - Строка - новая часть, которая следует за разделителем;
// *пМаркер - Строка, *"," - маркер.
//
Процедура ОбновитьТекстПослеМаркераВСтрокеЛкс(пОбъектИлиСвойство, пИмяСвойства = "", пНовыйТекст, пМаркер = ", ") Экспорт
Если пИмяСвойства <> "" Тогда
СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства];
Иначе
СтараяСтрока = пОбъектИлиСвойство;
КонецЕсли;
ПозицияРазделителя = Найти(СтараяСтрока, пМаркер);
Если ПозицияРазделителя = 0 Тогда
ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1;
КонецЕсли;
НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + пНовыйТекст;
Если пИмяСвойства <> "" Тогда
пОбъектИлиСвойство[пИмяСвойства] = НоваяСтрока;
Иначе
пОбъектИлиСвойство = НоваяСтрока;
КонецЕсли;
КонецПроцедуры // ОбновитьТекстПослеМаркераВСтрокеЛкс()
// Заменяет текущее выделение в поле текстового документа новым текстом.
// После этого устанавливает выделение на вставленный фрагмент.
//
// Параметры:
// ПолеТекстовогоДокумента - ПолеТекстовогоДокумента;
// НовыйТекст Строка.
//
Процедура ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
Перем НачальнаяСтрока;
Перем НачальнаяКолонка;
Перем КонечнаяСтрока;
Перем КонечнаяКолонка;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, НачальнаяСтрока, НачальнаяКолонка);
НачальнаяГраница = СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) + 1;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст;
КонечнаяГраница = НачальнаяГраница + СтрДлина(НовыйТекст);
Если КонечнаяГраница > СтрДлина(ПолеТекстовогоДокумента.ПолучитьТекст()) Тогда
КонечнаяГраница = КонечнаяГраница - 1;
КонецЕсли;
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяГраница, КонечнаяГраница);
КонецПроцедуры // ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс()
// Взято отсюда http://infostart.ru/public/100845/
// ИсходныеДанные - <примитивное значение>, ДвоичныеДАнные, ХранилищеЗначения
//
// Возвращаемое значение
// Число
Функция ВычислитьХэшЛкс(ИсходныеДанные, Хэш=5381, М=33, Разрядность=18446744073709551616) Экспорт
// приведем к строке
Если ТипЗнч(ИсходныеДанные) = Тип("ДвоичныеДанные") Тогда
СтрокаДляКодирования = Base64Строка(ИсходныеДанные);
ИначеЕсли ТипЗнч(ИсходныеДанные) = Тип("ХранилищеЗначения") Тогда
СтрокаДляКодирования = ЗначениеВСтрокуВнутр(ИсходныеДанные);
Иначе
СтрокаДляКодирования = Строка(ИсходныеДанные);
КонецЕсли;
ДлинаБлока = 11;
НачПозиция = 1;
ДлинаСтроки = СтрДлина(СтрокаДляКодирования);
Пока НачПозиция <= ДлинаСтроки Цикл
СтрокаБлока = Сред(СтрокаДляКодирования, НачПозиция, ДлинаБлока);
ДлинаПодстроки = СтрДлина(СтрокаБлока);
Если ДлинаПодстроки = ДлинаБлока Тогда
Хэш = ((((((((((( Хэш*М + КодСимвола(СтрокаБлока, 1))*М + КодСимвола(СтрокаБлока, 2))*М
+ КодСимвола(СтрокаБлока, 3))*М + КодСимвола(СтрокаБлока, 4))*М + КодСимвола(СтрокаБлока, 5))*М
+ КодСимвола(СтрокаБлока, 6))*М + КодСимвола(СтрокаБлока, 7))*М + КодСимвола(СтрокаБлока, 8))*М
+ КодСимвола(СтрокаБлока, 9))*М + КодСимвола(СтрокаБлока, 10))*М + КодСимвола(СтрокаБлока, 11))
Иначе
Для к = 1 По ДлинаПодстроки Цикл
Хэш = М * Хэш + КодСимвола(СтрокаБлока, к)
КонецЦикла
КонецЕсли;
Хэш = Хэш % Разрядность;
НачПозиция = НачПозиция + ДлинаБлока
КонецЦикла;
Возврат Хэш;
КонецФункции
Функция ПолучитьГУИДИнверсныйИзПрямогоЛкс(ПрямойГУИД) Экспорт
С = СтрЗаменить(ПрямойГУИД, "-", "");
Возврат Сред(С,17,16)+Сред(С,13,4)+Сред(С,9,4)+Сред(С,1,4)+Сред(С,5,4);
КонецФункции
Функция ПолучитьГУИДПрямойИзИнверсногоЛкс(ИнверсныйГУИД) Экспорт
С = ИнверсныйГУИД;
Возврат Сред(С,25,8)+"-"+Сред(С,21,4)+"-"+Сред(С,17,4)+"-"+Сред(С,1,4)+"-"+Сред(С,5,12);
КонецФункции
Функция ПолучитьОписаниеТиповВсеСсылкиЛкс() Экспорт
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(
"<TypeDescription xmlns=""http://v8.1c.ru/8.1/data/core"">
| <TypeSet xmlns:cc=""http://v8.1c.ru/8.1/data/enterprise/current-config"">cc:AnyRef</TypeSet>
|</TypeDescription>");
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803001 Тогда
Для Каждого ВнешнийИсточникДанных Из Вычислить("ВнешниеИсточникиДанных") Цикл // Для компиляции на платформе 8.2.13-
Результат = Новый ОписаниеТипов(Результат, ВнешнийИсточникДанных.Таблицы.ТипВсеСсылки().Типы());
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОписаниеТиповВсеРедактируемыеТипыЛкс() Экспорт
ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс();
ДополнительныеТипы = Новый Массив();
ДополнительныеТипы.Добавить(Тип("Строка"));
ДополнительныеТипы.Добавить(Тип("Число"));
ДополнительныеТипы.Добавить(Тип("Дата"));
ДополнительныеТипы.Добавить(Тип("Булево"));
ДополнительныеТипы.Добавить(Тип("СписокЗначений"));
ДополнительныеТипы.Добавить(Тип("Массив"));
ДополнительныеТипы.Добавить(Тип("ОписаниеТипов"));
ДополнительныеТипы.Добавить(Тип("МоментВремени"));
ДополнительныеТипы.Добавить(Тип("Граница"));
ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала"));
ДополнительныеТипы.Добавить(Тип("СтандартныйПериод"));
ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений"));
ДополнительныеТипы.Добавить(Тип("ДеревоЗначений"));
ДополнительныеТипы.Добавить(Тип("ТабличныйДокумент"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии"));
ДополнительныеТипы.Добавить(Тип("ВидСчета"));
ДополнительныеТипы.Добавить(Тип("Тип"));
ДополнительныеТипы.Добавить(Тип("Null"));
ДополнительныеТипы.Добавить(Тип("ПолеКомпоновкиДанных"));
//ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
//ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор"));
ДополнительныеТипы.Добавить(Тип("ХранилищеЗначения"));
ДополнительныеТипы.Добавить(Тип("ДвоичныеДанные"));
// Из-за бага платформы отключены
//ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления"));
//ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления"));
КвалификаторыЧисла = Новый КвалификаторыЧисла; //(25, 5); // Важно!
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла);
Возврат ОписаниеТипов;
КонецФункции
Функция РежимСовместимостиМеньше8_3_4Лкс() Экспорт
Возврат ирКэш.НомерРежимаСовместимостиЛкс() < 803004;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ДЕРЕВЬЯМИ
Процедура ДобавитьКолонкуЕслиНетЛкс(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено,
Заголовок = Неопределено, Ширина = 0) Экспорт
Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда
Возврат;
КонецЕсли;
КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина);
КонецПроцедуры // ДобавитьКолонкуЕслиНетЛкс()
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки = "Имя", ИгнорироватьПростойПервыйУровень = Ложь, Разделитель = ".") Экспорт
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Результат = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева).Строки.Индекс(СтрокаДерева);
Иначе
Результат = СтрокаДерева[ИмяКолонки];
КонецЕсли;
Если СтрокаДерева.Родитель = Неопределено Тогда
Если Истина
И ИгнорироватьПростойПервыйУровень
И СтрокаДерева.Владелец().Строки.Количество() = 1
Тогда
Результат = Неопределено;
КонецЕсли;
Иначе
РезультатСверху = ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева.Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень, Разделитель);
Если РезультатСверху <> Неопределено Тогда
Результат = РезультатСверху + Разделитель + Результат;
КонецЕсли;
КонецЕсли;
Возврат XMLСтрока(Результат);
КонецФункции // ПолучитьСтрокуПутиВДеревеЛкс()
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт
Если Истина
И ИгнорироватьПростойПервыйУровень
И ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений")
И СтрокаДерева.Строки.Количество() = 1
Тогда
Возврат НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Сред(Путь, 2));
КонецЕсли;
ТекущийУровень = ПолучитьПервыйФрагментЛкс(Путь);
Если Не ЗначениеЗаполнено(ТекущийУровень) Тогда
Возврат СтрокаДерева;
КонецЕсли;
ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2);
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ТекущаяСтрока = СтрокаДерева.Строки[Число(ТекущийУровень)];
Иначе
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
КонецЕсли;
Если ТекущаяСтрока <> Неопределено Тогда
Возврат НайтиПоСтрокеПутиВДеревеЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть);
Иначе
Возврат СтрокаДерева;
КонецЕсли;
КонецФункции // НайтиПоСтрокеПутиВДеревеЛкс()
Функция _ПолучитьМассивПутиСтрокиДереваЛкс(СтрокаДерева, ИмяКолонки = "Имя") Экспорт
Если СтрокаДерева.Родитель = Неопределено Тогда
Результат = Новый Массив;
Иначе
Результат = _ПолучитьМассивПутиСтрокиДереваЛкс(СтрокаДерева.Родитель, ИмяКолонки);
КонецЕсли;
ТекущийУровень = СтрокаДерева[ИмяКолонки];
//Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Результат.Добавить(ТекущийУровень);
//КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьМассивПутиСтрокиДереваЛкс()
Функция НайтиСтрокуДереваПоМассивуПутиЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, Позиция = 0) Экспорт
Индекс = Позиция;
ТекущийУровень = Путь[Индекс];
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ТекущаяСтрока = СтрокаДерева.Строки[ТекущийУровень];
Иначе
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
КонецЕсли;
Если Истина
И ТекущаяСтрока <> Неопределено
И Индекс < Путь.ВГраница()
Тогда
Возврат НайтиСтрокуДереваПоМассивуПутиЛкс(ТекущаяСтрока, ИмяКолонки, Путь, Позиция + 1);
Иначе
Возврат ТекущаяСтрока;
КонецЕсли;
КонецФункции // НайтиСтрокуДереваПоМассивуПутиЛкс()
// Процедура заполняет колонку дерева значением.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура ЗаполнитьКолонкуДереваЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл
ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки;
ЗаполнитьКолонкуДереваЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЦикла;
КонецПроцедуры // ЗаполнитьКолонкуДереваЛкс
// Процедура удаляет все строки дерева со значением в колонке.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
НачальноеКоличество = ЭлементДЗ.Строки.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик];
Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда
ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока);
Иначе
УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция ДекодироватьТекстИзXMLЛкс(Текст) Экспорт
//{ Заменяем символы, критичные для XML
//Текст = СтрЗаменить(Текст,"&amp;","&");
//Текст = СтрЗаменить(Текст,"&lt;","<");
//Текст = СтрЗаменить(Текст,"&gt;",">");
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку("<ф>" + Текст + "</ф>");
ЧтениеXML.Прочитать();
ЧтениеXML.Прочитать();
Результат = ЧтениеXML.Значение;
Возврат Результат;
КонецФункции // ПолучитьТекстИзXMLЛкс()
Функция КодироватьТекстВXMLЛкс(Текст) Экспорт
Если Текст = "" Тогда
Возврат "";
КонецЕсли;
//{ Заменяем символы, критичные для XML
//выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&amp;");
//выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","&lt;");
//выхХМЛТело = СтрЗаменить(выхХМЛТело,">","&gt;");
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("");
ЗаписьXML.ЗаписатьНачалоЭлемента("ф");
ЗаписьXML.ЗаписатьТекст(Текст);
ЗаписьXML.ЗаписатьКонецЭлемента();
Результат = ПолучитьСтрокуМеждуМаркерамиЛкс(ЗаписьXML.Закрыть(), "<ф>", "</ф>", Ложь);
Возврат Результат;
КонецФункции
Функция СтрокаВнутрВХМЛТелоЛкс(вхСтрока, выхХМЛТело = Неопределено) Экспорт
//{ Получение одной длинной строки
выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,"");
выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,"");
//}
выхХМЛТело = КодироватьТекстВXMLЛкс(выхХМЛТело);
//{ Замена одинарных символов
выхХМЛТело = СтрЗаменить(выхХМЛТело,",","</data><data>");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"{","<elem><data>");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"}","</data></elem>");
//}
//{ Удаляем лишние блоки <data><elem> и </data></elem>
выхХМЛТело = СтрЗаменить(выхХМЛТело,"<data><elem>","<elem>");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"</elem></data>","</elem>");
//}
//{ Добавляем перенос строки к </data> и к </elem> для удобства поиска различий
выхХМЛТело = СтрЗаменить(выхХМЛТело,"</elem>","</elem>"+СИМВОЛЫ.ПС);
выхХМЛТело = СтрЗаменить(выхХМЛТело,"</data>","</data>"+СИМВОЛЫ.ПС);
//}
Возврат выхХМЛТело;
КонецФункции
// Получает структуру для индикации прогресса цикла.
//
// Параметры:
// КоличествоПроходов Число - максимальное значение счетчика;
// ПредставлениеПроцесса Строка, *"Выполнено" отображаемое название процесса;
// КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора;
// ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса;
// РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс.
// МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений,
// эта реализация не поддерживает дробные значения;
// ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации
//
// Возвращаемое значение:
// Структура - которую потом нужно будет передавать в метод ОбработатьИндикаторЛкс.
//
Функция ПолучитьИндикаторПроцессаЛкс(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение",
Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1,
ТаблицаИндикаторов = Неопределено) Экспорт
ирПлатформа = ирКэш.Получить();
Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда
//#Если Клиент Тогда
// СостояниеЛкс(ПредставлениеПроцесса + "...");
//#КонецЕсли
КоличествоПроходов = 0;
КонецЕсли;
КоличествоПроходов = Цел(КоличествоПроходов);
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() = 0 Тогда
#Если Клиент Тогда
ПодключитьГлобальныйОбработчикОжиданияЛкс("ОсвободитьВсеИндикаторыПроцессовОтложенноЛкс");
#КонецЕсли
ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда
ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов";
КонецЕсли;
Индикатор = ТаблицаИндикаторов.Добавить();
Индикатор.КоличествоПроходов = КоличествоПроходов;
Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса;
Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя;
Индикатор.РазрешитьПрерывание = РазрешитьПрерывание;
Индикатор.ДатаНачалаПроцесса = ТекущаяДата();
Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления;
Индикатор.ДатаСледующегоОбновления = Индикатор.ДатаНачалаПроцесса + Индикатор.МинимальныйПериодОбновления;
Если КоличествоОбновлений > 0 Тогда
Шаг = КоличествоПроходов / КоличествоОбновлений;
Иначе
Шаг = 0;
КонецЕсли;
Индикатор.Шаг = Шаг;
//Индикатор.СледующийСчетчик = 0;
//Индикатор.Счетчик = 0;
Возврат Индикатор;
КонецФункции // ПолучитьИндикаторПроцессаЛкс()
// Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния)
// Параметры:
// СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор
// ВывестиИтогИндикации - Булево
// ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове
//
Процедура ОсвободитьИндикаторПроцессаЛкс(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если Индикатор = Неопределено Тогда
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
КонецЕсли;
КонецЕсли;
Если Индикатор <> Неопределено Тогда
Если ВывестиИтогИндикации Тогда
СообщитьИтогИндикацииЛкс(Индикатор);
КонецЕсли;
Если ТаблицаИндикаторов <> Неопределено Тогда
Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда
ТаблицаИндикаторов.Удалить(Индикатор);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ТаблицаИндикаторов = Неопределено
Или ТаблицаИндикаторов.Количество() = 0
Тогда
НовоеСостояние = "";
Иначе
НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния;
КонецЕсли;
#Если Клиент Тогда
Состояние(НовоеСостояние);
#КонецЕсли
КонецПроцедуры
Процедура ОсвободитьВсеИндикаторыПроцессовЛкс() Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
//Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл
// ОбработатьИндикаторЛкс(СтрокаИндикатора, , Истина);
//КонецЦикла;
ТаблицаИндикаторов.Очистить();
КонецПроцедуры
// Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла.
//
// Параметры:
// Индикатор Структура индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс;
// Счетчик Число, *Неопределено внешний счетчик цикла.
//
Функция ОбработатьИндикаторЛкс(Индикатор, Счетчик = Неопределено) Экспорт
#Если Клиент Тогда
Попытка
Если Индикатор.РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
Исключение
// На клиенте бывает, что строка таблицы индикаторов уже была удалена из-за модальности и обработчиков ожидания
Возврат Ложь;
КонецПопытки;
#КонецЕсли
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Если Счетчик = Неопределено Тогда
Счетчик = Индикатор.Счетчик + 1;
КонецЕсли;
Индикатор.Счетчик = Счетчик;
ОбновитьИндикатор = Истина;
ОчиститьСостояние = Ложь;
Если Ложь
Или Счетчик < Индикатор.КоличествоПроходов
Или Индикатор.КоличествоПроходов = 0
Тогда
ТекущаяДата = ТекущаяДата();
Если Индикатор.МинимальныйПериодОбновления > 0 Тогда
Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда
Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления;
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндикатор Тогда
Если Индикатор.Шаг > 0 Тогда
Если Счетчик >= Индикатор.СледующийСчетчик Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
//Иначе
// ОбновитьИндикатор = Ложь;
// ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
// Состояние(ТекстСостояния);
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда
ОчиститьСостояние = Истина;
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Если Счетчик = Неопределено Тогда   Счетчик = Индикатор.Счетчик + 1;   КонецЕсли;   Индикатор.Счетчик = Счетчик;   ОбновитьИндикатор = Истина;   ОчиститьСостояние = Ложь;   Если Ложь   Или Счетчик < Индикатор.КоличествоПроходов   Или Индикатор.КоличествоПроходов = 0   Тогда   ТекущаяДата = ТекущаяДата();   Если Индикатор.МинимальныйПериодОбновления > 0 Тогда   Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда   Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления;   Иначе   ОбновитьИндикатор = Ложь;   КонецЕсли;   КонецЕсли;   Если ОбновитьИндикатор Тогда   Если Индикатор.Шаг > 0 Тогда   Если Счетчик >= Индикатор.СледующийСчетчик Тогда   Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);   Иначе   ОбновитьИндикатор = Ложь;   КонецЕсли;           КонецЕсли;   КонецЕсли;   Иначе   Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда   ОчиститьСостояние = Истина;   ОбновитьИндикатор = Ложь;   КонецЕсли;   КонецЕсли;  
#Если Клиент Тогда
Если ОчиститьСостояние Тогда
Состояние("");
КонецЕсли;
#КонецЕсли
Если ОбновитьИндикатор Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда
МассивИндикаторов = Индикатор.Владелец();
Иначе
МассивИндикаторов = Новый Массив;
МассивИндикаторов.Добавить(Индикатор);
КонецЕсли;
#Если Клиент Тогда
ТекстСостояния = "";
Для Каждого лИндикатор Из МассивИндикаторов Цикл
Если ТекстСостояния <> "" Тогда
ТекстСостояния = ТекстСостояния + ".>> ";
КонецЕсли;
ТекстСостояния = ТекстСостояния + ПолучитьТекстСостоянияИндикатораЛкс(лИндикатор);
КонецЦикла;
лИндикатор.ТекстСостояния = ТекстСостояния;
Состояние(ТекстСостояния);
#КонецЕсли
КонецЕсли;
Возврат ОбновитьИндикатор;
КонецФункции // ОбработатьИндикаторЛкс()
Процедура СостояниеЛкс(СтрокаСостояния = "") Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния;
КонецЕсли;
#Если Клиент Тогда
Состояние(СтрокаСостояния);
#КонецЕсли
КонецПроцедуры
// Функция сравнивает две таблицы значений на идентичность структуры и данных
//
// Параметры
// ТаблицаЗначений1 - ТаблицаЗначений для сравнения
// ТаблицаЗначений2 - ТаблицаЗначений для сравнения
//
// Возвращаемое значение:
// Булево, идентичны или нет две таблицы
//
Функция ТаблицыЗначенийРавныЛкс(ТаблицаЗначений1, ТаблицаЗначений2) Экспорт
Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл
Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл
СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)];
Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл   СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)];   Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда   Возврат Ложь;   КонецЕсли;   КонецЦикла;  
КонецЦикла;
Возврат Истина;
КонецФункции // СравнитьТаблицыЗначений()
Процедура ФункциональныеОпцииОбъектаМДЛкс(ОбъектМД, выхЗначенияФункОпций, выхСписокФункОпций = Неопределено, выхФункциональныеОпцииВключены = Неопределено) Экспорт
выхЗначенияФункОпций = Новый Структура;
выхФункциональныеОпцииВключены = Истина;
Для Каждого ФункциональнаяОпция Из Метаданные.ФункциональныеОпции Цикл
Если ФункциональнаяОпция.Состав.Содержит(ОбъектМД) Тогда
ОпцияВключена = ПолучитьФункциональнуюОпцию(ФункциональнаяОпция.Имя);
выхЗначенияФункОпций.Вставить(ФункциональнаяОпция.Имя, ОпцияВключена);
Если Не ОпцияВключена Тогда
выхФункциональныеОпцииВключены = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
выхСписокФункОпций = Новый СписокЗначений;
Для Каждого КлючИЗначение Из выхЗначенияФункОпций Цикл
выхСписокФункОпций.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Ключ + " = " + ОпцияВключена);
КонецЦикла;
КонецПроцедуры
#Если Клиент Тогда
Функция ИмяФормыИзСтрокиИнструментаЛкс(Знач СтрокаИнструмента) Экспорт
ИмяВыбраннойФормы = СтрокаИнструмента.ПолноеИмя;
Если Найти(ИмяВыбраннойФормы, "ОбщаяФорма.") <> 1 И Найти(ИмяВыбраннойФормы, ".Форма.") = 0 Тогда
Если Найти(ИмяВыбраннойФормы, "Справочник.") = 1 Тогда
ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".ФормаСписка";
Иначе
ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".Форма";
КонецЕсли;
КонецЕсли;
Возврат ИмяВыбраннойФормы;
КонецФункции
Процедура ПодключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода, Интервал = 0.1, Однократно = Истина) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ПолучитьФорму().ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина);
Иначе
ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина);
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ФОРМАМИ
// РежимОткрытия - Булево - Истина - Открытие, иначе Сохранение
Функция ВыбратьФайлЛкс(РежимОткрытия = Истина, Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "") Экспорт
ВыборФайла = ДиалогВыбораФайлаЛкс(РежимОткрытия, Расширение, ОписаниеФормата, ПолноеИмяФайла, Каталог, КраткоеИмя);
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ВыборФайла.ПолноеИмяФайла;
КонецФункции
Функция ДиалогВыбораФайлаЛкс(РежимОткрытия = Истина, Знач Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "") Экспорт
Если РежимОткрытия = Истина Тогда
РежимДиалога = РежимДиалогаВыбораФайла.Открытие;
Иначе
РежимДиалога = РежимДиалогаВыбораФайла.Сохранение;
КонецЕсли;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалога);
Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда
Файл = Новый Файл(ПолноеИмяФайла);
ВыборФайла.Каталог = Файл.Путь;
ВыборФайла.ПолноеИмяФайла = Файл.Имя;
Иначе
ВыборФайла.Каталог = Каталог;
ВыборФайла.ПолноеИмяФайла = КраткоеИмя;
КонецЕсли;
ВыборФайла.Расширение = Расширение;
Если Не ЗначениеЗаполнено(Расширение) Тогда
Расширение = "*";
КонецЕсли;
ВыборФайла.Фильтр = ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата);
Возврат ВыборФайла;
КонецФункции
Функция ВыбратьКаталогВФормеЛкс(выхКаталог, ФормаДляУстановкиМодифицированности = Неопределено, Заголовок = "") Экспорт
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = выхКаталог;
ВыборФайла.Заголовок = Заголовок;
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
выхКаталог = ВыборФайла.Каталог;
Если ФормаДляУстановкиМодифицированности <> Неопределено Тогда
ФормаДляУстановкиМодифицированности.Модифицированность = Истина;
КонецЕсли;
Возврат выхКаталог;
КонецФункции
Процедура ПолучитьМассивЗначенийПеретаскиванияЛкс(Знач ПараметрыПеретаскивания, выхМассивЗначений, выхТипЗначенияПеретаскивания = Неопределено) Экспорт
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания);
Если выхТипЗначенияПеретаскивания = Тип("Массив") Тогда
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания[0]);
выхМассивЗначений = ЗначениеПеретаскивания;
Иначе
выхМассивЗначений = Новый Массив;
выхМассивЗначений.Добавить(ЗначениеПеретаскивания);
КонецЕсли;
КонецПроцедуры
// Параметры:
// КлючеваяКолонка - Строка - используется при отборе
// ПроверятьОформлениеСтроки - Булево - долго
Процедура ИзменитьПометкиВыделенныхСтрокЛкс(Знач ТабличноеПоле, ИмяКолонкиПометки = "Пометка", НовоеЗначениеПометки = Истина, КлючеваяКолонка = "НомерСтроки",
СтруктураОтбора = Неопределено, ПроверятьОформлениеСтроки = Истина) Экспорт
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() <= 1 Тогда
ВыделенныеСтроки = ТабличноеПоле.Значение;
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Или СтруктураОтбора <> Неопределено Тогда
Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора);
#Если Сервер И Не Сервер Тогда
Построитель = Новый ПостроительЗапроса;
#КонецЕсли
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка);
НомераОтобранныхСтрок = Построитель.Результат.Выгрузить();
НомераОтобранныхСтрок.Индексы.Добавить(КлючеваяКолонка);
КонецЕсли;
КонецЕсли;
Для каждого Строка из ВыделенныеСтроки Цикл
Если Истина
И НомераОтобранныхСтрок <> Неопределено
И НомераОтобранныхСтрок.Найти(Строка[КлючеваяКолонка], КлючеваяКолонка) = Неопределено
Тогда
// Строка не отвечает отбору
Продолжить;
КонецЕсли;
Если ПроверятьОформлениеСтроки Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(Строка);
Если ОформлениеСтроки.Ячейки[ИмяКолонкиПометки].ТолькоПросмотр Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Строка[ИмяКолонкиПометки] = НовоеЗначениеПометки;
КонецЦикла;
ТабличноеПоле.ОбновитьСтроки();
КонецПроцедуры
Функция ВыбратьСсылкуЛкс(ИмяТаблицыИлиМДИлиТип, НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт
Результат = ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип,, ИспользоватьДинамическийСписокИР,, Истина,, НачальноеЗначениеВыбора, Истина);
Возврат Результат;
КонецФункции
Процедура ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(ТаблицаИсточник, НачальноеПолноеИмяОбъекта = "") Экспорт
ФормаВыбораОбъектаБД = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхЛкс(,, НачальноеПолноеИмяОбъекта,, Истина,, Истина, Истина,, Истина,,, Истина);
РезультатВыбора = ФормаВыбораОбъектаБД.ОткрытьМодально();
Если РезультатВыбора = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектМД = ирОбщий.НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(РезультатВыбора.ПолноеИмяОбъекта);
ЭтоНаборЗаписей = ирОбщий.ЛиРегистровыйОбъектМетаданных(ОбъектМД);
Если ЭтоНаборЗаписей Тогда
ПолноеИмяМДСписка = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМДСписка = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
МакетныйОбъект = Неопределено;
ТекущаяГруппаТипаМетаданных = Неопределено;
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМДСписка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных);
Если ЭтоНаборЗаписей Тогда
ОбъектБД = МакетныйОбъект;
ТаблицаПриемник = ОбъектБД;
Иначе
ВыбраннаяСтрока = ОткрытьФормуСпискаЛкс(ПолноеИмяМДСписка,,,, Истина,,, Истина);
Если ВыбраннаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектБД = ирОбщий.ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(ВыбраннаяСтрока, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина);
ТаблицаПриемник = ОбъектБД[ОбъектМД.Имя];
КонецЕсли;
Если ТаблицаПриемник.Количество() > 0 Тогда
Если ЭтоНаборЗаписей Тогда
ТекстВопроса = "Хотите очистить набор записей в памяти перед заполнением?";
Иначе
ТекстВопроса = "Выбранная табличная часть объекта не пустая. Хотите очистить ее в памяти перед заполнением?";
КонецЕсли;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТаблицаПриемник.Очистить();
КонецЕсли;
КонецЕсли;
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник);
ОбработкаРедактора = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД");
#Если Сервер И Не Сервер Тогда
ОбработкаРедактора = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ФормаРедактора = ОбработкаРедактора.РедактироватьМодифицированныйОбъект(ОбъектБД);
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(РезультатВыбора.ПолноеИмяОбъекта);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(Значение1, Значение2, Модально = Ложь,
Название1 = Неопределено, Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Истина
И ТипЗнч(Значение1) = Тип("ТаблицаЗначений")
И ТипЗнч(Значение2) = Тип("ТаблицаЗначений")
Тогда
Обработка = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирСравнениеТаблиц");
#Если Сервер И Не Сервер Тогда
Обработка = Обработки.ирСравнениеТаблиц.Создать();
#КонецЕсли
Обработка.Таблица1 = Значение1;
Обработка.Таблица2 = Значение2;
Обработка.ОбновитьСопоставлениеКолонок();
Обработка.ЗаполнитьСопоставлениеКолонок();
Обработка.ПодобратьКлючевыеИСравниваемыеКолонки();
ФормаСравнителя = Обработка.ПолучитьФорму();
ФормаСравнителя.РежимРедактора = Истина;
ФормаСравнителя.Открыть();
Возврат ФормаСравнителя.СравнитьТаблицыВФорме();
КонецЕсли;
Путь1 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение1, Название1, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
Путь2 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение2, Название2, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
// Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится.
Если СравнениеФайлов = Неопределено Тогда
СравнениеФайлов = Новый СравнениеФайлов;
КонецЕсли;
СравнениеФайлов.ПервыйФайл = Путь1;
СравнениеФайлов.ВторойФайл = Путь2;
СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь;
Если Истина
И ТипЗнч(Значение1) = Тип("ТабличныйДокумент")
И ТипЗнч(Значение2) = Тип("ТабличныйДокумент")
Тогда
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент;
Иначе
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент;
КонецЕсли;
Если Модально Тогда
СравнениеФайлов.ПоказатьРазличияМодально();
Иначе
СравнениеФайлов.ПоказатьРазличия();
КонецЕсли;
Возврат СравнениеФайлов.Сравнить();
КонецФункции // СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс()
// Сравнивает табличный документ, полученный из элемента управления с предыдущим.
//
// Параметры:
// СравнительТабличныхДокументов Массив, *Неопределено переменная для хранения предыдущего табличного документа.
// ЭлементУправления ТабличноеПоле, ПолеТабличногоДокумента откуда получаем содержимое.
//
Процедура СравнитьСодержимоеЭлементаУправленияЛкс(ЭлементУправления) Экспорт
Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст());
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение);
ИначеЕсли Ложь
Или ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле")
Или ТипЗнч(ЭлементУправления) = Тип("ТаблицаФормы")
Тогда
СравниваемыйДокумент = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ЭлементУправления);
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеТабличногоДокумента") Тогда
СравниваемыйДокумент = ЭлементУправления.ПолучитьОбласть();
Иначе
Сообщить("Неподдерживаемый тип элемента управления для сравнения");
Возврат;
КонецЕсли;
МассивСравнения = ирКэш.ПолучитьБуферСравненияЛкс("" + ТипЗнч(СравниваемыйДокумент));
Если МассивСравнения.Количество() = 2 Тогда
МассивСравнения.Удалить(0);
КонецЕсли;
МассивСравнения.Добавить(СравниваемыйДокумент);
Если МассивСравнения.Количество() = 2 Тогда
Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
СравниваемыйДокумент1 = МассивСравнения[0];
СравниваемыйДокумент2 = МассивСравнения[1];
СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(СравниваемыйДокумент1, СравниваемыйДокумент2);
Иначе
Сообщить("Первое значение для сравнения запомнено. Теперь передайте второе значение.");
КонецЕсли;
КонецПроцедуры
Функция ВывестиСтрокиТабличногоПоляСНастройкойЛкс(Знач ТабличноеПоле, ВыводБезОформления = Истина, Знач НастройкиСписка = Неопределено) Экспорт
ФормаНастройки = ирКэш.Получить().ПолучитьФорму("ПараметрыВыводаСтрокТабличногоПоля");
ФормаНастройки.ТабличноеПоле = ТабличноеПоле;
Если ВыводБезОформления <> Неопределено Тогда
ФормаНастройки.БезОформления = ВыводБезОформления;
КонецЕсли;
РезультатФормы = ФормаНастройки.ОткрытьМодально();
Если РезультатФормы = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = ВывестиСтрокиТабличногоПоляЛкс(ТабличноеПоле, ФормаНастройки,,, НастройкиСписка);
Возврат Результат;
КонецФункции
Функция ВывестиСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач ПараметрыВывода, Отладка = Ложь, выхТекущаяСтрока = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт
КлючТекущейСтроки = Неопределено;
ИндексТекущейСтроки = Неопределено;
СтруктураТипа = Неопределено;
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле, , СтруктураТипа);
ВыбранныеКолонки = ПараметрыВывода.КолонкиТабличногоПоля.Выгрузить(Новый Структура("Пометка", Истина));
МассивСтрок = Неопределено;
ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ТипИсточника = "Список" Тогда
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
КлючТекущейСтроки = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда
КоллекцияСтрок = КлючиВыделенныхСтрокДинамическогоСписка(ТабличноеПоле);
КонецЕсли;
Иначе
Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда
МассивСтрок = ПолучитьМассивВыделенныхСтрокТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда
Если МассивСтрок <> Неопределено Тогда
КоллекцияСтрок = МассивСтрок;
Иначе
КоллекцияСтрок = ЗначениеТабличногоПоля.Строки;
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей"
Или ТипИсточника = "ТаблицаЗначений"
Тогда
Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
//ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущаяСтрока);
ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущиеДанные);
КонецЕсли;
КоллекцияСтрок = ТаблицаЗначенийИзТабличногоПоляЛкс(ТабличноеПоле, МассивСтрок);
КонецЕсли;
КонецЕсли;
Если ПараметрыВывода.БезОформления Тогда
ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Данные");
Если ТипИсточника = "Список" Тогда
КоллекцияСтрок = КлючиСтрокДинамическогоСпискаЛкс(ВыбранныеКолонки, КлючТекущейСтроки, НастройкиСписка, ПараметрыВывода, КоллекцияСтрок, ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
КоллекцияСтрок = Новый ТаблицаЗначений;
#КонецЕсли
ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки);
Если ТекущаяСтрока.Количество() > 0 Тогда
ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТекущаяСтрока[0]);
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы)) И ПараметрыВывода.КолонкиИдентификаторов Тогда
//ВыбранныеКолонки.Добавить("Ссылка");
КоллекцияСтрок.Колонки.Добавить("ИдентификаторСсылкиЛкс",, "Идентификатор ссылки");
ВыбранныеКолонки.Добавить("ИдентификаторСсылкиЛкс");
Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
СтрокаКоллекции.ИдентификаторСсылкиЛкс = СтрокаКоллекции.Ссылка.УникальныйИдентификатор();
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда
ТаблицаСтрокДерева = Новый ТаблицаЗначений;
Для Каждого КолонкаДерева Из ЗначениеТабличногоПоля.Колонки Цикл
ТаблицаСтрокДерева.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина);
КонецЦикла;
Если ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда
КоллекцияСтрок = ПолучитьВсеСтрокиДереваЗначенийЛкс(ЗначениеТабличногоПоля);
КонецЕсли;
Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтрокДерева.Добавить(), СтрокаДерева);
КонецЦикла;
КоллекцияСтрок = ТаблицаСтрокДерева;
КонецЕсли;
ИмяТекущейКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Результат = ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(КоллекцияСтрок,,, ПараметрыВывода.ИтогиЧисловыхКолонок,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки,
ПараметрыВывода.ОтображатьПустые, ПараметрыВывода.КолонкиИдентификаторов, ПараметрыВывода.КолонкиТипов, ПараметрыВывода.КолонкиЗначений, ВыбранныеКолонки, ИмяТекущейКолонки,
ПараметрыВывода.ВыводВТаблицуЗначений, Отладка);
Иначе
Если ТипИсточника = "Список" Тогда
КоллекцияСтрок = КлючиСтрокДинамическогоСпискаЛкс(, КлючТекущейСтроки, НастройкиСписка, ПараметрыВывода, КоллекцияСтрок, ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
КоллекцияСтрок = Новый ТаблицаЗначений;
#КонецЕсли
ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки);
Если ТекущаяСтрока.Количество() > 0 Тогда
ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТекущаяСтрока[0]);
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы)) Тогда
КоллекцияСтрок = КоллекцияСтрок.ВыгрузитьКолонку("Ссылка");
КонецЕсли;
КонецЕсли;
ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Имя");
Результат = Новый ТабличныйДокумент;
НомерКолонки = 1;
НомерСтроки = 1;
ОбластьТаблицы = Результат.Область();
ОбластьТаблицы.ЦветРамки = ЦветаСтиля.ЦветРамки;
ОбластьЗаголовков = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
ОбластьЗаголовков.ЦветФона = ТабличноеПоле.ЦветФонаШапки;
ОбластьЗаголовков.ЦветТекста = ТабличноеПоле.ЦветТекстаШапки;
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Колонка = ТабличноеПоле.Колонки[ВыбраннаяКолонка];
Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
Если Колонка.Видимость Тогда
ОбластьЗаголовка = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ОбластьЗаголовка.Текст = Колонка.ТекстШапки;
ОбластьЗаголовка.ЦветФона = Колонка.ЦветФонаШапки;
ОбластьЗаголовка.ЦветТекста = Колонка.ЦветТекстаШапки;
//ШиринаКолонки = Колонка.Ширина;
//Если ШиринаКолонки <= 0 Тогда
// Если ЗначениеЗаполнено(Колонка.Данные) Тогда
// ШиринаКолонки = ЗначениеТабличногоПоля.Колонки[Колонка.Данные].Ширина;
// Если ШиринаКолонки = 0 Тогда
// ШиринаКолонки = 30;
// КонецЕсли;
// Иначе
// ШиринаКолонки = 30;
// КонецЕсли;
//КонецЕсли;
//ШиринаКолонки = Мин(ШиринаКолонки, 50);
//ШиринаКолонки = Макс(ШиринаКолонки, 10);
//ОбластьЗаголовка.ШиринаКолонки = ШиринаКолонки;
ОбластьЗаголовка.ЦветФона = ЦветаСтиля.ЦветФонаШапкиТаблицы;
ОбластьЗаголовка.ЦветТекста = ЦветаСтиля.ЦветТекстаШапкиТаблицы;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЗаголовка, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
ВывестиСтрокиТабличногоПоляСОформлениемЛкс(КоллекцияСтрок, НомерСтроки, Результат, ТабличноеПоле,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки);
УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(Результат);
Если ТабличноеПоле.ТекущаяКолонка <> Неопределено Тогда
ИндексКолонки = ВыбранныеКолонки.Найти(ТабличноеПоле.ТекущаяКолонка.Имя);
Если ИндексКолонки <> Неопределено Тогда
Результат.ТекущаяОбласть = Результат.Область(2, ИндексКолонки + 1);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Результат <> Неопределено Тогда
Если ПараметрыВывода.ТолькоВыделенныеСтроки Или ИндексТекущейСтроки = Неопределено Тогда
ИндексТекущейСтроки = 0;
КонецЕсли;
Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда
НомерСтроки = ИндексТекущейСтроки + 2;
Результат.ТекущаяОбласть = Результат.Область(НомерСтроки, Результат.ТекущаяОбласть.Лево);
ИначеЕсли Результат.Количество() > ИндексТекущейСтроки Тогда
выхТекущаяСтрока = Результат[ИндексТекущейСтроки];
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КлючиСтрокДинамическогоСпискаЛкс(Знач ВыбранныеКолонки = Неопределено, Знач КлючТекущейСтроки, НастройкиСписка, Знач ПараметрыВывода, Знач КоллекцияСтрок, Знач ТабличноеПоле)
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда
ГруппаИли = НастройкаКомпоновки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли;
ГруппаИли.Использование = Истина;
Для Каждого КлючСтроки Из КоллекцияСтрок Цикл
ГруппаИ = ГруппаИли.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ;
ГруппаИ.Использование = Истина;
Для Каждого КлючИЗначение Из КлючТекущейСтроки Цикл
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ГруппаИ, КлючИЗначение.Ключ, КлючСтроки[КлючИЗначение.Ключ]);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Для Каждого КлючИЗначение Из КлючТекущейСтроки Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, КлючИЗначение.Ключ);
КонецЦикла;
Если ВыбранныеКолонки <> Неопределено Тогда
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка);
КонецЦикла;
КонецЕсли;
КоллекцияСтрок = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки);
Возврат КоллекцияСтрок;
КонецФункции
Функция ПолучитьМассивВыделенныхСтрокТабличногоПоляЛкс(Знач ТабличноеПоле) Экспорт
МассивСтрок = Новый Массив;
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
МассивСтрок.Добавить(ВыделеннаяСтрока);
КонецЦикла;
Возврат МассивСтрок;
КонецФункции
Процедура ВывестиСтрокиТабличногоПоляСОформлениемЛкс(Знач КоллекцияСтрок, НомерСтроки, Знач Результат, Знач ТабличноеПоле, Смещение = "", ВстроитьЗначенияВРасшифровки = Истина)
#Если Сервер И Не Сервер Тогда
Результат = Новый ТабличныйДокумент;
#КонецЕсли
Индикатор = ПолучитьИндикаторПроцессаЛкс(КоллекцияСтрок.Количество());
Для Каждого СтрокаИсточника Из КоллекцияСтрок Цикл
ОбработатьИндикаторЛкс(Индикатор);
НомерСтроки = НомерСтроки + 1;
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(СтрокаИсточника);
ОбластьСтроки = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
//ЗаполнитьЗначенияСвойств(ОбластьСтроки, ОформлениеСтроки, "Шрифт, ЦветТекста, ЦветФона");
НомерКолонки = 1;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда
Продолжить;
КонецЕсли;
Если Колонка.Видимость И ОформлениеСтроки <> Неопределено Тогда // Для строк ТЧ почему то ОформлениеСтроки = Неопределено, видимо баг платформы
ОформлениеЯчейки = ОформлениеСтроки.Ячейки[Колонка.Имя];
ОбластьЯчейки = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ЗаполнитьЗначенияСвойств(ОбластьЯчейки, ОформлениеЯчейки, "Шрифт, ЦветТекста, ЦветФона");
Если ОформлениеЯчейки.ОтображатьТекст Тогда
ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.Текст;
ИначеЕсли ОформлениеЯчейки.ОтображатьФлажок Тогда
ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.ЗначениеФлажка;
КонецЕсли;
Если Истина
И ВстроитьЗначенияВРасшифровки
//И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ОформлениеЯчейки.Значение, Ложь)
Тогда
ОбластьЯчейки.Расшифровка = ОформлениеЯчейки.Значение;
КонецЕсли;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЯчейки, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
Если ТипЗнч(СтрокаИсточника) = Тип("СтрокаДереваЗначений") И ТабличноеПоле.Развернут(СтрокаИсточника) Тогда
Результат.НачатьГруппуСтрок();
ВывестиСтрокиТабличногоПоляСОформлениемЛкс(СтрокаИсточника.Строки, НомерСтроки, Результат, ТабличноеПоле, Смещение + " ");
Результат.ЗакончитьГруппуСтрок();
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецПроцедуры
Процедура ВывестиСтрокиТабличногоПоляИПоказатьЛкс(Знач ТабличноеПоле, Знач ВыводБезОформления = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт
Результат = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ТабличноеПоле, ВыводБезОформления, НастройкиСписка);
Если Результат <> Неопределено Тогда
ОткрытьЗначениеЛкс(Результат, Ложь,,, Ложь);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(Знач ОбластьЯчейки, Знач ЭлементУправления) Экспорт
ЛинияСплошная = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная);
Если ЭлементУправления.ГоризонтальныеЛинии Тогда
ОбластьЯчейки.ГраницаСверху = ЛинияСплошная;
ОбластьЯчейки.ГраницаСнизу = ЛинияСплошная;
КонецЕсли;
Если ЭлементУправления.ВертикальныеЛинии Тогда
ОбластьЯчейки.ГраницаСлева = ЛинияСплошная;
ОбластьЯчейки.ГраницаСправа = ЛинияСплошная;
КонецЕсли;
КонецПроцедуры // ЛксСравнитьСодержимоеПоля()
Процедура РасширитьКолонкиТабличногоПоляЛкс(ТабличноеПоле, УважатьЗапретИзмененияРазмера = Истина) Экспорт
//ВведенноеЗначениеШирины = 10;
//Если ВвестиЧисло(ВведенноеЗначениеШирины, "Введите новую ширину колонки для всех колонок", 5, 0) Тогда
// УстановитьСвойствоВКоллекцииЛкс(ТабличноеПоле.Колонки, , "-Ширина", ВведенноеЗначениеШирины);
//КонецЕсли;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Ширина = Колонка.Ширина;
Если Ширина = 0 Тогда
// Антибаг платформы.
Ширина = 10;
КонецЕсли;
Если Ложь
Или Не УважатьЗапретИзмененияРазмера
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять
Тогда
НоваяШирина = Ширина + 3;
Колонка.Ширина = НоваяШирина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // РасширитьКолонкиТабличногоПоляЛкс()
// Пропорционально сжимает ширины колонок табличного поля.
//
// Параметры:
// ТабличноеПоле ТабличноеПоле;
// Сжатие Число, *2 коэффициент сжатия;
// УважатьЗапретИзмененияРазмера Булево, *Истина не сжимать колонки с запретом изменения размера;
//
Процедура СжатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, Сжатие = 2, УважатьЗапретИзмененияРазмера = Истина) Экспорт
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Ширина = Колонка.Ширина;
Если Ширина = 0 Тогда
// Антибаг платформы.
Ширина = 10;
КонецЕсли;
Если Ложь
Или Не УважатьЗапретИзмененияРазмера
Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять
Тогда
НоваяШирина = Ширина / Сжатие;
НоваяШирина = Макс(НоваяШирина, 1);
Колонка.Ширина = НоваяШирина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СжатьКолонкиТабличногоПоляЛкс()
// Интерактивно записывает значение в элемент управления. Интерактивность заключается в срабатывании
// события ПриИзменении у элемента управления.
//
// Параметры:
// ЭлементУправления ЭлементУправления которому присваиваем значение;
// Значение Произвольный присваиваемое значение;
// *ФормаИнициатор - Форма, *Неопределено - которая будет использована в качестве инициатора события;
// если не указана, то будет создана временная форма-пустышка.
//
// Результат - Булево - успешно ли значение установлено
Функция ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Знач Значение, Знач ФормаИнициатор = Неопределено) Экспорт
Если ФормаИнициатор = Неопределено Тогда
ФормаИнициатор = ирКэш.Получить().ПолучитьФорму("Пустышка", ЭлементУправления);
Иначе
СтарыйВладелец = ФормаИнициатор.ВладелецФормы;
СтарыйЗакрыватьПриВыборе = ФормаИнициатор.ЗакрыватьПриВыборе;
ФормаИнициатор.ВладелецФормы = ЭлементУправления;
ФормаИнициатор.ЗакрыватьПриВыборе = Ложь;
КонецЕсли;
НовоеЗначение = ЭлементУправления.ОграничениеТипа.ПривестиЗначение(Значение);
Если Ложь
Или НовоеЗначение <> Значение
Или ЭлементУправления.ТолькоПросмотр
Тогда
Возврат Ложь;
КонецЕсли;
ФормаИнициатор.ОповеститьОВыборе(Значение);
Если СтарыйЗакрыватьПриВыборе <> Неопределено Тогда
ФормаИнициатор.ВладелецФормы = СтарыйВладелец;
ФормаИнициатор.ЗакрыватьПриВыборе = СтарыйЗакрыватьПриВыборе;
КонецЕсли;
ЗначениеПоля = ДанныеЭлементаФормыЛкс(ЭлементУправления);
//Попытка
Результат = ЗначениеПоля = Значение;
//Исключение
// // Это поле управляемой формы
// Результат = Истина;
//КонецПопытки;
Возврат Результат;
КонецФункции // ИнтерактивноЗаписатьВЭлементУправленияЛкс()
// Интерактивно записывает значение в элемент управления (только поле ввода) колонки табличного поля.
// Интерактивность заключается в срабатывании события ПриИзменении у элемента управления.
// Строка табличного поля должна находиться в режиме редактирования,
// иначе никаких изменений данных не произойдет.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле - строка которого редактируется;
// Колонка КолонкаТабличногоПоля в элемент управления которой записываем;
// Значение Произвольный присваиваемое значение;
// *ФормаИнициатор - Форма, *Неопределено - которая будет использована в качестве инициатора события;
// если не указана, то будет создана временная форма-пустышка;
// *ВосстанавитьТекущуюКолонку Булево, *Истина;
// *ВключитьРежимРедактирования Булево, *Истина.
//
Процедура ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Знач Колонка, Знач Значение, Знач ФормаИнициатор = Неопределено,
Знач ВосстанавитьТекущуюКолонку = Истина, Знач ВключитьРежимРедактирования = Истина, Знач КонтролироватьТекущиеДанные = Истина) Экспорт
Если ТипЗнч(Колонка) = Тип("КолонкаТабличногоПоля") Тогда
ЭлементУправления = Колонка.ЭлементУправления;
Если ТипЗнч(ЭлементУправления) <> Тип("ПолеВвода") Тогда
Возврат;
КонецЕсли;
Иначе
ЭлементУправления = Колонка;
Если ТипЗнч(ЭлементУправления) <> Тип("ПолеФормы") Тогда
Возврат;
КонецЕсли;
КонецЕсли;
ДанныеПоля = ДанныеЭлементаФормыЛкс(ЭлементУправления);
ХмлТип = XMLТипЗнч(ДанныеПоля);
Если Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "CatalogRef.") > 0
Тогда
Если Ложь
Или (Истина
И ЗначениеЗаполнено(ЭлементУправления.ВыборПоВладельцу)
И Значение.Владелец <> ЭлементУправления.ВыборПоВладельцу)
Или (Истина
И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы
И Значение.ЭтоГруппа)
Или (Истина
И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Группы
И Не Значение.ЭтоГруппа)
Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если ВосстанавитьТекущуюКолонку Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
СтараяТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Иначе
СтараяТекущаяКолонка = ТабличноеПоле.ТекущийЭлемент;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущаяКолонка, Колонка);
Иначе
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущийЭлемент, Колонка);
КонецЕсли;
Если ВключитьРежимРедактирования Тогда
ТабличноеПоле.ИзменитьСтроку();
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Значение, ФормаИнициатор);
Если КонтролироватьТекущиеДанные Тогда // На 8.3.8 значение в свойство строки почему то не попадает
ПутьКДаннымКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если ПутьКДаннымКолонки <> "" Тогда
ТекущиеДанные = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле);
Попытка
ЗначениеЯчейки = ТекущиеДанные[ПутьКДаннымКолонки];
ИмяДанныхПравильное = Истина;
Исключение
// В табличных полях компоновки
ИмяДанныхПравильное = Ложь;
КонецПопытки;
Если ИмяДанныхПравильное Тогда
Если Значение <> ЗначениеЯчейки Тогда
// Такое случается в некоторых состояниях формы (пока Открыта() = Ложь)
// Также это срабатывает для неподдерживаемых типов в поле ввода
ТекущиеДанные[ПутьКДаннымКолонки] = Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ВосстанавитьТекущуюКолонку Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущаяКолонка, СтараяТекущаяКолонка);
Иначе
ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущийЭлемент, СтараяТекущаяКолонка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс()
// Проверяет колонку табличного поля на интерактивную доступность.
//
// Параметры:
// пКолонка КолонкаТабличногоПоля.
//
// Возвращаемое значение:
// Истина - колонка интерактивно доступна;
// Ложь - иначе.
//
Функция ЛиИнтерактивноДоступнаяКолонкаЛкс(КолонкаТабличногоПоля) Экспорт
Если Истина
И КолонкаТабличногоПоля.Доступность
И КолонкаТабличногоПоля.Видимость
И Не КолонкаТабличногоПоля.ТолькоПросмотр
И (Ложь
Или ТипЗнч(КолонкаТабличногоПоля) = Тип("ПолеФормы")
Или КолонкаТабличногоПоля.ДанныеФлажка <> ""
Или (Истина
И КолонкаТабличногоПоля.ЭлементУправления <> Неопределено
И КолонкаТабличногоПоля.ЭлементУправления.Доступность))
Тогда
Попытка
Если КолонкаТабличногоПоля.ЭлементУправления.ТолькоПросмотр Тогда
Возврат Ложь;
КонецЕсли;
Исключение
КонецПопытки;
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиИнтерактивноДоступнаяКолонкаЛкс()
// Копирует привязки между элементами форм.
//
// Параметры:
// пФорма Форма в которую копируем;
// ЭлементПриемник ЭлементУправления;
// ЭлементИсточник ЭлементУправления.
//
Процедура СкопироватьПривязкиЛкс(пФорма, ЭлементПриемник, ЭлементИсточник) Экспорт
Перем ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента;
Границы = Новый Массив;
Границы.Добавить(ГраницаЭлементаУправления.Верх);
Границы.Добавить(ГраницаЭлементаУправления.Низ);
Границы.Добавить(ГраницаЭлементаУправления.Лево);
Границы.Добавить(ГраницаЭлементаУправления.Право);
Для Каждого Граница Из Границы Цикл
ЭлементИсточник.ПолучитьПривязку( Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент,
ГраницаВторогоЭлемента);
Если ПервыйЭлемент <> Неопределено Тогда
ПервыйЭлемент = пФорма.ЭлементыФормы.Найти(ПервыйЭлемент.Имя);
Если ПервыйЭлемент = Неопределено Тогда
ПервыйЭлемент = пФорма.Панель;
КонецЕсли;
КонецЕсли;
Если ВторойЭлемент <> Неопределено Тогда
ВторойЭлемент = пФорма.ЭлементыФормы.Найти(ВторойЭлемент.Имя);
Если ВторойЭлемент = Неопределено Тогда
ВторойЭлемент = пФорма.Панель;
КонецЕсли;
КонецЕсли;
ЭлементПриемник.УстановитьПривязку(Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент,
ГраницаВторогоЭлемента);
КонецЦикла;
КонецПроцедуры // СкопироватьПривязкиЛкс()
// Заполняет форму по ее макету. Используется для динамического добавления элементов
// в типовые формы, чтобы облегчить их обновление. Макет формы, если явно не указан,
// ищется среди форм объекта метаданных формы по имени "Лкс"+<ИмяФормы>+"Макет".
// Для измененных элементов в макете к имени следует добавлять через "_" суффиксы
// в соответствии с изменениями: "Привязка", "Размер", "Позиция", "Внутри" (для коллекций).
// Следует вызывать в обработчике ПередОткрытием формы.
// Ограничения.
// 1. Без явного указания макета работает только для основной формы объекта.
// 2. Нельзя добавлять элементы в панели и поля табличного документа, т.к. у элемента нельзя
// определить родителя.
// 3. Нельзя, чтобы форма и макет имели разные размеры. Обрабатываеся.
// 4. Нельзя добавлять и изменять элементы, привязанные косвенно к низу формы.
// 5. Иногда элементы, привязанные косвенно к правой границе формы неверно располагаются.
// 6. Нельзя, чтобы оригинальные имена измененных элементов включали "_". Обрабатывается.
//
// Параметры:
// пФорма Форма которую настраиваем;
// *пМакет Форма - макет, по которому настраиваем.
//
Процедура НастроитьФормуПоМакетуЛкс(пФорма, пМакетФормы) Экспорт
МакетФормы = пМакетФормы;
СоответствиеПривязки = Новый Соответствие;
Если Ложь
Или пФорма.Высота <> МакетФормы.Высота
Или пФорма.Ширина <> МакетФормы.Ширина
Тогда
Сообщить("Не соответствие размеров формы при заполнении по макету",
СтатусСообщения.Важное);
КонецЕсли;
//ЗаполнитьЗначенияСвойств(пФорма, МакетФормы, , "ДокументОбъект, Данные, ЭтотОбъект, Панель, ЭлементыФормы");
//ЗаполнитьЗначенияСвойств(пФорма.Панель, МакетФормы.Панель, , "Данные");
ЭлементыФормы = пФорма.ЭлементыФормы;
Для Каждого ЭлементМакета Из МакетФормы.ЭлементыФормы Цикл
ИмяЭлемента = ЭлементМакета.Имя;
ЭлементФормы = ЭлементыФормы.Добавить(ТипЗнч(ЭлементМакета), ИмяЭлемента, Ложь, пФорма.Панель);
Если ТипЗнч(ЭлементМакета) = Тип("КоманднаяПанель") Тогда
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, Кнопки, ИсточникДействий");
Если ЭлементМакета.ИсточникДействий = пМакетФормы Тогда
ЭлементФормы.ИсточникДействий = пФорма;
КонецЕсли;
ИначеЕсли ТипЗнч(ЭлементМакета) = Тип("ТабличноеПоле") Тогда
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, ТекущаяСтрока");
Иначе
ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные");
КонецЕсли;
СоответствиеПривязки.Вставить(ЭлементФормы, ЭлементМакета);
КонецЦикла;
// Установи новые привязки
Для Каждого Привязка Из СоответствиеПривязки Цикл
ЭлементФормы = Привязка.Ключ;
ЭлементМакета = Привязка.Значение;
СкопироватьПривязкиЛкс(пФорма, ЭлементФормы, ЭлементМакета);
КонецЦикла;
КонецПроцедуры // НастроитьФормуПоМакетуЛкс()
// Изменяет свернутость всех строк табличного поля дерева значений.
//
// Параметры:
// ДЗ ТабличноеПоле связанное с деревом значений и включенным режимом Дерево;
// Свернуть Булево, *Истина - новое значение свернутости.
//
Процедура ДеревоЗначенийСвернутьЛкс(ДЗ, Свернуть = Ложь, Строки = Неопределено) Экспорт
Если Свернуть Тогда
ПредставлениеПроцесса = "Сворачиваем строки дерева";
Иначе
ПредставлениеПроцесса = "Разворачиваем строки дерева";
КонецЕсли;
Если Строки = Неопределено Тогда
Строки = ДЗ.Значение.Строки;
КонецЕсли;
Индикатор = ПолучитьИндикаторПроцессаЛкс(Строки.Количество(), ПредставлениеПроцесса);
Для Каждого СтрокаДерева Из Строки Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если Истина
И Свернуть
И ДЗ.Развернут(СтрокаДерева)
Тогда
ДЗ.Свернуть(СтрокаДерева);
ИначеЕсли Истина
И Не Свернуть
И Не ДЗ.Развернут(СтрокаДерева)
Тогда
ДЗ.Развернуть(СтрокаДерева, Истина);
КонецЕсли;
//ДеревоЗначенийСвернутьЛкс(ДЗ, Свернуть, СтрокаДерева.Строки, Индикатор);
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс(Индикатор);
КонецПроцедуры
Процедура ДеревоКонсолиПроверкаПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки) Экспорт
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ЗначениеПеретаскивания.Свойство("Тип") Тогда
Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда
ТекущийРодитель = Строка;
Пока ТекущийРодитель <> Неопределено Цикл
Если ТекущийРодитель = ЗначениеПеретаскивания.Значение Тогда
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.НеОбрабатывать;
Возврат;
КонецЕсли;
ТекущийРодитель = ТекущийРодитель.Родитель;
КонецЦикла;
СтандартнаяОбработка = Ложь;
ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.Копирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДеревоКонсолиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки, ИмяПоляНаименования) Экспорт
Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
Если ЗначениеПеретаскивания.Свойство("Тип") Тогда
Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда
СтандартнаяОбработка = Ложь;
Если Строка <> Неопределено Тогда
РодительскаяСтрока = Строка;
Иначе
РодительскаяСтрока = Элемент.Значение;
КонецЕсли;
НоваяСтрокаЗапросов = РодительскаяСтрока.Строки.Добавить();
СкопироватьСтрокиДереваЛкс(ЗначениеПеретаскивания.Значение, НоваяСтрокаЗапросов);
Если ЗначениеПеретаскивания.Значение.Родитель = НоваяСтрокаЗапросов.Родитель Тогда
НоваяСтрокаЗапросов[ИмяПоляНаименования] = ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(РодительскаяСтрока.Строки,
ЗначениеПеретаскивания.Значение[ИмяПоляНаименования], ИмяПоляНаименования, Ложь);
КонецЕсли;
Элемент.ТекущаяСтрока = НоваяСтрокаЗапросов;
Если ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда
РодительСтроки = ЗначениеПеретаскивания.Значение.Родитель;
Если РодительСтроки = Неопределено Тогда
РодительСтроки = Элемент.Значение;
Если ЗначениеПеретаскивания.Значение.Владелец() <> РодительСтроки Тогда
// Строка другой формы. Не будем ее удалять
РодительСтроки = Неопределено;
КонецЕсли;
КонецЕсли;
Если РодительСтроки <> Неопределено Тогда
РодительСтроки.Строки.Удалить(ЗначениеПеретаскивания.Значение);
КонецЕсли;
КонецЕсли;
Если Элемент.ИзменяетДанные Тогда
ЭтаФорма.Модифицированность = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ДеревоКонсолиНачалоПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, Выполнение, ИмяТипаСроки) Экспорт
Элемент.ТекущаяСтрока = Элемент.ТекущаяСтрока; // Для сохранения изменений в строке
ЗначениеПеретаскивания = Новый Структура("Тип, Значение", ИмяТипаСроки, Элемент.ТекущаяСтрока);
ПараметрыПеретаскивания.Значение = ЗначениеПеретаскивания;
КонецПроцедуры
Процедура СкопироватьСтрокиДереваЛкс(СтрокаИсточник, СтрокаПриемник, СтопСтрока = Неопределено) Экспорт
Если СтопСтрока = Неопределено Тогда
Если СтрокаПриемник.Родитель <> Неопределено Тогда
СтопСтрока = СтрокаПриемник.Родитель;
КонецЕсли;
КонецЕсли;
Дерево = СтрокаПриемник.Владелец();
Для Каждого Колонка Из Дерево.Колонки Цикл
СтрокаПриемник[Колонка.Имя] = ПолучитьКопиюОбъектаЛкс(СтрокаИсточник[Колонка.Имя]);
КонецЦикла;
Для Каждого Строка Из СтрокаИсточник.Строки Цикл
Если Строка = СтопСтрока Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
СкопироватьСтрокиДереваЛкс(Строка, НоваяСтрока, СтопСтрока);
КонецЦикла;
КонецПроцедуры
Процедура ИзменитьСвернутостьЛкс(Видимость, ГлавныйЭлемент, Разделитель, Панель, Направление, ПодчиненныйЭлемент = Неопределено,
ПропорциональныйРазмер = Истина) Экспорт
Если Разделитель = Неопределено Тогда
Разделитель = ГлавныйЭлемент;
КонецЕсли;
Если ТипЗнч(Разделитель) = Тип("Разделитель") Тогда
Если Разделитель.Ориентация = Ориентация.Авто Тогда
// возможно это касается только свертки вправо
Сообщить("Корректная работа свертки с разделителем """ + Разделитель.Имя + """ с ориентацией Авто невозможна из-за ошибки платформы",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
//ПервыйЭлемент = 0;
//ГраницаПервогоЭлемента = 0;
//ВторойЭлемент = 0;
//ГраницаВторогоЭлемента = 0;
Если СтрокиРавныЛкс(Направление, "лево") Тогда
Если Видимость Тогда
// откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель,
ГраницаЭлементаУправления.Право);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево);
КонецЕсли;
//Разделитель.Ширина = ШиринаРазделителя;
Иначе
// скроем
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Лево;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Лево;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "право") Тогда
Если Видимость Тогда
// откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель,
ГраницаЭлементаУправления.Право);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право);
КонецЕсли;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право);
//Разделитель.Ширина = ШиринаРазделителя;
КонецЕсли;
Иначе
// Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Право;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Право;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "низ") Тогда
Если Видимость Тогда
// Откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель,
ГраницаЭлементаУправления.Низ);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
//Разделитель.Высота = ШиринаРазделителя;
Иначе // Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Низ;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Низ;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх);
КонецЕсли;
КонецЕсли;
ИначеЕсли СтрокиРавныЛкс(Направление, "верх") Тогда
Если Видимость Тогда
// Откроем
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх);
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет;
Если Разделитель <> ГлавныйЭлемент Тогда
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет;
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ);
Если ПропорциональныйРазмер Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель,
ГраницаЭлементаУправления.Низ);
Иначе
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ);
КонецЕсли;
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх);
//Разделитель.Высота = ШиринаРазделителя;
КонецЕсли;
Иначе // Скроем
Если Разделитель <> ГлавныйЭлемент Тогда
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ);
ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ);
Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ);
ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Верх;
КонецЕсли;
Разделитель.Свертка = РежимСверткиЭлементаУправления.Верх;
Если ПодчиненныйЭлемент <> Неопределено Тогда
ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ИзменитьСвернутостьЛкс()
Процедура УстановитьТекстСОткатомЛкс(ПолеТекста, Текст) Экспорт
СтарыйТекст = ПолеТекста.ПолучитьТекст();
ПолеТекста.УстановитьГраницыВыделения(1, СтрДлина(СтарыйТекст) + 1);
ПолеТекста.ВыделенныйТекст = Текст;
КонецПроцедуры // УстановитьТекстСОткатомЛкс()
// <Описание процедуры>
//
// Параметры:
// Ссылка Ссылка, КлючЗаписи, КонстантаМенеджер;
// ПолноеИмя - Строка - полное имя метаданных для константы.
//
Процедура ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс(Ссылка, ПолноеИмя = "") Экспорт
Если ЛиКлючЗаписиРегистраЛкс(Ссылка) Тогда
ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка));
ПолноеИмя = ОбъектМетаданных.ПолноеИмя();
ФормаСписка = ПолучитьФормуСпискаЛкс(ОбъектМетаданных.ПолноеИмя(),,,,,, Ссылка);
ФормаСписка.Открыть();
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ПолучитьПервыйФрагментЛкс(ПолноеИмя)) Тогда
ОткрытьКонстантуВСпискеЛкс(ПолучитьПоследнийФрагментЛкс(ПолноеИмя));
Иначе
ОткрытьЗначение(Ссылка);
КонецЕсли;
КонецПроцедуры // ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс()
Процедура ОткрытьКонстантуВСпискеЛкс(ИмяКонстанты) Экспорт
ФормаСписка = ПолучитьФормуЛкс("Обработка.ирРедакторКонстант.Форма",,, ИмяКонстанты);
ФормаСписка.НачальноеЗначениеВыбора = ИмяКонстанты;
ФормаСписка.Открыть();
КонецПроцедуры
Функция ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(Знач Элемент, Текст) Экспорт
НачалоКолонки = 0; НачалоСтроки = 0; КонецКолонки = 0; КонецСтроки = 0;
Элемент.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
Элемент.Значение = Текст;
Элемент.УстановитьГраницыВыделения(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Успешна;
КонецФункции
#КонецЕсли
Процедура ЗаменитьИВыделитьВыделенныйТекстПоляЛкс(ЭтаФорма, ПолеТекстаВыражения, Знач НовыйВыделенныйТекст = "") Экспорт
Перем Граница1, Граница2, Граница3, Граница4;
Граница1 = 0; Граница2 = 0; Граница3 = 0; Граница4 = 0;
ПолеТекстаВыражения.ПолучитьГраницыВыделения(Граница1, Граница2, Граница3, Граница4);
Если Не ЗначениеЗаполнено(НовыйВыделенныйТекст) Тогда
НовыйВыделенныйТекст = ПолеТекстаВыражения.ПолучитьТекст();
Иначе
ПолеТекстаВыражения.ВыделенныйТекст = НовыйВыделенныйТекст;
КонецЕсли;
ПолеТекстаВыражения.УстановитьГраницыВыделения(Граница2, Граница2 + СтрДлина(НовыйВыделенныйТекст));
ЭтаФорма.ТекущийЭлемент = ПолеТекстаВыражения;
КонецПроцедуры
// Основным элементом страницы считается одноименный с ней элемент формы.
//
Процедура ОбновитьЗаголовкиСтраницПанелейЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
ЭлементыФормы = ЭтаФорма.Элементы;
Иначе
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
КонецЕсли;
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
Если Истина
#Если Клиент Тогда
И ТипЗнч(ЭлементФормы) <> Тип("Панель")
#КонецЕсли
И Не (Истина
И ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы")
И ЭлементФормы.Вид = ВидГруппыФормы.Страницы)
Тогда
Продолжить;
КонецЕсли;
ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭлементФормы);
КонецЦикла;
КонецПроцедуры // ОбновитьЗаголовкиСтраницПанелейЛкс()
Процедура ОбновитьЗаголовокФормыСОткрытымФайломЛкс(Знач ЭтаФорма, Знач ИмяОткрытогоФайла = Неопределено, Знач АвтосохранениеТекущегоФайла = Ложь) Экспорт
Если ИмяОткрытогоФайла <> "" Тогда
НоваяСтрока = "";
Если АвтосохранениеТекущегоФайла Тогда
НоваяСтрока = " <Автосохранение> ";
КонецЕсли;
НоваяСтрока = НоваяСтрока + ИмяОткрытогоФайла;
Иначе
НоваяСтрока = "<Новый файл>";
КонецЕсли;
ОбновитьТекстПослеМаркераВСтрокеЛкс(ЭтаФорма.Заголовок, , НоваяСтрока, ": ");
КонецПроцедуры // мУстановитьЗаголовокФормы()
Функция ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, Панель) Экспорт
ТабличноеПолеСтраниц = ЭлементыФормы.Найти("Страницы" + Панель.Имя);
Если ТабличноеПолеСтраниц <> Неопределено Тогда
ТаблицаСтраниц = ДанныеЭлементаФормыЛкс(ТабличноеПолеСтраниц);
КонецЕсли;
ОбщееКоличество = 0;
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
Если ТипЗнч(Панель) = Тип("ГруппаФормы") Тогда
Страницы = Панель.ПодчиненныеЭлементы;
Иначе
Страницы = Панель.Страницы;
КонецЕсли;
Для Каждого Страница Из Страницы Цикл
ИмяСтраницы = Страница.Имя;
Если ИмяСтраницы = "" Тогда // Служебная страница. Появляется после очистки страниц.
Продолжить;
КонецЕсли;
Если Найти("." + ИмяСтраницы, ".Страница") = 1 Тогда
ИмяСтраницы = СтрЗаменить("." + ИмяСтраницы, ".Страница", "");
КонецЕсли;
ЭУ = ЭлементыФормы.Найти(ИмяСтраницы);
Если ЭУ = Неопределено Тогда
Продолжить;
КонецЕсли;
ЗначениеСтраницы = Неопределено;
#Если Клиент Тогда
Если ТипЗнч(Страница) = Тип("СтраницаПанели") Тогда
ЗначениеСтраницы = Страница.Значение;
КонецЕсли;
#КонецЕсли
Если Ложь
Или НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя) <> Неопределено
Или (Истина
И ТипЗнч(ЗначениеСтраницы) = Тип("Структура")
И ЗначениеСтраницы.Свойство("Рассчитано")
И Не ЗначениеСтраницы.Рассчитано)
Тогда
Количество = "-";
Иначе
Суффикс = "";
Количество = Неопределено;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ЭУ) = Тип("ТабличноеПоле")
#КонецЕсли
Или ТипЗнч(ЭУ) = Тип("ТаблицаФормы")
Тогда
ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ЭУ);
Если ТипЗнч(ЗначениеЭУ) = Тип("ДеревоЗначений") Тогда
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
ИначеЕсли ТипЗнч(ЗначениеЭУ) = Тип("ДанныеФормыДерево") Тогда
Количество = ЗначениеЭУ.ПолучитьЭлементы().Количество();
Суффикс = "*";
Иначе
Попытка
Количество = ЗначениеЭУ.Количество();
Исключение КонецПопытки;
Если Количество = Неопределено Тогда
// Компоновка
Попытка
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение КонецПопытки;
КонецЕсли;
КонецЕсли;
//Если Количество = 0 Тогда
// Попытка
// КоличествоКолонок = ЗначениеЭУ.Колонки.Количество();
// Исключение
// КоличествоКолонок = 1;
// КонецПопытки;
// Если КоличествоКолонок = 0 Тогда
// Количество = "-";
// КонецЕсли;
//КонецЕсли;
#Если Клиент Тогда
ИначеЕсли Ложь
Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокумента")
Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокументаФормы")
Тогда
Количество = ?(ЭУ.ВысотаТаблицы > 0, 1, 0);
ИначеЕсли Ложь
Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокумента")
Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокументаФормы")
Тогда
Количество = ?(ЭУ.КоличествоСтрок() > 0, 1, 0);
ИначеЕсли Ложь
Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемы")
Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемыФормы")
Тогда
Количество = ЭУ.ЭлементыГрафическойСхемы.Количество();
#КонецЕсли
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипЗнч(ЭУ) = Тип("Панель")
#КонецЕсли
Или (Истина
И ТипЗнч(ЭУ) = Тип("ГруппаФормы")
И ЭУ.Вид = ВидГруппыФормы.Страницы)
Тогда
//Количество = ЭУ.Страницы.Количество();
//Если Количество = 1 Тогда
// Если ЭУ.Страницы[0].Имя = "" Тогда
// Количество = 0;
// КонецЕсли;
//КонецЕсли;
Количество = ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭУ);
КонецЕсли;
Если ТипЗнч(Количество) = Тип("Число") Тогда
ОбщееКоличество = ОбщееКоличество + Количество;
КонецЕсли;
КонецЕсли;
Если ТаблицаСтраниц <> Неопределено Тогда
СтрокаСтраницы = ТаблицаСтраниц.НайтиСтроки(Новый Структура("ИмяСтраницы", ИмяСтраницы));
Если СтрокаСтраницы.Количество() > 0 Тогда
СтрокаСтраницы = СтрокаСтраницы[0];
СтрокаСтраницы.Количество = Количество;
СтрокаСтраницы.Непустая = СтрокаСтраницы.Количество > 0;
КонецЕсли;
КонецЕсли;
ОбновитьТекстПослеМаркераВСтрокеЛкс(Страница.Заголовок, , "" + Количество + Суффикс + ")", "(");
КонецЦикла;
Возврат ОбщееКоличество;
КонецФункции // ОбновитьЗаголовкиСтраницПанелейЛкс()
//Для Объект = Неопределено возвращает Ложь, работает только для русского и английского языков платформы
// Параметры:
// КоличествоПараметров - нужно задать заведомо большее значение, чем может быть у метода
Функция МетодРеализованЛкс(Объект, ИмяМетода) Экспорт
Если Объект = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Выражение = "Объект." + ИмяМетода + "(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)";
Попытка
Выполнить(Выражение);
Исключение
Инфо = ИнформацияОбОшибке();
Описание = Инфо.Описание;
//СообщитьИис(Описание);
КонецПопытки;
Результат = Ложь
Или Описание = "Слишком много фактических параметров"
Или Описание = "Too many actual parameters";
Возврат Результат;
КонецФункции
// Параметры:
// КоличествоПроходов - Число(Н8,0)
// КлючЗамера - Строка
// ВыдатьСообщение - Булево
//
Функция НачатьЗамерЛкс(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя;
КонецЕсли;
ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1);
СтрокаЗамера = ТаблицаЗамеров.Добавить();
СтрокаЗамера.Ключ = КлючЗамера;
#Если Клиент Тогда
СтрокаЗамера.Отладчик = ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено;
#КонецЕсли
СтрокаЗамера.КоличествоПроходов = КоличествоПроходов;
Если Ложь
Или ВыдатьСообщение
//Или СтрокаЗамера.Отладчик
Тогда
Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов;
Если СтрокаЗамера.Отладчик Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
Сообщить(Сообщение);
КонецЕсли;
СтрокаЗамера.ДатаНачала = ПолучитьТекущееВремяВМиллисекундахЛкс();
Результат = КоличествоПроходов;
Возврат Результат;
КонецФункции
// Параметры:
// КлючЗамера - Строка - По умолчанию последний замер
//
Функция КончитьЗамерЛкс(Знач КлючЗамера = "") Экспорт
ТекущееВремя = ПолучитьТекущееВремяВМиллисекундахЛкс();
ирПлатформа = ирКэш.Получить();
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
Если ТаблицаЗамеров.Количество() > 0 Тогда
СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1];
КонецЕсли;
Иначе
СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ");
КонецЕсли;
Если СтрокаЗамера = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала;
Длительность = Длительность / 1000;
Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с";
Если СтрокаЗамера.КоличествоПроходов > 1 Тогда
Среднее = Длительность / СтрокаЗамера.КоличествоПроходов;
Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с";
КонецЕсли;
Если Ложь
Или СтрокаЗамера.Отладчик
Или ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено
Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
Сообщить(Сообщение);
ТаблицаЗамеров.Удалить(СтрокаЗамера);
Результат = Длительность;
Возврат Результат;
КонецФункции
Функция ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора = Неопределено) Экспорт
ВременнныйПостроительЗапроса = Новый ПостроительЗапроса;
ВременнныйПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличноеПоле.Значение);
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Тогда
СкопироватьОтборПостроителяЛкс(ВременнныйПостроительЗапроса.Отбор, ОтборСтрок);
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ВременнныйПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ).Установить(КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
Возврат ВременнныйПостроительЗапроса;
КонецФункции
Функция ПолучитьСтруктуруВыделенияТекстаЛкс() Экспорт
Структура = Новый Структура();
Структура.Вставить("НачальнаяСтрока");
Структура.Вставить("НачальнаяКолонка");
Структура.Вставить("КонечнаяСтрока");
Структура.Вставить("КонечнаяКолонка");
Возврат Структура;
КонецФункции
Функция ПолеТекстаолучитьДиапазонВыделенияЛкс(ПолеТекста) Экспорт
СтруктуруВыделения = ПолучитьСтруктуруВыделенияТекстаЛкс();
ПолеТекста.ПолучитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка,
СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка);
Возврат СтруктуруВыделения;
КонецФункции
Функция ПолеТекста_УстановитьДиапазонВыделенияЛкс(Знач ПолеТекста, Знач СтруктуруВыделения) Экспорт
ПолеТекста.УстановитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка,
СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка);
Возврат Неопределено;
КонецФункции
// Копирует таблицу значений из исходной таблицы значений с удалением типа Null из описаний типов колонок.
// Параметры:
// ОбработатьТолькоКолонки - Строка - имена колонок разделенные запятыми
// НеОбрабатыватьКолонки - Строка - имена колонок разделенные запятыми
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Знач Таблица, ЗагружатьДанныеВНовуюТаблицу = Истина, ОбрабатыватьТолькоКолонки = "", НеОбрабатыватьКолонки = "") Экспорт
Результат = Новый ТаблицаЗначений;
НовыеКолонки = Результат.Колонки;
ИсходныеКолонки = Таблица.Колонки;
ИменаОбрабатываемыхКолонок = Новый Массив();
Если ОбрабатыватьТолькоКолонки <> "" Тогда
ИменаОбрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбрабатыватьТолькоКолонки, ",", Истина);
КонецЕсли;
ИменаНеобрабатываемыхКолонок = Новый Массив();
Если НеОбрабатыватьКолонки <> "" Тогда
ИменаНеобрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(НеОбрабатыватьКолонки, ",", Истина);
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого Колонка Из ИсходныеКолонки Цикл
Если Ложь
Или (Истина
И ОбрабатыватьТолькоКолонки <> ""
И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено)
Или (Истина
И НеОбрабатыватьКолонки <> ""
И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено)
Тогда
ОписаниеТипов = Колонка.ТипЗначения;
Иначе
ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL");
КонецЕсли;
НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого Колонка Из ИсходныеКолонки Цикл   Если Ложь   Или (Истина   И ОбрабатыватьТолькоКолонки <> ""   И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено)   Или (Истина   И НеОбрабатыватьКолонки <> ""   И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено)   Тогда   ОписаниеТипов = Колонка.ТипЗначения;   Иначе   ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL");   КонецЕсли;   НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина);   КонецЦикла;  
Если ЗагружатьДанныеВНовуюТаблицу Тогда
ЗагрузитьВТаблицуЗначенийЛкс(Таблица, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиСсылочныйОбъектМетаданных(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Истина) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Истина
И Не ДляТабличнойЧастиПроверятьРодителя
И МассивФрагментов.Количество() > 2
Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = МассивФрагментов[0];
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Возврат Истина;
ИначеЕсли Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиРегистровыйОбъектМетаданных(ОбъектМД) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
КорневойТип = МассивФрагментов[0];
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
Возврат Истина;
ИначеЕсли Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиТипВнешнегоИсточникаДанных(Метаданные) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = Метаданные.ПолноеИмя();
Иначе
ПолноеИмя = Метаданные;
КонецЕсли;
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмя);
Возврат КорневойТип = "ВнешнийИсточникДанных";
КонецФункции
Функция ПолучитьИмяТаблицыИзМетаданныхЛкс(Знач ОбъектИлиИмяМД, ЛиТаблицаИзменений = Ложь, ЛиДвиженияССубконтоДляРегистраБухгалтерии = Истина,
ТолькоРазрешенные = Ложь) Экспорт
Если ТипЗнч(ОбъектИлиИмяМД) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектИлиИмяМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектИлиИмяМД;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если ТолькоРазрешенные Тогда
Если ТипЗнч(ОбъектИлиИмяМД) = Тип("Строка") Тогда
Если Фрагменты.Количество() > 1 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]); // очень долгая операция, поэтому лучше не устанавливать флаг ТолькоРазрешенные
Иначе
//ОбъектМД = Метаданные[Фрагменты[0]];
ОбъектМД = Неопределено;
КонецЕсли;
Иначе
ОбъектМД = ОбъектИлиИмяМД;
КонецЕсли;
Если Истина
И ОбъектМД <> Неопределено
И Не ПравоДоступа("Чтение", ОбъектМД)
Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Истина
И Фрагменты[0] = "Константа"
И Фрагменты.Количество() = 2
И Не ЛиТаблицаИзменений
Тогда
Если Не ирКэш.ИндивидуальныеТаблицыКонстантДоступныЛкс() Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс("Константы");
КонецЕсли;
КонецЕсли;
Если Фрагменты.Количество() = 4 Тогда
Если Ложь
Или СтрокиРавныЛкс(Фрагменты[2], "ТабличнаяЧасть")
Или СтрокиРавныЛкс(Фрагменты[2], "Перерасчет")
//Или СтрокиРавныЛкс(Фрагменты[2], "Таблица")
Тогда
Фрагменты.Удалить(2);
КонецЕсли;
КонецЕсли;
ИмяТаблицы = ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
Если Истина
И ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмя)
И Не ЛиТаблицаИзменений
И ЛиДвиженияССубконтоДляРегистраБухгалтерии
Тогда
ИмяТаблицы = ИмяТаблицы + ".ДвиженияССубконто";
КонецЕсли;
Если ЛиТаблицаИзменений Тогда
ИмяТаблицы = ИмяТаблицы + ".Изменения";
КонецЕсли;
Возврат ИмяТаблицы;
КонецФункции // ПолучитьИмяТаблицыИзМетаданныхЛкс()
Функция ПолучитьОпределениеТаблицыБДДляИЗЛкс(ИмяТаблицы) Экспорт
Результат = ИмяТаблицы;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы);
Если ТипТаблицы = "ДвиженияССубконто" Тогда
Результат = Результат + "(,, {Регистратор.*, НомерСтроки, Активность})";
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, выхМакетныйОбъект, выхТекущаяГруппаТипаМетаданных = Неопределено, выхКлючевыеПоля = Неопределено, ОбъектыНаСервере = Неопределено) Экспорт
выхКлючевыеПоля = Новый Массив;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы,,,, ОбъектыНаСервере);
выхТекущаяГруппаТипаМетаданных = "Ссылочный";
выхКлючевыеПоля.Добавить("Ссылка");
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицы, ОбъектыНаСервере);
выхТекущаяГруппаТипаМетаданных = "Регистр";
Для Каждого ЭлементОтбора Из выхМакетныйОбъект.Методы.Отбор Цикл
выхКлючевыеПоля.Добавить(ЭлементОтбора.ПутьКДанным);
КонецЦикла;
ИначеЕсли ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "МенеджерЗначения."));
выхТекущаяГруппаТипаМетаданных = "Константа";
Иначе
Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
выхТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица";
КонецЕсли;
//ВызватьИсключение "Макетный объект данных для таблицы типа " + ТипТаблицы + " не допустим";
КонецЕсли;
КонецПроцедуры
Функция ОписаниеТиповОбъектаИлиСтрокиБДПоИменамТаблицЛкс(Знач МассивИлиИмяТаблицыБД, Знач НуженТипОбъекта, РежимОбходаДанных = "Строки", Знач ТипТаблицы = Неопределено, выхПолноеИмяТаблицы = Неопределено) Экспорт
МассивИменТаблицБД = Новый Массив();
Если ТипЗнч(МассивИлиИмяТаблицыБД) = Тип("Строка") Тогда
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(МассивИлиИмяТаблицыБД);
МассивИменТаблицБД.Добавить(МассивИлиИмяТаблицыБД);
Иначе
МассивИменТаблицБД = МассивИлиИмяТаблицыБД;
КонецЕсли;
МассивТипов = Новый Массив();
Если Ложь
Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Или ТипТаблицы = "Внешняя"
Тогда
Если РежимОбходаДанных = "КлючиОбъектов" Тогда
РасширениеТипа = "Ссылка";
Иначе
РасширениеТипа = "Объект";
КонецЕсли;
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, РасширениеТипа);
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли Ложь
Или ирОбщий.ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если РежимОбходаДанных = "КлючиОбъектов" Тогда
РасширениеТипа = "Ссылка";
Иначе
РасширениеТипа = "Объект";
КонецЕсли;
Поля = ирОбщий.ПолучитьПоляТаблицыБДЛкс(МассивИменТаблицБД[0]);
Поле = Поля.Найти("Ссылка", "Имя");
Для Каждого ТипЗначения Из Поле.ТипЗначения.Типы() Цикл
ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Метаданные.НайтиПоТипу(ТипЗначения), РасширениеТипа);
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ТипТаблицы = "Точки" Тогда
РасширениеТипа = "ТочкаМаршрутаБизнесПроцессаСсылка";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, "БизнесПроцесс.", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(ТипТаблицы) Тогда
РасширениеТипа = "Ссылка";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда
РасширениеТипа = "МенеджерЗначения";
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + ".");
МассивТипов.Добавить(Тип(ИмяТипа));
КонецЦикла;
ИначеЕсли ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяТаблицыБД);
выхПолноеИмяТаблицы = МассивФрагментов[0] + "." + МассивФрагментов[1];
Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда
ИмяТипа = МассивФрагментов[0] + ТипТаблицы + "Строка." + МассивФрагментов[1];
Если ТипТаблицы = "ТабличнаяЧасть" Тогда
ИмяТипа = ИмяТипа + "." + МассивФрагментов[2];
выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + МассивФрагментов[2];
Иначе
выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + ТипТаблицы;
КонецЕсли;
МассивТипов.Добавить(Тип(ИмяТипа));
ИначеЕсли РежимОбходаДанных = "КлючиОбъектов" Тогда
МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Ссылка." + МассивФрагментов[1]));
Иначе
МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Объект." + МассивФрагментов[1]));
КонецЕсли;
КонецЦикла;
ИначеЕсли Ложь
Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы)
Тогда
Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда
РасширениеТипа = "Запись";
Иначе
РасширениеТипа = "НаборЗаписей";
КонецЕсли;
Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл
ТипЭлементаДанных = Тип(ирОбщий.ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяТаблицыБД, РасширениеТипа));
МассивТипов.Добавить(ТипЭлементаДанных);
КонецЦикла;
Иначе
ВызватьИсключение "Неподдерживаемый тип таблицы """ + ТипТаблицы + """";
КонецЕсли;
Результат = Новый ОписаниеТипов(МассивТипов);
Возврат Результат;
КонецФункции
Функция ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Результат = Истина
И Фрагменты.Количество() = 2
И (Ложь
Или Фрагменты[0] = "AccountingRegister"
Или Фрагменты[0] = "РегистрБухгалтерии");
Возврат Результат;
КонецФункции
// Создает тип из метаданных.
//
// Параметры:
// Метаданные ОбъектМетаданных;
// *Расширение - Строка, "Ссылка" - расширение типа.
//
// Возвращаемое значение:
// Тип.
//
Функция ПолучитьТипИзМетаданныхЛкс(ОбъектМД, Расширение = "Ссылка") Экспорт
Возврат Тип(ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД, Расширение));
КонецФункции // ПолучитьТипИзМетаданных()
Функция ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Экспорт
ЭлементСостава = ОбщийРеквизит.Состав.Найти(ОбъектМетаданных);
Результат = Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Использовать
Или (Истина
И ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Авто
И ОбщийРеквизит.АвтоИспользование = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита.Использовать));
Возврат Результат;
КонецФункции
Функция ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Знач Алгоритм) Экспорт
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = "" + Алгоритм;
Если Найти(Алгоритм, "-") > 0 Тогда
// Передан GUID
Алгоритм = Справочники.ирАлгоритмы.ПолучитьСсылку(Новый УникальныйИдентификатор(Алгоритм));
Иначе
// Передано имя алгоритма
Попытка
Алгоритм = ПредопределенноеЗначение("Справочник.ирАлгоритмы." + Алгоритм);
Исключение
КонецПопытки;
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = Справочники.ирАлгоритмы.НайтиПоНаименованию(Алгоритм, Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Алгоритм) Тогда
ВызватьИсключение "Алгоритм по идентификатору """ + Алгоритм + """ не найден";
КонецЕсли;
Возврат Алгоритм.ПолучитьОбъект();
КонецФункции
//Если объекту не назначена ссылка, назначает эту ссылку
Функция ПолучитьТочнуюСсылкуОбъектаЛкс(ОбъектБД) Экспорт
Ссылка = ОбъектБД.Ссылка;
Если Ссылка.Пустая() Тогда
Ссылка = ОбъектБД.ПолучитьСсылкуНового();
Если Ссылка.Пустая() Тогда
Ссылка = XMLЗначение(ТипЗнч(Ссылка), "" + Новый УникальныйИдентификатор);
ОбъектБД.УстановитьСсылкуНового(Ссылка);
КонецЕсли;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(Знач Текст) Экспорт
Текст = Символы.ПС + Текст;
Текст = СтрЗаменить(Текст, Символы.ПС, Символы.ПС + "|");
Текст = СтрЗаменить(Текст, """", """""");
Текст = """" + Текст + """";
Возврат Текст;
КонецФункции // ПолучитьСтроковыйЛитералИзМногострочногоТекста()
Функция ПолучитьВсеСтрокиДереваЗначенийЛкс(СтрокаИлиДеревоЗначений) Экспорт
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ДеревоЗначений = СтрокаИлиДеревоЗначений.Владелец();
Иначе
ДеревоЗначений = СтрокаИлиДеревоЗначений;
КонецЕсли;
Идентификатор = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
ДеревоЗначений.Колонки.Добавить(Идентификатор);
ВсеСтроки = СтрокаИлиДеревоЗначений.Строки.НайтиСтроки(Новый Структура(Идентификатор,), Истина);
ДеревоЗначений.Колонки.Удалить(Идентификатор);
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ВсеСтроки.Добавить(СтрокаИлиДеревоЗначений);
КонецЕсли;
Возврат ВсеСтроки;
КонецФункции // ПолучитьВсеСтрокиДереваЗначений()
Функция СериализацииРавныЛкс(Таблица1, Таблица2) Экспорт
Хмл1 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица1);
Хмл2 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица2);
Возврат (Хмл1 = Хмл2);
КонецФункции
// ВариантОбрезания - 1
// ВариантОбрезания - 2
Функция ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке = Неопределено, ВариантОбрезания = 2) Экспорт
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
Если ВариантОбрезания = 1 Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ИначеЕсли Истина
И ВариантОбрезания = 2
И ИнформацияОбОшибке.Причина <> Неопределено
Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
Иначе
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// МаксимальнаяГлубинаПричины - на сколько уровней вниз надо опуститься, пока есть вложенная причина
Функция ПредставлениеИнформацииОбОшибкеЛкс(Знач ИнформацияОбОшибке, Знач МаксимальнаяГлубинаПричины = 0, УбратьСтрокуКодаСПервогоУровня = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = "";
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
Для Счетчик = 1 По МаксимальнаяГлубинаПричины Цикл
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
#Если Сервер И Не Сервер Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Если УбратьСтрокуКодаСПервогоУровня Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
Иначе
// Такое может случаться в свойстве ИнформацияОбОшибке объекта ФоновоеЗадание из-за ошибки платформы
ОписаниеОшибки = "Описание ошибки отсутствует";
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// Первая строка табличного документа содержит заголовки
Функция ПолучитьТаблицуИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок = Истина, ДлинаСтрокиТипаКолонки = 150,
ВычислятьНетипизированныеЗначения = Ложь, ЛиВтораяСтрокаСодержитТипыЗначений = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент
#КонецЕсли
ТаблицаПриемник = Новый ТаблицаЗначений;
НачальнаяСтрока = 1;
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
ТипизированныеКолонки = Новый Соответствие;
Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
ИмяКолонки = ТабличныйДокумент.Область(1, Счетчик).Текст;
Если Найти(ИмяКолонки, ".") > 0 Тогда
Если Найти(ИмяКолонки, "_") > 0 Тогда
ВызватьИсключение "В именах колонок макета не допускается использование одновременно ""_"" и "".""";
КонецЕсли;
ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_");
КонецЕсли;
Иначе
ИмяКолонки = "Колонка" + Счетчик;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
ИменаТипов = ТабличныйДокумент.Область(2, Счетчик).Текст;
Иначе
ИменаТипов = "";
КонецЕсли;
Если ЗначениеЗаполнено(ИменаТипов) Тогда
ТипизированныеКолонки[Счетчик] = 1;
КонецЕсли;
ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов));
КонецЦикла;
// Цикл перебора строк табличного документа
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
//Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ВысотаТаблицы);
Для НомерСтроки = НачальнаяСтрока По ВысотаТаблицы Цикл
// Добавление строки результирующей таблицы
НоваяСтрокаТЗ = ТаблицаПриемник.Добавить();
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ТекстЯчейки = Область.Текст;
Если Не ЗначениеЗаполнено(ТекстЯчейки) Тогда
Поддокумент = ТабличныйДокумент.ПолучитьОбласть(НомерСтроки, НомерКолонки);
Если Поддокумент.Рисунки.Количество() > 0 Тогда
ТекстЯчейки = Поддокумент.Рисунки[0].Картинка;
КонецЕсли;
КонецЕсли;
ЗначениеЯчейки = Неопределено;
Если ТипизированныеКолонки[НомерКолонки] <> Неопределено Тогда
ОписаниеТиповКолонки = ТаблицаПриемник.Колонки[НомерКолонки - 1].ТипЗначения;
Если ОписаниеТиповКолонки.СодержитТип(Тип("ОписаниеТипов")) Тогда
Попытка
ЗначениеЯчейки = Новый ОписаниеТипов(ТекстЯчейки);
Исключение
КонецПопытки;
ИначеЕсли ОписаниеТиповКолонки.СодержитТип(Тип("Тип")) Тогда
Попытка
ЗначениеЯчейки = Тип(ТекстЯчейки);
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ВычислятьНетипизированныеЗначения
Или (Истина
И ТипизированныеКолонки[НомерКолонки] <> Неопределено
И ЗначениеЯчейки = Неопределено)
Тогда
Попытка
ЗначениеЯчейки = Вычислить(ТекстЯчейки);
Исключение
КонецПопытки;
КонецЕсли;
Если ЗначениеЯчейки = Неопределено Тогда
ЗначениеЯчейки = ТекстЯчейки;
КонецЕсли;
НоваяСтрокаТЗ[НомерКолонки - 1] = ЗначениеЯчейки;
КонецЦикла;
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
Процедура УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки, СхемаКомпоновки) Экспорт
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
#Если Сервер И Не Сервер Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
#КонецЕсли
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
Для НомерСтроки = 1 По ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
Если ТипЗнч(Область.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Для каждого ЗначениеПоля Из ДанныеРасшифровки.Элементы[Область.Расшифровка].ПолучитьПоля() Цикл
Если Не ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Область.Расшифровка = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьИдентификаторТипаЛкс(Тип) Экспорт
Результат = ПолучитьСтрокуМеждуМаркерамиЛкс("" + ЗначениеВСтрокуВнутр(Тип), ",", "}", Ложь);
Возврат Результат;
КонецФункции
Функция ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(Знач ТекстПрограммы = "") Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
#Если Клиент Тогда
ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс();
#Иначе
ВызватьИсключение "Получение текста из буфера обмена возможно только на клиенте";
#КонецЕсли
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой");
#Если Сервер И Не Сервер Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
ПолеВстроенногоЯзыка.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина, ТекстПрограммы);
СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический"));
//СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова", "Свойство"));
Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл
Параметры.Вставить(СтрокаПеременной.Слово);
КонецЦикла;
Возврат Параметры;
КонецФункции
// КолонкиНабора - КоллекцияКолонокДереваЗначений, КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокРезультатаЗапроса
Функция СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(Знач СхемаКомпоновкиДанных, Знач КолонкиНабора, Знач ИмяНабора = "Основной", Знач СоздаватьПапкиПолей = Ложь,
СоздаватьРесурсыЧисловыхПолей = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Результат = СхемаКомпоновкиДанных.НаборыДанных.Найти(ИмяНабора);
Если Результат = Неопределено Тогда
Результат = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
КонецЕсли;
Результат.Имя = ИмяНабора;
Результат.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя;
Результат.ИмяОбъекта = ИмяНабора;
Для Каждого ЭлементМетаданных Из КолонкиНабора Цикл
Если Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаДереваЗначений")
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаТаблицыЗначений")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаРезультатаЗапроса")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ИмяПоля;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ПолеНастройки")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Представление;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
ИмяПоля = "" + ЭлементМетаданных.Поле;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
Иначе
Продолжить;
КонецЕсли;
Поле = Результат.Поля.Найти(ИмяПоля);
Если Поле = Неопределено Тогда
Поле = Результат.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПутьКДанным = ИмяПоля;
Если СоздаватьПапкиПолей Тогда
ПутьКДанным = Результат.Имя + "." + ПутьКДанным;
КонецЕсли;
Поле.ПутьКДанным = ПутьКДанным;
Поле.Поле = ИмяПоля;
Поле.Заголовок = ЗаголовокПоля;
Поле.ТипЗначения = ЭлементМетаданных.ТипЗначения;
Если ЭлементМетаданных.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Поле.ВыражениеПредставления = "ирОбщий.РасширенноеПредставлениеЗначенияЛкс(" + ИмяПоля + ")";
КонецЕсли;
Если Истина
И СоздаватьРесурсыЧисловыхПолей
И Поле.ТипЗначения.СодержитТип(Тип("Число"))
Тогда
Ресурс = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
Ресурс.Выражение = "Сумма(" + ИмяПоля + ")";
Ресурс.ПутьКДанным = ИмяПоля;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьПараметрыСхемыПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
ОписанияПараметров = Запрос.НайтиПараметры(); // Здесь могут быть ложные ошибки синтаксического контроля
Для Каждого ОписаниеПараметра Из ОписанияПараметров Цикл
Если Не Запрос.Параметры.Свойство(ОписаниеПараметра.Имя) Тогда
Запрос.Параметры.Вставить(ОписаниеПараметра.Имя);
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из Запрос.Параметры Цикл
ЗначениеПараметра = КлючИЗначение.Значение;
Если ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(ЗначениеПараметра);
ЗначениеПараметра = Список;
КонецЕсли;
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти(КлючИЗначение.Ключ);
Если ПараметрСхемы = Неопределено Тогда
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Добавить();
КонецЕсли;
ПараметрСхемы.Имя = КлючИЗначение.Ключ;
ПараметрСхемы.ДоступенСписокЗначений = ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений");
//Тип надо задавать, чтобы значение корректно записалось. Иначе ссылки будут преобразованы к строке.
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(КлючИЗначение.Значение));
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ПараметрСхемы.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЕсли;
ПараметрСхемы.Значение = ЗначениеПараметра;
КонецЦикла;
КонецПроцедуры
Функция СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос, Знач ИмяНабора = "Основной", Представления = Неопределено) Экспорт
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновкиДанных.НаборыДанных, СхемаКомпоновкиДанных.ИсточникиДанных[0]);
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = Запрос.Текст;
Если Представления <> Неопределено Тогда
Для Каждого КлючИЗначение Из Представления Цикл
ПолеНабора = НаборДанных.Поля.Найти(КлючИЗначение.Ключ);
Если ПолеНабора = Неопределено Тогда
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПолеНабора.Поле = КлючИЗначение.Ключ;
ПолеНабора.ПутьКДанным = КлючИЗначение.Ключ;
ПолеНабора.Заголовок = КлючИЗначение.Значение;
КонецЦикла;
КонецЕсли;
ЗаполнитьПараметрыСхемыПоЗапросуЛкс(СхемаКомпоновкиДанных, Запрос);
Возврат НаборДанных;
КонецФункции
// Представления - Структура
Функция СоздатьСхемуКомпоновкиПоЗапросу(Знач ЗапросИлиТекст, ИмяНабораДанных = "НаборДанных1", Представления = Неопределено) Экспорт
Схема = Новый СхемаКомпоновкиДанных;
ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
Если ТипЗнч(ЗапросИлиТекст) = Тип("Строка") Тогда
Запрос = Новый Запрос;
Запрос.Текст = ЗапросИлиТекст;
Иначе
Запрос = ЗапросИлиТекст;
КонецЕсли;
СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Схема, Запрос, ИмяНабораДанных, Представления);
Возврат Схема;
КонецФункции
Функция ВыбратьВсеДоступныеПоляКомпоновки(Знач СхемаКомпоновки, Знач НастройкаКомпоновки = Неопределено) Экспорт
Если НастройкаКомпоновки = Неопределено Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
КонецЕсли;
КомпоновщикНастройки = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастройки.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки));
КомпоновщикНастройки.ЗагрузитьНастройки(НастройкаКомпоновки);
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Иначе
ЭлементСтруктуры = НастройкаКомпоновки.Структура[0];
КонецЕсли;
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Для Каждого ДоступноеПоле Из КомпоновщикНастройки.Настройки.ДоступныеПоляВыбора.Элементы Цикл
// Чтобы пропустить системные папки
Если Не ДоступноеПоле.Папка Тогда
НовоеВыбранноеПоле = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле;
НовоеВыбранноеПоле.Использование = Истина;
КонецЕсли;
КонецЦикла;
Возврат НастройкаКомпоновки;
КонецФункции
Функция ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(Знач ПолноеИмяИлиОбъектМД, ИмяНабораДанных = "НаборДанных1", ДобавитьАвтополеКоличествоСтрок = Истина,
ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда
ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
Иначе
ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
Схема = ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность, ДобавитьАвтополеКоличествоСтрок, ИндексПараметраПериодичность, ПсевдонимТаблицы,
ИменаВместоПредставлений);
Возврат Схема;
КонецФункции
Функция ПолучитьПоляТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
Запрос = Новый Запрос;
Запрос.Текст = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность) + " ГДЕ ЛОЖЬ";
Попытка
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Исключение
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = Запрос.Текст;
Попытка
ПостроительЗапроса.ЗаполнитьНастройки(); // Долгий способ пробуем только если быстрый не удался
Исключение
Если ВызыватьИсключениеПриОтсутствииПрав Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
ТаблицаРезультата.Колонки.Добавить(ДоступноеПоле.ПутьКДанным, ДоступноеПоле.ТипЗначения);
КонецЦикла;
КонецПопытки;
Если ТаблицаРезультата <> Неопределено Тогда
ПоляТаблицы = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаРезультата).Колонки;
КонецЕсли;
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя");
Результат.Колонки.Добавить("ТипЗначения");
Результат.Колонки.Добавить("Метаданные");
Результат.Колонки.Добавить("Заголовок");
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
СтрокаПоля = Результат.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы);
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл   СтрокаПоля = Результат.Добавить();   ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы);   КонецЦикла;  
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если Истина
И ТипТаблицы <> "ДвиженияССубконто"
И ТипТаблицы <> "ВиртуальнаяТаблица"
Тогда
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина);
Если ОбъектМД <> Неопределено Тогда
Если ТипТаблицы = "Внешняя" Тогда
Для Каждого ПолеТаблицы Из ОбъектМД.Поля Цикл
СтрокаПоля = Результат.Найти(ПолеТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
СтрокаПоля.Метаданные = ПолеТаблицы;
Заголовок = ПолеТаблицы.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
ПрефиксРеквизита = ОбъектМД.ПолноеИмя() + ".Реквизит.";
РодительМД = ОбъектМД.Родитель();
Если Истина
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Внешняя"
И ТипЗнч(РодительМД) <> Тип("ОбъектМетаданныхКонфигурация")
Тогда
ОбъектМДФильтра = РодительМД;
Иначе
ОбъектМДФильтра = ОбъектМД;
КонецЕсли;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ОбъектМДФильтра);
//Если ТипТаблицы = "ДвиженияССубконто" Тогда
// ПолноеИмяТаблицыБД = Лев(ПолноеИмяТаблицыБД, СтрДлина(ПолноеИмяТаблицыБД) - СТрДлина(".ДвиженияССубконто"));
//КонецЕсли;
СтрокиСтруктурыТаблицы = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("ИмяТаблицы", ПолноеИмяТаблицыБД));
Если СтрокиСтруктурыТаблицы.Количество() = 0 Тогда
Если Истина
И ТипТаблицы <> "Изменения"
И ТипТаблицы <> "Границы"
И ТипТаблицы <> "Константа"
И ТипТаблицы <> "ЗадачиПоИсполнителю"
Тогда
Сообщить("Не удалось найти в структуре хранения БД описание таблицы " + ПолноеИмяТаблицыБД);
Иначе
// Для отладки
// Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы.
// Сюда попадаем для границ последовательностей, у которых ошибочно пустое имя таблицы.
Пустышка = 1;
КонецЕсли;
Иначе
Если СтрокиСтруктурыТаблицы.Количество() > 1 Тогда
Пустышка = 1; // Для отладки. Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы
КонецЕсли;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого ПолеТаблицы Из СтрокиСтруктурыТаблицы[0].Поля Цикл
Если Истина
И ЗначениеЗаполнено(ПолеТаблицы.Метаданные)
И (Ложь
Или ПолеТаблицы.ИмяПоля <> "НомерСтроки"
Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0)
Тогда
СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя");
Если СтрокаПоля <> Неопределено Тогда
Если Найти(ПолеТаблицы.Метаданные, ПрефиксРеквизита) = 1 Тогда
// Для ускорения
СтрокаПоля.Метаданные = ОбъектМД.Реквизиты[ПолучитьПоследнийФрагментЛкс(ПолеТаблицы.Метаданные)];
Иначе
СтрокаПоля.Метаданные = Метаданные.НайтиПоПолномуИмени(ПолеТаблицы.Метаданные);
КонецЕсли;
Заголовок = СтрокаПоля.Метаданные.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Каждого ПолеТаблицы Из СтрокиСтруктурыТаблицы[0].Поля Цикл   Если Истина   И ЗначениеЗаполнено(ПолеТаблицы.Метаданные)   И (Ложь   Или ПолеТаблицы.ИмяПоля <> "НомерСтроки"   Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0)   Тогда   СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя");   Если СтрокаПоля <> Неопределено Тогда   Если Найти(ПолеТаблицы.Метаданные, ПрефиксРеквизита) = 1 Тогда     СтрокаПоля.Метаданные = ОбъектМД.Реквизиты[ПолучитьПоследнийФрагментЛкс(ПолеТаблицы.Метаданные)];   Иначе   СтрокаПоля.Метаданные = Метаданные.НайтиПоПолномуИмени(ПолеТаблицы.Метаданные);   КонецЕсли;   Заголовок = СтрокаПоля.Метаданные.Представление();   Если ЗначениеЗаполнено(Заголовок) Тогда   СтрокаПоля.Заголовок = Заголовок;   КонецЕсли;   КонецЕсли;   КонецЕсли;   КонецЦикла;  
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// НужныПредставления - Булево - для стандаратных полей будут заполняться представления (дольше)
Функция ПолучитьПоляТаблицыМДЛкс(ПолноеИмяИлиОбъектМД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "",
НужныПредставления = Истина) Экспорт
ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяИлиОбъектМД);
ПоляТаблицы = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность);
Если НужныПредставления Тогда
Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
КонецЕсли;
КомпоновщикТаблицы = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ПолноеИмяМД);
#Если Сервер И Не Сервер Тогда
КомпоновщикТаблицы = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Для Каждого ДоступноеПоле Из КомпоновщикТаблицы.Настройки.ДоступныеПоляВыбора.Элементы Цикл
Если Истина
И Найти("" + ДоступноеПоле.Заголовок, " ") < 1
Тогда
Продолжить;
КонецЕсли;
СтрокаПоля = ПоляТаблицы.Найти("" + ДоступноеПоле.Поле, "Имя");
Если СтрокаПоля <> Неопределено И Найти(СтрокаПоля, " ") < 1 Тогда
СтрокаПоля.Заголовок = ДоступноеПоле.Заголовок;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ПоляТаблицы;
КонецФункции
// Добавляет в набор данных поле набора данных
Функция ДобавитьПолеНабораДанныхЛкс(НаборДанных, Поле, Заголовок, ПутьКДанным = Неопределено) Экспорт
Если ПутьКДанным = Неопределено Тогда
ПутьКДанным = Поле;
КонецЕсли;
ПолеНабораДанных = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабораДанных.Поле = Поле;
ПолеНабораДанных.Заголовок = Заголовок;
ПолеНабораДанных.ПутьКДанным = ПутьКДанным;
Возврат ПолеНабораДанных;
КонецФункции
Функция ДобавитьПоляПериодаВНаборДанныхЛкс(НаборДанных)
СписокПериодов = Новый СписокЗначений;
СписокПериодов.Добавить("ПериодСекунда", "Период секунда");
СписокПериодов.Добавить("ПериодМинута", "Период минута");
СписокПериодов.Добавить("ПериодЧас", "Период час");
СписокПериодов.Добавить("ПериодДень", "Период день");
СписокПериодов.Добавить("ПериодНеделя", "Период неделя");
СписокПериодов.Добавить("ПериодДекада", "Период декада");
СписокПериодов.Добавить("ПериодМесяц", "Период месяц");
СписокПериодов.Добавить("ПериодКвартал", "Период квартал");
СписокПериодов.Добавить("ПериодПолугодие", "Период полугодие");
СписокПериодов.Добавить("ПериодГод", "Период год");
ИмяПапки = "Периоды";
СписокПолейНабораДанных = Новый СписокЗначений;
ПапкаПолейНабораДанных = НаборДанных.Поля.Добавить(Тип("ПапкаПолейНабораДанныхСхемыКомпоновкиДанных"));
ПапкаПолейНабораДанных.Заголовок = ИмяПапки;
ПапкаПолейНабораДанных.ПутьКДанным = ИмяПапки;
Для каждого Период Из СписокПериодов Цикл
ПолеНабораДанных = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабораДанных.Поле = Период.Значение;
ПолеНабораДанных.Заголовок = Период.Представление;
ПолеНабораДанных.ПутьКДанным = ИмяПапки + "." + Период.Значение;
СписокПолейНабораДанных.Добавить(ПолеНабораДанных);
КонецЦикла;
Возврат СписокПолейНабораДанных;
КонецФункции
// Функция добавляет поле итога в схему компоновки данных. Если параметр Выражение не указан, используется Сумма(ПутьКДанным)
Функция ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, ПутьКДанным, Выражение = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Если Выражение = Неопределено Тогда
Выражение = "Сумма(" + ПутьКДанным + ")";
КонецЕсли;
ПолеИтога = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
ПолеИтога.ПутьКДанным = ПутьКДанным;
ПолеИтога.Выражение = Выражение;
Возврат ПолеИтога;
КонецФункции
Процедура ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновкиДанных) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
ПолноеИмяМД = ПолноеИмяТаблицыБД;
Иначе
ИмяВиртуальнойТаблицы = "";
ПолноеИмяМД = ПолноеИмяТаблицыБД;
КонецЕсли;
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) И Не СтрокиРавныЛкс(ТипТаблицы, "Изменения") Тогда
// Добавляем измерения
Для каждого Измерение Из ОбъектМД.Измерения Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Измерение.Имя, Измерение.Синоним);
КонецЦикла;
// Добавляем реквизиты
Если Истина
И Не ЛиКорневойТипПоследовательностиЛкс(КорневойТип)
И Не СтрокиРавныЛкс(ТипТаблицы, "Перерасчет")
Тогда
//Если ПустаяСтрока(ИмяВиртуальнойТаблицы) Тогда
Для каждого Реквизит Из ОбъектМД.Реквизиты Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Реквизит.Имя, Реквизит.Синоним);
КонецЦикла;
//КонецЕсли;
// Добавляем поля периода
Если Ложь
Или ИмяВиртуальнойТаблицы = "ОстаткиИОбороты"
Или ИмяВиртуальнойТаблицы = "Обороты"
Или (Истина
И КорневойТип = "РегистрБухгалтерии"
И ИмяВиртуальнойТаблицы = "")
Тогда
ДобавитьПоляПериодаВНаборДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0]);
КонецЕсли;
// Добавляем ресурсы
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Если КорневойТип = "РегистрНакопления" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Приход", Ресурс.Синоним + " приход", Ресурс.Имя + "Приход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Приход");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Расход", Ресурс.Синоним + " расход", Ресурс.Имя + "Расход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Расход");
ИначеЕсли КорневойТип = "РегистрБухгалтерии" ТОгда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
Если НЕ Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборот", Ресурс.Синоним + " кор. оборот", Ресурс.Имя + "КорОборот");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборот");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборотДт", Ресурс.Синоним + " кор. оборот Дт", Ресурс.Имя + "КорОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборотКт", Ресурс.Синоним + " кор. оборот Кт", Ресурс.Имя + "КорОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборотКт");
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОборотыДтКт" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Дт", Ресурс.Синоним + " Дт", Ресурс.Имя + "Дт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Дт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Кт", Ресурс.Синоним + " Кт", Ресурс.Имя + "Кт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Кт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстаток", Ресурс.Синоним + " нач. остаток", Ресурс.Имя + "НачальныйОстаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстаток");
Если КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстатокДт", Ресурс.Синоним + " нач. остаток Дт", Ресурс.Имя + "НачальныйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстатокКт", Ресурс.Синоним + " нач. остаток Кт", Ресурс.Имя + "НачальныйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйРазвернутыйОстатокДт", Ресурс.Синоним + " нач. развернутый остаток Дт", Ресурс.Имя + "НачальныйРазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйРазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйРазвернутыйОстатокКт", Ресурс.Синоним + " нач. развернутый остаток Кт", Ресурс.Имя + "НачальныйРазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйРазвернутыйОстатокКт");
КонецЕсли;
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним + " оборот", Ресурс.Имя + "Оборот");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Если КорневойТип = "РегистрНакопления" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Приход", Ресурс.Синоним + " приход", Ресурс.Имя + "Приход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Приход");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Расход", Ресурс.Синоним + " расход", Ресурс.Имя + "Расход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Расход");
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстаток", Ресурс.Синоним + " кон. остаток", Ресурс.Имя + "КонечныйОстаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстаток");
Если КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстатокДт", Ресурс.Синоним + " кон. остаток Дт", Ресурс.Имя + "КонечныйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстатокКт", Ресурс.Синоним + " кон. остаток Кт", Ресурс.Имя + "КонечныйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйРазвернутыйОстатокДт", Ресурс.Синоним + " кон. развернутый остаток Дт", Ресурс.Имя + "КонечныйРазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйРазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйРазвернутыйОстатокКт", Ресурс.Синоним + " кон. развернутый остаток Кт", Ресурс.Имя + "КонечныйРазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйРазвернутыйОстатокКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "Остатки" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Остаток", Ресурс.Синоним + " остаток", Ресурс.Имя + "Остаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Остаток");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОстатокДт", Ресурс.Синоним + " остаток Дт", Ресурс.Имя + "ОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОстатокКт", Ресурс.Синоним + " остаток Кт", Ресурс.Имя + "ОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "РазвернутыйОстатокДт", Ресурс.Синоним + " развернутый остаток Дт", Ресурс.Имя + "РазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "РазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "РазвернутыйОстатокКт", Ресурс.Синоним + " развернутый остаток Кт", Ресурс.Имя + "РазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "РазвернутыйОстатокКт");
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
Если Ресурс.Тип.СодержитТип(Тип("Число")) Тогда
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя, Ресурс.Имя);
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
Если КорневойТип = "РегистрБухгалтерии" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Дт", Ресурс.Синоним + " Дт", Ресурс.Имя + "Дт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Дт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Кт", Ресурс.Синоним + " Кт", Ресурс.Имя + "Кт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Кт");
КонецЕсли;
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
Если ИмяВиртуальнойТаблицы = "" Тогда
ОбъектМетаданных = ОбъектМД;
Иначе
ОбъектМетаданных = ОбъектМД.ТабличныеЧасти.Найти(ИмяВиртуальнойТаблицы);
Если ОбъектМетаданных = Неопределено Тогда
ОбъектМетаданных = ОбъектМД;
КонецЕсли;
КонецЕсли;
Для каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Реквизит.Имя, Реквизит.Синоним);
Если Реквизит.Тип.СодержитТип(Тип("Число")) Тогда
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Реквизит.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
Иначе
ИмяВиртуальнойТаблицы = "";
КонецЕсли;
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
ВыбранныеПоля = НастройкаКомпоновки.Выбор;
Если ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
ВыбранныеПоляНачальныйОстаток = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляНачальныйОстаток.Заголовок = "Нач. остаток";
ВыбранныеПоляНачальныйОстаток.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
Если КорневойТип = "РегистрНакопления" Тогда
ВыбранныеПоляПриход = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляПриход.Заголовок = "Приход";
ВыбранныеПоляПриход.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
ВыбранныеПоляРасход = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляРасход.Заголовок = "Расход";
ВыбранныеПоляРасход.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ВыбранныеПоляОбороты = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляОбороты.Заголовок = "Обороты";
ВыбранныеПоляОбороты.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
КонецЕсли;
ВыбранныеПоляКонечныйОстаток = ВыбранныеПоля.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляКонечныйОстаток.Заголовок = "Кон. остаток";
ВыбранныеПоляКонечныйОстаток.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
КонецЕсли;
Если КорневойТип = "РегистрНакопления" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Приход",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Расход",, Ложь);
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстаток");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляПриход, Ресурс.Имя + "Приход");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляРасход, Ресурс.Имя + "Расход");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстаток");
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
КонецЕсли;
КонецЦикла;
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
КонецЦикла;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотКт");
Если Не Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "КорОборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "КорОборотДт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "КорОборотКт",, Ложь);
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОборотыДтКт" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот");
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "Остатки" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОстатокКт");
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстаток",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстатокКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйРазвернутыйОстатокДт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйРазвернутыйОстатокКт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "Оборот",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "ОборотКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстаток",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстатокКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйРазвернутыйОстатокДт",, Ложь);
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйРазвернутыйОстатокКт",, Ложь);
ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Дт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Кт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Дт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Кт");
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
//Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, ПолеТаблицыБД.Имя);
КонецЦикла;
//КонецЕсли;
КонецПроцедуры
Процедура ДобавитьПолеГруппировкиЛкс(Группировка, Наименование, Синоним)
Если Группировка.Найти(Наименование, "Поле") = Неопределено Тогда
ГруппировкаСтр = Группировка.Добавить();
ГруппировкаСтр.Поле = Наименование;
ГруппировкаСтр.Использование = Истина;
ГруппировкаСтр.Представление = Синоним;
КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, НастройкаКомпоновки) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
Иначе
ИмяВиртуальнойТаблицы = "";
КонецЕсли;
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
////ПолеГруппировки = ЭлементСтруктуры.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
//Если ТипТаблицы = "Справочники" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Наименование", "Наименование");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Ссылка.Наименование", "Наименование");
// КонецЕсли;
//ИначеЕсли ТипТаблицы = "Документы" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Ссылка", "Ссылка");
//ИначеЕсли Истина
// И ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Количество() > 0
// И ОбъектМД.Измерения.Количество() > 0
//Тогда
// Если ТипТаблицы = "РегистрБухгалтерии" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Регистратор", "Регистратор");
// ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
// ЭлементСтруктуры.ПоляГруппировки.Элементы.Удалить(ПолеГруппировки);
// // Группировки по забалансовым
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя, Измерение.Синоним);
// КонецЕсли
// КонецЦикла;
// // ИзмеренияДт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Дт", Измерение.Синоним + " Дт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоДт" + К, "СубконтоДт" + К);
// КонецЦикла;
// // ИзмеренияКт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Кт", Измерение.Синоним + " Кт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоКт" + К, "СубконтоКт" + К);
// КонецЦикла;
// Иначе
// Если ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Найти("Счет")<> Неопределено Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Счет", "Счет");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетДт", "СчетДт");
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетКт", "СчетКт");
// КонецЕсли;
// КонецЕсли;
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка,
// ОбъектМД.Измерения[0].Имя,
// ОбъектМД.Измерения[0].Синоним);
// КонецЕсли
//КонецЕсли;
ЭлементПорядка = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
КонецПроцедуры
Функция ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность = Неопределено, ДобавитьАвтополеКоличествоСтрок = Истина,
Знач ИндексПараметраПериодичность = Неопределено, Знач ПсевдонимТаблицы = "Т", ИменаВместоПредставлений = Ложь, РасширенноеЗаполнение = Ложь, ПервыеN = 0) Экспорт
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(Схема.НаборыДанных, ИсточникДанных);
#Если Сервер И Не Сервер Тогда
НаборДанных = Схема.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ПсевдонимТаблицы, Ложь, ПервыеN);
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(Схема);
КонецЕсли;
Если Ложь
Или ИменаВместоПредставлений
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 // Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
Если ИменаВместоПредставлений Тогда
ПолеНабора.Заголовок = ДоступноеПоле.Имя;
Иначе
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если РасширенноеЗаполнение Тогда
ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, Схема);
ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, Схема.НастройкиПоУмолчанию);
ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, Схема.НастройкиПоУмолчанию);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "Title", Метаданные[Отчет.ТипДанных][Отчет.ИмяОбъекта].Синоним);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "TitleOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "FilterOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "DataParametersOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
КонецЕсли;
Возврат Схема;
КонецФункции
Функция ПолучитьТекстЗапросаПолейТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = Неопределено, ПсевдонимТаблицы = "Т",
БлокироватьПолучениеДанных = Истина, ПервыеN = 0) Экспорт
ОписаниеТаблицы = ПолучитьОписаниеТаблицыБДИис(ПолноеИмяТаблицыБД);
Если ОписаниеТаблицы = Неопределено Тогда
ВызватьИсключение "Таблица БД с именем " + ПолноеИмяТаблицыБД + " не найдена";
КонецЕсли;
ПараметрыВиртуальнойТаблицы = "";
Если БлокироватьПолучениеДанных Тогда
ИндексПараметраОтбора = ОписаниеТаблицы.ИндексПараметраОтбора;
Иначе
ИндексПараметраОтбора = Неопределено;
КонецЕсли;
МаксимальныйИндекс = ИндексПараметраОтбора;
Если ИндексПараметраПериодичность <> Неопределено Тогда
Если МаксимальныйИндекс <> Неопределено Тогда
МаксимальныйИндекс = Макс(МаксимальныйИндекс, ИндексПараметраПериодичность);
Иначе
МаксимальныйИндекс = ИндексПараметраПериодичность;
КонецЕсли;
КонецЕсли;
Если МаксимальныйИндекс <> Неопределено Тогда
МассивВыраженийПараметров = Новый Массив;
Для Счетчик = 0 По МаксимальныйИндекс Цикл
МассивВыраженийПараметров.Добавить("");
КонецЦикла;
Если ИндексПараметраОтбора <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраОтбора] = "ЛОЖЬ";
КонецЕсли;
Если ИндексПараметраПериодичность <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраПериодичность] = ВыражениеПараметраПериодичность;
КонецЕсли;
ПараметрыВиртуальнойТаблицы = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивВыраженийПараметров);
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрыВиртуальнойТаблицы) Тогда
ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(" + ПараметрыВиртуальнойТаблицы + ")";
КонецЕсли;
Если Не ЗначениеЗаполнено(ПсевдонимТаблицы) Тогда
ПсевдонимТаблицы = "Т";
КонецЕсли;
ТекстЗапроса = "ВЫБРАТЬ ";
Если ЗначениеЗаполнено(ПервыеN) Тогда
ТекстЗапроса = ТекстЗапроса + "ПЕРВЫЕ " + XMLСтрокаервыеN) + " ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Возврат ТекстЗапроса;
КонецФункции
Функция _ПолучитьСхемуКомпоновкиПоВсемТаблицамБДЛкс(ТаблицаВсехТаблицБД, ИмяНабораДанных = "НаборДанных1",
ДобавитьАвтополеКоличествоСтрок = Истина, ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
КорневаяСхема = Новый СхемаКомпоновкиДанных;
НастройкиПоУмолчанию = КорневаяСхема.НастройкиПоУмолчанию;
Для Каждого ОписаниеТаблицы Из ТаблицаВсехТаблицБД Цикл
ПолноеИмяТаблицыБД = ОписаниеТаблицы.ПолноеИмя;
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(Схема.НаборыДанных, ИсточникДанных);
#Если Сервер И Не Сервер Тогда
НаборДанных = Схема.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
//ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
НаборДанных.Запрос = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(Схема);
КонецЕсли;
// Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Если Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЦикла;
КонецЕсли;
ВложеннаяСхема = КорневаяСхема.ВложенныеСхемыКомпоновкиДанных.Добавить();
//ВложеннаяСхема.Заголовок = ОписаниеТаблицы.Представление;
ВложеннаяСхема.Схема = Схема;
ВложеннаяСхема.Имя = СтрЗаменить(ПолноеИмяТаблицыБД, ".", "_1_");
ЭлементСтруктуры = НастройкиПоУмолчанию.Структура.Добавить(Тип("НастройкиВложенногоОбъектаКомпоновкиДанных"));
ЭлементСтруктуры.УстановитьИдентификатор(ВложеннаяСхема.Имя);
КонецЦикла;
Возврат КорневаяСхема;
КонецФункции
Функция ДобавитьДоступнуюТаблицуБДЛкс(ДоступныеТаблицыБД, ПолноеИмя, ПолноеИмяМД = "", ТипТаблицы = "", Имя = "", Представление = "", СхемаТаблицы = "", ПроверятьУникальность = Ложь,
ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмя) Тогда
ПолноеИмя = ПолноеИмяМД;
КонецЕсли;
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Фрагменты.Количество() > 1 Тогда
//Если Не ЗначениеЗаполнено(СхемаТаблицы) Тогда
// СхемаТаблицы = Фрагменты[0];
//КонецЕсли;
Фрагменты.Удалить(0);
КонецЕсли;
Если ПроверятьУникальность Тогда
СтрокаТаблицы = ДоступныеТаблицыБД.Найти(НРег(ПолноеИмя), "НПолноеИмя");
Иначе
СтрокаТаблицы = Неопределено;
КонецЕсли;
Если СтрокаТаблицы = Неопределено Тогда
СтрокаТаблицы = ДоступныеТаблицыБД.Добавить();
СтрокаТаблицы.Схема = СхемаТаблицы;
СтрокаТаблицы.ПолноеИмяМД = ПолноеИмяМД;
СтрокаТаблицы.ПолноеИмя = ПолноеИмя;
СтрокаТаблицы.НПолноеИмя = НРег(СтрокаТаблицы.ПолноеИмя);
СтрокаТаблицы.ИндексПараметраОтбора = ИндексПараметраОтбора;
Если Не ЗначениеЗаполнено(Имя) Тогда
СтрокаТаблицы.Имя = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
Иначе
СтрокаТаблицы.Имя = Имя;
КонецЕсли;
СтрокаТаблицы.Представление = Представление;
Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмя);
КонецЕсли;
СтрокаТаблицы.Тип = ТипТаблицы;
Если ТипТаблицы = "Перерасчет" Тогда
МетаРегистрРасчета = ОбъектМД.Родитель();
СтрокаТаблицы.Имя = МетаРегистрРасчета.Имя + "." + СтрокаТаблицы.Имя;
СтрокаТаблицы.Представление = МетаРегистрРасчета.Представление() + "." + СтрокаТаблицы.Представление;
КонецЕсли;
//СтрокаТаблицы.Описание = МетаИсточник.Представление();
КонецЕсли;
Возврат СтрокаТаблицы;
КонецФункции
Функция ПолучитьИндексКартинкиТипаТаблицыБДЛкс(ТипТаблицы) Экспорт
ИндексКартинки = 14;
Если ТипТаблицы = "Константы" Тогда
ИндексКартинки = 2;
ИначеЕсли ТипТаблицы = "Константа" Тогда
ИндексКартинки = 2;
//ИначеЕсли ТипТаблицы = "ТабличнаяЧасть" Тогда
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
ИндексКартинки = 20;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
ИндексКартинки = 27;
ИначеЕсли ТипТаблицы = "ВиртуальнаяТаблица" Тогда
ИндексКартинки = 28;
ИначеЕсли ТипТаблицы = "ВнешнийИсточникДанных" Тогда
ИндексКартинки = 29;
ИначеЕсли ТипТаблицы = "Справочник" Тогда
ИндексКартинки = 3;
ИначеЕсли ТипТаблицы = "Перечисление" Тогда
ИндексКартинки = 4;
ИначеЕсли ТипТаблицы = "Документ" Тогда
ИндексКартинки = 5;
ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда
ИндексКартинки = 6;
ИначеЕсли ТипТаблицы = "Последовательность" Тогда
ИндексКартинки = 7;
ИначеЕсли ТипТаблицы = "РегистрНакопления" Тогда
ИндексКартинки = 8;
ИначеЕсли ТипТаблицы = "РегистрСведений" Тогда
ИндексКартинки = 9;
ИначеЕсли ТипТаблицы = "РегистрБухгалтерии" Тогда
ИндексКартинки = 10;
ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда
ИндексКартинки = 11;
ИначеЕсли ТипТаблицы = "ПланОбмена" Тогда
ИндексКартинки = 19;
ИначеЕсли ТипТаблицы = "Задача" Тогда
ИндексКартинки = 17;
ИначеЕсли ТипТаблицы = "БизнесПроцесс" Тогда
ИндексКартинки = 18;
ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда
ИндексКартинки = 26;
ИначеЕсли ТипТаблицы = "ПланВидовРасчета" Тогда
ИндексКартинки = 25;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 22;
ИначеЕсли ТипТаблицы = "Перечисление" Тогда
ИндексКартинки = 23;
ИначеЕсли ТипТаблицы = "ПланСчетов" Тогда
ИндексКартинки = 24;
ИначеЕсли ТипТаблицы = "Перерасчет" Тогда
ИндексКартинки = 30;
ИначеЕсли СтрокиРавныЛкс(ТипТаблицы, "Table") Тогда
ИндексКартинки = 3;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПредставлениюЛкс(Знач ЭлементыНастройки, Знач Представление = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыНастройки, "Представление", Представление, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Представление = Представление;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
ТипЭлемента = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки);
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементыНастройки, Поле, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Поле = Поле;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки) Экспорт
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовПорядкаКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементПорядкаКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияВыбранныхПолейКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ВыбранноеПолеКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияПолейГруппировкиКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ПолеГруппировкиКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
КонецЕсли;
Возврат ТипЭлемента;
КонецФункции
Функция НайтиЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле, Знач ТипЭлемента = Неопределено) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ТипЭлемента = Неопределено Тогда
ТипЭлемента = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки);
КонецЕсли;
Для Каждого ЭлементНастроек Из ЭлементыНастройки Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(ЭлементНастроек) <> ТипЭлемента
Тогда
Попытка
ДочерниеЭлементыНастройки = ЭлементНастроек.Элементы;
Исключение
ДочерниеЭлементыНастройки = Неопределено;
КонецПопытки;
Если ДочерниеЭлементыНастройки <> Неопределено Тогда
НайденныйЭлемент = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ДочерниеЭлементыНастройки, Поле, ТипЭлемента);
Если НайденныйЭлемент <> Неопределено Тогда
Прервать;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ПолеЭлемента = ЭлементНастроек.ЛевоеЗначение;
Иначе
ПолеЭлемента = ЭлементНастроек.Поле;
КонецЕсли;
Если ПолеЭлемента = Поле Тогда
НайденныйЭлемент = ЭлементНастроек;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат НайденныйЭлемент;
КонецФункции
// Параметры:
// ВыбранныеПоля -
//
Функция ПолучитьВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(Знач ВыбранныеПоля, Знач ТолькоВключенные = Ложь, выхМассивРезультата = Неопределено) Экспорт
Если выхМассивРезультата <> Неопределено Тогда
Результат = выхМассивРезультата;
Иначе
Результат = Новый Массив();
КонецЕсли;
Для Каждого ВыбранноеПоле Из ВыбранныеПоля.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
РезультатВложенный = ПолучитьВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(ВыбранноеПоле, ТолькоВключенные, Результат);
Иначе
Если Ложь
Или Не ТолькоВключенные
Или ВыбранноеПоле.Использование
Тогда
Результат.Добавить(ВыбранноеПоле);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(Знач Группировки, Знач Поле = "") Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
ЭлементСуществует = Ложь;
Для Каждого Группировка Из Группировки Цикл
Поля = Группировка.ПоляГруппировки.Элементы;
Если Ложь
Или (Истина
И Поля.Количество() = 0
И "" + Поле = "")
Или (Истина
И Поля.Количество() = 1
И Поля[0].Поле = Поле)
Тогда
ЭлементСуществует = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЭлементСуществует Тогда
Если ТипЗнч(Группировки) = Тип("КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных") Тогда
Группировка = Группировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Иначе
Группировка = Группировки.Добавить();
КонецЕсли;
Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
Если "" + Поле <> "" Тогда
ПолеГруппировки = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Поле = Поле;
КонецЕсли;
КонецЕсли;
Группировка.Использование = Истина;
Возврат Группировка;
КонецФункции
Функция НайтиЭлементОтбораКомпоновкиЛкс(Знач Отбор, Знач ИменаПолей, Знач НайденныеЭлементы = Неопределено, Знач ТолькоВключенныеНаРавенствоЗначению = Ложь,
Знач ВключатьПодчиненные = Ложь) Экспорт
Если ТипЗнч(Отбор) = Тип("ОтборКомпоновкиДанных") Тогда
ЭлементыОтбора = Отбор.Элементы;
Иначе
ЭлементыОтбора = Отбор;
КонецЕсли;
Если ТипЗнч(ИменаПолей) = Тип("Строка") Тогда
МассивИменПолей = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаПолей, ",", Истина);
Иначе
МассивИменПолей = ИменаПолей;
КонецЕсли;
МассивПолей = Новый Массив;
Для Каждого ИмяПоля Из МассивИменПолей Цикл
МассивПолей.Добавить(Новый ПолеКомпоновкиДанных(ИмяПоля));
КонецЦикла;
МассивПолейПуст = МассивПолей.Количество() = 0;
Если НайденныеЭлементы = Неопределено Тогда
НайденныеЭлементы = Новый Соответствие;
КонецЕсли;
Для Каждого ЭлементОтбора ИЗ ЭлементыОтбора Цикл
Если Истина
И ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И (Ложь
Или Не ТолькоВключенныеНаРавенствоЗначению
Или (Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно
И ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных")
И ТипЗнч(ЭлементОтбора.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных")))
Тогда
Если Ложь
Или МассивПолейПуст
Или МассивПолей.Найти(ЭлементОтбора.ЛевоеЗначение) <> Неопределено
Тогда
НайденныеЭлементы.Вставить("" + ЭлементОтбора.ЛевоеЗначение, ЭлементОтбора);
КонецЕсли;
ИначеЕсли Истина
И ВключатьПодчиненные
И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
НайтиЭлементОтбораКомпоновкиЛкс(ЭлементОтбора.Элементы, МассивИменПолей, НайденныеЭлементы, ТолькоВключенныеНаРавенствоЗначению);
КонецЕсли;
КонецЦикла;
Если МассивИменПолей.Количество() = 1 Тогда
Результат = НайденныеЭлементы[МассивИменПолей[0]];
Иначе
Результат = НайденныеЭлементы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Знач ЭлементыОтбора, Знач Поле = "", Знач Значение = Неопределено, Знач Сравнение = "", Знач ДоступныеПоляОтбора = Неопределено,
Знач ПроверятьУникальность = Истина, ИспользованиеДляНового = Истина, СообщитьОДобавлении = Ложь) Экспорт
Если ТипЗнч(ЭлементыОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Отбор;
КонецЕсли;
Если ТипЗнч(ЭлементыОтбора) = Тип("ОтборКомпоновкиДанных") Тогда
ДоступныеПоляОтбора = ЭлементыОтбора.ДоступныеПоляОтбора;
ЭлементыОтбора = ЭлементыОтбора.Элементы;
ИначеЕсли ТипЗнч(ЭлементыОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Элементы;
Иначе
ЭлементыОтбора = ЭлементыОтбора;
КонецЕсли;
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементОтбора = НайтиЭлементОтбораКомпоновкиЛкс(ЭлементыОтбора, "" + Поле);
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.Использование = ИспользованиеДляНового;
ЭлементОтбора.ЛевоеЗначение = Поле;
ИначеЕсли Не ИспользованиеДляНового Тогда // Опасно
Возврат ЭлементОтбора;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
КонецЕсли;
// Вид сравнения
Если ТипЗнч(Сравнение) = Тип("ВидСравненияКомпоновкиДанных") Тогда
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравненияКомпоновкиДанных.ВСписке;
Иначе
Сравнение = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
КонецЕсли;
Если Истина
И Сравнение = ВидСравненияКомпоновкиДанных.Равно
И Значение = Неопределено
И ДоступныеПоляОтбора <> Неопределено
Тогда
ДоступноеПолеОтбора = ДоступныеПоляОтбора.НайтиПоле(Поле);
Если ДоступноеПолеОтбора <> Неопределено Тогда
Значение = ДоступноеПолеОтбора.Тип.ПривестиЗначение(Значение);
Если Истина
И Значение = ""
И ДоступноеПолеОтбора.Тип.КвалификаторыСтроки.Длина = 0
Тогда
Сравнение = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭлементОтбора.ВидСравнения = Сравнение;
ЭлементОтбора.ПравоеЗначение = Значение;
Если СообщитьОДобавлении Тогда
Сообщить("В отбор добавлен элемент """ + ЭлементОтбора.ЛевоеЗначение + " " + ЭлементОтбора.ВидСравнения + " " + ЭлементОтбора.ПравоеЗначение + """");
КонецЕсли;
Возврат ЭлементОтбора;
КонецФункции
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
Функция ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(ОтборСтрок, ИмяКолонки);
Иначе
КопияТаблицы = Таблица.Выгрузить(ОтборСтрок, ИмяКолонки);
КонецЕсли;
Типы = КопияТаблицы.Колонки[ИмяКолонки].ТипЗначения.Типы();
Если Истина
И Типы.Количество() = 1
И Типы[0] = Тип("Строка")
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
ИмяКолонкиНрег = ИмяКолонки + "_Нрег777233464645";
КопияТаблицы.Колонки.Добавить(ИмяКолонкиНрег);
Для Каждого СтрокаКопииТаблицы Из КопияТаблицы Цикл
СтрокаКопииТаблицы[ИмяКолонкиНрег] = НРег(СтрокаКопииТаблицы[ИмяКолонки]);
КонецЦикла;
Иначе
ИмяКолонкиНрег = ИмяКолонки;
КонецЕсли;
КолонкаКоличества = ИмяКолонки + "7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИмяКолонкиНрег, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
МассивНеуникальных.Добавить(СтрокаКопии[ИмяКолонкиНрег]);
КонецЕсли;
КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
// ИменаКолонок - Строка - имена колонок через запятую
Функция ПолучитьНеуникальныеКлючиТаблицыЛкс(Таблица, Знач ИменаКолонок = "") Экспорт
#Если Сервер И Не Сервер Тогда
Таблица = Новый ТаблицаЗначений;
#КонецЕсли
Если Не ЗначениеЗаполнено(ИменаКолонок) Тогда
ИменаКолонок = "";
Для Каждого КолонкаТаблицы Из Таблица.Колонки Цикл
Если ИменаКолонок <> "" Тогда
ИменаКолонок = ИменаКолонок + ",";
КонецЕсли;
ИменаКолонок = ИменаКолонок + КолонкаТаблицы.Имя;
КонецЦикла;
КонецЕсли;
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(, ИменаКолонок);
Иначе
КопияТаблицы = Таблица.Выгрузить(, ИменаКолонок);
КонецЕсли;
КолонкаКоличества = "Количество7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИменаКолонок, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
НеуникальныйКлюч = Новый Структура(ИменаКолонок);
ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии);
МассивНеуникальных.Добавить(НеуникальныйКлюч);
КонецЕсли;
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл   СтрокаКопии = КопияТаблицы[Индекс];   Если СтрокаКопии[КолонкаКоличества] > 1 Тогда   НеуникальныйКлюч = Новый Структура(ИменаКолонок);   ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии);   МассивНеуникальных.Добавить(НеуникальныйКлюч);   КонецЕсли;   КонецЦикла;  
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
Функция СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ОбъектыНаСервере = Неопределено) Экспорт
СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицыБД,,, Ложь, ОбъектыНаСервере);
Возврат СтруктураНабораЗаписей;
КонецФункции
Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, РасширениеТипа = "НаборЗаписей") Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
Если Фрагменты.Количество() > 2 Тогда
Если Фрагменты[0] = "РегистрРасчета" Тогда
ИмяТипа = "Перерасчет" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[2];
ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда
ИмяТипа = "РегистрБухгалтерии" + РасширениеТипа + "." + Фрагменты[1];
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ИмяТипа = "ВнешнийИсточникДанныхТаблица" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[3];
КонецЕсли;
Иначе
ИмяТипа = СтрЗаменить(ПолноеИмяТаблицыБД, ".", РасширениеТипа + ".");
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ПолучитьТипКлючаЗаписиТаблицыЛкс(ПолноеИмяТаблицы) Экспорт
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
Результат = Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяТаблицы));
ИначеЕсли Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Последовательность"
Тогда
Результат = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "КлючЗаписи."));
Иначе
Результат = Тип("Неопределено");
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ВернутьСтруктуру - Булево - возвращать структуру иначе список значений
// ДляНабораЗаписейРегистраСведений - Булево - для регистров сведений подчиненных регистратору вернуть ключ записываемого объекта
//
Функция ПолучитьСтруктуруКлючаТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВключатьНомерСтроки = Истина, ВернутьСтруктуру = Истина, ДляНабораЗаписейРегистраСведений = Истина) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
СписокПолей = Новый СписокЗначений;
Если Ложь
Или ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
НаборЗаписей = ирКэш.ЭталонныйНаборЗаписейЛкс(ПолноеИмяТаблицыБД);
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
#КонецЕсли
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
И Не ДляНабораЗаписейРегистраСведений
Тогда
Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период");
КонецЕсли;
Если ОбъектМД.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда
СписокПолей.Добавить(НаборЗаписей.Отбор.Регистратор.ТипЗначения, "Регистратор");
КонецЕсли;
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СписокПолей.Добавить(Измерение.Тип, Измерение.Имя);
КонецЦикла;
КонецЕсли;
Если СписокПолей.Количество() = 0 Тогда
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если Ложь
Или ЭлементОтбора.Использование
Или ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ВключатьНомерСтроки Тогда
Если ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период");
ИначеЕсли Истина
И ТипТаблицы <> "Перерасчет"
И (Ложь
Или Не ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Или (ДляНабораЗаписейРегистраСведений И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору))
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки");
КонецЕсли;
КонецЕсли;
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
Если ВключатьНомерСтроки Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки");
КонецЕсли;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
// Такой способ может быть долгим при частых вызовах
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицыБД + " КАК _Таблица_";
ПостроительЗапроса.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
Если Ложь
Или СтрокиРавныЛкс(ДоступноеПоле.ПутьКДанным, "НомерСообщения")
Тогда
Продолжить;
КонецЕсли;
СписокПолей.Добавить(ДоступноеПоле.ТипЗначения, ДоступноеПоле.ПутьКДанным);
КонецЦикла;
ИначеЕсли ТипТаблицы = "Внешняя" Тогда
ТаблицаМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяТаблицыБД);
Если ТаблицаМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
Иначе
НаборЗаписей = ирКэш.ЭталонныйНаборЗаписейЛкс(ПолноеИмяТаблицыБД);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЦикла;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда
Поля = ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Поле = Поля.Найти("Ссылка", "Имя");
СписокПолей.Добавить(Поле.ТипЗначения, "Ссылка");
Иначе
ВызватьИсключение "Полученияе структуры ключа таблицы БД типа """ + ТипТаблицы + """ не поддерживается";
КонецЕсли;
Если ВернутьСтруктуру Тогда
Результат = Новый Структура();
Для Каждого ЭлементСписка Из СписокПолей Цикл
Результат.Вставить(ЭлементСписка.Представление, ЭлементСписка.Значение);
КонецЦикла;
Иначе
Результат = СписокПолей;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура УдалитьМутабельныеЗначенияВСтруктуреЛкс(Знач ДополнительныеСвойстваЛ) Экспорт
// Убираем неудобные типы значений из дополнительных свойств объекта http://devtool1c.ucoz.ru/forum/2-832-1#3587
УдаляемыеКлючи = Новый Массив;
Для Каждого КлючИЗначение Из ДополнительныеСвойстваЛ Цикл
Если ТипЗнч(КлючИЗначение.Значение) = Тип("МенеджерВременныхТаблиц") Тогда
УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого Ключ Из УдаляемыеКлючи Цикл
ДополнительныеСвойстваЛ.Удалить(Ключ);
КонецЦикла;
КонецПроцедуры
Функция ЦветТекстаНеактивностиЛкс() Экспорт
Возврат Новый Цвет(100, 100, 100);
КонецФункции
// Для подчиненного регистра сведений выполняет чтение из БД
// Результат - Структура
Функция ПолучитьСтруктуруИзКлючаЗаписиЛкс(КлючЗаписи, ПолноеИмяМДЭлемента = "") Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмяМДЭлемента) Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи));
ПолноеИмяМДЭлемента = ОбъектМД.ПолноеИмя();
Иначе
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМДЭлемента);
КонецЕсли;
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента, Истина,, Ложь);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, КлючЗаписи);
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяМДЭлемента);
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ДанныеСтроки = ПолучитьСтрокуТаблицыБДПоКлючуЛкс(ПолноеИмяМДЭлемента, СтруктураКлюча);
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ДанныеСтроки);
КонецЕсли;
Возврат СтруктураКлюча;
КонецФункции
Функция Получить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 Тогда
Если ОбъектМД.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.НеИспользовать Тогда
СтруктураТЧ.Вставить("БазовыеВидыРасчета", "Базовые виды расчета");
КонецЕсли;
СтруктураТЧ.Вставить("ВедущиеВидыРасчета", "Ведущие виды расчета");
Если ОбъектМД.ИспользованиеПериодаДействия Тогда
СтруктураТЧ.Вставить("ВытесняющиеВидыРасчета", "Вытесняющие виды расчета");
КонецЕсли;
КонецЕсли;
Возврат СтруктураТЧ;
КонецФункции
Функция ЛиСтрокаСодержитВсеПодстрокиЛкс(Знач Строка, Знач Подстроки) Экспорт
Если ТипЗнч(Подстроки) = Тип("Строка") Тогда
Подстроки = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина);
КонецЕсли;
НСтрока = НРег(Строка);
Для Каждого Фрагмент Из Подстроки Цикл
Если Найти(НСтрока, Фрагмент) = 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.СодержитТип(Тип) Тогда
Результат = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьОписаниеТаблицыБДИис(ИмяТаблицыБД) Экспорт
Возврат ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Найти(НРег(ИмяТаблицыБД), "НПолноеИмя");
КонецФункции
Функция ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт
//ОписаниеТаблицы = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Найти(НРег(ПолноеИмяТаблицыБД), "НПолноеИмя");
//Если ОписаниеТаблицы <> Неопределено Тогда
// Возврат ОписаниеТаблицы.Тип;
//КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
ТипТаблицы = Фрагменты[0];
Если Фрагменты.Количество() > 2 Тогда
ПоследнийФрагмент = Фрагменты[Фрагменты.ВГраница()];
Если Ложь
Или ПоследнийФрагмент = "Изменения"
Или ПоследнийФрагмент = "ДвиженияССубконто"
Или ПоследнийФрагмент = "Границы"
Тогда
ТипТаблицы = ПоследнийФрагмент;
//// Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(МассивФрагментов[0]) Тогда
//// //ТипТаблицы = "ТабличнаяЧасть";
//// ТипТаблицы = МассивФрагментов[2];
//// КонецЕсли;
Иначе
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ОбъектМД = Неопределено Тогда
ТипТаблицы = Фрагменты[2];
Иначе
ТипТаблицы = "ТабличнаяЧасть";
КонецЕсли;
//ИначеЕсли СтрокиРавныЛкс(Фрагменты[2], "ДвиженияССубконто") Тогда
// ТипТаблицы = Фрагменты[0];
ИначеЕсли Фрагменты[0] = "РегистрРасчета" Тогда
ТипТаблицы = "Перерасчет";
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ТипТаблицы = "Внешняя";
Иначе
ТипТаблицы = "ВиртуальнаяТаблица";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ТипТаблицы;
КонецФункции
// ВариантИсточников - Число, *0
// 0 - Основные таблицы
// 1 - Таблицы изменений
// 2 - Внутреннее соединение основных таблиц с их таблицами изменений с отбором по узлу
Функция ПолучитьТекстЗапросаПоВыбраннымТаблицамЛкс(МассивИменОбъектовМД, ВариантИсточников = 0, ПервыеNКаждойТаблицы = 0, ПодключатьПоляКоличестваДвижений = Ложь) Экспорт
ЛитералЗаменыОтсутствующихПолей = "НЕОПРЕДЕЛЕНО"; // NULL нельзя использовать из-за ошибок платформы 8.2.14
// Сначала определим общие реквизиты
ПроверяемыеПоля = Новый Массив;
ТипыОбъектовМД = Новый Структура;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
ТипОбъектаМД = ПолучитьТипТаблицыБДЛкс(ИмяОбъектаМД);
ТипыОбъектовМД.Вставить(ТипОбъектаМД);
КонецЦикла;
Если ТипыОбъектовМД.Количество() > 1 Тогда
ТипОбъектаМД = Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ТипОбъектаМД) Тогда
ирКэш.Получить().ИнициализацияОписанияМетодовИСвойств();
СтрокаКорневогоТипа = ирКэш.Получить().ПолучитьСтрокуТипаМетаОбъектов(ТипОбъектаМД);
Если СтрокаКорневогоТипа <> Неопределено Тогда
СтрокаВида = ирКэш.Получить().ТаблицаИменЭлементовКоллекций.Найти(СтрокаКорневогоТипа.Множественное, "ИмяКоллекции");
Если СтрокаВида <> Неопределено Тогда
Если ирОбщий.СтрокиРавныЛкс(ТипОбъектаМД, "ТабличнаяЧасть") Тогда
ТипОбъектаМД = "Справочник.<Имя справочника>";
КонецЕсли;
ИмяОбщегоТипа = ТипОбъектаМД + "." + СтрокаВида.ИмяЭлементаКоллекции;
Если ВариантИсточников = 1 Тогда
ИмяОбщегоТипа = ИмяОбщегоТипа + ".Изменения";
КонецЕсли;
СтрокиИменПолей = ирКэш.Получить().ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ЯзыкПрограммы", ИмяОбщегоТипа, 1));
Для Каждого СтрокаСлова Из СтрокиИменПолей Цикл
Если Ложь
Или СтрокаСлова.ТипСлова = "Таблица"
Или ПроверяемыеПоля.Найти(СтрокаСлова.Слово) <> Неопределено // Для таблиц бухгалтерии могут быть дубли из-за вариантов с корреспонденцией и без
Тогда
Продолжить;
КонецЕсли;
ПроверяемыеПоля.Добавить(СтрокаСлова.Слово);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Находим максимум общих реквизитов
ОбщиеМетаПоля = Новый Массив;
ЭтоПервыйПроход = Истина;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
ИмяТаблицы = ИмяОбъектаМД;
ОбъектМетаданных = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ИмяОбъектаМД);
Если ВариантИсточников > 0 Тогда
ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных);
Если ЕстьТаблицаИзменений Тогда
Если ВариантИсточников = 1 Тогда
ИмяТаблицы = ИмяОбъектаМД + ".Изменения";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КоллекцияПолей = Новый Массив();
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для Каждого ПолеТаблицы Из ПоляТаблицыБД Цикл
Если ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
ИмяПоля = ПолеТаблицы.Имя;
Если Ложь
Или ПроверяемыеПоля.Найти(ИмяПоля) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
КоллекцияПолей.Добавить(ИмяПоля);
КонецЦикла;
Если ЭтоПервыйПроход Тогда
Для Каждого ИмяПоля Из КоллекцияПолей Цикл
ОбщиеМетаПоля.Добавить(ИмяПоля);
КонецЦикла;
Иначе
НачальноеКоличество = ОбщиеМетаПоля.Количество();
Для СчетчикОбщиеМетаПоля = 1 По НачальноеКоличество Цикл
ИмяПоля = ОбщиеМетаПоля[НачальноеКоличество - СчетчикОбщиеМетаПоля];
Если КоллекцияПолей.Найти(ИмяПоля) = Неопределено Тогда
ОбщиеМетаПоля.Удалить(НачальноеКоличество - СчетчикОбщиеМетаПоля);
КонецЕсли;
КонецЦикла;
Если ОбщиеМетаПоля.Количество() = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
ЭтоПервыйПроход = Ложь;
КонецЦикла;
ТекстОбщихМетаПолей = "";
Для Каждого ИмяПоля Из ОбщиеМетаПоля Цикл
Если Истина
И ЛиКорневойТипСсылкиЛкс(МассивИменОбъектовМД[0])
И ВариантИсточников > 0
Тогда
ИмяПоля = "Ссылка." + ИмяПоля;
КонецЕсли;
ТекстОбщихМетаПолей = ТекстОбщихМетаПолей + ", Т." + ИмяПоля;
КонецЦикла;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(МассивИменОбъектовМД.Количество(), "Генерация текста запроса");
#КонецЕсли
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("");
ЗаписьXMLПустая = Истина;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
ИмяТаблицы = ИмяОбъектаМД;
ОбъектМетаданных = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы);
КорневойТипТаблицы = ирОбщий.ПолучитьПервыйФрагментЛкс(ИмяТаблицы);
ТекстУсловияСоединения = "";
Если ВариантИсточников > 0 Тогда
ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных);
Если ЕстьТаблицаИзменений Тогда
Если ВариантИсточников = 1 Тогда
ИмяТаблицы = ИмяОбъектаМД + ".Изменения";
Иначе
ТекстУсловияСоединения = "_Изменения_.Узел = &Узел";
СтруктураКлючаИзменений = ирОбщий.ПолучитьСтруктуруКлючаТаблицыБДЛкс(ИмяТаблицы + ".Изменения");
Для Каждого КлючИЗначение Из СтруктураКлючаИзменений Цикл
Если ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Ключ, "Узел") Тогда
Продолжить;
КонецЕсли;
Если ТекстУсловияСоединения <> "" Тогда
ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " И";
КонецЕсли;
ТекстУсловияСоединения = ТекстУсловияСоединения + " _Изменения_." + КлючИЗначение.Ключ + " = Т." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстУсловияСоединения = Символы.ПС + " ВНУТРЕННЕЕ СОЕДИНЕНИЕ " + ИмяТаблицы + ".Изменения КАК _Изменения_
| ПО " + ТекстУсловияСоединения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПодключатьПоляКоличестваДвижений Тогда
Если ирОбщий.ЛиКорневойТипДокументаЛкс(КорневойТипТаблицы) Тогда
ТекстОбщееКоличествоДвижений = "";
Для Каждого МетаРегистр Из ОбъектМетаданных.Движения Цикл
ПолноеИмяРегистра = МетаРегистр.ПолноеИмя();
КраткоеИмяРегистра = МетаРегистр.Имя + "_";
ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " { ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ _Регистр_.Регистратор, КОЛИЧЕСТВО(*) КАК КоличествоСтрок
| ИЗ " + ПолноеИмяРегистра + " КАК _Регистр_ СГРУППИРОВАТЬ ПО _Регистр_.Регистратор) КАК " + КраткоеИмяРегистра + "
| ПО " + КраткоеИмяРегистра + ".Регистратор = Т.Ссылка}";
ВыражениеКоличества = "ЕСТЬNULL(" + КраткоеИмяРегистра + ".КоличествоСтрок, 0)";
Если ТекстОбщееКоличествоДвижений <> "" Тогда
ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + " + ";
КонецЕсли;
ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + ВыражениеКоличества;
ТекстОбщееКоличествоДвижений = ВыражениеКоличества + " КАК КоличествоСтрок" + КраткоеИмяРегистра + ", " + ТекстОбщееКоличествоДвижений;
КонецЦикла;
Если ЗначениеЗаполнено(ТекстОбщееКоличествоДвижений) Тогда
ТекстУсловияСоединения = ТекстУсловияСоединения + "
|{ГДЕ " + ТекстОбщееКоличествоДвижений + " КАК КоличествоСтрокВсеРегистры}";
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ВариантИсточников <> 1 Тогда
ТекстНеобязательныхПолей = "";
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для Каждого ПроверяемоеПоле Из ПроверяемыеПоля Цикл
Если ПоляТаблицыБД.Найти(ПроверяемоеПоле, "Имя") = Неопределено Тогда
ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", " + ЛитералЗаменыОтсутствующихПолей + " КАК " + ПроверяемоеПоле;
Иначе
ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", Т." + ПроверяемоеПоле;
КонецЕсли;
КонецЦикла;
//КонецЕсли;
Если Не ЗаписьXMLПустая Тогда
ЗаписьXML.ЗаписатьБезОбработки("
|ОБЪЕДИНИТЬ ВСЕ
|");
КонецЕсли;
ЗаписьXMLПустая = Ложь;
ЗаписьXML.ЗаписатьБезОбработки("ВЫБРАТЬ ");
Если ЗначениеЗаполнено(ПервыеNКаждойТаблицы) Тогда
ЗаписьXML.ЗаписатьБезОбработки("ПЕРВЫЕ " + XMLСтрокаервыеNКаждойТаблицы) + " ");
КонецЕсли;
Если ЗначениеЗаполнено(ТекстНеобязательныхПолей) Тогда
ЗаписьXML.ЗаписатьБезОбработки(Сред(ТекстНеобязательныхПолей, 2) + ", ");
КонецЕсли;
Если ЗначениеЗаполнено(ТекстОбщихМетаПолей) Тогда
ЗаписьXML.ЗаписатьБезОбработки(Сред(ТекстОбщихМетаПолей, 2) + ", ");
КонецЕсли;
ЗаписьXML.ЗаписатьБезОбработки("""" + ИмяТаблицы + """ КАКолноеИмяТаблицы ИЗ " + ИмяТаблицы + " КАК Т" + ТекстУсловияСоединения);
КонецЦикла;
//Если ЗначениеЗаполнено(ПервыеNОбщие) Тогда
// ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрокаервыеNОбщие) + " * ИЗ (" + ТекстЗапроса + ") КАК Т";
//КонецЕсли;
ТекстЗапроса = ЗаписьXML.Закрыть();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Возврат ТекстЗапроса;
КонецФункции
Функция ЕстьТаблицаИзмененийОбъектаМетаданных(ПолноеИмяИлиОбъектМетаданных) Экспорт
ЕстьТаблицаИзменений = Ложь;
Если ТипЗнч(ПолноеИмяИлиОбъектМетаданных) = Тип("Строка") Тогда
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмяИлиОбъектМетаданных);
Если ОбъектМетаданных = Неопределено Тогда
ВызватьИсключение "Объект метаданных не найден """ + ПолноеИмяИлиОбъектМетаданных + """";
КонецЕсли;
Иначе
ОбъектМетаданных = ПолноеИмяИлиОбъектМетаданных;
КонецЕсли;
//// Способ 1
//Для Каждого МетаПланОбмена Из Метаданные.ПланыОбмена Цикл
// Если МетаПланОбмена.Состав.Содержит(ОбъектМетаданных) Тогда // Долго на больших конфигурациях
// ЕстьТаблицаИзменений = Истина;
// Прервать;
// КонецЕсли;
//КонецЦикла;
//// Способ 2
//Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ПолучитьИмяТаблицыИзМетаданныхЛкс(ОбъектМетаданных, Истина) + " КАК Т");
//Попытка
// Запрос.НайтиПараметры(); // Долго, но стабильно. Длительность не зависит от количества планов обмена
// ЕстьТаблицаИзменений = Истина;
//Исключение
// //Описание = ОписаниеОшибки();
// Пустышка = 1;
//КонецПопытки;
//// Способ 3
//Массив = Новый Массив;
//Массив.Добавить(ОбъектМетаданных);
//СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных(Массив); // очень долго
//ЕстьТаблицаИзменений = СтруктураХранения.Найти("РегистрацияИзменений", "Назначение") <> Неопределено;
// Способ 4 Быстрый при небольшом количестве планов обмена, а при большом?
ОбъектыМетаданныхСРегистрациейИзменений = ирКэш.ОбъектыМетаданныхСРегистрациейИзменений();
ЕстьТаблицаИзменений = ОбъектыМетаданныхСРегистрациейИзменений[ОбъектМетаданных.ПолноеИмя()] <> Неопределено;
Возврат ЕстьТаблицаИзменений;
КонецФункции
Функция ПрочитатьНаборЗаписейВТаблицуЛкс(НаборЗаписей, НовыйРежимБлокировки = Неопределено) Экспорт
Если НовыйРежимБлокировки <> Неопределено Тогда
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина, НовыйРежимБлокировки);
КонецЕсли;
ЭтоИмитатор = Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И (Ложь
Или ТипЗнч(НаборЗаписей) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей"));
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
НаборЗаписей = Обработки.ирИмитаторНаборЗаписей.Создать();
#КонецЕсли
НаборЗаписей.Прочитать(, Ложь);
Результат = НаборЗаписей.Выгрузить();
Иначе
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
#КонецЕсли
Данные = НаборЗаписей;
ПолноеИмяМД = НаборЗаписей.Метаданные().ПолноеИмя();
КорневойТип = ирОбщий.ПолучитьПервыйФрагментЛкс(ПолноеИмяМД);
Если КорневойТип = "РегистрБухгалтерии" Тогда
// Чтобы в таблице правильно расставились субконто https://partners.v8.1c.ru/forum/t/1168440/m/1711008
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ Т.*
|ИЗ " + ПолноеИмяМД + ".ДвиженияССубконто(,, Регистратор = &Регистратор) КАК Т
|";
Запрос.УстановитьПараметр("Регистратор", НаборЗаписей.Отбор.Регистратор.Значение);
ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина, РежимБлокировкиДанных.Разделяемый);
// Избавиться от NULL в колонках видов субконто надо, чтобы потом метод Загрузить не выдавал ошибку
Результат = ирОбщий.ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Запрос.Выполнить().Выгрузить());
Иначе
НаборЗаписей.Прочитать();
Результат = НаборЗаписей.Выгрузить();
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект) Экспорт
Структура = Новый Структура;
СтруктураОбменаДанными = СтруктураОбменаДаннымиОбъектаЛкс(Объект);
Если СтруктураОбменаДанными <> Неопределено Тогда
Структура.Вставить("ОбменДанными", СтруктураОбменаДанными);
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойстваXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект.ДополнительныеСвойства);
Структура.Вставить("ДополнительныеСвойстваXML", ДополнительныеСвойстваXML);
КонецЕсли;
Возврат Структура;
КонецФункции
Функция СтруктураОбменаДаннымиОбъектаЛкс(Знач Объект = Неопределено) Экспорт
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Узлы = Новый Массив;
Если ОбменДанными <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
Если Получатели <> Неопределено Тогда
Для Каждого Получатель Из ОбменДанными.Получатели Цикл
Узлы.Добавить(Получатель);
КонецЦикла;
Автозаполнение = ОбменДанными.Получатели.Автозаполнение;
Отправитель = ОбменДанными.Отправитель;
Загрузка = ОбменДанными.Загрузка;
КонецЕсли;
КонецЕсли;
Получатели = Новый Структура;
Получатели.Вставить("Автозаполнение", Автозаполнение = Ложь);
Получатели.Вставить("Узлы", Узлы);
Результат = Новый Структура;
Результат.Вставить("Загрузка", Загрузка = Истина);
Результат.Вставить("Отправитель", Отправитель);
Результат.Вставить("Получатели", Получатели);
Возврат Результат;
КонецФункции // СериализоватьПараметрыОбменаДанными()
Процедура ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств) Экспорт
Если СтруктураДополнительныхСвойств.Свойство("ОбменДанными") Тогда
ВосстановитьСтруктуруОбменаДаннымиОбъектаЛкс(Объект, СтруктураДополнительныхСвойств.ОбменДанными);
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойства = ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураДополнительныхСвойств.ДополнительныеСвойстваXML);
СкопироватьУниверсальнуюКоллекциюЛкс(ДополнительныеСвойства, Объект.ДополнительныеСвойства);
КонецЕсли;
КонецПроцедуры
Процедура ВосстановитьСтруктуруОбменаДаннымиОбъектаЛкс(Знач Объект, Знач СтруктураОбменаДанными) Экспорт
Если СтруктураОбменаДанными = Неопределено Тогда
Возврат;
КонецЕсли;
ОбменДанными = Объект.ОбменДанными;
ЗаполнитьЗначенияСвойств(ОбменДанными, СтруктураОбменаДанными);
Если СтруктураОбменаДанными.Свойство("Получатели") Тогда
ЗаполнитьЗначенияСвойств(ОбменДанными.Получатели, СтруктураОбменаДанными.Получатели);
ОбменДанными.Получатели.Очистить();
Для Каждого Получатель Из СтруктураОбменаДанными.Получатели.Узлы Цикл
ОбменДанными.Получатели.Добавить(Получатель);
КонецЦикла;
КонецЕсли;
КонецПроцедуры // ВосстановитьПараметрыОбменаДаннымиЛкс()
// Записывает объект с параметризованным контекстом (клиент/сервер).
// Обеспечивает запись объекта с попытками. Позволяет обойти неинтенсивные дедлоки и превышения ожиданий блокировки.
// Также обеспечивает обход оптимистичных объектных блокировок в случае, если в БД пишутся точно те же данные объекта, что и актуальные.
// Эффективно для многопоточной записи объектов.
Процедура ЗаписатьОбъектЛкс(Объект, НаСервере = Ложь, РежимЗаписи = Неопределено, РежимПроведения = Неопределено, ОтключатьКонтрольЗаписи = Неопределено,
БезАвторегистрацииИзменений = Неопределено) Экспорт
Если НаСервере Тогда
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
ОбъектXML = Объект.Снимок(, Ложь);
Иначе
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
КонецЕсли;
ирСервер.ЗаписатьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, РежимЗаписи, РежимПроведения, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ТипОбъекта);
Если ЭтоИмитатор Тогда
Объект.ЗагрузитьСнимок(ОбъектXML);
Иначе
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
КонецЕсли;
//#Если Клиент Тогда
// Попытка
// СсылкаОбъекта = Объект.Ссылка;
// Исключение
// КонецПопытки;
// Если СсылкаОбъекта <> Неопределено Тогда
// // При групповых обработках видимо будут большие потери
// ОповеститьОбИзменении(СсылкаОбъекта);
// КонецЕсли;
//#КонецЕсли
Иначе
НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(Объект);
НачалоПопыток = ТекущаяДата();
// Для обхода дедлоков и оптимистичной объектной блокировки при высокой параллельности
Если РежимЗаписи = Неопределено Тогда
ПопытокЗаписиОбъекта = 5;
Иначе
ПопытокЗаписиОбъекта = 3;
КонецЕсли;
ПредельнаяДлительность = 20;
Для СчетчикПопыток = 1 По ПопытокЗаписиОбъекта Цикл
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Попытка
Если РежимЗаписи = Неопределено Тогда
Объект.Записать();
ИначеЕсли РежимЗаписи = "ПометкаУдаления" Тогда
Объект.Записать();
Объект.ОбменДанными.Загрузка = Ложь;
Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда
ПометкаУдаления = Объект.Данные.ПометкаУдаления;
Иначе
ПометкаУдаления = Объект.ПометкаУдаления;
КонецЕсли;
Объект.УстановитьПометкуУдаления(Не ПометкаУдаления);
ИначеЕсли Истина
И ТипЗнч(РежимЗаписи) = Тип("РежимЗаписиДокумента")
И РежимЗаписи <> РежимЗаписиДокумента.Запись
Тогда
Объект.ОбменДанными.Загрузка = Ложь;
Объект.Записать(РежимЗаписи, РежимПроведения);
Иначе
Объект.Записать(РежимЗаписи);
КонецЕсли;
Прервать;
Исключение
НужноВызватьИсключение = Истина;
ОписаниеОшибки = ОписаниеОшибки();
НовоеОписаниеОшибки = "";
Если ТранзакцияАктивна() Тогда
//НовоеОписаниеОшибки = "Транзакция активна" + Символы.ПС + ОписаниеОшибки;
Иначе
НОписаниеОшибки = НРег(ОписаниеОшибки);
Если Истина
И РежимЗаписи = Неопределено
И (Ложь
Или Найти(НОписаниеОшибки, "несоответствия версии или отсутствия записи базы данных") > 0
Или Найти(НОписаниеОшибки, "version mismatch or lack of database record") > 0)
Тогда
НужноВызватьИсключение = Ложь;
ТекущийXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект, Ложь);
//Объект.Прочитать(); // Чтение с блокировкой нам не нужно
ОбъектДляСравнения = ПеречитатьОбъектЗапросомЛкс(Объект);
Если Объект <> Неопределено Тогда
НовыйXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ОбъектДляСравнения, Ложь);
Если ТекущийXML = НовыйXML Тогда
Прервать;
Иначе
Попытка
лРежимЗагрузка = Объект.ОбменДанными.Загрузка;
Исключение
лРежимЗагрузка = Неопределено;
КонецПопытки;
ПолноеИмяМД = Объект.Метаданные().ПолноеИмя();
Если лРежимЗагрузка = Истина И СчетчикПопыток = 2 Тогда
Сообщить("Возможно в обработчиках ПередЗаписью объекта " + ПолноеИмяМД + " в режиме Загрузка выполняется его нестабильная модификация");
КонецЕсли;
НужноВызватьИсключение = СчетчикПопыток = ПопытокЗаписиОбъекта;
Если НужноВызватьИсключение Тогда
НовоеОписаниеОшибки = "Обход оптимистичной блокировки объекта " + ПолноеИмяМД + " отменен из-за его нестабильной модификации в обработчиках ПередЗаписью (Загрузка="
+ XMLСтрока(лРежимЗагрузка) + ")" + Символы.ПС + ОписаниеОшибки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или Найти(ОписаниеОшибки, "взаимоблокировк") > 0
Или Найти(ОписаниеОшибки, "deadlock") > 0
Тогда
НужноВызватьИсключение = Ложь;
КонецЕсли;
КонецЕсли;
Если Не НужноВызватьИсключение Тогда
Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда
//НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(НОписаниеОшибки, Ложь) Тогда
ВызватьИсключение;
КонецЕсли;
#КонецЕсли
Если НужноВызватьИсключение Тогда
СостояниеОбъекта = ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект);
Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта;
Иначе
НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
ВызватьИсключение НовоеОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецЕсли;
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта) Экспорт
ЭтоИмитатор = Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И (Ложь
Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей")
Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторКонстантаМенеджер")
Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект"));
Возврат ЭтоИмитатор;
КонецФункции
// Параметры:
// НаборЗаписейКуда - НаборЗаписей, ирИмитаторНаборЗаписей
// КоллекцияПолученаВыгрузкойНабора - Булево - используется при ЗаполнитьВидыСубконто = Истина
Процедура ЗагрузитьКоллекциюВНаборЗаписейЛкс(КоллекцияСтрокДвижений, НаборЗаписейКуда, ЗаполнитьВидыСубконто = Ложь, КоллекцияПолученаВыгрузкойНабора = Ложь) Экспорт
ТаблицаДляЗагрузки = НаборЗаписейКуда.ВыгрузитьКолонки();
Для Каждого СтрокаНовойТаблицы Из КоллекцияСтрокДвижений Цикл
ЗаполнитьЗначенияСвойств(ТаблицаДляЗагрузки.Добавить(), СтрокаНовойТаблицы);
КонецЦикла;
Если ЗаполнитьВидыСубконто Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(НаборЗаписейКуда));
КорневойТип = ПолучитьПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если КорневойТип = "РегистрБухгалтерии" Тогда
ЗаполнитьВидыСубконтоВТаблицеЛкс(ТаблицаДляЗагрузки, ОбъектМД, КоллекцияПолученаВыгрузкойНабора);
КонецЕсли;
КонецЕсли;
НаборЗаписейКуда.Загрузить(ТаблицаДляЗагрузки);
//ирОбщий.НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(НаборЗаписейКуда); //Теперь это делается в ирОбщий.ЗаписатьОбъектЛкс()
КонецПроцедуры
Процедура ЗаполнитьВидыСубконтоВТаблицеЛкс(ТаблицаДляЗагрузки, ОбъектМД, ТаблицаПолученаВыгрузкойНабора = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаДляЗагрузки = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
ОбъектМД = ТаблицаДляЗагрузки.Метаданные();
#КонецЕсли
СписокСчетов = Новый Массив;
Для Каждого Проводка Из ТаблицаДляЗагрузки Цикл
СписокСчетов.Добавить(Проводка.СчетДт);
СписокСчетов.Добавить(Проводка.СчетКт);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Т.НомерСтроки КАК НомерСтроки,
| Т.ВидСубконто КАК ВидСубконто,
| Т.Ссылка КАК Ссылка
|ИЗ
| " + ОбъектМД.ПланСчетов.ПолноеИмя() + ".ВидыСубконто КАК Т
|ГДЕ
| Т.Ссылка В(&Счет)
|УПОРЯДОЧИТЬ ПО ВидСубконто
|";
// Порядок видов субконто в Набор.Выгрузить() и "ВЫБРАТЬ * ИЗ Регистр" могут не совпадать https://partners.v8.1c.ru/forum/t/1168440/m/1711008
Запрос.УстановитьПараметр("Счет", СписокСчетов);
ТаблицаВидовСубконто = Запрос.Выполнить().Выгрузить();
МассивСторон = Новый Массив;
МассивСторон.Добавить("Дт");
МассивСторон.Добавить("Кт");
Для Каждого Проводка Из ТаблицаДляЗагрузки Цикл
Для Каждого Сторона Из МассивСторон Цикл
СтрокиВидовСубконто = ТаблицаВидовСубконто.НайтиСтроки(Новый Структура("Ссылка", Проводка["Счет" + Сторона]));
Счетчик = 1;
Для Каждого СтрокаВидаСубконто Из СтрокиВидовСубконто Цикл
Если ТаблицаПолученаВыгрузкойНабора Тогда
НомерСубконто = Счетчик;
Иначе
НомерСубконто = СтрокаВидаСубконто.НомерСтроки;
КонецЕсли;
Проводка["ВидСубконто" + Сторона + НомерСубконто] = СтрокаВидаСубконто.ВидСубконто;
Счетчик = Счетчик + 1;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПометкуУдаленияОбъектаЛкс(Объект, НаСервере = Ложь, ЗначениеПометки = Истина, БезАвторегистрацииИзменений = Неопределено) Экспорт
Если НаСервере Тогда
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
ОбъектXML = Объект.Снимок();
Иначе
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
КонецЕсли;
ирСервер.УстановитьПометкуУдаленияОбъектаЛкс(ОбъектXML, ДополнительныеСвойства, ЗначениеПометки);
Если ЭтоИмитатор Тогда
Объект.ЗагрузитьСнимок(ОбъектXML);
Иначе
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
КонецЕсли;
Иначе
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, , БезАвторегистрацииИзменений);
//Если РежимЗаписи = Неопределено Тогда
// Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//Иначе
Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УдалитьОбъектЛкс(Объект, НаСервере = Ложь, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Если НаСервере Тогда
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
ОбъектXML = Объект.Снимок(, Ложь);
Иначе
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
КонецЕсли;
ирСервер.УдалитьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, ТипОбъекта);
#Если Клиент Тогда
ОповеститьОбИзменении(Объект.Ссылка);
#КонецЕсли
Иначе
Объект.Удалить();
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПараметрыЗаписиОбъектаЛкс(Знач Объект, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Если ОбменДанными <> Неопределено Тогда
Если ОтключатьКонтрольЗаписи <> Неопределено Тогда
ОбменДанными.Загрузка = ОтключатьКонтрольЗаписи;
КонецЕсли;
Если БезАвторегистрацииИзменений <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
Если Получатели <> Неопределено Тогда
Получатели.Автозаполнение = Не БезАвторегистрацииИзменений;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Параметры:
// КлючОбъекта - Произвольный, *Неопределено - для нового ссылочного объекта Истина=Папка, для регистров передается Структура
Функция ОбъектБДПоКлючуЛкс(Знач ИмяОсновнойТаблицы, Знач КлючОбъекта = Неопределено, Знач СохранятьИдентификаторСсылки = Ложь, Знач ЧитатьДанныеРегистраИлиКонстанты = Истина,
Знач ОбъектыНаСервере = Неопределено, выхИдентификаторСсылки = Неопределено, РазрешитьВложенныйВызов = Истина, НомерВерсии = Неопределено) Экспорт
Если ОбъектыНаСервере = Неопределено Тогда
#Если Сервер И Не Клиент Тогда
ОбъектыНаСервере = Ложь;
#Иначе
ОбъектыНаСервере = ирОбщий.ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс();
#КонецЕсли
КонецЕсли;
ТипОсновнойТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ИмяОсновнойТаблицы);
ЭтоМетаСсылка = ирОбщий.ЛиТипТаблицыМетассылкиЛкс(ТипОсновнойТаблицы);
РазрешитьИмитаторы = ОбъектыНаСервере <> Ложь И Не ирКэш.ЛиПортативныйРежимЛкс() И Не ЭтоМетаСсылка И Не ирКэш.Получить().НеИспользоватьИмитаторыОбъектовДанных;
мМетаданныеОбъекта = ирОбщий.НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ИмяОсновнойТаблицы, Истина);
Если мМетаданныеОбъекта = Неопределено Тогда
Если ЗначениеЗаполнено(ИмяОсновнойТаблицы) Тогда
ИмяОсновнойТаблицы = Неопределено;
КонецЕсли;
Иначе
мПолноеИмяМД = мМетаданныеОбъекта.ПолноеИмя();
КонецЕсли;
ЭтоСсылочныйОбъект = Ложь
Или ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипОсновнойТаблицы)
Или (Истина
И ТипОсновнойТаблицы = "Внешняя"
И мМетаданныеОбъекта.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Если Истина
И РазрешитьИмитаторы
И РазрешитьВложенныйВызов
И (Ложь
Или ЭтоСсылочныйОбъект
Или ОбъектыНаСервере = "Обязательно")
Тогда
СтруктураСнимка = ирСервер.ПолучитьСнимокОбъектаБДПоКлючуЛкс(ИмяОсновнойТаблицы, КлючОбъекта, СохранятьИдентификаторСсылки, ЧитатьДанныеРегистраИлиКонстанты, выхИдентификаторСсылки, НомерВерсии);
Если СтруктураСнимка <> Неопределено Тогда
Имитатор = Новый (СтруктураСнимка.ТипОбъекта);
Имитатор.ЗагрузитьСнимок(СтруктураСнимка.Снимок);
Результат = Новый Структура;
Результат.Вставить("Методы", Имитатор);
Результат.Вставить("Данные", Имитатор.Данные);
КонецЕсли;
Иначе
ЭтоКонстанта = ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипОсновнойТаблицы);
ЭтоПланОбмена = ирОбщий.ЛиКорневойТипПланаОбменаЛкс(ТипОсновнойТаблицы);
ЭтоДокумент = ирОбщий.ЛиКорневойТипДокументаЛкс(ТипОсновнойТаблицы);
//ЭтоВнешнийОбъект = ТипОсновнойТаблицы = "Внешняя";
Если Ложь
Или Не ЗначениеЗаполнено(ТипОсновнойТаблицы)
Или (Истина
И ЭтоСсылочныйОбъект
И ТипЗнч(КлючОбъекта) = Тип("Строка"))
Тогда
Возврат Неопределено;
КонецЕсли;
Результат = Новый Структура;
Если ЭтоСсылочныйОбъект Тогда
Если ЭтоМетаСсылка Тогда
Объект = КлючОбъекта;
выхСтруктураОбъекта = КлючОбъекта;
Данные = Объект;
Методы = Объект;
Иначе
Если Истина
//И ЧитатьДанные
И ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта))
И ЗначениеЗаполнено(КлючОбъекта)
Тогда
Если ЗначениеЗаполнено(НомерВерсии) Тогда
ИсторияДанныхМоя = Вычислить("ИсторияДанных");
#Если Сервер И Не Сервер Тогда
ИсторияДанныхМоя = ИсторияДанных;
#КонецЕсли
Объект = ИсторияДанныхМоя.СформироватьПоВерсии(КлючОбъекта, НомерВерсии);
Объект.ДополнительныеСвойства.Вставить("НомерЗагруженнойВерсии", НомерВерсии);
Иначе
Объект = КлючОбъекта.ПолучитьОбъект();
//Если Объект <> Неопределено Тогда
// Объект.Прочитать(); // Получаем гарантировано свежие данные мимо объектного кэша, но объектный кэш не обновится https://partners.v8.1c.ru/forum/topic/1383852
//КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Объект = Неопределено Тогда
Если ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта)) Тогда
выхИдентификаторСсылки = КлючОбъекта.УникальныйИдентификатор();
ИначеЕсли Не СохранятьИдентификаторСсылки Тогда
выхИдентификаторСсылки = Неопределено;
КонецЕсли;
Если КлючОбъекта <> "" Тогда
ЭтоГруппаДляНового = КлючОбъекта = Истина;
Попытка
Объект = ирОбщий.СоздатьСсылочныйОбъектПоМетаданнымЛкс(мПолноеИмяМД, ЭтоГруппаДляНового, выхИдентификаторСсылки);
Исключение
// Может не быть прав на создание объекта
Сообщить("Ошибка создания объекта: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецЕсли;
КонецЕсли;
Данные = Объект;
Методы = Объект;
//#Если Не Клиент И Сервер Тогда
Если РазрешитьИмитаторы Тогда
ИмитаторОбъекта = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторСсылочныйОбъект");
#Если Сервер И Не Сервер Тогда
ИмитаторОбъекта = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
ИмитаторОбъекта.Конструктор(Объект);
Данные = ИмитаторОбъекта.Данные;
Методы = ИмитаторОбъекта;
КонецЕсли;
//#КонецЕсли
КонецЕсли;
Иначе
Если РазрешитьИмитаторы Тогда
Если ЭтоКонстанта Тогда
ИмитаторОбъекта = Обработки.ирИмитаторКонстантаМенеджер.Создать();
ИмитаторОбъекта.КонструкторПоКлючу(ИмяОсновнойТаблицы);
Иначе
ИмитаторОбъекта = Обработки.ирИмитаторНаборЗаписей.Создать();
ИмитаторОбъекта.КонструкторПоКлючу(ИмяОсновнойТаблицы, КлючОбъекта);
КонецЕсли;
Данные = ИмитаторОбъекта.Данные;
Методы = ИмитаторОбъекта;
Иначе
Если ЭтоКонстанта Тогда
Объект = Новый (СтрЗаменить(ИмяОсновнойТаблицы, ".", "МенеджерЗначения."));
Иначе
Объект = Новый (ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяОсновнойТаблицы));
#Если Сервер И Не Сервер Тогда
Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
#КонецЕсли
Если КлючОбъекта <> Неопределено Тогда
ЗаполнитьОтборПоКлючуЛкс(Объект.Отбор, КлючОбъекта);
КонецЕсли;
КонецЕсли;
Данные = Объект;
Методы = Объект;
КонецЕсли;
Если ЧитатьДанныеРегистраИлиКонстанты Тогда
Методы.Прочитать();
КонецЕсли;
КонецЕсли;
Результат.Вставить("Данные", Данные);
Результат.Вставить("Методы", Методы);
Возврат Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьОтборПоКлючуЛкс(Знач Отбор, Знач КлючОбъекта) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый ПостроительЗапроса;
Отбор = Пустышка.Отбор;
#КонецЕсли
Для Каждого ЭлементОтбора Из Отбор Цикл
СтруктураЧтенияЗначения = Новый Структура(ЭлементОтбора.Имя, null);
ЗаполнитьЗначенияСвойств(СтруктураЧтенияЗначения, КлючОбъекта);
Если СтруктураЧтенияЗначения[ЭлементОтбора.Имя] <> Null Тогда
Отбор[ЭлементОтбора.Имя].Установить(КлючОбъекта[ЭлементОтбора.Имя]);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ТипОбъектаБДЛкс(ОбъектБД) Экспорт
Результат = ТипЗнч(ОбъектБД);
Если Результат = Тип("Структура") Тогда
Имитатор = ОбъектБД.Методы;
Иначе
Имитатор = ОбъектБД;
КонецЕсли;
Результат = ТипЗнч(Имитатор);
Если ЭтоТипИмитатораОбъектаЛкс(Результат) Тогда
Результат = Имитатор._Тип;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция КопияОбъектаБДЛкс(СтруктураОбъекта) Экспорт
СтруктураОбъекта = СтруктураОбъекта.Методы.Скопировать();
Если ТипЗнч(СтруктураОбъекта) <> Тип("Структура") Тогда
СтруктураОбъектаНовая = Новый Структура;
СтруктураОбъектаНовая.Вставить("Методы", СтруктураОбъекта);
СтруктураОбъектаНовая.Вставить("Данные", СтруктураОбъекта);
СтруктураОбъекта = СтруктураОбъектаНовая;
КонецЕсли;
Возврат СтруктураОбъекта;
КонецФункции
Функция СкопироватьТаблицуЛкс(ТаблицаИлиТабличнаяЧасть, ПараметрыОтбора = Неопределено, Колонки = Неопределено) Экспорт
Если ТипЗнч(ТаблицаИлиТабличнаяЧасть) = Тип("ТаблицаЗначений") Тогда
Результат = ТаблицаИлиТабличнаяЧасть.Скопировать(ПараметрыОтбора, Колонки);
Иначе
Результат = ТаблицаИлиТабличнаяЧасть.Выгрузить(ПараметрыОтбора, Колонки);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект)
Попытка
ДополнительныеСвойства = Объект.ДополнительныеСвойства;
Исключение
ДополнительныеСвойства = Новый Структура;
КонецПопытки;
СостояниеОбъекта = "";
Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл
Если ЛиСсылкаНаОбъектБДЛкс(КлючИЗначение.Значение) И ТранзакцияАктивна() Тогда
// На случай сломанной транзакции
ПредставлениеЗначения = ирОбщий.ПолныйИдентификаторСсылкиЛкс(КлючИЗначение.Значение);
Иначе
ПредставлениеЗначения = "" + КлючИЗначение.Значение;
КонецЕсли;
СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + ПредставлениеЗначения;
КонецЦикла;
Возврат СостояниеОбъекта;
КонецФункции
Функция ПрочитатьДвиженияДокументаПакетноЛкс(Ссылка, ОбъектыНаСервере = Неопределено, ТолькоКоличествоСтрок = Ложь) Экспорт
ОбъектМД = Ссылка.Метаданные();
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, Истина, Истина);
Результат = Новый Соответствие;
Если ОбъектыМД.Количество() > 0 Тогда
Текст = "";
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Текст <> "" Тогда
Текст = Текст + ";" + Символы.ПС;
КонецЕсли;
ПолноеИмяМДРегистра = МетаРегистр.ПолноеИмя();
ИмяТаблицыБДРегистра = ПолучитьИмяТаблицыИзМетаданныхЛкс(МетаРегистр);
Если ТолькоКоличествоСтрок Тогда
Текст = Текст + "ВЫБРАТЬ Количество(*)";
Иначе
Текст = Текст + "ВЫБРАТЬ Т.*";
КонецЕсли;
Если ПолучитьТипТаблицыБДЛкс(ИмяТаблицыБДРегистра) = "ДвиженияССубконто" Тогда
Текст = Текст + "
|ИЗ " + ИмяТаблицыБДРегистра + "(,, Регистратор = &Ссылка) КАК Т";
Иначе
ИмяПоляОтбора = ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра);
Текст = Текст + "
|ИЗ " + ИмяТаблицыБДРегистра + " КАК Т
|ГДЕ Т." + ИмяПоляОтбора + " = &Ссылка";
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст = Текст;
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатПакета = Запрос.ВыполнитьПакет();
ИндексВПакете = 0;
Для Каждого МетаРегистр из ОбъектыМД Цикл
ПолноеИмяМДРегистра = МетаРегистр.ПолноеИмя();
ИмяТаблицыБДРегистра = ПолучитьИмяТаблицыИзМетаданныхЛкс(МетаРегистр);
Результат[ПолноеИмяМДРегистра] = РезультатПакета[ИндексВПакете].Выгрузить();
Если ТолькоКоличествоСтрок Тогда
Результат[ПолноеИмяМДРегистра] = Результат[ПолноеИмяМДРегистра][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=", Символы.ПС);
НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения);
Если НовыйКаталог.Существует() Тогда
КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения;
Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла;
Файл = Новый Файл(Результат);
ФайлСуществует = Файл.Существует();
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ФайлСуществует Тогда
Результат = Неопределено;
выхВариантРасположенияФайлаНастроек = Неопределено;
Иначе
выхДатаИзменения = Файл.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьТекстКонфигурационногоФайлаВнешнихСоединенийЛкс(АдресОтладчика = "") Экспорт
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст("
|<config xmlns=""http://v8.1c.ru/v8/comcntrcfg"">
//| <debugconfig debug=""true"" debuggerURL=""" + АдресОтладчика + """/>
| <debugconfig debug=""true""/>
|</config>"
);
Возврат ТекстовыйДокумент;
КонецФункции
Функция ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере = Ложь) Экспорт
Результат = ПолучитьПолноеИмяФайлаНастройкиПриложения1СЛкс("logcfg.xml", НаСервере);
Возврат Результат;
КонецФункции
Функция ПолучитьКаталогТехножурналаЛкс(НаСервере = Ложь) Экспорт
ИмяФайлаНастроекЖурнала = ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере);
Если ЗначениеЗаполнено(ИмяФайлаНастроекЖурнала) Тогда
ТекстХМЛ = ПрочитатьТекстИзФайлаЛкс(ИмяФайлаНастроекЖурнала, , НаСервере);
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.УстановитьСтроку(ТекстХМЛ);
ПостроительДом = Новый ПостроительDOM();
Попытка
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеХМЛ);
Исключение
Сообщить("Ошибка чтения настройки техножурнала: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Если ДокументДОМ <> Неопределено Тогда
Узлы = ДокументДом.ПолучитьЭлементыПоИмени("log");
Если Узлы.Количество() > 0 Тогда
Атрибут = Узлы.Элемент(0).Атрибуты.ПолучитьИменованныйЭлемент("location");
Если Атрибут <> Неопределено Тогда
Результат = Атрибут.ТекстовоеСодержимое;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТехножурналВключенЛкс(НаСервере = Ложь, ВыводитьСообщения = Ложь) Экспорт
КаталогЖурнала = "";
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
Если НаСервере Тогда
#Если Клиент Тогда
КаталогЖурнала = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогЖурналаСервера");
КаталогЖурналаВзятИзНастроекЧтения = Истина;
#КонецЕсли
КонецЕсли;
Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда
КаталогЖурнала = ПолучитьКаталогТехножурналаЛкс(НаСервере);
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
КонецЕсли;
Если ЗначениеЗаполнено(КаталогЖурнала) Тогда
Если Не ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере, ВыводитьСообщения) Тогда
Возврат Истина;
Иначе
Если ВыводитьСообщения Тогда
Если КаталогЖурналаВзятИзНастроекЧтения Тогда
Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в настройках чтения анализа техножурнала", СтатусСообщения.Внимание);
Иначе
Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в текущей настройке техножурнала", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ВыводитьСообщения Тогда
Если НаСервере Тогда
Сообщить("Каталог техножурнала сервера не удалось прочитать из текущей настройки техножурнала и не задан в настройках чтения инструмента ""Анализ техножурнала""");
Иначе
Сообщить("Каталог техножурнала клиента не удалось прочитать из текущей настройки техножурнала");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьСообщения = Истина) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала);
Иначе
Результат = Ложь;
ФайлКаталог = Новый Файл(КаталогЖурнала);
Если Не ФайлКаталог.Существует() Тогда
Результат = Истина;
Иначе
БлокирующиеФайлы = НайтиФайлы(КаталогЖурнала, "*.*");
Для Каждого БлокирующийФайл Из БлокирующиеФайлы Цикл
Если Не БлокирующийФайл.ЭтоКаталог() Тогда
Если ВыводитьСообщения Тогда
ТекстСообщения = "В корне каталога """ + КаталогЖурнала + """ техножурнала ";
Если НаСервере Тогда
ТекстСообщения = ТекстСообщения + "сервера";
Иначе
ТекстСообщения = ТекстСообщения + "клиента";
КонецЕсли;
Сообщить(ТекстСообщения + " обнаружены блокирующие файлы. Для работы журнала их необходимо удалить.",
СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиКлиентЗапущенНаКомпьютереСервераЛкс() Экспорт
Результат = НРег(ирСервер.ПолучитьИмяКомпьютераЛкс()) = НРег(ИмяКомпьютера());
Возврат Результат;
КонецФункции
Функция ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ТекстовыйДокумент.Записать(ИмяВременногоФайла, Кодировка);
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
мПлатформа.ПереместитьФайлКакАдминистратор(ИмяВременногоФайла, ПолноеИмяФайла);
КонецЕсли;
КонецФункции
Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ПолноеИмяФайла, Кодировка);
Результат = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах);
Иначе
Файлы = НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах);
Результат = Новый Массив;
Для Каждого Файл Из Файлы Цикл
Результат.Добавить(Файл.ПолноеИмя);
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ИзданиеПлатформы - Строка(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=""" + КаталогПустойИнфобазы + """;";
КонецЕсли;
СтрокаСоединенияБазы = "/IBConnectionString" + ПолучитьСтрокуСКавычкамиДляКоманднойСтрокиЛкс(СтрокаСоединенияБазы);
КодВозврата = Неопределено;
ИмяФайлаЛога = ПолучитьИмяВременногоФайла("txt");
Если Не ЗначениеЗаполнено(ПолноеИмяИсполняемогоФайла) Тогда
ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс();
КонецЕсли;
ПараметрыПакетногоЗапуска = "DESIGNER /Out""" + ИмяФайлаЛога + """ " + СтрокаСоединенияБазы + " " + КомандаКонфигуратора;
Если ПодавлятьДиалоги Тогда
ПараметрыПакетногоЗапуска = ПараметрыПакетногоЗапуска + " /DisableStartupDialogs /DisableStartupMessages";
КонецЕсли;
ЗапуститьПриложение("""" + ПолноеИмяИсполняемогоФайла + """ " + ПараметрыПакетногоЗапуска,, ДождатьсяЗавершения, КодВозврата);;
ФайлЛога = Новый Файл(ИмяФайлаЛога);
Если ФайлЛога.Существует() Тогда
ТекстовыйДокументЛога = Новый ТекстовыйДокумент;
ТекстовыйДокументЛога.Прочитать(ФайлЛога.ПолноеИмя);
выхТекстЛога = ТекстовыйДокументЛога.ПолучитьТекст();
КонецЕсли;
Возврат КодВозврата = 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";
КонецЕсли;
ПараметрыЗапускаДляОтладки = ПараметрыЗапускаДляОтладки + " " + СтрокаОтладчика;
Возврат ПараметрыЗапускаДляОтладки;
КонецФункции
// Создает COM объект клиента 1C и подключает его к базе по указанной строке соединения.
// Параметры:
// СтрокаСоединения - Строка
// ИмяПользователя - Строка
// ПарольПользователя - Строка
// ТипCOMОбъекта - Строка, *"Application" - "Application" или "ComConnector"
// Видимость - Булево - для Application
// ОбработатьИсключениеПодключения - Булево, *Ложь - при Истина исключение обрабатывается внутри метода и возвращется его описание в качестве результата
// ИмяСервераПроцессов - Строка - имя сервера, на котором создавать COM объект
//
// Возвращаемое значение:
// COMОбъект - клиента 1C, Строка - описание исключения
//
Функция СоздатьСеансИнфобазы1С8Лкс(Знач СтрокаСоединения = "", Знач ИмяПользователя = "", Знач ПарольПользователя = "",
Знач ТипCOMОбъекта = "Application", Знач Видимость = Ложь, Знач ОбработатьИсключениеПодключения = Ложь,
ОписаниеОшибки = "", ИмяСервераПроцессов = "", КодРазрешения = "") Экспорт
ДопСтрокаСоединения = "";
Если ЗначениеЗаполнено(ИмяПользователя) Тогда
ДопСтрокаСоединения = ДопСтрокаСоединения + "Usr=""" + ИмяПользователя + """;" + "Pwd=""" + ПарольПользователя + """;";
КонецЕсли;
Если ЗначениеЗаполнено(КодРазрешения) Тогда
ДопСтрокаСоединения = ДопСтрокаСоединения + "UC=""" + КодРазрешения + """;";
КонецЕсли;
#Если Клиент Тогда
Состояние("Подключение к базе через COM...");
#КонецЕсли
ИмяCOMКласса = "v" + ирКэш.НомерИзданияПлатформыЛкс();
Если Найти(ТипCOMОбъекта, ".") = 0 Тогда
ИмяCOMКласса = ИмяCOMКласса + ".";
КонецЕсли;
ИмяCOMКласса = ИмяCOMКласса + ТипCOMОбъекта;
Попытка
Соединение = Новый COMОбъект(ИмяCOMКласса, ИмяСервераПроцессов);
Исключение
ВызватьИсключение "Ошибка создания COM объекта " + ИмяCOMКласса + ": " + ОписаниеОшибки();
КонецПопытки;
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПолнаяСтрокаСоединения = СтрокаСоединения + ДопСтрокаСоединения;
Попытка
РезультатСоединения = Соединение.Connect(ПолнаяСтрокаСоединения);
Исключение
#Если Клиент Тогда
Состояние("");
#КонецЕсли
Если ОбработатьИсключениеПодключения Тогда
ОписаниеОшибки = ОписаниеОшибки();
Возврат ОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
#Если Клиент Тогда
Состояние("");
#КонецЕсли
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Найти(ТипCOMОбъекта, "Application") > 0 Тогда
#Если Клиент Тогда
Состояние("Ожидание инициализации сеанса...");
Для Счетчик = 1 По 20 Цикл
ОбработкаПрерыванияПользователя();
Попытка
Соединение.Visible = Видимость;
Прервать;
Исключение
// Тонкий клиент еще не готов
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
мПлатформа.Sleep(1);
КонецЦикла;
Состояние("");
Результат = Соединение;
#КонецЕсли
ИначеЕсли Найти(ТипCOMОбъекта, "ComConnector") > 0 Тогда
Результат = РезультатСоединения;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗапуститьСеансПодПользователемЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта = "", РежимЗапуска = "Авто", КодРазрешения = "",
СообщитьКоманднуюСтроку = Ложь, ОткрытьПортативныеИнструменты = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Истина, РазрешитьОтладку = Истина, ДополнительныеПараметры = "",
РежимИнтерфейсаТакси = Ложь, Элевация = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь) Экспорт
Если ЗначениеЗаполнено(ТипCOMОбъекта) Тогда
Соединение = СоздатьСеансИнфобазы1С8Лкс(, ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта, Истина,,,, КодРазрешения);
Иначе
#Если Клиент Тогда
//Если ирКэш.НомерВерсииПлатформыЛкс() = 802015 Тогда
// Предупреждение("В релиза 8.2.15 функция недоступна", 20); // Антибаг платформы 8.2.15
// Возврат;
//КонецЕсли;
Если РежимЗапуска = "Авто" Тогда
// Антибаг платформы. При передачи этого режима в явном виде в некоторых случаях пароль в командной строке игнорируется
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяИнфобазы);
Если ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда
КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий";
ИначеЕсли ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Тогда
КонечныйРежимЗапуска = "ОбычноеПриложение";
Иначе //Авто
Если Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда
КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий";
Иначе
КонечныйРежимЗапуска = "ОбычноеПриложение";
КонецЕсли;
КонецЕсли;
Иначе
КонечныйРежимЗапуска = РежимЗапуска;
КонецЕсли;
ПараметрыЗапуска = ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, КодРазрешения, Ложь, КонечныйРежимЗапуска,
РазрешитьОтладку, ОчисткаКэшаКлиентСерверныхВызовов, ДополнительныеПараметры, СообщитьКоманднуюСтроку, , ОткрытьПортативныеИнструменты, РежимИнтерфейсаТакси,
РазделениеДанных, ОтключитьАутентификациюОС);
ТекущаяДата = ирСервер.ПолучитьТекущуюДатуЛкс();
Если КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий" Тогда
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8c.exe"" " + ПараметрыЗапуска;
ЗапуститьПриложение(СтрокаЗапуска);
Иначе
Если Элевация Тогда
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + ПараметрыЗапуска;
Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска,,,, Ложь, Истина);
Иначе
ЗапуститьСистему(ПараметрыЗапуска);
КонецЕсли;
КонецЕсли;
Состояние("Ожидание запуска сеанса...");
Успех = Ложь;
ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс();
Пока Не Успех Цикл
ОбработкаПрерыванияПользователя();
Если ирСервер.ПолучитьТекущуюДатуЛкс() - ДатаПоследнегоВопроса >= 5 Тогда
Ответ = Вопрос("Продолжить ожидание сеанса (5 сек)?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Прервать;
КонецЕсли;
ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс();
КонецЕсли;
Сеансы = ПолучитьСеансыИнформационнойБазы();
Успех = Ложь;
Для Каждого Сеанс Из Сеансы Цикл
Если Истина
И Сеанс.НачалоСеанса >= ТекущаяДата
И НРег(Сеанс.ИмяКомпьютера) = НРег(ИмяКомпьютера())
И Сеанс.Пользователь <> Неопределено
И НРег(Сеанс.Пользователь.Имя) = НРег(ИмяПользователяИнфобазы)
Тогда
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Состояние("");
#Иначе
ВызватьИсключение "Запуск приложения допускается только на клиенте";
#КонецЕсли
КонецЕсли;
Возврат Соединение;
КонецФункции
// Параметры:
// XML -
// Тип -
// ИспользоватьXDTO -
// СообщатьОбОшибках -
//
Функция ВосстановитьОбъектИзСтрокиXMLЛкс(Знач ФайлИлиXML = "", Знач Тип = "", Знач ИспользоватьXDTO = Истина, Знач СообщатьОбОшибках = Истина) Экспорт
Если Ложь
Или ТипЗнч(ФайлИлиXML) = Тип("Файл")
Или ЗначениеЗаполнено(ФайлИлиXML)
Тогда
ЧтениеXML = Новый ЧтениеXML;
Если ТипЗнч(ФайлИлиXML) = Тип("Файл") Тогда
ЧтениеXML.ОткрытьФайл(ФайлИлиXML.ПолноеИмя);
Иначе
ЧтениеXML.УстановитьСтроку(ФайлИлиXML);
КонецЕсли;
Попытка
Если ИспользоватьXDTO Тогда
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Иначе
Результат = ПрочитатьXML(ЧтениеXML);
КонецЕсли;
Исключение
Если СообщатьОбОшибках Тогда
Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
КонецЕсли;
ЧтениеXML.Закрыть();
КонецПопытки;
// Антибаг платформы 8.2-8.3.6 СериализаторXDTO некорректно восстанавливает пустую табличную часть поверх непустой https://partners.v8.1c.ru/forum/t/1329468/m/1329468
Попытка
Пустышка = Результат.Модифицированность();
МетаТЧи = Результат.Метаданные().ТабличныеЧасти;
Исключение
МетаТЧи = Новый Массив;
КонецПопытки;
Для Каждого МетаТЧ Из МетаТЧи Цикл
ТЧ = Результат[МетаТЧ.Имя];
Если ТЧ.Количество() = 0 Тогда
Попытка
ТЧ.Вставить(0);
Исключение
// Недоступна по разделению группа/элемент с неадекватной ошибкой https://partners.v8.1c.ru/forum/t/1374212/m/1374212
Продолжить;
КонецПопытки;
ТЧ.Удалить(0);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Результат = Неопределено Тогда
Если ЗначениеЗаполнено(Тип) Тогда
Результат = Новый (Тип);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВосстановитьНастройкуКомпоновкиИзСтрокиXMLЛкс(Знач XML = "", Знач СообщатьОбОшибках = Истина) Экспорт
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(XML, Тип("НастройкиКомпоновкиДанных"), , СообщатьОбОшибках);
Возврат Результат;
КонецФункции
// Параметры:
// Объект -
// ИспользоватьXDTO -
//
Функция СохранитьОбъектВВидеСтрокиXMLЛкс(Знач Объект, Знач ИспользоватьXDTO = Истина, ИмяФайла = "", ВызыватьИсключение = Истина, Поток = Неопределено) Экспорт
ЭтоВременныйПоток = Поток = Неопределено;
Если ЭтоВременныйПоток Тогда
Поток = Новый ЗаписьXML;
Если ЗначениеЗаполнено(ИмяФайла) Тогда
Попытка
Поток.ОткрытьФайл(ИмяФайла);
Исключение
ВызватьИсключение ОписаниеОшибки(); // Чтобы в диалоге "Вычислить выражение" полное описание показывалось
КонецПопытки;
Иначе
Поток.УстановитьСтроку();
КонецЕсли;
КонецЕсли;
Результат = Неопределено;
ТипОбъекта = ТипЗнч(Объект);
ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта);
Если ЭтоИмитатор Тогда
#Если Сервер И Не Сервер Тогда
Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать();
#КонецЕсли
Результат = Объект.ДанныеВСтрокуXMLЧерезXDTO(ИспользоватьXDTO, ВызыватьИсключение);
Поток.ЗаписатьБезОбработки(Результат); // Криво
Иначе
Попытка
Если ИспользоватьXDTO Тогда
СериализаторXDTO.ЗаписатьXML(Поток, Объект);
Иначе
ЗаписатьXML(Поток, Объект);
КонецЕсли;
Исключение
Если ЭтоВременныйПоток Тогда
Поток.Закрыть();
КонецЕсли;
Если ВызыватьИсключение Тогда
ВызватьИсключение;
КонецЕсли;
Поток = Неопределено;
КонецПопытки;
Если Поток <> Неопределено Тогда
Если ЭтоВременныйПоток Тогда
Результат = Поток.Закрыть();
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗаписатьОбъектДляОтладкиЛкс(Объект, АдресРезультата = Неопределено) Экспорт
Если ТранзакцияАктивна() Тогда
лАдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
Параметры = Новый Массив();
Параметры.Добавить(СтрокаХМЛ);
Параметры.Добавить(лАдресРезультата);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗаписатьОбъектДляОтладкиЛкс", Параметры,, "Запись объекта для отладки (ИР)");
ФоновоеЗадание.ОжидатьЗавершения(3);
Результат = ПолучитьИзВременногоХранилища(лАдресРезультата);
Иначе
Если ТипЗнч(Объект) = Тип("Строка") Тогда
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(Объект);
КонецЕсли;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
Результат = "Объект для отладки";
ирОбщий.СохранитьЗначениеЛкс(Результат, Объект);
Иначе
Объект.Записать();
Результат = Объект.Ссылка;
КонецЕсли;
Если АдресРезультата <> Неопределено Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(КоллекцияСтрок, БазовоеИмяИлиСтрока, ИмяКлючевойКолонки = "Имя", ИмяДолжноБытьИдентификатором = Истина,
ЗаменаПустойСтроки = "_", Знач ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке = 50) Экспорт
ТекущийИндекс = 0;
Если ТипЗнч(БазовоеИмяИлиСтрока) = Тип("Строка") Или БазовоеИмяИлиСтрока = Неопределено Тогда
БазовоеИмя = БазовоеИмяИлиСтрока;
Иначе
ИсключаемаяСтрока = БазовоеИмяИлиСтрока;
БазовоеИмя = БазовоеИмяИлиСтрока[ИмяКлючевойКолонки];
//ТекущийИндекс = 1;
КонецЕсли;
Если ТипЗнч(КоллекцияСтрок) = Тип("ТаблицаЗначений") Тогда
Колонки = КоллекцияСтрок.Колонки;
ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда
Если КоллекцияСтрок.Количество() > 0 Тогда
Колонки = КоллекцияСтрок[0].Владелец().Колонки;
КонецЕсли;
Иначе // Табличная часть
Колонки = КоллекцияСтрок.ВыгрузитьКолонки().Колонки;
КонецЕсли;
Если ИмяДолжноБытьИдентификатором Тогда
ДопустимаяДлинаИдентификатора = Колонки[ИмяКлючевойКолонки].ТипЗначения.КвалификаторыСтроки.Длина;
Если Не ЗначениеЗаполнено(ДопустимаяДлинаИдентификатора) Тогда
ДопустимаяДлинаИдентификатора = ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
БазовоеИмя = мПлатформа.ПолучитьИдентификаторИзПредставления(БазовоеИмя, ЗаменаПустойСтроки);
БазовоеИмя = Лев(БазовоеИмя, ДопустимаяДлинаИдентификатора);
Иначе
Если ПустаяСтрока(БазовоеИмя) Тогда
БазовоеИмя = ЗаменаПустойСтроки;
КонецЕсли;
КонецЕсли;
Пока Истина Цикл
ТекущийПсевдоним = БазовоеИмя + Формат(ТекущийИндекс, "ЧГ=");
СтрокиОдноименных = КоллекцияСтрок.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ТекущийПсевдоним));
Если Ложь
Или СтрокиОдноименных.Количество() = 0
Или (Истина
И СтрокиОдноименных.Количество() = 1
И ИсключаемаяСтрока <> Неопределено
И СтрокиРавныЛкс(ТекущийПсевдоним, ИсключаемаяСтрока[ИмяКлючевойКолонки])
)
Тогда
Прервать;
КонецЕсли;
ТекущийИндекс = ТекущийИндекс + 1;
КонецЦикла;
Возврат ТекущийПсевдоним;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ЭлементОтбора - <тип> -
// Сравнение - <тип>, "" -
// Значение - <тип> -
// ЗначениеПо - <тип> -
// Использование - <тип>, Истина -
// ПриводитьТипДляНеопределено - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Сравнение = "", Знач Значение, Знач ЗначениеПо = Неопределено, Знач Использование = Истина,
Знач ПриводитьТипДляНеопределено = Истина) Экспорт
Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда
Значение = Новый Массив(Значение);
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
ИначеЕсли Истина
И ПриводитьТипДляНеопределено
И Значение = Неопределено
Тогда
Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(Значение);
КонецЕсли;
// Вид сравнения
Если СтрокиРавныЛкс(Сравнение, "Авто") Тогда
Сравнение = ОпределитьВидСравненияПоЗначениюЛкс(Значение);
ИначеЕсли ТипЗнч(Сравнение) = Тип("ВидСравнения") Тогда
ИначеЕсли Истина
И Сравнение <> Неопределено
И Сравнение <> ""
Тогда // Добавлено 25.03.2012
ВызватьИсключение "Неверный тип сравнения """ + ТипЗнч(Сравнение) + """";
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравнения.ВСписке;
Иначе
Сравнение = ВидСравнения.Равно;
КонецЕсли;
КонецЕсли;
// Еще надо сделать автоопределение Сожержит, как у компоновки
ЭлементОтбора.ВидСравнения = Сравнение;
Попытка
Если ЗначениеПо <> Неопределено Тогда
ЭлементОтбора.ЗначениеС = Значение;
ЭлементОтбора.ЗначениеПО = ЗначениеПо;
Иначе
ЭлементОтбора.Значение = Значение;
КонецЕсли;
Исключение
ВызватьИсключение "Ошибка установки значения типа """ + ТипЗнч(Значение) + """ элементу отбора """ + ЭлементОтбора.Имя + """: " + ОписаниеОшибки();
КонецПопытки;
Попытка
ЭлементОтбора.Использование = Использование;
Исключение
// Сюда попадаем для элемента отбора набора записей с регистратором
КонецПопытки;
КонецФункции
// Установить отбор по структуре
//
// Параметры:
// Отбор - <тип> -
// СтруктураОтбора - <тип> -
// Сравнение - <тип>, "Авто" -
// ДобавлятьСсылкуВПутьКДанным - <тип>, Ложь -
// СброситьПередУстановкой - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьОтборПоСтруктуреЛкс(Знач Отбор, Знач СтруктураОтбора, Знач Сравнение = "Авто", Знач ДобавлятьСсылкуВПутьКДанным = Ложь,
Знач СброситьПередУстановкой = Истина) Экспорт
Если СброситьПередУстановкой Тогда
Отбор.Сбросить();
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ПутьКДанным = КлючИЗначение.Ключ;
Если ДобавлятьСсылкуВПутьКДанным Тогда
ПутьКДанным = "Ссылка." + ПутьКДанным;
КонецЕсли;
НайтиДобавитьЭлементОтбораЛкс(Отбор, ПутьКДанным, Сравнение, КлючИЗначение.Значение, , , КлючИЗначение.Ключ);
КонецЦикла;
КонецФункции
Процедура ЗаполнитьНаборЗаписейПоОтборуЛкс(НаборЗаписей) Экспорт
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
СтруктураЗначенийОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
СтруктураЗначенийОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
ЗаполнитьЗначенияСвойств(СтрокаНабора, СтруктураЗначенийОтбора);
КонецЦикла;
КонецПроцедуры
// Параметры:
// Объект - Ссылочный объект или запись регистра
// Отбор - Отбор, ОтборКомпоновкиДанных
//
Функция УстановитьЗначенияРеквизитовПоОтборуЛкс(Объект, Отбор) Экспорт
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
#Если Сервер И Не Сервер Тогда
Отбор = Новый ПостроительЗапроса;
Отбор = Отбор.Отбор;
#КонецЕсли
Для Каждого ЭлементОтбора Из Отбор Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно
Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = ЭлементОтбора.Имя;
ЗначениеОтбора = ЭлементОтбора.Значение;
Попытка
Объект[ИмяРеквизита] = ЗначениеОтбора;
Исключение
// Сюда попадаем например для ЭтоГруппа
КонецПопытки;
КонецЦикла;
Иначе
#Если Сервер И Не Сервер Тогда
Отбор = Новый НастройкиКомпоновкиДанных;
Отбор = Отбор.Отбор;
#КонецЕсли
Для Каждого ЭлементОтбора Из Отбор.Элементы Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Равно
Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = "" + ЭлементОтбора.ЛевоеЗначение;
Если Найти(ИмяРеквизита, ".") > 0 Тогда
Продолжить;
КонецЕсли;
ЗначениеОтбора = ЭлементОтбора.ПравоеЗначение;
Попытка
Объект[ИмяРеквизита] = ЗначениеОтбора;
Исключение
// Сюда попадаем например для ЭтоГруппа
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецФункции
// Определить вид сравнения по значению
//
// Параметры:
// Значение - <тип> -
// РежимКомпоновки - <тип>, Ложь -
// ДоступныеВидыСравнения - <тип>, Неопределено -
//
// Возвращаемое значение:
//
Функция ОпределитьВидСравненияПоЗначениюЛкс(Знач Значение, Знач РежимКомпоновки = Ложь, Знач ДоступныеВидыСравнения = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если РежимКомпоновки Тогда
КоллекцияВидовСравнения = ВидСравненияКомпоновкиДанных;
Иначе
КоллекцияВидовСравнения = ВидСравнения;
КонецЕсли;
Если ТипЗначения = Тип("СписокЗначений") Тогда
Результат = КоллекцияВидовСравнения.ВСписке;
ИначеЕсли Истина
И ТипЗначения = Тип("Строка")
И ДоступныеВидыСравнения <> Неопределено
И ДоступныеВидыСравнения.НайтиПоЗначению(КоллекцияВидовСравнения.Содержит) <> Неопределено
Тогда
Результат = КоллекцияВидовСравнения.Содержит;
Иначе
Результат = КоллекцияВидовСравнения.Равно;
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения);
Если ОбъектМД <> Неопределено Тогда
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя());
Если ТипТаблицы = "Справочник" Тогда
Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
Иначе // иерархия элементов
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ОтборИлиОбъект - <тип> -
// ПутьКДанным - <тип>, "" -
// Сравнение - <тип>, "" -
// Значение - <тип>, Неопределено -
// ЗначениеПо - <тип>, Неопределено -
// Использование - <тип>, Истина -
// Имя - <тип>, "" -
// Представление - <тип>, "" -
//
// Возвращаемое значение:
//
Функция НайтиДобавитьЭлементОтбораЛкс(Знач ОтборИлиОбъект, Знач ПутьКДанным = "", Знач Сравнение = "", Знач Значение = Неопределено, Знач ЗначениеПо = Неопределено,
Знач Использование = Истина, Знач Имя = "", Знач Представление = "") Экспорт
Если ТипЗнч(ОтборИлиОбъект) = Тип("Отбор") Тогда
Отбор = ОтборИлиОбъект;
Иначе
Отбор = ОтборИлиОбъект.Отбор;
КонецЕсли;
// Ищем или добавляем новый элемент отбора
ЭлементОтбора = Неопределено;
//Если Имя <> Неопределено Тогда
// ЭлементОтбора= Отбор.Найти(Имя);
//КонецЕсли;
Если Имя <> Неопределено Тогда
Для Каждого ЭлОтбора Из Отбор Цикл
Если Ложь
Или ЭлОтбора.Имя = Имя
Или ЭлОтбора.Представление = Имя
Тогда
ЭлементОтбора = ЭлОтбора;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
Попытка
ЭлементОтбора = Отбор.Добавить(ПутьКДанным, Имя, Представление);
Исключение
ВызватьИсключение "Ошибка добавления элемента отбора """ + ПутьКДанным + """ построителя запроса: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
УстановитьЭлементОтбораЛкс(ЭлементОтбора, Сравнение, Значение, ЗначениеПо, Использование);
Результат = ЭлементОтбора;
Возврат Результат;
КонецФункции
Процедура ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, Префикс = "Т") Экспорт
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
ТекстЗапроса = Запрос.Текст;
Параметры = Новый Структура;
СкопироватьУниверсальнуюКоллекциюЛкс(Запрос.Параметры, Параметры);
Для Каждого КлючИЗначение Из Параметры Цикл
Если Найти(КлючИЗначение.Ключ, Префикс) = 1 Тогда
ВызватьИсключение "Начало имени параметра " + КлючИЗначение.Ключ + " совпадает с префиксом " + Префикс;
КонецЕсли;
НовоеИмя = Префикс + КлючИЗначение.Ключ;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&" + КлючИЗначение.Ключ, "&" + НовоеИмя);
Запрос.УстановитьПараметр(НовоеИмя, КлючИЗначение.Значение);
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
КонецПроцедуры
// ТаблицаПараметров - ТаблицаЗначений, ТабличнаяЧасть
Функция НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ЗначениеПараметра,
ИмяПараметра = Неопределено, ОбновитьКопиюСвойстваВНижнемРегистре = Ложь) Экспорт
Если ТипЗнч(ТаблицаПараметров) = Тип("ТаблицаЗначений") Тогда
МакетТаблицы = ТаблицаПараметров;
Иначе
МакетТаблицы = ТаблицаПараметров.ВыгрузитьКолонки();
КонецЕсли;
Строки = ТаблицаПараметров.НайтиСтроки(Новый Структура(ИмяКолонкиЗначения, ЗначениеПараметра));
Если Строки.Количество() > 0 Тогда
Результат = Строки[0];
Иначе
Если ТипЗнч(ЗначениеПараметра) = Тип("Строка") Тогда
ИмяПараметра = ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаПараметров, "П", ИмяКолонкиИмени);
Иначе
ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеПараметра)));
//Префикс = НРег(Лев(ОбъектМД.Имя, 1));
Префикс = "";
Если ИмяПараметра = Неопределено Тогда
ИмяПараметра = "" + РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда
ИмяПараметра = СтрЗаменить(ИмяТипа, ".", "") + "Пустая";
КонецЕсли;
ИмяПараметра = Префикс + ирКэш.Получить().ПолучитьИдентификаторИзПредставления(ИмяПараметра);
ДопустимаяДлинаСтроки = МакетТаблицы.Колонки[ИмяКолонкиИмени].ТипЗначения.КвалификаторыСтроки.Длина;
Если ДопустимаяДлинаСтроки > 0 Тогда
ИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки);
КонецЕсли;
КонецЕсли;
СтруктураСвойствПараметра = Новый Структура;
СтруктураСвойствПараметра.Вставить(ИмяКолонкиИмени, ИмяПараметра);
Счетчик = 0;
Пока ТаблицаПараметров.НайтиСтроки(СтруктураСвойствПараметра).Количество() > 0 Цикл
Счетчик = Счетчик + 1;
СтрокаНомера = "" + Счетчик;
Если ДопустимаяДлинаСтроки > 0 Тогда
лИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки - СтрДлина(СтрокаНомера));
Иначе
лИмяПараметра = ИмяПараметра;
КонецЕсли;
СтруктураСвойствПараметра[ИмяКолонкиИмени] = лИмяПараметра + СтрокаНомера;
КонецЦикла;
СтруктураСвойствПараметра.Вставить("ЭтоВыражение", Ложь);
СтруктураСвойствПараметра.Вставить(ИмяКолонкиЗначения, ЗначениеПараметра);
СтрокаНовогоПараметра = ТаблицаПараметров.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаНовогоПараметра, СтруктураСвойствПараметра);
Если ОбновитьКопиюСвойстваВНижнемРегистре Тогда
ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаНовогоПараметра, ИмяКолонкиИмени);
КонецЕсли;
Результат = СтрокаНовогоПараметра;
КонецЕсли;
Возврат Результат;
КонецФункции // ДобавитьПараметрЗначение()
Функция ИдентификаторИзПредставленияЛкс(Представление) Экспорт
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Возврат Платформа.ПолучитьИдентификаторИзПредставления(Представление);
КонецФункции
Функция _ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицыИлиНаборЗаписей, Знач КлючНабора, ДобавитьИЗаполнитьСтрокуНабора = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяТаблицыИлиНаборЗаписей) = Тип("Строка") Тогда
СтруктураНабораЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыИлиНаборЗаписей);
НаборЗаписей = СтруктураНабораЗаписей.Методы;
Иначе
НаборЗаписей = ПолноеИмяТаблицыИлиНаборЗаписей;
КонецЕсли;
#Если Сервер И Не Сервер Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
//СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолучитьИмяТаблицыИзМетаданныхЛкс(НаборЗаписей.Метаданные()), Ложь);
//Для Каждого ПолеКлюча Из СтруктураКлюча Цикл
// ИмяПоля = ПолеКлюча.Ключ;
// Попытка
// ЗначениеКлюча = КлючНабора[ИмяПоля];
// Исключение
// // Имеет смысл для регистров сведений
// Продолжить;
// КонецПопытки;
// ЭлементОтбора = НаборЗаписей.Отбор[ИмяПоля];
// ЭлементОтбора.Значение = ЗначениеКлюча;
// ЭлементОтбора.Использование = Истина;
//КонецЦикла;
Если ЛиКлючЗаписиРегистраЛкс(КлючНабора) Тогда
// Возможно эта строка лишена смысла
КлючНабора = ПолучитьСтруктуруИзКлючаЗаписиЛкс(КлючНабора, ПолноеИмяТаблицыИлиНаборЗаписей);
КонецЕсли;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
ИмяПоля = ЭлементОтбора.Имя;
Попытка
ЗначениеКлюча = КлючНабора[ИмяПоля];
Исключение
// Имеет смысл для регистров сведений
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеКлюча;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если ДобавитьИЗаполнитьСтрокуНабора Тогда
ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючНабора);
КонецЕсли;
Возврат НаборЗаписей;
КонецФункции
// Получает копию таблицы значений с минимальными типами колонок для содержания всех данных.
// Параметры:
// ТаблицаДанных - ТаблицаЗначений
// СужатьТолькоПроизвольныеКолонки - Булево - обрабатывать только колонки с пустым (произвольным) типом
// ИмяКолонки - Строка - нужна только эта колонка
//
Функция ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Знач ТаблицаДанных, СужатьТолькоПроизвольныеКолонки = Ложь, ИмяКолонки = "") Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаДанных = Новый ТаблицаЗначений;
#КонецЕсли
ОставляемыеКолонки = "";
СужаемыеКолонки = Новый Массив();
Для Каждого КолонкаДанных Из ТаблицаДанных.Колонки Цикл
Если ЗначениеЗаполнено(ИмяКолонки) И Не СтрокиРавныЛкс(ИмяКолонки, КолонкаДанных.Имя) Тогда
Продолжить;
КонецЕсли;
Если Истина
И СужатьТолькоПроизвольныеКолонки
И КолонкаДанных.ТипЗначения.Типы().Количество() > 0
Тогда
ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя;
Иначе
СужаемыеКолонки.Добавить(КолонкаДанных);
КонецЕсли;
КонецЦикла;
//Состояние("Оптимизация типов колонок");
НовыеКолонки = Новый Структура;
МетаданныеТаблицыИзменены = Ложь;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СужаемыеКолонки.Количество(), "Анализ колонок");
Для Каждого КолонкаДанных Из СужаемыеКолонки Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
Типы = Новый Массив;
ТаблицаКолонки = ТаблицаДанных.Скопировать(, КолонкаДанных.Имя);
ТаблицаКолонки.Свернуть(КолонкаДанных.Имя);
СтароеОписаниеТипов = КолонкаДанных.ТипЗначения;
Для Каждого СтрокаДанных Из ТаблицаКолонки Цикл
ТипЗначения = ТипЗнч(СтрокаДанных[КолонкаДанных.Имя]);
Если Истина
И ТипЗначения <> Тип("Неопределено")
И Типы.Найти(ТипЗначения) = Неопределено
Тогда
Типы.Добавить(ТипЗначения);
КонецЕсли;
КонецЦикла;
Если Типы.Количество() = 0 Тогда
Типы = КолонкаДанных.ТипЗначения.Типы();
Если Типы.Количество() = 0 Тогда
Типы.ДОбавить(Тип("Булево"));
Типы.ДОбавить(Тип("Число"));
КонецЕсли;
// Чтобы от супертипов через точку не было много соединений, оставляем только 2 типа
Пока Типы.Количество() > 2 Цикл
Типы.Удалить(0);
КонецЦикла;
КонецЕсли;
Если Типы.Количество() <> СтароеОписаниеТипов.Типы().Количество() Тогда
МетаданныеТаблицыИзменены = Истина;
КонецЕсли;
НовоеОписаниеТипов = Новый ОписаниеТипов(Типы, , , СтароеОписаниеТипов.КвалификаторыЧисла, СтароеОписаниеТипов.КвалификаторыСтроки, СтароеОписаниеТипов.КвалификаторыДаты);
НовыеКолонки.Вставить(КолонкаДанных.Имя, НовоеОписаниеТипов);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если МетаданныеТаблицыИзменены Тогда
Если ОставляемыеКолонки <> "" Тогда
ТипизированнаяТаблица = ТаблицаДанных.Скопировать(, ОставляемыеКолонки);
Иначе
ТипизированнаяТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Для Каждого КлючИЗначение Из НовыеКолонки Цикл
ТипизированнаяТаблица.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение, ТаблицаДанных.Колонки[КлючИЗначение.Ключ].Заголовок);
КонецЦикла;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаДанных.Количество() / 100, "Оптимизация таблицы");
Для Индекс = 0 По ТаблицаДанных.Количество() - 1 Цикл
Если Индекс % 100 = 0 Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ОставляемыеКолонки <> "" Тогда
СтрокаТипизированнойТаблицы = ТипизированнаяТаблица[Индекс];
Иначе
СтрокаТипизированнойТаблицы = ТипизированнаяТаблица.Добавить();
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтрокаТипизированнойТаблицы, ТаблицаДанных[Индекс]);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Иначе
ТипизированнаяТаблица = ТаблицаДанных;
КонецЕсли;
Результат = ТипизированнаяТаблица;
Возврат Результат;
КонецФункции
// ************************
// WMI
Функция ПолучитьСтруктуруИзЗначенияWMIЛкс(ЗначениеWMI) Экспорт
Результат = Новый Структура;
Для каждого СвойствоWMI из ЗначениеWMI Цикл
Если ТипЗнч(СвойствоWMI.Value) = Тип("COMSafeArray") Тогда
ЗначениеСвойства = СвойствоWMI.Value.Выгрузить();// возможно массив надо будет переделать
Иначе
ЗначениеСвойства = СвойствоWMI.Value;
//ИмяТипа = ПолучитьИмяТипаИзКвалификаторовWMIЛкс(СвойствоWMI);
//Если СтрокиРавныЛкс(ИмяТипа, "Дата") Тогда
Если СвойствоWMI.CIMTYPE = 101 Тогда //datetime
ЗначениеСвойства = СтрокаДатыWMIВДатуЛкс(ЗначениеСвойства);
КонецЕсли;
КонецЕсли;
Результат.Вставить(СвойствоWMI.Name, ЗначениеСвойства);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолучитьИмяТипаИзКвалификаторовWMIЛкс(Свойство) Экспорт
ИмяТипа = "";
Попытка
Квалификаторы = Свойство.Qualifiers_;
Исключение
// Нет у системных свойств
Квалификаторы = Новый Массив();
КонецПопытки;
Для Каждого Квалификатор Из Квалификаторы Цикл
Если СтрокиРавныЛкс("CIMTYPE", Квалификатор.Name) Тогда
ИмяТипа = Нрег(Квалификатор.Value);
Прервать;
КонецЕсли;
КонецЦикла;
Если Ложь
Или Найти(ИмяТипа, "int") > 0
Тогда
ИмяТипа = "Число";
ИначеЕсли Ложь
Или Найти(ИмяТипа, "date") > 0
Или Найти(ИмяТипа, "time") > 0
Тогда
ИмяТипа = "Дата";
ИначеЕсли Ложь
Или Найти(ИмяТипа, "string") > 0
Или Найти(ИмяТипа, "char") > 0
Тогда
ИмяТипа = "Строка";
ИначеЕсли ТипЗнч(ИмяТипа) = Тип("COMОбъект") Тогда
ИмяТипа = "COMОбъект.{WbemScripting.SwbemLocator}." + ИмяТипа;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции, ИмяСвойства = "Description") Экспорт
ОписаниеЭлемента = "";
Квалификаторы = ЭлементКоллекции.qualifiers_;
Попытка
КвалификаторОписание = Квалификаторы.item(ИмяСвойства);
Исключение
КвалификаторОписание = Неопределено;
КонецПопытки;
Если КвалификаторОписание <> Неопределено Тогда
ОписаниеЭлемента = КвалификаторОписание.Value;
КонецЕсли;
Возврат ОписаниеЭлемента;
КонецФункции
Функция ПолучитьДокументациюСвойстваWMIЛкс(ИмяКласса, ИмяСвойства, СлужбаWMI = Неопределено) Экспорт
Если СлужбаWMI = Неопределено Тогда
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс();
КонецЕсли;
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписанияСвойств = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Properties_;
Попытка
ОписаниеСвойства = ОписанияСвойств.item(ИмяСвойства);
Исключение
Возврат "";
КонецПопытки;
ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства);
ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "CIMTYPE");
Если ТипЗначений <> Неопределено Тогда
ТекстОписания = ТекстОписания + "
|Type: " + ТипЗначений;
КонецЕсли;
ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "Units");
Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда
ТекстОписания = ТекстОписания + "
|Unit: " + ЕдиницаИзмерения;
КонецЕсли;
Возврат ТекстОписания;
КонецФункции
Функция ПолучитьДокументациюМетодаWMIЛкс(ИмяКласса, ИмяМетода, СлужбаWMI = Неопределено) Экспорт
Если СлужбаWMI = Неопределено Тогда
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс();
КонецЕсли;
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписанияМетодов = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Methods_;
Попытка
ОписаниеМетода = ОписанияМетодов.item(ИмяМетода);
Исключение
Возврат "";
КонецПопытки;
ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода);
ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "CIMTYPE");
Если ТипЗначений <> Неопределено Тогда
ТекстОписания = ТекстОписания + "
|Type: " + ТипЗначений;
КонецЕсли;
ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "Units");
Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда
ТекстОписания = ТекстОписания + "
|Unit: " + ЕдиницаИзмерения;
КонецЕсли;
Возврат ТекстОписания;
КонецФункции
// Параметры:
// СтрокаДаты - Строка(0,П)
//
Функция СтрокаДатыWMIВДатуЛкс(Знач СтрокаДаты = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаДаты) Тогда
Возврат Дата(1,1,1);
Иначе
Строка = Лев(СтрокаДаты, 4) + Сред(СтрокаДаты, 5, 2) + Сред(СтрокаДаты, 7, 2)
+ Сред (СтрокаДаты, 9, 2) + Сред(СтрокаДаты, 11, 2) + Сред(СтрокаДаты, 13, 2);
Попытка
Результат = Дата(Строка);
Исключение
Сообщить("Ошибка преобразования даты WMI из строки """ + СтрокаДаты + """: " + ОписаниеОшибки());
Возврат Дата(1,1,1);
КонецПопытки;
Результат = Результат + Вычислить("0." + Сред(СтрокаДаты, 16, 6));
КонецЕсли;
Возврат Результат;
КонецФункции
// WMI
// *************************
// ************************
// ADO
Функция ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С = Неопределено) Экспорт
Если РезультатТаблица = Неопределено Тогда
РезультатТаблица = Новый ТаблицаЗначений;
КонецЕсли;
мПлатформа = ирКэш.Получить();
FieldКолонка = Новый Соответствие;
Для каждого Field Из РезультатRecordset.Fields Цикл
Если ПустаяСтрока(Field.Name) Тогда
ИмяКолонки = ":?";
Для о=1 По СтрДлина(Field.Name)-1 Цикл
ИмяКолонки = ИмяКолонки + "?";
КонецЦикла;
Иначе
ИмяКолонки = Field.Name;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(ИмяКолонки) Тогда
ИмяКолонки = мПлатформа.ПолучитьИдентификаторИзПредставления(ИмяКолонки);
КонецЕсли;
// контроль полей - двойников по именам
НомерДвойника=0;
Пока РезультатТаблица.Колонки.Найти(ИмяКолонки + Формат(НомерДвойника,"ЧГ=0")) <> Неопределено Цикл
НомерДвойника = НомерДвойника + 1;
КонецЦикла;
ИмяКолонки = ИмяКолонки + Формат(НомерДвойника, "ЧГ=0");
Если Типизировать1С = Истина Тогда
Тип1С = FieldADO_ПолучитьТип1CЛкс(Field);
Иначе
Тип1С = Неопределено;
КонецЕсли;
//Если Тип1С=Неопределено Тогда
// Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,,"["+Name+"]");
//Иначе
Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,Тип1С);
//КонецЕсли;
FieldКолонка.Вставить(Field, Колонка);
КонецЦикла;
Возврат FieldКолонка;
КонецФункции
// Выгружает результат запроса ADO (объект 'ADODB.Recordset') в таблицу значений с выводом прогресса состояния выгрузки
Функция ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С = Ложь, БинарныеВСтроку = Ложь, RecordsAffected = 0,
ИгнорироватьНеподдерживаемыеТипы = Ложь, ЗагружатьЭлементов = Неопределено, СмещениеГода = 0) Экспорт
РезультатТаблица = Новый ТаблицаЗначений;
Если РезультатRecordset = Неопределено Тогда
Возврат РезультатТаблица;
КонецЕсли;
Если ЗначениеЗаполнено(ЗагружатьЭлементов) Тогда
КоличествоЭлементов = Мин(ЗагружатьЭлементов, РезультатRecordset.RecordCount);
Иначе
КоличествоЭлементов = РезультатRecordset.RecordCount;
КонецЕсли;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Загрузка результата");
Если РезультатRecordset.State = 0 Тогда
// Выполнена команда
РезультатТаблица.Колонки.Добавить("ExecutionInfo",, "Информация о выполнении:");
Стр = РезультатТаблица.Добавить();
Стр.ExecutionInfo = "Число записей, обработанных запросом: " + RecordsAffected;
Иначе
FieldКолонка = ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С);
// Открыта выборка
ТипCOMSafeArray = Тип("COMSafeArray");
adBinaryType = ирОбщий.intTypeADOЛкс("adBinary");
adVarBinaryType = ирОбщий.intTypeADOЛкс("adVarBinary");
adLongVarBinaryType = ирОбщий.intTypeADOЛкс("adLongVarBinary");
ПервыйРаз = Истина;
Счетчик = 0;
Если РезультатRecordset.EOF() = 0 И РезультатRecordset.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, СмещениеГода = 2000, Использование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);
//Сообщить("ГУИД = "+ГУИД);
//Сообщить("СтрокаH = "+СтрокаH);
Возврат СтрокаHEXtoCOMSafeArrayЛкс(СтрокаH);
КонецФункции
// преобразует значение уникального идентификатора ссылки в COMSafeArray
Функция СсылкаToCOMSafeArrayЛкс(Ссылка) Экспорт
Попытка
ГУИД = СокрЛП(Ссылка.УникальныйИдентификатор());
Исключение
// переданное значение не ссылка
Возврат Неопределено;
КонецПопытки;
Возврат GUIDToCOMSafeArrayЛкс(ГУИД);
КонецФункции
// преобразоваение значения COMSafeArray, содержащие 2-байтовые целые в шестнадцатиричную строку
Функция BinaryCOMSafeArrayToHEXЛкс(Array) Экспорт
СтрHEX="";
Если ТипЗнч(Array)<>Тип("COMSafeArray") Тогда
Возврат "?COMSafeArray?";
КонецЕсли;
Массив=Array.Выгрузить();
Для каждого Слово Из Массив Цикл
Если ТипЗнч(Слово)=Тип("Число") Тогда
Слово=Цел(Слово);
Если (Слово<0)ИЛИ(Слово>255) Тогда
СтрHEX=СтрHEX+"??";
Иначе
Байт1=Слово%16;
Байт2=Цел(Слово/16);
СтрHEX=СтрHEX+DigitDECtoHEXЛксайт2)+DigitDECtoHEXЛксайт1);
КонецЕсли;
Иначе
СтрHEX=СтрHEX+"??";
КонецЕсли;
КонецЦикла;
Возврат "0x"+СтрHEX;
КонецФункции
// возвращает свойства параметра ADO из переданной структуры
// с автоматическим подбором значений свойств по значению 1С (если свойство неопределено)
Процедура ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils=Неопределено)
Перем ТипЗначения1С;
Если ТипЗнч(стТипADO)=Тип("Структура") Тогда
стТипADO.Свойство("Direction",Direction);
стТипADO.Свойство("Type",Type);
стТипADO.Свойство("Precision",Precision);
стТипADO.Свойство("NumericScale",NumericScale);
стТипADO.Свойство("Size",Size);
стТипADO.Свойство("Attributes",Attributes);
стТипADO.Свойство("ТипЗначения1С",ТипЗначения1С);
КонецЕсли;
Если Истина
И ТипЗнч(ТипЗначения1С) = Тип("ОписаниеТипов")
И ТипЗначения1С.Типы().Количество() > 0
И НЕ ТипЗначения1С.СодержитТип(ТипЗнч(Значение1С))
Тогда
// приведем значение 1С к указанному типу (актуально для значений Null, возвращаемых запросами 1С)
Значение1С = ТипЗначения1С.ПривестиЗначение(Значение1С);
КонецЕсли;
Если Direction=Неопределено Тогда
Direction=1; // 1 - входящий(Default) ... или 0 - неизвестно ???
КонецЕсли;
Тип1С=ТипЗнч(Значение1С);
Попытка
Ссылка = Значение1С.Ссылка;
Исключение
Ссылка = Неопределено;
Попытка
// перечисления стоят особняком среди "ссылочных" типов
МетаДата = Значение1С.Метаданные();
Если Метаданные.Перечисления.Содержит(МетаДата) Тогда
Ссылка = Значение1С;
КонецЕсли;
Исключение
КонецПопытки;
КонецПопытки;
Если Type=Неопределено Тогда
// попытаемся подобрать по типу 1С
Если Тип1С=Тип("Число") Тогда
//Type = 4; // adSingle
//Type = 5; // adDouble
//Type = 14; // adDecimal
//Type = 131; // adNumeric
//Type = 139; // adVarNumeric
Если Цел(Значение1С)=Значение1С Тогда
Если ?(Значение1С<0,-1,1)*Значение1С <= 2147483647 Тогда // 2^32-1
Type = intTypeADOЛкс("adInteger"); // 3
Иначе
Type = intTypeADOЛкс("adBigInt"); // 20
КонецЕсли;
Иначе
Type = 14; // adDecimal
КонецЕсли;
ИначеЕсли Тип1С=Тип("Строка") Тогда
//Type = 129; // adChar
//Type = 130; // adWChar
//Type = 200; // adVarChar
//Type = 201; // adLongVarChar
//Type = 202; // adVarWChar
//Type = 203; // adLongVarWChar
Если СтрДлина(Значение1С)<=4000 Тогда
Type = intTypeADOЛкс("adVarChar"); // 200
Иначе
Type = intTypeADOЛкс("adLongVarChar"); // 201
КонецЕсли;
ИначеЕсли Тип1С=Тип("Дата") Тогда
//Type = 134; // adDBTime
Если НачалоДня(Значение1С)=Значение1С Тогда
Type = intTypeADOЛкс("adDBDate"); // 133
Иначе
Type = intTypeADOЛкс("adDBTimeStamp"); // 135
КонецЕсли;
ИначеЕсли Тип1С=Тип("Булево") Тогда
Type = intTypeADOЛкс("adBoolean"); // 11
ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда
Type = intTypeADOЛкс("adBinary"); // 128
Size = 16;
Иначе
Если Ссылка <> Неопределено Тогда
// ссылочный тип - преобразуем в COMSafeArray
Type = intTypeADOЛкс("adBinary"); // 128
Size = 16;
Иначе
Type = intTypeADOЛкс("adEmpty"); // 0? (Default)
КонецЕсли;
КонецЕсли;
КонецЕсли;
// ADOUtils.V8DateToDBDate( Дата ) // с учетом YearOffset
// ADOUtils.BooleanParameter( Значение ) // COMSafeArray(1)
// ADOUtils.TypeParameter( Значение ) // COMSafeArray(1) *_TYPE
// ADOUtils.TableNumberParameter( Значение ) // COMSafeArray(4) *_RTRef
// ADOUtils.DataVersionParameter( Значение ) // COMSafeArray(8) _Version
// ADOUtils.RRefParameter( Значение ) // COMSafeArray(16) *IDRRef
Если Ложь
Или Type = intTypeADOЛкс("adBinary") // 128
Или Type = intTypeADOЛкс("adVarBinary")
Тогда // 204
//Если ADOUtils = Неопределено Тогда
// ADOUtils = ПолучитьADOUtils();
// Если ADOUtils = Неопределено Тогда
// ADOUtils = Null; // для избежания повторных инициализаций
// КонецЕсли;
//КонецЕсли;
Если Ссылка <> Неопределено Тогда
// ссылочный тип - преобразуем в COMSafeArray(16)
ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка);
//Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда
// ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка);
//Иначе
// ЗначениеADO = ADOUtils.RRefParameter(Ссылка);
//КонецЕсли;
ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда
// ГУИД - преобразуем в COMSafeArray(16)
ЗначениеADO = GUIDToCOMSafeArrayЛкс(Значение1С);
ИначеЕсли Тип1С=Тип("Булево") Тогда
// Булево - преобразуем в COMSafeArray(1)
ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00"));
//Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда
// ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00"));
//Иначе
// ЗначениеADO = ADOUtils.BooleanParameter(Значение1С);
//КонецЕсли;
Иначе
КонецЕсли;
КонецЕсли;
Если Precision=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adDecimal") // 14
ИЛИ Type = intTypeADOЛкс("adNumeric") // 131
ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139
Тогда
Precision = СтрДлина(СтрЗаменить(Строка(Значение1С)," ",""));
КонецЕсли;
КонецЕсли;
Если NumericScale=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adDecimal") // 14
ИЛИ Type = intTypeADOЛкс("adNumeric") // 131
ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139
Тогда
NumericScale = СтрДлина(Строка(Значение1С-Цел(Значение1С)));
КонецЕсли;
КонецЕсли;
Если Size=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adChar") // 129
ИЛИ Type = intTypeADOЛкс("adWChar") // 130
ИЛИ Type = intTypeADOЛкс("adVarChar") // 200
//ИЛИ Type = intTypeADOЛкс("adLongVarChar") // 201
ИЛИ Type = intTypeADOЛкс("adVarWChar") // 202
//ИЛИ Type = intTypeADOЛкс("adLongVarWChar") // 203
Тогда
Size = СтрДлина(Значение1С);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// создает массив объектов ADODB.Parameter по списку параметров ADO и по списку типов ADO
Функция ParametersArrayПолучитьЛкс(стПараметры,стПарТипADO, ADOUtils = Неопределено) Экспорт
ParametersArray = Новый Массив;
ТипаМассив = Тип("Массив");
ТипаСоответствие = Тип("Соответствие");
cтПараметрыТип = ТипЗнч(стПараметры);
cтПарТипADOТип = ТипЗнч(стПарТипADO);
Если стПараметры = Неопределено Тогда
Возврат ParametersArray;
ИначеЕсли cтПараметрыТип = ТипаМассив ИЛИ cтПараметрыТип = ТипаСоответствие Тогда
Если стПарТипADO <> Неопределено И cтПарТипADOТип <> cтПараметрыТип Тогда
ВызватьИсключение(
"Тип значения списка типов параметров ADO ('"+cтПарТипADOТип+"') не равен
|типу значения списка параметров запроса ('"+cтПараметрыТип+"') !");
КонецЕсли;
Иначе
ВызватьИсключение(
"Не предусмотренный тип значения списка параметров запроса ('"+cтПараметрыТип+"') !");
КонецЕсли;
ОбъектЗапрос = Новый COMОбъект("ADODB.Command");
Индекс = 0;
Для каждого Параметр Из стПараметры Цикл
Если cтПараметрыТип = ТипаМассив Тогда
ПараметрИмя = Неопределено;
Значение1С = Параметр;
ИначеЕсли cтПараметрыТип = ТипаСоответствие Тогда
ПараметрИмя = СокрЛП(Параметр.Ключ);
Значение1С = Параметр.Значение;
Иначе
Продолжить;
КонецЕсли;
Индекс = Индекс + 1;
стТипADO=Неопределено;
Если cтПарТипADOТип=ТипаМассив Тогда
Если Индекс<=стПарТипADO.Количество()-1 Тогда
стТипADO = стПарТипADO.Получить(Индекс);
КонецЕсли;
ИначеЕсли cтПарТипADOТип = ТипаСоответствие Тогда
стТипADO = стПарТипADO.Получить(Параметр.Ключ);
КонецЕсли;
ЗначениеADO = Неопределено;
Attributes = Неопределено;
Direction = Неопределено;
Type = Неопределено;
Precision = Неопределено;
NumericScale = Неопределено;
Size = Неопределено; // прочитаем свойства параметра ADO по полученной структуре типа и значению 1С
ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils);
// создадим параметр ADO и заполним его свойства
Parameter = ОбъектЗапрос.CreateParameter();
Если НЕ ПустаяСтрока(Type) Тогда
Parameter.Type=Type;
КонецЕсли;
Если НЕ ПустаяСтрока(Direction) Тогда
Parameter.Direction=Direction;
КонецЕсли;
Если НЕ ПустаяСтрока(Size) Тогда
Parameter.Size=Size;
КонецЕсли;
Если НЕ ПустаяСтрока(Attributes) Тогда
Parameter.Attributes=Attributes;
КонецЕсли;
Если НЕ ПустаяСтрока(ПараметрИмя) Тогда
Parameter.Name = ПараметрИмя;
КонецЕсли;
Если ЗначениеADO = Неопределено Тогда
Parameter.Value=Значение1С; // преобразование не явное
Иначе
Parameter.Value=ЗначениеADO;
КонецЕсли;
// добавим в массив
ParametersArray.Добавить(Parameter);
КонецЦикла;
Возврат ParametersArray;
КонецФункции // ParametersArrayПолучитьЛкс()
// формирует массив или соответствие со значениями параметров запроса из строки таблицы значений
Функция стПараметры_Получить_ТЗЛкс(тзПараметры,СтрокаПараметров,NamedParameters,Знач ParametersPrefix) Экспорт
Если NamedParameters=Истина Тогда
ParametersPrefix=СокрЛП(ParametersPrefix);
стПараметры=Новый Соответствие;
Для каждого Колонка Из тзПараметры.Колонки Цикл
стПараметры.Вставить(ParametersPrefix+Колонка.Имя,СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка)));
КонецЦикла;
Иначе
стПараметры=Новый Массив;
Для каждого Колонка Из тзПараметры.Колонки Цикл
стПараметры.Добавить(СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка)));
КонецЦикла;
КонецЕсли;
Возврат стПараметры;
КонецФункции // стПараметры_Получить_ТЗЛкс()
// добавляет и устанавливает объект ADODB.Parameter в коллекцию параметров
// если не заданы свойства параметра ADO, делается попытка их подбора по типу значения 1С
Функция ADODBCommand_УстановитьПараметрПо1СЛкс(ОбъектЗапрос,Инициализация,Индекс,Name,стТипADO,Значение1С,ADOUtils,ЕррорИнфо) Экспорт
ЗначениеADO=Неопределено;
Attributes=Неопределено;
Direction=Неопределено;
Type=Неопределено;
Precision=Неопределено;
NumericScale=Неопределено;
Size=Неопределено; // прочитаем свойства параметра ADO из переданной структуры по значению 1С
ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils);
ЕррорИнфо="";
Попытка
Если ОбъектЗапрос.Prepared = Ложь ИЛИ Инициализация <> Ложь Тогда
// инициализация параметров запроса
Добавить = Ложь;
Если Name = Неопределено Тогда
// по переданному индексу параметра
Parameter = ОбъектЗапрос.CreateParameter();
Добавить = Истина; // создаем без имени
Иначе
// по переданному имени параметра
Попытка
// если уже есть параметр с именем - используем его
Parameter = ОбъектЗапрос.Parameters.Item(Name);
Исключение
Parameter = Неопределено;
КонецПопытки;
Если Parameter = Неопределено Тогда
// если нет - создаем с указанным именем
Parameter = ОбъектЗапрос.CreateParameter();
Parameter.Name = Name;
Добавить = Истина;
КонецЕсли;
КонецЕсли;
Если НЕ ПустаяСтрока(Type) Тогда
Parameter.Type=Type;
КонецЕсли;
Если НЕ ПустаяСтрока(Direction) Тогда
Parameter.Direction=Direction;
КонецЕсли;
Если НЕ ПустаяСтрока(Size) Тогда
Parameter.Size=Size;
КонецЕсли;
Если НЕ ПустаяСтрока(Attributes) И Attributes <> 0 Тогда
Parameter.Attributes=Attributes;
КонецЕсли;
Если Добавить = Истина Тогда
ОбъектЗапрос.Parameters.Append(Parameter);
КонецЕсли;
Иначе
// установка параметра предварительно подготовленного параметризованного запроса
Если Name = Неопределено Тогда
// по переданному индексу параметра
Parameter = ОбъектЗапрос.Parameters.Item(Индекс);
Иначе
// по переданному имени параметра
Parameter = ОбъектЗапрос.Parameters.Item(Name);
КонецЕсли;
КонецЕсли;
Если ЗначениеADO = Неопределено Тогда
Parameter.Value=Значение1С; // преобразование не явное
Иначе
Parameter.Value=ЗначениеADO;
КонецЕсли;
Исключение
ЕррорИнфо=ОписаниеОшибки();
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
// ^^^ УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ^^^
// *** ПЕРЕЧИСЛЕНИЯ ADO ***
// возвращает строковое представление типа параметра ADO(свойства Direction) по его числовому значению
Функция strDirectionParADOЛкс(intTypeADOЛкс) Экспорт
intType = Цел(intTypeADOЛкс);
Если intType = 0 Тогда Возврат "adParamUnknown"; // Direction unknown
ИначеЕсли intType = 1 Тогда Возврат "adParamInput"; // Input parameter (Default)
ИначеЕсли intType = 2 Тогда Возврат "adParamOutput"; // Output parameter
ИначеЕсли intType = 3 Тогда Возврат "adParamInputOutput"; // Input and output parameter
ИначеЕсли intType = 4 Тогда Возврат "adParamReturnValue"; // Return value
Иначе Возврат "adParamInput"; // как 1
КонецЕсли;
КонецФункции
// возвращает числовое значения типа параметра ADO(свойства Direction) по его числовому представлению
Функция intDirectionParADOЛкс(strTypeADOЛкс) Экспорт
strType = НРег(strTypeADOЛкс);
Если strType = Нрег("adParamUnknown") Тогда Возврат 0; // Direction unknown
ИначеЕсли strType = Нрег("adParamInput") Тогда Возврат 1; // Input parameter (Default)
ИначеЕсли strType = Нрег("adParamOutput") Тогда Возврат 2; // Output parameter
ИначеЕсли strType = Нрег("adParamInputOutput") Тогда Возврат 3; // Input and output parameter
ИначеЕсли strType = Нрег("adParamReturnValue") Тогда Возврат 4; // Return value
Иначе Возврат 1; // adParamInput
КонецЕсли;
КонецФункции
// возвращает строковое представление типа значения ADO по его числовому значению
Функция strTypeADOЛкс(intTypeADOЛкс) Экспорт
intType = Цел(intTypeADOЛкс);
Если intType = 0 Тогда Возврат "adEmpty"; // no value
ИначеЕсли intType = 2 Тогда Возврат "adSmallInt"; // 2-byte signed integer
ИначеЕсли intType = 3 Тогда Возврат "adInteger"; // 4-byte signed integer
ИначеЕсли intType = 4 Тогда Возврат "adSingle"; // single-precision floating-point value
ИначеЕсли intType = 5 Тогда Возврат "adDouble"; // double-precision floating-point value
ИначеЕсли intType = 6 Тогда Возврат "adCurrency"; // currency value
ИначеЕсли intType = 7 Тогда Возврат "adDate"; // number of days since December 30, 1899 + the fraction of a day
ИначеЕсли intType = 8 Тогда Возврат "adBSTR"; // null-terminated character string
ИначеЕсли intType = 9 Тогда Возврат "adIDispatch"; // pointer to an IDispatch interface on a COM object(currently not supported by ADO)
ИначеЕсли intType = 10 Тогда Возврат "adError"; // 32-bit error code
ИначеЕсли intType = 11 Тогда Возврат "adBoolean"; // boolean value
ИначеЕсли intType = 12 Тогда Возврат "adVariant"; // automation Variant(currently not supported by ADO)
ИначеЕсли intType = 13 Тогда Возврат "adIUnknown"; // pointer to an IUnknown interface on a COM object(currently not supported by ADO)
ИначеЕсли intType = 14 Тогда Возврат "adDecimal"; // exact numeric value with a fixed precision and scale
ИначеЕсли intType = 16 Тогда Возврат "adTinyInt"; // 1-byte signed integer
ИначеЕсли intType = 17 Тогда Возврат "adUnsignedTinyInt"; // 1-byte unsigned integer
ИначеЕсли intType = 18 Тогда Возврат "adUnsignedSmallInt"; // 2-byte unsigned integer
ИначеЕсли intType = 19 Тогда Возврат "adUnsignedInt"; // 4-byte unsigned integer
ИначеЕсли intType = 20 Тогда Возврат "adBigInt"; // 8-byte signed integer
ИначеЕсли intType = 21 Тогда Возврат "adUnsignedBigInt"; // 8-byte unsigned integer
ИначеЕсли intType = 64 Тогда Возврат "adFileTime"; // number of 100-nanosecond intervals since January 1,1601
ИначеЕсли intType = 72 Тогда Возврат "adGUID"; // globally unique identifier (GUID)
ИначеЕсли intType = 128 Тогда Возврат "adBinary"; // binary value
ИначеЕсли intType = 129 Тогда Возврат "adChar"; // string value
ИначеЕсли intType = 130 Тогда Возврат "adWChar"; // null-terminated Unicode character string
ИначеЕсли intType = 131 Тогда Возврат "adNumeric"; // exact numeric value with a fixed precision and scale
ИначеЕсли intType = 132 Тогда Возврат "adUserDefined"; // user-defined variable
ИначеЕсли intType = 133 Тогда Возврат "adDBDate"; // date value (yyyymmdd)
ИначеЕсли intType = 134 Тогда Возврат "adDBTime"; // time value (hhmmss)
ИначеЕсли intType = 135 Тогда Возврат "adDBTimeStamp"; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths)
ИначеЕсли intType = 136 Тогда Возврат "adChapter"; // 4-byte chapter value that identifies rows in a child rowset
ИначеЕсли intType = 138 Тогда Возврат "adPropVariant"; // automation PROPVARIANT
ИначеЕсли intType = 139 Тогда Возврат "adVarNumeric"; // numeric value(Parameter object only)
ИначеЕсли intType = 200 Тогда Возврат "adVarChar"; // string value (Parameter object only)
ИначеЕсли intType = 201 Тогда Возврат "adLongVarChar"; // long string value
ИначеЕсли intType = 202 Тогда Возврат "adVarWChar"; // null-terminated Unicode character string
ИначеЕсли intType = 203 Тогда Возврат "adLongVarWChar"; // long null-terminated Unicode string value
ИначеЕсли intType = 204 Тогда Возврат "adVarBinary"; // binary value (Parameter object only)
ИначеЕсли intType = 205 Тогда Возврат "adLongVarBinary"; // long binary value
ИначеЕсли intType = 8192 Тогда Возврат "AdArray"; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type
Иначе Возврат "adEmpty"; // как 0
КонецЕсли;
КонецФункции
// возвращает числовое значение типа значения ADO по его строковому представлению
Функция intTypeADOЛкс(strTypeADOЛкс) Экспорт
strType = НРег(strTypeADOЛкс);
Если strType = НРег("adEmpty") Тогда Возврат 0; // no value
ИначеЕсли strType = НРег("adSmallInt") Тогда Возврат 2; // 2-byte signed integer
ИначеЕсли strType = НРег("adInteger") Тогда Возврат 3; // 4-byte signed integer
ИначеЕсли strType = НРег("adSingle") Тогда Возврат 4; // single-precision floating-point value
ИначеЕсли strType = НРег("adDouble") Тогда Возврат 5; // double-precision floating-point value
ИначеЕсли strType = НРег("adCurrency") Тогда Возврат 6; // currency value
ИначеЕсли strType = НРег("adDate") Тогда Возврат 7; // number of days since December 30, 1899 + the fraction of a day
ИначеЕсли strType = НРег("adBSTR") Тогда Возврат 8; // null-terminated character string
ИначеЕсли strType = НРег("adIDispatch") Тогда Возврат 9; // pointer to an IDispatch interface on a COM object(currently not supported by ADO)
ИначеЕсли strType = НРег("adError") Тогда Возврат 10; // 32-bit error code
ИначеЕсли strType = НРег("adBoolean") Тогда Возврат 11; // boolean value
ИначеЕсли strType = НРег("adVariant") Тогда Возврат 12; // automation Variant(currently not supported by ADO)
ИначеЕсли strType = НРег("adIUnknown") Тогда Возврат 13; // pointer to an IUnknown interface on a COM object(currently not supported by ADO)
ИначеЕсли strType = НРег("adDecimal") Тогда Возврат 14; // exact numeric value with a fixed precision and scale
ИначеЕсли strType = НРег("adTinyInt") Тогда Возврат 16; // 1-byte signed integer
ИначеЕсли strType = НРег("adUnsignedTinyInt") Тогда Возврат 17; // 1-byte unsigned integer
ИначеЕсли strType = НРег("adUnsignedSmallInt") Тогда Возврат 18;// 2-byte unsigned integer
ИначеЕсли strType = НРег("adUnsignedInt") Тогда Возврат 19; // 4-byte unsigned integer
ИначеЕсли strType = НРег("adBigInt") Тогда Возврат 20; // 8-byte signed integer
ИначеЕсли strType = НРег("adUnsignedBigInt") Тогда Возврат 21; // 8-byte unsigned integer
ИначеЕсли strType = НРег("adFileTime") Тогда Возврат 64; // number of 100-nanosecond intervals since January 1,1601
ИначеЕсли strType = НРег("adGUID") Тогда Возврат 72; // globally unique identifier (GUID)
ИначеЕсли strType = НРег("adBinary") Тогда Возврат 128; // binary value
ИначеЕсли strType = НРег("adChar") Тогда Возврат 129; // string value
ИначеЕсли strType = НРег("adWChar") Тогда Возврат 130; // null-terminated Unicode character string
ИначеЕсли strType = НРег("adNumeric") Тогда Возврат 131; // exact numeric value with a fixed precision and scale
ИначеЕсли strType = НРег("adUserDefined") Тогда Возврат 132; // user-defined variable
ИначеЕсли strType = НРег("adDBDate") Тогда Возврат 133; // date value (yyyymmdd)
ИначеЕсли strType = НРег("adDBTime") Тогда Возврат 134; // time value (hhmmss)
ИначеЕсли strType = НРег("adDBTimeStamp") Тогда Возврат 135; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths)
ИначеЕсли strType = НРег("adChapter") Тогда Возврат 136; // 4-byte chapter value that identifies rows in a child rowset
ИначеЕсли strType = НРег("adPropVariant") Тогда Возврат 138; // automation PROPVARIANT
ИначеЕсли strType = НРег("adVarNumeric") Тогда Возврат 139; // numeric value(Parameter object only)
ИначеЕсли strType = НРег("adVarChar") Тогда Возврат 200; // string value (Parameter object only)
ИначеЕсли strType = НРег("adLongVarChar") Тогда Возврат 201; // long string value
ИначеЕсли strType = НРег("adVarWChar") Тогда Возврат 202; // null-terminated Unicode character string
ИначеЕсли strType = НРег("adLongVarWChar") Тогда Возврат 203; // long null-terminated Unicode string value
ИначеЕсли strType = НРег("adVarBinary") Тогда Возврат 204; // binary value (Parameter object only)
ИначеЕсли strType = НРег("adLongVarBinary") Тогда Возврат 205; // long binary value
ИначеЕсли strType = НРег("AdArray") Тогда Возврат 8192; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type
Иначе Возврат 0; // adEmpty
КонецЕсли;
КонецФункции
// возвращает числовое значение типа курсора по его строковому представлению
Функция strCursorTypeЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adOpenUnspecified"; // Does not specify the type of cursor
ИначеЕсли intV = 0 Тогда Возврат "adOpenForwardOnly"; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default)
ИначеЕсли intV = 1 Тогда Возврат "adOpenKeyset"; // Uses a keyset cursor. Like a dynamic cursor, except...
ИначеЕсли intV = 2 Тогда Возврат "adOpenDynamic"; // Uses a dynamic cursor
ИначеЕсли intV = 3 Тогда Возврат "adOpenStatic"; // Uses a static cursor
Иначе Возврат "adOpenForwardOnly"; // как 0
КонецЕсли;
КонецФункции
// возвращает строковое представление типа курсора по его числовому значению
Функция intCursorTypeЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adOpenUnspecified") Тогда Возврат -1; // Does not specify the type of cursor
ИначеЕсли strV = Нрег("adOpenForwardOnly") Тогда Возврат 0; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default
ИначеЕсли strV = Нрег("adOpenKeyset") Тогда Возврат 1; // Uses a keyset cursor. Like a dynamic cursor, except...
ИначеЕсли strV = Нрег("adOpenDynamic") Тогда Возврат 2; // Uses a dynamic cursor
ИначеЕсли strV = Нрег("adOpenStatic") Тогда Возврат 3; // Uses a static cursor
Иначе Возврат 0; // adOpenForwardOnly
КонецЕсли;
КонецФункции
// возвращает числовое значение местоположения курсора по его строковому представлению
Функция strCursorLocationЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 1 Тогда Возврат "adUseNone"; // Does not use cursor services
ИначеЕсли intV = 2 Тогда Возврат "adUseServer"; // Uses a server-side cursor (Default)
ИначеЕсли intV = 3 Тогда Возврат "adParamOutput"; // Uses a client-side cursor supplied by a local cursor library
Иначе Возврат "adUseServer"; // как 2
КонецЕсли;
КонецФункции
// возвращает строковое представление местоположения курсора по его числовому значению
Функция intCursorLocationЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adUseNone") Тогда Возврат 1; // Does not use cursor services
ИначеЕсли strV = Нрег("adUseServer") Тогда Возврат 2; // Uses a server-side cursor (Default)
ИначеЕсли strV = Нрег("adParamOutput") Тогда Возврат 3; // Uses a client-side cursor supplied by a local cursor library
Иначе Возврат 2; // adUseServer
КонецЕсли;
КонецФункции
// возвращает числовое значение типа блокировки данных по его строковому представлению
Функция strLockTypeЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adLockUnspecified"; // Unspecified type of lock. Clones inherits lock type from the original Recordset
ИначеЕсли intV = 1 Тогда Возврат "adLockReadOnly"; // Read-only records
ИначеЕсли intV = 2 Тогда Возврат "adLockPessimistic"; // Pessimistic locking, record by record. The provider lock records immediately after editing
ИначеЕсли intV = 3 Тогда Возврат "adLockOptimistic"; // Optimistic locking, record by record. The provider lock records only when calling update
ИначеЕсли intV = 4 Тогда Возврат "adLockBatchOptimistic"; // Optimistic batch updates. Required for batch update mode
Иначе Возврат "adLockUnspecified"; // как -1
КонецЕсли;
КонецФункции
// возвращает строковое представление типа блокировки данных по его числовому значению
Функция intLockTypeЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adLockUnspecified") Тогда Возврат -1; // Unspecified type of lock
ИначеЕсли strV = Нрег("adLockReadOnly") Тогда Возврат 1; // Read-only records
ИначеЕсли strV = Нрег("adLockPessimistic") Тогда Возврат 2; // Pessimistic locking, record by record. The provider lock records immediately after editing
ИначеЕсли strV = Нрег("adLockOptimistic") Тогда Возврат 3; // Optimistic locking, record by record. The provider lock records only when calling update
ИначеЕсли strV = Нрег("adLockBatchOptimistic") Тогда Возврат 4; // Optimistic batch updates. Required for batch update mode
Иначе Возврат -1; // adLockUnspecified
КонецЕсли;
КонецФункции
// возвращает числовое значение опции MarshalOptions по его строковому представлению
Функция strMarshalOptionsЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 0 Тогда Возврат "adMarshalAll"; // Returns all rows (Default)
ИначеЕсли intV = 1 Тогда Возврат "adMarshalModifiedOnly"; // Returns only modified rows
Иначе Возврат "adMarshalAll"; // как 0
КонецЕсли;
КонецФункции
// возвращает строковое представление опции MarshalOptions по его числовому значению
Функция intMarshalOptionsЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adMarshalAll") Тогда Возврат 0; // Returns all rows (Default)
ИначеЕсли strV = Нрег("adMarshalModifiedOnly") Тогда Возврат 1; // Returns only modified rows
Иначе Возврат 0; // adMarshalAll
КонецЕсли;
КонецФункции
// возвращает строковое представление типа команды ADO по его числовому значению
Функция strCommandTypeADOЛкс(intTypeADOЛкс) Экспорт
Если ТипЗнч(intTypeADOЛкс) = Тип("Число") Тогда
intType = Цел(intTypeADOЛкс);
Иначе
intType = 0;
КонецЕсли;
Если intType = -1 Тогда Возврат "adCmdUnspecified"; // Unspecified type of command
ИначеЕсли intType = 1 Тогда Возврат "adCmdText"; // строка оператора T-SQL
ИначеЕсли intType = 2 Тогда Возврат "adCmdTable"; // имя таблицы для выборки строк
ИначеЕсли intType = 4 Тогда Возврат "adCmdStoredProc"; // имя хранимой процедуры
ИначеЕсли intType = 8 Тогда Возврат "adCmdUnknown"; // неизвестно, проверять провайдером (Default)
ИначеЕсли intType = 256 Тогда Возврат "adCmdFile"; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only)
ИначеЕсли intType = 512 Тогда Возврат "adCmdTableDirect"; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only)
Иначе Возврат "adCmdUnknown"; // как 8
КонецЕсли;
КонецФункции
// возвращает числовое значение типа команды ADO по его строковому представлению
Функция intCommandTypeADOЛкс(strTypeADOЛкс) Экспорт
strType = Нрег(strTypeADOЛкс);
Если strType = Нрег("adCmdUnspecified") Тогда Возврат -1; // Unspecified type of command
ИначеЕсли strType = Нрег("adCmdText") Тогда Возврат 1; // строка оператора T-SQL
ИначеЕсли strType = Нрег("adCmdTable") Тогда Возврат 2; // имя таблицы для выборки строк
ИначеЕсли strType = Нрег("adCmdStoredProc") Тогда Возврат 4; // имя хранимой процедуры
ИначеЕсли strType = Нрег("adCmdUnknown") Тогда Возврат 8; // неизвестно, проверять провайдером (Default)
ИначеЕсли strType = Нрег("adCmdFile") Тогда Возврат 256; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only)
ИначеЕсли strType = Нрег("adCmdTableDirect") Тогда Возврат 512; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only)
Иначе Возврат 8; // adCmdUnknown
КонецЕсли;
КонецФункции
// возвращает строковое представление типа команды ADO по его числовому значению
Функция strExecuteOptionЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adOptionUnspecified"; // Unspecified command
ИначеЕсли intV = 16 Тогда Возврат "adAsyncExecute"; // The command should execute asynchronously
ИначеЕсли intV = 32 Тогда Возврат "adAsyncFetch"; // The remaining rows after specified in the CacheSize should be retrieved asynchronously
ИначеЕсли intV = 64 Тогда Возврат "adAsyncFetchNonBlocking"; // The main thread never blocks while retrieving.
ИначеЕсли intV = 128 Тогда Возврат "adExecuteNoRecords"; // Discard, not return retrieved rows (with Command or Connection.Execute only)
ИначеЕсли intV = 256 Тогда Возврат "adExecuteStream"; // The results of a command execution is a stream (with Connection.Execute only)
ИначеЕсли intV = 512 Тогда Возврат "adExecuteRecord"; // Return a single row as a Record object
Иначе Возврат "adOptionUnspecified"; // как -1
КонецЕсли;
КонецФункции
// возвращает числовое значение типа команды ADO по его строковому представлению
Функция intExecuteOptionЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adOptionUnspecified") Тогда Возврат -1; // Unspecified command
ИначеЕсли strV = Нрег("adAsyncExecute") Тогда Возврат 16; // The command should execute asynchronously
ИначеЕсли strV = Нрег("adAsyncFetch") Тогда Возврат 32; // The remaining rows after specified in the CacheSize should be retrieved asynchronously
ИначеЕсли strV = Нрег("adAsyncFetchNonBlocking") Тогда Возврат 64; // The main thread never blocks while retrieving
ИначеЕсли strV = Нрег("adExecuteNoRecords") Тогда Возврат 128; // Discard, not return retrieved rows (with Command or Connection.Execute only)
ИначеЕсли strV = Нрег("adExecuteStream") Тогда Возврат 256; // The results of a command execution is a stream (with Connection.Execute only)
ИначеЕсли strV = Нрег("adExecuteRecord") Тогда Возврат 512; // Return a single row as a Record object
Иначе Возврат -1; // adOptionUnspecified
КонецЕсли;
КонецФункции
// возвращает строковое представление опции аттрибутов параметра ADO по числовому значению опции
Функция strParameterADOAttributesЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 16 Тогда Возврат "adParamSigned"; // The parameter will accept signed values.
ИначеЕсли intV = 64 Тогда Возврат "adParamNullAble"; // The parameter will accept null values.
ИначеЕсли intV = 128 Тогда Возврат "adParamLong"; // The parameter will accept long binary data.
Иначе Возврат "adParamSigned"; // как 16
КонецЕсли;
КонецФункции
// возвращает числовое значение оцции аттрибутов параметра ADO по строковому представлению опции
Функция intParameterADOAttributesЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adParamSigned") Тогда Возврат 16; // The parameter will accept signed values.
ИначеЕсли strV = Нрег("adParamNullAble") Тогда Возврат 64; // The parameter will accept null values.
ИначеЕсли strV = Нрег("adParamLong") Тогда Возврат 128; // The parameter will accept long binary data.
Иначе Возврат 16; // adParamSigned
КонецЕсли;
КонецФункции
// ^^^ ПЕРЕЧИСЛЕНИЯ ADO ^^^
// ADO
// ************************
// В платформе все корневые элементы древовидных структур содержат в свойстве Родитель Неопределено.
// Поэтому возникает неудобство при работе с этим свойством, заключающееся в необходимости часто проверять его значение на Неопределено.
// Параметры:
// СтрокаДерева - СтрокаДереваЗначений, <Элемент любого иерархического объекта, имеющий родителя>
// Дерево - <Иерархический объект, которому принадлежит элемент> - для дерева значений не нужно передавать
//
Функция ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево = Неопределено) Экспорт
Родитель = СтрокаДерева.Родитель;
Если Родитель = Неопределено Тогда
Если Дерево = Неопределено Тогда
Родитель = СтрокаДерева.Владелец();
Иначе
Родитель = Дерево;
КонецЕсли;
КонецЕсли;
Возврат Родитель;
КонецФункции
// Результат - Неопределено, "*", Число
Функция ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение) Экспорт
Если Не ЭтоКоллекцияЛкс(Значение) Тогда
КоличествоЭлементов = Неопределено;
Иначе
КоличествоЭлементов = "*";
Если ТипЗнч(Значение) = Тип("COMSafeArray") Тогда
КоличествоЭлементов = Значение.GetLength();
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
Попытка
КоличествоЭлементов = Значение.Count;
Исключение
КонецПопытки;
КонецЕсли;
Если КоличествоЭлементов = "*" Тогда
Попытка
КоличествоЭлементов = Значение.Количество();
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Возврат КоличествоЭлементов;
КонецФункции
Функция ЭтоКоллекцияЛкс(Значение) Экспорт
// Антибаг платформы 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1017316#1017316
Если Значение = ПараметрыСеанса Тогда
Возврат Истина;
КонецЕсли;
Попытка
Для Каждого _Элемент Из Значение Цикл
Прервать;
КонецЦикла;
ЭтоКоллекция = Истина;
Исключение
ЭтоКоллекция = Ложь;
КонецПопытки;
Возврат ЭтоКоллекция;
КонецФункции
Функция ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
ТипМетаданных = Фрагменты[0];
ИмяОбъекта = Фрагменты[1];
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ТипОбъекта = Тип(ТипМетаданных + "Объект." + ИмяОбъекта);
Иначе
КэшТиповВнешнихМетаданных = ирПортативный.мКэшТиповВнешнихМетаданных;
ВнешнийОбъект = КэшТиповВнешнихМетаданных[ПолноеИмяМД];
Если ВнешнийОбъект <> Неопределено Тогда
ТипОбъекта = ТипЗнч(ВнешнийОбъект);
КонецЕсли;
КонецЕсли;
Если ТипОбъекта <> Неопределено Тогда
Результат = Новый (ТипОбъекта);
Иначе
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(ИмяОбъекта, ТипМетаданных);
Попытка
Результат = Менеджер.Создать(ПолноеИмяФайла, Ложь);
//// Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1442085/m/1442085
//Если ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Тогда
// Пустышка = Результат.ПолучитьФорму();
//КонецЕсли;
Исключение
// Это очень помогает при ошибках функций режима отладки
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Если Истина
И КэшТиповВнешнихМетаданных <> Неопределено
// Такой прием ко всем нельзя применять, т.к. при получении формы у разных экземпляров будет возвращаться всегда форма первого экземпляра, если она открыта
И (Ложь
Или ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой"
Или ИмяОбъекта = "ирПлатформа")
Тогда
КэшТиповВнешнихМетаданных[ПолноеИмяМД] = Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьПолноеИмяМДТипаЛкс(Тип) Экспорт
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМетаданных <> Неопределено Тогда
Результат = ОбъектМетаданных.ПолноеИмя();
Если ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Тогда
Результат = Результат + ".Точки";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОптимальныйПотоковыйПисательЛкс() Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803006 Тогда
ПотоковыйПисатель = Новый ("ЗаписьJSON");
Иначе
ПотоковыйПисатель = Новый ЗаписьXML;
КонецЕсли;
Возврат ПотоковыйПисатель;
КонецФункции
Функция ОптимальныйПотоковыйЧитательЛкс() Экспорт
Если ирКэш.НомерВерсииПлатформыЛкс() >= 803006 Тогда
ПотоковыйЧитатель = Новый ("ЧтениеJSON");
Иначе
ПотоковыйЧитатель = Новый ЧтениеXML;
КонецЕсли;
Возврат ПотоковыйЧитатель;
КонецФункции
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент И Клиент Тогда
Процедура ПоказатьНеуникальныеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач СтрокаКлюча = "") Экспорт
НеуникальныеКлючи = ПолучитьНеуникальныеКлючиТаблицыЛкс(ТабличноеПоле.Значение, СтрокаКлюча);
ТекстСообщения = "Найдено " + НеуникальныеКлючи.Количество() + " неуникальных ключей строк";
Если НеуникальныеКлючи.Количество() > 0 Тогда
ВыделитьСтрокиТабличногоПоляПоКлючуЛкс(ТабличноеПоле, НеуникальныеКлючи[0], СтрокаКлюча);
ТекстСообщения = ТекстСообщения + ". Выделены строки первого ключа";
//ЭтаФорма.ТекущийЭлемент = ТабличноеПоле;
КонецЕсли;
Сообщить(ТекстСообщения);
КонецПроцедуры
Функция ПолучитьКоординатыСтрокиДереваЛкс(СтрокаДерева, ИмяКлючевойКолонки = "") Экспорт
Координаты = Новый Массив();
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
Координата = Родитель[ИмяКлючевойКолонки];
Иначе
Координата = ПолучитьРодителяСтрокиДереваЛкс(Родитель).Строки.Индекс(Родитель);
КонецЕсли;
Координаты.Вставить(0, Координата);
Родитель = Родитель.Родитель;
КонецЦикла;
Возврат Координаты;
КонецФункции
Функция ПолучитьСтрокуДереваПоКоординатамЛкс(Дерево, Координаты, ИмяКлючевойКолонки = "") Экспорт
СтрокаДерева = Дерево;
Для Каждого Координата Из Координаты Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
СтрокаДерева = СтрокаДерева.Строки.Найти(Координата, ИмяКлючевойКолонки);
Иначе
СтрокаДерева = СтрокаДерева.Строки[Координата];
КонецЕсли;
КонецЦикла;
Возврат СтрокаДерева;
КонецФункции
Процедура УстановитьТекстПоляСохраняяПозициюЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
НачальнаяКолонка = 0; НачальнаяСтрока = 0; КонечнаяКолонка = 0; КонечнаяСтрока = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекст);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
КонецПроцедуры
Функция ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL, АдресЧужойСхемыБД = "") Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЗначениеSDBL, ":");
Если Фрагменты.Количество() < 2 Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаНомераТаблицы = Фрагменты[0];
ИдентификаторОбъекта = Фрагменты[1];
ПолноеИмяМД = ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомераТаблицы, АдресЧужойСхемыБД);
ОбъектМетаданныхНайден = Истина;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
ПолноеИмяМД = "НеизвестныйСсылочныйТип" + СтрокаНомераТаблицы;
ОбъектМетаданныхНайден = Ложь;
КонецЕсли;
Результат = ПолноеИмяМД + "._" + ИдентификаторОбъекта;
Если ОбъектМетаданныхНайден И Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
//СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(Ложь);
// Этот способ не работал для перечислений
//УникальныйИдентификатор = Новый УникальныйИдентификатор(ПолучитьГУИДПрямойИзИнверсногоЛкс(Фрагменты[1]));
//Массив = Новый Массив();
//Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда
// Массив.Добавить(УникальныйИдентификатор);
//КонецЕсли;
//Значение = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)), Массив);
//
ПустаяСсылка = Новый (Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД)));
ПустаяСсылкаВнутр = ЗначениеВСтрокуВнутр(ПустаяСсылка);
ФрагментыПустойСсылки = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПустаяСсылкаВнутр, ":");
СсылкаВнутр = ФрагментыПустойСсылки[0] + ":" + ИдентификаторОбъекта + "}";
Попытка
Результат = ЗначениеИзСтрокиВнутр(СсылкаВнутр);
Исключение
// Например, если Фрагменты[1] содержит неверное число символов
КонецПопытки;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомерТаблицы, АдресЧужойСхемыБД = "") Экспорт
СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(,, АдресЧужойСхемыБД);
#Если Сервер И Не Сервер Тогда
СтруктураБД = Новый ТаблицаЗначений;
#КонецЕсли
СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданныхЛкс(, АдресЧужойСхемыБД);
Для Каждого СтрокаШаблона Из СловарьШаблоновМетаданных.НайтиСтроки(Новый Структура("Значение", 1)) Цикл
ИмяКандидат = СтрЗаменить(СтрокаШаблона.Ключ, "1", СтрокаНомерТаблицы);
СтрокаСтруктуры = СтруктураБД.Найти(ИмяКандидат, "КраткоеИмяТаблицыХранения");
Если СтрокаСтруктуры <> Неопределено Тогда
Возврат СтрокаСтруктуры.Метаданные;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
// Эта обертка нужно для возможности привязать ее к команде панели инструментов
Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт
ОтладитьОтложенныйОбъектЛкс();
КонецПроцедуры
Процедура ОтладитьОтложенныйОбъектЛкс(СсылкаИлиИмяФайла = Неопределено, УдалитьОбъектПослеУспешногоОткрытия = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
Ссылка = Справочники.ирОбъектыДляОтладки.ПустаяСсылка();
#КонецЕсли
СтруктураПараметров = Неопределено;
Если СсылкаИлиИмяФайла = Неопределено Тогда
СсылкаИлиИмяФайла = ПолучитьТекстИзБуфераОбменаОСЛкс();
ЕстьСправочник = Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено;
Если Не ВвестиСтроку(СсылкаИлиИмяФайла, "Введите результат сохранения объекта") Тогда
Если ЕстьСправочник Тогда
СсылкаИлиИмяФайла = ВыбратьСсылкуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки,, Ложь);
Иначе
ПутьДляФайловОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Расширение = ПолучитьРасширениеФайловДляОтладкиЛкс();
лПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, "Файлы объектов для отладки",, ПутьДляФайловОбъектовДляОтладки);
Если лПолноеИмяФайла <> Неопределено Тогда
СсылкаИлиИмяФайла = "Файл """ + лПолноеИмяФайла + """";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
ирПлатформа = ирКэш.Получить();
ВычислительРегулярныхВыражений = ирПлатформа.RegExp;
ВычислительРегулярныхВыражений.Pattern = "Объект ""([^""]+)""|Файл ""([^""]+)""|Пользователь ""([^""]+)""";
Результат = ВычислительРегулярныхВыражений.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);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Некорректный объект для отладки: " + ОписаниеОшибки, СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
КонецЕсли;
Объект = СтруктураПараметров.Объект;
ТипОперации = СтруктураПараметров.ТипОперации;
Если ТипОперации = "Отладить" Тогда
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = СтруктураПараметров.НастройкаКомпоновки;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
СтруктураЗапроса = Объект;
Объект = Новый Запрос;
Если Истина
И СтруктураЗапроса.Свойство("ВременныеТаблицы")
И СтруктураЗапроса.ВременныеТаблицы <> Неопределено
Тогда
Объект.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = "";
#Если Клиент Тогда
СостояниеЛкс("Подготовка временных таблиц");
#КонецЕсли
ТекстЗапросаПодготовки = "";
НеподдерживаемыеКолонки = "";
Для Каждого КлючИЗначение Из СтруктураЗапроса.ВременныеТаблицы Цикл
Если ТекстЗапросаПодготовки <> "" Тогда
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + ";";
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + ",";
КонецЕсли;
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + "ВЫБРАТЬ Т.* ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ &" + КлючИЗначение.Ключ + " КАК Т";
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + КлючИЗначение.Ключ;
ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КлючИЗначение.Значение, Истина);
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Если Ложь
Или Колонка.ТипЗначения.СодержитТип(Тип("МоментВремени"))
Или Колонка.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))
Или Колонка.ТипЗначения.СодержитТип(Тип("Тип"))
Тогда
Если НеподдерживаемыеКолонки <> "" Тогда
НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + ", ";
КонецЕсли;
НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + КлючИЗначение.Ключ + "." + Колонка.Имя;
КонецЕсли;
КонецЦикла;
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ТаблицаЗначений);
КонецЦикла;
Если НеподдерживаемыеКолонки <> "" Тогда
// https://partners.v8.1c.ru/forum/t/1570237/m/1570237
ВызватьИсключение "Невозможно восстановить временные таблицы из-за недопустимых типов (МоментВремени, УникальныйИдентификатор, Тип) в колонках: " + НеподдерживаемыеКолонки;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстЗапросаПодготовки) Тогда
Объект.Текст = ТекстЗапросаПодготовки;
Попытка
Объект.Выполнить();
Исключение
Сообщить("Ошибка восстановления временных таблиц: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
Объект.Параметры.Очистить();
Объект.Текст = СтруктураЗапроса.Текст;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураЗапроса.Параметры, Объект.Параметры);
Для Каждого КлючИЗначение Из СтруктураЗапроса.Параметры Цикл
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеИзСтрокиВнутр(КлючИЗначение.Значение));
КонецЦикла;
КонецЕсли;
ОтладитьЛкс(Объект, , НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, СтруктураПараметров.ВнешниеНаборыДанных);
ИначеЕсли ТипОперации = "Исследовать" Тогда
ИсследоватьЛкс(Объект, , СтруктураПараметров.КакКоллекцию);
КонецЕсли;
Если УдалитьОбъектПослеУспешногоОткрытия Тогда
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
УдалитьФайлы(СсылкаИлиИмяФайла);
Иначе
УдалениеОбъекта = Новый УдалениеОбъекта(СсылкаИлиИмяФайла);
УдалениеОбъекта.ОбменДанными.Загрузка = Истина;
УдалениеОбъекта.Записать();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// ОформляемыеКолонки - имена колонок, разделенные запятыми
Процедура ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля(ОформлениеСтроки, Знач ОформляемыеКолонки = "") Экспорт
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОформляемыеКолонки = Новый Структура(ОформляемыеКолонки);
НеФильтровтатьКолонки = (ОформляемыеКолонки.Количество() = 0);
Для Каждого Ячейка Из ОформлениеСтроки.Ячейки Цикл
Если Ложь
Или НеФильтровтатьКолонки
Или ОформляемыеКолонки.Свойство(Ячейка.Имя)
Тогда
ЗначениеЯчейки = Ячейка.Значение;
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
Ячейка.УстановитьТекст(ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки));
Ячейка.ЦветФона = WebЦвета.Роса;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля()
Процедура ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, РасширенноеЗначение = Null, ЛиТипСтрокаСлужебный = Ложь) Экспорт
Менеджер = Неопределено;
ТекущеееЗначение = ДанныеЭлементаФормыЛкс(Элемент);
Если ТипЗнч(ТекущеееЗначение) = Тип("Строка") Тогда
Попытка
ТипЗначенияПоля = ПолучитьТипЗначенияЭлементаФормыЛкс(Элемент);
Исключение
Если ТипЗнч(Элемент) = Тип("ПолеВвода") Тогда
ВызватьИсключение;
Иначе
// Для поля формы игнорируем
Возврат;
КонецЕсли;
КонецПопытки;
Типы = ТипЗначенияПоля.Типы();
Если Типы.Количество() > 1 Тогда
ПредставлениеЗначения = ПолучитьСтрокуМеждуМаркерамиЛкс(ТекущеееЗначение, "(", ")");
ЗначениеСсылки = ПреобразоватьЗначениеИзSDBLЛкс(ПредставлениеЗначения);
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
//e1cib/data/Справочник.ирОбъектыДляОтладки?ref=aa3a0009dd50223411e1c2907cccb6b7
Маркер = "e1cib/data/";
Если СтрокиРавныЛкс(Нрег(Лев(ТекущеееЗначение, СтрДлина(Маркер))), Маркер) Тогда
ТекстСсылки = Сред(ТекущеееЗначение, СтрДлина(Маркер) + 1);
Разделитель = "?ref=";
Идентификатор = ПолучитьПоследнийФрагментЛкс(ТекстСсылки, Разделитель);
Идентификатор = ПолучитьГУИДПрямойИзИнверсногоЛкс(Идентификатор);
ПолноеИмяМД = ПолучитьПервыйФрагментЛкс(ТекстСсылки, Разделитель);
лМенеджер = Новый (СтрЗаменить(ПолноеИмяМД, ".", "Менеджер."));
ЗначениеСсылки = лМенеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(Идентификатор));
КонецЕсли;
КонецЕсли;
Если Истина
И ЗначениеСсылки <> Неопределено
И ТипЗнч(ЗначениеСсылки) <> Тип("Строка")
И Элемент.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСсылки))
Тогда
Ответ = КодВозвратаДиалога.Да;
Если Не ЛиТипСтрокаСлужебный Тогда
Ответ = Вопрос("Хотите вставить строку как ссылку?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет);
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Значение = ЗначениеСсылки;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ТекущеееЗначение);
Если Фрагменты.Количество() > 1 Тогда
ИмяТипа = Фрагменты[0] + "." + Фрагменты[1];
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Значение = ОписаниеТипов.ПривестиЗначение();
Менеджер = ПолучитьМенеджерЛкс(Значение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЛиТипСтрокаСлужебный
И СтандартнаяОбработка
И ЗначениеЗаполнено(ТекущеееЗначение)
Тогда
Значение = "";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущеееЗначение)) Тогда
Менеджер = ПолучитьМенеджерЛкс(ТекущеееЗначение);
КонецЕсли;
Если Менеджер <> Неопределено Тогда
Значение = ПреобразоватьПредставлениеВСсылкуЛкс(Менеджер, Текст);
Если Значение <> Неопределено Тогда
СтандартнаяОбработка = Ложь;
КонецЕсли;
Иначе
Если Ложь
Или (Истина
И РасширенноеЗначение <> Null
И ТипЗнч(РасширенноеЗначение) <> ТипЗнч(ТекущеееЗначение))
Или Элемент.ОграничениеТипа.ПривестиЗначение(ТекущеееЗначение) <> ТекущеееЗначение
Тогда
// Откат
СтандартнаяОбработка = Ложь;
Значение = Новый СписокЗначений;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПреобразоватьПредставлениеВСсылкуЛкс(Знач МенеджерИлиОбъектМД, Знач Текст, КэшПоиска = Неопределено) Экспорт
Если ТипЗнч(МенеджерИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда
Менеджер = ПолучитьМенеджерЛкс(МенеджерИлиОбъектМД);
Иначе
Менеджер = МенеджерИлиОбъектМД;
КонецЕсли;
Текст = СокрЛП(Текст);
УникальныйИдентификатор = ирКэш.Получить().ПолучитьУникальныйИдентификаторИзСтроки(Текст);
Если УникальныйИдентификатор <> Неопределено Тогда
Значение = Менеджер.ПолучитьСсылку(УникальныйИдентификатор);
Иначе
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Менеджер));
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
Или Не РедактированиеРазрешено))
Тогда
СтандартнаяОбработка = Ложь;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , РасширенноеЗначение);
ФормаРедактирования.ТабличноеПоле = ЭлементУправления;
ИначеЕсли ТипРасширенногоЗначения = Тип("МоментВремени") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("МоментВремени", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("ТабличныйДокумент") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ТабличныйДокумент", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Граница") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Граница", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Массив") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Массив", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("УникальныйИдентификатор") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("УникальныйИдентификатор", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("СписокЗначений") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("СписокЗначений", , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Строка") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("Тип") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , Новый УникальныйИдентификатор());
ФормаРедактирования.МножественныйВыбор = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("ОписаниеТипов") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , РасширенноеЗначение);
ФормаРедактирования.МножественныйВыбор = Истина;
ИначеЕсли ТипРасширенногоЗначения = Тип("ХранилищеЗначения") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ХранилищеЗначения", , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("ДвоичныеДанные") Тогда
ФормаРедактирования = мПлатформа.ПолучитьФорму("ДвоичныеДанные", , Новый УникальныйИдентификатор());
КонецЕсли;
Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда
ФормаРедактирования.Заголовок = ЗаголовокФормы;
КонецЕсли;
Если ФормаРедактирования.Открыта() Тогда
ФормаРедактирования.Активизировать();
Возврат Результат;
КонецЕсли;
ФормаРедактирования.ТолькоПросмотр = Не РедактированиеРазрешено;
Если РедактированиеРазрешено Тогда
ФормаРедактирования.НачальноеЗначениеВыбора = ПолучитьКопиюОбъектаЛкс(РасширенноеЗначение); // Опасно
Иначе
ФормаРедактирования.НачальноеЗначениеВыбора = РасширенноеЗначение;
КонецЕсли;
Если РедактированиеРазрешено И РедактироватьМодально Тогда
РезультатВыбора = ФормаРедактирования.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
РасширенноеЗначение = РезультатВыбора;
Результат = Истина;
КонецЕсли;
Иначе
ФормаРедактирования.Открыть();
КонецЕсли;
ИначеЕсли Ложь
Или ТипРасширенногоЗначения = Тип("Число")
Или ТипРасширенногоЗначения = Тип("Строка")
Или ТипРасширенногоЗначения = Тип("Дата")
Или ТипРасширенногоЗначения = Тип("Булево")
Или ТипРасширенногоЗначения = Тип("Неопределено")
Или ТипРасширенногоЗначения = Тип("Null")
Или ТипРасширенногоЗначения = Тип("ПолеКомпоновкиДанных")
Или ТипРасширенногоЗначения = Тип("СтандартнаяДатаНачала")
Или ТипРасширенногоЗначения = Тип("СтандартныйПериод")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияНакопления")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияБухгалтерии")
Или ТипРасширенногоЗначения = Тип("ВидСчета")
Или (Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "Ref.") > 0)
Тогда
Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда
Если ЗначениеЗаполнено(РасширенноеЗначение) Тогда
Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ПолучитьПолноеИмяМДТипаЛкс(ТипРасширенногоЗначения) + " ГДЕ Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", РасширенноеЗначение);
ОбъектСуществует = Не Запрос.Выполнить().Пустой();
Если Не ОбъектСуществует Тогда
//ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле);
ОткрытьСсылкуВРедактореОбъектаБДЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Не СтандартнаяОбработка
Или Не РедактированиеРазрешено
Тогда
Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда
Если Истина
И ЗначениеЗаполнено(РасширенноеЗначение)
И ОбъектСуществует
Тогда
ОткрытьЗначение(РасширенноеЗначение);
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
Если СтандартнаяОбработка Тогда
ОткрытьЗначение(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Иначе
//Если Истина
// И ТипЗначения1 <> Неопределено
// И ТипЗначения1.ПривестиЗначение(РасширенноеЗначение) <> РасширенноеЗначение
//Тогда
ИсследоватьЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
//КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОткрытьРедакторИзПоляТабличногоДокументаЛкс(ПолеТабличногоДокумента) Экспорт
Копия = Новый ТабличныйДокумент;
Копия.Вывести(ПолеТабличногоДокумента);
ЗаполнитьЗначенияСвойств(Копия, ПолеТабличногоДокумента);
Результат = ирОбщий.ОткрытьЗначениеЛкс(Копия,,,, Ложь);
Возврат Результат;
КонецФункции
Функция ОткрытьРедакторСтрокиТаблицыЛкс(ЭтаФорма, ТабличноеПоле, ИмяТаблицыБДТабличногоПоля = Неопределено, СвязиИПараметрыВыбора = Истина) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Форма = мПлатформа.ПолучитьФорму("СтрокаТаблицы", ЭтаФорма, ТабличноеПоле);
Форма.ИмяТаблицыБД = ИмяТаблицыБДТабличногоПоля;
Форма.СвязиИПараметрыВыбора = СвязиИПараметрыВыбора;
Форма.Открыть();
Возврат Форма;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ТабличноеПоле, СтандартнаяОбработка = Ложь, РасширенноеЗначение = Null,
РедактированиеРазрешено = Истина, ПринудительноВОтдельнойФорме = Ложь, Данные = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
ЭлементУправления = Колонка.ЭлементУправления;
Иначе
Колонка = ТабличноеПоле.ТекущийЭлемент;
ЭлементУправления = Колонка;
КонецЕсли;
Если Не ЗначениеЗаполнено(Данные) Тогда
Данные = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если РасширенноеЗначение = Null Тогда
Если Не ЗначениеЗаполнено(Данные) Тогда
Возврат Ложь;
КонецЕсли;
РасширенноеЗначение = ТабличноеПоле.ТекущиеДанные[Данные];
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") И ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ТабличноеПоле.ТекущаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
РедактированиеРазрешено = РедактированиеРазрешено И Не Ячейка.ТолькоПросмотр;
КонецЕсли;
РедактированиеРазрешено = Истина
И РедактированиеРазрешено
И Не ТабличноеПоле.ТолькоПросмотр
И Не Колонка.ТолькоПросмотр
И ЭлементУправления <> Неопределено
И Не ЭлементУправления.ТолькоПросмотр;
Результат = ОткрытьЗначениеЛкс(РасширенноеЗначение, РедактированиеРазрешено, СтандартнаяОбработка,,, ПринудительноВОтдельнойФорме);
Если Результат Тогда
НовоеЗначение = РасширенноеЗначение; // Сохраняем значение, т.к. оно может испортиться следующей строкой
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени, УникальныйИдентификатор)
РасширенноеЗначение = НовоеЗначение;
КонецЕсли;
Возврат Результат;
КонецФункции // ОткрытьЗначениеЯчейки()
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаРасширенногоЗначения_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, РасширенноеЗначение = Null) Экспорт
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = Элемент.Значение;
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Элемент.ОграничениеТипа;
НовыйТип = ирОбщий.ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТип <> Неопределено Тогда
МассивТипов = ирОбщий.БыстрыйМассивЛкс(НовыйТип);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
РасширенноеЗначение = НовоеЗначение;
Элемент.Значение = РасширенноеЗначение; //
ЗначениеИзменено = Истина;
КонецЕсли;
Иначе
Результат = ирОбщий.ОткрытьЗначениеЛкс(РасширенноеЗначение, Истина, СтандартнаяОбработка);
Если Результат Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
Если Не СтандартнаяОбработка Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение = Null, ИспользоватьОграничениеТипа = Ложь,
СтруктураОтбора = Неопределено, Данные = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
ЭлементУправления = Колонка.ЭлементУправления;
Иначе
Колонка = ТабличноеПоле.ТекущийЭлемент;
ЭлементУправления = Колонка;
КонецЕсли;
Если Не ЗначениеЗаполнено(Данные) Тогда
Данные = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
РазрешитьВыборТипа = Истина;
Иначе
РазрешитьВыборТипа = Ложь;
КонецЕсли;
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле)[Данные];
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
Если Не РазрешитьВыборТипа Тогда
Возврат ЗначениеИзменено;
КонецЕсли;
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Неопределено;
Если ИспользоватьОграничениеТипа Тогда
ОграничениеТипа = ЭлементУправления.ОграничениеТипа;
Если Истина
И ОграничениеТипа.Типы().Количество() = 0
И ТипЗнч(ЭлементУправления) = Тип("ПолеФормы")
И ЗначениеЗаполнено(ЭлементУправления.СвязьПоТипу.ПутьКДанным)
Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ЭлементУправления);
Попытка
ОграничениеТипа = Вычислить("ЭтаФорма." + ЭлементУправления.СвязьПоТипу.ПутьКДанным);
Исключение
ВызватьИсключение "Ошибка вычисления влияющего типа поля: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если ОграничениеТипа.Типы().Количество() = 0 Тогда
ОграничениеТипа = ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементУправления);
КонецЕсли;
КонецЕсли;
НовыйТип = ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТип <> Неопределено Тогда
МассивТипов = БыстрыйМассивЛкс(НовыйТип);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени)
РасширенноеЗначение = НовоеЗначение;
ЗначениеИзменено = Истина;
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, ЭлементУправления, Истина,, РасширенноеЗначение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если РасширенноеЗначение <> Неопределено Тогда
ЗначениеИзменено = ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение, Истина, Истина, Данные) Или ЗначениеИзменено;
//Если ЗначениеИзменено Тогда
Если Не СтандартнаяОбработка Тогда
ТабличноеПоле.ТекущиеДанные[Данные] = РасширенноеЗначение;//
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, ЭлементУправления, Истина,, РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// ИменаКолонокСПиктограммамиТипов - Массив, Строка
Процедура ТабличноеПолеПриВыводеСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки, КнопкаРежимаОтображения = Неопределено, Знач ИменаКолонокСПиктограммамиТипов = "", РасширенныеКолонки = Неопределено,
РасширенноеПредставлениеХранилищЗначений = Ложь) Экспорт
КолонкиТаблицы = Элемент.Колонки;
Если КнопкаРежимаОтображения <> Неопределено Тогда
ВариантОтображенияИдентификаторов = КнопкаРежимаОтображения.Текст;
КонецЕсли;
Ячейки = ОформлениеСтроки.Ячейки;
СостоянияКнопки = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
ЛиОтбражатьПустые = Ложь
Или ВариантОтображенияИдентификаторов = СостоянияКнопки[1]
Или ВариантОтображенияИдентификаторов = СостоянияКнопки[2];
ОтображатьИдентификаторы = Ложь
Или ВариантОтображенияИдентификаторов = СостоянияКнопки[2];
ирПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Если ТипЗнч(ИменаКолонокСПиктограммамиТипов) = Тип("Строка") Тогда
ИменаКолонокСПиктограммамиТипов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонокСПиктограммамиТипов, ",", Истина);
КонецЕсли;
Для Каждого Колонка Из КолонкиТаблицы Цикл
Ячейка = Ячейки[Колонка.Имя];
КолонкаДанных = Неопределено;
Если РасширенныеКолонки <> Неопределено Тогда
РасширенныеКолонки.Свойство(Колонка.Имя, КолонкаДанных);
КонецЕсли;
КолонкаОтображаетДанныеФлажка = Ложь;
Если КолонкаДанных <> Неопределено Тогда
ЗначениеЯчейки = ДанныеСтроки[КолонкаДанных];
Иначе
Если Истина
И Не ЗначениеЗаполнено(Колонка.Данные)
И ЗначениеЗаполнено(Колонка.ДанныеФлажка)
Тогда
ЗначениеЯчейки = Ячейка.ЗначениеФлажка;
КолонкаОтображаетДанныеФлажка = Истина;
Иначе
ЗначениеЯчейки = Ячейка.Значение;
КонецЕсли;
КонецЕсли;
Если Ложь
Или КолонкаОтображаетДанныеФлажка
Или Формат(ЗначениеЯчейки, Колонка.Формат) = Ячейка.Текст
Тогда // Здесь могут быть обращения к БД
ПредставлениеЗначения = "";
Если Истина
И Не КолонкаОтображаетДанныеФлажка
И ТипЗнч(ЗначениеЯчейки) <> Тип("Строка")
Тогда
ПредставлениеЗначения = РасширенноеПредставлениеЗначенияЛкс(ЗначениеЯчейки, Колонка,, РасширенноеПредставлениеХранилищЗначений);
КонецЕсли;
Если ЛиОтбражатьПустые И Не ЭтоКоллекцияЛкс(ЗначениеЯчейки) Тогда
ЦветПустых = ЦветФонаЯчеекПустыхЗначенийЛкс();
Если ТипЗнч(ЗначениеЯчейки) = Тип("Строка") Тогда
ПредставлениеЗначения = """" + ЗначениеЯчейки + """";
Ячейка.ЦветФона = ЦветПустых;
Иначе
Попытка
ЗначениеНепустое = ЗначениеЗаполнено(ЗначениеЯчейки) И ЗначениеЯчейки <> Ложь;
Исключение
ЗначениеНепустое = Истина;
КонецПопытки;
Если Не ЗначениеНепустое Тогда
ПредставлениеЗначения = ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки);
Ячейка.ЦветФона = ЦветПустых;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПредставлениеЗначения <> "" Тогда
Ячейка.УстановитьТекст(ПредставлениеЗначения);
КонецЕсли;
КонецЕсли;
Если ОтображатьИдентификаторы Тогда
ИдентификаторСсылки = ПолучитьИдентификаторСсылкиЛкс(ЗначениеЯчейки, Истина);
Если ИдентификаторСсылки <> Неопределено Тогда
Ячейка.УстановитьТекст(ИдентификаторСсылки);
КонецЕсли;
КонецЕсли;
Если ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) <> Неопределено Тогда
Если ТипЗнч(ЗначениеЯчейки) <> Тип("ПолеКомпоновкиДанных") Тогда
ТипЗначения = ТипЗнч(ЗначениеЯчейки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если Ячейки.Найти(ИмяКолонкиНомерСтроки) <> Неопределено Тогда
Если ТипЗнч(ДанныеСтроки) = Тип("СтрокаДереваЗначений") Тогда
ИндексСтроки = ПолучитьРодителяСтрокиДереваЛкс(ДанныеСтроки, ДанныеСтроки.Владелец()).Строки.Индекс(ДанныеСтроки);
Иначе
ИндексСтроки = ДанныеСтроки.Владелец().Индекс(ДанныеСтроки);
КонецЕсли;
Ячейки[ИмяКолонкиНомерСтроки].УстановитьТекст(XMLСтрока(ИндексСтроки + 1));
Ячейки[ИмяКолонкиНомерСтроки].ЦветТекста = Новый Цвет(128, 128, 128);
КонецЕсли;
КонецПроцедуры
Функция ПолныйИдентификаторСсылкиЛкс(Знач ЗначениеЯчейки) Экспорт
ИдентификаторСсылки = ПолучитьИдентификаторСсылкиЛкс(ЗначениеЯчейки);
Возврат ИдентификаторСсылки;
КонецФункции
Функция ПолучитьИдентификаторЗначенияЛкс(Значение) Экспорт
ИдентификаторЗначения = ПолучитьИдентификаторСсылкиЛкс(Значение);
Если ИдентификаторЗначения = Неопределено Тогда
ИдентификаторЗначения = Формат(Значение, "ЧН=; ДП=; БЛ=");
КонецЕсли;
Возврат ИдентификаторЗначения;
КонецФункции
Процедура ТабличноеПолеВставитьКолонкуНомерСтрокиЛкс(Знач ТабличноеПоле) Экспорт
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиНомерСтроки) = Неопределено Тогда
КолонкаТП = ТабличноеПоле.Колонки.Вставить(0);
КолонкаТП.Имя = ИмяКолонкиНомерСтроки;
КолонкаТП.ТекстШапки = "№";
КолонкаТП.ПодсказкаВШапке = "Номер элемента в пределах родителя (служебная)";
КолонкаТП.ТолькоПросмотр = Истина;
КолонкаТП.Ширина = 3;
КонецЕсли;
КонецПроцедуры // ОбновитьТаблицуКолонок()
Процедура _РасширенныйВыборПравогоЗначенияОтбораКомпоновкиЛкс(ТабличноеПолеОтбора) Экспорт
ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока;
Если Ложь
Или ТекущаяСтрока = Неопределено
Или ТипЗнч(ТекущаяСтрока) = Тип("ОтборКомпоновкиДанных")
Или ТипЗнч(ТекущаяСтрока) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
Возврат;
КонецЕсли;
ЗначениеОтбора = ТекущаяСтрока.ПравоеЗначение;
КолонкаТП = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента;
ТабличноеПолеОтбора.ТекущаяКолонка = КолонкаТП;
Если ТипЗнч(ЗначениеОтбора) <> Тип("СписокЗначений") Тогда
Если ЛиСсылкаНаОбъектБДЛкс(ЗначениеОтбора, Ложь) Тогда
ТабличноеПолеОтбора.ИзменитьСтроку();
ирОбщий.ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеОтбора)),,, КолонкаТП.ЭлементУправления, Истина,, ЗначениеОтбора);
КонецЕсли;
Иначе
Результат = ирОбщий.ОткрытьЗначениеЛкс(ЗначениеОтбора, Истина);
Если Результат Тогда
ТекущаяСтрока.ПравоеЗначение = ЗначениеОтбора;
ТекущаяСтрока.Использование = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка) Экспорт
МассивСостояний = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда
ТекстКнопки = Кнопка.Текст;
Иначе
ТекстКнопки = Кнопка.Заголовок;
КонецЕсли;
Если ТекстКнопки = МассивСостояний[2] Тогда
Кнопка.Пометка = Ложь;
НовыйТекстКнопки = МассивСостояний[0];
Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирПусто");
ИначеЕсли ТекстКнопки = МассивСостояний[1] Тогда
Кнопка.Пометка = Истина;
НовыйТекстКнопки = МассивСостояний[2];
Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирИдентификатор");
Иначе//Если ТекстКнопки = МассивСостояний[0] Тогда
Кнопка.Пометка = Истина;
НовыйТекстКнопки = МассивСостояний[1];
Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирПусто");
КонецЕсли;
Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда
Кнопка.Текст = НовыйТекстКнопки;
Иначе
Кнопка.Заголовок = НовыйТекстКнопки;
КонецЕсли;
КонецПроцедуры
Процедура ПрименитьИзмененияИЗакрытьФормуЛкс(ЭтаФорма, ЗначениеВыбора = Неопределено) Экспорт
ЭтаФорма.Модифицированность = Ложь;
Если Ложь
Или ЭтаФорма.ВладелецФормы <> Неопределено
Или Не ЭтаФорма.Открыта()
Тогда
ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
КонецЕсли;
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть(ЗначениеВыбора);
КонецЕсли;
//Если ЭтаФорма.Открыта() Тогда
// ЭтаФорма.Закрыть(ЗначениеВыбора);
//Иначе//Если ЭтаФорма.МодальныйРежим Тогда
// ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
//КонецЕсли;
КонецПроцедуры // ПрименитьИзмененияИЗакрытьФорму()
Функция НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Знач Слово, ЯзыкПрограммы = 0, ПоискСУчетомТипаСлова = Истина) Экспорт
мПлатформа = ирКэш.Получить();
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
МассивВозможныхТиповСлова = Новый Массив;
МассивВозможныхТиповСлова.Добавить("Конструктор");
Слово = НРег(Слово);
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) = "("
Тогда
Если Прав(Слово, 1) = "(" Тогда
Слово = ПолучитьСтрокуБезКонцаЛкс(Слово, 1);
КонецЕсли;
МассивВозможныхТиповСлова.Добавить("Метод");
КонецЕсли;
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) <> "("
Тогда
МассивВозможныхТиповСлова.Добавить("Свойство");
МассивВозможныхТиповСлова.Добавить("Конструкция");
МассивВозможныхТиповСлова.Добавить("Событие");
МассивВозможныхТиповСлова.Добавить("Таблица");
КонецЕсли;
ТаблицаСтруктурВозможныхТиповКонтекста = мПлатформа.ПолучитьНовуюТаблицуСтруктурТипа();
Для Каждого ВозможныйТипСлова Из МассивВозможныхТиповСлова Цикл
Если ВозможныйТипСлова = "Конструктор" Тогда
КлючПоиска = Новый Структура("ТипКонтекста, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
Иначе
КлючПоиска = Новый Структура("НСлово, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
КонецЕсли;
НайденныеСтроки = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
НайденныеСтроки = мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
КонецЦикла;
КлючПоиска = Новый Структура("НСлово, ЯзыкПрограммы", Слово, ЯзыкПрограммы);
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
Возврат ТаблицаСтруктурВозможныхТиповКонтекста;
КонецФункции // НайтиВозможныеСтрокиОписанияСлова()
// Открывает форму синтакс-помощника и загружает в нее нужную страницу, подсвечивая заданную строку.
//
// Параметры:
// ВнутреннийПутьКОписанию Строка внутренний путь к странице синтакс-помощника;
// СтрокаДляПодсветки Строка которую нужно подсветить в тексте страницы.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьСтраницуСинтаксПомощникаЛкс(ВнутреннийПутьКОписанию, СтрокаДляПодсветки = "", ВладелецФормы = Неопределено, КлючУникальности = Неопределено) Экспорт
Если ВнутреннийПутьКОписанию = "" Тогда
Возврат Неопределено;
КонецЕсли;
ФормаСправка = ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , , КлючУникальности);
ФормаСправка.ВладелецФормы = ВладелецФормы;
ФормаСправка.ОткрытьАдрес(ВнутреннийПутьКОписанию, СтрокаДляПодсветки);
ФормаСправка.ВладелецФормы = Неопределено;
Возврат ФормаСправка;
КонецФункции // ОткрытьСтраницуСинтаксПомощникаЛкс()
// Обходит строки табличного поля и имитирует редактирование и выбор пользователем заданного значения.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле;
// ЗначениеОбработки - Произвольные - значение, которое будем записывать в ячейки;
// *ФормаИнициатор - Форма, *Неопределено - форма, от имени которой будет записывать;
// *ТипИсточника Строка, *Неопределено "ТаблицаЗначений", "ТабличнаяЧасть";
// *Колонка КолонкаТабличногоПоля, *Неопределено колонка в которой обходим ячейки, по умолчанию текущая;
// *ТолькоВыделенныеСтроки - Булево, *Истина - обходить только выделенные строки.
//
Процедура УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, ЗначениеОбработки, ФормаИнициатор = Неопределено, Знач ТипИсточника = Неопределено,
Знач Колонка = Неопределено, Знач ТолькоВыделенныеСтроки = Истина, Знач ИнтерактивноеУстановка = Истина) Экспорт
Если Колонка = Неопределено Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
Иначе
ТабличноеПоле.ТекущаяКолонка = Колонка;
КонецЕсли;
ЗначениеТабличногоПоля = ТабличноеПоле.Значение;
Если ТипИсточника = "" Тогда
ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
ЕстьОтборСтрок = Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей";
Если ТолькоВыделенныеСтроки Тогда
Если Истина
И ТабличноеПоле.ВыделенныеСтроки.Количество() = 1
И ТипИсточника <> "ДеревоЗначений"
Тогда
ТекстОтбора = "";
Если ЕстьОтборСтрок Тогда
ТекстОтбора = " удовлетворяющие отбору";
КонецЕсли;
Ответ = Вопрос("Выделена только одна строка. Хотите обработать все" + ТекстОтбора + " строки?",
РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТолькоВыделенныеСтроки = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КлючиСтрокДляОбработки = Новый Массив;
Если ТолькоВыделенныеСтроки Тогда
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючиСтрокДляОбработки.Добавить(ВыделеннаяСтрока);
КонецЦикла;
Иначе
Если ЕстьОтборСтрок Тогда
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЗначениеТабличногоПоля);
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить("НомерСтроки");
СкопироватьОтборПостроителяЛкс(Построитель.Отбор, ТабличноеПоле.ОтборСтрок);
ТаблицаРезультата = Построитель.Результат.Выгрузить();
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаРезультата.НомерСтроки - 1);
КонецЦикла;
ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда
Для Каждого СтрокаТаблицы Из ТабличноеПоле.Значение Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Индикатор = ПолучитьИндикаторПроцессаЛкс(КлючиСтрокДляОбработки.Количество(), "Групповая установка значения");
// Нужно встать на редактируемую колонку, чтобы сработал режим редактирования
Для Каждого КлючСтроки Из КлючиСтрокДляОбработки Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если ТипЗнч(КлючСтроки) = Тип("Число") Тогда
ТекущаяСтрока = ТабличноеПоле.Значение[КлючСтроки];
Иначе
ТекущаяСтрока = КлючСтроки;
КонецЕсли;
Если ТипЗнч(ЗначениеОбработки) = Тип("Структура") Тогда
ЗаполнитьЗначенияСвойств(ЗначениеОбработки.Параметры, ТекущаяСтрока);
НовоеЗначение = ВычислитьВыражение(ЗначениеОбработки.Формула, ЗначениеОбработки.Параметры);
Иначе
НовоеЗначение = ЗначениеОбработки;
КонецЕсли;
Если ИнтерактивноеУстановка Тогда
ТабличноеПоле.ТекущаяСтрока = ТекущаяСтрока;
//ТабличноеПоле.ИзменитьСтроку();
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение, ФормаИнициатор,,, Ложь);
ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь);
Иначе
ТекущаяСтрока[Колонка.Имя] = НовоеЗначение;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс(Индикатор);
КонецПроцедуры
Функция ТаблицаЗначенийИзТабличногоПоляЛкс(Знач ИсточникДействий, МассивСтрок = Неопределено) Экспорт
ИмяТипаЗначения = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ИсточникДействий);
Если ИмяТипаЗначения = "Список" Тогда
Возврат Неопределено;
КонецЕсли;
ЗначениеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ИсточникДействий);
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ИсточникДействий) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
Если ТипЗнч(ЗначениеТабличногоПоля) = Тип("ТаблицаЗначений") Тогда
ВыгрузкаРезультата = ЗначениеТабличногоПоля.Скопировать(МассивСтрок);
Иначе
ВыгрузкаРезультата = ЗначениеТабличногоПоля.Выгрузить(МассивСтрок);
КонецЕсли;
Иначе
ТипЗначенияТаблицы = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ИсточникДействий).Типы()[0];
ИмяОбщегоТипа = ОбщийТипДанныхТабличногоПоляЛкс(ИсточникДействий, Истина);
ОбъектМДТаблицы = Метаданные.НайтиПоТипу(ТипЗначенияТаблицы);
Если ОбъектМДТаблицы <> Неопределено Тогда
ВыгрузкаРезультата = Новый ТаблицаЗначений;
Если ИмяОбщегоТипа = "ТабличнаяЧасть" Тогда
// Через поля таблицы БД нельзя, т.к. у ТЧ может не быть проекции в БД
Для Каждого МетаРеквизит Из ОбъектМДТаблицы.Реквизиты Цикл
ВыгрузкаРезультата.Колонки.Добавить(МетаРеквизит.Имя, МетаРеквизит.Тип, МетаРеквизит.Представление());
КонецЦикла;
Иначе
ПоляТаблицыБД = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ОбъектМДТаблицы);
Для Каждого ПолеБД Из ПоляТаблицыБД Цикл
ВыгрузкаРезультата.Колонки.Добавить(ПолеБД.Имя, ПолеБД.ТипЗначения, ПолеБД.Заголовок);
КонецЦикла;
КонецЕсли;
Иначе
ВыгрузкаРезультата = ДанныеФормыВЗначение(ЗначениеТабличногоПоля, Тип(ИмяТипаЗначения));
#Если Сервер И Не Сервер Тогда
ВыгрузкаРезультата = Новый ТаблицаЗначений;
#КонецЕсли
ВыгрузкаРезультата.Очистить(); // Лишняя работа для единообразия
КонецЕсли;
КоллекцияСтрок = ЗначениеТабличногоПоля;
Если МассивСтрок <> Неопределено Тогда
КоллекцияСтрок = Новый Массив;
Для Каждого ИдентификаторСтроки Из МассивСтрок Цикл
КоллекцияСтрок.Добавить(ИсточникДействий.ДанныеСтроки(ИдентификаторСтроки));
КонецЦикла;
КонецЕсли;
Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
ЗаполнитьЗначенияСвойств(ВыгрузкаРезультата.Добавить(), СтрокаКоллекции);
КонецЦикла;
КонецЕсли;
Возврат ВыгрузкаРезультата;
КонецФункции
Процедура ПоследниеВыбранныеНажатиеЛкс(Знач ЭтаФорма, ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач Кнопка) Экспорт
//КлючСтроки = ЗначениеИзСтрокиВнутр(Кнопка.Имя);
КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(Кнопка) = Тип("КомандаФормы") Тогда
Сообщить("В управляемых формах функция не реализована");
Возврат;
Иначе
ИндексЭлементаСписка = Число(Сред(Кнопка.Имя, 2));
КонецЕсли;
Если ПоследниеВыбранные.Количество() <= ИндексЭлементаСписка Тогда
Возврат;
КонецЕсли;
КлючСтроки = ПоследниеВыбранные[ИндексЭлементаСписка].Значение;
СтрокаНайдена = ирОбщий.УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(ЭтаФорма, ТабличноеПоле, КлючевоеПоле, КлючСтроки,, Истина);
Если СтрокаНайдена И ЭтаФорма.РежимВыбора Тогда
Ответ = Вопрос("Выбрать установленную строку?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЭтаФорма.ОповеститьОВыборе(КлючСтроки);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура НайденныеСтандартноСсылкиПриВыводеСтрокиЛкс(Знач ОформлениеСтроки) Экспорт
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Ячейки = ОформлениеСтроки.Ячейки;
Если ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ирОбщий.ПолучитьПервыйФрагментЛкс(ДанныеСтроки.Метаданные)) Тогда
Попытка
КлючЗаписи = ЗначениеИзСтрокиВнутр(Ячейки.Данные.Текст);
Исключение
// Некоторые большие ключи регистров в сериализованном виде не умещаются в 1024 символа
КлючЗаписи = "<Ключ записи регистра обрезан и не может быть восстановлен>";
КонецПопытки;
Ячейки.Данные.Текст = ирОбщий.ПредставлениеКлючаСтрокиБДЛкс(КлючЗаписи, Ложь);
КонецЕсли;
КонецПроцедуры
Процедура ПоследниеВыбранныеДобавитьЛкс(ЭтаФорма, ВыбранноеЗначение) Экспорт
ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс();
Если Истина
И ЗапоминатьПоследниеВыбранные <> Неопределено
И ЗапоминатьПоследниеВыбранные > 0
Тогда
КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
ПоследниеВыбранные = Новый СписокЗначений;
КонецЕсли;
Если ТипЗнч(ВыбранноеЗначение) <> Тип("Массив") Тогда
МассивВыбранныхСтрок = Новый Массив;
МассивВыбранныхСтрок.Добавить(ВыбранноеЗначение);
Иначе
// Такое предположительно происходит из-за ошибки в платформе
МассивВыбранныхСтрок = ВыбранноеЗначение;
КонецЕсли;
Для Каждого СтрокаИзМассива Из МассивВыбранныхСтрок Цикл
Индекс = ПоследниеВыбранные.НайтиПоЗначению(СтрокаИзМассива);
Если Индекс <> Неопределено Тогда
ПоследниеВыбранные.Удалить(Индекс);
КонецЕсли;
КлючСтроки = СтрокаИзМассива;
ПредставленияКлюча = ПредставлениеКлючаСтрокиБДЛкс(КлючСтроки);
ПоследниеВыбранные.Вставить(0, КлючСтроки, ПредставленияКлюча);
КонецЦикла;
ирОбщий.СохранитьЗначениеЛкс(КлючЗначения, ПоследниеВыбранные);
КонецЕсли;
КонецПроцедуры
Процедура ОформитьФонТекущейСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Элемент.ТекущаяСтрока = ДанныеСтроки Тогда
ОформлениеСтроки.ЦветФона = WebЦвета.СветлоНебесноГолубой;
КонецЕсли;
КонецПроцедуры
Функция ПроверитьЗапуститьОтладчик(Знач ВремяОжиданияЗапуска = 5) Экспорт
ИдентификаторПроцессаОтладчика = Неопределено;
Платформа = ирКэш.Получить();
ПортОтладки = Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
//Если Не УФ(сПроверитьДоступностьКонфигуратора) Тогда
// Сообщить("Конфигуратор уже открыт, но отладка не подключена. Выполните подключение отладчика вручную");
// Перейти ~Конец;
//КонецЕсли;
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164
Если ирКэш.НомерВерсииПлатформыЛкс() = 802015 Тогда
Предупреждение("Из-за ошибки платформы 8.2.15 запуск и подключение отладчика необходимо выполнять вручную", 20);
Возврат Неопределено;
КонецЕсли;
Если ПортОтладки = Неопределено Тогда
Предупреждение("Включите разрешение отладки в главном меню ""Сервис/Параметры/Системные"" и повторите операцию снова");
Возврат Неопределено;
КонецЕсли;
ПараметрыЗапуска = "CONFIG /DEBUG /DEBUGTARGET""tcp://127.0.0.1:" + ПортОтладки + """";
ЗапуститьСистему(ПараметрыЗапуска);
Платформа.Sleep(ВремяОжиданияЗапуска);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
ИдентификаторПроцессаОтладчика = 0;
КонецЕсли;
Пока Истина Цикл
Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
Ответ = Вопрос("Отладчик еще не подключился. Повторить снова?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
Иначе
Платформа.АктивизироватьОкноПроцесса1С8(Число(ИдентификаторПроцессаОтладчика));
КонецЕсли;
Если ИдентификаторПроцессаОтладчика <> Неопределено Тогда
Результат = Число(ИдентификаторПроцессаОтладчика);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ТекущаяКолонка = ТабличноеПоле.ТекущийЭлемент;
Иначе
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
КонецЕсли;
Если ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ИмяКолонки = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущаяКолонка, Истина);
Иначе
ИмяКолонки = ТекущаяКолонка.Данные;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ИмяКолонки];
XMLТип = XMLТипЗнч(ЗначениеЯчейки);
Если XMLТип = Неопределено Тогда
Возврат;
КонецЕсли;
Если Найти(XMLТип.ИмяТипа, "Ref.") = 0 Тогда
Возврат;
КонецЕсли;
//Если Ложь
// Или Найти(XMLТип.ИмяТипа, "EnumRef.") > 0
// Или Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0
//Тогда
// ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеЯчейки)),, Истина,,,, ЗначениеЯчейки);
//Иначе
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеЯчейки);
//КонецЕсли;
КонецПроцедуры
// Параметры
// КлючИлиОбъект - СтруктураОбъектаБД, Ссылка, ОбъектБД
Функция ОткрытьСсылкуВРедактореОбъектаБДЛкс(КлючОбъекта, пИскомоеЗначение = Неопределено) Экспорт
Форма = ПолучитьФормуСсылки(КлючОбъекта, пИскомоеЗначение);
Форма.Открыть();
Возврат Форма;
КонецФункции
Функция ОткрытьОбъектВРедактореОбъектаБДЛкс(ОбъектБД, пИскомоеЗначение = Неопределено, КлючУникальности = Неопределено) Экспорт
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", ОбъектБД);
ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Ложь);
ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", пИскомоеЗначение);
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючУникальности);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Форма.фОбъект, ПараметрыФормы, "ПараметрКлючИлиОбъект, ПараметрПрочитатьОбъект, ПараметрИскомоеЗначение");
Форма.Открыть();
Возврат Форма;
КонецФункции
// Параметры
// КлючИлиОбъект - СтруктураОбъектаБД, Ссылка, ОбъектБД
Функция ПолучитьФормуСсылки(КлючОбъекта, пИскомоеЗначение = Неопределено)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", КлючОбъекта);
ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Истина);
ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", пИскомоеЗначение);
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючОбъекта);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы);
Возврат Форма;
КонецФункции
Процедура НайтиИПоказатьСсылкиНаОбъектБД(СсылкаНаКоторуюИщемСсылки) Экспорт
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", СсылкаНаКоторуюИщемСсылки);
Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы);
#Если Сервер И Не Сервер Тогда
Форма = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы);
Форма.Открыть();
Форма.НайтиИПоказатьСсылкиВФорме();
КонецПроцедуры // НайтиСсылки()
// ВариантПросмотра - Строка - "Компактный", "ЯзыкЗапросов", "ВстроенныйЯзык", ...
Функция ПолучитьФормуТекстаЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор();
КонецЕсли;
ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("Текст", ВладелецФормы, КлючУникальности);
ФормаПросмотра.НачальноеЗначениеВыбора = Текст;
ФормаПросмотра.РекомендуемыйВариант = ВариантПросмотра;
ФормаПросмотра.ТолькоПросмотр = ТолькоПросмотр;
Если Не ЗначениеЗаполнено(Заголовок) Тогда
//Заголовок = ФормаПросмотра.Заголовок;
Заголовок = ""; // Чтобы при повторном открытии не оставался старый текст
КонецЕсли;
ФормаПросмотра.Заголовок = Заголовок;
Возврат ФормаПросмотра;
КонецФункции
Функция ОткрытьТекстЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
ФормаПросмотра = ПолучитьФормуТекстаЛкс(Текст, Заголовок, ВариантПросмотра, ТолькоПросмотр, КлючУникальности, ВладелецФормы);
ФормаПросмотра.Открыть();
Возврат ФормаПросмотра;
КонецФункции
Процедура ПолеВводаТекста_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтандартнаяОбработка = Ложь;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("Текст", Элемент, Новый УникальныйИдентификатор);
ФормаРедактора.РежимВыбора = Истина;
ФормаРедактора.НачальноеЗначениеВыбора = Элемент.Значение;
ФормаРедактора.Открыть();
КонецЕсли;
КонецПроцедуры
// Для управляемой формы возвращает путь относительно родителя
Функция ПутьКДаннымКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Колонка = Неопределено) Экспорт
Если Колонка = Неопределено Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Колонка = ТабличноеПоле.ТекущийЭлемент;
Иначе
Колонка = ТабличноеПоле.ТекущаяКолонка;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Колонка) = Тип("ПолеФормы") Тогда
ДанныеКолонки = ПутьКДаннымЭлементаУправляемойФормыЛкс(Колонка, Истина);
ИначеЕсли Колонка <> Неопределено Тогда
ДанныеКолонки = Колонка.Данные;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
ДанныеКолонки = Колонка.ДанныеФлажка;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Если Ложь
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений")
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений")
Тогда
ДанныеКолонки = Колонка.ДанныеКартинки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ДанныеКолонки;
КонецФункции
Процедура ТабличноеПоле_ОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(Знач ТабличноеПоле) Экспорт
Если ТабличноеПоле.ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Возврат;
КонецЕсли;
ДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДанныеТабличногоПоля, "Пользовательские");
Попытка
Отбор = НастройкиСписка.Отбор;
Исключение
Отбор = ТабличноеПоле.ОтборСтрок;
КонецПопытки;
//Отбор = Новый ("Отбор");
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
ЭлементОтбора = Отбор[ДанныеКолонки];
ДоступноеПоле = ЭлементОтбора;
ТекущееЗначениеОтбора = ЭлементОтбора.Значение;
Иначе
ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Отбор, ДанныеКолонки,,,,, Ложь);
ДоступноеПоле = Отбор.ДоступныеПоляОтбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ДанныеКолонки));
ТекущееЗначениеОтбора = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки];
Если ЭлементОтбора.Использование Тогда
Если Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно
Тогда
Если Ложь
Или ТипЗнч(ЗначениеЯчейки) <> Тип("Булево")
Или ДоступноеПоле.ТипЗначения.Типы().Количество() > 1
Тогда
СписокЗначений = Новый СписокЗначений;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
НовыйВидСравения = ВидСравнения.НеВСписке;
Иначе
НовыйВидСравения = ВидСравненияКомпоновкиДанных.НеВСписке;
КонецЕсли;
СписокЗначений.Добавить(ТекущееЗначениеОтбора);
СписокЗначений.Добавить(ЗначениеЯчейки);
ЭлементОтбора.ВидСравнения = НовыйВидСравения;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.Значение = СписокЗначений;
Иначе
ЭлементОтбора.ПравоеЗначение = СписокЗначений;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке
Тогда
СписокЗначений = ТекущееЗначениеОтбора;
СписокЗначений.Добавить(ЗначениеЯчейки);
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
ИначеЕсли Ложь
Или ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке
Тогда
СписокЗначений = ТекущееЗначениеОтбора;
СписокЗначений.Удалить(СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки));
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
Иначе
ЭлементОтбора.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЭлементОтбора.Использование Тогда
ЭлементОтбора.Использование = Истина;
Если Истина
И ДоступноеПоле.ТипЗначения.СодержитТип(Тип("Строка"))
И ДоступноеПоле.ТипЗначения.КвалификаторыСтроки.Длина = 0
Тогда
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
// Особенность платформы
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
Иначе
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит;
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда
// Привести значение нужно например для NULL в динамическом списке регистра бухгалтерии
ЭлементОтбора.Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(ЗначениеЯчейки);
Иначе
ЭлементОтбора.ПравоеЗначение = ЗначениеЯчейки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ЗагрузитьЗначениеИзФайлаИнтерактивноЛкс(Знач Расширение = "", Знач ОписаниеФормата = "", Знач Сжатие = Истина) Экспорт
Если Не ЗначениеЗаполнено(Расширение) И Сжатие Тогда
Расширение = "zip";
КонецЕсли;
ПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = ЗагрузитьЗначениеИзФайлаЛкс(ПолноеИмяФайла, Сжатие);
Возврат Результат;
КонецФункции
Функция ЗагрузитьЗначениеИзФайлаЛкс(ПолноеИмяФайла, Знач Сжатие = Ложь) Экспорт
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла);
ЗипЧтение.ИзвлечьВсе(ВременныйКаталог);
ПолноеИмяФайла = ВременныйКаталог + "\" + ЗипЧтение.Элементы[0].Имя;
КонецЕсли;
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ);
Исключение
Сообщить(ОписаниеОшибки());
Результат = Неопределено;
КонецПопытки;
ЧтениеХМЛ.Закрыть();
Если Сжатие Тогда
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлИнтерактивноЛкс(Знач Значение, Знач Расширение = "", Знач ОписаниеФормата = "", Знач Сжатие = Истина, Знач УровеньСжатия = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(Расширение) И Сжатие Тогда
Расширение = "zip";
КонецЕсли;
ПолноеИмяФайла = ВыбратьФайлЛкс(Ложь, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Результат = СохранитьЗначениеВФайлЛкс(Значение, ПолноеИмяФайла, Сжатие, УровеньСжатия);
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлЛкс(Знач Значение, Знач ПолноеИмяФайла, Сжатие = Ложь, УровеньСжатия = Неопределено) Экспорт
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//ЗначениеВФайл(ВыборФайла.ПолноеИмяФайла, Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
Результат = Истина;
Исключение
Сообщить(ОписаниеОшибки());
Результат = Ложь;
КонецПопытки;
ЗаписьХМЛ.Закрыть();
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
Файл = Новый Файл(ПолноеИмяФайла);
ИмяВременногоФайла = ВременныйКаталог + "\" + Файл.Имя;
ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла);
ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия);
ЗаписьЗип.Добавить(ИмяВременногоФайла);
ЗаписьЗип.Записать();
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыбратьРедактируемыйТипЛкс(ОграничениеТипа = Неопределено, ТолькоПросмотр = Ложь, НачальноеЗначениеВыбора = Неопределено) Экспорт
Если ОграничениеТипа = Неопределено Тогда
ОграничениеТипа = Новый ОписаниеТипов;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов");
ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = НачальноеЗначениеВыбора;
ФормаРедактора.МножественныйВыбор = Ложь;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции // РедактироватьДопустимыеТипы()
Функция РедактироватьОписаниеРедактируемыхТиповЛкс(ОграничениеТипаИлиПолеВвода, ТолькоПросмотр = Ложь) Экспорт
Если ТипЗнч(ОграничениеТипаИлиПолеВвода) = Тип("ОписаниеТипов") Тогда
ВладелецФормы = Неопределено;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода;
Иначе
ВладелецФормы = ОграничениеТипаИлиПолеВвода;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода.Значение;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы);
//ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = ОграничениеТипа;
ФормаРедактора.МножественныйВыбор = Истина;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции // РедактироватьДопустимыеТипы()
// ПолноеИмяНачальногоТипаВыбора - Строка - полное имя метаданного
Функция ОткрытьПодборСВыборомТипаЛкс(ВладелецФормы, ОписаниеТипов = Неопределено, Знач НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Истина,
ПриПустомОписанииТиповРазрешатьВсе = Ложь) Экспорт
Если ТипЗнч(ОписаниеТипов) = Тип("Строка") Тогда
ДоступныеОбъекты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОписаниеТипов, ",", Истина);
ИначеЕсли ОписаниеТипов <> Неопределено Тогда
ДоступныеОбъекты = Новый Массив();
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ДоступныеОбъекты.Добавить(ПолучитьПолноеИмяМДТипаЛкс(Тип));
КонецЦикла;
Если ДоступныеОбъекты.Количество() = 0 И ПриПустомОписанииТиповРазрешатьВсе Тогда
ДоступныеОбъекты = Неопределено;
КонецЕсли;
КонецЕсли;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ТипНачальногоЗначенияВыбора = ТипОбъектаБДЛкс(НачальноеЗначениеВыбора);
ПолноеИмяНачальногоТипаВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипНачальногоЗначенияВыбора);
КонецЕсли;
Если Ложь
Или ДоступныеОбъекты = Неопределено
Или ДоступныеОбъекты.Количество() = 0
Или ДоступныеОбъекты.Количество() > 1
Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ПолноеИмяНачальногоТипаВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Результат = Форма.ОткрытьМодально();
Если Результат = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = Результат.ПолноеИмяОбъекта;
Иначе
ПолноеИмяМД = ДоступныеОбъекты[0];
КонецЕсли;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Возврат Неопределено;
КонецЕсли;
Если ПолноеИмяНачальногоТипаВыбора <> ПолноеИмяМД Тогда
НачальноеЗначениеВыбора = Неопределено;
КонецЕсли;
ТекущаяСтрока = Неопределено;
Отбор = Неопределено;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ИмяXMLТипа = СериализаторXDTO.XMLТип(ТипНачальногоЗначенияВыбора).ИмяТипа;
Если Ложь
Или Найти(ИмяXMLТипа, "Ref.") > 0
Или Найти(ИмяXMLТипа, "RecordKey.") > 0
Тогда
ТекущаяСтрока = НачальноеЗначениеВыбора;
Иначе
Отбор = НачальноеЗначениеВыбора.Методы.Отбор;
КонецЕсли;
КонецЕсли;
ФормаВыбора = ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, Истина, Истина, ТекущаяСтрока);
Возврат ФормаВыбора;
КонецФункции
Функция ПолучитьФормуВыбораОбъектаМетаданныхЛкс(ВладелецФормы, КлючУникальности, НачальноеЗначениеВыбора, МножественныйВыбор = Ложь, ОтображатьСсылочныеОбъекты = Ложь,
ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь,
ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь, ТолькоИспользованиеПолнотекстовогоПоиска = Ложь) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы, КлючУникальности);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", ОтображатьКонстанты);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", ОтображатьВыборочныеТаблицы);
лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", ОтображатьТаблицыИзменений);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", ОтображатьТабличныеЧасти);
лСтруктураПараметров.Вставить("ОтображатьРегистры", ОтображатьРегистры);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ОтображатьПоследовательности);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", ОтображатьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ОтображатьВнешниеИсточникиДанных);
лСтруктураПараметров.Вставить("МножественныйВыбор", МножественныйВыбор);
лСтруктураПараметров.Вставить("ЗапретитьВыбиратьСсылочныеОбъекты", ЗапретитьВыбиратьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("ТолькоИспользованиеПолнотекстовогоПоиска", ТолькоИспользованиеПолнотекстовогоПоиска);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Возврат Форма;
КонецФункции
Функция ПолучитьФормуВыбораТаблицыСтруктурыБДЛкс(ЛиИменаБД, ИмяТаблицыХранения = "") Экспорт
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСтруктураХраненияБД.Форма",,, Истина);
Форма.РежимВыбора = Истина;
Форма.ПараметрИмяТаблицыХранения = ИмяТаблицыХранения;
Форма.ПараметрПоказыватьSDBL = Не ЛиИменаБД;
Форма.ПараметрПоказыватьСУБД = ЛиИменаБД;
Возврат Форма
КонецФункции
Функция РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаXMLАлгоритма, ВнешниеПараметры = Неопределено) Экспорт
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма);
Результат = РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры);
Если Результат Тогда
СтрокаXMLАлгоритма = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураАлгоритма);
КонецЕсли;
Возврат Результат;
КонецФункции
// Открыть редактирование текста алгоритма с параметрами в консоли кода
// Парамерты:
// СтруктураАлгоритма - Структура - возвращаемый
// "ТекстАлгоритма" - Строка - текст алгоритма,
// "ВнутренниеПараметры" - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внутренними (значения определяются при редактировании) параметрами алгоритма;
// ВнешниеПараметры* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внешними (значения определяются при каждом выполнении) параметрами алгоритма;
// Методы* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаМетодовПодсказкиЛкс с дополнительными методами доступными в алгоритме;
// Результат - Булево - принял ли изменения пользователь
Функция РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры = Неопределено, Методы = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ВнешниеПараметры = Новый ТаблицаЗначений;
#КонецЕсли
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОбработкаКонсольКода = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКода");
ФормаКонсоли = ОбработкаКонсольКода.ПолучитьФорму();
Если ВнешниеПараметры <> Неопределено Тогда
КопияПараметров = ВнешниеПараметры.Скопировать();
Если КопияПараметров.Колонки.Найти("ТаблицаСтруктурТипов") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("ТаблицаСтруктурТипов");
КонецЕсли;
Если КопияПараметров.Колонки.Найти("Значение") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("Значение");
КонецЕсли;
Если КопияПараметров.Колонки.Найти("Фиксированный") = Неопределено Тогда
КопияПараметров.Колонки.Добавить("Фиксированный");
КонецЕсли;
Для Каждого СтрокаПараметра Из КопияПараметров Цикл
Если Истина
И ТипЗнч(СтрокаПараметра.ТипЗначения) = Тип("ОписаниеТипов")
И СтрокаПараметра.ТаблицаСтруктурТипов = Неопределено
Тогда
СтрокаПараметра.ТаблицаСтруктурТипов = мПлатформа.ПолучитьТаблицуСтруктурТиповИзОписанияТипов(СтрокаПараметра.ТипЗначения);
КонецЕсли;
КонецЦикла;
КопияПараметров.ЗаполнитьЗначения(Истина, "Фиксированный");
ФормаКонсоли.мСписокВнешнихПараметров = КопияПараметров;
КонецЕсли;
Если СтруктураАлгоритма <> Неопределено Тогда
Если СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда
ФормаКонсоли.ПараметрТекст = СтруктураАлгоритма.ТекстАлгоритма;
КонецЕсли;
Если СтруктураАлгоритма.Свойство("ВнутренниеПараметры") Тогда
ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, КопияПараметров, Новый Структура("Вход", Истина));
КонецЕсли;
КонецЕсли;
ФормаКонсоли.мМетоды = Методы;
ФормаКонсоли.мРежимРедактора = Истина;
ФормаКонсоли.ОткрытьМодально();
РезультатФормы = ФормаКонсоли.РезультатФормы;
Результат = РезультатФормы <> Неопределено;
Если Результат Тогда
ВнутренниеПараметры = РезультатФормы.Параметры.Скопировать(Новый Структура("Вход, Выход, Фиксированный", Истина, Ложь, Ложь), "Имя, Значение");
СтруктураАлгоритма = Новый Структура("ТекстАлгоритма, ВнутренниеПараметры", РезультатФормы.Текст, ВнутренниеПараметры);
КонецЕсли;
Возврат Результат;
КонецФункции
// Конструктор таблицы параметров алгоритма
// Результат - ТаблицаЗначений - колонки "Имя, Значение, Вход, Выход, ТипЗначения, Комментарий"
Функция НоваяТаблицаПараметровАлгоритмаЛкс() Экспорт
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Значение");
Результат.Колонки.Добавить("Вход", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("Выход", Новый ОписаниеТипов("Булево"));
Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"));
Результат.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ТаблицаСтруктурТипов");
Возврат Результат;
КонецФункции
// Конструктор таблицы методов контекстной подсказки
// Результат - ТаблицаЗначений - колонки "Имя, ТипЗначения"
Функция НоваяТаблицаМетодовПодсказкиЛкс() Экспорт
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"));
Результат.Колонки.Добавить("ТаблицаСтруктурТипов");
Возврат Результат;
КонецФункции
Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П0 = null, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null) Экспорт
СтрокаСобытия = ТаблицаСобытий.Найти(ИмяСобытия, "ИмяСобытия");
СтрокаXMLАлгоритма = СтрокаСобытия.Алгоритм;
Если Не ЗначениеЗаполнено(СтрокаXMLАлгоритма) Тогда
Возврат Истина;
КонецЕсли;
Если ТаблицаСобытий.Колонки.Найти("АлгоритмОбъект") = Неопределено Тогда
ТаблицаСобытий.Колонки.Добавить("АлгоритмОбъект");
КонецЕсли;
АлгоритмОбъект = СтрокаСобытия.АлгоритмОбъект;
Если АлгоритмОбъект = Неопределено Тогда
Попытка
АлгоритмОбъект = ДесериализоватьАлгоритмОбъектЛкс(СтрокаXMLАлгоритма);
Исключение
ВызватьИсключение "Ошибка десериализации алгоритма для события " + ИмяСобытия + ": " + ОписаниеОшибки();
КонецПопытки;
АлгоритмОбъект.Наименование = ИмяСобытия;
ЗагрузитьВТаблицуЗначенийЛкс(СтрокаСобытия.Параметры, АлгоритмОбъект.Параметры);
СтрокаСобытия.АлгоритмОбъект = АлгоритмОбъект;
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Попытка
Результат = мПлатформа.ВыполнитьМетодАлгоритма(АлгоритмОбъект, 0, П0, П1, П2, П3, П4, П5, П6, П7);
Исключение
//выхОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки());
выхОписаниеОшибки = ОписаниеОшибки();
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Функция СтрокаСобытияАлгоритмНачалоВыбораЛкс(Знач СтрокаСобытия) Экспорт
АлгоритмИзменен = РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаСобытия.Алгоритм, СтрокаСобытия.Параметры);
Если СтрокаСобытия.Параметры.Колонки.Найти("Значение") <> Неопределено Тогда
СтрокаСобытия.Параметры.ЗаполнитьЗначения(, "Значение");
КонецЕсли;
Если АлгоритмИзменен Тогда
Если СтрокаСобытия.Владелец().Колонки.Найти("АлгоритмОбъект") <> Неопределено Тогда
СтрокаСобытия.АлгоритмОбъект = Неопределено
КонецЕсли;
КонецЕсли;
Возврат АлгоритмИзменен;
КонецФункции
Функция ДесериализоватьАлгоритмОбъектЛкс(Знач СтрокаXMLАлгоритма) Экспорт
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма);
АлгоритмОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторАлгоритмОбъект");
#Если Сервер И Не Сервер Тогда
АлгоритмОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать();
#КонецЕсли
АлгоритмОбъект.ТекстАлгоритма = СтруктураАлгоритма.ТекстАлгоритма;
ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, АлгоритмОбъект.Параметры, Новый Структура("Вход", Истина));
Возврат АлгоритмОбъект;
КонецФункции
Процедура ОформитьЯчейкуАлгоритмаВТабличномПолеЛкс(Знач ОформлениеСтроки, ИмяКолонки = "Алгоритм") Экспорт
Если ЗначениеЗаполнено(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки]) Тогда
СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки],,, Ложь);
Если СтруктураАлгоритма <> Неопределено И СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда
ОформлениеСтроки.Ячейки[ИмяКолонки].УстановитьТекст(СокрП(СтруктураАлгоритма.ТекстАлгоритма));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// ИсторияФайлов - СписокЗначений
// Кнопки - КнопкиКоманднойПанели
Процедура ОбновитьПодменюИсторииФайловЛкс(ИсторияФайлов, Кнопки, ИмяДействия = "ОткрытьФайлИзИстории") Экспорт
Кнопки.Очистить();
ДлинаПредставления = 100;
ДействиеКнопки = Новый Действие(ИмяДействия);
Для Каждого СтрокаФайла Из ИсторияФайлов Цикл
Файл = Новый Файл(СтрокаФайла.Значение);
ДлинаПути = ДлинаПредставления - СтрДлина(Файл.Имя);
Представление = Лев(Файл.Имя, ДлинаПредставления);
Если ДлинаПути > 0 Тогда
Если ДлинаПути < СтрДлина(Файл.Путь) + 3 Тогда
Представление = Лев(Файл.Путь, ДлинаПути) + "...\" + Представление;
Иначе
Представление = Файл.Путь + Представление;
КонецЕсли;
КонецЕсли;
КнопкаФайла = Кнопки.Добавить("_" + Формат(ИсторияФайлов.Индекс(СтрокаФайла), "ЧГ=;ЧН="), ТипКнопкиКоманднойПанели.Действие, Представление, ДействиеКнопки);
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьВИсториюЭлементЛкс(СписокИстории, ЗначениеЭлемента, РазмерИстории = 20) Экспорт
ЭлементИстории = СписокИстории.НайтиПоЗначению(ЗначениеЭлемента);
Если ЭлементИстории <> Неопределено Тогда
СписокИстории.Удалить(ЭлементИстории);
КонецЕсли;
СписокИстории.Вставить(0, ЗначениеЭлемента);
Пока СписокИстории.Количество() > РазмерИстории Цикл
СписокИстории.Удалить(РазмерИстории);
КонецЦикла;
КонецПроцедуры
Процедура ПоместитьТекстВБуферОбменаОСЛкс(Текст) Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов
//Документ = Новый COMОбъект("HTMLFILE");
Окно = Документ.parentWindow;
Окно.ClipboardData.SetData("Text", Текст);
Конецпроцедуры
Функция ПолучитьТекстИзБуфераОбменаОСЛкс() Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов
//Документ = Новый COMОбъект("HTMLFILE");
Окно = Документ.parentWindow;
Результат = Окно.ClipboardData.GetData("Text");
Возврат Результат;
КонецФункции
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь,
МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, Модально = Ложь, ПользовательскийОтбор = Неопределено) Экспорт
ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор);
Если ФормаСписка = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Модально Тогда
Если ФормаСписка.Открыта() Тогда
ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор,
Новый УникальныйИдентификатор);
КонецЕсли;
Результат = ФормаСписка.ОткрытьМодально();
Возврат Результат;
Иначе
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецЕсли;
КонецФункции
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь,
МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, ПользовательскийОтбор = Неопределено, КлючУникальности = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
Если ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("ОбъектМетаданных") Тогда
ИмяТаблицы = ИмяТаблицыИлиМДИлиТип.ПолноеИмя();
ИначеЕсли ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("Тип") Тогда
ИмяТаблицы = ПолучитьПолноеИмяМДТипаЛкс(ИмяТаблицыИлиМДИлиТип);
Иначе
ИмяТаблицы = ИмяТаблицыИлиМДИлиТип;
КонецЕсли;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы);
//МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Если Ложь
Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы)
Или ТипТаблицы = "Изменения"
Или ТипТаблицы = "Перерасчет"
//Или ТипТаблицы = "Внешняя"
//Или МассивФрагментов.Количество() > 2
Тогда
Сообщить("Для таблицы " + ИмяТаблицы + " форма списка не предусмотрена");
Возврат Неопределено;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
ИспользоватьДинамическийСписокИР = ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ИмяТаблицы);
КонецЕсли;
Если Истина
И РежимВыбора = Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
Тогда
ИспользоватьДинамическийСписокИР = Истина; // Потому что у форм списков регистров режим выбора можно включить только через основной элемент управления
КонецЕсли;
Если ТипТаблицы = "Точки" Тогда
ИспользоватьДинамическийСписокИР = Истина;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
Ответ = Вопрос("Хотите использовать Динамический список (ИР)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
ИспользоватьДинамическийСписокИР = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ПользовательскийОтбор <> Неопределено Тогда
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
ПользовательскийОтборКомпоновки = ПользовательскиеНастройки.Элементы.Добавить(Тип("ОтборКомпоновкиДанных"));
ПользовательскийОтборКомпоновки.ИдентификаторПользовательскойНастройки = Новый УникальныйИдентификатор("dfcece9d-5077-440b-b6b3-45a5cb4538eb"); // Идентификатор установлен экспериментально
Если ТипЗнч(ПользовательскийОтбор) = Тип("Отбор") Тогда
Для Каждого ЭлементОтбора Из ПользовательскийОтбор Цикл
Если ЭлементОтбора.Использование Тогда
СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель");
Если СтрокаВидаСравнения = Неопределено Тогда
// %%%% Здесь можно добавить интеллекта
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ПользовательскийОтборКомпоновки, ЭлементОтбора.Имя, ЭлементОтбора.Значение, СтрокаВидаСравнения.Компоновка);
КонецЕсли;
КонецЦикла;
Иначе
СкопироватьОтборЛюбойЛкс(ПользовательскийОтборКомпоновки, ПользовательскийОтбор);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
СтруктураОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из Отбор Цикл
Если ЭлементОтбора.Использование Тогда
Если ЭлементОтбора.ВидСравнения = ВидСравнения.Равно Тогда
СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
СтруктураОтбора = Отбор;
КонецЕсли;
ПараметрыФормы = Новый Структура("РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока, Отбор, ПользовательскиеНастройки",
РежимВыбора, МножественныйВыбор, Не МножественныйВыбор, ТекущаяСтрока, СтруктураОтбора, ПользовательскиеНастройки);
Если Истина
И ИспользоватьДинамическийСписокИР
И ТипТаблицы <> "Внешняя"
Тогда
КлючУникальности = ИмяТаблицы + ";" + КлючУникальности;
ПараметрыФормы.Вставить("ИмяТаблицы", ИмяТаблицы);
//Если Не РежимВыбора Тогда
// КлючУникальности = Новый УникальныйИдентификатор;
//КонецЕсли;
ФормаСписка = ПолучитьФормуЛкс("Обработка.ирДинамическийСписок.Форма", ПараметрыФормы, ВладелецФормы, КлючУникальности);
ФормаСписка.РежимВыбора = РежимВыбора; // Чтобы заголовок сразу правильный сформировался
ФормаСписка.УстановитьОбъектМетаданных(ИмяТаблицы);
ОтборДинамическогоСписка = ФормаСписка.Отбор();
ПользовательскийОтборДинамическогоСписка = ФормаСписка.ПользовательскийОтбор();
Иначе
Если РежимВыбора Тогда
Попытка
ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаВыбора", ПараметрыФормы, ВладелецФормы, КлючУникальности);
Исключение
// Например у регистров нет форм выбора
КонецПопытки;
КонецЕсли;
Если ФормаСписка = Неопределено Тогда
ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаСписка", ПараметрыФормы, ВладелецФормы, КлючУникальности);
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
Попытка
ОтборДинамическогоСписка = ФормаСписка.Отбор;
Исключение
КонецПопытки;
ПользовательскийОтборДинамическогоСписка = ОтборДинамическогоСписка;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
ФормаСписка.РежимВыбора = РежимВыбора;
ФормаСписка.ЗакрыватьПриВыборе = Не МножественныйВыбор;
ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока;
Попытка
ФормаСписка.МножественныйВыбор = МножественныйВыбор;
Исключение
// Есть не у всех форм
КонецПопытки;
Попытка
ФормаСписка.ПараметрТекущаяСтрока = ТекущаяСтрока;
Исключение
// Есть не у всех форм
КонецПопытки;
КонецЕсли;
Если Истина
И ОтборДинамическогоСписка <> Неопределено
И Отбор <> Неопределено
Тогда
СкопироватьОтборЛюбойЛкс(ОтборДинамическогоСписка, Отбор);
КонецЕсли;
Если Истина
И ПользовательскийОтборДинамическогоСписка <> Неопределено
И ПользовательскийОтбор <> Неопределено
Тогда
СкопироватьОтборЛюбойЛкс(ПользовательскийОтборДинамическогоСписка, ПользовательскийОтбор);
КонецЕсли;
Возврат ФормаСписка;
КонецФункции
Процедура ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = Элемент.Значение;
Если Не ВыборФайла.Выбрать() Тогда
Возврат;
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, ВыборФайла.Каталог);
КонецПроцедуры
Функция ОткрытьСсылкуВСпискеЛкс(Ссылка) Экспорт
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя();
СтруктураПараметры = Новый Структура;
СтруктураПараметры.Вставить("ТекущаяСтрока", Ссылка);
ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор);
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецФункции
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПоле_ОтобразитьФлажкиЛкс(ОформлениеСтроки, Знач ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки];
//Если Ячейка.ТолькоПросмотр Тогда
// Продолжить;
//КонецЕсли;
Если ТипЗнч(Ячейка.Значение) = Тип("Булево") Тогда
Ячейка.УстановитьФлажок(Ячейка.Значение);
Ячейка.УстановитьТекст("");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПоле__ПриИзмененииФлажкаЛкс(Элемент, Знач Колонка) Экспорт
Если ТипЗнч(Колонка.ЭлементУправления) = Тип("ПолеВвода") Тогда
ОформлениеСтроки = Элемент.ОформлениеСтроки(Элемент.ТекущаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
Если Не Ячейка.ТолькоПросмотр Тогда
Если Истина
И Колонка.Данные = ""
И Колонка.ДанныеФлажка = ""
Тогда
Колонка.ЭлементУправления.Значение = Не Ячейка.Значение;
//ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение);
Иначе
//МетаданныеТипа = глПолучитьМетаданныеТипа(ТипЗнч(Элемент.Значение), "ТипСписка", Истина);
//РедактированиеВДиалоге = Ложь;
//Если Истина
// И МетаданныеТипа <> Неопределено
// И МетаданныеТипа.КлассМетаданных.Предок = оСсылочный
//Тогда
// Попытка
// ВыбранныйСпособРедактирования = Элемент.СпособРедактирования;
// Исключение
// КонецПопытки;
// РедактированиеВДиалоге = ВыбранныйСпособРедактирования <> СпособРедактированияСписка.ВСписке;
//КонецЕсли;
//РазрешитьИзменение = Истина;
//Если РедактированиеВДиалоге Тогда
//Иначе
//Элемент.ЗакончитьРедактированиеСтроки(Ложь);
Элемент.ИзменитьСтроку();
ЗначениеЯчейки = Колонка.ЭлементУправления.Значение;
Если ТипЗнч(ЗначениеЯчейки) = Тип("Булево") Тогда
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ЗначениеЯчейки, , , Ложь);
//Элемент.ТекущаяКолонка = Колонка;
КонецЕсли;
Элемент.ЗакончитьРедактированиеСтроки(Ложь);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПиктограммуТипаЛкс(Тип) Экспорт
ИмяОбщегоТипа = Неопределено;
КлючПоиска = Новый Структура("ИД", ПолучитьИдентификаторТипаЛкс(Тип));
мПлатформа = ирКэш.Получить();
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Иначе
//СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
//ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМД <> Неопределено Тогда
ТекущееИмяТипа = ОбъектМД.ПолноеИмя();
ИмяОбщегоТипа = ПолучитьПервыйФрагментЛкс(ТекущееИмяТипа);
КонецЕсли;
КонецЕсли;
Картинка = Неопределено;
Если ИмяОбщегоТипа <> Неопределено Тогда
ИмяКартинки = "ир" + ПолучитьПервыйФрагментЛкс(ИмяОбщегоТипа);
Попытка
Картинка = ирКэш.КартинкаПоИмениЛкс(ИмяКартинки);
Исключение
ИмяКартинки = ИмяОбщегоТипа;
Попытка
Картинка = БиблиотекаКартинок[ИмяКартинки];
Исключение
КонецПопытки;
КонецПопытки;
КонецЕсли;
Возврат Картинка;
КонецФункции
Функция ПрочитатьДополнительныеПоляСсылающихсяОбъектовЛкс(Знач ТабличноеПоле, Знач КомпоновщикДопПолей, Знач ТаблицаДанных = Неопределено, ИмяПоляСсылки = "Данные") Экспорт
#Если Сервер И Не Сервер Тогда
КомпоновщикДопПолей = Новый КомпоновщикНастроекКомпоновкиДанных;
#КонецЕсли
Если ТаблицаДанных = Неопределено Тогда
ТаблицаДанных = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
КонецЕсли;
КомпоновщикДопПолей.Восстановить(СпособВосстановленияНастроекКомпоновкиДанных.Полное);
МассивДопПолей = Новый Структура();
ДопустимоеЧислоДопПолей = 5;
Счетчик = 1;
СтрокаПорядка = "";
СтрокаВыбора = "";
Для Каждого ПолеПорядка Из КомпоновщикДопПолей.Настройки.Порядок.Элементы Цикл
Если ПолеПорядка.Использование Тогда
ИмяПоля = "" + ПолеПорядка.Поле;
ИмяКолонки = "Реквизит" + Счетчик;
ДоступноеПоле = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(ПолеПорядка.Поле);
Если Счетчик > ДопустимоеЧислоДопПолей Тогда
Сообщить("Дополнительное поле """ + ДоступноеПоле.Заголовок + """ пропущено, т.к. допускается не более " + ДопустимоеЧислоДопПолей + " полей");
Продолжить;
КонецЕсли;
МассивДопПолей.Вставить(ИмяКолонки, ИмяПоля);
КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки];
КолонкаТП.Видимость = Истина;
КолонкаТП.ТекстШапки = ДоступноеПоле.Заголовок;
Если СтрокаПорядка <> "" Тогда
СтрокаПорядка = СтрокаПорядка + ",";
КонецЕсли;
СтрокаПорядка = СтрокаПорядка + ИмяКолонки + " ";
Если ПолеПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
СтрокаПорядка = СтрокаПорядка + "Возр";
Иначе
СтрокаПорядка = СтрокаПорядка + "Убыв";
КонецЕсли;
СтрокаВыбора = СтрокаВыбора + ",
| Т." + ИмяПоля + " КАК " + ИмяКолонки;
Счетчик = Счетчик + 1;
КонецЕсли;
КонецЦикла;
Если Не ЗначениеЗаполнено(СтрокаПорядка) Тогда
СтрокаПорядка = "Дата";
КонецЕсли;
Для Счетчик = Счетчик По ДопустимоеЧислоДопПолей Цикл
ИмяКолонки = "Реквизит" + Счетчик;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТП = ТабличноеПоле.ПодчиненныеЭлементы[ТабличноеПоле.Имя + ИмяКолонки];
Иначе
КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки];
КонецЕсли;
КолонкаТП.Видимость = Ложь;
КонецЦикла;
СтандартныеРеквизиты = Новый Структура;
СтандартныеРеквизиты.Вставить("ПометкаУдаления", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("Проведен", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("ЭтоГруппа", "ЛОЖЬ");
СтандартныеРеквизиты.Вставить("Дата", "ДАТАВРЕМЯ(1,1,1)");
Для Каждого КлючИЗначение Из СтандартныеРеквизиты Цикл
ИмяРеквизита = КлючИЗначение.Ключ;
Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект." + ИмяРеквизита)) = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаВыбора = СтрокаВыбора + ",
| ЕСТЬNULL(Т.Объект." + ИмяРеквизита + ", " + КлючИЗначение.Значение + ") КАК " + ИмяРеквизита;
КонецЦикла;
Если ТипЗнч(ТаблицаДанных) <> Тип("ТаблицаЗначений") Тогда
//КопияТаблицыДанных = ТаблицаДанных.Выгрузить(, ИмяПоляСсылки);
КопияТаблицыДанных = ТаблицаЗначенийИзТабличногоПоляЛкс(ТабличноеПоле);
Иначе
КопияТаблицыДанных = ТаблицаДанных;
КонецЕсли;
КопияТаблицыДанных = ирОбщий.ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КопияТаблицыДанных,, ИмяПоляСсылки);
ОписаниеТиповСсылки = КопияТаблицыДанных.Колонки[ИмяПоляСсылки].ТипЗначения;
ПорцияОбъектов = Новый ТаблицаЗначений;
ПорцияОбъектов.Колонки.Добавить("Объект", ОписаниеТиповСсылки);
ПорцияОбъектов.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число"));
РазмерПорции = 10000;
КоличествоПорций = Цел(ТаблицаДанных.Количество() / РазмерПорции) + 1;
Запрос = Новый Запрос;
ТекстЗапроса = "
|ВЫБРАТЬ Т.* ПОМЕСТИТЬ Т ИЗ &Т КАК Т;
|ВЫБРАТЬ Т.Объект, Т.Индекс" + СтрокаВыбора + "
|ИЗ Т КАК Т";
Запрос.Текст = ТекстЗапроса;
ИндексСтроки = 0;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоПорций, "Чтение дополнительных полей");
ДоступноеПолеОбъект = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект"));
Для СчетчикПорций = 1 По КоличествоПорций Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
ПорцияОбъектов.Очистить();
Для Счетчик = 1 По РазмерПорции Цикл
Если ИндексСтроки = ТаблицаДанных.Количество() Тогда
Прервать;
КонецЕсли;
СтрокаОбъекта = ТаблицаДанных[ИндексСтроки];
ИндексСтроки = ИндексСтроки + 1;
Если Ложь
Или ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]) = Тип("Строка")
Или СтрокаОбъекта[ИмяПоляСсылки] = Неопределено
Или ДоступноеПолеОбъект = Неопределено
Или Не ДоступноеПолеОбъект.ТипЗначения.СодержитТип(ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]))
Тогда
СтрокаОбъекта.ИндексКартинки = 12; // Регистр сведений
Продолжить;
КонецЕсли;
СтрокаПорции = ПорцияОбъектов.Добавить();
СтрокаПорции.Объект = СтрокаОбъекта[ИмяПоляСсылки];
СтрокаПорции.Индекс = ИндексСтроки - 1;
КонецЦикла;
Запрос.УстановитьПараметр("Т", ПорцияОбъектов);
РезультатЗапроса = Запрос.Выполнить();
РеквизитыПорции = РезультатЗапроса.Выгрузить();
Для Каждого СтрокаПорции Из РеквизитыПорции Цикл
СтрокаОбъекта = ТаблицаДанных[СтрокаПорции.Индекс];
СтрокаОбъекта.ИндексКартинки = ирОбщий.ПолучитьИндексКартинкиСсылкиЛкс(СтрокаПорции.Объект, Истина, СтрокаПорции);
ЗаполнитьЗначенияСвойств(СтрокаОбъекта, СтрокаПорции);
КонецЦикла;
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
СтрокаПорядка = "Метаданные," + СтрокаПорядка;
Возврат СтрокаПорядка;
КонецФункции
Процедура ОбновитьДоступныеПоляДляДополнительныхПолейЛкс(Знач ТаблицаДанных, Знач КомпоновщикДопПолей, Знач ТабличноеПолеДоступныхПолей) Экспорт
//Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() = 0 Тогда
Если ТипЗнч(ТаблицаДанных) = Тип("ТаблицаЗначений") Тогда
ПолныеИменаМД = ТаблицаДанных.Скопировать(, "Метаданные");
Иначе
ПолныеИменаМД = ТаблицаДанных.Выгрузить(, "Метаданные");
КонецЕсли;
ПолныеИменаМД.Свернуть("Метаданные");
ПолныеИменаМД = ПолныеИменаМД.ВыгрузитьКолонку(0);
МассивТипов = Новый Массив();
Для Каждого ПолноеИмяМД Из ПолныеИменаМД Цикл
Если ТипЗнч(ПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ПолноеИмяМД = ПолноеИмяМД.ПолноеИмя();
КонецЕсли;
Попытка
Тип = Тип(ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД));
Исключение
Продолжить;
КонецПопытки;
МассивТипов.Добавить(Тип);
КонецЦикла;
Если МассивТипов.Количество() > 0 Тогда
КоллекцияПолей = Новый Массив();
КоллекцияПолей.Добавить(Новый Структура("Имя, ТипЗначения", "Объект", Новый ОписаниеТипов(МассивТипов)));
ТекстЗапроса = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей);
СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса);
Иначе
СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
КонецЕсли;
Если ТипЗнч(ТабличноеПолеДоступныхПолей) = Тип("ТаблицаФормы") Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПолеДоступныхПолей);
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПоместитьВоВременноеХранилище(СхемаКомпоновки), ЭтаФорма.УникальныйИдентификатор);
Иначе
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки);
КонецЕсли;
КомпоновщикДопПолей.Инициализировать(ИсточникДоступныхНастроек);
Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() > 0 Тогда
#Если Клиент И Не Сервер Тогда
ТабличноеПолеДоступныхПолей.Развернуть(КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы[0]);
#КонецЕсли
КонецЕсли;
//КонецЕсли;
КонецПроцедуры
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПоле_ОтобразитьПиктограммыТиповЛкс(ОформлениеСтроки, ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки.Найти(ИмяКолонки);
//:Ячейка=Новый("ОформлениеЯчейки")
Если Ячейка <> Неопределено Тогда
ДанныеКартинки = Ячейка.Значение;
Если ТипЗнч(ДанныеКартинки) = Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
СсылкаКартинка = Неопределено;
ТипЗначения = ТипЗнч(ДанныеКартинки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт
ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
//ТипЗначенияТабличногоПоля = ТипЗнч(ИсточникДействий.Значение);
//ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаИзКонкретногоТипа, ТипЗначенияТабличногоПоля);
Попытка
Количество = ЗначениеЭУ.Количество();
Попытка
Отбор = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Исключение
Попытка
//Коллекция компоновки
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение
Попытка
//Или ИмяОбщегоТипа = "ДеревоЗначений"
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
Исключение
// ДинамическийСписок
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
ИмяСлужебногоПоля = "СлужебноеПоле123213м34";
ТекстЗапроса = "ВЫБРАТЬ Т.*, 0 КАК " + ИмяСлужебногоПоля + " ИЗ " + ПолноеИмяТаблицы + " КАК Т";
СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ЗначениеЭУ);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяСлужебногоПоля);
Запрос = ПолучитьЗапросИзКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки,,,,, Ложь);
#Если Сервер И Не Сервер Тогда
Запрос = Новый Запрос;
#КонецЕсли
Запрос.Текст = СтрЗаменить(Запрос.Текст, "0 КАК " + ИмяСлужебногоПоля, "РАЗРЕШЕННЫЕ КОЛИЧЕСТВО(*) КАК КоличествоСтрок");
Количество = Запрос.Выполнить().Выгрузить()[0][0];
Отбор = НастройкиСписка.Отбор;
КонецПопытки;
КонецПопытки;
КонецПопытки;
Текст = "Количество строк ";
Если Отбор <> Неопределено Тогда
Текст = Текст + "с отбором """ + Отбор + """ ";
КонецЕсли;
Сообщить(Текст + "- " + Формат(Количество, "ЧН=") + "(" + Формат(Количество, "ЧН=; ЧГ=") + ")" + Суффикс);
Результат = Количество;
Возврат Результат;
КонецФункции
// ТипНастроек - Число
Функция НастройкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, ТипНастроек = "Результирующие") Экспорт
Если ТипЗнч(ДинамическийСписок) = Тип("ДинамическийСписок") Тогда
Если ТипНастроек = "Результирующие" Тогда
НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ПолучитьНастройки();
ИначеЕсли ТипНастроек = "Фиксированные" Тогда
НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки;
ИначеЕсли ТипНастроек = "Пользовательские" Тогда
ПользовательскиеНастройки = ДинамическийСписок.КомпоновщикНастроек.ПользовательскиеНастройки;
#Если Сервер И Не Сервер Тогда
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
#КонецЕсли
НастройкиСписка = Новый Структура("Отбор, Порядок, УсловноеОформление");
Для Каждого ЭлементПользовательскихНастроек Из ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ОтборКомпоновкиДанных") Тогда
НастройкиСписка.Отбор = ЭлементПользовательскихНастроек;
ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ПорядокКомпоновкиДанных") Тогда
НастройкиСписка.Порядок = ЭлементПользовательскихНастроек;
ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("УсловноеОформлениеКомпоновкиДанных") Тогда
НастройкиСписка.УсловноеОформление = ЭлементПользовательскихНастроек;
КонецЕсли;
КонецЦикла;
Иначе
НастройкиСписка = ДинамическийСписок;
КонецЕсли;
Иначе
НастройкиСписка = ДинамическийСписок;
КонецЕсли;
Возврат НастройкиСписка;
КонецФункции
// Получает картинку для корневого типа конфигурации.
//
// Параметры:
// пКорневойТип Строка корневой тип конфигурации.
//
// Возвращаемое значение:
// Картинка корневого типа конфигурации.
//
Функция ПолучитьКартинкуКорневогоТипаЛкс(пКорневойТип) Экспорт
Если СтрокиРавныЛкс("Изменения", пКорневойТип) Тогда
Картинка = ирКэш.КартинкаПоИмениЛкс("ирТаблицаИзменений");
КонецЕсли;
Если Картинка = Неопределено Тогда
Картинка = ирКэш.КартинкаПоИмениЛкс("ир" + пКорневойТип);
КонецЕсли;
Если Картинка = Неопределено Тогда
Попытка
Картинка = БиблиотекаКартинок[пКорневойТип];
Исключение
КонецПопытки;
КонецЕсли;
Если Картинка = Неопределено Тогда
Картинка = Новый Картинка();
КонецЕсли;
Возврат Картинка;
КонецФункции // ПолучитьКартинкуКорневогоТипа()
Функция ОткрытьТекущуюСтрокуТабличногоПоляТаблицыБДВРедактореОбъектаБДЛкс(ТабличноеПоле, ПолноеИмяМД = Неопределено, ДоступныеПоляВыбора = Неопределено, Связанный = Ложь,
ФормаРедактора = Неопределено, ОбъектыНаСервере = Неопределено, ДляРегистровСоздатьНаборЗаписей = Истина) Экспорт
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если ТекущаяСтрока = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если ПолноеИмяМД = Неопределено Тогда
ПолноеИмяМД = ДанныеЭлементаФормыЛкс(ТабличноеПоле).ОсновнаяТаблица;
КонецЕсли;
ТекущаяКолонка = ТабличноеПоле.ТекущийЭлемент;
Если ТекущаяКолонка <> Неопределено Тогда
ИмяКолонкиДанных = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле, Истина);
КонецЕсли;
Иначе
Если ПолноеИмяМД = Неопределено Тогда
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя();
КонецЕсли;
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если ТекущаяКолонка <> Неопределено Тогда
ИмяКолонкиДанных = ТекущаяКолонка.Данные;
КонецЕсли;
КонецЕсли;
Если Истина
И ИмяКолонкиДанных <> Неопределено
И (Ложь
Или ДоступныеПоляВыбора = Неопределено
Или ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ИмяКолонкиДанных)) <> Неопределено)
Тогда
ИмяКолонки = ИмяКолонкиДанных;
Иначе
ИмяКолонки = "";
КонецЕсли;
СтруктураКлючаСтроки = Неопределено;
ПолноеИмяТаблицы = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
Если ТабличноеПоле.ТекущиеДанные <> Неопределено Тогда
КлючОбъекта = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТабличноеПоле.ТекущиеДанные, ДляРегистровСоздатьНаборЗаписей, СтруктураКлючаСтроки, ОбъектыНаСервере);
КонецЕсли;
Если КлючОбъекта = Неопределено Тогда
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицы);
Если Ложь
Или ЛиКорневойТипСсылкиЛкс(КорневойТип)
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Тогда
//КлючОбъекта = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Ссылка."));
ТипКлюча = ТипЗнч(ТекущаяСтрока.Ссылка);
КлючОбъекта = Новый (ТипКлюча);
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипКлюча).ПолноеИмя();
Иначе
КлючОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы,,, Ложь, ОбъектыНаСервере);
КонецЕсли;
КонецЕсли;
Если ФормаРедактора = Неопределено Тогда
КлючУникальности = ТекущаяСтрока;
Если Связанный Тогда
КлючУникальности = "Связанный";
КонецЕсли;
ФормаРедактора = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", , , КлючУникальности);
КонецЕсли;
Если Не ФормаРедактора.Открыта() Тогда
ПараметрыФормы = Новый Структура("ПараметрКлючИлиОбъект, ПараметрПрочитатьОбъект", КлючОбъекта, Истина);
ЗаполнитьЗначенияСвойств(ФормаРедактора.фОбъект, ПараметрыФормы);
Иначе
ФормаРедактора.ЗагрузитьОбъектПоКлючу(КлючОбъекта);
КонецЕсли;
ФормаРедактора.Открыть();
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ПолноеИмяТаблицы, ИмяКолонки, СтруктураКлючаСтроки);
Возврат ФормаРедактора;
КонецФункции
// Если в текущей строке не достаточно полей для заполнения ключа записи регистра, то всегда возвращается набор записей, не смотря на параметр ДляРегистровСоздатьНаборЗаписей.
Функция КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, Знач ТекущаяСтрока, ДляРегистровСоздатьНаборЗаписей = Ложь, выхСтруктураКлючаСтроки = Неопределено,
ОбъектыНаСервере = Неопределено) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,,, ДляРегистровСоздатьНаборЗаписей);
#Если Сервер И Не Сервер Тогда
СтруктураКлюча = Новый Структура;
#КонецЕсли
Если СтруктураКлюча.Свойство("НомерСтроки") Тогда
выхСтруктураКлючаСтроки = Новый Структура("НомерСтроки");
ИначеЕсли СтруктураКлюча.Свойство("Период") Тогда
выхСтруктураКлючаСтроки = Новый Структура("Период");
Иначе
выхСтруктураКлючаСтроки = Неопределено;
КонецЕсли;
Если выхСтруктураКлючаСтроки <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(выхСтруктураКлючаСтроки, ТекущаяСтрока);
КонецЕсли;
Если Ложь
Или ЛиКорневойТипСсылкиЛкс(ТипТаблицы)
Или ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы)
Тогда
Если ирОбщий.ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущаяСтрока), Ложь) Тогда
КлючОбъекта = ТекущаяСтрока;
Иначе
КлючОбъекта = ТекущаяСтрока.Ссылка;
КонецЕсли;
ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(КлючОбъекта)).ПолноеИмя();
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
КлючОбъекта = ТекущаяСтрока.Ссылка;
ИначеЕсли Ложь
Или ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
//Или ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы)
Тогда
Если Не ДляРегистровСоздатьНаборЗаписей Тогда
НайденыВсеПоляКлючаЗаписи = Истина;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Попытка
Пустышка = ТекущаяСтрока[КлючИЗначение.Ключ];
Исключение
НайденыВсеПоляКлючаЗаписи = Ложь;
Прервать;
КонецПопытки;
КонецЦикла;
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
Если Ложь
Или ДляРегистровСоздатьНаборЗаписей
Или Не НайденыВсеПоляКлючаЗаписи
Тогда
//КлючОбъекта = ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицы, ТекущаяСтрока);
УдаляемыеКлючи = Новый Массив;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Если ТипЗнч(КлючИЗначение.Значение) = Тип("ОписаниеТипов") Тогда
УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ);
КонецЕсли;
КонецЦикла;
Для Каждого УдаляемыйКлюч Из УдаляемыеКлючи Цикл
СтруктураКлюча.Удалить(УдаляемыйКлюч);
КонецЦикла;
КлючОбъекта = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча,, Ложь, ОбъектыНаСервере);
Иначе
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
МенеджерРегистра = Новый (СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "Менеджер."));
КлючОбъекта = МенеджерРегистра.СоздатьКлючЗаписи(СтруктураКлюча);
КонецЕсли;
Иначе
КлючОбъекта = Неопределено;
КонецЕсли;
Возврат КлючОбъекта;
КонецФункции
Функция _КонтрольРазмераВыборкиПользователемЛкс(ЗапросИлиПостроитель, МаксимальноеЧислоСтрок = 500000) Экспорт
КоличествоСтрокРезультата = ирКэш.Получить().ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(ЗапросИлиПостроитель);
Если Истина
И ТипЗнч(КоличествоСтрокРезультата) = Тип("Число")
И КоличествоСтрокРезультата > МаксимальноеЧислоСтрок
Тогда
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Все", "Все");
Кнопки.Добавить("Часть", "Первые " + Формат(МаксимальноеЧислоСтрок, "ЧГ="));
Ответ = Вопрос("Загружаемая таблица содержит " + КоличествоСтрокРезультата + " строк. Сколько строк загружать?", Кнопки, , "Часть");
//Если Ответ <> КодВозвратаДиалога.ОК Тогда
// Возврат;
//КонецЕсли;
Если Ответ = "Все" Тогда
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Иначе
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Возврат МаксимальноеЧислоСтрок;
КонецФункции
// Параметры:
// ИмяКлючевойКолонки - Строка - содержит имя таблицы
//
Функция ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь) Экспорт
МассивКлючей = Новый Массив;
Если ДеревоМетаданных <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
Для Каждого СтрокаДерева1 Из ДеревоМетаданных.Строки Цикл
Для Каждого СтрокаДерева2 Из СтрокаДерева1.Строки Цикл
КорневойТип = ПолучитьПервыйФрагментЛкс(СтрокаДерева2[ИмяКлючевойКолонки]);
Если Ложь
Или КорневойТип = "ВнешнийИсточникДанных"
Или КорневойТип = "РегламентноеЗадание"
Или КорневойТип = "ОбщаяФорма"
Или КорневойТип = "Интерфейс"
Или КорневойТип = "Отчет"
Или КорневойТип = "Обработка"
Тогда
Продолжить;
КонецЕсли;
ИмяТаблицы = СтрокаДерева2[ИмяКлючевойКолонки];
Если ИмяТаблицы = Неопределено Тогда
Продолжить;
КонецЕсли;
Если НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивКлючей.Добавить(ИмяТаблицы);
Для Каждого СтрокаДерева3 Из СтрокаДерева2.Строки Цикл
МассивКлючей.Добавить(СтрокаДерева3[ИмяКлючевойКолонки]);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КлючамиЗаданыИменаТаблиц = Ложь;
Иначе
ЛокальныеТаблицы = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Скопировать(Новый Структура("Схема", ""), "ПолноеИмя, Тип");
НачальноеКоличество = ЛокальныеТаблицы.Количество();
Для СчетчикЛокальныеТаблицы = 1 По НачальноеКоличество Цикл
ОписаниеТаблицы = ЛокальныеТаблицы[НачальноеКоличество - СчетчикЛокальныеТаблицы];
Если ОписаниеТаблицы.Тип = "ВиртуальнаяТаблица" Тогда
ЛокальныеТаблицы.Удалить(ОписаниеТаблицы);
КонецЕсли;
КонецЦикла;
МассивКлючей = ЛокальныеТаблицы.ВыгрузитьКолонку("ПолноеИмя");
КлючамиЗаданыИменаТаблиц = Истина;
КонецЕсли;
ТекстПакета = "";
ТекстЗапроса = "";
СчетчикТаблиц = 0;
Для Каждого ПолноеИмяМД Из МассивКлючей Цикл
ТекстЧастиОбъединения = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные,
КлючамиЗаданыИменаТаблиц);
Если ТекстЧастиОбъединения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "
|ОБЪЕДИНИТЬ ВСЕ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ТекстЧастиОбъединения;
СчетчикТаблиц = СчетчикТаблиц + 1;
Если СчетчикТаблиц = 255 Тогда
СчетчикТаблиц = 0;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
ТекстЗапроса = "";
КонецЕсли;
КонецЦикла;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
Если ЗначениеЗаполнено(ТекстПакета) Тогда
Запрос = Новый Запрос;
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
Запрос.Текст = ТекстПакета;
Состояние("Сбор статистики таблиц...");
РезультатПакета = Запрос.ВыполнитьПакет();
Состояние("");
Результат = Новый Массив();
Для Каждого РезультатЗапроса Из РезультатПакета Цикл
Результат.Добавить(РезультатЗапроса.Выгрузить());
КонецЦикла;
Иначе
Результат = Новый Массив();
КонецЕсли;
Если СтруктураОтбора = Неопределено Тогда
СписокТаблиц = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
Для Каждого ТаблицаРезультата Из Результат Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
ОписаниеТаблицы = СписокТаблиц.Найти(НРег(СтрокаРезультата.ИмяТаблицы), "НПолноеИмя");
ОписаниеТаблицы.КоличествоСтрок = СтрокаРезультата[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьКоличествоИзмененийПоУзлуЛкс(Узел, МассивМетаданных = Неопределено) Экспорт
#Если Клиент Тогда
Состояние("Вычисление количества изменений на узле...");
#КонецЕсли
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", Узел);
МетаПланОбмена = Узел.Метаданные();
ТекстЗапроса = "";
Для Каждого ЭлементСОстава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСОстава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(МетаОбъект.ПолноеИмя(), ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ Количество(*) КАК Количество
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел
|";
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
ТаблицаКоличестваИзменений = Запрос.Выполнить().Выгрузить();
КоличествоИзменений = ТаблицаКоличестваИзменений.Итог("Количество");
Иначе
КоличествоИзменений = 0;
КонецЕсли;
#Если Клиент Тогда
Состояние("");
#КонецЕсли
Возврат КоличествоИзменений;
КонецФункции
Процедура ОбновитьСтатистикуПоТаблицеОбъектаМДВРезультатеПакетаЛкс(РезультатПакета, ПолноеИмяМД, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Истина) Экспорт
ТекстЗапроса = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные);
Запрос = Новый Запрос(ТекстЗапроса);
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
СтруктураКлюча = Новый Структура(ИмяКлючевойКолонки);
КолонкиКоличества = Новый Массив();
КолонкиКоличества.Добавить(ИмяКолонкиКоличества);
Если ЛиТаблицыИзменений Тогда
СтруктураКлюча.Вставить("Узел");
КолонкиКоличества.Добавить("КоличествоВыгруженных");
КолонкиКоличества.Добавить("КоличествоНевыгруженных");
КонецЕсли;
СтатистикаПоТаблице = Запрос.Выполнить().Выгрузить();
СтатистикаПоТаблице.Колонки.Добавить("Найдена", Новый ОписаниеТипов("булево"));
Для Каждого ЭлементПакета Из РезультатПакета Цикл
СтрокиРезультата = ЭлементПакета.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ПолноеИмяМД));
Если СтрокиРезультата.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из СтрокиРезультата Цикл
ЗаполнитьЗначенияСвойств(СтруктураКлюча, СтрокаРезультата);
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = 0;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(СтруктураКлюча) Цикл
СтрокаСтатистики.Найдена = Истина;
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = СтрокаСтатистики[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(Новый Структура("Найдена", Ложь)) Цикл
СтрокаРезультата = ЭлементПакета.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаСтатистики);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМДИлиТаблицы, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь, ЭтоПолноеИмяТаблицы = Ложь) Экспорт
ТекстЧастиОбъединения = "
|ВЫБРАТЬ";
Если Не ЭтоПолноеИмяТаблицы Тогда
ИмяТаблицы = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМДИлиТаблицы, ЛиТаблицыИзменений, Ложь, ТолькоРазрешенные);
Если ИмяТаблицы = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| """ + ПолноеИмяМДИлиТаблицы + """ КАК " + ИмяКлючевойКолонки + ",";
Иначе
ИмяТаблицы = ПолноеИмяМДИлиТаблицы;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| """ + ИмяТаблицы + """ КАК ИмяТаблицы,
| Количество(*) КАК " + ИмяКолонкиКоличества + ",";
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| Узел,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоНевыгруженных,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 0 ИНАЧЕ 1 КОНЕЦ) КАК КоличествоВыгруженных,";
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| 1
|ИЗ " + ИмяТаблицы + " КАК Т
|ГДЕ 1 = 1";
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
Если ирОбщий.СтрокиРавныЛкс("_ТипУзла_", КлючИЗначение.Ключ) Тогда
ОпределениеПоля = "ТИПЗНАЧЕНИЯ(Т.Узел)";
Иначе
ОпределениеПоля = "Т." + КлючИЗначение.Ключ;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| И " + ОпределениеПоля + " В (&" + КлючИЗначение.Ключ + ")";
КонецЦикла;
КонецЕсли;
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
|СГРУППИРОВАТЬ ПО Узел";
КонецЕсли;
Возврат ТекстЧастиОбъединения;
КонецФункции
Процедура ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта",
СуммируемыеКолонки = "КоличествоСтрок", СтруктураОтбора = Неопределено, КлючеваяКолонкаСодержитИмяТаблицы = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
ВсеСтрокиДерева = ПолучитьВсеСтрокиДереваЗначенийЛкс(ДеревоМетаданных);
СтруктураСуммируемыхКолонок = Новый Структура(СуммируемыеКолонки);
МассивСуммируемыхКолонок = Новый Массив();
Для Каждого КлючИЗначение Из СтруктураСуммируемыхКолонок Цикл
МассивСуммируемыхКолонок.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
Для Каждого ИмяСуммируемойКолонки Из МассивСуммируемыхКолонок Цикл
СтрокаДерева[ИмяСуммируемойКолонки] = Неопределено;
КонецЦикла;
КонецЦикла;
Если РезультатПакета = Неопределено Тогда
ТаблицаКоличества = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
Если КлючеваяКолонкаСодержитИмяТаблицы Тогда
ИмяКлючевойКолонкиИсточника = "ПолноеИмя";
Иначе
ИмяКлючевойКолонкиИсточника = "ПолноеИмяМД";
КонецЕсли;
Иначе
ИмяКлючевойКолонкиИсточника = ИмяКлючевойКолонки;
Для Каждого ТаблицаРезультата Из РезультатПакета Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
Если ТаблицаКоличества = Неопределено Тогда
ТаблицаКоличества = ТаблицаРезультата.СкопироватьКолонки();
ТаблицаКоличества.Колонки.Удалить(ИмяКлючевойКолонкиИсточника);
ТаблицаКоличества.Колонки.Добавить(ИмяКлючевойКолонкиИсточника); // Чтобы убрать ограничение на длину строки, которое может быть разным в результатах запросов пакета
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
ПодходитФильтру = Истина;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ЗначениеРезультата = СтрокаРезультата[КлючИЗначение.Ключ];
Если ТипЗнч(КлючИЗначение.Значение) = Тип("Массив") Тогда
Если КлючИЗначение.Значение.Найти(ЗначениеРезультата) = Неопределено Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
Иначе
Если КлючИЗначение.Значение <> ЗначениеРезультата Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ПодходитФильтру Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
ЗаполнитьЗначенияСвойств(ТаблицаКоличества.Добавить(), СтрокаРезультата);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Если ТаблицаКоличества <> Неопределено Тогда
Для Каждого СтрокаКоличества Из ТаблицаКоличества Цикл
Если СтрокаКоличества[ИмяСуммируемойКолонки] = Неопределено Тогда
Продолжить;
КонецЕсли;
СтрокаДерева = ДеревоМетаданных.Строки.Найти(СтрокаКоличества[ИмяКлючевойКолонкиИсточника], ИмяКлючевойКолонки, Истина);
Если СтрокаДерева <> Неопределено Тогда
Для Каждого ИмяСуммируемойКолонки Из МассивСуммируемыхКолонок Цикл
ДобавитьКоличествоСтрокРодителюЛкс(СтрокаДерева, СтрокаКоличества[ИмяСуммируемойКолонки], ИмяСуммируемойКолонки);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьКоличествоСтрокРодителюЛкс(Знач СтрокаДерева, Знач ДобавкаККоличеству, Знач ИмяСуммируемойКолонки= "КоличествоСтрок") Экспорт
СтароеКоличество = СтрокаДерева[ИмяСуммируемойКолонки];
Если СтароеКоличество = Неопределено Тогда
СтароеКоличество = 0;
КонецЕсли;
НовоеКоличество = ?(СтрокаДерева[ИмяСуммируемойКолонки] = Неопределено, 0, СтрокаДерева[ИмяСуммируемойКолонки]) + ДобавкаККоличеству;
СтрокаДерева[ИмяСуммируемойКолонки] = НовоеКоличество;
Если СтрокаДерева.Уровень() > 1 Тогда
Возврат;
КонецЕсли;
Родитель = СтрокаДерева.Родитель;
Пока Родитель <> Неопределено Цикл
Если ТипЗнч(НовоеКоличество) <> Тип("Число") Тогда
Родитель[ИмяСуммируемойКолонки] = "?";
КонецЕсли;
КоличествоРодителя = Родитель[ИмяСуммируемойКолонки];
Если КоличествоРодителя = "?" Тогда
Прервать;
КонецЕсли;
Если ТипЗнч(КоличествоРодителя) <> Тип("Число") Тогда
КоличествоРодителя = 0;
КонецЕсли;
Родитель[ИмяСуммируемойКолонки] = КоличествоРодителя - СтароеКоличество + НовоеКоличество;
Родитель = Родитель.Родитель;
КонецЦикла;
КонецПроцедуры // ЗаполнитьДеревоИсточников()
Процедура ОбновитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
РезультатПакета = ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора);
ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета, ИмяКлючевойКолонки, ИмяКолонкиКоличества);
КонецПроцедуры
Процедура УстановитьЗначениеКолонкиДереваЛкс(ДеревоЗначений, ИмяКолонки = "Пометка", НовоеЗначение = Истина) Экспорт
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ДеревоЗначений);
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
СтрокаДерева.Пометка = НовоеЗначение;
КонецЦикла;
КонецПроцедуры
// НовыйРежим - Булево - Имя/Синоним
Процедура ТабличноеПоле_ОбновитьКолонкиИмяСинонимЛкс(ТабличноеПоле, НовыйРежим, ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление") Экспорт
КолонкиТП = ТабличноеПоле.Колонки;
КолонкаИмя = КолонкиТП[ИмяКолонкиИмя];
КолонкаСиноним = КолонкиТП[ИмяКолонкиСиноним];
КолонкаИмя.Видимость = НовыйРежим;
КолонкаСиноним.Видимость = Не НовыйРежим;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
КолонкаИмя.ОтображатьИерархию = НовыйРежим;
КолонкаСиноним.ОтображатьИерархию = Не НовыйРежим;
КонецЕсли;
ИндексКолонкиИмя = КолонкиТП.Индекс(КолонкаИмя);
ИндексКолонкиСиноним = КолонкиТП.Индекс(КолонкаСиноним);
Если НовыйРежим = (ИндексКолонкиИмя > ИндексКолонкиСиноним) Тогда
КолонкиТП.Сдвинуть(КолонкаИмя, ИндексКолонкиСиноним - ИндексКолонкиИмя);
КонецЕсли;
Если НовыйРежим Тогда
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Имя;
Иначе
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Представление;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПоле_ОформитьЯчейкиИмяСинонимЛкс(ТабличноеПоле, ОформлениеСтроки,
ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление", ИмяКолонкиИндексКартинки = "ИндексКартинки", ДанныеФлажка = "") Экспорт
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ТабличноеПоле.Колонки[ИмяКолонкиИмя].Видимость Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиИмя];
ВедущийИндекс = ТабличноеПоле.Колонки.Индекс(ВедущаяКолонка);
КонецЕсли;
Если ТабличноеПоле.Колонки[ИмяКолонкиСиноним].Видимость Тогда
Если Ложь
Или ВедущаяКолонка = Неопределено
Или ТабличноеПоле.Колонки.Индекс(ТабличноеПоле.Колонки[ИмяКолонкиСиноним]) < ВедущийИндекс
Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиСиноним];
КонецЕсли;
КонецЕсли;
Если ВедущаяКолонка <> Неопределено Тогда
Ячейка = ОформлениеСтроки.Ячейки[ВедущаяКолонка.Имя];
Если ЗначениеЗаполнено(ИмяКолонкиИндексКартинки) Тогда
ИндексКартинки = ДанныеСтроки[ИмяКолонкиИндексКартинки];
Если ИндексКартинки >= 0 Тогда
Ячейка.ОтображатьКартинку = Истина;
Ячейка.ИндексКартинки = ИндексКартинки;
КонецЕсли;
КонецЕсли;
Если ДанныеФлажка <> "" Тогда
Ячейка.ОтображатьФлажок = Истина;
Ячейка.Флажок = ДанныеСтроки[ДанныеФлажка];
КонецЕсли;
КоличествоДочерних = ДанныеСтроки.Строки.Количество();
Если КоличествоДочерних > 0 Тогда
Ячейка.УстановитьТекст(Ячейка.Текст + " (" + КоличествоДочерних + ")");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева) Экспорт
Если Истина
И ТабличноеПолеДерева.ТекущаяКолонка <> Неопределено
И ЗначениеЗаполнено(ТабличноеПолеДерева.ТекущаяКолонка.Данные)
И ТабличноеПолеДерева.Значение.Колонки[ТабличноеПолеДерева.ТекущаяКолонка.Данные].ТипЗначения.СодержитТип(Тип("Строка"))
Тогда
ТекущаяКолонкаТП = ТабличноеПолеДерева.ТекущаяКолонка;
Иначе
Для Каждого КолонкаТП Из ТабличноеПолеДерева.Колонки Цикл
Если Не КолонкаТП.Видимость Тогда
Продолжить;
КонецЕсли;
КолонкаДерева = ТабличноеПолеДерева.Значение.Колонки[КолонкаТП.Данные];
Если КолонкаДерева.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ТекущаяКолонкаТП = КолонкаТП;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ТекущаяКолонкаТП;
КонецФункции
Функция НайтиСтрокуТабличногоПоляДереваЗначенийСоСложнымФильтромЛкс(ТабличноеПолеДерева, ПолеВводаФильтра, Подстроки = "") Экспорт
ТекущаяКолонкаТП = ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева);
Если ТекущаяКолонкаТП = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ИмяТекущейКолонки = ТекущаяКолонкаТП.Данные;
Если Не ЗначениеЗаполнено(ИмяТекущейКолонки) Тогда
Возврат Неопределено;
КонецЕсли;
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
ТекущаяСтрока = ТабличноеПолеДерева.ТекущаяСтрока;
Если Подстроки = "" Тогда
Подстроки = ПолеВводаФильтра.Значение;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина);
ИндексСтроки = 0;
Если ТекущаяСтрока <> Неопределено Тогда
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ИндексСтроки = ВсеСтроки.Найти(ТекущаяСтрока) + 1;
КонецЕсли;
КонецЕсли;
Успех = Ложь;
Для ИндексСтроки = ИндексСтроки По ВсеСтроки.Количество() - 1 Цикл
ТекущаяСтрока = ВсеСтроки[ИндексСтроки];
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ТабличноеПолеДерева.ТекущаяСтрока = ТекущаяСтрока;
ТабличноеПолеДерева.ТекущаяКолонка = ТекущаяКолонкаТП;
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Успех Тогда
ПолеВводаФильтра.ЦветФонаПоля = Новый Цвет();
Иначе
ТекущаяСтрока = Неопределено;
ПолеВводаФильтра.ЦветФонаПоля = ПолучитьЦветСтиляЛкс("ирЦветФонаОшибки");
КонецЕсли;
Возврат ТекущаяСтрока;
КонецФункции
Процедура ВыделитьСтрокиТабличногоПоляПоКлючуЛкс(ТабличноеПоле, ЗначенияКлюча, Знач СтрокаКлюча = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаКлюча) Тогда
СтрокаКлюча = "";
Для Каждого КолонкаТаблицы Из ТабличноеПоле.Значение.Колонки Цикл
Если СтрокаКлюча <> "" Тогда
СтрокаКлюча = СтрокаКлюча + ",";
КонецЕсли;
СтрокаКлюча = СтрокаКлюча + КолонкаТаблицы.Имя;
КонецЦикла;
КонецЕсли;
КлючПоиска = Новый Структура(СтрокаКлюча);
ЗаполнитьЗначенияСвойств(КлючПоиска, ЗначенияКлюча);
Если ЗначениеЗаполнено(СтрокаКлюча) Тогда
ТабличноеПоле.Значение.Сортировать(СтрокаКлюча);
КонецЕсли;
ТабличноеПоле.ВыделенныеСтроки.Очистить();
ТекущаяСтрокаУстановлена = Ложь;
Для Каждого НеуникальнаяСтрока Из ТабличноеПоле.Значение.НайтиСтроки(КлючПоиска) Цикл
ТабличноеПоле.ВыделенныеСтроки.Добавить(НеуникальнаяСтрока);
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = НеуникальнаяСтрока;
ТекущаяСтрокаУстановлена = Истина;
КонецЕсли;
КонецЦикла;
//ТабличноеПоле.ОбновитьСтроки();
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле, ЧислоПервыхИгнорируемыхСтрок = 0) Экспорт
Счетчик = 0;
Для Каждого Строка Из ТабличноеПоле.Значение.Строки Цикл
Счетчик = Счетчик + 1;
Если Счетчик > ЧислоПервыхИгнорируемыхСтрок Тогда
ТабличноеПоле.Развернуть(Строка, Истина);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_СвернутьВсеСтрокиЛкс(ТабличноеПоле, ВосстановитьТекущуюСтроку = Ложь) Экспорт
МассивТекущихУзлов = Новый Массив;
Если ВосстановитьТекущуюСтроку Тогда
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Пока ТекущаяСтрока <> Неопределено Цикл
МассивТекущихУзлов.Добавить(ТекущаяСтрока);
ТекущаяСтрока = ТекущаяСтрока.Родитель;
КонецЦикла;
КонецЕсли;
ВсеСтрокиДерева = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
Индикатор = ПолучитьИндикаторПроцессаЛкс(ВсеСтрокиДерева.Количество());
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если Истина
И ТабличноеПоле.Развернут(СтрокаДерева)
И СтрокаДерева.Строки.Количество() > 0
И МассивТекущихУзлов.Найти(СтрокаДерева) = Неопределено
Тогда
ТабличноеПоле.Свернуть(СтрокаДерева);
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_АвтоРазвернутьВсеСтрокиЛкс(ТабличноеПоле, МаксимальноеЧислоСтрок = 30, ТекущаяСтрокаУстановлена = Ложь) Экспорт
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
ЧислоДинамическихСтрок = ВсеСтроки.Количество();
Если ЧислоДинамическихСтрок > 0 Тогда
Если ЧислоДинамическихСтрок <= МаксимальноеЧислоСтрок Тогда
ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле);
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0].Строки[0];
КонецЕсли;
Иначе
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0];
Если ТабличноеПоле.Значение.Строки.Количество() = 1 Тогда
ТабличноеПоле.Развернуть(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ПрименитьСтрокуПоискаКТабличномуПолюДереваЛкс(ТабличноеПолеДерева, СтрокаПоиска, ИменаКолонокДанныхДляПоиска, выхСтруктураПоиска, АктивизироватьПервуюСтроку = Истина) Экспорт
СтруктураКолонок = Новый Структура(ИменаКолонокДанныхДляПоиска);
НайденныеСтрокиДерева = Новый Массив();
Если ЗначениеЗаполнено(СтрокаПоиска) Тогда
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
ИндексТекущейСтроки = ВсеСтроки.Найти(ТабличноеПолеДерева.ТекущаяСтрока);
ИндексАктивизируемойСтроки = Неопределено;
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
Для Каждого КлючИЗначение Из СтруктураКолонок Цикл
ИнтереснаяКолонка = КлючИЗначение.Ключ;
Значение = СтрокаДерева[ИнтереснаяКолонка];
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = НРег(Значение);
Если Найти(Значение, НРег(СтрокаПоиска)) > 0 Тогда
НайденныеСтрокиДерева.Добавить(СтрокаДерева);
Если ИндексТекущейСтроки <> Неопределено И ВсеСтроки.Найти(СтрокаДерева) >= ИндексТекущейСтроки И ИндексАктивизируемойСтроки = Неопределено Тогда
ИндексАктивизируемойСтроки = НайденныеСтрокиДерева.Количество() - 1;
КонецЕсли;
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если Не ТабличноеПолеДерева.Развернут(Родитель) Тогда
ТабличноеПолеДерева.Развернуть(Родитель);
КонецЕсли;
Родитель = Родитель.Родитель;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если АктивизироватьПервуюСтроку И НайденныеСтрокиДерева.Количество() > 0 Тогда
Если ИндексАктивизируемойСтроки = Неопределено Тогда
ИндексАктивизируемойСтроки = 0;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = НайденныеСтрокиДерева[ИндексАктивизируемойСтроки];
КонецЕсли;
КонецЕсли;
ТекущийИндексНайденнойСтроки = 0;
выхСтруктураПоиска = Новый Структура("ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева", ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева);
КонецПроцедуры
Процедура СледующееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки + 1;
Если СтруктураПоиска.ТекущийИндексНайденнойСтроки >= СтруктураПоиска.НайденныеСтрокиДерева.Количество() Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = 0;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки];
КонецЕсли;
КонецПроцедуры
Процедура ПредыдущееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки - 1;
Если СтруктураПоиска.ТекущийИндексНайденнойСтроки < 0 Тогда
СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.НайденныеСтрокиДерева.Количество() - 1;
КонецЕсли;
ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки];
КонецЕсли;
КонецПроцедуры
Процедура ОформитьСтрокуВТабличномПолеДереваСПоискомЛкс(ТабличноеПолеДерева, ОформлениеСтроки, ДанныеСтроки, СтруктураПоиска) Экспорт
Если СтруктураПоиска = Неопределено Тогда
Возврат;
КонецЕсли;
Если СтруктураПоиска.НайденныеСтрокиДерева.Найти(ДанныеСтроки) <> Неопределено Тогда
ОформлениеСтроки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
КонецЕсли;
КонецПроцедуры
Функция ДобавитьСсылкуВИзбранноеЛкс(Ссылка, ДобавлятьВИзбранноеРаботыПользователя = Истина, ДобавлятьВИзрабнноеИнтерфейснойПанели = Истина) Экспорт
Если ДобавлятьВИзбранноеРаботыПользователя Тогда
Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя");
Если Избранное = Неопределено Тогда
Избранное = Новый ИзбранноеРаботыПользователя;
КонецЕсли;
ЭлементИзбранного = Новый ЭлементИзбранногоРаботыПользователя;
ЭлементИзбранного.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка);
Избранное.Добавить(ЭлементИзбранного);
ХранилищеСистемныхНастроек.Сохранить("Общее/ИзбранноеРаботыПользователя", "", Избранное);
ОбновитьИнтерфейс();
КонецЕсли;
Если ДобавлятьВИзрабнноеИнтерфейснойПанели Тогда
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", Ссылка.Метаданные().ПолноеИмя());
СтруктураЭлемента.Вставить("Имя", Ссылка);
НоваяСтрока = ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, "Избранное");
Если ФормаИнтерфейснойПанели.Открыта() Тогда
ФормаИнтерфейснойПанели.ЗаполнитьСтатическиеВеткиДереваИнтерфейса(ФормаИнтерфейснойПанели, НоваяСтрока);
Иначе
ФормаИнтерфейснойПанели.СохранитьНастройки(ФормаИнтерфейснойПанели);
КонецЕсли;
КонецЕсли;
КонецФункции
//
Процедура ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ирКэш.Получить().Это2iS Тогда
ДУЛкс("УФ(П1, П2)", "ОткрытьКоллекциюВКонсолиОбработкиДанных", ТабличноеПоле.Значение);
Иначе
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле);
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
Строка = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Строка);
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок);
КонецЕсли;
КонецПроцедуры // ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс()
Процедура ОткрытьОбъектыИзВыделенныхСтрокВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, ПолноеИмяТаблицы = "") Экспорт
ПараметрКоманды = Новый Массив();
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючОбъекта = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ВыделеннаяСтрока);
ПараметрКоманды.Добавить(КлючОбъекта);
КонецЦикла;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ПараметрКоманды);
КонецПроцедуры // ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс()
Функция ОткрытьПодборИОбработкуОбъектовИзТабличногоПоляДинамическогоСпискаЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт
ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПолноеИмяМД = "";
ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, ПолноеИмяМД);
Если ЗначениеЗаполнено(ПолноеИмяМД) Тогда
Ответ = Вопрос("Обработать только выделенные строки (Да) иначе будет использован текущий отбор (Нет)?", РежимДиалогаВопрос.ДаНет);
Иначе
Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
КлючиВыделенныхСтрок = КлючиВыделенныхСтрокДинамическогоСписка(ТабличноеПоле);
Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда
ВыбранныеПоля = Новый Массив;
Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл
Если Не КолонкаТП.Видимость Тогда
Продолжить;
КонецЕсли;
ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле, КолонкаТП);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Продолжить;
КонецЕсли;
ВыбранныеПоля.Добавить(ДанныеКолонки);
КонецЦикла;
КонецЕсли;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(КлючиВыделенныхСтрок, ВыбранныеПоля);
Иначе
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, ПолноеИмяМД);
Форма.Открыть();
Форма.УстановитьОбластьПоиска();
Форма.СтрокаПоиска = "";
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
СкопироватьОтборЛюбойЛкс(Форма.Компоновщик.Настройки.Отбор, НастройкиСписка.Отбор);
СкопироватьПорядокЛюбойЛкс(Форма.Компоновщик.Настройки.Порядок, НастройкиСписка.Порядок);
КонецЕсли;
Возврат Форма;
КонецФункции
Функция КлючиВыделенныхСтрокДинамическогоСписка(Знач ТабличноеПоле, выхКлючВыделеннойСтроки = Неопределено)
ПараметрКоманды = Новый Массив();
Для Каждого Строка Из ТабличноеПоле.ВыделенныеСтроки Цикл
Если ТипЗнч(Строка) = Тип("СтрокаТаблицыЗначений") Тогда
КлючСтроки = Строка.Ссылка;
Иначе
КлючСтроки = Строка;
КонецЕсли;
ПараметрКоманды.Добавить(КлючСтроки);
Если ТабличноеПоле.ТекущаяСтрока = Строка Тогда
выхКлючВыделеннойСтроки = КлючСтроки;
КонецЕсли;
КонецЦикла;
Возврат ПараметрКоманды;
КонецФункции
// Параметры:
// ВыбранныеПоля - Массив, *Неопределено
Функция ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок, ВыбранныеПоля = Неопределено) Экспорт
Если МассивСсылок.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма");
Форма.Открыть();
Форма.ЗагрузитьОбъектыДляОбработки(ПолучитьУникальныеЗначенияМассиваЛкс(МассивСсылок),, ВыбранныеПоля);
Возврат Форма;
КонецФункции // ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс()
Функция ПолучитьУникальныеЗначенияМассиваЛкс(Массив) Экспорт
НовыйМассив = Новый Массив;
Соответствие = Новый Соответствие;
Для Каждого Элемент Из Массив Цикл
Если Соответствие[Элемент] = 1 Тогда
Продолжить;
КонецЕсли;
Соответствие.Вставить(Элемент, 1);
НовыйМассив.Добавить(Элемент);
КонецЦикла;
Возврат НовыйМассив;
КонецФункции
Функция ПолучитьСтруктуруВосстановленияКонсолиЛкс(ИмяИлиОбъектКонсоли) Экспорт
Если ТипЗнч(ИмяИлиОбъектКонсоли) = Тип("Строка") Тогда
ИмяКонсоли = ИмяИлиОбъектКонсоли;
Иначе
ИмяКонсоли = ИмяИлиОбъектКонсоли.Метаданные().Имя;
КонецЕсли;
Структура = Новый Структура();
Структура.Вставить("БлокировкаВосстановления", Неопределено);
ПрефиксИмениФайлаВосстановления = ИмяКонсоли + "_" + ИмяПользователя() + "_";
Структура.Вставить("ПрефиксИмениФайлаВосстановления", ПрефиксИмениФайлаВосстановления);
ИмяФайлаВосстановления = ирКэш.Получить().КаталогФайловогоКэша + "\" + ПрефиксИмениФайлаВосстановления + Новый УникальныйИдентификатор + ".tmp";
Структура.Вставить("ФайлВосстановления", Новый Файл(ИмяФайлаВосстановления));
Возврат Структура;
КонецФункции
Функция СохранитьФайлВКонсолиСВосстановлениемЛкс(ДиалогВыбораФайла, Знач ИмяСохраняемогоФайла, ИмяОткрытогоФайла = "", ДанныеДляФайла, СтруктураВосстановления, ЗапрашиватьИмяФайла = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
ДиалогВыбораФайла = Новый ДиалогВыбораФайла();
#КонецЕсли
ФайлВосстановления = СтруктураВосстановления.ФайлВосстановления;
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
БлокировкаВосстановления = СтруктураВосстановления.БлокировкаВосстановления;
СохранитьФайл = Истина;
Если Не СтрокиРавныЛкс(ИмяСохраняемогоФайла, ФайлВосстановления.ПолноеИмя) Тогда
// Здесь можно вставить проверочную сериализацию+десериализацию
ФайлВыбран = Истина;
лФайл = Новый Файл(ИмяОткрытогоФайла);
ДиалогВыбораФайла.ПолноеИмяФайла = ИмяСохраняемогоФайла;
Если Ложь
Или ПустаяСтрока(ИмяСохраняемогоФайла)
Или ЗапрашиватьИмяФайла
Или Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1
Тогда
Пока Истина Цикл
Если ДиалогВыбораФайла.Выбрать() Тогда
лФайл = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла);
Если Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда
КодОтвета = Вопрос("Это имя файла зарезервировано. Хотите выбрать другое?", РежимДиалогаВопрос.ОКОтмена);
Если КодОтвета = КодВозвратаДиалога.ОК Тогда
Продолжить;
Иначе
ФайлВыбран = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
ИмяСохраняемогоФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
ФайлВыбран = Истина;
Прервать;
Иначе
ФайлВыбран = Ложь;
СохранитьФайл = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
ФайлВыбран = Ложь;
КонецЕсли;
Если СохранитьФайл Тогда
МоментНачала = ТекущаяДата();
Если Истина
И НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя)
И БлокировкаВосстановления <> Неопределено
Тогда
БлокировкаВосстановления = Неопределено;
КонецЕсли;
ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(ДанныеДляФайла);
Если Не ЗначениеВФайл(ИмяСохраняемогоФайла, ДанныеДляФайла) Тогда
Сообщить("Ошибка записи файла """ + ИмяСохраняемогоФайла + """", СтатусСообщения.Внимание);
ФайлВыбран = Ложь;
КонецЕсли;
выхДлительность = ТекущаяДата() - МоментНачала;
Если выхДлительность > 1 Тогда
Сообщить("Автосохранение файла восстановления выполнено за " + выхДлительность + " секунд");
КонецЕсли;
Если НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) Тогда
БлокировкаВосстановления = Новый ЗаписьТекста(ИмяСохраняемогоФайла,,,Истина);
КонецЕсли;
КонецЕсли;
Возврат ФайлВыбран;
КонецФункции
Функция ПроверитьВыбратьФайлВосстановленияКонсолиЛкс(СтруктураВосстановления) Экспорт
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
СписокВосстановления = Новый СписокЗначений;
ФайлыВосстановления = НайтиФайлы(ирКэш.Получить().КаталогФайловогоКэша, ПрефиксИмениФайлаВосстановления + "*.tmp");
Для Каждого ФайлВосстановления Из ФайлыВосстановления Цикл
#Если Сервер И Не Сервер Тогда
ФайлВосстановления = Новый Файл();
#КонецЕсли
Попытка
ФайлВосстановления.УстановитьВремяИзменения(ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс());
//Пустышка = Новый ЗаписьТекста(ФайлВосстановления.ПолноеИмя, , , Истина);
Исключение
// Файла заблокирован и значит сессия продолжается.
Продолжить;
КонецПопытки;
СписокВосстановления.Добавить(ФайлВосстановления.ПолноеИмя, "" + (ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс()) + " - "
+ ФайлВосстановления.ИмяБезРасширения);
КонецЦикла;
ИмяФайлаВосстановления = "";
Если СписокВосстановления.Количество() > 0 Тогда
СписокВосстановления.СортироватьПоПредставлению(НаправлениеСортировки.Убыв);
СписокВосстановления.Добавить("<Удалить все файлы восстановления>");
ВыбранныйЭлемент = СписокВосстановления.ВыбратьЭлемент("Вы можете открыть файл восстановления прерванной сессии");
Если ВыбранныйЭлемент <> Неопределено Тогда
Если ВыбранныйЭлемент.Значение = "<Удалить все файлы восстановления>" Тогда
Для Каждого ЭлементСписка Из СписокВосстановления Цикл
Если ВыбранныйЭлемент = ЭлементСписка Тогда
Продолжить;
КонецЕсли;
УдалитьФайлы(ЭлементСписка.Значение);
КонецЦикла;
Иначе
ИмяФайлаВосстановления = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяФайлаВосстановления;
КонецФункции
Процедура УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(СтруктураВосстановления) Экспорт
СтруктураВосстановления.БлокировкаВосстановления = Неопределено;
Попытка
УдалитьФайлы(СтруктураВосстановления.ФайлВосстановления.ПолноеИмя);
Исключение
КонецПопытки;
КонецПроцедуры
Процедура СчитатьПорциюВыборкиВТаблицуЛкс(Выборка, ТаблицаПриемник, Знач РазмерПорции = 9999, СчитыватьЧерезКопиюТаблицы = Истина,
СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
Пустышка = Новый Запрос;
Выборка = Пустышка.Выполнить();
#КонецЕсли
Если СчитыватьЧерезКопиюТаблицы Тогда
// Иначе добавление и заполнение строк при связи с табличным полем будет дольше выполняться
КопияТаблицыПриемника = ТаблицаПриемник.Скопировать();
Если СсылкаНаБуфернуюТаблицу <> Неопределено Тогда
СсылкаНаБуфернуюТаблицу.Вставить("Таблица", КопияТаблицыПриемника);
КонецЕсли;
Иначе
КопияТаблицыПриемника = ТаблицаПриемник;
КонецЕсли;
КоличествоРезультата = Выборка.Количество();
Несчитано = КоличествоРезультата - КопияТаблицыПриемника.Количество();
Если Ложь
Или РазмерПорции > Несчитано
Или РазмерПорции = 0
Тогда
РазмерПорции = Несчитано;
КонецЕсли;
Если Несчитано = РазмерПорции Тогда
ПредставлениеПроцесса = "Загрузка выборки";
Иначе
ПредставлениеПроцесса = "Загрузка порции выборки";
КонецЕсли;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(РазмерПорции, ПредставлениеПроцесса);
#КонецЕсли
КолонкиВложенныхТаблиц = Новый Массив();
Для Каждого Колонка Из Выборка.Владелец().Колонки Цикл
Если Колонка.ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
КолонкиВложенныхТаблиц.Добавить(Колонка.Имя);
КонецЕсли;
КонецЦикла;
ЕстьКолонкиВложенныхТаблиц = КолонкиВложенныхТаблиц.Количество() > 0;
РазмерПорцииОсталось = РазмерПорции;
Пока Выборка.Следующий() Цикл
НоваяСтрока = КопияТаблицыПриемника.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
Если ЕстьКолонкиВложенныхТаблиц Тогда
Для Каждого КолонкаВложеннойТаблицы Из КолонкиВложенныхТаблиц Цикл
НоваяСтрока[КолонкаВложеннойТаблицы] = Выборка[КолонкаВложеннойТаблицы].Выгрузить();
КонецЦикла;
КонецЕсли;
Если РазмерПорцииОсталось > 0 Тогда
РазмерПорцииОсталось = РазмерПорцииОсталось - 1;
Если РазмерПорцииОсталось = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
КонецЦикла;
Если РазмерПорции = Несчитано Тогда
Выборка = Неопределено;
КонецЕсли;
#Если Клиент Тогда
ОсвободитьИндикаторПроцессаЛкс();
#КонецЕсли
ТаблицаПриемник = КопияТаблицыПриемника;
КонецПроцедуры // СчитатьПорциюРезультата()
// ТабличноеПоле определяется как источник действий командной панели.
// Параметру ВыборкаРезультата внутри присваивается значение!
Процедура ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатЗапроса, ВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", БезопасныйПорогКоличестваСтрок = 100000, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
лЗапрос = Новый Запрос;
РезультатЗапроса = лЗапрос.Выполнить();
#КонецЕсли
//БезопасныйПорогКоличестваСтрок = 1; // Для отладки
ВыборкаРезультата = РезультатЗапроса.Выбрать();
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
Если Ложь
Или БезопасныйПорогКоличестваСтрок = 0
Или ВыборкаРезультата.Количество() < БезопасныйПорогКоличестваСтрок
Тогда
ВыборкаРезультата = Неопределено;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Ложь;
ТабличноеПоле.Значение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
Попытка
Выполнить("ЭтаФорма." + ИмяОбработчикаОбновления + "()");
Исключение
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Иначе
ТабличноеПоле.Значение = Новый ТаблицаЗначений;
Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл
ТипЗначения = Колонка.ТипЗначения;
Если ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений");
КонецЕсли;
ТабличноеПоле.Значение.Колонки.Добавить(Колонка.Имя, ТипЗначения, Колонка.Имя, Колонка.Ширина);
КонецЦикла;
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
СчитатьПорциюВыборкиВТаблицуЛкс(ВыборкаРезультата, ТабличноеПоле.Значение, БезопасныйПорогКоличестваСтрок, , СсылкаНаБуфернуюТаблицу);
КонецЕсли;
КонецПроцедуры
// ТабличноеПоле определяется как источник действий командной панели.
Процедура ЗагрузитьВыборкуВТабличноеПолеПолностьюЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
СчитатьПорциюВыборкиВТаблицуЛкс(мВыборкаРезультата, ТабличноеПоле.Значение, 0, , СсылкаНаБуфернуюТаблицу);
КонецПроцедуры
// Параметру КоличествоРезультата внутри присваивается значение!
Процедура ПослеЗагрузкиВыборкиВТабличноеПолеЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
Если ТипЗнч(мВыборкаРезультата) = Тип("COMОбъект") Тогда
КоличествоРезультата = 0;
Попытка
КоличествоРезультата = мВыборкаРезультата.Count;
Исключение
Если мВыборкаРезультата.State <> 0 Тогда
КоличествоРезультата = мВыборкаРезультата.RecordCount;
КонецЕсли;
КонецПопытки;
ВсеСчитано = КоличествоРезультата = ТабличноеПоле.Значение.Количество();
ИначеЕсли ТипЗнч(мВыборкаРезультата) = Тип("ВыборкаИзРезультатаЗапроса") Тогда
КоличествоРезультата = мВыборкаРезультата.Количество();
Если СсылкаНаБуфернуюТаблицу <> Неопределено И СсылкаНаБуфернуюТаблицу.Свойство("Таблица") Тогда
ТабличноеПоле.Значение = СсылкаНаБуфернуюТаблицу.Таблица;
КонецЕсли;
ВсеСчитано = Ложь;
Иначе
КоличествоРезультата = ТабличноеПоле.Значение.Количество();
ВсеСчитано = Истина;
КонецЕсли;
ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, ТабличноеПоле.Значение.Количество(),
КоличествоРезультата, ВсеСчитано);
КонецПроцедуры
Функция ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(ПолноеИмяТаблицы, ИмяКолонки, ЗначениеОтбора, МаксимальнаяПорция = 0) Экспорт
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицы);
#Если Сервер И Не Сервер Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
ТекстПоля = "";
ПсевдонимТаблицы = "Т";
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если Ложь
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
Тогда
Продолжить;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстПоля) Тогда
ТекстПоля = ТекстПоля + ", ";
КонецЕсли;
ТекстПоля = ТекстПоля + ПсевдонимТаблицы + "." + ПолеТаблицыБД.Имя;
КонецЦикла;
ТекстПервые = "";
Если МаксимальнаяПорция > 0 Тогда
ТекстПервые = " ПЕРВЫЕ " + Формат(МаксимальнаяПорция, "ЧГ=") + " ";
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ " + ТекстПервые + " " + ТекстПоля + "
|ИЗ " + ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяТаблицы) + " КАК " + ПсевдонимТаблицы + "
|{ГДЕ " + ПсевдонимТаблицы + "." + ИмяКолонки + "}";
Построитель = Новый ПостроительЗапроса(ТекстЗапроса);
Если ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда
ЭлементОтбора = Построитель.Отбор.Добавить(ИмяКолонки);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = ЗначениеОтбора;
ЭлементОтбора.Использование = Истина;
Иначе
Построитель.Отбор.Добавить(ИмяКолонки).Установить(ЗначениеОтбора);
КонецЕсли;
Возврат Построитель;
КонецФункции
Функция ЗагрузитьСвязанныеСтрокиТаблицыБДЛкс(ЭтаФорма, ТабличноеПолеСвязанныхКолонок, ТабличноеПолеСвязанныхСтрок, КоманднаяПанельСвязанныхСтрок, мВыборкаРезультатаСтрокиТаблицы,
ЗначениеОтбора) Экспорт
СтрокаСвязаннойКолонки = ТабличноеПолеСвязанныхКолонок.ТекущаяСтрока;
Если СтрокаСвязаннойКолонки = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ЭтаФорма.СтрокиТаблицыБД = Новый ТаблицаЗначений;
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
//Если ЗначениеОтбора = Неопределено Тогда
// ЗначениеОтбора = СтрокаСвязаннойКолонки.Ссылка;
//КонецЕсли;
Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора);
//ЧислоСтрокДляЗагрузки = ирОбщий.КонтрольРазмераВыборкиПользователемЛкс(Построитель);
//Если ЧислоСтрокДляЗагрузки > 0 Тогда
// Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора, ЧислоСтрокДляЗагрузки);
//КонецЕсли;
//// http://partners.v8.1c.ru/forum/thread.jsp?id=1034151#1034151
////МаксимальныйРазмер = 500000;
////Построитель = ПолучитьПостроительВыборкиСвязанныхСтрок(, МаксимальныйРазмер);
// Антибаг 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1017264#1017264
Если ирКэш.НомерВерсииПлатформыЛкс() >= 802014 Тогда
Если Истина
И СтрокаСвязаннойКолонки.ТипТаблицы = "Изменения"
И Найти(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, "РегистрСведений.") = 1
Тогда
Если Метаданные.ОбщиеРеквизиты.Количество() > 0 Тогда
Возврат Неопределено;
КонецЕсли;
//Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
// ВыбранноеПоле = Построитель.ВыбранныеПоля.Найти(ОбщийРеквизит.Имя);
// Если Истина
// И ВыбранноеПоле <> Неопределено
// И ОбъектМетаданных.Измерения.Найти(ОбщийРеквизит.Имя) = Неопределено
// Тогда
// Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
// Построитель.ВыбранныеПоля.Удалить(ВыбранноеПоле);
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
КонецЕсли;
Попытка
РезультатСтрокиТаблицы = Построитель.Результат;
Исключение
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1031481#1031481
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
ирОбщий.ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатСтрокиТаблицы, мВыборкаРезультатаСтрокиТаблицы, КоманднаяПанельСвязанныхСтрок);
//Если СтрокиТаблицыБД.Количество() = МаксимальныйРазмер Тогда
// Сообщить("Были выбраны первые " + МаксимальныйРазмер + " строк таблицы");
//КонецЕсли;
СтруктураОтбора = Новый Структура("ПолноеИмяТаблицы, ИмяКолонки", СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки);
ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаСвязаннойКолонки);
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
ТабличноеПолеСвязанныхСтрок.ТекущаяКолонка = ТабличноеПолеСвязанныхСтрок.Колонки[СтрокаСвязаннойКолонки.ИмяКолонки];
Для Каждого КолонкаТП Из ТабличноеПолеСвязанныхСтрок.Колонки Цикл
КолонкаТП.ТолькоПросмотр = Истина;
КонецЦикла;
Попытка
ИскомаяСсылка = СтрокаСвязаннойКолонки.Ссылка
Исключение
ИскомаяСсылка = Неопределено;
КонецПопытки;
Если ИскомаяСсылка <> Неопределено Тогда
ТекущаяСтрока = ТабличноеПолеСвязанныхСтрок.Значение.Найти(ИскомаяСсылка, СтрокаСвязаннойКолонки.ИмяКолонки);
Если ТекущаяСтрока <> Неопределено Тогда
ТабличноеПолеСвязанныхСтрок.ТекущаяСтрока = ТекущаяСтрока;
КонецЕсли;
КонецЕсли;
Возврат СтрокаСвязаннойКолонки.ПолноеИмяТаблицы;
КонецФункции
Процедура ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоЗагружено, КоличествоРезультата, ВсеСчитано) Экспорт
Если ВсеСчитано Тогда
СтрокаКоличествоРезультата = "" + КоличествоЗагружено;
ПолеСтрокиКоличестваРезультата.ЦветФона = Новый Цвет();
Иначе
СтрокаКоличествоРезультата = "" + КоличествоЗагружено + "/" + КоличествоРезультата;
ПолеСтрокиКоличестваРезультата.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаВычисляемогоЗначения");
КонецЕсли;
ПолеСтрокиКоличестваРезультата.Значение = СтрокаКоличествоРезультата;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Не ВсеСчитано;
КонецПроцедуры
// Формирует макет компоновки и извлекает из него запрос
// Параметры:
// Схема - СхемаКомпоновкиДанных
// НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных
// ДобавлятьУпорядочивание - Булево
// ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один
// выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура,
// где ключи - имена колонок, а значения - полные имена полей
//
// Результат - Запрос
//
Функция ПолучитьЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновкиДанных, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "",
ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт
НастройкаКомпоновкиДанных = ПолучитьКопиюОбъектаЛкс(НастройкаКомпоновкиДанных);
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновкиДанных = Новый НастройкиКомпоновкиДанных
#КонецЕсли
Если НастройкаКомпоновкиДанных.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура);
КонецЕсли;
Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ДобавитьВыбранноеПоле);
КонецЕсли;
Если Не СПредставлениямиСсылок Тогда
Для Каждого ВыбранноеПоле Из НастройкаКомпоновкиДанных.Выбор.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Неподдерживаемый тип выбранного поля - " + ТипЗнч(ВыбранноеПоле);
КонецЕсли;
Если ВыбранноеПоле.Использование Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации
КонецЕсли;
КонецЦикла;
НастройкаКомпоновкиДанных.Выбор.Элементы.Очистить();
КонецЕсли;
СтрокаПорядка = ПолучитьСтрокуПорядкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Порядок);
НастройкаКомпоновкиДанных.Порядок.Элементы.Очистить();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновкиДанных, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Запрос = Новый Запрос;
Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда
Сообщить("В макете компоновки обнаружено более одного запроса");
КонецЕсли;
ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
Если ДобавлятьУпорядочивание Тогда
Если ЗначениеЗаполнено(СтрокаПорядка) Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|УПОРЯДОЧИТЬ ПО
| " + СтрокаПорядка;
КонецЕсли;
Если Ложь
Или Автоупорядочивание
//Или ЗначениеЗаполнено(СтрокаПорядка)
Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|АВТОУПОРЯДОЧИВАНИЕ";
КонецЕсли;
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Если ПрефиксИменПараметров <> "" Тогда
ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров);
КонецЕсли;
Если выхСхемаКолонок <> Неопределено Тогда
//выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки);
//
НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0];
Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл
выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным);
КонецЦикла;
Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл
выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным);
КонецЦикла;
КонецЕсли;
Возврат Запрос;
КонецФункции
Функция ПолучитьТекстОтбораЗапросаКомпоновкиЛкс(ЗапросСОтбором, ПсевдонимТаблицыПередГДЕ = "Т") Экспорт
ТекстОтбораДублей = ПолучитьПоследнийФрагментЛкс(ЗапросСОтбором.Текст, "КАК " + ПсевдонимТаблицыПередГДЕ + "
|ГДЕ", Ложь);
Если Не ЗначениеЗаполнено(ТекстОтбораДублей) Тогда
ТекстОтбораДублей = " ИСТИНА ";
КонецЕсли;
Возврат ТекстОтбораДублей;
КонецФункции
// Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений.
// Параметры:
// СхемаКомпоновки - СхемаКомпоновкиДанных
// НастройкаКомпоновки - НастройкиКомпоновкиДанных
// КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений
// ВнешниеНаборыДанных - Структура
// ТолькоСоздатьКолонки - Булево
// СхемаКолонок - Структура - Если Неопределено, то не возвращается
// МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено.
// ОтключитьОбщиеИтоги - Булево
// РежимОтладки - Булево
//
Функция СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(Знач СхемаКомпоновки, Знач НастройкаКомпоновки, КоллекцияЗначений = Неопределено, Знач ВнешниеНаборыДанных = Неопределено,
Знач ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено, Знач МаксимальноеЧислоСтрокРезультата = 0, Знач ОтключитьОбщиеИтоги = Истина, Знач РежимОтладки = Ложь,
ПроверятьДоступностьПолей = Ложь) Экспорт
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
//ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
//ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ОтключитьОбщиеИтоги Тогда
НастройкаКомпоновки.ПараметрыВывода.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВертикальноеРасположениеОбщихИтогов"),
РасположениеИтоговКомпоновкиДанных.Нет);
КонецЕсли;
Если Ложь
Или КоллекцияЗначений = Неопределено
Или ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений")
Или ТипЗнч(КоллекцияЗначений) = Тип("Массив")
Тогда
КоллекцияРезультата = Новый ТаблицаЗначений;
Иначе
КоллекцияРезультата = КоллекцияЗначений;
КонецЕсли;
Если РежимОтладки Тогда
ОтладитьЛкс(СхемаКомпоновки, Ложь, НастройкаКомпоновки, ВнешниеНаборыДанных);
//Возврат Неопределено;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Попытка
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Исключение
//ИнформацияОбОшибке = ИнформацияОбОшибке();
//Если глКэш.ЭтоВидимоеПриложение Тогда
// ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
//Иначе
// ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
//КонецЕсли;
ВызватьИсключение;
Возврат Неопределено;
КонецПопытки;
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
//ОтладитьЛкс(МакетКомпоновки, Ложь);
//Возврат Неопределено;
Если МаксимальноеЧислоСтрокРезультата > 0 Тогда
// Здесь тратится дополнительное ощутимое время на предварительный запрос.
ирПлатформа = ирКэш.Получить();
ГрубоеКоличествоСтрокРезультата = ирПлатформа.ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки(МакетКомпоновки);
Если ГрубоеКоличествоСтрокРезультата > МаксимальноеЧислоСтрокРезультата Тогда
Сообщить("Настройки компоновки приводят к слишком большой выборке данных. Попробуйте задать более сильные ограничения.");
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
//Антибаг платформы 1.14. Удаляем дубли ячеек по именам колонок в макете.
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 0 Тогда
ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки;
КоличествоЯчеек = ЯчейкиЗаголовка.Количество();
СтруктураКолонок = Новый Структура;
ИндексЯчейки = 0;
Пока ИндексЯчейки < КоличествоЯчеек Цикл
ЯчейкаКолонки = ЯчейкиЗаголовка[ИндексЯчейки];
ИмяКолонки = ЯчейкаКолонки.Имя;
//ИмяКолонки = ирПлатформа.ПолучитьИдентификаторИзПредставления(ЯчейкаКолонки.Имя); // От этого варианта отказались из-за портативности
ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_");
ИмяКолонки = СтрЗаменить(ИмяКолонки, "]", "");
ИмяКолонки = СтрЗаменить(ИмяКолонки, "[", "");
ИмяКолонки = СтрЗаменить(ИмяКолонки, " ", "_");
ЯчейкаКолонки.Имя = ИмяКолонки;
Если СтруктураКолонок.Свойство(ИмяКолонки) Тогда
Для ИндексМакета = 1 По ОписанияМакетовОбластей.Количество() - 1 Цикл
МакетСтроки = ОписанияМакетовОбластей[ИндексМакета];
МакетСтроки.Макет.Ячейки.Удалить(ИндексЯчейки);
КонецЦикла;
ЯчейкиЗаголовка.Удалить(ИндексЯчейки);
КоличествоЯчеек = КоличествоЯчеек - 1;
Иначе
ИндексЯчейки = ИндексЯчейки + 1;
СтруктураКолонок.Вставить(ИмяКолонки);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если СхемаКолонок <> Неопределено Тогда
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
СхемаКолонок.Очистить();
Если ЯчейкиЗаголовка <> Неопределено Тогда
КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество();
Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл
Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл
// Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205
// http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023
ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс];
Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение;
Если ПараметрЯчейки = Неопределено Тогда
Продолжить;
КонецЕсли;
Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение;
ПозицияТочки = Найти(Выражение, ".");
Если Ложь
Или ПозицияТочки = 0
Или Найти(Выражение, " ") > 0
Или Найти(Выражение, "(") > 0
Тогда
//ИмяПоля = "";
Продолжить;
Иначе
ИмяПоля = Сред(Выражение, ПозицияТочки + 1);
КонецЕсли;
СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля);
Прервать;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТолькоСоздатьКолонки Тогда
КоллекцияЗначений.Колонки.Очистить();
ЯчейкиЗаголовка = МакетКомпоновки.Макеты[0].Макет.Ячейки;
Для Каждого Ячейка Из ЯчейкиЗаголовка Цикл
//КолонкаКоллекции = КоллекцияЗначений.Колонки.Найти(Ячейка.Имя);
//Если КолонкаКоллекции = Неопределено Тогда
КоллекцияЗначений.Колонки.Добавить(Ячейка.Имя, Ячейка.ТипЗначения, Ячейка.Заголовок,);
//КонецЕсли;
КонецЦикла;
Иначе
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, , Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(КоллекцияРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецЕсли;
//ИсследоватьЛкс(КоллекцияРезультата);
Если ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений") Тогда
Есть0 = КоллекцияРезультата.Колонки.Количество() > 0;
Есть1 = КоллекцияРезультата.Колонки.Количество() > 1;
Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл
НовыйЭлемент = КоллекцияЗначений.Добавить();
Если Есть0 Тогда
НовыйЭлемент.Значение = СтрокаРезультата[0];
КонецЕсли;
Если Есть1 Тогда
НовыйЭлемент.Представление = СтрокаРезультата[1];
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(КоллекцияЗначений) = Тип("Массив") Тогда
Если КоллекцияРезультата.Колонки.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл
КоллекцияЗначений.Добавить(СтрокаРезультата[0]);
КонецЦикла;
КонецЕсли;
Иначе
КоллекцияЗначений = КоллекцияРезультата;
КонецЕсли;
Результат = КоллекцияЗначений;
Возврат Результат;
КонецФункции
Функция НайтиПоказатьСтрокуВПолеТекстовогоДокументаЛкс(Форма, ПолеТекстовогоДокумента, СтрокаПоиска) Экспорт
Позиция = Найти(Нрег(ПолеТекстовогоДокумента.ПолучитьТекст()), Нрег(СтрокаПоиска));
Если Позиция > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Позиция, Позиция + СтрДлина(СтрокаПоиска));
Форма.ТекущийЭлемент = ПолеТекстовогоДокумента;
Результат = Истина;
Иначе
Если СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Элемент - ПолеТабличногоДокумента
//
Функция ПолеТабличногоДокументаолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт
Сумма = 0;
СчетчикЯчеекСуммы = 0;
СчетчикЯчеекОбщий = 0;
ВыделенныеОбласти = Элемент.ВыделенныеОбласти;
ЕстьИгнорированныеОбласти = Ложь;
НачальноеКоличество = ВыделенныеОбласти.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда
Продолжить;
КонецЕсли;
ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1);
СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти;
Если ПлощадьОбласти < 10000 Тогда
Для НомерКолонки = Область.Лево по Область.Право Цикл
Для НомерСтроки = Область.Верх по Область.Низ Цикл
ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Попытка
Число = Число(ОбластьЯчейки.Текст);
Исключение
Продолжить;
КонецПопытки;
Сумма = Сумма + Число;
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1;
КонецЦикла;
КонецЦикла;
Иначе
ЕстьИгнорированныеОбласти = Истина;
КонецЕсли;
КонецЦикла;
СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы;
Сумма = "" + Сумма;
Если ЕстьИгнорированныеОбласти Тогда
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?";
Сумма = Сумма + "+?";
КонецЕсли;
Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + "";
Возврат Текст;
КонецФункции
// Параметры:
// Таблица - ТаблицаЗначений - может быть модифицирована здесь, поэтому нужно передавать копию, если нужна неизменность
Функция ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(ТаблицаЗначений, Знач Приемник = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхКолонок = Истина,
АвтофиксацияШапки = Истина, ВстроитьЗначенияВРасшифровки = Истина, ОтображатьПустые = Ложь, ДобавлятьКолонкиИдентификаторов = Ложь, ДобавлятьКолонкиТипов = Ложь,
ДобавлятьКолонкиПредставлений = Ложь, Знач ВыбранныеКолонки = Неопределено, ИмяТекущейКолонки = "", ВыводВТаблицуЗначений = Ложь, Отладка = Ложь) Экспорт
ТребоватьТипЛкс(ТаблицаЗначений, Тип("ТаблицаЗначений"));
ирПлатформа = ирКэш.Получить();
Если ДобавлятьКолонкиТипов Или ДобавлятьКолонкиИдентификаторов Тогда
//ТаблицаЗначений = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаЗначений);
ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(ТаблицаЗначений);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ирПлатформа = Обработки.ирПлатформа.Создать();
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ВнешниеНаборыДанных = Новый Структура("Основной", ТаблицаЗначений);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
КолонкиИдентификаторов = Новый Массив;
КолонкиТипов = Новый Массив;
Если ВыбранныеКолонки = Неопределено Тогда
ВыбранныеКолонки = Новый Массив;
Для Каждого Колонка Из КолонкиИсточникаДанныхЛкс(ТаблицаЗначений) Цикл
ВыбранныеКолонки.Добавить(Колонка.Имя);
КонецЦикла;
КонецЕсли;
//ПримитивныеТипы = Новый Массив;
//ПримитивныеТипы.Добавить(Тип("Число"));
//ПримитивныеТипы.Добавить(Тип("Строка"));
//ПримитивныеТипы.Добавить(Тип("Дата"));
//ПримитивныеТипы.Добавить(Тип("Булево"));
//ПримитивныеТипы.Добавить(Тип("Неопределено"));
//ПримитивныеТипы.Добавить(Тип("Null"));
//ПримитивныеТипы.Добавить(Тип("УникальныйИдентификатор"));
ИменаТипов = Новый Структура;
ПозицииКолонок = Новый Структура;
ИндексТекущейКолонки = 0;
Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл
Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда
Продолжить;
КонецЕсли;
Колонка = ТаблицаЗначений.Колонки.Найти(ВыбраннаяКолонка);
Если Колонка = Неопределено Тогда
// Например "ИдентификаторСсылкиЛкс" в таблице формы
Продолжить;
КонецЕсли;
ТипыКолонки = Колонка.ТипЗначения.Типы();
ПозицииКолонок.Вставить(Колонка.Имя, НастройкаКомпоновки.Выбор.Элементы.Количество());
Если ДобавлятьКолонкиПредставлений Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка);
КонецЕсли;
Если Ложь
Или ОтображатьПустые
Или (Истина
И ДобавлятьКолонкиТипов
И ТипыКолонки.Количество() > 1)
Тогда
КолонкиТипов.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ВыбраннаяКолонка + "_ИмяТипаЗначения_", Новый ОписаниеТипов("Строка"),
Колонка.Заголовок + " (тип)");
Если ДобавлятьКолонкиТипов Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка + "_ИмяТипаЗначения_");
КонецЕсли;
ИменаТиповКолонки = Новый Соответствие;
Для Каждого Тип Из ТипыКолонки Цикл
ИменаТиповКолонки.Вставить(Тип, ПредставлениеТипаЛкс(Тип, Колонка.ТипЗначения, Истина));
КонецЦикла;
ИменаТипов.Вставить(Колонка.Имя, ИменаТиповКолонки);
КонецЕсли;
Если ДобавлятьКолонкиИдентификаторов Тогда
ЕстьСсылочныйТип = ТипыКолонки.Количество() = 0;
Если Не ЕстьСсылочныйТип Тогда
Для Каждого Тип Из ТипыКолонки Цикл
Если ЛиТипСсылкиБДЛкс(Тип, Ложь) Тогда
ЕстьСсылочныйТип = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЕстьСсылочныйТип Тогда
Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда
ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество();
КонецЕсли;
КолонкиИдентификаторов.Добавить(Колонка.Имя);
ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ВыбраннаяКолонка + "_ИдентификаторЗначения_", Новый ОписаниеТипов("Строка"),
Колонка.Заголовок + " (идентификатор)");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка + "_ИдентификаторЗначения_");
КонецЕсли;
КонецЕсли;
Если ОтображатьПустые Тогда
ПустыеЗначения = Новый Массив;
ПустыеЗначения.Добавить(Неопределено);
ПустыеЗначения.Добавить(0);
ПустыеЗначения.Добавить(Дата(1,1,1));
ПустыеЗначения.Добавить(Ложь);
ПустыеЗначения.Добавить("");
Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл
Если Ложь
Или Колонка.ТипЗначения.Типы().Количество() = 0
Или Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение))
Тогда
ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение));
//ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс());
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, , ВидСравненияКомпоновкиДанных.НеЗаполнено);
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, ПустоеЗначение, ВидСравненияКомпоновкиДанных.Равно);
ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка);
КонецЕсли;
КонецЦикла;
// Отдельно для особенного Null
ПустоеЗначение = Null;
Если Истина
И Колонка.ТипЗначения.Типы().Количество() > 0
И Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение))
Тогда
ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить();
ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение));
//ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс());
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка + "_ИмяТипаЗначения_", "Null", ВидСравненияКомпоновкиДанных.Равно);
ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Ложь
Или КолонкиТипов.Количество() > 0
Или КолонкиИдентификаторов.Количество() > 0
Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЗначений.Количество(), "Заполнение доп. колонок");
Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор); // добавляет значительную долю длительности цикла
// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
#Если Сервер И Не Сервер Тогда
Для Каждого ИмяКолонки Из КолонкиТипов Цикл
Если Ложь
Или ДобавлятьКолонкиТипов
Или СтрокаТаблицы[ИмяКолонки] = Null
Тогда
СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])];
КонецЕсли;
КонецЦикла;
Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл
СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = ПолучитьИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);
КонецЦикла;
#КонецЕсли
// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы ""Инструменты разработчика"" (http://devtool1c.ucoz.ru)
Для Каждого ИмяКолонки Из КолонкиТипов Цикл   Если Ложь   Или ДобавлятьКолонкиТипов   Или СтрокаТаблицы[ИмяКолонки] = Null   Тогда   СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])];   КонецЕсли;   КонецЦикла;   Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл   СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = ПолучитьИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);   КонецЦикла;  
КонецЦикла;
КонецЕсли;
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхКолонок);
Если Отладка Тогда
ОтладитьЛкс(СхемаКомпоновки, , НастройкаКомпоновки, ВнешниеНаборыДанных);
Возврат Неопределено;
КонецЕсли;
Если ВыводВТаблицуЗначений Тогда
Приемник = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных);
//Приемник = ТаблицаЗначений.Скопировать(, "...");
Иначе
Приемник = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных, ДанныеРасшифровки, АвтофиксацияШапки,, ВстроитьЗначенияВРасшифровки);
#Если Сервер И Не Сервер Тогда
Приемник = Новый ТабличныйДокумент;
#КонецЕсли
Если ЗначениеЗаполнено(ИмяТекущейКолонки) Тогда
Приемник.ТекущаяОбласть = Приемник.Область(2, ПозицииКолонок[ИмяТекущейКолонки] + 1);
КонецЕсли;
Для Счетчик = 1 По ВыбранныеКолонки.Количество() Цикл
ИмяКолонки = ВыбранныеКолонки[Счетчик - 1];
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Продолжить;
КонецЕсли;
Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки);
Если Колонка <> Неопределено Тогда
Приемник.Область(1, ПозицииКолонок[ИмяКолонки] + 1).Примечание.Текст = "Типы значений: " + РасширенноеПредставлениеЗначенияЛкс(Колонка.ТипЗначения);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Приемник;
КонецФункции
Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Если ДанныеРасшифровки = Неопределено Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КонецЕсли;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, ДанныеРасшифровки,,, ПроверятьДоступностьПолей);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки);
Если ВстроитьЗначенияПолейВРасшифровки Тогда
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ИдентификаторРасшифровки = Ячейка.Расшифровка;
Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля();
Если ЗначенияПолей.Количество() > 0 Тогда
Ячейка.Расшифровка = ЗначенияПолей[0].Значение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
Функция ДополнительныеДействияРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровки) Экспорт
#Если Сервер И Не Сервер Тогда
ЭлементРасшифровки = Новый ЭлементРасшифровкиКомпоновкиДанныхПоля;
#КонецЕсли
ДополнительныеПунктыМеню = Новый СписокЗначений;
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
ЗначениеПоляЗначение = ЗначениеПоля.Значение;
ПорогДлины = 100;
ПредставлениеЗначения = "" + ЗначениеПоляЗначение;
Если СтрДлина(ПредставлениеЗначения) > ПорогДлины Тогда
ПредставлениеЗначения = Лев(ПредставлениеЗначения, 100) + "...";
КонецЕсли;
ДополнительныеПунктыМеню.Добавить(Новый Структура("Значение, Открыть", ЗначениеПоля.Значение), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """",
, ирОбщий.ПолучитьПиктограммуТипаЛкс(ТипЗнч(ЗначениеПоля.Значение)));
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение) Тогда
ДополнительныеПунктыМеню.Добавить(Новый Структура("Ссылка, ОткрытьВРедактореОбъектаБД", ЗначениеПоля.Значение), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """",
, ирКэш.КартинкаПоИмениЛкс("ирРедактироватьОбъектБД"));
КонецЕсли;
КонецЦикла;
Возврат ДополнительныеПунктыМеню;
КонецФункции
Процедура ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(Знач ВыбранноеДействие, СтандартнаяОбработка) Экспорт
Если ТипЗнч(ВыбранноеДействие) = Тип("Структура") Тогда
Если ВыбранноеДействие.Свойство("Открыть") Тогда
ирОбщий.ОткрытьЗначениеЛкс(ВыбранноеДействие.Значение,, СтандартнаяОбработка);
ИначеЕсли ВыбранноеДействие.Свойство("ОткрытьВРедактореОбъектаБД") Тогда
ирОбщий.ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранноеДействие.Ссылка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Параметры:
// ОтчетОбъект - Форма, ОтчетОбъект
Процедура ОтчетКомпоновкиОбработкаРасшифровкиЛкс(Знач ОтчетОбъект, Знач Расшифровка, СтандартнаяОбработка, ДополнительныеПараметры, ПолеТабличногоДокумента, ДанныеРасшифровки,
Авторасшифровка = Ложь) Экспорт
#Если _ Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[0];
ТабличныйДокумент = Новый ТабличныйДокумент;
ОтчетОбъект = Отчеты.ирАнализЗамераПроизводительности.Создать();
#КонецЕсли
Если ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
//Возврат;
КонецЕсли;
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[Расшифровка];
ДоступныеДействия = Новый Массив;
РазрешитьАвтовыборДействия = Истина;
ПараметрВыбранногоДействия = Неопределено;
СписокДополнительныхДействий = ДополнительныеДействияРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки);
Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ОбработкаРасшифровки") Тогда
ОтчетОбъект.ОбработкаРасшифровки(ДанныеРасшифровки, ЭлементРасшифровки, ПолеТабличногоДокумента, ДоступныеДействия, СписокДополнительныхДействий, РазрешитьАвтовыборДействия);
КонецЕсли;
Если Истина
И РазрешитьАвтовыборДействия
И Авторасшифровка
И СписокДополнительныхДействий.Количество() = 1
Тогда
ВыбранноеДействие = СписокДополнительныхДействий[0].Значение;
КонецЕсли;
Если ВыбранноеДействие = Неопределено Тогда
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек);
ОбработкаРасшифровки.ВыбратьДействие(Расшифровка, ВыбранноеДействие, ПараметрВыбранногоДействия, ДоступныеДействия, СписокДополнительныхДействий, Авторасшифровка);
КонецЕсли;
Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Нет Тогда
СтандартнаяОбработка = Ложь;
//Возврат;
КонецЕсли;
Если ПараметрВыбранногоДействия = Неопределено Тогда
ПараметрВыбранногоДействия = Новый Соответствие;
ЗначенияПолей = ЭлементРасшифровки.ПолучитьПоля();
Для Каждого ЗначениеПоля Из ЗначенияПолей Цикл
ПараметрВыбранногоДействия.Вставить("" + ЗначениеПоля.Поле, ЗначениеПоля.Значение);
КонецЦикла;
КонецЕсли;
ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(ВыбранноеДействие, СтандартнаяОбработка);
Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ДействиеРасшифровки") Тогда
ОтчетОбъект.ДействиеРасшифровки(ВыбранноеДействие, ПараметрВыбранногоДействия, СтандартнаяОбработка);
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
ОткрытьЗначение(ПараметрВыбранногоДействия);
ИначеЕсли ТипЗнч(ВыбранноеДействие) = Тип("ДействиеОбработкиРасшифровкиКомпоновкиДанных") Тогда
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных);
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек);
НовыеНастройки = ОбработкаРасшифровки.ПрименитьНастройки(Расшифровка, ПараметрВыбранногоДействия);
ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НовыеНастройки);
ОтчетОбъект.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Непосредственно);
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецПроцедуры
// мВнешниеНаборыДанных - Структура, Неопределено - не очищается
Функция ДополнитьСтруктуруВнешихНаборовДанныхПустышкамиЛкс(лСхемаКомпоновкиДанных, мВнешниеНаборыДанных = Неопределено) Экспорт
Если мВнешниеНаборыДанных = Неопределено Тогда
мВнешниеНаборыДанных = Новый Структура();
КонецЕсли;
// Создадим пустышки внешних наборов данных, если они не переданы
ОбъектТаблица = 0;
Для Каждого НаборДанных Из лСхемаКомпоновкиДанных.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
Если НаборДанных.ИмяОбъекта = "" Тогда
Продолжить;
КонецЕсли;
Если Не мВнешниеНаборыДанных.Свойство(НаборДанных.ИмяОбъекта, ОбъектТаблица) Тогда
ОбъектТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Попытка
КолонкиОбъектаТаблицы = ОбъектТаблица.Колонки;
Исключение
// Тогда это табличная часть, но возможно и тут будет исключение
КолонкиОбъектаТаблицы = ОбъектТаблица.ВыгрузитьКолонки().Колонки;
КонецПопытки;
Если КолонкиОбъектаТаблицы.Количество() > 0 Тогда
Продолжить;
КонецЕсли;
Для Каждого Поле Из НаборДанных.Поля Цикл
Если ТипЗнч(Поле) = Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
Если КолонкиОбъектаТаблицы.Найти(Поле.Поле) = Неопределено Тогда
КолонкиОбъектаТаблицы.Добавить(Поле.Поле, Поле.ТипЗначения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
мВнешниеНаборыДанных.Вставить(НаборДанных.ИмяОбъекта, ОбъектТаблица);
КонецЕсли;
КонецЦикла;
Возврат мВнешниеНаборыДанных;
КонецФункции
Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Истина) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент);
ТекущееЗначение = ДанныеЭлементаФормыЛкс(Элемент);
Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение, Ложь) Тогда
НачальноеЗначениеВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ТекущееЗначение));
КонецЕсли;
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда
лПолноеИмяОбъекта = Неопределено;
Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда
ИмяТипаСсылки = ИмяТипаИзПолногоИмениМДЛкс(лПолноеИмяОбъекта, "Ссылка");
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки);
НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение);
Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда
//Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,,, Элемент, Истина);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Возврат НовоеЗначение;
КонецФункции
// Результат - значение выбранного типа, но не обязательно выбранное (выбор типа выполняется синхронно, а значения - асинхронно)
Функция ПолеВвода_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, ИгнорироватьОписаниеТипов = Ложь) Экспорт
РезультатВыбора = ДанныеЭлементаФормыЛкс(Элемент);
Если Истина
И ИгнорироватьОписаниеТипов
И (Ложь
Или ТипЗнч(РезультатВыбора) = Тип("Строка")
Или РезультатВыбора = Неопределено)
Тогда
РезультатВыбора = ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка);
ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(РезультатВыбора, Ложь) Тогда
СтандартнаяОбработка = Ложь;
ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РезультатВыбора)),,, Элемент, Истина,, РезультатВыбора);
Иначе
// Тут надо делать выбор из диалога плоского списка типов
КонецЕсли;
Возврат РезультатВыбора;
КонецФункции
// Для "Ссылка.Организация" вернет "Организация", для "Основание.Контрагент" вернет "ОснованиеКонтрагент"
// Параметры:
// ИмяПоля - Строка
Функция ПолучитьИмяКолонкиРезультатаПоИмениПоляЛкс(Знач ИмяПоля) Экспорт
Начало = "Ссылка.";
ДлинаНачала = СтрДлина(Начало);
Если СтрокиРавныЛкс(Лев(ИмяПоля, ДлинаНачала), Начало) Тогда
ИмяПоля = Сред(ИмяПоля, ДлинаНачала + 1);
КонецЕсли;
ИмяПоля = СтрЗаменить(ИмяПоля, ".", "");
Возврат ИмяПоля;
КонецФункции
Процедура ДобавитьМногострочнуюСтрокуВТекстЛкс(СобираемыйТекст, Выражение, Смещение, СНовойСтроки = Ложь, ОбрезатьЛевыеПустые = Ложь) Экспорт
Если СНовойСтроки Тогда
СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение;
КонецЕсли;
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Выражение);
СобираемыйТекст = СобираемыйТекст + ТекстовыйДокумент.ПолучитьСтроку(1);
Для Счетчик = 2 По ТекстовыйДокумент.КоличествоСтрок() Цикл
ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(Счетчик);
Если ОбрезатьЛевыеПустые Тогда
ТекущаяСтрока = СокрЛ(ТекущаяСтрока);
КонецЕсли;
СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение + ТекущаяСтрока;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьИндексКартинкиТипаЛкс(ОписаниеТипов) Экспорт
Если ОписаниеТипов = Неопределено Тогда
Возврат 14;
КонецЕсли;
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() = 1 Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Типы[0]);
Если Типы[0] = Тип("Число") Тогда
ИндексКартинки = 0;
ИначеЕсли Типы[0] = Тип("Строка") Тогда
ИндексКартинки = 1;
ИначеЕсли Типы[0] = Тип("Дата") Тогда
ИндексКартинки = 2;
ИначеЕсли Типы[0] = Тип("Булево") Тогда
ИндексКартинки = 3;
ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда
ИндексКартинки = 19;
ИначеЕсли Типы[0] = Тип("Тип") Тогда
ИндексКартинки = 20;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 7;
ИначеЕсли КорневойТип = "Документ" Тогда
ИндексКартинки = 8;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 9;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 10;
ИначеЕсли КорневойТип = "ПланСчетов" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда
ИндексКартинки = 14;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки ПорядокКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1C") Экспорт
Строка = "";
Если СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
СтрокаВозр = "Возр";
СтрокаУбыв = "Убыв";
Иначе
СтрокаВозр = "Asc";
СтрокаУбыв = "Desc";
КонецЕсли;
Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + СтрокаВозр;
Иначе
Строка = Строка + СтрокаУбыв;
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс()
////////////////////////////////
// ФОРМЫ
Процедура ИнициализироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы) Экспорт
// Проверяем режим модальности
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ОткрыватьФормуПерезапуска = Ложь;
// Проверка контроля модальности
СпрашиватьОПерезапуске = Истина;
Список = Новый СписокЗначений;
Попытка
Список.ВыбратьЭлемент();
Исключение
СпрашиватьОПерезапуске = Ложь;
КонецПопытки;
Если Ложь
Или ирКэш.НомерИзданияПлатформыЛкс() = "82"
Или мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина
Или Метаданные.РежимИспользованияМодальности = Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.Использовать
Тогда
Если Не СпрашиватьОПерезапуске Тогда
ВызватьИсключение "При запуске приложения из конфигуратора автоматически включается контроль модальности.
|Запустите приложение другим способом, чтобы разрешить модальность.";
КонецЕсли;
Иначе
ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС();
ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'");
КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine;
мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина;
Если Ложь
Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckModal") > 0
//Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckExtensionsAndAddInsSyncCalls") > 0
Тогда
Сообщить("При запуске сеанса из конфигуратора автоматически включается контроль модальности. Для его отключения рекомендуется перезапустить сеанс через открывшуюся форму.",
СтатусСообщения.Внимание);
ОткрыватьФормуПерезапуска = Истина;
КонецЕсли;
КонецЕсли;
// Проверяем защиту от опасных действий
// Здесь это делать мало полезно, т.к. она срабатывает раньше
Если Истина
И ирКэш.ЛиПортативныйРежимЛкс()
И мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась <> Истина
//И ирКэш.НомерВерсииПлатформыЛкс() < 803010 // Когда в платформе исправят проблему, тогда и отключим
Тогда
ТекущийПользовательБазы = ПользователиИнформационнойБазы.ТекущийПользователь();
Попытка
ЗащитаОтОпасныхДействий = ТекущийПользовательБазы.ЗащитаОтОпасныхДействий;
Исключение
ЗащитаОтОпасныхДействий = Неопределено;
КонецПопытки;
Если Истина
И ЗначениеЗаполнено(ТекущийПользовательБазы.Имя)
И ЗащитаОтОпасныхДействий <> Неопределено
И ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина
Тогда
Сообщить("У текущего пользователя базы включена защита от опасных действий.
|Для корректной работы инструментров ее рекомендуется отключить перезапуском сеанса через открывшуюся форму.", СтатусСообщения.Внимание);
ОткрыватьФормуПерезапуска = Истина;
КонецЕсли;
мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась = Истина;
КонецЕсли;
Если ОткрыватьФормуПерезапуска Тогда
#Если ТолстыйКлиентОбычноеПриложение Тогда
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ПерезапускСеансаОбычная");
#Иначе
ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#КонецЕсли
КонецЕсли;
Если мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась <> Истина Тогда
мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась = Истина;
#Если (ТолстыйКлиентОбычноеПриложение ИЛИ ТолстыйКлиентУправляемоеПриложение) И Не Сервер Тогда
// Проверка компиляции общих модулей с обработчиками событий
СписокМодулей = Новый Структура;
ОбщиеМодули = Метаданные.ОбщиеМодули;
#Если ТолстыйКлиентУправляемоеПриложение Тогда
ИмяКлиента = "Управляемое";
#Иначе
ИмяКлиента = "Обычное";
#КонецЕсли
ИмяСвойства = "Клиент" + ИмяКлиента + "Приложение";
Для Каждого Подписка Из Метаданные.ПодпискиНаСобытия Цикл
МетаМодуль = ОбщиеМодули.Найти(ирОбщий.ПолучитьПервыйФрагментЛкс(Подписка.Обработчик));
Если МетаМодуль = Неопределено Тогда
// Некорректная подписка
Продолжить;
КонецЕсли;
Если Не МетаМодуль[ИмяСвойства] И Не МетаМодуль.ВызовСервера Тогда
СписокМодулей.Вставить(МетаМодуль.Имя);
КонецЕсли;
КонецЦикла;
Если СписокМодулей.Количество() > 0 Тогда
Если ИмяКлиента = "Управляемое" Тогда
//Сообщить("Для работы с инструментами в этой конфигурации рекомендуется использовать режим запуска ""Обычное приложение"".");
Иначе
Сообщить("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на события.", СтатусСообщения.Внимание);
Сообщить("Поэтому в работе некоторых инструментов возможны ошибки ""При подписке * на событие * произошла ошибка. Обработчик события не найден.""");
Если ИмяКлиента = "Обычное" Тогда
Сообщить("Необходимо в конфигураторе установить ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение"".");
КонецЕсли;
ТекстСообщения = "Рекумендуется установить флажок ""Клиент (" + ИмяКлиента + " приложение)"" или ""Вызова сервера"" и обеспечить компиляцию у этих общих модулей:";
Для Каждого КлючИЗначение Из СписокМодулей Цикл
ТекстСообщения = ТекстСообщения + " " + КлючИЗначение.Ключ + ",";
КонецЦикла;
Сообщить(ТекстСообщения);
КонецЕсли;
КонецЕсли;
#Если ТолстыйКлиентОбычноеПриложение Тогда
Если Истина
И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение
И Не Метаданные.ИспользоватьУправляемыеФормыВОбычномПриложении
Тогда
Сообщить("Рекомендуется включить в свойствах конфигурации флажок ""Использовать управляемые формы в обычном приложении""");
КонецЕсли;
#КонецЕсли
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если Не Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении Тогда
Сообщить("Рекомендуется включить в свойствах конфигурации флажок ""Использовать обычные формы в управляемом приложении"" доступный в режиме ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение""");
КонецЕсли;
#КонецЕсли
КонецЕсли;
НастроитьЭлементыФормыЛкс(ЭтаФорма);
Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма);
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы);
мСвойстваФормы.Вставить("НеготовыеСтраницы", Новый СписокЗначений);
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Контейнер = Новый Структура();
Оповестить("ирПолучитьБазовуюФорму", Контейнер);
Если Не Контейнер.Свойство("ирПортативный") Тогда
БазоваяФорма = ирПортативный.ПолучитьФорму();
БазоваяФорма.Открыть();
КонецЕсли;
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + мПлатформа.ПолучитьИдентификаторИзПредставления(ПолноеИмяФормы) + "(ЭтаФорма)";
Выполнить(СтрокаВызова);
Иначе
МетаФорма = Метаданные.НайтиПоПолномуИмени(ПолноеИмяФормы);
Если МетаФорма = Неопределено Тогда
Сообщить("Метаформа не найдена по полному имени """ + ПолноеИмяФормы + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
ФлажокОбъектыНаСервере = ЭтаФорма.ЭлементыФормы.Найти("ОбъектыНаСервере");
Если ФлажокОбъектыНаСервере <> Неопределено Тогда
ФлажокОбъектыНаСервере.Доступность = Не ирКэш.ЛиПортативныйРежимЛкс() Или ирПортативный.ЛиСерверныйМодульДоступенЛкс();
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ФлажокОбъектыНаСервере.Подсказка = "Запись и удаление объектов данных выполнять на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение.";
Иначе
ФлажокОбъектыНаСервере.Подсказка = "Работать с объектами данных на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение.";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура НастроитьЭлементыФормыЛкс(ЭтаФорма) Экспорт
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
КнопкиВсехДействийКомандныхПанелей = Новый Соответствие;
ИмяКнопки = "СтруктураКоманднойПанели";
ИмяОсновногоРеквизита = "ОсновнойОбъект";
Попытка
ОсновнойРеквизит = ЭтаФорма[ИмяОсновногоРеквизита];
Исключение
КонецПопытки;
Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл
Если ОсновнойРеквизит <> Неопределено Тогда
Попытка
Данные = ЭлементФормы.Данные;
Исключение
Данные = "";
КонецПопытки;
Если Не ПустаяСтрока(Данные) И Найти(Данные, ".") = 0 Тогда
Если Не ЗначениеЗаполнено(ЭлементФормы.Подсказка) Тогда
РеквизитОбъекта = ОсновнойРеквизит.Метаданные().Реквизиты.Найти(Данные);
Если РеквизитОбъекта <> Неопределено Тогда
ЭлементФормы.Подсказка = РеквизитОбъекта.Подсказка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Встраиваем кнопки структуры командной панели
КоманднаяПанель = Неопределено;
ВстроитьВНачало = Истина;
Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда
КоманднаяПанель = ЭлементФормы;
Если Не КоманднаяПанель.Видимость Тогда
Продолжить;
КонецЕсли;
//ИначеЕсли ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
// КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
Иначе
Попытка
// В контекстных меню функция маловостребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок
КоманднаяПанель = ЭлементФормы.КонтекстноеМеню;
ВстроитьВНачало = Ложь;
Исключение
КонецПопытки;
КонецЕсли;
Если Истина
И КоманднаяПанель <> Неопределено
И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено
Тогда
НужноВстроить = Ложь;
КоличествоКнопок = 0;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда
КоличествоКнопок = КоличествоКнопок + 1;
Если КоличествоКнопок > 4 Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЕсли;
Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда
НужноВстроить = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если НужноВстроить Тогда
Если ВстроитьВНачало Тогда
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0);
Иначе
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Добавить();
КонецЕсли;
КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки;
КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаСтруктураКоманднойПанели.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКоманднаяПанель");
КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели";
КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели";
Попытка
КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие");
Исключение
// В этой форме нет обработчика
Возврат;
КонецПопытки;
КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель);
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда
НастроитьТабличноеПолеЛкс(ЭлементФормы);
КонецЕсли;
КонецЦикла;
мСвойстваФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей);
КонецПроцедуры
Процедура НастроитьТабличноеПолеЛкс(Знач ЭлементФормы) Экспорт
// Возвращаем старый стиль шапок колонок, при котором видна текущая колонка
Если ЭлементФормы.Колонки.Количество() > 0 Тогда
// Антифича платформы 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=898034
Если ЭлементФормы.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда
ЭлементФормы.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт
мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма);
КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка];
Если Кнопка <> Неопределено Тогда
Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда
// Для контекстных меню
КоманднаяПанель = КоманднаяПанель.Кнопки[0];
КонецЕсли;
КонецЕсли;
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы");
ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель;
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма) Экспорт
ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы");
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Функция ОткрытьФормуСоединенияСУБДЛкс(Автоподключение = Ложь) Экспорт
ФормаПодключения = ирКэш.Получить().ПолучитьФорму("ПараметрыСоединенияСУБД");
ФормаПодключения.Автоподключение = Автоподключение;
Если Автоподключение И Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
ФормаПодключения.ОткрытьМодально();
КонецЕсли;
Возврат ФормаПодключения;
КонецФункции
#КонецЕсли
Функция ПреставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт
Представление = "";
Если СочетаниеКлавиш.Alt Тогда
Представление = Представление + "Alt+";
КонецЕсли;
Если СочетаниеКлавиш.Ctrl Тогда
Представление = Представление + "Ctrl+";
КонецЕсли;
Если СочетаниеКлавиш.Shift Тогда
Представление = Представление + "Shift+";
КонецЕсли;
Представление = Представление + СочетаниеКлавиш.Клавиша;
Возврат Представление;
КонецФункции
Функция ЦветФонаЯчеекПустыхЗначенийЛкс() Экспорт
ЦветПустых = Новый Цвет(250, 255, 250); //WebЦвета.Роса;
Возврат ЦветПустых;
КонецФункции
Функция ВосстановитьЗначениеЛкс(КлючНастроек) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
Возврат ВосстановитьЗначениеЛкс(КлючНастроек);
#Иначе
Результат = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), КлючНастроек);
#Если Клиент Тогда
Если Результат = Неопределено Тогда
// Импорт из старого хранилища настроек
Результат = ВосстановитьЗначение(КлючНастроек);
Если Результат <> Неопределено Тогда
СохранитьЗначениеЛкс(КлючНастроек, Результат);
СохранитьЗначение(КлючНастроек, Неопределено);
КонецЕсли;
КонецЕсли;
#КонецЕсли
Возврат Результат;
#КонецЕсли
КонецФункции
Функция СохранитьЗначениеЛкс(КлючНастроек, Значение) Экспорт
#Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда
ирСервер.СохранитьЗначениеЛкс(КлючНастроек, Значение);
#Иначе
ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Значение);
#КонецЕсли
КонецФункции
Процедура ДобавитьИндексВТаблицуЛкс(ТаблицаЗначений, Знач СтрокаИндекса) Экспорт
#Если Сервер И Не Сервер Тогда
ТаблицаЗначений = Новый ТаблицаЗначений;
#КонецЕсли
ИндексНайден = Ложь;
Для Каждого Индекс Из ТаблицаЗначений.Индексы Цикл
Если "" + Индекс = СтрокаИндекса Тогда
ИндексНайден = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ИндексНайден Тогда
ТаблицаЗначений.Индексы.Добавить(СтрокаИндекса);
КонецЕсли;
КонецПроцедуры // вВыполнитьОбработку()
// Можно ради скорости отказываться от использования этой функции
Функция ЛиПустаяПодгруппа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) = """" Тогда
Текст = Лев(Текст, СтрДлина(Текст) - 1);
КонецЕсли;
Возврат Текст;
КонецФункции
// Разделяет URL по составным частям: протокол, сервер, путь к ресурсу.
//
// Параметры:
// URL - Строка - ссылка на ресурс в сети Интернет
//
// Возвращаемое значение:
// Структура:
// Протокол - Строка - протокол доступа к ресурсу
// ИмяСервера - Строка - сервер, на котором располагается ресурс
// ПутьКФайлуНаСервере - Строка - путь к ресурсу на сервере
//
Функция РазделитьURLЛкс(Знач URL) Экспорт
СтруктураURL = СтруктураURIЛкс(URL);
Результат = Новый Структура;
Результат.Вставить("Протокол", ?(ПустаяСтрока(СтруктураURL.Схема), "http", СтруктураURL.Схема));
Результат.Вставить("ИмяСервера", СтруктураURL.ИмяСервера);
Результат.Вставить("ПутьКФайлуНаСервере", СтруктураURL.ПутьНаСервере);
Возврат Результат;
КонецФункции
// Разбирает строку URI на составные части и возвращает в виде структуры.
// На основе RFC 3986.
//
// Параметры:
// СтрокаURI - Строка - ссылка на ресурс в формате: <схема>://<логин>:<пароль>@<хост>:<порт>/<путь>?<параметры>#<якорь>
//
// Возвращаемое значение:
// Структура - составные части URI согласно формату:
// * Схема - Строка
// * Логин - Строка
// * Пароль - Строка
// * ИмяСервера - Строка - часть <хост>:<порт> входного параметра
// * Хост - Строка
// * Порт - Строка
// * ПутьНаСервере - Строка - часть <путь>?<параметры>#<якорь> входного параметра
//
Функция СтруктураURIЛкс(Знач СтрокаURI) Экспорт
СтрокаURI = СокрЛП(СтрокаURI);
// схема
Схема = "";
Позиция = Найти(СтрокаURI, "://");
Если Позиция > 0 Тогда
Схема = НРег(Лев(СтрокаURI, Позиция - 1));
СтрокаURI = Сред(СтрокаURI, Позиция + 3);
КонецЕсли;
// строка соединения и путь на сервере
СтрокаСоединения = СтрокаURI;
ПутьНаСервере = "";
Позиция = Найти(СтрокаСоединения, "/");
Если Позиция > 0 Тогда
ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1);
СтрокаСоединения = Лев(СтрокаСоединения, Позиция - 1);
КонецЕсли;
// информация пользователя и имя сервера
СтрокаАвторизации = "";
ИмяСервера = СтрокаСоединения;
Позиция = Найти(СтрокаСоединения, "@");
Если Позиция > 0 Тогда
СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1);
ИмяСервера = Сред(СтрокаСоединения, Позиция + 1);
КонецЕсли;
// логин и пароль
Логин = СтрокаАвторизации;
Пароль = "";
Позиция = Найти(СтрокаАвторизации, ":");
Если Позиция > 0 Тогда
Логин = Лев(СтрокаАвторизации, Позиция - 1);
Пароль = Сред(СтрокаАвторизации, Позиция + 1);
КонецЕсли;
// хост и порт
Хост = ИмяСервера;
Порт = "";
Позиция = Найти(ИмяСервера, ":");
Если Позиция > 0 Тогда
Хост = Лев(ИмяСервера, Позиция - 1);
Порт = Сред(ИмяСервера, Позиция + 1);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Схема);
Результат.Вставить("Логин", Логин);
Результат.Вставить("Пароль", Пароль);
Результат.Вставить("ИмяСервера", ИмяСервера);
Результат.Вставить("Хост", Хост);
Результат.Вставить("Порт", ?(ПустаяСтрока(Порт), Неопределено, Число(Порт)));
Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
Возврат Результат;
КонецФункции
// Поиск числа в строке
//
// Параметры:
// ИсходнаяСтрока - Строка, строка в которой ищется число
// ПозицияЧисла - Число, позиция начала числа
// КоличествоСимволов - Число, количество символов числа
//
// Возвращаемое значение:
// Булево - Истина, число найдено
//
Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, ПозицияЧисла, КоличествоСимволов) Экспорт
ПозицияЧисла = 0;
КоличествоСимволов = 0;
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
Для Сч = 1 По ДлинаСтроки Цикл
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
Если ПозицияЧисла = 0 Тогда
ПозицияЧисла = Сч;
КоличествоСимволов = 1;
Иначе
КоличествоСимволов = КоличествоСимволов + 1;
КонецЕсли;
Иначе
Если ПозицияЧисла <> 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ПозицияЧисла > 0;
КонецФункции // НайтиЧислоВСтроке()
Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт
#Если Клиент Тогда
Если ВыводитьПредупрежденияИСообщения Тогда
Ответ = КодВозвратаДиалога.ОК;
Если НаСервере Тогда
ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
Иначе
ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
КонецЕсли;
Если ОбщийРазмер > 0 Тогда
Ответ = Вопрос("Действительно удалить рекурсивно все файлы (" + Формат(Цел(ОбщийРазмер/1000000), "ЧН=") + "МБ) в каталоге журнала?", РежимДиалогаВопрос.ОКОтмена);
КонецЕсли;
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если НаСервере Тогда
ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения);
Возврат;
КонецЕсли;
#КонецЕсли
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина);
Если ФайлыЖурнала.Количество() > 0 Тогда
СчетчикНеудаленных = 0;
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
Попытка
УдалитьФайлы(ФайлЖурнала.ПолноеИмя);
Исключение
СчетчикНеудаленных = СчетчикНеудаленных + 1;
КонецПопытки;
КонецЦикла;
Если ВыводитьПредупрежденияИСообщения Тогда
Если СчетчикНеудаленных > 0 Тогда
Сообщить("" + СчетчикНеудаленных + " файлов техножурнала удалить не удалось");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс()
Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт
Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги);
ОбщийРазмер = 0;
Для Каждого Файл Из Файлы Цикл
Если Файл.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
ОбщийРазмер = ОбщийРазмер + Файл.Размер();
КонецЦикла;
Возврат ОбщийРазмер;
КонецФункции
// Выполняет копирование файлов рекурсивно
Процедура СкопироватьФайлыЛкс(КаталогИсточник, КаталогПриемник) Экспорт
Файлы = НайтиФайлы(КаталогИсточник, "*.*");
Для Каждого Файл Из Файлы Цикл
ФайлПриемник = Новый Файл(КаталогПриемник + "\" + Файл.Имя);
Если Файл.ЭтоКаталог() Тогда
СоздатьКаталог(ФайлПриемник.ПолноеИмя);
СкопироватьФайлыЛкс(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
Продолжить;
КонецЕсли;
КопироватьФайл(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя);
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка", НезависимыйРодитель = Ложь) Экспорт
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ТекСостояние = Родитель[ИмяДанныхФлажка];
НайденыВключенные = Ложь;
НайденыВыключенные = Ложь;
Для каждого Строка из Родитель.Строки Цикл
ЗначениеФлажка = Строка[ИмяДанныхФлажка];
Если ЗначениеФлажка = 0 Тогда
НайденыВыключенные = Истина;
ИначеЕсли ЗначениеФлажка = 1 Тогда
НайденыВключенные = Истина;
ИначеЕсли ЗначениеФлажка = 2 Тогда
НайденыВключенные = Истина;
НайденыВыключенные = Истина;
Прервать;
КонецЕсли;
Если НайденыВключенные И НайденыВыключенные Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если НезависимыйРодитель Тогда
Если НайденыВключенные Тогда
Включить = 2;
КонецЕсли;
Иначе
Если НайденыВключенные И НайденыВыключенные Тогда
Включить = 2;
ИначеЕсли НайденыВключенные И Не НайденыВыключенные Тогда
Включить = 1;
ИначеЕсли Не НайденыВключенные И НайденыВыключенные Тогда
Включить = 0;
ИначеЕсли Не НайденыВключенные И Не НайденыВыключенные Тогда
Включить = 2;
КонецЕсли;
КонецЕсли;
Если Включить = ТекСостояние Тогда
Возврат;
Иначе
Если Родитель[ИмяДанныхФлажка] <> 1 Или Не НезависимыйРодитель Тогда
Родитель[ИмяДанныхФлажка] = Включить;
УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт
ТекСостояние = ТекСтрока[ИмяДанныхФлажка];
Подчиненные = ТекСтрока.Строки;
Если ТекСостояние = 2 Тогда
ТекСтрока[ИмяДанныхФлажка] = 0;
КонецЕсли;
Если Подчиненные.Количество() > 0 Тогда
Для каждого Строка из Подчиненные Цикл
Строка[ИмяДанныхФлажка] = ТекСостояние;
УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ЛиСпискиПодсистемПересекаютсяЛкс(ФильтрПодсистем, СписокПодсистем) Экспорт
Если ТипЗнч(ФильтрПодсистем) = Тип("Строка") Тогда
СписокФильтра = Новый СписокЗначений;
СписокФильтра.Добавить(ФильтрПодсистем);
КонецЕсли;
Если Ложь
Или СписокФильтра.Количество() = 0
Или СписокФильтра[0] = ""
Тогда
Возврат Истина;
КонецЕсли;
Для Каждого Подсистема Из СписокПодсистем Цикл
Если ТипЗнч(Подсистема) = Тип("ОбъектМетаданных") Тогда
ИмяПодсистемы = Подсистема.ПолноеИмя();
Иначе
ИмяПодсистемы = Подсистема.Значение;
КонецЕсли;
Если СписокФильтра.НайтиПоЗначению(ИмяПодсистемы) <> Неопределено Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Разбирает строку на две части: до подстроки разделителя и после
//
// Параметры:
// Стр - разбираемая строка
// Разделитель - подстрока-разделитель
// Режим - 0 - разделитель в возвращаемые подстроки не включается
// 1 - разделитель включается в левую подстроку
// 2 - разделитель включается в правую подстроку
//
// Возвращаемое значение:
// Правая часть строки - до символа-разделителя
//
Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт
ПраваяЧасть = "";
ПозРазделителя = Найти(Стр, Разделитель);
ДлинаРазделителя = СтрДлина(Разделитель);
Если ПозРазделителя > 0 Тогда
ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя));
Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1)));
КонецЕсли;
Возврат(ПраваяЧасть);
КонецФункции // вОтделитьРазделителем()
// Проверяет попадание даты внутрь интервала всключая границы
Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И ЗначениеЗаполнено(НачалоПериода)
И ПроверяемаяДата < НачалоПериода)
Или (Истина
И ЗначениеЗаполнено(КонецПериода)
И ПроверяемаяДата > КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
// Проверяет попадание даты внутрь интервала исключая границы
Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ПустаяДата = Дата("00010101");
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И НачалоПериода <> ПустаяДата
И ПроверяемаяДата <= НачалоПериода)
Или (Истина
И КонецПериода <> ПустаяДата
И ПроверяемаяДата >= КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт
ПроверочныйФайл = Новый Файл(Каталог);
Попытка
ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог();
Исключение
Если ВыводитьСообщения Тогда
Сообщить("Указанный путь """ + Каталог + """ не доступен: " + ОписаниеОшибки());
КонецЕсли;
Возврат Ложь;
КонецПопытки;
Если Не ЭтоКаталог Тогда
Если ВыводитьСообщения Тогда
Сообщить("Указанный путь """ + Каталог + """ не является каталогом");
КонецЕсли;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // ЛиКаталогДоступен()
Функция ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(СтрокаРасширений, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт
Расширения = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаРасширений, ",", Истина);
Результат = "";
Для Каждого Расширение Из Расширения Цикл
Если Результат <> "" Тогда
Результат = Результат + "|";
КонецЕсли;
ОписаниеРасширения = "(*." + Расширение + ")|*." + Расширение;
Если ЗначениеЗаполнено(ОписаниеФормата) Тогда
ОписаниеРасширения = ОписаниеФормата + " " + ОписаниеРасширения;
КонецЕсли;
Результат = Результат + ОписаниеРасширения;
КонецЦикла;
Если РазрешитьВсеФайлы Тогда
Результат = Результат + "|Все файлы (*.*)|*.*";
КонецЕсли;
Возврат Результат;
КонецФункции
// Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных
// в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана.
// Фиксированные коллекции превращаются в нефиксированные.
//
// Параметры:
// КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция;
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник.
//
// Возвращаемое значение:
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник.
//
Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт
ТипКоллекции = ТипЗнч(КоллекцияИсточник);
Если Ложь
Или ТипКоллекции = Тип("Массив")
Или ТипКоллекции = Тип("ФиксированныйМассив")
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных")
#КонецЕсли
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Массив;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Добавить(Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Структура")
Или ТипКоллекции = Тип("ФиксированнаяСтруктура")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Структура;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Соответствие")
Или ТипКоллекции = Тип("ФиксированноеСоответствие")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Соответствие;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый СписокЗначений;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки();
КонецЕсли;
ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник);
Возврат КоллекцияПриемник;
#КонецЕсли
Иначе
Сообщить("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """");
Возврат Неопределено;
КонецЕсли;
КонецФункции // СкопироватьУниверсальнуюКоллекциюЛкс()
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда
// Параметры:
// СписокПодсистем - СписокЗначений
// Результат - Соответствие - ключи - объекты метаданных входящие в заданные подсистемы
Функция ОбъектыПодсистемЛкс(СписокПодсистем, СтрокаДереваПодсистем = Неопределено, ОбъектыВыбранныхПодсистем = Неопределено) Экспорт
Если ОбъектыВыбранныхПодсистем = Неопределено Тогда
ОбъектыВыбранныхПодсистем = Новый Соответствие;
КонецЕсли;
Для Каждого ЭлементСписка Из СписокПодсистем Цикл
ПодсистемаМД = Метаданные.НайтиПоПолномуИмени("Подсистема." + СтрЗаменить(ЭлементСписка.Значение, ".", ".Подсистема."));
Для Каждого ЭлементСостава Из ПодсистемаМД.Состав Цикл
ОбъектыВыбранныхПодсистем.Вставить(ЭлементСостава, 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Строка(СчетчикСтроки) + " указаны значения не для всех колонок");
КонецЕсли;
Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда
СтрокаТаблицы = ТаблицаПриемник.Добавить();
Для ИндексКолонки = 0 По Массив.ВГраница() Цикл
СтрокаТаблицы[ИндексКолонки] = Массив[ИндексКолонки];
КонецЦикла;
Иначе //Если ТипЗнч(ТаблицаПриемник) = Тип("ТабличныйДокумент") Тогда
#Если Сервер И Не Сервер Тогда
ТаблицаПриемник = Новый ТабличныйДокумент;
#КонецЕсли
АдресЯчейки = "R" + Формат(СчетчикСтроки, "ЧГ=") + "C";
Для ИндексКолонки = 0 По Массив.ВГраница() Цикл
ТаблицаПриемник.Область(АдресЯчейки + Формат(ИндексКолонки + 1, "ЧГ=")).Текст = Массив[ИндексКолонки];
КонецЦикла;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
Возврат ТаблицаПриемник;
КонецФункции // ПолучитьМассивИзСтрокиСРазделителемЛкс()
Функция ОбщийТипДанныхТабличногоПоляЛкс(Знач ТабличноеПоле, ПреобразоватьТипДанныхФормы = Ложь, выхСтруктураТипа = Неопределено) Экспорт
мПлатформа = ирКэш.Получить();
ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
Если ПреобразоватьТипДанныхФормы Тогда
ТипЗначенияТабличногоПоля = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ТабличноеПоле).Типы()[0];
Иначе
ТипЗначенияТабличногоПоля = ТипЗнч(ЗначениеТабличногоПоля);
КонецЕсли;
Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда
ТипИсточника = "ДеревоЗначений";
ИначеЕсли Ложь
Или ТипЗначенияТабличногоПоля = Тип("ДанныеФормыКоллекция")
Или ТипЗначенияТабличногоПоля = Тип("ДанныеФормыСтруктураСКоллекцией")
Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДанныеФормыДерево") Тогда
ТипИсточника = "ДеревоЗначений";
Иначе
мПлатформа.ИнициализацияОписанияМетодовИСвойств();
выхСтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля);
Если Ложь
Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0
Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВидыСубконто") > 0
Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "БазовыеВидыРасчета") > 0
Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВедущиеВидыРасчета") > 0
Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВытесняющиеВидыРасчета") > 0
Тогда
ТипИсточника = "ТабличнаяЧасть";
ИначеЕсли Найти(выхСтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда
ТипИсточника = "НаборЗаписей";
ИначеЕсли Найти(выхСтруктураТипа.ИмяОбщегоТипа, "Список.") > 0 Тогда
ТипИсточника = "Список";
ИначеЕсли выхСтруктураТипа.ИмяОбщегоТипа = "ДинамическийСписок" Тогда
//ТипИсточника = "ДинамическийСписок";
ТипИсточника = "Список";
КонецЕсли;
КонецЕсли;
Возврат ТипИсточника;
КонецФункции // ИнтерактивноУстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗ()
// Параметры:
// ЭтаФорма - Форма
// ТабличноеПоле - ТабличноеПоле
// КлючевоеПоле - Строка
// ЗначениеКлюча -
// СообщатьОбУспехе - Булево
//
Функция УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач ЗначениеКлюча = Неопределено, Знач СообщатьОбУспехе = Ложь,
АктивизироватьТабличноеПолеПриУспехе = Ложь) Экспорт
ТипИсточника = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле);
Если Ложь
Или ТипИсточника = "ТаблицаЗначений"
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей"
Тогда
ДанныеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
ДанныеТабличногоПоля = Новый ТаблицаЗначений;
#КонецЕсли
Если КлючевоеПоле <> Неопределено Тогда
НайденныеСтроки = ДанныеТабличногоПоля.НайтиСтроки(Новый Структура(КлючевоеПоле, ЗначениеКлюча));
Иначе
НайденныеСтроки = ДанныеТабличногоПоля;
КонецЕсли;
Если НайденныеСтроки.Количество() > 0 Тогда
НайденнаяСтрока = НайденныеСтроки[0];
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
НайденнаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор();
КонецЕсли;
КонецЕсли;
ЭтоКлиентскийИсточникДанных = Истина;
ИначеЕсли ТипИсточника = "ДеревоЗначений" Тогда
НайденнаяСтрока = ТабличноеПоле.Значение.Строки.Найти(ЗначениеКлюча, КлючевоеПоле, Истина);
ЭтоКлиентскийИсточникДанных = Истина;
Иначе
НайденнаяСтрока = ЗначениеКлюча;
Отбор = ТабличноеПоле.Значение.Отбор;
ЭтоКлиентскийИсточникДанных = Ложь;
МетаданныеИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение));
ИмяТаблицыБД = МетаданныеИсточника.ПолноеИмя();
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ИмяТаблицыБД;
ПостроительЗапроса.ЗаполнитьНастройки();
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ИмяТаблицыБД);
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ЗначениеКлюча);
УстановитьОтборПоСтруктуреЛкс(ПостроительЗапроса.Отбор, СтруктураКлюча);
СтрокаЕстьВИсточникеДанных = Не ПостроительЗапроса.Результат.Пустой();
КонецЕсли;
Если ЭтоКлиентскийИсточникДанных Тогда
СтрокаЕстьВИсточникеДанных = НайденнаяСтрока <> Неопределено;
КонецЕсли;
Если СтрокаЕстьВИсточникеДанных Тогда
ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока;
Иначе
Сообщить("Строка не найдена в источнике данных");
КонецЕсли;
Если ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока Тогда
Если АктивизироватьТабличноеПолеПриУспехе Тогда
ЭтаФорма.ТекущийЭлемент = ТабличноеПоле;
КонецЕсли;
Результат = Истина;
Иначе
Если СтрокаЕстьВИсточникеДанных Тогда
ТекстСообщения = "Строка найдена в источнике данных, но не найдена в табличном поле";
Если Отбор <> Неопределено Тогда
ТекстСообщения = ТекстСообщения + " с учетом отбора " + Отбор;
КонецЕсли;
Сообщить(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры
// МетаданныеКолонок - КоллекцияОбъектовМетаданных, ТаблицаЗначений - для таблицы значений используются колонки Имя и Метаданные
Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияТиповКолонок = Неопределено, МетаданныеКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено,
ТолькоПросмотр = Ложь) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если ОписанияТиповКолонок = Неопределено Тогда
ОписанияТиповКолонок = ирСервер.ПолучитьТаблицуДочернихРеквизитовЛкс(ТабличноеПоле);
КонецЕсли;
Иначе
Если ОписанияТиповКолонок = Неопределено Тогда
ОписанияТиповКолонок = ТабличноеПоле.Значение.Колонки;
КонецЕсли;
КонецЕсли;
Для Каждого КолонкаТаблицы Из ОписанияТиповКолонок Цикл
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТабличногоПоля = ТабличноеПоле.ПодчиненныеЭлементы.Найти(ТабличноеПоле.Имя + КолонкаТаблицы.Имя);
Иначе
КолонкаТабличногоПоля = ТабличноеПоле.Колонки.Найти(КолонкаТаблицы.Имя);
КонецЕсли;
Если КолонкаТабличногоПоля = Неопределено Тогда
Продолжить;
КонецЕсли;
Если КолонкаТабличногоПоля.Видимость Тогда
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если ТабличноеПоле.ТекущийЭлемент = Неопределено Тогда
ТабличноеПоле.ТекущийЭлемент = КолонкаТабличногоПоля;
КонецЕсли;
Иначе
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
ТабличноеПоле.ТекущаяКолонка = КолонкаТабличногоПоля;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ТолькоПросмотр Тогда
КолонкаТабличногоПоля.ТолькоПросмотр = Истина;
КонецЕсли;
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
ТипыРеквизита = КолонкаТаблицы.ТипЗначения.Типы();
Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда
КолонкаТабличногоПоля.Данные = "";
КолонкаТабличногоПоля.ДанныеФлажка = КолонкаТаблицы.Имя;
КолонкаТабличногоПоля.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
КолонкаТабличногоПоля.Ширина = 3;
Иначе
Если КолонкаТаблицы.Ширина > 0 Тогда
КолонкаТабличногоПоля.Ширина = Мин(КолонкаТаблицы.Ширина, 50); // Почему то в редакторе таблицы значений не работала автоширина (-1)
КонецЕсли;
Если КолонкаТабличногоПоля.Ширина = 0 Тогда
КолонкаТабличногоПоля.Ширина = 3; // Для 8.2 необходимо, иначе колонки будут не видны
КонецЕсли;
КонецЕсли;
Если МетаданныеКолонок <> Неопределено Тогда
Если ТипЗнч(МетаданныеКолонок) = Тип("КоллекцияОбъектовМетаданных") Тогда
Метареквизит = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя);
Иначе
СтрокаПоля = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя, "Имя");
Если СтрокаПоля <> Неопределено Тогда
Метареквизит = СтрокаПоля.Метаданные;
Иначе
Метареквизит = Неопределено;
КонецЕсли;
КонецЕсли;
Если Метареквизит <> Неопределено Тогда
Попытка
Подсказка = Метареквизит.Подсказка;
Исключение
// У графы журнала нет подсказки
Подсказка = Неопределено;
КонецПопытки;
Если Подсказка <> Неопределено Тогда
КолонкаТабличногоПоля.ПодсказкаВШапке = Подсказка;
Если Метареквизит.МногострочныйРежим Тогда
КолонкаТабличногоПоля.ЭлементУправления.МногострочныйРежим = Метареквизит.МногострочныйРежим;
КолонкаТабличногоПоля.ЭлементУправления.РасширенноеРедактирование = Метареквизит.РасширенноеРедактирование;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ДоступныеПоляВыбора <> Неопределено Тогда
ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя));
Если ДоступноеПоле <> Неопределено Тогда
ТекстШапки = ДоступноеПоле.Заголовок;
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
КолонкаТабличногоПоля.Заголовок = ТекстШапки;
Иначе
КолонкаТабличногоПоля.ТекстШапки = ТекстШапки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьСтраницуТЧ()
Функция ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс() Экспорт
МассивСостояний = Новый Массив;
МассивСостояний.Добавить("Не отображать");
МассивСостояний.Добавить("Отображать пустые");
МассивСостояний.Добавить("Отображать пустые и идентификаторы");
Возврат МассивСостояний;
КонецФункции
Функция КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
КлючУникальности = ЭтаФорма.мКлючУникальности;
Иначе
КлючУникальности = ЭтаФорма.КлючУникальности;
КонецЕсли;
Результат = ИмяФормыИзФормыЛкс(ЭтаФорма) + "." + КлючУникальности + ".ПоследниеВыбранные";
Возврат Результат;
КонецФункции
// Параметры:
// ЭтаФорма - Форма
// КнопкаПодменю - Кнопка - подменю, в которое будут добавлены кнопки
//
Процедура ПоследниеВыбранныеЗаполнитьПодменюЛкс(Знач ЭтаФорма, КнопкаПодменю) Экспорт
КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма);
ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения);
Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда
ОчиститьПодчиненныеЭлементыФормыЛкс(КнопкаПодменю);
Иначе
КнопкаПодменю.Кнопки.Очистить();
КонецЕсли;
Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда
Возврат;
КонецЕсли;
ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс();
Для Счетчик = ЗапоминатьПоследниеВыбранные По ПоследниеВыбранные.Количество() - 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Тип.ИмяТипа;
КонецЕсли;
Возврат ИдентификаторСсылки;
КонецФункции
Функция ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ОбязательныеДляПроверкиИмена = """") Экспорт
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивИмен = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбязательныеДляПроверкиИмена, ",", Истина, Ложь);
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст);
Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл
МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы);
КонецЦикла;
ИначеЕсли ирКэш.НомерВерсииПлатформыЛкс() >= 803008 Тогда
#Если Сервер И Не Сервер Тогда
Пустышка = Новый Запрос;
ЗапросИлиМенеджерВременныхТаблиц = Пустышка.МенеджерВременныхТаблиц;
#КонецЕсли
Для Каждого ТаблицаМенеджера Из ЗапросИлиМенеджерВременныхТаблиц.Таблицы Цикл
МассивИмен.Добавить(ТаблицаМенеджера.ПолноеИмя);
КонецЦикла;
ИначеЕсли Не ЗначениеЗаполнено(ОбязательныеДляПроверкиИмена) Тогда
ВызватьИсключение "Необходимо указать имена временных таблиц";
КонецЕсли;
Возврат МассивИмен;
КонецФункции // ПолВТ()
Процедура СкопироватьДеревоЛкс(ИсходноеДерево, НовоеДерево, ОчиститьПередЗагрузкой = Истина) Экспорт
Если ОчиститьПередЗагрузкой Тогда
НовоеДерево.Строки.Очистить();
КонецЕсли;
Если ИсходноеДерево.Строки.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для каждого СтрокаДерева из ИсходноеДерево.Строки Цикл
НоваяСтрока = НовоеДерево.Строки.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева);
СкопироватьДеревоЛкс(СтрокаДерева, НоваяСтрока, ОчиститьПередЗагрузкой = Истина);
КонецЦикла;
КонецПроцедуры
Функция СоздатьСамоудаляющийсяКомандныйФайлЛкс(Знач ТекстКомандногоФайла = "", Знач КраткоеИмяФайла = "") Экспорт
Если ЗначениеЗаполнено(КраткоеИмяФайла) Тогда
ПолноеИмяФайла = КаталогВременныхФайлов() + КраткоеИмяФайла + ".bat";
Иначе
ПолноеИмяФайла = ПолучитьИмяВременногоФайла("bat");
КонецЕсли;
ТекстКомандногоФайла = ТекстКомандногоФайла + "
|del """ + ПолноеИмяФайла + """
|";
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(ТекстКомандногоФайла);
ТекстовыйДокумент.Записать(ПолноеИмяФайла, КодировкаТекста.OEM);
Результат = ПолноеИмяФайла;
Возврат Результат;
КонецФункции
// Проверить уникальность строк ТЧ по колонке
//
// Параметры:
// Объект - <тип> -
// ИмяТаблицы - <тип> -
// ИмяКолонки - <тип>, "" -
//
// Возвращаемое значение:
//
Функция ПроверитьУникальностьСтрокТЧПоКолонкеЛкс(Объект, ИмяТаблицы, ИмяКолонки = "", ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено,
МассивИсключений = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = Объект.Метаданные().ТабличныеЧасти[ИмяТаблицы].Реквизиты[0].Имя;
КонецЕсли;
Если Истина
И МассивИсключений <> Неопределено
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
НовыйМассивИсключений = Новый Массив;
Для Каждого ИсключаемоеЗначение Из МассивИсключений Цикл
Если ТипЗнч(ИсключаемоеЗначение) = Тип("Строка") Тогда
ИсключаемоеЗначение = НРег(ИсключаемоеЗначение);
КонецЕсли;
НовыйМассивИсключений.Добавить(ИсключаемоеЗначение);
КонецЦикла;
МассивИсключений = НовыйМассивИсключений;
КонецЕсли;
Успех = Истина;
НеуникальныеЗначения = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Объект[ИмяТаблицы], ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа, ОтборСтрок);
Для Каждого НеуникальноеЗначение Из НеуникальныеЗначения Цикл
Если Истина
И МассивИсключений <> Неопределено
И МассивИсключений.Найти(НеуникальноеЗначение) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
Сообщить("Значение """ + НеуникальноеЗначение + """ встречается более одного раза среди активных строк в колонке """ + ИмяКолонки + """ таблицы """ + ИмяТаблицы + """",
СтатусСообщения.Внимание);
Успех = Ложь;
КонецЦикла;
Возврат Успех;
КонецФункции
Функция ПолучитьПроцессОСЛкс(Знач ИдентификаторПроцесса = Неопределено, Знач НачалоПроцесса = Неопределено, Знач Компьютер = Неопределено,
ВызватьИсключениеПриОшибкеПодключенияWMI = Истина, ДопустимоеОтклонениеВремени = 2, МаркерВКоманднойСтроке = Неопределено, ИмяИсполняемогоФайла = Неопределено) Экспорт
Если СтрокиРавныЛкс(ИдентификаторПроцесса, "текущий") Тогда
ИдентификаторПроцесса = ирКэш.Получить().ПолучитьИдентификаторПроцессаОС();
КонецЕсли;
Попытка
WMIЛокатор = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер);
Исключение
Если ВызватьИсключениеПриОшибкеПодключенияWMI Тогда
ВызватьИсключение;
КонецЕсли;
ОписаниеОшибки = ОписаниеОшибки();
Сообщить(ОписаниеОшибки, СтатусСообщения.Внимание);
WMIЛокатор = Неопределено;
КонецПопытки;
Если WMIЛокатор = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
// ТекстОтбора = "1=1 AND"; Синтаксис WQL такого не допускает
ТекстОтбора = "";
Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " ProcessID = " + XMLСтрока(ИдентификаторПроцесса);
КонецЕсли;
Если ЗначениеЗаполнено(МаркерВКоманднойСтроке) Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " CommandLine LIKE '%" + МаркерВКоманднойСтроке + "%'";
КонецЕсли;
Если ЗначениеЗаполнено(ИмяИсполняемогоФайла) Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " Name = '" + ИмяИсполняемогоФайла + "'";
КонецЕсли;
Если НачалоПроцесса <> Неопределено Тогда
Если ТекстОтбора <> "" Тогда
ТекстОтбора = ТекстОтбора + "AND ";
КонецЕсли;
ТекстОтбора = ТекстОтбора + " CreationDate >= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса - ДопустимоеОтклонениеВремени);
ТекстОтбора = ТекстОтбора + " AND CreationDate <= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса + 1 + ДопустимоеОтклонениеВремени);
КонецЕсли;
Результат = "Процесс ОС с отбором (" + ТекстОтбора + ") не найден";
ТекстЗапросаWQL = "Select * from Win32_Process Where " + ТекстОтбора;
ВыборкаПроцессовОС = WMIЛокатор.ExecQuery(ТекстЗапросаWQL);
Для Каждого ПроцессОС Из ВыборкаПроцессовОС Цикл
Результат = ПроцессОС;
Прервать;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ЭтоЛокальныйКомпьютерЛкс(Компьютер) Экспорт
Результат = Ложь
Или Не ЗначениеЗаполнено(Компьютер)
Или Компьютер = "."
Или СтрокиРавныЛкс(Компьютер, "localhost")
Или Компьютер = "127.0.0.1"
#Если Не ВебКлиент Тогда
Или СтрокиРавныЛкс(Компьютер, ИмяКомпьютера())
#КонецЕсли
;
Возврат Результат;
КонецФункции
Функция ПолучитьЛитералДатыДляWQLЛкс(Знач Результат) Экспорт
Результат = Результат - СмещениеСтандартногоВремени();
Результат = "'" + Формат(Результат, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'";
Возврат Результат
КонецФункции
Функция ПолучитьФайлWMIЛкс(ПолноеИмяФайла, КомпьютерИлиИмя = Неопределено) Экспорт
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(КомпьютерИлиИмя);
ФайлыWMI = СлужбаWMI.ExecQuery("Select * from CIM_Datafile where name='" + ЗаменитьСлешиНаДвойныеЛкс(ПолноеИмяФайла) + "'");
Для каждого ФайлWMI Из ФайлыWMI цикл
КонецЦикла;
Возврат ФайлWMI;
КонецФункции // ПолучитьФайлWMIИис()
Процедура ЗаполнитьДоступныеСборкиПлатформыЛкс(СборкиПлатформы, Компьютер = "", ТипыComКлассов = Неопределено) Экспорт
#Если Сервер И Не Сервер Тогда
СборкиПлатформы = Обработки.ирУправлениеСлужбамиСерверов1С.Создать().СборкиПлатформы;
#КонецЕсли
СборкиПлатформы.Очистить();
// Оба варианта пришлось оставить, т.к. WMI вариант очень долгий
Если ирОбщий.ЭтоИмяЛокальногоСервераЛкс(Компьютер) Тогда
Инсталлер = Новый COMОбъект("WindowsInstaller.Installer");
Продукты = Инсталлер.Products;
Иначе
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер);
Если СлужбаWMI = Неопределено Тогда
Возврат;
КонецЕсли;
Продукты = СлужбаWMI.ExecQuery("SELECT * FROM Win32_Product WHERE Vendor LIKE '1C' OR Vendor LIKE '1С'");
КонецЕсли;
Для Каждого Продукт Из Продукты Цикл
Если ЭтоИмяЛокальногоСервераЛкс(Компьютер) Тогда
Попытка
ПубликаторПродукта = Инсталлер.ProductInfo(Продукт, "Publisher");
Исключение
Продолжить;
КонецПопытки;
Если Истина
И ПубликаторПродукта <> "1C" // латинские буквы
И ПубликаторПродукта <> "1С" // русские буквы
И ПубликаторПродукта <> "1С-Софт" // русские буквы
Тогда
Продолжить;
КонецЕсли;
//НаименованиеПродукта = Инсталлер.ProductInfo(Продукт, "ProductName");
КаталогВерсии = Инсталлер.ProductInfo(Продукт, "InstallLocation");
//СтрокаРелиза = Инсталлер.ProductInfo(Продукт, "VersionString");
Иначе
КаталогВерсии = Продукт.InstallLocation;
КонецЕсли;
СтрокаТаблицыСборок = СборкиПлатформы.Добавить();
СтрокаТаблицыСборок.Каталог = КаталогВерсии;
ФайлПолученияВерсии = Неопределено;
Если ТипыComКлассов <> Неопределено Тогда
Для Каждого ТипКласса Из ТипыComКлассов Цикл
//Если Метаданные().ТабличныеЧасти.СборкиПлатформы.Реквизиты.Найти(ВыборкаКлассов.Имя) = Неопределено Тогда
// Продолжить;
//КонецЕсли;
ФайлКомпоненты = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\" + ТипКласса.КлючевойФайл, Компьютер);
СтрокаТаблицыСборок[ТипКласса.Имя] = ФайлКомпоненты <> Неопределено;
Если СтрокаТаблицыСборок[ТипКласса.Имя] Тогда
ФайлПолученияВерсии = ФайлКомпоненты;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\ragent.exe", Компьютер);
СтрокаТаблицыСборок.АгентСервера = ИсполняемыйФайл <> Неопределено;
Если СтрокаТаблицыСборок.АгентСервера Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\ras.exe", Компьютер);
СтрокаТаблицыСборок.СерверАдминистрирования = ИсполняемыйФайл <> Неопределено;
Если СтрокаТаблицыСборок.СерверАдминистрирования Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\dbgs.exe", Компьютер);
СтрокаТаблицыСборок.СерверОтладки = ИсполняемыйФайл <> Неопределено;
Если СтрокаТаблицыСборок.СерверОтладки Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\crserver.exe", Компьютер);
СтрокаТаблицыСборок.СерверХранилища = ИсполняемыйФайл <> Неопределено;
Если СтрокаТаблицыСборок.СерверХранилища Тогда
ФайлПолученияВерсии = ИсполняемыйФайл;
КонецЕсли;
Если ФайлПолученияВерсии <> Неопределено Тогда
СтрокаТаблицыСборок.ФайлыСуществуют = Истина;
СтрокаТаблицыСборок.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 Тогда
ГлавнаяТаблица.Индексы.Добавить("Метаданные");
КонецЕсли;
Для Каждого ИмяМД Из ОтборПоМетаданным Цикл
Для Каждого СтрокаТаблицы Из ГлавнаяТаблица.НайтиСтроки("Метаданные", ИмяМД) Цикл
ЗаполнитьЗначенияСвойств(Результат.Добавить(), СтрокаТаблицы);
КонецЦикла;
КонецЦикла;
Иначе
Результат = ГлавнаяТаблица;
КонецЕсли;
Иначе
Результат = ПолучитьСтруктуруХраненияБазыДанных(ОтборПоМетаданным, ЛиИменаБД);
КонецЕсли;
ОбработатьВыборкуСтруктурыХраненияБДЛкс(Результат, ЛиИменаБД, ВычислитьИменаИндексов);
Если ОтборПоМетаданным = Неопределено Тогда
#Если Клиент Тогда
Состояние("");
#КонецЕсли
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД) Экспорт
Если Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда
Возврат Неопределено;
Иначе
Результат = ПолучитьИзВременногоХранилища(АдресЧужойСхемыБД);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОбновитьПовторноИспользуемыеЗначенияЛкс() Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ОбновитьПовторноИспользуемыеЗначенияЛкс();
Иначе
ОбновитьПовторноИспользуемыеЗначения();
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСовместимоеЗначениеПараметраЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт
Результат = ЗначениеПараметра;
ТипЗначенияПараметра = ТипЗнч(Результат);
Если Истина
И ТипЗначенияПараметра = Тип("Массив")
И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено
Тогда
СписокЗначений = Новый СписокЗначений;
ПреобразованиеУспешно = Истина;
Для Каждого ЭлементМассива Из ЗначениеПараметра Цикл
Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда
СписокЗначений.Добавить(ЭлементМассива);
Иначе
ПреобразованиеУспешно = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПреобразованиеУспешно Тогда
Результат = СписокЗначений;
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из массива в список значений", СтатусСообщения.Внимание);
КонецЕсли;
Иначе
МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
Если МетаданныеТипаЗначения <> Неопределено Тогда
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя());
Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Результат = ЗначениеПараметра.Выгрузить();
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из табличной части в таблицу значений", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда
#Если Сервер И Не Сервер Тогда
ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов;
#КонецЕсли
Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(ЗначениеПараметра);
Если Результат <> ЗначениеПараметра Тогда
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано """ + ЗначениеПараметра + """->""" + Результат + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт
ТекстЗапроса = ДинамическийСписок.ТекстЗапроса;
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ТекущаяГруппировка = выхНастройкаКомпоновки;
Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл
Если ПолеГруппировки.Использование Тогда
ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле);
КонецЕсли;
КонецЦикла;
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура);
Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл
Если ДоступноеПоле.Папка Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЦикла;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(выхНастройкаКомпоновки);
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Отбор);
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Параметры);
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Порядок);
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.УсловноеОформление);
выхНастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
выхСхема = СоздатьСхемуКомпоновкиПоЗапросу(Запрос);
КонецПроцедуры
// Если передана НастройкаКомпоновкиПриемник, то в качестве результата вернется ее копия!
Функция СкопироватьНастройкиКомпоновкиЛкс(НастройкаКомпоновкиИлиДинамическийСписокИсточник, Знач НастройкаКомпоновкиПриемник = Неопределено, КопироватьОтбор = Ложь,
КопироватьПараметры = Ложь, КопироватьПорядок = Ложь, КопироватьУсловноеОформление = Ложь) Экспорт
#Если Сервер И Не Сервер Тогда
НастройкаКомпоновкиИсточник = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновкиПриемник = Неопределено Тогда
НастройкаКомпоновкиПриемник = Новый НастройкиКомпоновкиДанных;
КонецЕсли;
Если ТипЗнч(НастройкаКомпоновкиИлиДинамическийСписокИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда
Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор;
Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыДанных;
УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление;
Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок;
Иначе // ДинамическийСписок
Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор;
Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Параметры;
УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление;
Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок;
КонецЕсли;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновкиПриемник);
Если КопироватьОтбор Тогда
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор);
КонецЕсли;
Если КопироватьПараметры Тогда
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(Параметры);
КонецЕсли;
Если КопироватьПорядок Тогда
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
Если КопироватьУсловноеОформление Тогда
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции // СкопироватьОтборКомпоновкиЛкс()
Функция ПолучитьРасширениеФайловДляОтладкиЛкс() Экспорт
Результат = "deb";
Возврат Результат;
КонецФункции
Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Наименование = "")
Если Не ЗначениеЗаполнено(Наименование) Тогда
Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + СтруктураПараметров.Объект;
КонецЕсли;
Успех = Ложь;
ДоступноФоновоеЗадание = Не (Истина
И ТранзакцияАктивна()
И ирКэш.ЭтоФайловаяБазаЛкс()
// В файловой базе даже 8.3 не получится, т.к. там не истинной параллельности
//И (Ложь
// Или РежимСовместимостиМеньше8_3_4Лкс()
// Или ирКэш.ЭтоФоновоеЗаданиеЛкс())
);
Если Истина
И Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено
И ДоступноФоновоеЗадание
Тогда
Попытка
ХранимоеЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров);
ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент();
ОбъектДляОтладки.Наименование = Наименование;
ОбъектДляОтладки.XML = ХранимоеЗначение;
выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки);
Успех = Истина;
Исключение
Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки();
КонецПопытки;
Если Успех Тогда
Результат = "Данные помещены в справочник ""Объекты для отладки"". Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")";
КонецЕсли;
Иначе
//выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор);
//Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
//+ " Адрес """ + выхОбъектДляОтладки + """";
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Успех = Ложь;
Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
РасширениеФайловДляОтладки = ПолучитьРасширениеФайловДляОтладкиЛкс();
Платформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
Платформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
Наименование = Платформа.ПолучитьИдентификаторИзПредставления(Наименование);
ИмяФайла = КаталогОбъектовДляОтладки + "\" + Наименование + "." + РасширениеФайловДляОтладки;
ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла);
Попытка
СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя);
Успех = Истина;
Исключение
Сообщить("Ошибка сохранения файла для отладки: " + ОписаниеОшибки());
КонецПопытки;
Если Успех Тогда
выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя;
Результат = "Данные помещены в файл. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Файл """ + выхОбъектДляОтладки + """";
КонецЕсли;
Иначе
ТекстРекомендации = "Рекомендуется в общих настройках инструментов задать каталог объектов для отладки.";
Сообщить(ТекстРекомендации);
КонецЕсли;
Если Не Успех Тогда
Если ТранзакцияАктивна() И Не ДоступноФоновоеЗадание Тогда
Попытка
ОтменитьТранзакцию();
Успех = Истина;
Исключение
// Системная транзакция записи объекта
КонецПопытки;
Если Не Успех Тогда
Результат = "Невозможно отменить транзакцию записи объекта для сохранения объекта для отладки в общие настройки. " + ТекстРекомендации;
Иначе
Сообщить("Транзакция была отменена для сохранения объекта для отладки в общие настройки");
КонецЕсли;
Иначе
Успех = Истина;
КонецЕсли;
Если Успех Тогда
Успех = Ложь;
Попытка
КлючНастройки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураПараметров);
Успех = Истина;
Исключение
Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Если Успех Тогда
Результат = "Данные помещены в настройку """ + КлючНастройки + """. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Пользователь """ + ИмяПользователя() + """";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СоздаваемыеВременныеТаблицыПакетаЛкс(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе = Ложь) Экспорт
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
МассивТаблиц = мПлатформа.ПолучитьМассивСоздаваемыхВременныхТаблицПакета(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе);
Возврат МассивТаблиц;
КонецФункции
// Подставляет параметры в строку. Максимально возможное число параметров - 9.
// Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы.
//
// Параметры:
// СтрокаПодстановки - Строка - шаблон строки с параметрами (вхождениями вида "%ИмяПараметра");
// Параметр<n> - Строка - подставляемый параметр.
//
// Возвращаемое значение:
// Строка - текстовая строка с подставленными параметрами.
//
// Пример:
// ПодставитьПараметрыВСтроку(НСтр("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];
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ЗначениеПоля = ТекущиеЗначенияПолей.Найти(ИмяПоля);
ИмяСвойства = СтрЗаменить(ИмяПоля, ".", "");
Если Истина
И ЗначениеПоля <> Неопределено
И Не СтруктураПолей.Свойство(ИмяСвойства)
Тогда
СтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение);
Если СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда
Результат = Истина;
Прервать
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Не Результат Тогда
РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей();
Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл
Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, СтруктураПолей);
Если Результат Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьСоединениеСУБД(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяСервера) Тогда
ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс();
ИмяСервера = ПараметрыСоединения.ИмяСервера;
ИмяБД = ПараметрыСоединения.ИмяБД;
ИмяПользователя = ПараметрыСоединения.ИмяПользователя;
Пароль = ПараметрыСоединения.Пароль;
КонецЕсли;
КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
ИсточникДанных = КонсольЗапросов.ПолучитьСтруктуруИсточникаДанныхADO();
ИсточникДанных.Платформа = 11; // ADO-SQLOLEDB
ИсточникДанных.БазаСервер = ИмяСервера;
ИсточникДанных.БазаИмя = ИмяБД;
ИсточникДанных.АутентификацияОС = Не ЗначениеЗаполнено(ИмяПользователя);
ИсточникДанных.Пользователь = ИмяПользователя;
ИсточникДанных.Пароль = Пароль;
СоединениеADO = Неопределено;
ОшибкиПодключения = Неопределено;
Если Не КонсольЗапросов.ConnectADO(ИсточникДанных, СоединениеADO,, ОшибкиПодключения) Тогда
СообщениеОбОшибке = "Ошибки подключения к серверу MSSQL:";
Для каждого ОшибкаПодключения Из ОшибкиПодключения Цикл
СообщениеОбОшибке = СообщениеОбОшибке + Символы.ПС + ОшибкаПодключения;
КонецЦикла;
Сообщить(СообщениеОбОшибке);
СоединениеADO = Неопределено;
КонецЕсли;
Возврат СоединениеADO;
КонецФункции
Функция ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ИмяЗапроса = "Запрос для отладки", Параметры = Неопределено, Автоподключение = Ложь) Экспорт
КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если Сервер И Не Сервер Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
КонсольЗапросов.ОткрытьЗапросБД(ТекстЗапроса, ИмяЗапроса, Параметры, Автоподключение);
КонецФункции
Функция HTTPСоединение(ИмяСервера) Экспорт
Попытка
Результат = Новый HTTPСоединение(ИмяСервера);
Исключение
// Антибаг платформы https://bugboard.v8.1c.ru/error/000013833.html
Результат = Новый HTTPСоединение(ИмяСервера,,,, Новый ИнтернетПрокси(Ложь));
КонецПопытки;
Возврат Результат;
КонецФункции
Процедура ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(ИмяФайлаВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляТекущейВнешнейОбработки, ДатаИзмененияВнешнейОбработки, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(ИмяФайлаВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляТекущейВнешнейОбработки, ДатаИзмененияВнешнейОбработки);
Иначе
мПлатформа = ирКэш.Получить();
#Если Сервер И Не Сервер Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс();
Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда
Сообщить("В общих настройках инструментов не задан каталог объектов для отладки! Сохранение внешней обработки не выполнено.", СтатусСообщения.Внимание);
Возврат;
КонецЕсли;
ИмяФайлаВнешнейОбработки = КаталогОбъектовДляОтладки + "\" + ИмяВнешнейОбработки + ".epf";
ФайлВнешнейОбработки = Новый Файл(ИмяФайлаВнешнейОбработки);
Если Ложь
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() > ДатаИзмененияВнешнейОбработки
И мПлатформа.ФайловыйКэшАлгоритмовДопускаетРедактирование)
Или (Истина
И ФайлВнешнейОбработки.Существует()
И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() = ДатаИзмененияВнешнейОбработки
И ТекстМодуляТекущейВнешнейОбработки = ТекстМодуля)
Тогда
Возврат;
КонецЕсли;
мПлатформа.СформироватьВнешнююОбработку(ИмяВнешнейОбработки, ФайлВнешнейОбработки, ТекстМодуля);
ДатаИзмененияВнешнейОбработки = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
КонецЕсли;
КонецПроцедуры
Процедура ЗаписатьДокументDOMВФайлЛкс(Знач ДокументДом, Знач ИмяФайла) Экспорт
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьДом = Новый ЗаписьDOM;
ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
ЗаписьXML.Закрыть();
КонецПроцедуры
Функция ПрочитатьФайлВДокументDOMЛкс(Знач ИмяФайла, ИгнорироватьПробельныеСимволы = Ложь) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы);
ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
ПостроительДом = Новый ПостроительDOM();
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
Возврат ДокументДОМ;
КонецФункции
Функция ПрочитатьТекстВДокументDOMЛкс(Знач Текст, ИгнорироватьПробельныеСимволы = Ложь) Экспорт
ЧтениеXML = Новый ЧтениеXML;
ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы);
ЧтениеXML.УстановитьСтроку(Текст, ПараметрыЧтения);
ПостроительDOM = Новый ПостроительDOM;
ДокументДом = ПостроительDOM.Прочитать(ЧтениеXML);
Возврат ДокументДом;
КонецФункции
Функция ПолучитьДокументDOMИзСтрокиВнутрЛкс(ТекстФайла, ИгнорироватьПробельныеСимволы = Истина) Экспорт
XMLСтрока = СтрокаВнутрВХМЛТелоЛкс(ТекстФайла);
ДокументDOM = ПрочитатьТекстВДокументDOMЛкс(XMLСтрока, ИгнорироватьПробельныеСимволы);
Возврат ДокументDOM;
КонецФункции
Функция АдаптироватьРасширениеЛкс(ТолькоПриНаличииПодключенныхКоманд = Ложь) Экспорт
#Если ТонкийКлиент Или ВебКлиент Тогда
Результат = ирСервер.АдаптироватьРасширениеЛкс();
Возврат Результат;
#КонецЕсли
ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс());
Если ТолькоПриНаличииПодключенныхКоманд Тогда
ЕстьПодключенныеКоманды = Ложь;
Если ПометкиКоманд <> Неопределено Тогда
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
Если КлючИЗначение.Значение = Истина Тогда
ЕстьПодключенныеКоманды = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Не ЕстьПодключенныеКоманды Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
ЭтотРасширение = ирКэш.ЭтотРасширениеКонфигурацииЛкс();
#Если Сервер И Не Сервер Тогда
ЭтотРасширение = РасширенияКонфигурации.Создать();
#КонецЕсли
ИмяРасширения = ЭтотРасширение.Имя;
ТипВсеСсылки = ирОбщий.ПолучитьОписаниеТиповВсеСсылкиЛкс();
ТипВсеПланыОбмена = ПланыОбмена.ТипВсеСсылки();
ТекстовыйДокумент = Новый ТекстовыйДокумент;
КаталогВыгрузкиРасширения = ПолучитьИмяВременногоФайла();
ИмяФайлаСпискаВыгрузкиРасширения = ПолучитьИмяВременногоФайла("txt");
// Сначала выгружаем из конфигурации все ссылочные метаданные
//ТекстСпискаОбъектовКонфигурации = Метаданные.ПолноеИмя();
ТекстСпискаОбъектовКонфигурации = "";
СписокДобавляемыхТипов = Новый Массив;
Для Каждого Тип Из ТипВсеСсылки.Типы() Цикл
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя();
КонецЦикла;
ТекстСпискаОбъектовКонфигурации = Сред(ТекстСпискаОбъектовКонфигурации, 2); // !
ИмяФайлаСпискаВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла("txt");
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовКонфигурации);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиКонфигурации);
КаталогВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла();
СоздатьКаталог(КаталогВыгрузкиКонфигурации);
ТекстЛога = "";
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиКонфигурации + """ -listFile """ + ИмяФайлаСпискаВыгрузкиКонфигурации + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка конфигурации в файлы");
УдалитьФайлы(ИмяФайлаСпискаВыгрузкиРасширения);
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиКонфигурации);
Сообщить(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Выгружаем объекты из расширения
ТекстЛога = "";
СоздатьКаталог(КаталогВыгрузкиРасширения);
ТекстСпискаОбъектовРасширения = "Конфигурация." + ИмяРасширения;
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "ОбщаяКоманда." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовРасширения);
ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы");
Если Не Успех Тогда
УдалитьФайлы(КаталогВыгрузкиРасширения);
Сообщить(ТекстЛога);
Возврат Ложь;
КонецЕсли;
// Добавим ссылочные объекты в расширение
ИмяФайла = КаталогВыгрузкиРасширения + "\Configuration.xml";
ОписаниеРасширения = Новый ТекстовыйДокумент;
ОписаниеРасширения.Прочитать(ИмяФайла);
ОписаниеРасширения = ОписаниеРасширения.ПолучитьТекст();
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
//ЧтениеXML = Новый ЧтениеXML;
//ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, Ложь);
//ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
//ПостроительДом = Новый ПостроительDOM();
//ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
//ЧтениеXML.Закрыть();
УзелТиповСпискаОбъектов = ДокументДом.ПолучитьЭлементыПоИмени("ChildObjects");
УзелТиповСпискаОбъектов = УзелТиповСпискаОбъектов[0];
СписокДобавляемыхТипов = Новый Массив;
Для Каждого Тип Из ТипВсеСсылки.Типы() Цикл
XMLИмяТипа = XMLТип(Тип).ИмяТипа;
Если Найти(XMLИмяТипа, "RoutePointRef.") > 0 Тогда
Продолжить;
КонецЕсли;
XMLТипМетаданного = ирОбщий.ПолучитьПервыйФрагментЛкс(XMLИмяТипа, "Ref.");
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя();
Если Найти(ОписаниеРасширения, "<" + XMLТипМетаданного + ">" + ОбъектМД.Имя + "<") > 0 Тогда
Продолжить;
КонецЕсли;
СписокДобавляемыхТипов.Добавить(Тип);
УзелОбъекта = ДокументДом.СоздатьЭлемент(XMLТипМетаданного);
УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя;
УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта);
КонецЦикла;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
//ЗаписьXML = Новый ЗаписьXML;
//ЗаписьXML.ОткрытьФайл(ИмяФайла);
//ЗаписьДом = Новый ЗаписьDOM;
//ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
//ЗаписьXML.Закрыть();
// Перенесем объекты метаданных из конфигурации в расширение
Для Каждого Тип Из СписокДобавляемыхТипов Цикл
XMLИмяТипа = XMLТип(Тип).ИмяТипа;
Если Найти(XMLИмяТипа, "RoutePointRef.") > 0 Тогда
Продолжить;
КонецЕсли;
ПолноеИмяМДXML = СтрЗаменить(XMLИмяТипа, "Ref.", ".");
ИмяКлассаМДXML = ПолучитьПервыйФрагментЛкс(ПолноеИмяМДXML);
ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ПолноеИмяМДXML + ".xml");
ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя);
//ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя);
ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя);
ТекстФайла = ТекстовыйДокумент.ПолучитьТекст();
ЧтоЗаменять = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстФайла, "<Properties>", "</" + ИмяКлассаМДXML + ">",, Истина);
НаЧтоЗаменять =
" <Properties>
| <Name>" + ирОбщий.ПолучитьПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + "</Name>
| <ObjectBelonging>Adopted</ObjectBelonging>
| </Properties>
| <ChildObjects/>
| </" + ИмяКлассаМДXML + ">";
ТекстФайла = СтрЗаменить(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ЧтоЗаменять = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">",, Истина);
НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>";
ТекстФайла = СтрЗаменить(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять);
ТекстовыйДокумент.УстановитьТекст(ТекстФайла);
ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя);
КонецЦикла;
// Добавим типы ссылочных объектов в общие команды
#Если Сервер И Не Сервер Тогда
ТипВсеСсылки = Новый ОписаниеТипов;
#КонецЕсли
Для Каждого КлючИЗначение Из ПометкиКоманд Цикл
ИмяКоманды = КлючИЗначение.Ключ;
ИмяФайла = КаталогВыгрузкиРасширения + "\CommonCommand." + ИмяКоманды + ".xml";
ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла);
//ЧтениеXML = Новый ЧтениеXML;
//ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, Ложь);
//ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения);
//ПостроительДом = Новый ПостроительDOM();
//ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML);
//ЧтениеXML.Закрыть();
УзелТиповПараметра = ДокументДом.ПолучитьЭлементыПоИмени("CommandParameterType");
УзелТиповПараметра = УзелТиповПараметра[0];
Пока УзелТиповПараметра.ДочерниеУзлы.Количество() > 0 Цикл
УзелТиповПараметра.УдалитьДочерний(УзелТиповПараметра.ПервыйДочерний);
КонецЦикла;
Если КлючИЗначение.Значение Тогда
Если ИмяКоманды = Метаданные.ОбщиеКоманды.ирРедактироватьИзмененияНаУзле.Имя Тогда
ТипыПараметра = ТипВсеПланыОбмена.Типы();
Иначе
ТипыПараметра = ТипВсеСсылки.Типы();
КонецЕсли;
Для Каждого Тип Из ТипыПараметра Цикл
УзелТипа = ДокументДом.СоздатьЭлемент("v8:Type"); // http://v8.1c.ru/8.1/data/core
УзелТипа.ТекстовоеСодержимое = "cfg:" + XMLТип(Тип).ИмяТипа; // http://v8.1c.ru/8.1/data/enterprise/current-config
УзелТиповПараметра.ДобавитьДочерний(УзелТипа);
КонецЦикла;
КонецЕсли;
ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла);
//ЗаписьXML = Новый ЗаписьXML;
//ЗаписьXML.ОткрытьФайл(ИмяФайла);
//ЗаписьДом = Новый ЗаписьDOM;
//ЗаписьДом.Записать(ДокументДом, ЗаписьXML);
//ЗаписьXML.Закрыть();
КонецЦикла;
ТекстЛога = "";
// Пришлось отказаться от частичной загрузки из-за непонятной ошибки
// Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации
//ФайлыДляЗагрузки = НайтиФайлы(КаталогВыгрузкиРасширения, "*");
//ТекстовыйДокумент.Очистить();
//Для Каждого Файл Из ФайлыДляЗагрузки Цикл
// ТекстовыйДокумент.ДобавитьСтроку(Файл.ПолноеИмя);
//КонецЦикла;
//ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения);
//Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain",
// СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,, "Загрузка расширения из файлов");
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain",
СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Загрузка расширения из файлов");
УдалитьФайлы(КаталогВыгрузкиРасширения);
Если Не Успех Тогда
Сообщить(ТекстЛога);
КонецЕсли;
// Почему то без этого расширение не применялось (оставалась активной кнопка "Обновить конфигурацию БД"
//ЭтотРасширение.Записать();
КонечныйФайл = ПолучитьИмяВременногоФайла();
Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpCfg """ + КонечныйФайл + """ -Extension """ + ИмяРасширения + """", СтрокаСоединенияИнформационнойБазы(), ТекстЛога);
Если Не Успех Тогда
Сообщить(ТекстЛога);
Возврат Ложь;
КонецЕсли;
ЭтотРасширение.Записать(Новый ДвоичныеДанные(КонечныйФайл));
Возврат Истина;
КонецФункции
Функция ПредставлениеКлючаСтрокиБДЛкс(Знач КлючСтроки, ПолучатьПредставленияСсылок = Истина) Экспорт
Если ЛиКлючЗаписиРегистраЛкс(КлючСтроки) Тогда
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(Метаданные.НайтиПоТипу(ТипЗнч(КлючСтроки)).ПолноеИмя(),, Ложь);
ПредставленияКлюча = "";
Для Каждого ЭлементСписка Из СтруктураКлюча Цикл
Если ПредставленияКлюча <> "" Тогда
ПредставленияКлюча = ПредставленияКлюча + ", ";
КонецЕсли;
ПредставлениеЗначения = КлючСтроки[ЭлементСписка.Представление];
Если Не ПолучатьПредставленияСсылок И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ПредставлениеЗначения) Тогда
ПредставлениеЗначения = "" + ПредставлениеЗначения.УникальныйИдентификатор();
Иначе
ПредставлениеЗначения = "" + ПредставлениеЗначения;
КонецЕсли;
ПредставленияКлюча = ПредставленияКлюча + ЭлементСписка.Представление + " = " + ПредставлениеЗначения;
КонецЦикла;
Иначе
ПредставленияКлюча = "" + КлючСтроки;
//СтруктураЧтения = Новый Структура("Владелец");
//Попытка
// ЗаполнитьЗначенияСвойств(СтруктураЧтения, КлючСтроки);
//Исключение
// // Нет доступа
//КонецПопытки;
//Если ЗначениеЗаполнено(СтруктураЧтения.Владелец) Тогда
// Если ПолучатьПредставленияСсылок Тогда
// Владелец = Владелец.УникальныйИдентификатор();
// КонецЕсли;
// ПредставленияКлюча = "[" + ПредставлениеКлючаСтрокиБДЛкс(Владелец) + "]" + ПредставленияКлюча;
//КонецЕсли;
КонецЕсли;
Возврат ПредставленияКлюча;
КонецФункции
Функция ПеременныеОкруженияПроцессаЛкс()
Shell = Новый COMОбъект("WScript.Shell");
ПеременныеОкружения = Shell.Environment("PROCESS");
Возврат ПеременныеОкружения;
КонецФункции
Функция КаталогПрограммныхФайловОСЛкс(x64 = Ложь) Экспорт
ПеременныеОкружения = ПеременныеОкруженияПроцессаЛкс();
Если ирКэш.Это64битнаяОСЛкс() Тогда
Если x64 Тогда
ИмяПеременной = "ProgramW6432";
Иначе
ИмяПеременной = "ProgramFiles(x86)";
КонецЕсли;
Иначе
ИмяПеременной = "ProgramFiles";
КонецЕсли;
КаталогПрограммныхФайлов = ПеременныеОкружения.Item(ИмяПеременной);
Возврат КаталогПрограммныхФайлов;
КонецФункции
Функция КаталогПеремещаемыхДанныхПриложенийЛкс() Экспорт
ПеременныеОкружения = ПеременныеОкруженияПроцессаЛкс();
КаталогПеремещаемыхДанныхПриложений = ПеременныеОкружения.Item("Appdata");
Возврат КаталогПеремещаемыхДанныхПриложений;
КонецФункции
Функция ПараметрыСоединенияADOЭтойБДЛкс(выхСтрокаСвойств = "") Экспорт
выхСтрокаСвойств = "ИмяСервера, ИмяБД, ИмяПользователя, Пароль, НаСервере";
ПараметрыСоединения = Новый Структура(выхСтрокаСвойств);
ПараметрыСоединения.ИмяСервера = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяСервера");
ПараметрыСоединения.ИмяБД = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяБД");
ПараметрыСоединения.ИмяПользователя = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяПользователя");
НовыйПароль = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.Пароль");
Если НовыйПароль <> Неопределено Тогда
ПараметрыСоединения.Пароль = НовыйПароль.Получить();
КонецЕсли;
ПараметрыСоединения.НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере");
Возврат ПараметрыСоединения;
КонецФункции
Функция ПроверитьСоединениеADOЭтойБДЛкс(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "", Знач НаСервере = Неопределено, ЗапрашиватьПользователя = Истина) Экспорт
#Если Клиент Тогда
Если ЗапрашиватьПользователя И Не ЗначениеЗаполнено(ИмяСервера) Тогда
ОткрытьФормуСоединенияСУБДЛкс(Истина);
КонецЕсли;
#КонецЕсли
Если НаСервере = Истина Тогда
ЛиСоединениеУстановлено = ирСервер.ПроверитьСоединениеADOЭтойБДЛкс(ИмяСервера, ИмяБД, ИмяПользователя, Пароль);
Иначе
Соединение = ПолучитьСоединениеСУБД(ИмяСервера, ИмяБД, ИмяПользователя, Пароль);
ЛиСоединениеУстановлено = Соединение <> Неопределено;
КонецЕсли;
Возврат ЛиСоединениеУстановлено;
КонецФункции
Функция ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(Знач ТекстЗапроса, Знач РежимОтладки = Ложь, Знач ПредставлениеЗапроса = "", Знач СмещениеГода = 2000, Знач ИспользованиеGWF = Истина,
Знач НаСервере = Неопределено) Экспорт
Если РежимОтладки Тогда
ирОбщий.ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ПредставлениеЗапроса);
Возврат Неопределено;
КонецЕсли;
Если НаСервере = Неопределено Тогда
НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере");
КонецЕсли;
Если НаСервере = Истина Тогда
Таблица = ирСервер.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(ТекстЗапроса, СмещениеГода, ИспользованиеGWF);
Иначе
Соединение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();
Возврат Результат;
КОнецФункции
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент И Клиент Тогда
Функция ЗагрузитьТабличныйДокументИнтерактивноЛкс(Знач ТабличныйДокумент = Неопределено) Экспорт
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла";
ДиалогВыбораФайла.Фильтр = "Табличный документ (*.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 По ТабличныйДокумент.ВысотаТаблицы Цикл
ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка);
ОбластьЯчейки.СодержитЗначение = Истина;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ОткрытьОднократноАдаптациюРасширенияЛкс() Экспорт
ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс());
Если ПометкиКоманд = Неопределено Тогда
ПометкиКоманд = Новый Структура;
ХранилищеОбщихНастроек.Сохранить(, "ирАдаптацияРасширения.ПометкиКоманд", ПометкиКоманд,, ирОбщий.ИмяПродуктаЛкс());
ОткрытьФормуМодально("ОбщаяФорма.ирАдаптацияРасширения", Новый Структура("Автооткрытие", Истина));
КонецЕсли;
КонецПроцедуры
Функция ПодтверждениеОперацииСУБДЛкс() Экспорт
Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы и нарушение лицензионного соглашения 1С?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да;
КонецФункции
// РежимИмяСиноним - Булево - Истина - Имя
Процедура НастроитьАвтоТабличноеПолеДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним = Ложь, РазрешитьСортировку = Истина) Экспорт
// Антибаг платформы 8.2-8.3 для регистра бухгалтерии https://partners.v8.1c.ru/forum/t/1372055/m/1372055
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ);
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ДинамическийСписок));
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ПолноеИмяТаблицы = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
КорневойТип = ирОбщий.ПолучитьПервыйФрагментЛкс(ПолноеИмяМД);
//СтруктураХраненияПолей = ирКэш.ПолучитьСтруктуруХраненияБДЛкс().НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ПолноеИмяМД);
СтруктураХраненияТаблицы = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0];
СтруктураХраненияПолей = СтруктураХраненияТаблицы.Поля;
ВерсияПлатформы = ирКэш.НомерВерсииПлатформыЛкс();
Если КорневойТип <> "РегистрБухгалтерии" Тогда
ОсновнойЭУ.СоздатьКолонки();
КонецЕсли;
Попытка
КолонкиСписка = ОсновнойЭУ.Значение.Колонки;
Исключение
// Перечисление
КонецПопытки;
КолонкиТП = ОсновнойЭУ.Колонки;
Колонка = КолонкиТП.Найти("Картинка");
Если Колонка = Неопределено Тогда
КолонкаКартинки = КолонкиТП.Добавить("Картинка");
КолонкаКартинки.ОтображатьСтандартнуюКартинку = Истина;
КолонкаКартинки.Ширина = 3;
КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КолонкаКартинки.ТекстШапки = "";
КонецЕсли;
Попытка
НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка;
Исключение
НастройкаПорядка = Неопределено;
КонецПопытки;
Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл
Колонка = КолонкиТП.Найти(ЭлементОтбора.Имя);
Если Колонка = Неопределено Тогда
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1002521#1002521
Если Ложь
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоДт") = 1
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоКт") = 1
Тогда
Продолжить;
КонецЕсли;
Попытка
КолонкиСписка.Добавить(ЭлементОтбора.Имя, Ложь);
Исключение
// Сюда попадает например элемент отбора от критерия отбора
Продолжить;
КонецПопытки;
Колонка = КолонкиТП.Добавить();
КонецЕсли;
//Колонка.ТекстШапки = ЭлементОтбора.Представление;
Если КорневойТип <> "Перечисление" Тогда
ДанныеПодключены = Ложь;
Если Истина
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Булево"))
И ЭлементОтбора.ТипЗначения.Типы().Количество() = 1
Тогда
Колонка.УстановитьЭлементУправления(Тип("Флажок"));
Попытка
Колонка.ДанныеФлажка = ЭлементОтбора.Имя;
ДанныеПодключены = Истина;
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
Иначе
Колонка.УстановитьЭлементУправления(Тип("ПолеВвода"));
Попытка
Колонка.Данные = ЭлементОтбора.Имя;
ДанныеПодключены = Истина;
Исключение
ОписаниеОшибки = ОписаниеОшибки(); // Для отладки
КонецПопытки;
КонецЕсли;
Если Не ДанныеПодключены Тогда
Колонка.Видимость = Ложь;
КонецЕсли;
КонецЕсли;
// Закомментировал 13.02.2011
//Если ЗначениеЗаполнено(Колонка.Данные) Тогда
// Колонка.Имя = Колонка.Данные;
//КонецЕсли;
Колонка.Имя = ЭлементОтбора.Имя;
СтрокаСтрукутрыПоля = СтруктураХраненияПолей.Найти(ЭлементОтбора.Имя, "ИмяПоля");
Если СтрокаСтрукутрыПоля <> Неопределено Тогда
МетаданныеПоля = СтрокаСтрукутрыПоля.Метаданные;
Если ЗначениеЗаполнено(МетаданныеПоля) Тогда
МетаданныеПоля = Метаданные.НайтиПоПолномуИмени(МетаданныеПоля);
КонецЕсли;
Попытка
Колонка.ПодсказкаВШапке = МетаданныеПоля.Подсказка;
Исключение
// У графы журнала нет подсказки
КонецПопытки;
КонецЕсли;
// Антибаг платформы 8.2-8.3.6 https://partners.v8.1c.ru/forum/t/1337995/m/1337995
Если Истина
И ВерсияПлатформы < 803008
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))
Тогда
Сообщить("Колонка """ + ЭлементОтбора.Имя + """ типа УникальныйИдентификатор не будет отображаться из-за ошибки платформы");
КолонкиТП.Удалить(Колонка);
Продолжить;
КонецЕсли;
Если РазрешитьСортировку И НастройкаПорядка <> Неопределено Тогда
ЭлементУправленияПорядком = НастройкаПорядка.Найти(ЭлементОтбора.Имя);
Если ЭлементУправленияПорядком <> Неопределено Тогда
ЭлементУправленияПорядком.Доступность = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если КолонкиСписка <> Неопределено Тогда
Для Каждого ЭлементНастройкиОтбора Из ОсновнойЭУ.НастройкаОтбора Цикл
ЭлементНастройкиОтбора.Доступность = Истина;
КонецЦикла;
НовыйПорядок = ирОбщий.ПолучитьСтрокуПорядкаЛкс(ДинамическийСписок.Порядок);
Если Не ЗначениеЗаполнено(НовыйПорядок) Тогда
НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка;
ПредопределенныеПоля = Новый Массив();
Если ТипТаблицы = "ПланСчетов" Тогда
ПредопределенныеПоля.Добавить("Код");
КонецЕсли;
ПредопределенныеПоля.Добавить("Наименование");
ПредопределенныеПоля.Добавить("Дата");
ПредопределенныеПоля.Добавить("Период");
ПредопределенныеПоля.Добавить("ДатаИзменения");
ПредопределенныеПоля.Добавить("ДатаСоздания");
ПредопределенныеПоля.Добавить("Номер");
ПредопределенныеПоля.Добавить("Код");
Для Каждого ПредопределенноеПоле Из ПредопределенныеПоля Цикл
ЭлементПорядка = НастройкаПорядка.Найти(ПредопределенноеПоле);
Если ЭлементПорядка <> Неопределено Тогда
Для Каждого ИндексТаблицыБД Из СтруктураХраненияТаблицы.Индексы Цикл
Если ИндексТаблицыБД.Поля[0].ИмяПоля = ПредопределенноеПоле Тогда
ЭлементПорядка.Доступность = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ЭлементПорядка.Доступность Тогда
НовыйПорядок = ПредопределенноеПоле;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЗначениеЗаполнено(НовыйПорядок) Тогда
// Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки (антибаг платформы)
ДинамическийСписок.Порядок.Установить(НовыйПорядок);
КонецЕсли;
//Компоновщик = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ОбъектМД.ПолноеИмя());
//#Если Сервер И Не Сервер Тогда
// Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
//#КонецЕсли
//Для Каждого ПолеВыбора Из Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл
// Если ПолеВыбора.Папка Тогда
// Продолжить;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда
КолонкаИдентификатора = КолонкиТП.Добавить("ИдентификаторСсылкиЛкс");
КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки";
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
КолонкаИдентификатора = КолонкиТП.Добавить("ИмяПредопределенныхДанных");
КолонкаИдентификатора.ТекстШапки = "Имя предопределенных данных";
КолонкаИдентификатора.Видимость = Ложь;
КонецЕсли;
НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним);
КонецПроцедуры
Процедура НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение));
ПоляТаблицы = ПолучитьПоляТаблицыМДЛкс(ОбъектМД.ПолноеИмя());
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
Колонка = ОсновнойЭУ.Колонки.Найти(ПолеТаблицы.Имя);
Если Колонка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Колонка.ТекстШапки = ПолеТаблицы.Имя;
Иначе
Колонка.ТекстШапки = ПолеТаблицы.Заголовок;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка()
Процедура ФормаОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт
Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть();
Если ЭтаФорма.Открыта() Тогда
Параметр.Отказ = Истина;
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
Параметр.Ответ = Истина;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда
Попытка
Сообщить(ЭтаФорма.Имя);
Исключение
Попытка
Сообщить(ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя());
Исключение
Сообщить("Неизвестная форма");
КонецПопытки;
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт
СтандартнаяОбработка = Ложь;
Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЗапуститьПриложение(ИмяФайла);
КонецЕсли;
КонецПроцедуры
// Создает новый экземпляр обработки и открывает его форму.
//
// Параметры:
// Объект - ОбработкаОбъект, ОтчетОбъект.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьНовоеОкноОбработкиЛкс(ЭтотОбъект) Экспорт
Если ТипЗнч(ЭтотОбъект) = Тип("УправляемаяФорма") Тогда
Результат = ПолучитьФормуЛкс(ЭтотОбъект.ИмяФормы,,, Новый УникальныйИдентификатор);
Иначе
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать();
Иначе
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя();
НовыйОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбъекта);
КонецЕсли;
Результат = НовыйОбъект.ПолучитьФорму();
КонецЕсли;
Результат.Открыть();
Возврат Результат;
КонецФункции // ОткрытьНовоеОкноОбработкиЛкс()
Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено, ТолькоВнешниеФормы = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
//ирПортативный #Если Сервер И Не Сервер Тогда
// Такой прием нужен для обхода ошибка компиляции в портативном режиме
Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
//ирПортативный #КонецЕсли
Иначе
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяФормы);
Если Не ТолькоВнешниеФормы Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]);
КонецЕсли;
Если ОбъектМД = Неопределено Тогда
ТипМетаданных = Фрагменты[0];
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных);
Если Истина
И СтрокиРавныЛкс(Фрагменты[2], "Форма")
И Фрагменты.Количество() = 4
Тогда
ИмяФормы = Фрагменты[3];
Иначе
ИмяФормы = Неопределено;
КонецЕсли;
Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность);
Иначе
Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОткрытьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт
Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
Форма.Открыть();
Возврат Форма;
КонецФункции
Функция ПолучитьЦветСтиляЛкс(ИмяЦвета) Экспорт
//Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя);
Если ИмяЦвета = "ирТекстИнформационнойНадписи" Тогда
Возврат Новый Цвет(83, 106, 194);
ИначеЕсли ИмяЦвета = "ирЦветФонаЧередованияСтрок" Тогда
Возврат WebЦвета.МятныйКрем;
ИначеЕсли ИмяЦвета = "ирЦветФонаВычисляемогоЗначения" Тогда
Возврат WebЦвета.ГолубойСКраснымОттенком;
ИначеЕсли ИмяЦвета = "ирЦветФонаОшибки" Тогда
Возврат Новый Цвет(255, 245, 245);
ИначеЕсли ИмяЦвета = "ирЦветФонаРасширенногоПредставленияЗначения" Тогда
Возврат Новый Цвет(255, 255, 180);
Иначе
Результат = ЦветаСтиля[ИмяЦвета];
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Значение -
// ОчиститьПередУстановкой - Булево
// УстановитьТекст - Булево
// УстановитьЗначение - Булево
//
Функция БуферОбмена_УстановитьЗначениеЛкс(Знач Значение = "", Знач ОчиститьПередУстановкой = Истина, Знач УстановитьТекст = Истина, Знач УстановитьЗначение = Истина) Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
Если ОчиститьПередУстановкой Тогда
WinAPI.OpenClipboard(0);
WinAPI.EmptyClipboard();
WinAPI.CloseClipboard();
КонецЕсли;
CF_TEXT = 1;
CF_UNICODETEXT = 13;
CF_OEMTEXT = 7;
Если УстановитьЗначение Тогда
ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс();
ВнутреннееЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение,,, Ложь);
БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, ФорматБуфераОбмена1С);
КонецЕсли;
Если УстановитьТекст Тогда
ВнутреннееЗначение = "" + Значение; // Может тормозить из-за обращений к БД
Если ВнутреннееЗначение <> "" Тогда
БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, CF_UNICODETEXT);
КонецЕсли;
КонецЕсли;
КонецФункции
// Параметры:
// ВнутреннееЗначение -
// ФорматЗначения - Число(0,0) - CF_TEXT = 1;
// ПомещатьВКодировкеUTF8 - Булево - Иначе используется UNICODE
//
Функция БуферОбмена_УстановитьДанныеПоФорматуЛкс(Знач ВнутреннееЗначение, Знач ФорматЗначения = 1, Знач ПомещатьВКодировкеUTF8 = Ложь) Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
ВнутреннееЗначение = "" + ВнутреннееЗначение;
КоличествоСимволов = СтрДлина(ВнутреннееЗначение);
ПромежуточныйТекст = WinAPI.StrPtr(ВнутреннееЗначение, "s");
GMEM_DDESHARE = 8192; // &H2000;
Дескриптор = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 2);
Указатель = WinAPI.GlobalLock(Дескриптор);
WinAPI.MultiByteToWideChar(0, 0, ПромежуточныйТекст, -1, Указатель, КоличествоСимволов + 1);
Если ПомещатьВКодировкеUTF8 Тогда
Дескриптор2 = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 1);
Указатель2 = WinAPI.GlobalLock(Дескриптор2);
CP_UTF8 = 65001; // UTF-8 translation
WinAPI.WideCharToMultiByte(CP_UTF8, 0, Указатель, -1, Указатель2, КоличествоСимволов + 1);
WinAPI.GlobalUnlock(Дескриптор);
Указатель = Указатель2;
Дескриптор = Указатель2;
КонецЕсли;
WinAPI.OpenClipboard(0);
WinAPI.SetClipboardData(ФорматЗначения, Дескриптор);
WinAPI.CloseClipboard();
WinAPI.GlobalUnlock(Дескриптор);
КонецФункции
// Параметры:
// ФорматЗначения - Число(0,0) - CF_TEXT = 1;
// Кодировка - Строка(0,П) - w (по умолчанию), s, z. Значения s и z нужны для чтения строки в ANSI- или OEM-кодировке, при этом она конвертируется в Юникод
//
Функция БуферОбменаолучитьДанныеПоФорматуЛкс(Знач ФорматЗначения = 1, Знач Кодировка = "w") Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
WinAPI.OpenClipboard(0);
Дескриптор = WinAPI.GetClipboardData(ФорматЗначения);
Если Дескриптор <> 0 Тогда
Указатель = WinAPI.GlobalLock(Дескриптор);
Результат = WinAPI.StrGet(Указатель, Кодировка);
WinAPI.GlobalUnlock(Дескриптор);
Иначе
Результат = "";
КонецЕсли;
WinAPI.CloseClipboard();
Возврат Результат;
КонецФункции
Функция БуферОбменаолучитьЗначениеЛкс() Экспорт
ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс();
СтрокаXML = БуферОбменаолучитьДанныеПоФорматуЛксорматБуфераОбмена1С);
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXML,,, Ложь);
Возврат Результат;
КонецФункции
Функция БуферОбменаолучитьТекстЛкс() Экспорт
CF_UNICODETEXT = 13;
Результат = БуферОбменаолучитьДанныеПоФорматуЛкс(CF_UNICODETEXT);
Возврат Результат;
КонецФункции
// Параметры:
// ПолеВвода - ПолеВвода
// Значение -
// Текст - Строка(0,П)
//
Функция ВставитьЗначениеВПолеВводаЛкс(Знач ПолеВвода, Знач Значение, Знач Текст = "") Экспорт
Результат = Ложь;
Если Истина
И Значение <> Неопределено
И Не ПолеВвода.ТолькоПросмотр
Тогда
ТипНовогоЗначения = ТипЗнч(Значение);
Если Ложь
Или ТипЗнч(ПолеВвода.Значение) = ТипНовогоЗначения
Или ПолеВвода.ОграничениеТипа.Типы().Количество() = 0
Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения)
Тогда
Результат = ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, Значение);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка
// Кнопка - КнопкаКоманднойПанели
// СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром.
// ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма
//
Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Текст = БуферОбменаолучитьТекстЛкс();
Значение = БуферОбменаолучитьЗначениеЛкс();
ПродолжитьОбработку = Истина;
ТипЗначения = ТипЗнч(Значение);
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Если Не ЭтаФорма.ТолькоПросмотр Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение, Текст);
Если ПродолжитьОбработку И ЗначениеЗаполнено(ТекущийЭлементФормы.Данные) Тогда
// Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
Попытка
ЭтаФорма[ТекущийЭлементФормы.Данные] = Значение;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
Попытка
РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге;
Исключение
РедактированиеВДиалоге = Ложь;
КонецПопытки;
Если Истина
И Не РедактированиеВДиалоге
И Не ЭтаФорма.ТолькоПросмотр
И Не ТекущийЭлементФормы.ТолькоПросмотр
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
ДобавитьСтроку = Истина
И ТекущийЭлементФормы.ТекущиеДанные = Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок;
Если Истина
И Значение <> Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок
И Не ДобавитьСтроку
Тогда
Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет,
, КодВозвратаДиалога.Нет);
ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ДобавитьСтроку Тогда
ИмяТекущейКолонки = ТекущийЭлементФормы.ТекущаяКолонка.Имя;
ТекущийЭлементФормы.ДобавитьСтроку();
ТекущийЭлементФормы.ТекущаяКолонка = ТекущийЭлементФормы.Колонки[ИмяТекущейКолонки];
КонецЕсли;
Если ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда
ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строку при вызове команды и иногда установке текущей колонки
КонецЕсли;
Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда
ПолеВвода = ТекущийЭлементФормы.ТекущаяКолонка.ЭлементУправления;
Если ТипЗнч(ПолеВвода) = Тип("ПолеВвода") Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ПолеВвода, Значение, Текст);
ИмяКолонкиДанных = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы);
Если ПродолжитьОбработку И ЗначениеЗаполнено(ИмяКолонкиДанных) Тогда
// Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора
Если ТипЗнч(ТекущийЭлементФормы.ТекущиеДанные) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ИмяКолонкиДанных = ПолучитьПервыйФрагментЛкс(ИмяКолонкиДанных, "Для");
КонецЕсли;
Попытка
ТекущийЭлементФормы.ТекущиеДанные[ИмяКолонкиДанных] = Значение;
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПродолжитьОбработку Тогда
мПлатформа = ирКэш.Получить();
мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш);
Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
//ирПлатформа.WshShell.SendKeys("^v^м", 20); //англ.v,русс
WinAPI = ирКэш.ПолучитьWinAPI();
ДескрипторОкнаФокуса = WinAPI.GetActiveWindow();
WinAPI.EnableWindow(ДескрипторОкнаФокуса);
WM_KEYDOWN = 256; //0x0100
WM_KEYUP = 257; //0x0101
WM_COPY = 757; //0x0301
WM_CHAR = 258; //0x0102
WM_PASTE = 758; //0x0302
WM_GETTEXT = 13; //0x000D
VK_CONTROL = 17; // CTRL
KEY_V = 86; // V
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1);
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_V, 1);
Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1);
КонецЕсли;
Если WinAPI.GetAsyncKeyState(KEY_V) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_V, 1);
КонецЕсли;
ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина);
КонецЕсли;
КонецФункции
// Параметры:
// ЭтаФорма - Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма
// НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка
// Кнопка - КнопкаКоманднойПанели
// СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром.
// ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма
//
Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Значение = ТекущийЭлементФормы.Значение;
//Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = Неопределено;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
//:ТекущийЭлементФормы = Новый ("ТабличноеПоле")
Если Истина
И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя];
Значение = Ячейка.Значение;
//Если ТипЗнч(Значение) = Тип("Строка") Тогда
////Если ОписаниеТиповВсеРедактируемыеТипыЛкс().СодержитТип(ТипЗнч(Значение)) Тогда
// ОбъектМДСписка = Метаданные.НайтиПоТипу(ТипЗнч(ТекущийЭлементФормы.Значение));
// Если ОбъектМДСписка <> Неопределено Тогда
// Если ЛиКорневойТипСсылкиЛкс(ПолучитьПервыйФрагментЛкс(ОбъектМДСписка.ПолноеИмя())) Тогда
// КлючеваяКолонкаДанных = "Ссылка";
// КонецЕсли;
// КонецЕсли;
// ТипСтроки = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока);
// Если КлючеваяКолонкаДанных <> Неопределено Тогда
// Значение = Новый Массив;
// Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл
// Значение.Добавить(ВыделеннаяСтрока[КлючеваяКолонкаДанных]);
// КонецЦикла;
// ИначеЕсли ТипСтроки = Тип("ДоступноеПолеКомпоновкиДанных") Тогда
// Значение = Новый Массив;
// Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл
// Значение.Добавить(ВыделеннаяСтрока);
// КонецЦикла;
// Иначе
// Значение = Неопределено;
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда
#Если Сервер И Не Сервер Тогда
ТекущийЭлементФормы = Новый ТабличныйДокумент;
#КонецЕсли
Попытка
ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки;
Исключение
ДанныеРасшифровки = Неопределено;
КонецПопытки;
Если Истина
И ДанныеРасшифровки <> Неопределено
И ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено
И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных")
Тогда
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка];
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда
Продолжить;
КонецЕсли;
Значение = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЕсли;
мПлатформа = ирКэш.Получить();
мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш);
Если Значение <> Неопределено Тогда
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ИмяМетода", "БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс");
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("Значение", Значение);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ОчиститьПередУстановкой", Ложь);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьТекст", Ложь);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьЗначение", Истина);
КонецЕсли;
Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
//ирПлатформа.WshShell.SendKeys("^c^с"); //англ.C,русс.С
WinAPI = ирКэш.ПолучитьWinAPI();
ДескрипторОкнаФокуса = WinAPI.GetActiveWindow();
WinAPI.EnableWindow(ДескрипторОкнаФокуса);
WM_KEYDOWN = 256; //0x0100
WM_KEYUP = 257; //0x0101
WM_COPY = 757; //0x0301
WM_CHAR = 258; //0x0102
WM_PASTE = 758; //0x0302
WM_GETTEXT = 13; //0x000D
VK_CONTROL = 17; // CTRL
KEY_C = 67; // С
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1);
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_C, 1);
Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1);
КонецЕсли;
Если WinAPI.GetAsyncKeyState(KEY_C) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_C, 1);
КонецЕсли;
ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина);
КонецФункции
Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле);
Форма.НастройкиСписка = НастройкиСписка;
Форма.ОткрытьМодально();
КонецФункции
Процедура Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
ИмяКоманднойПанели = "КП_ПолеВвода";
КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели);
Если КонтекстноеМенюФормы = Неопределено Тогда
КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели);
КонтекстноеМенюФормы.Видимость = Ложь;
КонецЕсли;
//лПлатформа = ирКэш.Получить();
//МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды");
//КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода;
//ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы);
КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(КонтекстноеМенюФормы);
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда
Попытка
КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню;
Исключение
// Поле ввода принадлежит не панели, поэтому у него нет свойства
Продолжить;
КонецПопытки;
Если КонтекстноеМеню = Неопределено Тогда
//ЭлементФормы.АвтоКонтекстноеМеню = Ложь;
ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ДействияФормы = ЭлементыФормы.Найти("ДействияФормы");
Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда
ПанельФормы = ЭтаФорма.Панель;
Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда
ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь);
ДействияФормы.ИсточникДействий = ЭтаФорма;
ПанельФормы.КонтекстноеМеню = ДействияФормы;
Иначе
ДействияФормы = ПанельФормы.КонтекстноеМеню;
КонецЕсли;
КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(ДействияФормы);
КонецЕсли;
КонецПроцедуры
Процедура ФормариЗакрытииЛкс(ЭтаФорма) Экспорт
// У некоторых из-за большого объема данных в настройках пользователя это вызывает большие задержки
//ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс");
КонецПроцедуры
Процедура КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(Знач КоманднаяПанельПолеВвода)
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить("МакетФормы");
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
Попытка
КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие");
Исключение
КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать);
Возврат;
КонецПопытки;
КнопкаКопировать.Имя = "БуферОбмена_Копировать";
КнопкаКопировать.Текст = "Копировать значение";
КнопкаКопировать.Подсказка = "Копировать значение в буфер обмена";
КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка;
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина);
КнопкаКопировать.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКопировать"); // Здесь в расширении будет неявное обращение к серверу https://partners.v8.1c.ru/forum/topic/1635523
КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаВставить.Имя = "БуферОбмена_Вставить";
КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаВставить.Текст = "Вставить значение";
КнопкаВставить.Подсказка = "Вставить значение из буфера обмена";
КнопкаВставить.Пояснение = КнопкаВставить.Подсказка;
КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина);
КнопкаВставить.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие");
КнопкаВставить.Картинка = ирКэш.КартинкаПоИмениЛкс("ирВставить"); // Здесь в расширении будет неявное обращение к серверу https://partners.v8.1c.ru/forum/topic/1635523
КонецПроцедуры
Процедура УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка) Экспорт
Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда
БуферОбмена_КопироватьЛкс(ЭтаФорма, Кнопка);
ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда
БуферОбмена_ВставитьЛкс(ЭтаФорма, Кнопка);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры) Экспорт
Параметры.Кнопка.СочетаниеКлавиш = Параметры.СочетаниеКлавиш;
КонецПроцедуры
Процедура БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс(Параметры) Экспорт
БуферОбмена_УстановитьЗначениеЛкс(Параметры.Значение, Параметры.ОчиститьПередУстановкой, Параметры.УстановитьТекст, Параметры.УстановитьЗначение);
УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры);
КонецПроцедуры
Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт
мПлатформа = ирКэш.Получить();
ПараметрыОбработчикаОжидания = мПлатформа.ПараметрыОбработчикаОжидания;
Выполнить(ПараметрыОбработчикаОжидания.ИмяМетода + "(ПараметрыОбработчикаОжидания)");
мПлатформа.ПараметрыОбработчикаОжидания = Неопределено;
КонецПроцедуры
// Родственник ВернутьПостоянныйПарольПользователяЛкс
// Пароль устанавливается временный и опционально роль ирРазработчик
Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина,
ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска = Истина) Экспорт
#Если Сервер И Не Сервер Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
#КонецЕсли
мПлатформа = ирКэш.Получить();
НужноВернутьАутентификациюОС = Ложь;
НужноВернутьАутентификациюПаролем = Ложь;
НужноВернутьПароль = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Ложь;
УдалитьРольРазработчикИР = Ложь;
Если ПодменитьПарольНаВремяЗапуска Тогда
Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда
Сообщить("Назначение временного пароля собственному пользователю не допускается");
Возврат Неопределено;
КонецЕсли;
мhash = ПользовательИБ.СохраняемоеЗначениеПароля;
Если ПользовательИБ.АутентификацияОС = Истина Тогда
ПользовательИБ.АутентификацияОС = Ложь;
НужноВернутьАутентификациюОС = Истина;
КонецЕсли;
Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда
ПользовательИБ.АутентификацияСтандартная = Истина;
НужноВернутьАутентификациюПаролем = Истина;
КонецЕсли;
Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ";
ПользовательИБ.Пароль = Пароль;
НужноВернутьПароль = Истина;
КонецЕсли;
Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда
УдалитьРольРазработчикИР = Истина;
ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
КонецЕсли;
Если ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска Тогда
Если ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() И ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь;
НужноВернутьЗащитуОтОпасныхДействий = Истина;
КонецЕсли;
КонецЕсли;
ПользовательИБ.Записать();
НаборПараметров = Новый Структура();
НаборПараметров.Вставить("mHash", мhash);
НаборПараметров.Вставить("НужноВернутьАутентификациюПаролем", НужноВернутьАутентификациюПаролем);
НаборПараметров.Вставить("НужноВернутьАутентификациюОС", НужноВернутьАутентификациюОС);
НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ);
НаборПараметров.Вставить("НужноВернутьПароль", НужноВернутьПароль);
НаборПараметров.Вставить("НужноВернутьЗащитуОтОпасныхДействий", НужноВернутьЗащитуОтОпасныхДействий);
НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР);
НаборПараметров.Вставить("Имя", ПользовательИБ.Имя);
НаборПараметров.Вставить("Пароль", Пароль);
Возврат НаборПараметров;
КонецФункции
// Родственник УстановитьВременныеСвойстваПользователюИБЛкс
Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт;
//УстановитьПривилегированныйРежим(Истина);
Если НаборПараметров <> Неопределено Тогда
мhash = НаборПараметров.mhash;
НужноВернутьАутентификациюПаролем = НаборПараметров.НужноВернутьАутентификациюПаролем;
НужноВернутьАутентификациюОС = НаборПараметров.НужноВернутьАутентификациюОС;
НужноВернутьПароль = НаборПараметров.НужноВернутьПароль;
НужноВернутьЗащитуОтОпасныхДействий = НаборПараметров.НужноВернутьЗащитуОтОпасныхДействий;
ПользовательИБ = НаборПараметров.ПользовательИБ;
УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР;
Иначе
Возврат;
КонецЕсли;
Если НужноВернутьПароль Тогда
ПользовательИБ.СохраняемоеЗначениеПароля = мHash;
КонецЕсли;
Если НужноВернутьАутентификациюПаролем Тогда
ПользовательИБ.АутентификацияСтандартная = Ложь;
КонецЕсли;
Если НужноВернутьАутентификациюОС Тогда
ПользовательИБ.АутентификацияОС = Истина;
КонецЕсли;
Если НужноВернутьЗащитуОтОпасныхДействий И ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() Тогда
ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина;
КонецЕсли;
Если УдалитьРольРазработчикИР Тогда
ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
ПользовательИБ.Записать();
КонецПроцедуры
Функция ОткрытьМенеджерТабличногоПоляЛкс(ТабличноеПоле, ЭтаФорма, АктивизироватьСтраницу = "") Экспорт
ФормаМенеджера = ирКэш.Получить().ПолучитьФорму("МенеджерТабличногоПоля", ЭтаФорма);
ФормаМенеджера.УстановитьСвязь(ТабличноеПоле, , АктивизироватьСтраницу);
Возврат ФормаМенеджера;
КонецФункции
Процедура ОткрытьСвязанныйСеансТонкогоКлиентаЛкс() Экспорт
Результат = ирКэш.ПолучитьСеансТонкогоКлиентаЛкс();
Результат.Visible = Истина;
Окна = Результат.ПолучитьОкна();
СписокОткрытыхОбъектов = Новый СписокЗначений;
Для Каждого Окно Из Окна Цикл
Попытка
Содержимое = Окно.Содержимое;
Исключение
// В 8.2 нет такого свойства
Продолжить;
КонецПопытки;
Для Каждого Форма Из Содержимое Цикл
Попытка
СсылкаCOM = Форма.Parameters.Key;
Исключение
СсылкаCOM = Неопределено;
КонецПопытки;
Если СсылкаCOM <> Неопределено Тогда
ФрагментыИмениТипа = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Форма.FormName);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Новый УникальныйИдентификатор(Результат.String(СсылкаCOM.УникальныйИдентификатор())));
Ссылка = Новый (Тип(ФрагментыИмениТипа[0] + "Ссылка." + ФрагментыИмениТипа[1]), МассивПараметров);
СписокОткрытыхОбъектов.Добавить(Ссылка, ФрагментыИмениТипа[0] + "." + ФрагментыИмениТипа[1] + " - " + Ссылка);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если СписокОткрытыхОбъектов.Количество() > 0 Тогда
СписокОткрытыхОбъектов.СортироватьПоПредставлению();
ВыбранныйЭлемент = СписокОткрытыхОбъектов.ВыбратьЭлемент("Выберите объект для открытия в редакторе объекта БД");
Если ВыбранныйЭлемент <> Неопределено Тогда
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранныйЭлемент.Значение);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ОповеститьОЗаписиОбъектаЛкс(ТипОбъекта, Источник = Неопределено) Экспорт
Оповестить("ЗаписанОбъект", ТипОбъекта, Источник);
ОповеститьОбИзменении(ТипОбъекта);
КонецПроцедуры
Функция ОткрытьОбъектМетаданныхЛкс(ОбъектИлиПолноеИмяМД) Экспорт
Если ТипЗнч(ОбъектИлиПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = ОбъектИлиПолноеИмяМД;
Иначе
ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиПолноеИмяМД);
КонецЕсли;
#Если Сервер И Не Сервер Тогда
ОбъектМД = Метаданные.НайтиПоТипу();
#КонецЕсли
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Если Фрагменты.Количество() = 2 Тогда
Форма = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
Форма.ПараметрИмяОбъектаМетаданных = ПолноеИмяМД;
Форма.ПрименитьПараметрыФормы();
КонецЕсли;
Возврат Форма;
КонецФункции
Процедура ВыделитьПервыеСтрокиДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач Количество, Знач НастройкиСписка = Неопределено) Экспорт
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле);
ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле);
СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы,,,,,,, Количество);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Если НастройкиСписка = Неопределено Тогда
НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок);
КонецЕсли;
ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор);
ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок);
СтруктураКлюча = ирОбщий.ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,, Ложь);
Для Каждого ЭлементСписка Из СтруктураКлюча Цикл
ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ЭлементСписка.Представление);
КонецЦикла;
КлючиСтрок = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки);
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КлючиСтрок.Количество(), "Выделение");
Для Каждого КлючСтроки Из КлючиСтрок Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
ВыделенныеСтроки.Добавить(ирОбщий.КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, КлючСтроки));
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если КлючиСтрок.Количество() <> Количество Тогда
Сообщить("Выделены все отобранные элементы, но меньшим количеством " + XMLСтрока(КлючиСтрок.Количество()));
КонецЕсли;
КонецПроцедуры
Функция ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, выхПолноеИмяМД = "") Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
//выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма);
ПолноеИмяТаблицы = ЭтаФорма.мСлужебныеДанные.ОсновныеТаблицыСписков[ПутьКДаннымСписка];
ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ОбъектМД <> Неопределено Тогда
выхПолноеИмяМД = ОбъектМД.ПолноеИмя();
КонецЕсли;
Иначе
выхПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя();
КонецЕсли;
ПолноеИмяТаблицы = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД);
Возврат ПолноеИмяТаблицы;
КонецФункции
Функция ОбработкаОбъектИзФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
ОбработкаОбъект = ЭтаФорма;
Иначе
//ОбработкаОбъект = ЭтаФорма.РеквизитФормыВЗначение("фОбъект");
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЭтаФорма.ИмяФормы);
ОбработкаОбъект = ДанныеФормыВЗначение(ЭтаФорма.фОбъект, Тип("ОбработкаОбъект." + Фрагменты[1]));
КонецЕсли;
Возврат ОбработкаОбъект;
КонецФункции
Функция ПолучитьАдресСтрокиДереваЗначенийЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
КлючиУровней = Новый Массив();
ТекущаяСтрока = СтрокаДерева;
Пока ТекущаяСтрока <> Неопределено Цикл
КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]);
ТекущаяСтрока = ТекущаяСтрока.Родитель;
КонецЦикла;
Возврат КлючиУровней;
КонецФункции
Функция ПолучитьАдресСтрокиДереваФормыЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
КлючиУровней = Новый Массив();
ТекущаяСтрока = СтрокаДерева;
Пока ТекущаяСтрока <> Неопределено Цикл
КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]);
ТекущаяСтрока = ТекущаяСтрока.ПолучитьРодителя();
КонецЦикла;
Возврат КлючиУровней;
КонецФункции
Процедура ПроверитьЗакрытьФормуПриОтказеЛкс(ЭтаФорма, Знач Отказ) Экспорт
// Антибаг платформы 8.3.11-12 Не работает установка параметра Отказ перед открытием обычной формы в управляемом приложении
// https://partners.v8.1c.ru/forum/t/1713475/m/1713475
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если Отказ И Не ЭтаФорма.МодальныйРежим Тогда
ЭтаФорма.Закрыть();
КонецЕсли;
#КонецЕсли
КонецПроцедуры
#КонецЕсли
#Если Клиент Тогда
Процедура ОткрытьСписокИнструментовЛкс() Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
ФормаСпискаИнструментов = ПолучитьФормуЛкс("Обработка.ирПортативный.Форма.Форма");
ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = Истина;
ФормаСпискаИнструментов.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура СохранитьНастройкиПользователяЛкс() Экспорт
#Если ВебКлиент Или МобильныйКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
СохранитьНастройкиПользователя();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт
#Если ВебКлиент Тогда
Сообщить("Команда недоступна в вебклиенте");
#ИначеЕсли ТонкийКлиент Тогда
ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая");
#Иначе
Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда
Сообщить("Команда недоступна в варианте Расширение");
Возврат;
КонецЕсли;
Форма = ирКэш.Получить().ПолучитьФорму("НастройкиАлгоритмов");
Форма.Открыть();
#КонецЕсли
КонецПроцедуры
Процедура ОткрытьАдминистративнаяРегистрация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.СодержитТип(Тип) Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
// Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка.
//
// Параметры:
// Строка Строка.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиИмяПеременнойЛкс(Строка) Экспорт
Если ПустаяСтрока(Строка) Тогда
Возврат Ложь;
КонецЕсли;
Пустышка = Новый Структура;
Попытка
Пустышка.Вставить(Строка);
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции // ЛиИмяПеременнойЛкс()
// Пространство имен текущей конфигурации.
// Возвращаемое значение:
//
Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт
Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config";
КонецФункции
Функция БезопасноПолучитьЗначениеСвойстваЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт
СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка);
ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы);
ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка];
Возврат ЗаголовокЭлемента;
КонецФункции
Функция ВосстановитьТекущуюСтрокуТаблицыФормыЛкс(ТаблицаФормы, Знач КлючТекущейСтроки, ДанныеТаблицы = Неопределено, ИмяКлючевойКолонки = "Ссылка") Экспорт
Если КлючТекущейСтроки <> Неопределено Тогда
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ТаблицаФормы.Значение;
КонецЕсли;
Если ТипЗнч(КлючТекущейСтроки) <> Тип("Структура") Тогда
КлючТекущейСтроки = Новый Структура(ИмяКлючевойКолонки, КлючТекущейСтроки);
КонецЕсли;
НайденныеСтроки = ДанныеТаблицы.НайтиСтроки(КлючТекущейСтроки);
Если НайденныеСтроки.Количество() > 0 Тогда
Строка = НайденныеСтроки[0];
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТаблицаФормы.ТекущаяСтрока = ИдентификаторСтроки;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ПолучитьКлючТекущейСтрокиЛкс(ТаблицаФормы, ИмяКлючевойКолонки = "Ссылка") Экспорт
ТекущиеДанные = ТаблицаФормы.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
КлючТекущейСтроки = ТекущиеДанные[ИмяКлючевойКолонки];
КонецЕсли;
Возврат КлючТекущейСтроки;
КонецФункции
Процедура ДинамическийСписок_ОбъектМетаданных_НачалоВыбора(ЭтаФорма, Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, ЭтаФорма);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ЭтаФорма.фОбъект.ОбъектМетаданных);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма"));
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма"));
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма"));
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Форма.ОткрытьМодально();
КонецПроцедуры
Процедура РедакторОбъектаБД_ИмяТаблицы_НачалоВыбора(ЭтаФорма, Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, ЭтаФорма);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ЭтаФорма.фОбъект.ИмяОсновнойТаблицы);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Ложь);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Форма.ОткрытьМодально();
КонецПроцедуры
Функция ИмяФормыИзФормыЛкс(ЭтаФорма) Экспорт
Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда
Результат = ЭтаФорма.ИмяФормы;
Иначе
Результат = СлужебныеДанныеФормыЛкс(ЭтаФорма).ИмяФормы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СлужебныеДанныеФормыЛкс(ЭтаФорма)
#Если Клиент Тогда
Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда
Результат = ЭтаФорма.Панель.Страницы[0].Значение;
Если Результат = Неопределено Тогда
Результат = Новый Структура();
ЭтаФорма.Панель.Страницы[0].Значение = Результат;
КонецЕсли;
Иначе
#КонецЕсли
Результат = ЭтаФорма.мСлужебныеДанные;
#Если Клиент Тогда
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Процедура ОчиститьПодчиненныеЭлементыФормыЛкс(Знач Родитель, КоличествоНеудаляемых = 1) Экспорт
Если Ложь
#Если Клиент Тогда
Или ТипЗнч(Родитель) = Тип("Панель")
#КонецЕсли
Тогда
Родитель.Страницы.Очистить();
ИначеЕсли Ложь
#Если Клиент Тогда
Или ТипЗнч(Родитель) = Тип("ТабличноеПоле")
#КонецЕсли
Тогда
Родитель.Колонки.Очистить();
Иначе
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Родитель);
ПодчиненныеЭлементы = Родитель.ПодчиненныеЭлементы;
НачальноеКоличество = ПодчиненныеЭлементы.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненныйЭлемент = ПодчиненныеЭлементы[НачальноеКоличество - Счетчик];
Если ПодчиненныеЭлементы.Количество() > КоличествоНеудаляемых Тогда
ЭтаФорма.Элементы.Удалить(ПодчиненныйЭлемент);
Иначе
// Статистически добавленные нельзя удалять
ПодчиненныйЭлемент.Видимость = Ложь;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя);
Если ЭлементСписка <> Неопределено И Готовность Тогда
НеготовыеСтраницы.Удалить(ЭлементСписка);
ИначеЕсли ЭлементСписка = Неопределено И Не Готовность Тогда
НеготовыеСтраницы.Добавить(Страница.Имя);
КонецЕсли;
КонецПроцедуры
Функция ПолучитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт
НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы;
#Если Сервер И Не Сервер Тогда
НеготовыеСтраницы = Новый СписокЗначений;
#КонецЕсли
ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя);
Результат = ЭлементСписка = Неопределено;
Возврат Результат;
КонецФункции
Процедура СоздатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, ЗаменитьКолонкуНомерСтроки = Ложь) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
ОчиститьПодчиненныеЭлементыФормыЛкс(ТабличноеПоле, 0);
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле);
ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле);
РеквизитыТаблицы = ЭтаФорма.ПолучитьРеквизиты(ПутьКДанным);
Для Каждого РеквизитТаблицы Из РеквизитыТаблицы Цикл
ПолеФормы = ЭтаФорма.Элементы.Добавить(ТабличноеПоле.Имя + РеквизитТаблицы.Имя, Тип("ПолеФормы"), ТабличноеПоле);
ПолеФормы.Вид = ВидПоляФормы.ПолеВвода;
Попытка
ПолеФормы.ПутьКДанным = ПутьКДанным + "." + РеквизитТаблицы.Имя;
Исключение
// При РеквизитТаблицы.Имя = "КоличествоСтрок"
КонецПопытки;
КонецЦикла;
Иначе
ТабличноеПоле.СоздатьКолонки();
Если ЗаменитьКолонкуНомерСтроки И ТабличноеПоле.Значение.Колонки.Найти("НомерСтроки") <> Неопределено Тогда
ТабличноеПоле.Колонки.НомерСтроки.Данные = "";
ТабличноеПоле.Колонки.НомерСтроки.ТолькоПросмотр = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Знач Строка = Неопределено) Экспорт
Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда
Если Строка = Неопределено Тогда
Строка = ТабличноеПоле.ТекущаяСтрока;
КонецЕсли;
Если Строка <> Неопределено Тогда
ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле);
#Если Сервер И Не Сервер Тогда
ДанныеТаблицы = Новый ТаблицаЗначений;
#КонецЕсли
Строка = ДанныеТаблицы.НайтиПоИдентификатору(Строка);
КонецЕсли;
Иначе
Если Строка = Неопределено Тогда
Строка = ТабличноеПоле.ТекущиеДанные;
КонецЕсли;
КонецЕсли;
Возврат Строка;
КонецФункции
Функция ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементФормы, ВызыватьИсключение = Истина) Экспорт
Попытка
ТипЗначения = ЭлементФормы.ТипЗначения;
Исключение
// Упр
ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы);
Попытка
ТипЗначения = ЭтаФорма.мСлужебныеДанные.ТипыЗначений[ЭлементФормы.Имя];
Исключение
Если ВызыватьИсключение Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
КонецПопытки;
Возврат ТипЗначения;
КонецФункции
// Чтобы функция возвращала правильное значение, в форме должен быть
// выполнен общий обработчик формы _ПриСозданииНаСервереИис.
//
// Параметры:
// Поле - <тип> -
//
// Возвращаемое значение:
//
Функция ДанныеЭлементаФормыЛкс(Знач Элемент, выхПутьКДанным = "") Экспорт
Попытка
// Обычная форма
Данные = Элемент.Значение;
Попытка
выхПутьКДанным = Элемент.Данные;
Исключение
// Колонка табличного поля
выхПутьКДанным = Неопределено;
КонецПопытки;
Возврат Данные;
Исключение
КонецПопытки;
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Элемент, Тип("УправляемаяФорма")); // Переменная ЭтаФорма используется в Вычислить ниже
выхПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Элемент, , ЭтаФорма);
Если Не ЗначениеЗаполнено(выхПутьКДанным) Тогда
//ВызватьИсключение "Для элемента формы " + Элемент.Имя + " не найден путь к данным";
Возврат Неопределено;
КонецЕсли;
Попытка
Данные = Вычислить("ЭтаФорма." + выхПутьКДанным);
Исключение
//ВызватьИсключение "Ошибка получения данных " + выхПутьКДанным + " элемента формы " + Элемент.Имя + ": " + ОписаниеОшибки();
Возврат Неопределено;
КонецПопытки;
Возврат Данные;
КонецФункции
Функция ИдентификаторСтрокиТабличногоПоляЛкс(Знач НоваяСтрока) Экспорт
Если Ложь
Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементКоллекции")
Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементДерева")
Тогда
НоваяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецЕсли;
Возврат НоваяСтрока;
КонецФункции
Функция НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт
Структура = Новый Структура(Свойство);
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство);
Если Структура[Свойство] = Значение Тогда
Результат = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РежимОтладкиИзКоманднойСтрокиЛкс(Знач СтрокаЗапускаПроцесса) Экспорт
МаркерОтладки = "-debug";
ПозицияСтрокиТипаОтладчика = Найти(НРег(СтрокаЗапускаПроцесса), Нрег(МаркерОтладки));
Если ЗначениеЗаполнено(ПозицияСтрокиТипаОтладчика) Тогда
СтрокаОтладчика = СокрЛ(Сред(СтрокаЗапускаПроцесса, ПозицияСтрокиТипаОтладчика + СтрДлина(МаркерОтладки)));
Если Найти(НРег(СтрокаОтладчика), "-http") = 1 Тогда
РежимОтладки = "http";
Иначе
РежимОтладки = "tcp";
КонецЕсли;
Иначе
РежимОтладки = "нет";
КонецЕсли;
Возврат РежимОтладки;
КонецФункции // Заполнить()
Функция СтрЗаменитьОбязательноЛкс(ГдеЗаменять, Знач ЧтоЗаменять, Знач НаЧтоЗаменять) Экспорт
Если Найти(ГдеЗаменять, ЧтоЗаменять) < 1 Тогда
ВызватьИсключение "Шаблонная строка """ + ЧтоЗаменять + """ не найдена в тексте";
КонецЕсли;
ГдеЗаменять = СтрЗаменить(ГдеЗаменять, ЧтоЗаменять, НаЧтоЗаменять);
Возврат ГдеЗаменять;
КонецФункции
///////////////////////////////////////////////////
// Управляемые формы
// Рекурсивно идет вверх до родителя нужного типа
// Параметры:
// ТипРодителя - Тип, *Неопределено - Неопределено=Тип("УправляемаяФорма") Возвращаемое значение:
//
Функция РодительЭлементаУправляемойФормыЛкс(Знач Элемент, ТипРодителя = Неопределено) Экспорт
ТипУправляемаяФорма = Тип("УправляемаяФорма");
Если ТипРодителя = Неопределено Тогда
ТипРодителя = ТипУправляемаяФорма;
КонецЕсли;
Пока ТипЗнч(Элемент) <> ТипРодителя Цикл
Если ТипЗнч(Элемент) = ТипУправляемаяФорма Тогда
Элемент = Неопределено;
Прервать;
КонецЕсли;
//Попытка
Элемент = Элемент.Родитель;
//Исключение
// Родитель = Неопределено;
// Прервать;
//КонецПопытки;
КонецЦикла;
Возврат Элемент;
КонецФункции
// Путь - можно передавать как полный путь к реквизиту, так и путь к родительскому реквизиту
//
// Параметры:
// ЭтаФорма - <тип> -
// Путь - <тип>, "" -
// ИмяРеквизита - <тип>, "" -
//
// Возвращаемое значение:
//
Функция ПолучитьРеквизитФормыЛкс(ЭтаФорма, Знач Путь = "", Знач ИмяРеквизита = "") Экспорт
Если Не ЗначениеЗаполнено(ИмяРеквизита) Тогда
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Путь);
ИмяРеквизита = Фрагменты[Фрагменты.Количество() - 1];
Фрагменты.Удалить(Фрагменты.Количество() - 1);
Путь = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
КонецЕсли;
Результат = Неопределено;
РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты(Путь);
Для Каждого РеквизитФормы Из РеквизитыФормы Цикл
Если НРег(РеквизитФормы.Имя) = Нрег(ИмяРеквизита) Тогда
Результат = РеквизитФормы;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции // ПолучитьРеквизитФормы()
// Получить тип реквизита формы
//
// Параметры:
// ЭтаФорма - <тип> -
// Путь - <тип>, "" -
// ИмяРеквизита - <тип> -
//
// Возвращаемое значение:
//
Функция ПолучитьТипРеквизитаФормыЛкс(ЭтаФорма, Путь = "", ИмяРеквизита = "") Экспорт
РеквизитФормы = ПолучитьРеквизитФормыЛкс(ЭтаФорма, Путь, ИмяРеквизита);
Результат = РеквизитФормы.ТипЗначения.Типы()[0];
Возврат Результат;
КонецФункции // ПолучитьРеквизитФормы()
// Получить путь К данным элемента управляемой формы. Чтобы функция возвращала правильное значение, в форме должен быть
// выполнен общий обработчик формы _ПриСозданииНаСервереИис.
//
// Параметры:
// Поле - <тип> -
//
// Возвращаемое значение:
//
Функция ПутьКДаннымЭлементаУправляемойФормыЛкс(Знач Поле, ОтносительноРодителя = Ложь, Знач ЭтаФорма = Неопределено) Экспорт
Если ЭтаФорма = Неопределено Тогда
ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Поле, Тип("УправляемаяФорма"));
КонецЕсли;
ПутьКДаннымПоля = "";
Если Поле <> ЭтаФорма Тогда
СнимокФормы = Новый Структура("мСлужебныеДанные");
ЗаполнитьЗначенияСвойств(СнимокФормы, ЭтаФорма);
Если СнимокФормы.мСлужебныеДанные <> Неопределено И Не ЭтаФорма.мСлужебныеДанные.ПутиКДанным.Свойство(Поле.Имя, ПутьКДаннымПоля) Тогда
ПутьКДаннымПоля = "";
КонецЕсли;
Если ОтносительноРодителя Тогда
ПутьКДаннымПоля = ПолучитьПоследнийФрагментЛкс(ПутьКДаннымПоля);
КонецЕсли;
КонецЕсли;
Возврат ПутьКДаннымПоля;
КонецФункции
Процедура СкопироватьКнопкиКоманднойПанелиУправляемойФормыЛкс(Знач КоманднаяПанельИсточник, Знач КоманднаяПанельПриемник, Знач ПрефиксИмени) Экспорт
ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(КоманднаяПанельИсточник);
ЭлементыФормы = ЭтаФорма.Элементы;
Для Каждого КнопкаОбразец Из КоманднаяПанельИсточник.ПодчиненныеЭлементы Цикл
Если Ложь
Или ТипЗнч(КнопкаОбразец) = Тип("ГруппаФормы")
Или Не ЗначениеЗаполнено(КнопкаОбразец.ИмяКоманды)
Тогда
// Это - системная команда
Продолжить;
КонецЕсли;
ИмяНовойКнопки = ПрефиксИмени + КнопкаОбразец.Имя;
НоваяКнопка = ЭлементыФормы.Добавить(ИмяНовойКнопки, ТипЗнч(КнопкаОбразец), КоманднаяПанельПриемник);
ЗаполнитьЗначенияСвойств(НоваяКнопка, КнопкаОбразец,, "Имя");
КонецЦикла;
КонецПроцедуры
Функция НайтиСтрокуДереваФормыПоАдресуЛкс(НачальнаяСтрока, КлючиУровней, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт
ТекущаяСтрока = НачальнаяСтрока;
Уровень = 0;
Для Уровень = 0 По КлючиУровней.Количество() - 1 Цикл
ЭлементыДерева = ТекущаяСтрока.ПолучитьЭлементы();
лТекущаяСтрока = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыДерева, ИмяКлючевойКолонки, КлючиУровней[Уровень]);
Если лТекущаяСтрока <> Неопределено Тогда
ТекущаяСтрока = лТекущаяСтрока;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ТекущаяСтрока;
КонецФункции
Процедура НастроитьЗаголовкиАвтоТаблицыФормыДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт
ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ);
ПоляТаблицы = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ДинамическийСписок.ОсновнаяТаблица);
ПоляТаблицы = ПоляТаблицы.Скопировать();
СтрокаПоляИденитификатора = ПоляТаблицы.Добавить();
СтрокаПоляИденитификатора.Имя = "ИдентификаторСсылкиЛкс";
СтрокаПоляИденитификатора.Заголовок = "Идентификатор ссылки";
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
Колонка = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ПолеТаблицы.Имя);
Если Колонка = Неопределено Тогда
Продолжить;
КонецЕсли;
Если РежимИмяСиноним Тогда
Колонка.Заголовок = ПолеТаблицы.Имя;
Иначе
Колонка.Заголовок = ПолеТаблицы.Заголовок;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка()