//////////////////////////////////////////////////////////////////////////////// // Подсистема "Инструменты разработчика" // Авторское право (с) 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") Тогда ВыбраннаяФорма = "Обработка.ирПортативный.Форма.ФормаУправляемая"; СтандартнаяОбработка = Ложь; КонецЕсли; КонецПроцедуры Функция ПолучитьОписаниеТиповОдногоТипаИзОписанияТиповЛкс(Тип, ОписаниеТипов) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов = Новый ОписаниеТипов; #КонецЕсли Массив = Новый Массив; Массив.Добавить(Тип); Результат = Новый ОписаниеТипов(Массив, ОписаниеТипов.КвалификаторыЧисла, ОписаниеТипов.КвалификаторыСтроки, ОписаниеТипов.КвалификаторыДаты, ОписаниеТипов.КвалификаторыДвоичныхДанных); Возврат Результат; КонецФункции // Функция разбивает строку разделителем. // // Параметры: // пСтрока - Строка - которую разбиваем; // *пРазделитель - Строка, "." - символ-разделитель; // *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП. // *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив. // // Возвращаемое значение: // Массив - фрагментов. // Функция ПолучитьМассивИзСтрокиСРазделителемЛкс(Знач Стр, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь, ОставлятьПустуюСтроку = Истина) Экспорт МассивСтрок = Новый Массив; Если Истина И Не ОставлятьПустуюСтроку И ПустаяСтрока(Стр) Тогда Возврат МассивСтрок; КонецЕсли; //лСтрока = СтрЗаменить(Стр, Разделитель, Символы.ПС); //// Баг платформы. СтрЧислоСтрок не учитывает терминальный перевод строки. //ЧислоСтрок = СтрЧислоСтрок(лСтрока + " "); //Для Счетчик = 1 По ЧислоСтрок Цикл // Фрагмент = СтрПолучитьСтроку(лСтрока, Счетчик); // Если ОбрезатьНепечатныеСимволы Тогда // Фрагмент = СокрЛП(Фрагмент); // КонецЕсли; // МассивСтрок.Добавить(Фрагмент); //КонецЦикла; Если Разделитель = " " Тогда Стр = СокрЛП(Стр); Пока 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); СтрокаТипов = ""; Для Каждого Тип Из Массив Цикл Если ТипЗначения = Тип Тогда Возврат; КонецЕсли; Если Тип = Неопределено Тогда Прервать; КонецЕсли; Если СтрокаТипов <> "" Тогда СтрокаТипов = СтрокаТипов + ", "; КонецЕсли; СтрокаТипов = СтрокаТипов + Тип; КонецЦикла; ВызватьИсключение "Получено значение типа """ + ТипЗначения + """ вместо ожидаемых типов: " + СтрокаТипов + "."; КонецПроцедуры #Если Не ТонкийКлиент И Не ВебКлиент Тогда Функция ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, выхВремяНачала = Неопределено) Экспорт #Если Сервер И Не Клиент Тогда Файл = Новый Файл(ИмяФайлаВнешнейОбработки); Если Не Файл.Существует() Тогда КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда ВызватьИсключение "файл внешней обработки алгоритма не доступен на сервере. Рекомендуется в общих настройках инструментов задать сетевой каталог объектов для отладки."; КонецЕсли; КонецЕсли; #КонецЕсли ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки, Ложь); ОбщиеМодули = ПолучитьСтруктуруОсновныхОбщихМодулейЛкс(); выхВремяНачала = ирОбщий.ПолучитьТекущееВремяВМиллисекундахЛкс(); ВнешняяОбработка.мМетод(СтруктураПараметров, ОбщиеМодули); //Возврат Результат; КонецФункции Функция ПолучитьСтруктуруОсновныхОбщихМодулейЛкс() Экспорт ОбщиеМодули = Новый Структура; ОбщиеМодули.Вставить("ирОбщий", ирОбщий); ОбщиеМодули.Вставить("ирКэш", ирКэш); ОбщиеМодули.Вставить("ирСервер", ирСервер); Возврат ОбщиеМодули; КонецФункции // ВыполнитьЛокально() Процедура ОбновитьТипЗначенияВСтрокеТаблицыЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиИлиОписаниеТипов = "ОписаниеТипов", Знач ИмяКолонкиТипаЗначения = "ТипЗначения", Знач ИмяКолонкиИмяТипаЗначения = "ИмяТипаЗначения", Знач Колонки = Неопределено) Экспорт Если Колонки = Неопределено Тогда Колонки = ТекущаяСтрока.Владелец().Колонки; Иначе ТребоватьТипЛкс(Колонки, Тип("ТаблицаЗначений"), Тип("КоллекцияКолонокТаблицыЗначений"), Тип("КоллекцияКолонокДереваЗначений"), Тип("КоллекцияКолонокРезультатаЗапроса"), , Тип("КоллекцияОбъектовМетаданных")); #Если Сервер И Не Сервер Тогда Колонки = Новый ТаблицаЗначений; Колонки = Колонки.Колонки; #КонецЕсли КонецЕсли; ТипЗначения = ТипЗнч(ТекущаяСтрока[ИмяКолонкиЗначения]); Если ТипЗнч(ИмяКолонкиИлиОписаниеТипов) <> Тип("ОписаниеТипов") Тогда КолонкаОписанияТипов = Колонки.Найти(ИмяКолонкиИлиОписаниеТипов); Если КолонкаОписанияТипов <> Неопределено Тогда ИмяКолонкиИлиОписаниеТипов = ТекущаяСтрока[ИмяКолонкиИлиОписаниеТипов]; Иначе ИмяКолонкиИлиОписаниеТипов = Неопределено; КонецЕсли; КонецЕсли; Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения, "Имя") <> Неопределено; Иначе ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения) <> Неопределено; КонецЕсли; Если ЕстьКолонкаТипЗначения Тогда ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Ложь); КонецЕсли; Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения, "Имя") <> Неопределено; Иначе ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения) <> Неопределено; КонецЕсли; Если ЕстьКолонкаИмяТипаЗначения Тогда ТекущаяСтрока[ИмяКолонкиИмяТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Истина); КонецЕсли; КонецПроцедуры Функция ПолучитьПараметрыЗапускаПриложения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 Тогда Возврат Истина; КонецЕсли; Иначе УзлыДляРегистрации = МассивУзлов; КонецЕсли; Успех = Истина; ирПлатформа = ирКэш.Получить(); Для Каждого Объект Из МассивОбъектов Цикл Если Индикатор <> Неопределено Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонецЕсли; Если НовоеЗначение Тогда ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, Объект); // Антибаг платформы 8.2.17-8.3.4 Если Истина И ирПлатформа.ВерсияПлатформы < 803005 И ТипЗнч(Объект) <> Тип("ОбъектМетаданных") И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбмена, Объект) Тогда Успех = Ложь; Сообщить("Не удалось зарегистрировать изменение """ + Объект + """ из-за ошибки платформы, исправленной в 8.3.5"); КонецЕсли; Иначе ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, Объект); КонецЕсли; Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина); Для Каждого МетаРегистр из ОбъектыМД Цикл Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда Если ПропускатьДвиженияВнеПланаОбмена Тогда Продолжить; Иначе ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя; КонецЕсли; КонецЕсли; ИмяТаблицыБДРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(МетаРегистр); НаборЗаписей = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяТаблицыБДРегистра); НаборЗаписей.Отбор[0].Установить(Объект.Ссылка); Если НовоеЗначение Тогда ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, НаборЗаписей); // Антибаг платформы 8.2.17-8.3.4 Если Истина И ирПлатформа.ВерсияПлатформы < 803005 И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбмена, НаборЗаписей) Тогда Успех = Ложь; Сообщить("Не удалось зарегистрировать изменение " + Объект + " из-за ошибки платформы, исправленной в 8.3.5"); КонецЕсли; Иначе ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, НаборЗаписей); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; Если Индикатор <> Неопределено Тогда ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; Возврат Успех; КонецФункции Функция ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов, ТолькоУзлыСАвторегистрацией = Ложь) Экспорт УзлыДляРегистрации = Новый Массив; Для Каждого ПроверяемыйУзел Из МассивУзлов Цикл ЭлементСостава = ПроверяемыйУзел.Метаданные().Состав.Найти(ОбъектМД); Если Истина И ЭлементСостава <> Неопределено И (Ложь Или Не ТолькоУзлыСАвторегистрацией Или ЭлементСостава.АвтоРегистрация = АвтоРегистрацияИзменений.Разрешить) Тогда УзлыДляРегистрации.Добавить(ПроверяемыйУзел); КонецЕсли; КонецЦикла; Возврат УзлыДляРегистрации; КонецФункции // Копирует регистрацию изменений с узла источника на узлы приемники. Опционально каждый тип данных отдельно равномерно распределяется по узлам приемникам. // Параметры: // НомерСообщения - Неопределено - брать номер отправленного с узла, Null - не фильтровать но номеру сообщения, иначе выбираются все изменения с номером равным или меньшим заданного // Возвращаемое значение: Массив - количество изменений зарегистрированных по каждому узлу Функция СкопироватьРаспределитьРегистрациюИзмененийПоУзламЛкс(УзелИсточник, УзлыПриемники, Распределять = Ложь, НомерСообщения = Null, МассивМетаданных = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда УзелИсточник = ПланыОбмена.ПолныйИис.ПустаяСсылка(); УзлыПриемники = Новый Массив; #КонецЕсли #Если Клиент Тогда Состояние("Выбираем все изменения для узла..."); #КонецЕсли Если НомерСообщения = Неопределено Тогда НомерСообщения = УзелИсточник.НомерОтправленного; КонецЕсли; Результат = Новый Массив; Для Счетчик = 1 По УзлыПриемники.Количество() Цикл Если Распределять И ТипЗнч(УзлыПриемники[Счетчик - 1]) <> ТипЗнч(УзелИсточник) Тогда ВызватьИсключение "Нельзя распределять на узлы другого плана обмена"; КонецЕсли; Результат.Добавить(0); КонецЦикла; Запрос = Новый Запрос; Запрос.УстановитьПараметр("Узел", УзелИсточник); Запрос.УстановитьПараметр("НомерСообщения", НомерСообщения); МетаПланОбмена = УзелИсточник.Метаданные(); ТекстЗапроса = ""; ТипыДанныхЗапросов = Новый Массив; Для Каждого ЭлементСостава Из МетаПланОбмена.Состав Цикл МетаОбъект = ЭлементСостава.Метаданные; Если Ложь Или МетаОбъект = Неопределено Или (Истина И МассивМетаданных <> Неопределено И МассивМетаданных.Найти(МетаОбъект) = Неопределено) Тогда Продолжить; КонецЕсли; Если ТекстЗапроса <> "" Тогда ТекстЗапроса = ТекстЗапроса + ";" + Символы.ПС; КонецЕсли; ПолноеИмяМД = МетаОбъект.ПолноеИмя(); ТипыДанныхЗапросов.Добавить(ПолноеИмяМД); ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(ПолноеИмяМД, ".Перерасчет.", ".") + ".Изменения"; ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ * |ИЗ | " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений |ГДЕ | РегистрацияИзменений.Узел = &Узел"; Если НомерСообщения <> Null Тогда ТекстЗапроса = ТекстЗапроса = " И НомерСообщения <= &НомерСообщения"; КонецЕсли; КонецЦикла; Если ТекстЗапроса <> "" Тогда Запрос.Текст = ТекстЗапроса; РезультатПакета = Запрос.ВыполнитьПакет(); ИндикаторСостава = ПолучитьИндикаторПроцессаЛкс(РезультатПакета.Количество(), "Распределение изменений"); Для ИндексЗапроса = 0 По РезультатПакета.ВГраница() Цикл ОбработатьИндикаторЛкс(ИндикаторСостава); РезультатЗапроса = РезультатПакета[ИндексЗапроса]; #Если Сервер И Не Сервер Тогда РезультатЗапроса1 = Новый Запрос; РезультатЗапроса = РезультатЗапроса1.Выполнить(); #КонецЕсли ПолноеИмяМД = ТипыДанныхЗапросов[ИндексЗапроса]; //Если Ложь // Или РезультатЗапроса.Колонки.Найти("НомерСообщения1") <> Неопределено // Или РезультатЗапроса.Колонки.Найти("Узел1") <> Неопределено //Тогда // ВызватьИсключение "В таблице " + ПолноеИмяМД + " в основной отбор включены измерения с запрещенными именами (НомерСообщения, Узел)"; //КонецЕсли; ТаблицаКорректна = Истина; Для Каждого КолонкаРезультата Из РезультатЗапроса.Колонки Цикл Если Не ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, КолонкаРезультата.Имя) Тогда Сообщить("Изменения таблицы " + ПолноеИмяМД + " не были скопированы, т.к. она имеет некорректное поле " + КолонкаРезультата.Имя + ", порожденное конфликтом имен полей"); ТаблицаКорректна = Ложь; Прервать; КонецЕсли; КонецЦикла; Если Не ТаблицаКорректна Тогда Продолжить; КонецЕсли; МакетныйОбъект = ""; ТекущаяГруппаТипаМетаданных = ""; Выборка = РезультатЗапроса.Выбрать(); ИндексУзла = 0; КоличествоЭлементов = Выборка.Количество(); Если КоличествоЭлементов > 0 Тогда Если Распределять Тогда УзлыРегистрации = УзлыПриемники; Иначе УзлыРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД), УзлыПриемники); Если УзлыРегистрации.Количество() < УзлыПриемники.Количество() Тогда Сообщить("Изменения таблицы " + ПолноеИмяМД + " были скопированы не на все узлы, т.к. некоторые планы обмена приемников не содержат ее."); КонецЕсли; КонецЕсли; Если УзлыРегистрации.Количество() > 0 Тогда ИндикаторТаблицы = ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПолноеИмяМД); ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМД, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); //, КлючевыеПоля Пока Выборка.Следующий() Цикл ОбработатьИндикаторЛкс(ИндикаторТаблицы); Объект = ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Выборка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Ложь, "НомерСообщения, Узел"); // Регистрация Если Распределять Тогда УзелПриемник = УзлыРегистрации[ИндексУзла]; ПланыОбмена.ЗарегистрироватьИзменения(УзелПриемник, Объект); Результат[ИндексУзла] = Результат[ИндексУзла] + 1; ИндексУзла = ИндексУзла + 1; Если ИндексУзла = УзлыРегистрации.Количество() Тогда ИндексУзла = 0; КонецЕсли; Иначе ПланыОбмена.ЗарегистрироватьИзменения(УзлыРегистрации, Объект); Результат[0] = Результат[0] + 1; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; Возврат Результат; КонецФункции Функция ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, ИмяПоля) Экспорт Если Ложь Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "Узел1") Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "НомерСообщения1") Тогда //ПолноеИмяРегистра = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ПолноеИмяТаблицыБД,, ".Изменения"); КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяМД); Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД); Если ОбъектМД <> Неопределено Тогда Если ОбъектМД.Измерения.Найти("" + ИмяПоля) = Неопределено Тогда Возврат Ложь; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Истина; КонецФункции // ИгнорироватьКолонки - Строка - имена колонок через запятую, которые не будут учитываться Функция ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Знач Выборка, Знач МакетныйОбъект, Знач ТекущаяГруппаТипаМетаданных, СчитатьДанныеОбъекта = Истина, Знач ИгнорироватьКолонки = "", Заблокировать = Ложь) Экспорт Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда Объект = Выборка.Ссылка; Если Заблокировать Тогда ЗаблокироватьСсылкуВТранзакцииЛкс(Объект); КонецЕсли; Если СчитатьДанныеОбъекта Тогда Объект = Объект.ПолучитьОбъект(); КонецЕсли; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда Объект = МакетныйОбъект; Если ЗначениеЗаполнено(ИгнорироватьКолонки) Тогда ИгнорироватьКолонки = Нрег(ИгнорироватьКолонки) + ","; КонецЕсли; Для Каждого ЭлементОтбора Из Объект.Отбор Цикл Если Найти(ИгнорироватьКолонки, НРег(ЭлементОтбора.Имя) + ",") > 0 Тогда Продолжить; КонецЕсли; Попытка ЗначениеПоля = Выборка[ЭлементОтбора.Имя]; Исключение // Независимый регистр сведений, у измерения не включен ОсновнойОтбор Продолжить; КонецПопытки; ЭлементОтбора.Значение = ЗначениеПоля; ЭлементОтбора.Использование = Истина; КонецЦикла; Если Заблокировать Тогда ЗаблокироватьНаборЗаписейПоОтборуЛкс(Объект); КонецЕсли; Если СчитатьДанныеОбъекта Тогда Объект.Прочитать(); КонецЕсли; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Константа" Тогда Объект = МакетныйОбъект; Если Заблокировать Тогда ЗаблокироватьКонстантуЛкс(Объект); КонецЕсли; Если СчитатьДанныеОбъекта Тогда Объект.Прочитать(); КонецЕсли; КонецЕсли; Возврат Объект; КонецФункции // Добавляет глобальные переменные и методы в контекст поля текстового документа с контекстной подсказкой. // // Параметры // ПолеТекстовогоДокументаСКонтекстнойПодсказкой - ОбработкаОбъект.ПолеТекстовогоДокументаСКонтекстнойПодсказкой. // Процедура ИнициализироватьГлобальныйКонтекстПодсказкиЛкс(ПолеТекстовогоДокументаСКонтекстнойПодсказкой) Экспорт #Если Сервер И Не Сервер Тогда ПолеТекстовогоДокументаСКонтекстнойПодсказкой = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать(); #КонецЕсли Если ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ЯзыкПрограммы = 1 Тогда Возврат; КонецЕсли; ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ОчиститьТаблицуСловЛокальногоКонтекста(); ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьПравилоВычисленияФункции( "ирКПА", "ПравилоВычисленияТипаЗначенияКПА"); МассивГлобальныхПеременных = Новый Массив; МассивГлобальныхПеременных.Добавить("ирПлатформа"); Для Каждого ИмяГлобальнойПеременной Из МассивГлобальныхПеременных Цикл Попытка ГлобальнаяПеременная = ВычислитьВыражение(ИмяГлобальнойПеременной); Исключение // ирПлатформа может отсутствовать Продолжить; КонецПопытки; МассивТипов = Новый Массив; МассивТипов.Добавить(ТипЗнч(ГлобальнаяПеременная)); ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста( ИмяГлобальнойПеременной, "Свойство", Новый ОписаниеТипов(МассивТипов), ГлобальнаяПеременная, Истина); КонецЦикла; СтруктураГлобальныхФункций = Новый Структура; СтруктураГлобальныхФункций.Вставить("Исследовать", Тип("Число")); СтруктураГлобальныхФункций.Вставить("Отладить", Тип("Число")); СтруктураГлобальныхФункций.Вставить("Оперировать", Тип("Число")); СтруктураГлобальныхФункций.Вставить("Наблюдать"); Для Каждого ЭлементГлобальнойФункции Из СтруктураГлобальныхФункций Цикл Если ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("Тип") Тогда МассивТипов = Новый Массив; МассивТипов.Добавить(ЭлементГлобальнойФункции.Значение); ОписаниеТипов = Новый ОписаниеТипов(МассивТипов); ИначеЕсли ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("ОписаниеТипов") Тогда ОписаниеТипов = ЭлементГлобальнойФункции.Значение; КонецЕсли; ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста( ЭлементГлобальнойФункции.Ключ, "Метод", ОписаниеТипов); КонецЦикла; КонецПроцедуры // ИнициализироватьГлобальныйКонтекстПодсказкиЛкс() // Параметры - ТаблицаЗначений с колонкой Имя Функция ЛиПараметрыАлгоритмыКорректныЛкс(Параметры) Экспорт Результат = Истина; Если Параметры.Количество() = 0 Тогда Возврат Результат; КонецЕсли; Для Каждого СтрокаПараметра Из Параметры Цикл Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда Результат = Ложь; Сообщить("Имя параметра """ + СтрокаПараметра.Имя + """ не отвечает правилам формирования имен встроенного языка", СтатусСообщения.Внимание); КонецЕсли; КонецЦикла; НеуникальныеИмена = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя"); Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл Сообщить("Параметр """ + НеуникальноеИмя + """ встречается более одного раза", СтатусСообщения.Внимание); Результат = Ложь; КонецЦикла; Возврат Результат; КонецФункции // ПараметрыКорректны() // Возможно нужно объединить с ПолучитьМетаданныеЛкс Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт Объект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД); Результат = Объект.Метаданные(); Возврат Результат; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С МЕТАДАННЫМИ И ТИПАМИ // Получает тип из описания типов, типа или значения. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Тип - найденный тип. // Функция ПолучитьТипОбъектаЛкс(пОбъект) ТипОбъекта = Тип("Неопределено"); ТипПараметра = ТипЗнч(пОбъект); Если ТипПараметра = Тип("ОписаниеТипов") Тогда Если пОбъект.Типы().Количество() > 0 Тогда ТипОбъекта = пОбъект.Типы()[0]; КонецЕсли; ИначеЕсли ТипПараметра <> Тип("Тип") Тогда ТипОбъекта = ТипПараметра; Иначе ТипОбъекта = пОбъект; КонецЕсли; Возврат ТипОбъекта; КонецФункции // ПолучитьТипОбъектаЛкс() // Проверяет, является ли строка именем корневого типа объекта БД. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом объекта БД; // Ложь – иначе. // Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(Знач КорневойТип) Экспорт Если Найти(КорневойТип, ".") > 0 Тогда КорневойТип = ПолучитьПервыйФрагментЛкс(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "БизнесПроцесс" ИЛИ КорневойТип = "Задача" ИЛИ КорневойТип = "Документ" ИЛИ КорневойТип = "ПланВидовРасчета" ИЛИ КорневойТип = "ПланВидовХарактеристик" ИЛИ КорневойТип = "ПланОбмена" ИЛИ КорневойТип = "ПланСчетов" ИЛИ КорневойТип = "Справочник" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипКонстантыЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "Константа" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипПланаОбменаЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "ПланОбмена" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипДокументаЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "Документ" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли строка именем корневого типа ссылки. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом ссылки; // Ложь – иначе. // Функция ЛиКорневойТипСсылкиЛкс(Знач КорневойТип, ИсключаяСсылкиМетаданных = Ложь) Экспорт Если Найти(КорневойТип, ".") > 0 Тогда КорневойТип = ПолучитьПервыйФрагментЛкс(КорневойТип); КонецЕсли; Если Ложь ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Перечисление" ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Точки" // Грязно ИЛИ КорневойТип = "ВнешнийИсточникДанных" // Грязно ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипСсылкиЛкс() // Проверяет, является ли строка именем корневого типа регистра БД. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом регистра БД; // Ложь – иначе. // Функция ЛиКорневойТипРегистраБДЛкс(КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт Если Ложь ИЛИ КорневойТип = "РегистрСведений" ИЛИ КорневойТип = "РегистрНакопления" ИЛИ КорневойТип = "РегистрБухгалтерии" ИЛИ КорневойТип = "ДвиженияССубконто" ИЛИ КорневойТип = "РегистрРасчета" ИЛИ КорневойТип = "Перерасчет" ИЛИ (Истина И СчитатьПоследовательностьРегистром И КорневойТип = "Последовательность") Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "РегистрРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "РегистрСведений" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "Перечисление" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт Если Ложь ИЛИ ТипТаблицы = "Перечисление" ИЛИ ТипТаблицы = "Точки" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "Последовательность" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "ЖурналДокументов" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "КритерийОтбора" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С МЕТАДАННЫМИ И ТИПАМИ Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип) Экспорт Если Ложь Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Или ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли строка именем типа вложенной таблицы БД. // // Параметры: // ТипТаблицы - Строка, Неопределено - имя типа таблицы. // // Возвращаемое значение: // Булево. // Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт Если Ложь ИЛИ ТипТаблицы = "ТабличнаяЧасть" ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиТипВложеннойТаблицыБДЛкс() Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт Если Ложь ИЛИ ТипТаблицы = "ВидыСубконто" ИЛИ ТипТаблицы = "БазовыеВидыРасчета" ИЛИ ТипТаблицы = "ВедущиеВидыРасчета" ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиТипВложеннойТаблицыБДЛкс() // Проверяет, корневой тип на наличие реквизита "Код". // // Параметры: // КорневойТип - Строка, Произвольный. // // Возвращаемое значение: // Истина – реквизит "Код" имеется; // Ложь – иначе. // Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт Если Ложь Или КорневойТип = "ПланВидовХарактеристик" Или КорневойТип = "ПланОбмена" Или КорневойТип = "ПланСчетов" Или КорневойТип = "ПланРасчета" Или КорневойТип = "Справочник" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс() // Проверяет, корневой тип на наличие реквизита "Предопределенный". // // Параметры: // КорневойТип - Строка, Произвольный. // // Возвращаемое значение: // Истина – реквизит "Предопределенный" имеется; // Ложь – иначе. // Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт Если Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланСчетов" Или КорневойТип = "ПланВидовХарактеристик" Или КорневойТип = "ПланВидовРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс() // Проверяет, метаданные на иерархию. // Иначе говоря проверяется начилие реквизита "Родитель". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией; // Ложь – иначе. // Функция ЛиМетаданныеИерархическогоОбъектаЛкс(пМетаданныеТипа) Экспорт КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа); Если Ложь Или КорневойТип = "ПланСчетов" Или (Истина И (Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланВидовХарактеристик") И пМетаданныеТипа.Иерархический) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс() // Проверяет, метаданные на иерархию. // Иначе говоря проверяется начилие реквизита "Родитель". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией; // Ложь – иначе. // Функция ЛиМетаданныеПодчиненногоОбъектаЛкс(пМетаданныеТипа) Экспорт КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа); Если Истина И (Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланВидовХарактеристик") И пМетаданныеТипа.Владельцы.Количество() > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс() // Проверяет, метаданные на иерархию с группами. // Иначе говоря проверяется начилие реквизита "ЭтоГруппа". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией групп; // Ложь – иначе. // Функция ЛиМетаданныеОбъектаСГруппамиЛкс(пМетаданныеТипа) Экспорт //ТипТаблицы = ПолучитьТипТаблицыБДЛкс(пМетаданныеТипа); КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа, Истина); Если Ложь Или (Истина И КорневойТип = "Справочник" И пМетаданныеТипа.Иерархический И пМетаданныеТипа.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов) Или (Истина И КорневойТип = "ПланВидовХарактеристик" И пМетаданныеТипа.Иерархический) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиМетаданныеОбъектаСГруппамиЛкс() // Проверяет, является ли значение ссылкой на объект БД. // // Параметры: // пЗначение – ОбъектМетаданных, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является ссылкой на объект БД; // Ложь – значение не является ссылкой на объект БД. // Функция ЛиСсылкаНаОбъектБДЛкс(пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт //Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьКорневойТипКонфигурацииЛкс(пЗначение, Истина)); Результат = ЛиТипСсылкиБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных); Возврат Результат; КонецФункции // ЛиСсылкаНаОбъектБДЛкс Функция ЛиТипСсылкиБДЛкс(Тип, ИсключаяСсылкиМетаданных = Истина) Экспорт Результат = Ложь; ХмлТип = XMLТип(Тип); Если ХмлТип <> Неопределено Тогда Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда Если Ложь Или Не ИсключаяСсылкиМетаданных Или (Истина И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0 И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0) Тогда Результат = Истина; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиТипОбъектаБДЛкс(Тип) Экспорт Результат = Ложь; ХмлТип = XMLТип(Тип); Если ХмлТип <> Неопределено Тогда Если Ложь Или Найти(ХмлТип.ИмяТипа, "Object.") > 0 Или Найти(ХмлТип.ИмяТипа, "RecordSet.") > 0 Или Найти(ХмлТип.ИмяТипа, "ValueManager.") > 0 Тогда Результат = Истина; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт XMLТип = XMLТип(Тип); Если XMLТип <> Неопределено Тогда Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда Возврат Истина; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции // Получить структуру отбора по связям И параметрам выбора // // Параметры: // ЭтаФорма - <тип> - // ПолеФормыИлиРеквизитМетаданных - <тип> - // ДляОчистки - <тип>, Ложь - // // Возвращаемое значение: // Функция ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ЭтотОбъект, ПолеФормыИлиРеквизитМетаданных, ОбъектВладелец = Неопределено, ДляОчистки = Ложь) Экспорт Попытка СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора; Исключение Возврат Новый Структура(); КонецПопытки; ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора; Отбор = Новый Структура(); МаркерОтбора = НРег("Отбор."); Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл #Если Сервер И Не Сервер Тогда СвязьПараметраВыбора = Новый СвязьПараметраВыбора; #КонецЕсли Если Истина И ДляОчистки И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять Тогда Продолжить; КонецЕсли; Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(СвязьПараметраВыбора.ПутьКДанным); ИмяРеквизита = Фрагменты[Фрагменты.ВГраница()]; Если Фрагменты.Количество() = 1 Тогда Если ОбъектВладелец = Неопределено Тогда ОбъектДляРеквизита = ЭтотОбъект; Иначе ОбъектДляРеквизита = ОбъектВладелец; КонецЕсли; Иначе ОбъектДляРеквизита = ЭтотОбъект; КонецЕсли; Попытка ЗначениеДанных = Вычислить("ОбъектДляРеквизита." + ИмяРеквизита); Исключение // Например поле таблицы или на сервере текущая строка таблицы Продолжить; КонецПопытки; Если Найти(НРег(СвязьПараметраВыбора.Имя), МаркерОтбора) <> 1 Тогда // Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор" Продолжить; КонецЕсли; Отбор.Вставить(Сред(СвязьПараметраВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ЗначениеДанных); КонецЦикла; Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл #Если Сервер И Не Сервер Тогда ПараметрВыбора = Новый ПараметрВыбора; #КонецЕсли Если Найти(НРег(ПараметрВыбора.Имя), МаркерОтбора) <> 1 Тогда // Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор" Продолжить; КонецЕсли; Отбор.Вставить(Сред(ПараметрВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ПараметрВыбора.Значение); КонецЦикла; Возврат Отбор; КонецФункции // Проверяет, является ли значение ссылкой на значение перечисления. // // Параметры: // пЗначение – Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является ссылкой на объект БД; // Ложь – значение не является ссылкой на объект БД. // Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт Возврат (ПолучитьКорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление"); КонецФункции // ЛиСсылкаНаПеречислениеЛкс() // Проверяет, является ли ключом записи регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип ключа записи регистра подтвержден; // Ложь – тип ключа записи регистра не подтвержден. // Функция ЛиКлючЗаписиРегистраЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "ключ записи:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКлючЗаписиРегистраЛкс() // Проверяет, является ли записью регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип записи регистра подтвержден; // Ложь – тип записи регистра не подтвержден. // Функция ЛиЗаписьРегистраЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "запись:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКлючЗаписиБД() // Проверяет, является ли набором записей регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип набора записей регистра подтвержден; // Ложь – тип набора записей регистра не подтвержден. // Функция ЛиНаборЗаписейРегистраЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "набор записей:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиНаборЗаписейРегистраЛкс() // Проверяет, является ли субконтом описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип субконто подтвержден; // Ложь – тип субконто не подтвержден. // Функция ЛиСубконтоЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "субконто:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиСубконтоЛкс() // Проверяет, является ли менеджером записи регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип менеджер записи регистра подтвержден; // Ложь – тип менеджер записи регистра не подтвержден. // Функция ЛиМенеджерЗаписиРегистраЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "менеджер записи:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиМенеджерЗаписиРегистраЛкс() // Проверяет, является ли значение табличной частью внешней обработки. // // Параметры: // пЗначение – Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является табличной частью внешней обработки; // Ложь – значение не является табличной частью внешней обработки. // Функция ЛиТабличнаяЧастьВнешнейОбработкиЛкс(пЗначение) Экспорт СтрокаТипЗначения = ПолучитьПервыйФрагментЛкс(Строка(пЗначение)); Возврат (СтрокаТипЗначения = "ВнешняяОбработкаТабличнаяЧасть"); КонецФункции // ЛксЛиВнешняяОбработка() // Получает ссылочный тип по метаданным. // // Параметры: // пМетаданные – ОбъектМетаданных. // // Возвращаемое значение: // – Тип - ссылочный; // Неопределено – тип нельзя получить. // Функция ПолучитьСсылочныйТипПоМетаданнымЛкс(пМетаданные) Экспорт Результат = Неопределено; КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданные, Истина); Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя); КонецЕсли; Возврат Результат; КонецФункции // ПолучитьСсылочныйТипПоМетаданнымЛкс() // Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем метаданные. // // Возвращаемое значение: // – Метаданные - полученные; // Неопределено - не удалось получить метаданные. // Функция ПолучитьМетаданныеЛкс(пОбъект) Экспорт Если ТипЗнч(пОбъект) = Тип("Строка") Тогда Если ПустаяСтрока(пОбъект) Тогда Результат = Неопределено; Иначе Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(пОбъект); Если Фрагменты.Количество() = 3 Тогда // ВидыСубконто, Изменения ПолноеИмяМД = Фрагменты[0] + "." + Фрагменты[1]; Иначе ПолноеИмяМД = пОбъект; КонецЕсли; Результат = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД); КонецЕсли; Возврат Результат; КонецЕсли; ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Результат = Метаданные.НайтиПоТипу(ТипОбъекта); Возврат Результат; КонецФункции // ПолучитьМетаданныеЛкс() // Получает метаданные списка по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // // Параметры: // пОбъект – Произвольное – проверяемое значение. // // Возвращаемое значение: // – Метаданные - списка; // Неопределено – значение не является списком. // Функция ПолучитьМетаданныеСпискаЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); МаркерСписка = "список:"; Если Найти(Строка(ТипОбъекта), МаркерСписка) > 0 Тогда Возврат ПолучитьМетаданныеЛкс(ТипОбъекта); Иначе Возврат Неопределено; КонецЕсли; КонецФункции // ПолучитьМетаданныеСпискаЛкс() // Определяет корневой тип конфигурации по описанию типов, типу, метаданным, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем метаданные; // *пЛиТолькоДляКорневого - Булево, *Ложь - возвращать только для объекта корневого типа. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено - не удалось получить имя типа. // Функция ПолучитьКорневойТипКонфигурацииЛкс(пОбъект, пЛиТолькоДляКорневого = Ложь) Экспорт Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда МетаданныеТипа = пОбъект; Иначе МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект); КонецЕсли; Результат = Неопределено; Если МетаданныеТипа <> Неопределено Тогда ПолноеИмя = МетаданныеТипа.ПолноеИмя(); Если пЛиТолькоДляКорневого Тогда МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя); Если МассивФрагментов.Количество() = 2 Тогда Результат = МассивФрагментов[0]; КонецЕсли; Иначе Результат = ПолучитьПервыйФрагментЛкс(ПолноеИмя); КонецЕсли; //Если Результат = "ВнешнийИсточникДанных" Тогда // Результат = Результат + "Таблица"; //КонецЕсли; КонецЕсли; Если Результат = "ТабличнаяЧасть" Тогда // Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект Результат = Неопределено; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьКорневойТипКонфигурацииЛкс() // Определяет имя корневого типа строки табличной части по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем корневой тип строки табличной части. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является строкой табличной части. // Функция ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "табличная часть строка:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя()); КонецЕсли; Возврат Неопределено; КонецФункции // ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс() // Определяет имя корневого типа табличной части по описанию типов, типу, метаданным, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего определяем корневой тип. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является строкой табличной части. // Функция ПолучитьКорневойТипТабличнойЧастиЛкс(пОбъект) Экспорт Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда МетаданныеТипа = пОбъект; Иначе МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект); КонецЕсли; Если МетаданныеТипа <> Неопределено Тогда ПолноеИмя = МетаданныеТипа.ПолноеИмя(); МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя); Если Истина И МассивФрагментов.Количество() >= 4 И МассивФрагментов[2] = "ТабличнаяЧасть" Тогда Возврат МассивФрагментов[2]; КонецЕсли; КонецЕсли; Возврат Неопределено; КонецФункции // ПолучитьКорневойТипТабличнойЧастиЛкс() // Определяет имя корневого типа списка по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем корневой тип строки табличной части. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является списком. // Функция ПолучитьКорневойТипСпискаЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "список:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя()); КонецЕсли; Возврат Неопределено; КонецФункции // ПолучитьКорневойТипСпискаЛкс() // Определяет имя табличной части по ее метаданным. // // Параметры: // пМетаданные – ОбъектМетаданных – который проверяем. // // Возвращаемое значение: // - Строка – имя табличной части; // Неопределено – это метаданные не табличной части. // Функция ПолучитьИмяТабличнойЧастиЛкс(пМетаданные) Экспорт Если пМетаданные <> Неопределено Тогда МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пМетаданные.ПолноеИмя()); Если МассивФрагментов.ВГраница() >= 2 Тогда Если МассивФрагментов[2] = "ТабличнаяЧасть" Тогда Возврат МассивФрагментов[3]; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Неопределено; КонецФункции // ПолучитьИмяТабличнойЧастиЛкс() // Получает менеджер по описанию типов, типу, метаданным, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем менеджер. // // Возвращаемое значение: // – МенеджерОбъекта - для ссылки или ссылочного типа; // Неопределено - не удалось получить. // Функция ПолучитьМенеджерЛкс(пОбъект) Экспорт Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда МетаданныеОбъекта = пОбъект; Иначе МетаданныеОбъекта = ПолучитьМетаданныеЛкс(пОбъект); КонецЕсли; Если МетаданныеОбъекта = Неопределено Тогда Возврат Неопределено; КонецЕсли; МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(МетаданныеОбъекта.ПолноеИмя()); КорневойТип = МассивФрагментов[0]; Менеджер = Неопределено; Если Истина И МассивФрагментов.Количество() = 4 И КорневойТип = "ВнешнийИсточникДанных" Тогда ИмяТипаМенеджера = МассивФрагментов[0] + "ТаблицаМенеджер." + МассивФрагментов[1] + "." + МассивФрагментов[3]; Иначе //КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеОбъекта, Истина); // Изменил 02.03.2012 Если КорневойТип <> Неопределено Тогда ИмяТипаМенеджера = КорневойТип + "Менеджер." + МетаданныеОбъекта.Имя; Иначе ИмяТипаМенеджера = "Неопределено"; КонецЕсли; КонецЕсли; Попытка Менеджер = Новый (ИмяТипаМенеджера); Исключение КонецПопытки; Возврат Менеджер; КонецФункции // ПолучитьМенеджерЛкс() // Получает запись регистра по ключу записи. // // Параметры: // пКлючЗаписи – КлючЗаписиРегистра – идентифицирующий запись. // // Возвращаемое значение: // – ЗаписьРегистра – найденная запись. // Функция ПолучитьЗаписьРегистраПоКлючуЛкс(пКлючЗаписи) Экспорт МенеджерЗначения = ПолучитьМенеджерЛкс(пКлючЗаписи); МенеджерЗаписи = МенеджерЗначения.СоздатьМенеджерЗаписи(); ЗаполнитьЗначенияСвойств(МенеджерЗаписи, пКлючЗаписи); МенеджерЗаписи.Прочитать(); Возврат МенеджерЗаписи; КонецФункции // ПолучитьЗаписьРегистраПоКлючуЛкс() // Больше не используется. Кандидат на удаление. // Получает список реквизитов объекта БД. // // Параметры: // пОбъект – определитель объекта метаданных; // *ЛиВключатьТолькоЧитаемые - Булево, *Ложь - включать ли в список только читаемые реквизиты; // *ЛиВключатьНедоступные - Булево, *Ложь - включать ли в список недоступные (группы/элементы) реквизиты; // *ЛиСортировать - Булево, *Ложь - отсортировать ли по представлению; // *ЛиСКартинками - Булево, *Ложь - добавлять ли картинки; // *ЛиСТабличнымиЧастями - Булево, *Ложь - включать ли в список табличные части. // // Возвращаемое значение: // СписокЗначений – содержащий в качестве значений имена реквизитов. // Функция ПолучитьСписокРеквизитовОбъектаБДЛкс(пОбъект, ЛиВключатьТолькоЧитаемые = Ложь, ЛиВключатьНедоступные = Ложь, ЛиСортировать = Ложь, ЛиСКартинками = Ложь, ЛиСТабличнымиЧастями = Ложь) Экспорт СписокРеквизитов = Новый СписокЗначений; Если пОбъект = Неопределено Тогда Возврат СписокРеквизитов; КонецЕсли; Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда ОбъектМетаданных = пОбъект; Иначе ОбъектМетаданных = ПолучитьМетаданныеЛкс(пОбъект); КонецЕсли; КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМетаданных); ИерархияГрупп = Ложь; КартинкаРеквизита = Неопределено; #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.СлужебныйРеквизит; КонецЕсли; #КонецЕсли Если КорневойТип = "Задача" Тогда СписокРеквизитов.Добавить("БизнесПроцесс", "Бизнес процесс", , КартинкаРеквизита); СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита); Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита); КонецЕсли; Если ОбъектМетаданных.ДлинаНомера > 0 Тогда СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита); КонецЕсли; СписокРеквизитов.Добавить("ТочкаМаршрута", "Точка маршрута", , КартинкаРеквизита); СписокРеквизитов.Добавить("Выполнена", "Выполнена", , КартинкаРеквизита); Для Каждого Рекв из ОбъектМетаданных.РеквизитыАдресации Цикл СписокРеквизитов.Добавить(Рекв.Имя, Рекв.Представление(), , КартинкаРеквизита); КонецЦикла; КонецЕсли; Если КорневойТип = "Документ" Тогда СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита); Если ОбъектМетаданных.ДлинаНомера > 0 Тогда СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита); КонецЕсли; Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("Проведен", "Проведен", , КартинкаРеквизита); КонецЕсли; КонецЕсли; Если КорневойТип = "Справочник" Тогда Если ОбъектМетаданных.Владельцы.Количество() > 0 Тогда СписокРеквизитов.Добавить("Владелец", "Владелец", , КартинкаРеквизита); КонецЕсли; КонецЕсли; ЭтоГруппа = Ложь; Если ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Тогда Если ОбъектМетаданных.ДлинаКода > 0 Тогда СписокРеквизитов.Добавить("Код", "Код", , КартинкаРеквизита); КонецЕсли; Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита); КонецЕсли; Если ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМетаданных) Тогда СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита); Если ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМетаданных) Тогда ИерархияГрупп = Истина; Если Не ЛиВключатьНедоступные Тогда ЭтоГруппа = пОбъект.ЭтоГруппа; КонецЕсли; Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита); КонецЕсли; КонецЕсли; Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита); Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита); КонецЕсли; КонецЕсли; #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.Реквизит; КонецЕсли; #КонецЕсли Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл Если Ложь Или ЛиВключатьНедоступные Или Не ИерархияГрупп Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента Или (Истина И ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Или (Истина И Не ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Тогда СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Если ЛиСТабличнымиЧастями Тогда #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть; КонецЕсли; #КонецЕсли Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл Если Ложь Или ЛиВключатьНедоступные Или Не ИерархияГрупп Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента Или (Истина И ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Или (Истина И Не ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Тогда СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Если ЛиСортировать Тогда СписокРеквизитов.СортироватьПоПредставлению(); КонецЕсли; Возврат СписокРеквизитов; КонецФункции // ПолучитьСписокРеквизитовОбъектаБДЛкс() // Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр". // // Параметры: // Порядок – Порядок. // // Возвращаемое значение: // Строка - для установки порядка. // Функция ПолучитьСтрокуПорядкаЛкс(Порядок) Экспорт Строка = ""; Для Каждого ЭлементПорядка Из Порядок Цикл Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " "; Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда Строка = Строка + "возр"; Иначе Строка = Строка + "убыв"; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 2); КонецФункции // ПолучитьСтрокуПорядкаЛкс() // Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода. // Безопасность заключается в том, что нет свойств локального контекста // и недоступны доопределенные Свойства глобального контекста. // // Параметры: // ТекстДляВыполнения – Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Выполнить(ТекстДляВыполнения); КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс() // Получает копию произвольного объекта. Копирование производится через сериализацию. // // Параметры: // пОбъект – Произвольное – сохраняемое значение; // // Возвращаемое значение: // Произвольный - копия объекта. // Функция ПолучитьКопиюОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт Если ИспользоватьXDTO Тогда НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект)); Иначе НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект)); КонецЕсли; Возврат НовыйОбъект; КонецФункции // ПолучитьКопиюОбъектаЛкс() // Находит элемент коллекции по свойству "ПутьКДанным". // // Параметры: // пКоллекция – Коллекция – все элементы которой имеют свойство "ПутьКДанным"; // пПутьКДанным – Строка – искомое значение. // // Возвращаемое значение: // – ЭлементКоллекции; // Неопределено - не найден. // Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт СуществующаяСтрока = Неопределено; Для Каждого ЭлементКоллеции Из пКоллекция Цикл Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда СуществующаяСтрока = ЭлементКоллеции; Прервать; КонецЕсли; КонецЦикла; Возврат СуществующаяСтрока; КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс() // Находит поле настройки по пути к данным. // // Параметры: // пПоляНастройки – ПоляНастройки; // пПутьКДанным – Строка – путь к данным поля в виде разыменовывания; // *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю. // // Возвращаемое значение: // ПолеНастройки – найденное поле; // Неопределено - иначе. // Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт ПоляНастройки = пПоляНастройки; МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пПутьКДанным); ТекущееПоле = Неопределено; Для Каждого Фрагмент Из МассивФрагментов Цикл пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент; ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю); Если ТекущееПоле = Неопределено Тогда Прервать; КонецЕсли; ПоляНастройки = ТекущееПоле.Поля; КонецЦикла; Возврат ТекущееПоле; КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс() // Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно. // // Параметры: // пЭлементОтбораПриемник – ЭлементОтбора – куда копируем; // пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем. // Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование"); МассивСвойствЭлементаОтбора = Новый Массив; МассивСвойствЭлементаОтбора.Добавить("ВидСравнения"); МассивСвойствЭлементаОтбора.Добавить("Значение"); МассивСвойствЭлементаОтбора.Добавить("ЗначениеС"); МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо"); Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл Значение = пЭлементОтбораИсточник[Свойство]; Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда пЭлементОтбораПриемник[Свойство] = Значение; КонецЕсли; КонецЦикла; КонецПроцедуры // СкопироватьЭлементОтбораЛкс() Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено, Знач ПроверятьДоступностьПолей = Ложь, Знач ДоступныеПоляОтбора = Неопределено, ТолькоИспользуемые = Истина, ОчищатьПриемник = Истина) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый НастройкиКомпоновкиДанных; ОтборКомпоновкиДанных = Пустышка.Отбор; #КонецЕсли Если СоответствиеИмен = Неопределено Тогда СоответствиеИмен = Новый ТаблицаЗначений(); СоответствиеИмен.Колонки.Добавить("Источник"); //СоответствиеИмен.Колонки.Добавить("Приемник"); КонецЕсли; Если ДоступныеПоляОтбора = Неопределено Тогда ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора; КонецЕсли; Если ОчищатьПриемник Тогда ОтборКомпоновкиДанных.Элементы.Очистить(); КонецЕсли; ИндексГраницы = ЭлементыОтбора.Количество() - 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; КонецЕсли; Возврат ИндексКартинки; КонецФункции // ПолучитьИндексКартинкиСсылкиЛкс() // Добавляет в таблицу значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт СтрокаСовпадающихКолонок = ""; Разделитель = ","; Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда КолонкиИсточника = ТаблицаИсточник.Колонки; Иначе КолонкиИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаИсточник)).Реквизиты; КонецЕсли; ЛиПриемникТЧ = ТипЗнч(ТаблицаПриемник) <> Тип("ТаблицаЗначений"); Если ЛиПриемникТЧ Тогда КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки; Иначе КолонкиПриемника = ТаблицаПриемник.Колонки; КонецЕсли; Для каждого Колонка Из КолонкиПриемника Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если Истина И (Ложь Или Не ЛиПриемникТЧ Или Колонка.Имя <> "НомерСтроки") И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок); //Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл // СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива]; //КонецЦикла; Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений); КонецЕсли; КонецЦикла; КонецПроцедуры // ЗагрузитьВТаблицуЗначенийЛкс() // Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВДеревоЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ДеревоИсточник = Новый ДеревоЗначений; ДеревоПриемник = Новый ДеревоЗначений; #КонецЕсли СтрокаСовпадающихКолонок = ""; Разделитель = ","; КолонкиИсточника = ДеревоИсточник.Колонки; Для каждого Колонка Из ДеревоПриемник.Колонки Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); ЗагрузитьВСтрокиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок); КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс() // Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаРодительИсточника, СтрокаРодительПриемника, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт СтрокиПриемника = СтрокаРодительПриемника.Строки; Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл СтрокаПриемника = СтрокиПриемника.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок); Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений); КонецЕсли; ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок); КонецЦикла; КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс() // Выводит сообщение пользователю. Способ вывода определяется модальным режимом. // В модальном режиме используется Предупреждение(), в немодальном Сообщить(). // // Параметры: // ТекстСообщения – Строка; // МодальныйРежим – Булево, *Ложь; // *Статус - СтатусСообщения, *Неопределено. // Процедура СообщитьСУчетомМодальностиЛкс(ТекстСообщения, МодальныйРежим = Ложь, Статус = Неопределено) Экспорт Если Статус = Неопределено Тогда Статус = СтатусСообщения.Обычное; КонецЕсли;; #Если Клиент Тогда Если МодальныйРежим Тогда Предупреждение(ТекстСообщения); Иначе #КонецЕсли Сообщить(ТекстСообщения, Статус); #Если Клиент Тогда КонецЕсли; #КонецЕсли КонецПроцедуры // СообщитьСУчетомМодальностиЛкс() // Сообщает итог индикации (длительность). // // Параметры: // Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс. // Процедура СообщитьИтогИндикацииЛкс(Индикатор) Экспорт ТекущаяДата = ТекущаяДата(); ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса; //Часов = Цел(ПрошлоВремени / 3600); //Осталось = ПрошлоВремени - (Часов * 3600); //Минут = Цел(ПрошлоВремени / 60); //Секунд = Цел(Цел(ПрошлоВремени - (Минут * 60))); //ПрошлоВремениСтрока = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":" // + Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":" // + Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН="); ПрошлоВремениСтрока = формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП="); ТекстСообщения = Индикатор.ПредставлениеПроцесса + " завершено, обработано " + Индикатор.Счетчик + " элементов за " + ПрошлоВремениСтрока + " (" + ПрошлоВремени + " сек)."; Если Индикатор.Счетчик > 0 Тогда ТекстСообщения = ТекстСообщения + " Грубое среднее время обработки элемента - " + Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН=") + " мс"; КонецЕсли; Сообщить(ТекстСообщения); КонецПроцедуры // ОбработатьИндикаторЛкс() // Получает более подробное представление значения, чем штатное приведение к строковому типу. // // Параметры: // Значение – Произвольный – что нужно представить. // // Возвращаемое значение: // Строка – представление. // Функция РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля = Неопределено, ДобавлятьПредставлениеТипа = Ложь, РасширенноеПредставлениеХранилищЗначений = Ложь) Экспорт Результат = ""; Разделитель = ", "; КоличествоЭлементов = ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение); Если КоличествоЭлементов <> Неопределено Тогда Результат = "(" + КоличествоЭлементов + ")"; КонецЕсли; Если ТипЗнч(Значение) = Тип("Граница") Тогда Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение; ИначеЕсли ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Значение)) Тогда Результат = "" + Значение; Если Не ЗначениеЗаполнено(Результат) Тогда Результат = "(" + Значение.Имя + ")"; КонецЕсли; ИначеЕсли ТипЗнч(Значение) = Тип("ОписаниеТипов") Тогда #Если Сервер И Не Сервер Тогда Значение = Новый ОписаниеТипов; #КонецЕсли ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 20; Коллекция = Значение.Типы(); Для Каждого Тип Из Коллекция Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + ПредставлениеТипаЛкс(Тип, Значение); МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "..."; Прервать; КонецЕсли; КонецЦикла; Если Коллекция.Количество() > 1 Тогда Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")"; Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; КонецЕсли; Результат = Результат + ПредставлениеКоллекции; ИначеЕсли Ложь Или ТипЗнч(Значение) = Тип("Массив") Или ТипЗнч(Значение) = Тип("ФиксированныйМассив") Или ТипЗнч(Значение) = Тип("СписокЗначений") Тогда ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 20; Для Каждого ЭлементМассива Из Значение Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + ЭлементМассива; МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "..."; Прервать; КонецЕсли; КонецЦикла; Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; Результат = Результат + ПредставлениеКоллекции; ИначеЕсли Ложь Или ТипЗнч(Значение) = Тип("Структура") Или ТипЗнч(Значение) = Тип("Соответствие") Тогда ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 20; Для Каждого КлючИЗначение Из Значение Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение; МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "..."; Прервать; КонецЕсли; КонецЦикла; Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; Результат = Результат + ПредставлениеКоллекции; ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда ирПлатформа = ирКэш.Получить(); ИмяОбщегоТипа = ирПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(Значение); ПолноеИмяОсновногоКласса = ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь); ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", ""); Результат = Результат + ИмяОбщегоТипа; ИначеЕсли Истина И РасширенноеПредставлениеХранилищЗначений И ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда Результат = Результат + ТипЗнч(Значение); ВложенноеЗначение = Значение.Получить(); Результат = Результат + ": " + ВложенноеЗначение; ИначеЕсли ТипЗнч(Значение) = Тип("Файл") Тогда Результат = Результат + ТипЗнч(Значение); Результат = Результат + ": " + Значение.ПолноеИмя; //ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда // Результат = Результат + """" + Значение + """"; Иначе СтрокаФормата = ""; Если КолонкаТабличногоПоля <> Неопределено Тогда СтрокаФормата = КолонкаТабличногоПоля.Формат; // Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался //Если Истина // И ПустаяСтрока(СтрокаФормата) // И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода") //Тогда // КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла; // СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти; //КонецЕсли; КонецЕсли; Результат = Результат + Формат(Значение, СтрокаФормата); КонецЕсли; Возврат Результат; КонецФункции Функция ПредставлениеТипаЛкс(Знач Тип, Знач ОписаниеТипов = Неопределено, ИспользоватьИмя = Ложь) Если ИспользоватьИмя Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип); ПредставлениеТипа = мПлатформа.ПолучитьСтрокуКонкретногоТипа(СтруктураТипа); Иначе ПредставлениеТипа = "" + Тип; КонецЕсли; Если ОписаниеТипов <> Неопределено Тогда Если Тип = Тип("Число") Тогда ПредставлениеТипа = ПредставлениеТипа + "(" + ОписаниеТипов.КвалификаторыЧисла.Разрядность + "," + ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")"; ИначеЕсли Тип = Тип("Строка") Тогда ПредставлениеТипа = ПредставлениеТипа + "(" + XMLСтрока(ОписаниеТипов.КвалификаторыСтроки.Длина) + ")"; ИначеЕсли Тип = Тип("Дата") Тогда Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда ПредставлениеКвалификатора = "В"; ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда ПредставлениеКвалификатора = "ДВ"; ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда ПредставлениеКвалификатора = "Д"; КонецЕсли; ПредставлениеТипа = ПредставлениеТипа + "(" + ПредставлениеКвалификатора + ")"; КонецЕсли; КонецЕсли; Возврат ПредставлениеТипа; КонецФункции // ЛксПолучитьПредставлениеЗначение() // Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств. // Отсутствие свойства приравнивается к значению Неопределено. // // Параметры: // Первый – Произвольный – первый объект для сравнения; // Второй – Произвольный – первый объект для сравнения; // СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения. // // Возвращаемое значение: // Булево – Равны ли значения всех указанных свойств. // Функция СравнитьЗначенияСвойствЛкс(Первый, Второй, СвойстваДляСравнения) Экспорт Структура1 = Новый Структура(СвойстваДляСравнения); ЗаполнитьЗначенияСвойств(Структура1, Первый); Структура2 = Новый Структура(СвойстваДляСравнения); ЗаполнитьЗначенияСвойств(Структура2, Второй); Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2); Возврат Результат; КонецФункции // СравнитьЗначенияСвойствЛкс() #Если Клиент Тогда Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина); лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина); лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина); лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина); лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина); лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина); лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина); лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина); лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина); лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина); лСтруктураПараметров.Вставить("МножественныйВыбор", Истина); лДоступныеОбъекты = ТаблицаЗначенийИзТабличногоПоляЛкс(ТабличноеПоле); лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД); лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД); Если ЭтоКолонкаПолногоИмениМД Тогда ДоступныеОбъекты = Новый Массив; Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); ДоступныеОбъекты.Добавить(СреднееИмяМД); КонецЦикла; Иначе //лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина); //лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина); ДоступныеОбъекты = лДоступныеОбъекты; КонецЕсли; ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД]; Если Истина И ЭлементОтбора.Использование И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Тогда лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения(); Если ЭтоКолонкаПолногоИмениМД Тогда НачальноеЗначениеВыбора = Новый Массив; Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); НачальноеЗначениеВыбора.Добавить(СреднееИмяМД); КонецЦикла; Иначе НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора; КонецЕсли; Иначе НачальноеЗначениеВыбора = ДоступныеОбъекты; КонецЕсли; мПлатформа = ирКэш.Получить(); Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных"); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора); лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; ЗначениеВыбора = Форма.ОткрытьМодально(); Если ЗначениеВыбора <> Неопределено Тогда Если ЭтоКолонкаПолногоИмениМД Тогда ТаблицаВсехТаблицБД = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс(); МассивИменМД = Новый Массив; Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя"); Если СтрокаОписанияТаблицы <> Неопределено Тогда МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД); Иначе МассивИменМД.Добавить(СреднееИмяМД); КонецЕсли; КонецЦикла; Иначе МассивИменМД = ЗначениеВыбора; КонецЕсли; СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(МассивИменМД); ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке; ЭлементОтбора.Значение = СписокЗначений; ЭлементОтбора.Использование = Истина; КонецЕсли; КонецПроцедуры Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма"); Дерево = Новый ДеревоЗначений; Дерево.Колонки.Добавить("Объект"); Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов"); НачатьТранзакцию(); Попытка Для Каждого Объект Из Объекты Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КопияОбъекта = Объект.Ссылка.ПолучитьОбъект(); ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта); Попытка КопияОбъекта.ОбменДанными.Загрузка = Истина; Исключение Сообщить("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается"); Возврат; КонецПопытки; КопияОбъекта.Записать(); СтрокаГруппы = Дерево.Строки.Добавить(); СтрокаЭлемента = СтрокаГруппы.Строки.Добавить(); СтрокаЭлемента[0] = КопияОбъекта.Ссылка; СтрокаЭлемента = СтрокаГруппы.Строки.Добавить(); СтрокаЭлемента[0] = Объект; КонецЦикла; Исключение ОтменитьТранзакцию(); ВызватьИсключение; КонецПопытки; ЗафиксироватьТранзакцию(); ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь); ФормаОбработки.ОтключатьКонтрольЗаписи = Истина; ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь; КонецПроцедуры // ПередОткрытием() // Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно. // Иными словам колонка отображает данные, хранимые отдельно. // // Параметры: // ОформлениеЯчейки – ОформлениеЯчейки // Значение - Произвольный - значение для отображения. // Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт Если Значение = Неопределено Тогда Значение = ОформлениеЯчейки.Значение; КонецЕсли; Если ВыводитьПиктограммуТипа Тогда ТипЗначения = ТипЗнч(Значение); Если Истина И ТипЗначения = Тип("Булево") И ОформлениеЯчейки.ОтображатьФлажок Тогда // Иначе КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения); Если КартинкаТипа <> Неопределено Тогда ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа); КонецЕсли; КонецЕсли; КонецЕсли; РасширенноеПредставление = РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля); Если Ложь Или ОформлениеЯчейки.Текст = РасширенноеПредставление Тогда Возврат; КонецЕсли; //ОформлениеЯчейки.ТолькоПросмотр = Истина; //ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения"); ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление); КонецПроцедуры // ОформитьЯчейкуСРасширеннымЗначениемЛкс() // Находит файлы в иерархии заданного каталога локальной файловой системы. // // Параметры: // Путь – Строка; // Маска – Строка. // // Возвращаемое значение: // Массив – элементы типа Файл. // Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт НайденныеКаталоги = НайтиФайлы(Путь, "*.*"); МассивРезультатов = Новый Массив; Для каждого НайденныйФайл Из НайденныеКаталоги Цикл Если НайденныйФайл.ЭтоКаталог() Тогда МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска)); КонецЕсли; КонецЦикла; МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска)); Результат = Новый Массив; Для Каждого ЭлементРезультат Из МассивРезультатов Цикл Для Каждого Файл Из ЭлементРезультат Цикл Результат.Добавить(Файл); КонецЦикла; КонецЦикла; Возврат Результат; КонецФункции // НайтиФайлыВИерархииЛкс() // Проверяет, является ли тип типом элемента формы. // // Параметры: // пТип – Тип – проверяемый тип. // // Возвращаемое значение: // Истина – тип элемента формы подтвержден; // Ложь – тип элемента формы не подтвержден. // Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт Если Ложь ИЛИ пТип = Тип("Индикатор") ИЛИ пТип = Тип("Кнопка") ИЛИ пТип = Тип("КоманднаяПанель") ИЛИ пТип = Тип("Надпись") ИЛИ пТип = Тип("Панель") ИЛИ пТип = Тип("Переключатель") ИЛИ пТип = Тип("ПолеВвода") ИЛИ пТип = Тип("ПолеВыбора") ИЛИ пТип = Тип("ПолеСписка") ИЛИ пТип = Тип("ПолеТекстовогоДокумента") ИЛИ пТип = Тип("ПолеТабличногоДокумента") ИЛИ пТип = Тип("ПолосаРегулирования") ИЛИ пТип = Тип("ТабличноеПоле") ИЛИ пТип = Тип("РамкаГруппы") ИЛИ пТип = Тип("Флажок") Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиТипЭлементаФормыЛкс() // Получает структуру свойств объекта по имени типа или объекту. // Свойства должны располагаться в порядке: // - общие, // - ролевые в порядке невлияния на предшествующие. // // Параметры: // пОбъект - Произвольный - имя типа или сам объект; // пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения. // // Возвращаемое значение: // – Структура – свойств. // Функция ПолучитьСтруктуруСвойствОбъектаЛкс(пОбъект, пЛиДляСохранения = Ложь) Экспорт СтруктураСвойств = Новый Структура; ТипОбъекта = ТипЗнч(пОбъект); МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта); Если МетаОбъект <> Неопределено Тогда КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект, Истина); Если Ложь ИЛИ КорневойТип = "Обработка" ИЛИ КорневойТип = "Отчет" Тогда Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; КонецЕсли; Если ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; КонецЕсли; Если Истина И ТипОбъекта <> Тип("Тип") И ТипОбъекта <> Тип("ОписаниеТипов") И ТипОбъекта <> Тип("ОбъектМетаданных") Тогда Если ПолучитьКорневойТипСпискаЛкс(ТипОбъекта) <> Неопределено Тогда СтруктураСвойств.Вставить("Колонки"); СтруктураСвойств.Вставить("Порядок"); СтруктураСвойств.Вставить("Отбор"); ИначеЕсли ЛиНаборЗаписейРегистраЛкс(ТипОбъекта) Тогда СтруктураСвойств.Вставить("Отбор"); КонецЕсли; КонецЕсли; //ИначеЕсли Ложь // ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели") // ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля") // ИЛИ ТипОбъекта = Тип("СтраницыПанели") // ИЛИ ТипОбъекта = Тип("ЭлементыФормы") // ИЛИ ТипОбъекта = Тип("ПоляНастройки") //Тогда // Для Каждого Элемент Из пОбъект Цикл // СтруктураСвойств.Вставить(Элемент.Имя); // КонецЦикла; // ИначеЕсли Ложь Или ТипОбъекта = Тип("СтрокаТаблицыЗначений") Или ТипОбъекта = Тип("СтрокаДереваЗначений") Тогда Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; ИначеЕсли ЛиТипЭлементаФормыЛкс(ТипОбъекта) Тогда СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("ИзменяетДанные"); СтруктураСвойств.Вставить("ПервыйВГруппе"); СтруктураСвойств.Вставить("ПропускатьПриВводе"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КонтекстноеМеню"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("Лево"); СтруктураСвойств.Вставить("Верх"); СтруктураСвойств.Вставить("Высота"); СтруктураСвойств.Вставить("Ширина"); КонецЕсли; СтруктураСвойств.Вставить("Подсказка"); СтруктураСвойств.Вставить("ПорядокОбхода"); СтруктураСвойств.Вставить("ПорядокОтображения"); СтруктураСвойств.Вставить("ПрозрачныйФон"); СтруктураСвойств.Вставить("Рамка"); Если ТипОбъекта = Тип("Кнопка") Тогда СтруктураСвойств.Вставить("РежимМеню"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("МногострочныйРежим"); СтруктураСвойств.Вставить("ПоложениеКартинки"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("Шрифт"); СтруктураСвойств.Вставить("Кнопки"); ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда СтруктураСвойств.Вставить("АвтоЗаполнение"); СтруктураСвойств.Вставить("Вспомогательная"); СтруктураСвойств.Вставить("ВыравниваниеКнопок"); СтруктураСвойств.Вставить("ИсточникДействий"); СтруктураСвойств.Вставить("Кнопки"); СтруктураСвойств.Вставить("Ориентация"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда СтруктураСвойств.Вставить("БегущаяСтрока"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ГиперСсылка"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Панель") Тогда СтруктураСвойств.Вставить("Страницы"); СтруктураСвойств.Вставить("АвтоПорядокОбхода"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("ОтображениеЗакладок"); СтруктураСвойств.Вставить("ПорядокОбхода"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("РаспределятьПоСтраницам"); СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("ТекущаяСтраница"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ВыбираемоеЗначение"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ПоложениеЗаголовка"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ОграничениеТипа"); СтруктураСвойств.Вставить("КнопкаВыбора"); СтруктураСвойств.Вставить("РежимВыбораИзСписка"); СтруктураСвойств.Вставить("КнопкаСпискаВыбора"); СтруктураСвойств.Вставить("СписокВыбора"); СтруктураСвойств.Вставить("АвтоВыборНезаполненного"); СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного"); СтруктураСвойств.Вставить("АвтоПереносСтрок"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("БыстрыйВыбор"); СтруктураСвойств.Вставить("ВыбиратьТип"); СтруктураСвойств.Вставить("ВыборГруппИЭлементов"); СтруктураСвойств.Вставить("ВыборНезаполненного"); СтруктураСвойств.Вставить("ВыборПоВладельцу"); СтруктураСвойств.Вставить("ВыделенныйТекст"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ВысотаСпискаВыбора"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КартинкаКнопкиВыбора"); СтруктураСвойств.Вставить("КнопкаОткрытия"); СтруктураСвойств.Вставить("КнопкаОчистки"); СтруктураСвойств.Вставить("КнопкаРегулирования"); СтруктураСвойств.Вставить("МаксимальноеЗначение"); СтруктураСвойств.Вставить("Маска"); СтруктураСвойств.Вставить("МинимальноеЗначение"); СтруктураСвойств.Вставить("МногострочныйРежим"); СтруктураСвойств.Вставить("ОтметкаНезаполненного"); СтруктураСвойств.Вставить("РасширенноеРедактирование"); СтруктураСвойств.Вставить("РедактированиеТекста"); СтруктураСвойств.Вставить("РежимВыбораНезаполненного"); СтруктураСвойств.Вставить("РежимПароля"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ШиринаСпискаВыбора"); СтруктураСвойств.Вставить("Шрифт"); СтруктураСвойств.Вставить("ЭлементСвязиПоТипу"); СтруктураСвойств.Вставить("Значение"); ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ВысотаСпискаВыбора"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КартинкаКнопкиВыбора"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("КнопкаВыбора"); СтруктураСвойств.Вставить("КнопкаОткрытия"); СтруктураСвойств.Вставить("КнопкаОчистки"); СтруктураСвойств.Вставить("КнопкаРегулирования"); СтруктураСвойств.Вставить("СписокВыбора"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ШиринаСпискаВыбора"); СтруктураСвойств.Вставить("Значение"); ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ОтображатьКартинку"); СтруктураСвойств.Вставить("ОтображатьПометку"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ТекущаяСтрока"); ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда // **** Доделать СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("АвтоВводНовойСтроки"); СтруктураСвойств.Вставить("АвтоКонтекстноеМеню"); СтруктураСвойств.Вставить("АвтоОбновление"); СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию"); СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку"); СтруктураСвойств.Вставить("Дерево"); СтруктураСвойств.Вставить("ИерархическийПросмотр"); СтруктураСвойств.Вставить("ИзменятьАвтоОбновление"); СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр"); СтруктураСвойств.Вставить("ИзменятьСпособРедактирования"); СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя"); СтруктураСвойств.Вставить("ПериодАвтоОбновления"); СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки"); СтруктураСвойств.Вставить("РодительВерхнегоУровня"); СтруктураСвойств.Вставить("РежимВыбора"); СтруктураСвойств.Вставить("РежимВыделения"); СтруктураСвойств.Вставить("РежимВыделенияСтроки"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("СпособРедактирования"); СтруктураСвойств.Вставить("ТекущийРодитель"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("Колонки"); СтруктураСвойств.Вставить("НастройкаОтбора"); СтруктураСвойств.Вставить("НастройкаПорядка"); СтруктураСвойств.Вставить("ТекущаяКолонка"); СтруктураСвойств.Вставить("ТекущаяСтрока"); СтруктураСвойств.Вставить("ТекущиеДанные"); СтруктураСвойств.Вставить("ВыделенныеСтроки"); // **** //ВертикальнаяПолосаПрокрутки //ВертикальныеЛинии //Вывод //ВысотаПодвала //ВысотаШапки //ГоризонтальнаяПолосаПрокрутки //ГоризонтальныеЛинии //ИзменятьНастройкуКолонок //ИзменятьПозициюКолонок //ИзменятьПорядокСтрок //ИзменятьСоставСтрок //НачальноеОтображениеДерева //НачальноеОтображениеСписка //Подвал //ПропускатьПриВводе //РазрешитьНачалоПеретаскивания //РазрешитьПеретаскивание //РежимВводаСтрок //ФиксацияСлева //ФиксацияСправа //ЦветТекста //ЦветТекстаВыделения //ЦветТекстаКнопки //ЦветТекстаПодвала //ЦветТекстаШапки //ЦветФона //ЦветФонаВыделения //ЦветФонаКнопки //ЦветФонаПодвала //ЦветФонаЧередованияСтрок //ЦветФонаШапки //ЧередованиеЦветовСтрок //Шапка //Ширина //Шрифт //ШрифтПодвала //ШрифтШапки ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ОтображатьВыделение"); СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания"); СтруктураСвойств.Вставить("РазрешитьПеретаскивание"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("ЦветРамки"); ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда СтруктураСвойств.Вставить("ТриСостояния"); СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ПоложениеЗаголовка"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаПоля"); КонецЕсли; ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда СтруктураСвойств.Вставить("ТипКнопки"); СтруктураСвойств.Вставить("Действие"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("ИзменяетДанные"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КнопкаПоУмолчанию"); СтруктураСвойств.Вставить("Кнопки"); СтруктураСвойств.Вставить("Отображение"); СтруктураСвойств.Вставить("Подсказка"); СтруктураСвойств.Вставить("Пометка"); СтруктураСвойств.Вставить("ПорядокКнопок"); СтруктураСвойств.Вставить("Пояснение"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("Текст"); ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КартинкаЗаголовка"); СтруктураСвойств.Вставить("Раскрыта"); ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда СтруктураСвойств.Вставить("АвтоВысотаЯчейки"); СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного"); СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ВысотаЯчейки"); СтруктураСвойств.Вставить("ГиперСсылка"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ДанныеФлажка"); СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КартинкаПодвала"); СтруктураСвойств.Вставить("КартинкаШапки"); СтруктураСвойств.Вставить("КартинкиСтрок"); СтруктураСвойств.Вставить("ОтображатьВПодвале"); СтруктураСвойств.Вставить("ОтображатьВШапке"); СтруктураСвойств.Вставить("ОтображатьИерархию"); СтруктураСвойств.Вставить("ПодсказкаВШапке"); СтруктураСвойств.Вставить("Положение"); СтруктураСвойств.Вставить("ПропускатьПриВводе"); СтруктураСвойств.Вставить("РежимРедактирования"); СтруктураСвойств.Вставить("ТекстПодвала"); СтруктураСвойств.Вставить("ТекстШапки"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ТриСостоянияФлажка"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветТекстаПодвала"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветТекстаШапки"); СтруктураСвойств.Вставить("ЦветФонаПодвала"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ЦветФонаШапки"); СтруктураСвойств.Вставить("Ширина"); СтруктураСвойств.Вставить("ШрифтПодвала"); СтруктураСвойств.Вставить("ШрифтТекста"); СтруктураСвойств.Вставить("ШрифтШапки"); СтруктураСвойств.Вставить("ЭлементУправления"); СтруктураСвойств.Вставить("ИзменениеРазмера"); СтруктураСвойств.Вставить("ИзменятьВидимость"); СтруктураСвойств.Вставить("ИзменятьНастройку"); СтруктураСвойств.Вставить("ИзменятьПозицию"); ИначеЕсли ТипОбъекта = Тип("Форма") Тогда СтруктураСвойств.Вставить("АвтоЗаголовок"); СтруктураСвойств.Вставить("Высота"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ЗакрыватьПриВыборе"); СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца"); СтруктураСвойств.Вставить("ИзменениеРазмера"); СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна"); СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна"); СтруктураСвойств.Вставить("КартинкаЗаголовка"); СтруктураСвойств.Вставить("КлючУникальности"); СтруктураСвойств.Вставить("МножественныйВыбор"); СтруктураСвойств.Вставить("Модифицированность"); СтруктураСвойств.Вставить("НачальноеЗначениеВыбора"); СтруктураСвойств.Вставить("Панель"); СтруктураСвойств.Вставить("ПоведениеКлавишиEnter"); СтруктураСвойств.Вставить("ПоложениеОкна"); СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна"); СтруктураСвойств.Вставить("РазрешитьСоединятьОкно"); СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное"); СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное"); СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся"); СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное"); СтруктураСвойств.Вставить("РежимВыбора"); СтруктураСвойств.Вставить("РежимРабочегоСтола"); СтруктураСвойств.Вставить("СоединяемоеОкно"); СтруктураСвойств.Вставить("СостояниеОкна"); СтруктураСвойств.Вставить("СпособОтображенияОкна"); СтруктураСвойств.Вставить("Стиль"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("Ширина"); СтруктураСвойств.Вставить("ЭлементыФормы"); СтруктураСвойств.Вставить("ТекущийЭлемент"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("ВладелецФормы"); СтруктураСвойств.Вставить("МодальныйРежим"); КонецЕсли; ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПостроительОтчета") ИЛИ пОбъект = "ПостроительОтчета" Тогда СтруктураСвойств.Вставить("Текст"); СтруктураСвойств.Вставить("ДоступныеПоля"); СтруктураСвойств.Вставить("ВыбранныеПоля"); СтруктураСвойств.Вставить("ИзмеренияКолонки"); СтруктураСвойств.Вставить("ИзмеренияСтроки"); СтруктураСвойств.Вставить("Отбор"); СтруктураСвойств.Вставить("Параметры"); // не все ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПолеНастройки") ИЛИ пОбъект = "ПолеНастройки" Тогда СтруктураСвойств.Вставить("Измерение"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Отбор"); СтруктураСвойств.Вставить("Поле"); СтруктураСвойств.Вставить("Порядок"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("СписокЗначений"); СтруктураСвойств.Вставить("ТипЗначения"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("Поля"); СтруктураСвойств.Вставить("Родитель"); КонецЕсли; ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета") ИЛИ пОбъект = "ИзмерениеПостроителяОтчета" Тогда СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("ТипИзмерения"); // не все ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета") ИЛИ пОбъект = "ПолеПостроителяОтчета" Тогда СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ЭлементОтбора") ИЛИ пОбъект = "ЭлементОтбора" Тогда СтруктураСвойств.Вставить("ВидСравнения"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ЗначениеПо"); СтруктураСвойств.Вставить("ЗначениеС"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Использование"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("ТипЗначения"); КонецЕсли; Возврат СтруктураСвойств; КонецФункции // ПолучитьСтруктуруСвойствОбъектаЛкс() // Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно. // // Параметры: // *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено; // *СтартоваяСтрока - Число, *0 - стартовое смещение строки; // *СтартоваяКолонка - Число, *0 - стартовое смещение колонки; // *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса; // *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо Сообщить(). // *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено; // *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка. // // Возвращаемое значение: // Строка – истинное описание ошибки. // Функция ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента = Неопределено, СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено, ИмяМодуля = Неопределено, ПредставлениеКонтекста = "") Экспорт НомерСтроки = 0; Если ИмяМодуля <> Неопределено Тогда Вступление = Символы.Таб; Иначе Вступление = ""; КонецЕсли; Если ИнформацияОбОшибке = Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); КонецЕсли; ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(ОписаниеОшибки, Истина, ЛиМодально); Если Истина И ЯзыкПрограммы = 0 И ИмяМодуля <> Неопределено И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Возврат ОписаниеОшибки; КонецЕсли; Если ЯзыкПрограммы = 2 Тогда Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; Выражение = ""; Если Выражение = "" Тогда Маркер = "Ошибка в выражении """; Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3); КонецЕсли; КонецЕсли; Если Выражение = "" Тогда Маркер = "Поле не найдено """; Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда МаркерНайден = Истина; Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1); КонецЕсли; КонецЕсли; Если Выражение <> "" Тогда ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст(); ПозицияВыражения = Найти(ТекстПоля, Выражение); Если ПозицияВыражения > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение)); Пустышка = 0; НомерСтроки = 0; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка); КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ИнформацияОбОшибке.Причина <> Неопределено И ИнформацияОбОшибке.ИмяМодуля <> "" И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ФигурноеОписаниеОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь); Если ФигурноеОписаниеОшибки <> Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И ИнформацияОбОшибке.ИмяМодуля <> "" И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; МаксимальныйНомерСтроки = 100000; Если ПолеТекстовогоДокумента <> Неопределено Тогда МаксимальныйНомерСтроки = ПолеТекстовогоДокумента.КоличествоСтрок(); КонецЕсли; ФигурноеОписаниеОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Описание, "{", "}", Ложь); ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если НомерСтроки = 0 Тогда НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки); Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда СтрокаКоординатыОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ФигурноеОписаниеОшибки, "(", ")", Ложь); Если СтрокаКоординатыОшибки <> Неопределено Тогда НомерКолонки = 0; МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаКоординатыОшибки, ","); СтрокаНомерСтроки = МассивФрагментов[0]; Попытка НомерСтроки = Число(СтрокаНомерСтроки); Исключение КонецПопытки; НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки); Если МассивФрагментов.Количество() > 1 Тогда СтрокаНомерКолонки = МассивФрагментов[1]; Попытка НомерКолонки = Число(СтрокаНомерКолонки); Исключение КонецПопытки; НомерКолонки = НомерКолонки + СтартоваяКолонка; КонецЕсли; Если НомерСтроки = 0 Тогда НомерКолонки = 1; НомерСтроки = 1; КонецЕсли; ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")"); КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И НомерСтроки <= 0 Тогда Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки; Иначе ОписаниеОшибки = "Ошибка без описания"; КонецЕсли; Иначе ОписаниеОшибки = "Строка кода " + НомерСтроки + ": " + ОписаниеОшибки; КонецЕсли; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; ТекстСообщения = ""; Если ПолеТекстовогоДокумента <> Неопределено Тогда Если НомерСтроки > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 1000); КонецЕсли; ТекстСообщения = ТекстСообщения + ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста; ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки; ПолныйТекстСообщения = Вступление + ТекстСообщения; Если ЛиМодально Тогда Предупреждение(ТекстСообщения); Иначе Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное); КонецЕсли; Иначе ПолныйТекстСообщения = Вступление + ТекстСообщения; Если ЛиМодально Тогда Предупреждение(ОписаниеОшибки); Иначе Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное); КонецЕсли; КонецЕсли; Возврат ПолныйТекстСообщения; КонецФункции Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт Результат = Ложь; Если Истина //И (Ложь // Или Не ирКэш.ЛиПортативныйРежимЛкс() // Или ирПортативный.ЛиСерверныйМодульДоступенЛкс()) И Найти(ОписаниеОшибки, "мутабельн") > 0 И Найти(ОписаниеОшибки, "Записать") > 0 Тогда ТекстСообщения = "Чтобы избежать ошибки передачи мутабельного значения при записи объектов, используйте "; Если ЭтоПроизвольныйАлгоритм Тогда ТекстСообщения = ТекстСообщения + "функцию ""ирОбщий.ЗаписатьОбъектЛкс(Объект, Истина)"""; Иначе ТекстСообщения = ТекстСообщения + "опцию ""Запись на сервере"" инструмента"; КонецЕсли; Если ирКэш.ЛиПортативныйРежимЛкс() И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс() Тогда ТекстСообщения = ТекстСообщения + ", которая станет доступной после указания пользователя внешнего соединения в настройках инструментов"; КонецЕсли; Если ЛиМодально Тогда Предупреждение(ТекстСообщения); Иначе Сообщить(ТекстСообщения, СтатусСообщения.Внимание); КонецЕсли; Результат = Истина; КонецЕсли; Возврат Результат; КонецФункции // ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс() // Рассчитыват и устанавливает ширину колонок табличного документа. Ориентирована на обработку // результата построителя отчета. // // Параметры: // ТабличныйДокумент – ТабличныйДокумент; // *ЛиМинимальный – Булево, *Ложь – признак установки необходимой ширины, иначе достаточной; // *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием; // *ШиринаОбластиПолей - Число, *0 - ширина области полей (не показателей); // *РассчитыватьШиринуКолонкиПоНазванию - Булево, *Истина - признак расчета ширины колонки по названию; // *МинимальнаяШиринаКолонкиПоказатель - Число, *10 - минимальная ширина колонки показателя; // *ПорогКоличестваЯчеекДляАнализа - Число, *100000 - пороговое количество ячеек для анализа (усечение по высоте). // Процедура УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(ТабличныйДокумент, ЛиМинимальный = Ложь, ЛиИгнорироватьОбрезание = Ложь, ШиринаОбластиПолей = 0, РассчитыватьШиринуКолонкиПоНазванию = Ложь, МинимальнаяШиринаКолонкиПоказатель = 10, ПорогКоличестваЯчеекДляАнализа = 10000) Экспорт Перем МаксимальнаяШиринаКолонки; Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных; Перем ОбластьШапки, ОбластьПодвала; Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста; Перем КоличествоУровнейГруппировокСтрок, Отступ; Перем ШириныКолонок; СтрокаСостояния = "Расчет ширины колонок табличного документа "; КоличествоОбновленийСостояния = 10; // Ограничение максимальной ширины колонки МаксимальнаяШиринаКолонки = 50; // Массив, в который будут помещаться ширины колонок ШириныКолонок = Новый Массив; // Получим количество уровней группировок в отчете для учета автоматического отступа КоличествоУровнейГруппировокСтрок = ТабличныйДокумент.КоличествоУровнейГруппировокСтрок(); // Инициализируем начальные строки НачальнаяСтрока = 0; НачалоДанных = 0; // Найдем в результирующем документе область шапки таблицы ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаТаблицы"); Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины НачальнаяСтрока = ОбластьШапки.Верх; НачалоДанных = ОбластьШапки.Низ + 1; Иначе // Если область шапки таблицы не найдена, найдем область шапки строк ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаСтрок"); Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины НачальнаяСтрока = ОбластьШапки.Верх; НачалоДанных = ОбластьШапки.Низ + 1; КонецЕсли; КонецЕсли; // Получим область подвала отчета и вычислим конечную строку расчета ОбластьПодвала = ТабличныйДокумент.Области.Найти("Подвал"); Если ТипЗнч(ОбластьПодвала) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Область подвала найдена КонечнаяСтрока = ОбластьПодвала.Верх - 1; Иначе // Область подвала не найдена КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы; КонецЕсли; СтарыйПрогресс = 0; КоличествоЯчеекПоказателейДляРасчета = (КонечнаяСтрока - НачальнаяСтрока) * (ТабличныйДокумент.ШиринаТаблицы - 1); Если КоличествоЯчеекПоказателейДляРасчета > ПорогКоличестваЯчеекДляАнализа Тогда КонечнаяСтрока = Мин(КонечнаяСтрока, ПорогКоличестваЯчеекДляАнализа / (ТабличныйДокумент.ШиринаТаблицы - 1)); КонецЕсли; // Переберем все колонки отчета Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ПрогрессКолонок = ТекущаяКолонка / ТабличныйДокумент.ШиринаТаблицы / КонечнаяСтрока; АвтоОтступ = 0; // Переберем строки, которые будут использованы для расчета ширин колонок Для ТекущаяСтрока = НачальнаяСтрока По КонечнаяСтрока Цикл ОбработкаПрерыванияПользователя(); Прогресс = КоличествоОбновленийСостояния * ПрогрессКолонок * ТекущаяСтрока; Если Прогресс - СтарыйПрогресс >= 1 Тогда СтарыйПрогресс = Прогресс; СостояниеЛкс(СтрокаСостояния + Цел(100 * ПрогрессКолонок * ТекущаяСтрока) + "%"); КонецЕсли; ШиринаКолонки = 0; // Получим область текущей ячейки ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка); Если ОбластьЯчейки.Лево <> ТекущаяКолонка Или ОбластьЯчейки.Верх <> ТекущаяСтрока Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; // Данная ячейка обрезает текст Если Истина И ЛиИгнорироватьОбрезание И ОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Обрезать Тогда Продолжить; КонецЕсли; Если КоличествоУровнейГруппировокСтрок > 0 И ТекущаяСтрока = НачалоДанных Тогда // Для первой строки с данными получим значение автоотступа АвтоОтступ = ОбластьЯчейки.АвтоОтступ; КонецЕсли; // Получим текст ячейки ТекстЯчейки = ОбластьЯчейки.Текст; КоличествоСтрокВТекстеЯчейки = СтрЧислоСтрок(ТекстЯчейки); // Для каждой строки из текста ячейки рассчитаем количество символов в строке Для НомерСтрокиТекста = 1 По КоличествоСтрокВТекстеЯчейки Цикл ШиринаТекстаЯчейки = СтрДлина(СтрПолучитьСтроку(ТекстЯчейки, НомерСтрокиТекста)); Если Истина И НЕ РассчитыватьШиринуКолонкиПоНазванию И ТекущаяСтрока < НачалоДанных И ШиринаТекстаЯчейки > 0 Тогда ШиринаТекстаЯчейки = МинимальнаяШиринаКолонкиПоказатель; КонецЕсли; // Если используется автоотступ, то прибавим к ширине ячейки его величину Если АвтоОтступ <> Неопределено И АвтоОтступ > 0 Тогда ШиринаТекстаЯчейки = ШиринаТекстаЯчейки + КоличествоУровнейГруппировокСтрок * АвтоОтступ; КонецЕсли; ШиринаКолонки = Макс(ШиринаКолонки, ШиринаТекстаЯчейки); КонецЦикла; Если ШиринаКолонки > МаксимальнаяШиринаКолонки Тогда // Ограничим ширину колонки ШиринаКолонки = МаксимальнаяШиринаКолонки; КонецЕсли; Если ШиринаКолонки <> 0 Тогда // Ширина колонки рассчитана // Определим, сколько ячеек по ширине используется в области для текущей ячейки КоличествоКолонок = ОбластьЯчейки.Право - ОбластьЯчейки.Лево; // Переберем все ячейки, расположенные в области Для НомерКолонки = 0 По КоличествоКолонок Цикл Если ШириныКолонок.ВГраница() >= ТекущаяКолонка - 1 + НомерКолонки Тогда // В массиве ширин колонок уже был элемент для текущей колонки Если ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Неопределено Тогда // Значение ширины колонки еще не было установлено ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = ШиринаКолонки / (КоличествоКолонок + 1); Иначе // Значение ширины колонки уже было установлено // Вычислим максимум ширины колонки ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Макс(ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки], ШиринаКолонки / (КоличествоКолонок + 1)); КонецЕсли; Иначе // В массиве ширин колонок еще не было элемента для данной колонки // Добавим элемент в массив ширин колонок ШириныКолонок.Вставить(ТекущаяКолонка - 1 + НомерКолонки, ШиринаКолонки / (КоличествоКолонок + 1)); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; // Конец цикла перебора строк КонецЦикла; // Конец цикла перебора колонок // Переберем все элементы в массиве вычисленных ширин колонок Для ТекущаяКолонка = 0 По ШириныКолонок.ВГраница() Цикл Если ШиринаОбластиПолей >= ТекущаяКолонка Тогда УстановитьМинимальнуюШирину = Ложь; Иначе УстановитьМинимальнуюШирину = ЛиМинимальный; КонецЕсли; Если ШириныКолонок[ТекущаяКолонка] <> Неопределено Тогда ОбластьКолонки = ТабличныйДокумент.Область(, ТекущаяКолонка + 1, НачалоДанных, ТекущаяКолонка + 1); // Ширина колонок установлена // Установим ширину области ячеек Если УстановитьМинимальнуюШирину Тогда ОбластьКолонки.ШиринаКолонки = Макс(ШириныКолонок[ТекущаяКолонка] + 1, МинимальнаяШиринаКолонкиПоказатель); Иначе ОбластьКолонки.ШиринаКолонки = ШириныКолонок[ТекущаяКолонка] + 1; КонецЕсли; КонецЕсли; КонецЦикла; СостояниеЛкс(""); КонецПроцедуры // УстановитьАвтоширинуКолонокТабличногоДокументаЛкс() // Устанавливает отбор построителя по расшифровке, содержащей NULL'ы. // Устанавливает значение каждого NULL элемента отбора в "<Отсутствует>" и вид сравнения в "Равно". // Для измерений, которые могут содержать значенение "NULL" в запросах в секции условий построителя следует // писать "ЕСТЬNULL(ПутьКДаннымИзмерения, "<Отсутствует>") КАК ИмяИзмерения". // // Параметры: // пПостроительОтчета – ПостроительОтчета – чей отбор обрабатываем; // пРасшифровка - Структура - расшифровка. // Процедура УстановитьОтборПостроителяПриРасшифровкеЛкс(пПостроительОтчета, пРасшифровка) Экспорт Для каждого ЭлементРасшифровки Из пРасшифровка Цикл Если ЭлементРасшифровки.Значение = NULL Тогда ЭлементОтбора = пПостроительОтчета.Отбор[ЭлементРасшифровки.Ключ]; Если ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка")) Тогда ЭлементОтбора.Значение = "<Отсутствует>"; Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.Равно; КонецЕсли; Иначе Сообщить("Запрос не поддерживает расшифровку по отсутствующему значению элемента отбора """ + ЭлементОтбора.Представление + """!"); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // УстановитьОтборПостроителяПриРасшифровкеЛкс() // Получает копию построителя отчетов. // // Параметры: // Оригинал – ПостроительОтчета. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ПолучитьКопиюПостроителяОтчетаЛкс(Оригинал, ВосстанавливатьНастройки = Истина) Экспорт Копия = Новый ПостроительОтчета; Для Каждого ДоступноеПоле Из Оригинал.ДоступныеПоля Цикл ЗаполнитьЗначенияСвойств(Копия.ДоступныеПоля.Добавить(ДоступноеПоле.Имя, ДоступноеПоле.Представление), ДоступноеПоле); КонецЦикла; Если ВосстанавливатьНастройки Тогда Копия.Текст = Оригинал.Текст; Копия.ЗаполнитьНастройки(); // Баг платформы. Без этого почему то иногда измерения не восстанавливаются! Копия.УстановитьНастройки(Оригинал.ПолучитьНастройки()); КонецЕсли; Возврат Копия; КонецФункции // ПолучитьКопиюПостроителяОтчетаЛкс() // Возвращает менеджер временных таблиц, в котором создана временная таблица по переданному источнику. // // Параметры: // ВнешнийИсточник – ТаблицаЗначений; // ИмяТаблицы – Строка; // *МенеджерВременныхТаблиц – МенеджерВременныхТаблиц, *Неопределено. // // Возвращаемое значение: // МенеджерВременныхТаблиц. // Функция ПолучитьВременнуюТаблицуЛкс(ВнешнийИсточник, ИмяТаблицы, МенеджерВременныхТаблиц = Неопределено) Экспорт Если МенеджерВременныхТаблиц = Неопределено Тогда МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; КонецЕсли; ТекстВЫБРАТЬ = ""; Для Каждого Колонка Из ВнешнийИсточник.Колонки Цикл ТекстВЫБРАТЬ = ТекстВЫБРАТЬ + ", " + Колонка.Имя; КонецЦикла; ТекстЗапроса = "ВЫБРАТЬ " + Сред(ТекстВЫБРАТЬ, 3); ТекстЗапроса = ТекстЗапроса + " ПОМЕСТИТЬ " + ИмяТаблицы; ТекстЗапроса = ТекстЗапроса + " ИЗ &ВнешнийИсточник КАК ВнешнийИсточник"; Запрос = Новый Запрос(ТекстЗапроса); Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; Запрос.УстановитьПараметр("ВнешнийИсточник", ВнешнийИсточник); Запрос.Выполнить(); Возврат МенеджерВременныхТаблиц; КонецФункции // ПолучитьВременнуюТаблицуЛкс() Функция ПолучитьТекстСостоянияИндикатораЛкс(Индикатор) Экспорт Счетчик = Индикатор.Счетчик; Если Истина И Индикатор.ЛиВыводитьВремя И Счетчик > 0 И Счетчик < Индикатор.КоличествоПроходов Тогда ТекущаяДата = ТекущаяДата(); ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса; Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1); ОсталосьДней = Цел(Осталось / (24*60*60)); ТекстОсталось = ", Осталось: ~"; Если ОсталосьДней > 0 Тогда ТекстОсталось = ТекстОсталось + ОсталосьДней + "д"; КонецЕсли; ТекстОсталось = ТекстОсталось + формат(Дата(1,1,1) + Осталось, "ДЛФ=T"); Иначе ТекстОсталось = ""; КонецЕсли; Если Индикатор.КоличествоПроходов > 0 Тогда ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось; Иначе ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " "; КонецЕсли; Возврат ТекстСостояния; КонецФункции // ПолучитьТекстСостоянияИндикатораЛкс() // Открывает справку по первой подсистеме метаданных переданного объекта // // Параметры: // Объект - любой объект, имеющий метаданные. // Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт Если Ложь Или ТипЗнч(Объект) = Тип("Неопределено") Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения") Тогда // ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда ПолноеИмяМД = СлужебныеДанныеФормыЛкс(Объект).ИмяФормы; ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда ПолноеИмяМД = Объект.ИмяФормы; Иначе Если ТипЗнч(Объект) = Тип("Тип") Тогда ОбъектМД = Метаданные.НайтиПоТипу(Объект); Иначе ОбъектМД = Объект.Метаданные(); КонецЕсли; ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешняяОбработка.", "Обработка."); ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешнийОтчет.", "Отчет."); КонецЕсли; Форма = ирКэш.Получить().ПолучитьФорму("ОПодсистеме",, ПолноеИмяМД); Форма.Открыть(); КонецПроцедуры // ОткрытьСправкуПоПодсистемеЛкс() Процедура ПанельИнструментовОПодсистемеЛкс() Экспорт ОткрытьСправкуПоПодсистемеЛкс(); КонецПроцедуры // Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицой или деревом значений. // Процедура ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ТабличноеПоле) Экспорт Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда Возврат; КонецЕсли; ФормаОбработки = ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма"); Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; СписокВыбора = Новый СписокЗначений; СписокВыбора.Добавить(0, "Создать группы дублей из пар неправильных значений текущей и правильных значений следующей колонок"); СписокВыбора.Добавить(1, "Создать одну группу дублей из значений текущей колонки выделенных строк"); //СписокВыбора.Добавить(2, "Создать правила замены значений из текущей колонки на значения следующей колонки"); ВыбранныйВариант = СписокВыбора.ВыбратьЭлемент("Выберите вариант"); Если ВыбранныйВариант = Неопределено Тогда Возврат; КонецЕсли; Если ВыбранныйВариант.Значение = 1 Тогда Если ВыделенныеСтроки.Количество() = 0 Тогда Возврат ; КонецЕсли; ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Возврат; КонецЕсли; МассивСсылок = Новый Массив; Для Каждого Строка Из ВыделенныеСтроки Цикл ЗначениеСтроки = Строка[ИмяКолонки]; ТипЗначения = ТипЗнч(ЗначениеСтроки); Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда Продолжить; КонецЕсли; МассивСсылок.Добавить(ЗначениеСтроки); КонецЦикла; ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок,, 0); ИначеЕсли ВыбранныйВариант.Значение = 0 Тогда ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка; Если Ложь Или ТекущаяКолонка = Неопределено Или ТекущаяКолонка.Данные = "" Тогда Возврат; КонецЕсли; ИндексКолонки = ТабличноеПоле.Колонки.Индекс(ТекущаяКолонка); Если ТабличноеПоле.Колонки.Количество() = ИндексКолонки + 1 Тогда Возврат; КонецЕсли; СледующаяКолонка = ТабличноеПоле.Колонки[ИндексКолонки + 1]; Если СледующаяКолонка.Данные = "" Тогда Возврат; КонецЕсли; ФормаОбработки.ОткрытьСЗаполнениемГруппДублейПоТаблицеПар(ТабличноеПоле.Значение, ТекущаяКолонка.Данные, СледующаяКолонка.Данные); КонецЕсли; ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя); КонецЕсли; КонецПроцедуры // ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс() //////////////////////////////////////////////////////////////////////////////// // ТЕХНОЛОГИЯ КОМПОНЕНТ // Возвращает кнопку командной панели компоненты по ее имени из макета. // // Параметры: // ОбъектКомпоненты - ОбработкаОбъект - компонента; // КраткоеИмяКнопки – Строка - имя кнопки из макета компоненты; // *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей. // // Возвращаемое значение: // Кнопка. // Функция ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Знач КоманднаяПанель = Неопределено) Экспорт Если КоманднаяПанель = Неопределено Тогда КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель; КонецЕсли; ПолноеИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяКнопки); Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки); Если Кнопка = Неопределено Тогда Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда Продолжить; КонецЕсли; Кнопка = ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю); Если Кнопка <> Неопределено Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Возврат Кнопка; КонецФункции // ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс() // Формирует имя элемента управления экземпляра компоненты. // // Параметры: // ИмяКласса – Строка; // ИмяЭкземпляра - Строка; // КраткоеИмяЭлементаУправления – Строка. // // Возвращаемое значение: // Строка - имя. // Функция СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяЭлементаУправления) Экспорт Возврат ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) + КраткоеИмяЭлементаУправления; КонецФункции Функция ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) Экспорт Возврат ОбъектКомпоненты.ИмяКласса + "_" + ОбъектКомпоненты.Имя + "_"; КонецФункции // СформироватьИмяЭлементаУправленияЭкземпляраЛкс() // <Описание функции> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() Экспорт ТаблицаСобытий = Новый ТаблицаЗначений; ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта"); ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма"); ТаблицаСобытий.Колонки.Добавить("ИмяСобытия"); ТаблицаСобытий.Колонки.Добавить("Компонента"); ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика"); Возврат ТаблицаСобытий; КонецФункции // ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() // Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника. // // Параметры: // ОбъектКомпоненты - ОбработкаОбъект - компонента; // КнопкиМакета – КоллекцияКнопокКоманднойПанели – источник; // КнопкиПриемника – КоллекцияКнопокКоманднойПанели – приемник; // *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено; // Процедура ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника, ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено) Экспорт КнопкиПриемника = КнопкаПриемника.Кнопки; ИмяКласса = ОбъектКомпоненты.ИмяКласса; Если ДействияКнопокКомпонент = Неопределено Тогда ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие"); Иначе ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель")); ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей; ДопКнопкиКоманднойПанели = Новый Массив; ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели); ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие") КонецЕсли; ИмяЭкземпляра = ОбъектКомпоненты.Имя; Для Каждого КнопкаМакета Из КнопкиМакета Цикл Кнопка = Неопределено; Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда Если Истина И Строка(КнопкаМакета.Действие) = "" Тогда // Это пустое действие Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки); ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя"); Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя); //Попытка Кнопка.Действие = ДействиеТранслятор; //Исключение // ОписаниеОшибки = ОписаниеОшибки(); // Для отладки // Возврат; //КонецПопытки; Если ДействияКнопокКомпонент <> Неопределено Тогда СтрокаДействия = ДействияКнопокКомпонент.Добавить(); СтрокаДействия.Кнопка = Кнопка; СтрокаДействия.Компонента = ОбъектКомпоненты; ВызовОбработчика = "Действие_"; Если ОбщийПриемник = Неопределено Тогда ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя; Иначе ВызовОбработчика = ВызовОбработчика + ОбщийПриемник; КонецЕсли; СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)"; КонецЕсли; Иначе Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие); // Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда Кнопка.Картинка = КнопкаМакета.Картинка; КонецЕсли; ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Картинка"); КонецЕсли; КонецЕсли; Если Кнопка = Неопределено Тогда Кнопка = КнопкиПриемника.Добавить(); ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя"); Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя); Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник); КонецЕсли; КонецЕсли; Если Истина И ДействияКнопокКомпонент <> Неопределено И ЭтоКоманднаяПанель Тогда ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя); КонецЕсли; КонецЦикла; КонецПроцедуры // ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс() // Возвращает имя экземляра компоненты, которой принадлежит элемент управления. // // Параметры: // ЭлементУправления – ЭлементУправления. // // Возвращаемое значение: // Строка - имя. // Функция ПолучитьИмяЭкземпляраЛкс(ЭлементУправления) Экспорт Результат = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЭлементУправления.Имя, "_")[1]; Возврат Результат; КонецФункции // ПолучитьИмяЭкземпляраЛкс() // Устанавливает свойство у элементов именованной коллекции. // // Параметры: // Коллекция – Любая индексированная коллекция; // МассивИлиСтрока – Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр; // Свойство – Строка - имя Свойства которое нужно установить; // ЗначениеСвойства – Произвольный. // Процедура УстановитьСвойствоВКоллекцииЛкс(Коллекция, МассивИлиСтрока = Неопределено, Свойство, ЗначениеСвойства) Экспорт ДоступенИндексСвойств = Лев(Свойство, 1) <> "-"; Если МассивИлиСтрока <> Неопределено Тогда Если ТипЗнч(МассивИлиСтрока) = Тип("Строка") Тогда МассивИндексов = ПолучитьМассивИзСтрокиСРазделителемЛкс(МассивИлиСтрока, ",", Истина); Иначе МассивИндексов = МассивИлиСтрока; КонецЕсли; Для Каждого ИмяЭлемента Из МассивИндексов Цикл ЭлементКоллекции = Коллекция[ИмяЭлемента]; Если ДоступенИндексСвойств Тогда ЭлементКоллекции[Свойство] = ЗначениеСвойства; Иначе Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства"); КонецЕсли; КонецЦикла; Иначе Для Каждого ЭлементКоллекции Из Коллекция Цикл Если ДоступенИндексСвойств Тогда ЭлементКоллекции[Свойство] = ЗначениеСвойства; Иначе Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства"); КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры // УстановитьСвойствоВКоллекцииЛкс() Процедура ПриПолученииДанныхТабличногоПоляКолонокЛкс(ОформленияСтрок, ИмяКолонкиОписанияТипов = "ТипЗначения") Экспорт Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки; ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки[ИмяКолонкиОписанияТипов]); Если ИндексКартинки <> Неопределено Тогда ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ИндексКартинки = ИндексКартинки; КонецЕсли; КонецЦикла; КонецПроцедуры // ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс() //////////////////////////////////////////////////////////////////////////////// // КОМПОНОВКА // Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки. // // Параметры: // ОформленияСтрок – ОформленияСтрок. // Процедура ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс(ОформленияСтрок) Экспорт Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл ИндексКартинки = Неопределено; ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки; Попытка ЭтоПапка = ДанныеСтроки.Папка; ЭтоРесурс = ДанныеСтроки.Ресурс; Исключение ЭтоПапка = Ложь; ЭтоРесурс = Ложь; КонецПопытки; Если ЭтоПапка Тогда ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0; Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл Если Не ДоступноеПоле.Ресурс Тогда ПапкаСРесурсами = Ложь; Прервать; КонецЕсли; КонецЦикла; Если ПапкаСРесурсами Тогда ИндексКартинки = 17; КонецЕсли; КонецЕсли; Если Не ЭтоРесурс И Не ЭтоПапка Тогда ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки.ТипЗначения); КонецЕсли; Если ИндексКартинки <> Неопределено Тогда ОформлениеСтроки.Ячейки[0].ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки[0].ИндексКартинки = ИндексКартинки; КонецЕсли; КонецЦикла; КонецПроцедуры // ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс() // Подключает обработчики событий для табличного поля отбора компоновки данных. // // Параметры: // ТабличноеПоле – ТабличноеПоле – отбора компоновки. // Процедура ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс(ТабличноеПоле) Экспорт ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей")); ТабличноеПоле.Колонки[0].КартинкиСтрок = ПолучитьОбщуюКартинкуЛкс("ирТипыДоступныхПолейКомпоновки"); КонецПроцедуры // ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс() // Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом. // Содержит рекурсивный вызов. // // Параметры: // НаборыДанных – НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных; // *СтруктураНаборовДанных – Структура, *Неопрелено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных")) // // Возвращаемое значение: // Структура. // Функция ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт Если СтруктураНаборовДанных = Неопределено Тогда СтруктураНаборовДанных = Новый Структура; КонецЕсли; Для каждого НаборДанных Из НаборыДанных Цикл Если Ложь Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда // Платформа генерит такие наборы для служебных целей ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); Иначе ИмяНабора = НаборДанных.Имя; КонецЕсли; СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных)); ИначеЕсли Ложь Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных") Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных") Тогда ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(НаборДанных.Элементы, СтруктураНаборовДанных); КонецЕсли; КонецЦикла; Возврат СтруктураНаборовДанных; КонецФункции // ПолучитьСтруктуруНаборовДанныхЗапросовЛкс() // Получает макет компоновки данных по схеме с использованием временных таблиц. // // Параметры: // Схема – СхемаКомпоновкиДанных; // Настройки - НастройкиКомпоновкиДанных; // *ВнешниеНаборыДанных – Структура, *Неопределено - туда добавляются временные таблицы; // *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено; // *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов. // // Возвращаемое значение: // МакетКомпоновкиДанных. // Функция ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс(Схема, Настройки, ВнешниеНаборыДанных = Неопределено, ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено, ПроверятьДоступностьПолей = Ложь) Экспорт RegExp = Новый COMОбъект("VBScript.RegExp"); RegExp.Global = Истина; RegExp.MultiLine = Истина; RegExp.IgnoreCase = Истина; // Допустим 1 уровень скобок. шСкобки = "\([^\)\(]*?\)"; RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(.*?)""\)"; Если ВнешниеНаборыДанных = Неопределено Тогда ВнешниеНаборыДанных = Новый Структура; КонецЕсли; Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; // Выполним создание всех временных таблиц. Временной таблицей считаем набор данных запрос, // имя которого начинается с "@". Наборы данных временных таблиц удаляются из предварительной схемы. ПредварительнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема)); НаборыДанныхСхемы = ПредварительнаяСхема.НаборыДанных; ЕстьВременныеТаблицы = Ложь; НачальноеКоличество = НаборыДанныхСхемы.Количество(); Для СчетчикНаборыДанныхСхемы = 1 По НачальноеКоличество Цикл НаборДанных = НаборыДанныхСхемы[НачальноеКоличество - СчетчикНаборыДанныхСхемы]; Если Истина И Лев(НаборДанных.Имя, 1) = "@" И ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда ВременнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема)); // Кривое копирование набора данных в новую схемы, где он будет один. ВременнаяСхема.СвязиНаборовДанных.Очистить(); НаборыДанныхВременнойСхемы = ВременнаяСхема.НаборыДанных; НаборыДанныхВременнойСхемыВГраница = НаборыДанныхВременнойСхемы.Количество() - 1; Для СчетчикВременнойСхемы = 0 По НаборыДанныхВременнойСхемыВГраница Цикл НаборДанныхВременнойСхемы = НаборыДанныхВременнойСхемы[НаборыДанныхВременнойСхемыВГраница - СчетчикВременнойСхемы]; Если НаборДанныхВременнойСхемы.Имя <> НаборДанных.Имя Тогда НаборыДанныхВременнойСхемы.Удалить(НаборДанныхВременнойСхемы); КонецЕсли; КонецЦикла; Для Каждого ПолеНабора Из НаборыДанныхВременнойСхемы[0].Поля Цикл ПолеНабора.ОграничениеИспользования.Поле = Ложь; ПолеНабора.ВыражениеПредставления = ПолеНабора.ПутьКДанным; КонецЦикла; КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ВременнаяСхема)); КомпоновщикНастроек.ЗагрузитьНастройки(Настройки); КомпоновщикНастроек.Настройки.Структура.Очистить(); КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить(); КомпоновщикНастроек.Восстановить(); ВременныеНастройки = КомпоновщикНастроек.Настройки; // Установим использование параметров Для Каждого ЭлементПараметра Из ВременныеНастройки.ПараметрыДанных.Элементы Цикл ЭлементПараметра.Использование = Истина; КонецЦикла; // Установим структуру и выбранные поля ЭлементСтруктуры = ВременныеНастройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); Для Каждого ДоступноеПоле Из ВременныеНастройки.ДоступныеПоляВыбора.Элементы Цикл // Чтобы пропустить системные папки Если Не ДоступноеПоле.Папка Тогда НовоеВыбранноеПоле = ВременныеНастройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле; НовоеВыбранноеПоле.Использование = Истина; КонецЕсли; КонецЦикла; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ВременнаяСхема, ВременныеНастройки,,,, ПроверятьДоступностьПолей); Запрос.Текст = МакетКомпоновкиДанных.НаборыДанных[0].Запрос; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение); КонецЦикла; Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1"); ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя); //// Недоступные поля набора данных цепляются в настройках при совпадаении имен с выбранными полями //// http://partners.v8.1c.ru/forum/thread.jsp?id=514094 //Для Каждого Поле Из НаборДанных.Поля Цикл // Поле.ПутьКДанным = "_поле_" + Поле.ПутьКДанным; //КонецЦикла; НаборыДанныхСхемы.Удалить(НаборДанных); ЕстьВременныеТаблицы = Истина; КонецЕсли; КонецЦикла; Если Не ЕстьВременныеТаблицы Тогда Если ЛиОтладка Тогда ВремяНачалаКомпоновкиМакета = ПолучитьТекущееВремяВМиллисекундахЛкс(); КонецЕсли; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, Настройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей); Если ЛиОтладка Тогда Сообщить("Компоновка макета - " + Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс"); КонецЕсли; Иначе // Выполним получение результата предварительного запроса КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПредварительнаяСхема)); КомпоновщикНастроек.ЗагрузитьНастройки(Настройки); КомпоновщикНастроек.Восстановить(); ПредварительныеНастройки = КомпоновщикНастроек.Настройки; Если ЛиОтладка Тогда ВремяНачалаКомпоновкиМакета = ПолучитьТекущееВремяВМиллисекундахЛкс(); КонецЕсли; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, ПредварительныеНастройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей); Если ЛиОтладка Тогда Сообщить("Компоновка макета - " + Строка(ПолучитьТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс"); КонецЕсли; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение); КонецЦикла; СтруктураНаборовДанныхЗапросовМакета = ПолучитьСтруктуруНаборовДанныхЗапросовЛкс(МакетКомпоновкиДанных.НаборыДанных); Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных; Запрос.Текст = НаборДанных.Запрос; Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1"); РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя); ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса); КонецЦикла; // Получение конечного макета Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец; НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных; НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных")); // Копируем Свойства набора данных запроса в набор данных объекта ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос); НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя; Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл ПолеРезультата = НаборДанныхОбъект.Поля.Добавить(); ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала); ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль); КонецЦикла; КоллекцияВладелец.Удалить(НаборДанныхЗапрос); КонецЦикла; КонецЕсли; // Баг платформы. Пустая дата превращается в Неопределено. Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл Если ПараметрСхемы.ОграничениеИспользования Тогда Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя); ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение); КонецЕсли; КонецЕсли; КонецЦикла; Возврат МакетКомпоновкиДанных; КонецФункции // ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс() // Выводит результат СКД с установкой вертикальной автофиксации. // Параметры: // Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет; // ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных; // ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных; // МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей; // РазрешитьПрерывание - Булево, *Истина. // Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки, Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(Таб); ПроцессорВывода.НачатьВывод(); ФиксацияВыполнена = Ложь; Если МассивИгнорируемыхПолей = Неопределено Тогда МассивИгнорируемыхПолей = Новый Массив; КонецЕсли; Пока Истина Цикл ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий(); Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда Прервать; КонецЕсли; Если РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; // Автофиксация Если Истина И Автофиксация И Не ФиксацияВыполнена Тогда Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля(); Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда Таб.ФиксацияСверху = Таб.ВысотаТаблицы; ФиксацияВыполнена = Истина; Прервать; КонецЕсли; КонецЦикла; Если ФиксацияВыполнена Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных); Если Истина И выхЭлементыРезультата <> Неопределено И выхЭлементыРезультата.Количество() < 10000 Тогда выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных); КонецЕсли; Если РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; КонецЦикла; ПроцессорВывода.ЗакончитьВывод(); КонецПроцедуры // ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс #КонецЕсли // Переустанавливает значения недоступных параметров из схемы (антибаг платформы). // // Параметры: // СхемаКомпоновкиДанных – СхемаКомпоновкиДанных; // КомпоновщикНастроек – КомпоновщикНастроекКомпоновкиДанных. // Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт #Если Сервер И Не Сервер Тогда КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; #КонецЕсли Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр); Если Истина И ПараметрСхемы <> Неопределено И ПараметрСхемы.ОграничениеИспользования Тогда //Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда // Попытка // ЗначениеПараметра.Значение = Вычислить(); // Исключение // КонецПопытки; //Иначе ЗначениеПараметра.Значение = ПараметрСхемы.Значение; //КонецЕсли; //ЗначениеПараметра.Использование = Истина; КонецЕсли; КонецЦикла; КонецПроцедуры // ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс() Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт ПолеКоличества = "КоличествоСтрокАвто"; ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить(); ВычисляемоеПоле.Выражение = "1"; ВычисляемоеПоле.Заголовок = "Количество строк (авто)"; ВычисляемоеПоле.ПутьКДанным = ПолеКоличества; РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить(); РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества; РесурсКоличествоЗаписей.Выражение = "Сумма(1)"; КонецПроцедуры // Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений. // // Параметры: // СтруктураТаблиц – Структура – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь, ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт Если СхемаКомпоновкиДанных = Неопределено Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных); КонецЕсли; Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл КолонкиНабора = КолонкиИсточникаДанныхЛкс(КлючИЗначение.Значение); СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КолонкиНабора, КлючИЗначение.Ключ, СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей); КонецЦикла; Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных); КонецЕсли; Возврат СхемаКомпоновкиДанных; КонецФункции Функция КолонкиИсточникаДанныхЛкс(Знач ИсточникДанных) Если Ложь Или ТипЗнч(ИсточникДанных) = Тип("ДеревоЗначений") Или ТипЗнч(ИсточникДанных) = Тип("ТаблицаЗначений") Тогда КолонкиНабора = ИсточникДанных.Колонки; Иначе КолонкиНабора = ИсточникДанных.ВыгрузитьКолонки().Колонки; КонецЕсли; Возврат КолонкиНабора; КонецФункции // СоздатьСхемуПоТаблицамЗначенийЛкс() // Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки. // // Параметры: // ПоляНастройки – ПоляНастройки – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "НаборДанных1") Экспорт Если СхемаКомпоновкиДанных = Неопределено Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных); КонецЕсли; НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных")); НаборДанных.Имя = ИмяНабора; НаборДанных.ИсточникДанных = ИсточникДанных.Имя; НаборДанных.ИмяОбъекта = ИмяНабора; Для Каждого ПолеНастройки Из ПоляНастройки Цикл Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); Поле.ПутьКДанным = ПолеНастройки.Имя; Поле.Поле = ПолеНастройки.ПутьКДанным; Поле.Заголовок = ПолеНастройки.Представление; Поле.ТипЗначения = ПолеНастройки.ТипЗначения; ОграничениеИспользования = Поле.ОграничениеИспользования; ОграничениеИспользования.Поле = Не ПолеНастройки.Поле; ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор; ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок; ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение; ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0; ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов; ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения; КонецЦикла; Возврат СхемаКомпоновкиДанных; КонецФункции // СоздатьСхемуПоПолямНастройкиЛкс() // Параметры: // Поле - // Доступность - // ПрименитьГруппировка - // ПрименитьПоле - // ПрименитьПорядок - // ПрименитьУсловие - // Возвращаемое значение: // Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач Поле, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина, Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт МассивГруппОграничений = Новый Массив; МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования); Попытка МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов); Исключение КонецПопытки; Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл Если ПрименитьГруппировка Тогда ОграничениеИспользования.Группировка = Ограничивать; КонецЕсли; Если ПрименитьПоле Тогда ОграничениеИспользования.Поле = Ограничивать; КонецЕсли; Если ПрименитьПорядок Тогда ОграничениеИспользования.Порядок = Ограничивать; КонецЕсли; Если ПрименитьУсловие Тогда ОграничениеИспользования.Условие = Ограничивать; КонецЕсли; КонецЦикла; КонецФункции // Функция добавляет в схему компоновки источник данных с типом "Local" Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить(); ИсточникДанных.Имя = "ИсточникДанных1"; ИсточникДанных.ТипИсточникаДанных = "Local"; Возврат ИсточникДанных; КонецФункции // Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "НаборДанных1") Экспорт НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")); НаборДанных.Имя = ИмяНабораДанных; НаборДанных.ИсточникДанных = ИсточникДанных.Имя; Возврат НаборДанных; КонецФункции // Устаревшее! Новая - ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.ПолучитьВыражениеПорядкаКомпоновкиНаЯзыке // Получает строку для установки порядка компоновки. // // Параметры: // ПорядокКомпоновки – ПорядокКомпоновкиДанных. // // Возвращаемое значение: // Строка - для установки порядка. // Функция ПолучитьСтрокуПорядкаКомпоновкиЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено) Экспорт Строка = ""; Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл Если Ложь Или Не ЭлементПорядка.Использование Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных") Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле Тогда Продолжить; КонецЕсли; ИмяПоля = "" + ЭлементПорядка.Поле; Если СимволЗаменыТочки <> Неопределено Тогда ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки); КонецЕсли; Строка = Строка + ", " + ИмяПоля + " "; Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда Строка = Строка + "Возр"; Иначе Строка = Строка + "Убыв"; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 3); КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс() // Конструктор массива через Параметры. // // Параметры: // *п... – Произвольный – элементы массива. // // Возвращаемое значение: // Массив - полученный массив. // Функция БыстрыйМассивЛкс( п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено, п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено, п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено, п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено ) Экспорт Перем М; М = Новый Массив(); Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли; Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли; Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли; Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли; Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли; Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли; Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли; Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли; Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли; Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли; Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли; Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли; Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли; Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли; Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли; Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли; Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли; Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли; Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли; Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли; Возврат М; КонецФункции // БыстрыйМассивЛкс() //////////////////////////////////////////////////////////////////////////////// // РАБОТА СО СТРОКАМИ // <Описание функции> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // Строка - путь к файлу. // Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт Если Ложь Или ТипЗнч(Значение) = Тип("ТабличныйДокумент") Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент") Тогда Документ = Значение; Иначе Документ = Новый ТекстовыйДокумент; Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда Значение = Значение.Получить(); КонецЕсли; Если ТипЗнч(Значение) <> Тип("Строка") И ПолучатьXMLПредставлениеДляНеизвестныхТипов Тогда Представление = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение); Иначе Представление = Значение; КонецЕсли; Документ.УстановитьТекст(ПолучитьТекстИзXMLЛкс(Представление)); КонецЕсли; Путь = ПолучитьИмяВременногоФайла(Название); Документ.Записать(Путь); Возврат Путь; КонецФункции // ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс() // Получает строку путем отсечения заданного числа последних символов. // // Параметры: // пСтрока – Строка – исходная; // пДлинаКонца - Число, *1 - количество отсекаемых символов; // // Возвращаемое значение: // – Строка. // Функция ПолучитьСтрокуБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт Если СтрДлина(пСтрока) < пДлинаКонца Тогда Возврат ""; Иначе Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца); КонецЕсли; КонецФункции // ПолучитьСтрокуБезКонцаЛкс() // Функция собирает строку из элементов массива с разделителем. // // Параметры: // пМассив - Массив - из которого формируем строку; // *пРазделитель - Строка - символ-разделитель. // // Возвращаемое значение: // Строка. // Функция ПолучитьСтрокуСРазделителемИзМассиваЛкс(пМассив, пРазделитель = ", ") Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); Пустая = Истина; Для Каждого Элемент Из пМассив Цикл Если Не Пустая Тогда ЗаписьXML.ЗаписатьБезОбработки(пРазделитель); Иначе Пустая = Ложь; КонецЕсли; ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент)); КонецЦикла; Результат = ЗаписьXML.Закрыть(); Возврат Результат; КонецФункции // ПолучитьСтрокуСРазделителемИзМассиваЛкс() // Получает представление из идентификатора по правилу // "Дебиторка_По_контрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства". // После символа "_" регистр не меняется, а сам символ заменяется на " ". // // Параметры: // ИсходнаяСтрока – Строка – идентификатор. // // Возвращаемое значение: // – Строка – представление. // Функция ПолучитьПредставлениеИзИдентификатораЛкс(ИсходнаяСтрока) Экспорт СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1); Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1); ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1); СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1); ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1); Если ТекущийСимвол = "_" Тогда СтрокаВозврата = СтрокаВозврата + " "; Продолжить; ИначеЕсли Истина И ВРЕГ(ТекущийСимвол) = ТекущийСимвол // В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку. //И ПредыдущийСимвол <> " " Тогда Если Ложь ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол ИЛИ (Истина И ПредыдущийСимвол <> "_" И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол И ВРЕГ(СледующийСимвол) <> СледующийСимвол) Тогда СтрокаВозврата = СтрокаВозврата + " "; Если Ложь ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол Тогда ТекущийСимвол = НРЕГ(ТекущийСимвол); КонецЕсли; КонецЕсли; КонецЕсли; СтрокаВозврата = СтрокаВозврата + ТекущийСимвол; КонецЦикла; Возврат СтрокаВозврата; КонецФункции // ПолучитьПредставлениеИзИдентификатораЛкс() // Преобразует строку для использования в регулярных выражениях. // Производится // // Параметры: // пТекст – Строка. // // Возвращаемое значение: // Строка – для вставки в регулярные выражения. // Функция ПреобразоватьТекстДляРегулярныхВыраженийЛкс(пТекст) Экспорт Текст = пТекст; СтрокаСпецСимволов = "\[]^$()?*+."; Для Счетчик = 1 По СтрДлина(СтрокаСпецСимволов) Цикл СпецСимвол = Сред(СтрокаСпецСимволов, Счетчик, 1); Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол); КонецЦикла; Возврат Текст; КонецФункции // ПреобразоватьТекстДляРегулярныхВыраженийЛкс() // Преобразует строку для правого операнда оператора ПОДОБНО языка запросов. // // Параметры: // пТекст – Строка. // // Возвращаемое значение: // Строка. // Функция ПреобразоватьСтрокуДляПОДОБНОЛкс(Знач Результат, Спецсимвол = "~") Экспорт ЗарезервированныеСимволы = Новый Массив; ЗарезервированныеСимволы.Добавить("~"); //ЗарезервированныеСимволы.Добавить("%"); ЗарезервированныеСимволы.Добавить("_"); ЗарезервированныеСимволы.Добавить("["); ЗарезервированныеСимволы.Добавить("-"); ЗарезервированныеСимволы.Добавить("]"); Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол); КонецЦикла; Возврат Результат; КонецФункции // ПреобразоватьСтрокуДляПОДОБНОЛкс() // Получает строку путем повтора переданной строки заданное количество раз. // // Параметры: // СтрокаДляПовтора – Строка; // ЧислоПовторов – Число. // // Возвращаемое значение: // Строка. // Функция ПолучитьСтрокуПовторомЛкс(СтрокаДляПовтора, ЧислоПовторов) Экспорт Результат = ""; Для Счетчик = 1 По ЧислоПовторов Цикл Результат = Результат + СтрокаДляПовтора; КонецЦикла; Возврат Результат; КонецФункции // ПолучитьСтрокуПовторомЛкс() // Обновляет в строковом свойстве объекта часть, которая следует за маркером. // Если маркер не находится, то он добавляется. // // Параметры: // пОбъект – Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке; // *пИмяСвойства – Строка, *"" – имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке; // пНовыйТекст - Строка - новая часть, которая следует за разделителем; // *пМаркер - Строка, *"," - маркер. // Процедура ОбновитьТекстПослеМаркераВСтрокеЛкс(пОбъектИлиСвойство, пИмяСвойства = "", пНовыйТекст, пМаркер = ", ") Экспорт Если пИмяСвойства <> "" Тогда СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства]; Иначе СтараяСтрока = пОбъектИлиСвойство; КонецЕсли; ПозицияРазделителя = Найти(СтараяСтрока, пМаркер); Если ПозицияРазделителя = 0 Тогда ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1; КонецЕсли; НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + пНовыйТекст; Если пИмяСвойства <> "" Тогда пОбъектИлиСвойство[пИмяСвойства] = НоваяСтрока; Иначе пОбъектИлиСвойство = НоваяСтрока; КонецЕсли; КонецПроцедуры // ОбновитьТекстПослеМаркераВСтрокеЛкс() // Заменяет текущее выделение в поле текстового документа новым текстом. // После этого устанавливает выделение на вставленный фрагмент. // // Параметры: // ПолеТекстовогоДокумента - ПолеТекстовогоДокумента; // НовыйТекст – Строка. // Процедура ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт Перем НачальнаяСтрока; Перем НачальнаяКолонка; Перем КонечнаяСтрока; Перем КонечнаяКолонка; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, НачальнаяСтрока, НачальнаяКолонка); НачальнаяГраница = СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) + 1; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст; КонечнаяГраница = НачальнаяГраница + СтрДлина(НовыйТекст); Если КонечнаяГраница > СтрДлина(ПолеТекстовогоДокумента.ПолучитьТекст()) Тогда КонечнаяГраница = КонечнаяГраница - 1; КонецЕсли; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяГраница, КонечнаяГраница); КонецПроцедуры // ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс() // Взято отсюда http://infostart.ru/public/100845/ // ИсходныеДанные - <примитивное значение>, ДвоичныеДАнные, ХранилищеЗначения // // Возвращаемое значение // Число Функция ВычислитьХэшЛкс(ИсходныеДанные, Хэш=5381, М=33, Разрядность=18446744073709551616) Экспорт // приведем к строке Если ТипЗнч(ИсходныеДанные) = Тип("ДвоичныеДанные") Тогда СтрокаДляКодирования = Base64Строка(ИсходныеДанные); ИначеЕсли ТипЗнч(ИсходныеДанные) = Тип("ХранилищеЗначения") Тогда СтрокаДляКодирования = ЗначениеВСтрокуВнутр(ИсходныеДанные); Иначе СтрокаДляКодирования = Строка(ИсходныеДанные); КонецЕсли; ДлинаБлока = 11; НачПозиция = 1; ДлинаСтроки = СтрДлина(СтрокаДляКодирования); Пока НачПозиция <= ДлинаСтроки Цикл СтрокаБлока = Сред(СтрокаДляКодирования, НачПозиция, ДлинаБлока); ДлинаПодстроки = СтрДлина(СтрокаБлока); Если ДлинаПодстроки = ДлинаБлока Тогда Хэш = ((((((((((( Хэш*М + КодСимвола(СтрокаБлока, 1))*М + КодСимвола(СтрокаБлока, 2))*М + КодСимвола(СтрокаБлока, 3))*М + КодСимвола(СтрокаБлока, 4))*М + КодСимвола(СтрокаБлока, 5))*М + КодСимвола(СтрокаБлока, 6))*М + КодСимвола(СтрокаБлока, 7))*М + КодСимвола(СтрокаБлока, 8))*М + КодСимвола(СтрокаБлока, 9))*М + КодСимвола(СтрокаБлока, 10))*М + КодСимвола(СтрокаБлока, 11)) Иначе Для к = 1 По ДлинаПодстроки Цикл Хэш = М * Хэш + КодСимвола(СтрокаБлока, к) КонецЦикла КонецЕсли; Хэш = Хэш % Разрядность; НачПозиция = НачПозиция + ДлинаБлока КонецЦикла; Возврат Хэш; КонецФункции Функция ПолучитьГУИДИнверсныйИзПрямогоЛкс(ПрямойГУИД) Экспорт С = СтрЗаменить(ПрямойГУИД, "-", ""); Возврат Сред(С,17,16)+Сред(С,13,4)+Сред(С,9,4)+Сред(С,1,4)+Сред(С,5,4); КонецФункции Функция ПолучитьГУИДПрямойИзИнверсногоЛкс(ИнверсныйГУИД) Экспорт С = ИнверсныйГУИД; Возврат Сред(С,25,8)+"-"+Сред(С,21,4)+"-"+Сред(С,17,4)+"-"+Сред(С,1,4)+"-"+Сред(С,5,12); КонецФункции Функция ПолучитьОписаниеТиповВсеСсылкиЛкс() Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку( " | cc:AnyRef |"); Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Если ирКэш.Получить().ВерсияПлатформы >= 803001 Тогда Для Каждого ВнешнийИсточникДанных Из Вычислить("ВнешниеИсточникиДанных") Цикл // Для компиляции на платформе 8.2.13- Результат = Новый ОписаниеТипов(Результат, ВнешнийИсточникДанных.Таблицы.ТипВсеСсылки().Типы()); КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции Функция ОписаниеТиповВсеРедактируемыеТипыЛкс() Экспорт ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс(); ДополнительныеТипы = Новый Массив(); ДополнительныеТипы.Добавить(Тип("Строка")); ДополнительныеТипы.Добавить(Тип("Число")); ДополнительныеТипы.Добавить(Тип("Дата")); ДополнительныеТипы.Добавить(Тип("Булево")); ДополнительныеТипы.Добавить(Тип("СписокЗначений")); ДополнительныеТипы.Добавить(Тип("Массив")); ДополнительныеТипы.Добавить(Тип("ОписаниеТипов")); ДополнительныеТипы.Добавить(Тип("МоментВремени")); ДополнительныеТипы.Добавить(Тип("Граница")); ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала")); ДополнительныеТипы.Добавить(Тип("СтандартныйПериод")); ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений")); ДополнительныеТипы.Добавить(Тип("ДеревоЗначений")); ДополнительныеТипы.Добавить(Тип("ТабличныйДокумент")); ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления")); ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии")); ДополнительныеТипы.Добавить(Тип("ВидСчета")); ДополнительныеТипы.Добавить(Тип("Тип")); ДополнительныеТипы.Добавить(Тип("Null")); ДополнительныеТипы.Добавить(Тип("ПолеКомпоновкиДанных")); //ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация //ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор")); ДополнительныеТипы.Добавить(Тип("ХранилищеЗначения")); ДополнительныеТипы.Добавить(Тип("ДвоичныеДанные")); // Из-за бага платформы отключены //ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления")); //ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления")); КвалификаторыЧисла = Новый КвалификаторыЧисла; //(25, 5); // Важно! ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла); Возврат ОписаниеТипов; КонецФункции Функция РежимСовместимостиМеньше8_3_4Лкс() Экспорт Возврат Ложь Или ирКэш.Получить().ВерсияПлатформы < 803004 Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_3 Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_2 Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_1 Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_2_16 Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_2_13 Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ДЕРЕВЬЯМИ Процедура ДобавитьКолонкуЕслиНетЛкс(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено, Заголовок = Неопределено, Ширина = 0) Экспорт Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда Возврат; КонецЕсли; КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина); КонецПроцедуры // ДобавитьКолонкуЕслиНетЛкс() // ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее Функция ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки = "Имя", ИгнорироватьПростойПервыйУровень = Ложь, Разделитель = ".") Экспорт Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Результат = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева).Строки.Индекс(СтрокаДерева); Иначе Результат = СтрокаДерева[ИмяКолонки]; КонецЕсли; Если СтрокаДерева.Родитель = Неопределено Тогда Если Истина И ИгнорироватьПростойПервыйУровень И СтрокаДерева.Владелец().Строки.Количество() = 1 Тогда Результат = Неопределено; КонецЕсли; Иначе РезультатСверху = ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева.Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень, Разделитель); Если РезультатСверху <> Неопределено Тогда Результат = РезультатСверху + Разделитель + Результат; КонецЕсли; КонецЕсли; Возврат XMLСтрока(Результат); КонецФункции // ПолучитьСтрокуПутиВДеревеЛкс() // ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее Функция НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт Если Истина И ИгнорироватьПростойПервыйУровень И ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений") И СтрокаДерева.Строки.Количество() = 1 Тогда Возврат НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Сред(Путь, 2)); КонецЕсли; ТекущийУровень = ПолучитьПервыйФрагментЛкс(Путь); Если Не ЗначениеЗаполнено(ТекущийУровень) Тогда Возврат СтрокаДерева; КонецЕсли; ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2); Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ТекущаяСтрока = СтрокаДерева.Строки[Число(ТекущийУровень)]; Иначе ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки); КонецЕсли; Если ТекущаяСтрока <> Неопределено Тогда Возврат НайтиПоСтрокеПутиВДеревеЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть); Иначе Возврат СтрокаДерева; КонецЕсли; КонецФункции // НайтиПоСтрокеПутиВДеревеЛкс() Функция _ПолучитьМассивПутиСтрокиДереваЛкс(СтрокаДерева, ИмяКолонки = "Имя") Экспорт Если СтрокаДерева.Родитель = Неопределено Тогда Результат = Новый Массив; Иначе Результат = _ПолучитьМассивПутиСтрокиДереваЛкс(СтрокаДерева.Родитель, ИмяКолонки); КонецЕсли; ТекущийУровень = СтрокаДерева[ИмяКолонки]; //Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Результат.Добавить(ТекущийУровень); //КонецЕсли; Возврат Результат; КонецФункции // ПолучитьМассивПутиСтрокиДереваЛкс() Функция НайтиСтрокуДереваПоМассивуПутиЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, Позиция = 0) Экспорт Индекс = Позиция; ТекущийУровень = Путь[Индекс]; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ТекущаяСтрока = СтрокаДерева.Строки[ТекущийУровень]; Иначе ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки); КонецЕсли; Если Истина И ТекущаяСтрока <> Неопределено И Индекс < Путь.ВГраница() Тогда Возврат НайтиСтрокуДереваПоМассивуПутиЛкс(ТекущаяСтрока, ИмяКолонки, Путь, Позиция + 1); Иначе Возврат ТекущаяСтрока; КонецЕсли; КонецФункции // НайтиСтрокуДереваПоМассивуПутиЛкс() // Процедура заполняет колонку дерева значением. // // Параметры // ЭлементДЗ - ДеревоЗначений; // ИмяКолонки - Строка; // ЗначениеКолонки - Произвольный. // Процедура ЗаполнитьКолонкуДереваЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки; ЗаполнитьКолонкуДереваЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки); КонецЦикла; КонецПроцедуры // ЗаполнитьКолонкуДереваЛкс // Процедура удаляет все строки дерева со значением в колонке. // // Параметры // ЭлементДЗ - ДеревоЗначений; // ИмяКолонки - Строка; // ЗначениеКолонки - Произвольный. // Процедура УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт НачальноеКоличество = ЭлементДЗ.Строки.Количество(); Для Счетчик = 1 По НачальноеКоличество Цикл ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик]; Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока); Иначе УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки); КонецЕсли; КонецЦикла; КонецПроцедуры // УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция ПолучитьТекстИзXMLЛкс(Текст) Экспорт //{ Заменяем символы, критичные для XML Текст = СтрЗаменить(Текст,"&","&"); Текст = СтрЗаменить(Текст,"<","<"); Текст = СтрЗаменить(Текст,">",">"); Возврат Текст; КонецФункции // ПолучитьТекстИзXMLЛкс() Функция СтрокаВнутрВХМЛТелоЛкс(вхСтрока, выхХМЛТело = Неопределено) Экспорт //{ Получение одной длинной строки выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,""); выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,""); //} //{ Заменяем символы, критичные для XML // & на & // < на < // > на > выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&"); выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","<"); выхХМЛТело = СтрЗаменить(выхХМЛТело,">",">"); //{ Замена одинарных символов выхХМЛТело = СтрЗаменить(выхХМЛТело,",",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"{",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"}",""); //} //{ Удаляем лишние блоки и выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""); //} //{ Добавляем перенос строки к и к для удобства поиска различий выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС); выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС); //} Возврат выхХМЛТело; КонецФункции // Получает структуру для индикации прогресса цикла. // // Параметры: // КоличествоПроходов – Число - максимальное значение счетчика; // ПредставлениеПроцесса – Строка, *"Выполнено" – отображаемое название процесса; // КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора; // ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса; // РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс. // МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений, // эта реализация не поддерживает дробные значения; // ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации // // Возвращаемое значение: // Структура - которую потом нужно будет передавать в метод ОбработатьИндикаторЛкс. // Функция ПолучитьИндикаторПроцессаЛкс(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение", Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1, ТаблицаИндикаторов = Неопределено) Экспорт ирПлатформа = ирКэш.Получить(); Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда //#Если Клиент Тогда // СостояниеЛкс(ПредставлениеПроцесса + "..."); //#КонецЕсли КоличествоПроходов = 0; КонецЕсли; КоличествоПроходов = Цел(КоличествоПроходов); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если ТаблицаИндикаторов.Количество() = 0 Тогда #Если Клиент Тогда ПодключитьГлобальныйОбработчикОжиданияЛкс("ОсвободитьВсеИндикаторыПроцессовОтложенноЛкс"); #КонецЕсли ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов"; КонецЕсли; Индикатор = ТаблицаИндикаторов.Добавить(); Индикатор.КоличествоПроходов = КоличествоПроходов; Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса; Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя; Индикатор.РазрешитьПрерывание = РазрешитьПрерывание; Индикатор.ДатаНачалаПроцесса = ТекущаяДата(); Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления; Индикатор.ДатаСледующегоОбновления = Индикатор.ДатаНачалаПроцесса + Индикатор.МинимальныйПериодОбновления; Если КоличествоОбновлений > 0 Тогда Шаг = КоличествоПроходов / КоличествоОбновлений; Иначе Шаг = 0; КонецЕсли; Индикатор.Шаг = Шаг; //Индикатор.СледующийСчетчик = 0; //Индикатор.Счетчик = 0; Возврат Индикатор; КонецФункции // ПолучитьИндикаторПроцессаЛкс() // Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния) // Параметры: // СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор // ВывестиИтогИндикации - Булево // ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове // Процедура ОсвободитьИндикаторПроцессаЛкс(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если Индикатор = Неопределено Тогда Если ТаблицаИндикаторов.Количество() > 0 Тогда Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1]; КонецЕсли; КонецЕсли; Если Индикатор <> Неопределено Тогда Если ВывестиИтогИндикации Тогда СообщитьИтогИндикацииЛкс(Индикатор); КонецЕсли; Если ТаблицаИндикаторов <> Неопределено Тогда Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда ТаблицаИндикаторов.Удалить(Индикатор); КонецЕсли; КонецЕсли; КонецЕсли; Если Ложь Или ТаблицаИндикаторов = Неопределено Или ТаблицаИндикаторов.Количество() = 0 Тогда НовоеСостояние = ""; Иначе НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния; КонецЕсли; #Если Клиент Тогда Состояние(НовоеСостояние); #КонецЕсли КонецПроцедуры Процедура ОсвободитьВсеИндикаторыПроцессовЛкс() Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; //Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл // ОбработатьИндикаторЛкс(СтрокаИндикатора, , Истина); //КонецЦикла; ТаблицаИндикаторов.Очистить(); КонецПроцедуры // Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла. // // Параметры: // Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс; // Счетчик – Число, *Неопределено – внешний счетчик цикла. // Функция ОбработатьИндикаторЛкс(Индикатор, Счетчик = Неопределено) Экспорт Если Счетчик = Неопределено Тогда Попытка Счетчик = Индикатор.Счетчик; Исключение // Бывает, что строка таблицы индикаторов уже была удалена Возврат Ложь; КонецПопытки; Счетчик = Счетчик + 1; КонецЕсли; Индикатор.Счетчик = Счетчик; #Если Клиент Тогда Если Индикатор.РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; #КонецЕсли ОбновитьИндикатор = Истина; Если Ложь Или Счетчик < Индикатор.КоличествоПроходов Или Индикатор.КоличествоПроходов = 0 Тогда ТекущаяДата = ТекущаяДата(); Если Индикатор.МинимальныйПериодОбновления > 0 Тогда Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления; Иначе ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; Если ОбновитьИндикатор Тогда Если Индикатор.Шаг > 0 Тогда Если Счетчик >= Индикатор.СледующийСчетчик Тогда Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг); Иначе ОбновитьИндикатор = Ложь; КонецЕсли; //Иначе // ОбновитьИндикатор = Ложь; // ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " "; // Состояние(ТекстСостояния); КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда #Если Клиент Тогда Состояние(""); #КонецЕсли ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; Если ОбновитьИндикатор Тогда Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг); Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда МассивИндикаторов = Индикатор.Владелец(); Иначе МассивИндикаторов = Новый Массив; МассивИндикаторов.Добавить(Индикатор); КонецЕсли; #Если Клиент Тогда ТекстСостояния = ""; Для Каждого лИндикатор Из МассивИндикаторов Цикл Если ТекстСостояния <> "" Тогда ТекстСостояния = ТекстСостояния + ".>> "; КонецЕсли; ТекстСостояния = ТекстСостояния + ПолучитьТекстСостоянияИндикатораЛкс(лИндикатор); КонецЦикла; лИндикатор.ТекстСостояния = ТекстСостояния; Состояние(ТекстСостояния); #КонецЕсли КонецЕсли; Возврат ОбновитьИндикатор; КонецФункции // ОбработатьИндикаторЛкс() Процедура СостояниеЛкс(СтрокаСостояния = "") Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если ТаблицаИндикаторов.Количество() > 0 Тогда Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1]; СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния; КонецЕсли; #Если Клиент Тогда Состояние(СтрокаСостояния); #КонецЕсли КонецПроцедуры // Функция сравнивает две таблицы значений на идентичность структуры и данных // // Параметры // ТаблицаЗначений1 - ТаблицаЗначений для сравнения // ТаблицаЗначений2 - ТаблицаЗначений для сравнения // // Возвращаемое значение: // Булево, идентичны или нет две таблицы // Функция ТаблицыЗначенийРавныЛкс(ТаблицаЗначений1, ТаблицаЗначений2) Экспорт Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда Возврат Ложь; КонецЕсли; Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда Возврат Ложь; КонецЕсли; Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда Возврат Ложь; КонецЕсли; Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда Возврат Ложь; КонецЕсли; Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)]; Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда Возврат Ложь; КонецЕсли; КонецЦикла; КонецЦикла; Возврат Истина; КонецФункции // СравнитьТаблицыЗначений() #Если Клиент Тогда Функция ИмяФормыИзСтрокиИнструментаЛкс(Знач СтрокаИнструмента) Экспорт ИмяВыбраннойФормы = СтрокаИнструмента.ПолноеИмя; Если Найти(ИмяВыбраннойФормы, "ОбщаяФорма.") <> 1 И Найти(ИмяВыбраннойФормы, ".Форма.") = 0 Тогда Если Найти(ИмяВыбраннойФормы, "Справочник.") = 1 Тогда ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".ФормаСписка"; Иначе ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".Форма"; КонецЕсли; КонецЕсли; Возврат ИмяВыбраннойФормы; КонецФункции Процедура ПодключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода, Интервал = 0.1, Однократно = Истина) Экспорт Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ирПортативный.ПолучитьФорму().ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина); Иначе ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина); КонецЕсли; КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ФОРМАМИ // РежимОткрытия - Булево - Истина - Открытие, иначе Сохранение Функция ВыбратьФайлЛкс(РежимОткрытия = Истина, Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "") Экспорт Если Не ЗначениеЗаполнено(Расширение) Тогда Расширение = "*"; КонецЕсли; Если РежимОткрытия = Истина Тогда РежимДиалога = РежимДиалогаВыбораФайла.Открытие; Иначе РежимДиалога = РежимДиалогаВыбораФайла.Сохранение; КонецЕсли; ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалога); Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда Файл = Новый Файл(ПолноеИмяФайла); ВыборФайла.Каталог = Файл.Путь; ВыборФайла.ПолноеИмяФайла = Файл.Имя; Иначе ВыборФайла.Каталог = Каталог; ВыборФайла.ПолноеИмяФайла = КраткоеИмя; КонецЕсли; ВыборФайла.Фильтр = ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата); ВыборФайла.Расширение = Расширение; Если Не ВыборФайла.Выбрать() Тогда Возврат Неопределено; КонецЕсли; Возврат ВыборФайла.ПолноеИмяФайла; КонецФункции Функция ВыбратьКаталогВФормеЛкс(Каталог, ФормаДляУстановкиМодифицированности = Неопределено, Заголовок = "") Экспорт ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); ВыборФайла.Каталог = Каталог; ВыборФайла.Заголовок = Заголовок; Если Не ВыборФайла.Выбрать() Тогда Возврат Неопределено; КонецЕсли; Каталог = ВыборФайла.Каталог; Если ФормаДляУстановкиМодифицированности <> Неопределено Тогда ФормаДляУстановкиМодифицированности.Модифицированность = Истина; КонецЕсли; Возврат Каталог; КонецФункции Процедура ПолучитьМассивЗначенийПеретаскиванияЛкс(Знач ПараметрыПеретаскивания, выхМассивЗначений, выхТипЗначенияПеретаскивания = Неопределено) Экспорт ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания); Если выхТипЗначенияПеретаскивания = Тип("Массив") Тогда выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания[0]); выхМассивЗначений = ЗначениеПеретаскивания; Иначе выхМассивЗначений = Новый Массив; выхМассивЗначений.Добавить(ЗначениеПеретаскивания); КонецЕсли; КонецПроцедуры // Параметры: // КлючеваяКолонка - Строка - используется при отборе // ПроверятьОформлениеСтроки - Булево - долго Процедура ИзменитьПометкиВыделенныхСтрокЛкс(Знач ТабличноеПоле, ИмяКолонкиПометки = "Пометка", НовоеЗначениеПометки = Истина, КлючеваяКолонка = "НомерСтроки", СтруктураОтбора = Неопределено, ПроверятьОформлениеСтроки = Истина) Экспорт ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Если ВыделенныеСтроки.Количество() <= 1 Тогда ВыделенныеСтроки = ТабличноеПоле.Значение; Попытка ОтборСтрок = ТабличноеПоле.ОтборСтрок; Исключение КонецПопытки; Если ОтборСтрок <> Неопределено Или СтруктураОтбора <> Неопределено Тогда Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора); #Если Сервер И Не Сервер Тогда Построитель = Новый ПостроительЗапроса; #КонецЕсли Построитель.ВыбранныеПоля.Очистить(); Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка); НомераОтобранныхСтрок = Построитель.Результат.Выгрузить(); НомераОтобранныхСтрок.Индексы.Добавить(КлючеваяКолонка); КонецЕсли; КонецЕсли; Для каждого Строка из ВыделенныеСтроки Цикл Если Истина И НомераОтобранныхСтрок <> Неопределено И НомераОтобранныхСтрок.Найти(Строка[КлючеваяКолонка], КлючеваяКолонка) = Неопределено Тогда // Строка не отвечает отбору Продолжить; КонецЕсли; Если ПроверятьОформлениеСтроки Тогда ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(Строка); Если ОформлениеСтроки.Ячейки[ИмяКолонкиПометки].ТолькоПросмотр Тогда Продолжить; КонецЕсли; КонецЕсли; Строка[ИмяКолонкиПометки] = НовоеЗначениеПометки; КонецЦикла; ТабличноеПоле.ОбновитьСтроки(); КонецПроцедуры Функция ВыбратьСсылкуЛкс(ИмяТаблицыИлиМДИлиТип, НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт Результат = ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип,, ИспользоватьДинамическийСписокИР,, Истина,, НачальноеЗначениеВыбора, Истина); Возврат Результат; КонецФункции Процедура ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(ТаблицаИсточник, НачальноеПолноеИмяОбъекта = "") Экспорт ФормаВыбораОбъектаБД = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхЛкс(,, НачальноеПолноеИмяОбъекта,, Истина,, Истина, Истина,, Истина,,, Истина); РезультатВыбора = ФормаВыбораОбъектаБД.ОткрытьМодально(); Если РезультатВыбора = Неопределено Тогда Возврат; КонецЕсли; ОбъектМД = ирОбщий.НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(РезультатВыбора.ПолноеИмяОбъекта); ЭтоНаборЗаписей = ирОбщий.ЛиРегистровыйОбъектМетаданных(ОбъектМД); Если ЭтоНаборЗаписей Тогда ПолноеИмяМДСписка = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмяМДСписка = ОбъектМД.Родитель().ПолноеИмя(); КонецЕсли; МакетныйОбъект = Неопределено; ТекущаяГруппаТипаМетаданных = Неопределено; ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМДСписка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); Если ЭтоНаборЗаписей Тогда ОбъектБД = МакетныйОбъект; ТаблицаПриемник = ОбъектБД; Иначе ВыбраннаяСтрока = ОткрытьФормуСпискаЛкс(ПолноеИмяМДСписка,,,, Истина,,, Истина); Если ВыбраннаяСтрока = Неопределено Тогда Возврат; КонецЕсли; ОбъектБД = ирОбщий.ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(ВыбраннаяСтрока, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина); ТаблицаПриемник = ОбъектБД[ОбъектМД.Имя]; КонецЕсли; Если ТаблицаПриемник.Количество() > 0 Тогда Если ЭтоНаборЗаписей Тогда ТекстВопроса = "Хотите очистить набор записей в памяти перед заполнением?"; Иначе ТекстВопроса = "Выбранная табличная часть объекта не пустая. Хотите очистить ее в памяти перед заполнением?"; КонецЕсли; Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да); Если Ответ = КодВозвратаДиалога.Да Тогда ТаблицаПриемник.Очистить(); КонецЕсли; КонецЕсли; ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник); ОбработкаРедактора = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД"); #Если Сервер И Не Сервер Тогда ОбработкаРедактора = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ФормаРедактора = ОбработкаРедактора.РедактироватьМодифицированныйОбъект(ОбъектБД); ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(РезультатВыбора.ПолноеИмяОбъекта); КонецПроцедуры // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(Значение1, Значение2, Модально = Ложь, Название1 = Неопределено, Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт Если Истина И ТипЗнч(Значение1) = Тип("ТаблицаЗначений") И ТипЗнч(Значение2) = Тип("ТаблицаЗначений") Тогда Обработка = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирСравнениеТаблиц"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирСравнениеТаблиц.Создать(); #КонецЕсли Обработка.Таблица1 = Значение1; Обработка.Таблица2 = Значение2; Обработка.ОбновитьСопоставлениеКолонок(); Обработка.ЗаполнитьСопоставлениеКолонок(); Обработка.ПодобратьКлючевыеИСравниваемыеКолонки(); ФормаСравнителя = Обработка.ПолучитьФорму(); ФормаСравнителя.РежимРедактора = Истина; ФормаСравнителя.Открыть(); Возврат ФормаСравнителя.СравнитьТаблицы(); КонецЕсли; Путь1 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение1, Название1, ПолучатьXMLПредставлениеДляНеизвестныхТипов); Путь2 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение2, Название2, ПолучатьXMLПредставлениеДляНеизвестныхТипов); // Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится. Если СравнениеФайлов = Неопределено Тогда СравнениеФайлов = Новый СравнениеФайлов; КонецЕсли; СравнениеФайлов.ПервыйФайл = Путь1; СравнениеФайлов.ВторойФайл = Путь2; СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь; Если Истина И ТипЗнч(Значение1) = Тип("ТабличныйДокумент") И ТипЗнч(Значение2) = Тип("ТабличныйДокумент") Тогда СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент; Иначе СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент; КонецЕсли; Если Модально Тогда СравнениеФайлов.ПоказатьРазличияМодально(); Иначе СравнениеФайлов.ПоказатьРазличия(); КонецЕсли; Возврат СравнениеФайлов.Сравнить(); КонецФункции // СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс() // Сравнивает табличный документ, полученный из элемента управления с предыдущим. // // Параметры: // СравнительТабличныхДокументов – Массив, *Неопределено – переменная для хранения предыдущего табличного документа. // ЭлементУправления – ТабличноеПоле, ПолеТабличногоДокумента – откуда получаем содержимое. // Процедура СравнитьСодержимоеЭлементаУправленияЛкс(ЭлементУправления) Экспорт Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда СравниваемыйДокумент = Новый ТекстовыйДокумент; СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст()); ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда СравниваемыйДокумент = Новый ТекстовыйДокумент; СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение); ИначеЕсли Ложь Или ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Или ТипЗнч(ЭлементУправления) = Тип("ТаблицаФормы") Тогда СравниваемыйДокумент = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ЭлементУправления); ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеТабличногоДокумента") Тогда СравниваемыйДокумент = ЭлементУправления.ПолучитьОбласть(); Иначе Сообщить("Неподдерживаемый тип элемента управления для сравнения"); Возврат; КонецЕсли; МассивСравнения = ирКэш.ПолучитьБуферСравненияЛкс("" + ТипЗнч(СравниваемыйДокумент)); Если МассивСравнения.Количество() = 2 Тогда МассивСравнения.Удалить(0); КонецЕсли; МассивСравнения.Добавить(СравниваемыйДокумент); Если МассивСравнения.Количество() = 2 Тогда Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Нет Тогда Возврат; КонецЕсли; СравниваемыйДокумент1 = МассивСравнения[0]; СравниваемыйДокумент2 = МассивСравнения[1]; СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(СравниваемыйДокумент1, СравниваемыйДокумент2); КонецЕсли; КонецПроцедуры Функция ВывестиСтрокиТабличногоПоляСНастройкойЛкс(Знач ТабличноеПоле, ВыводБезОформления = Истина, Знач НастройкиСписка = Неопределено) Экспорт ФормаНастройки = ирКэш.Получить().ПолучитьФорму("ПараметрыВыводаСтрокТабличногоПоля"); ФормаНастройки.ТабличноеПоле = ТабличноеПоле; Если ВыводБезОформления <> Неопределено Тогда ФормаНастройки.БезОформления = ВыводБезОформления; КонецЕсли; РезультатФормы = ФормаНастройки.ОткрытьМодально(); Если РезультатФормы = Неопределено Тогда Возврат Неопределено; КонецЕсли; Результат = ВывестиСтрокиТабличногоПоляЛкс(ТабличноеПоле, ФормаНастройки,,, НастройкиСписка); Возврат Результат; КонецФункции Функция ВывестиСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач ПараметрыВывода, Отладка = Ложь, выхТекущаяСтрока = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт КлючТекущейСтроки = Неопределено; ИндексТекущейСтроки = Неопределено; СтруктураТипа = Неопределено; ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле, , СтруктураТипа); ВыбранныеКолонки = ПараметрыВывода.КолонкиТабличногоПоля.Выгрузить(Новый Структура("Пометка", Истина)); МассивСтрок = Неопределено; ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле); Если ТипИсточника = "Список" Тогда ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); КлючТекущейСтроки = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы); Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, ТабличноеПоле.ТекущаяСтрока); КонецЕсли; Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда КоллекцияСтрок = КлючиВыделенныхСтрокДинамическогоСписка(ТабличноеПоле); КонецЕсли; Иначе Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда МассивСтрок = ПолучитьМассивВыделенныхСтрокТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; Если ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда Если МассивСтрок <> Неопределено Тогда КоллекцияСтрок = МассивСтрок; Иначе КоллекцияСтрок = ЗначениеТабличногоПоля.Строки; Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТабличноеПоле.ТекущаяСтрока); КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипИсточника = "ТабличнаяЧасть" Или ТипИсточника = "НаборЗаписей" Или ТипИсточника = "ТаблицаЗначений" Тогда Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущаяСтрока); КонецЕсли; КоллекцияСтрок = ТаблицаЗначенийИзТабличногоПоляЛкс(ТабличноеПоле, МассивСтрок); КонецЕсли; КонецЕсли; Если ПараметрыВывода.БезОформления Тогда ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Данные"); Если ТипИсточника = "Список" Тогда ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле); СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; Если НастройкиСписка = Неопределено Тогда НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок); КонецЕсли; ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор); ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок); Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда ГруппаИли = НастройкаКомпоновки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных")); ГруппаИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли; ГруппаИли.Использование = Истина; Для Каждого КлючСтроки Из КоллекцияСтрок Цикл ГруппаИ = ГруппаИли.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных")); ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ; ГруппаИ.Использование = Истина; Для Каждого КлючИЗначение Из КлючТекущейСтроки Цикл НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ГруппаИ, КлючИЗначение.Ключ, КлючСтроки[КлючИЗначение.Ключ]); КонецЦикла; КонецЦикла; КонецЕсли; Для Каждого КлючИЗначение Из КлючТекущейСтроки Цикл НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, КлючИЗначение.Ключ); КонецЦикла; Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда Продолжить; КонецЕсли; НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка); КонецЦикла; КоллекцияСтрок = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки); ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки); Если ТекущаяСтрока.Количество() > 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; НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы; #Если Сервер И Не Сервер Тогда НеготовыеСтраницы = Новый СписокЗначений; #КонецЕсли Если ТипЗнч(Панель) = Тип("Панель") Тогда Страницы = Панель.Страницы; Иначе Страницы = Панель.ПодчиненныеЭлементы; КонецЕсли; Для Каждого Страница Из Страницы Цикл ИмяСтраницы = Страница.Имя; Если ИмяСтраницы = "" Тогда // Служебная страница. Появляется после очистки страниц. Продолжить; КонецЕсли; Если Найти("." + ИмяСтраницы, ".Страница") = 1 Тогда ИмяСтраницы = СтрЗаменить("." + ИмяСтраницы, ".Страница", ""); КонецЕсли; ЭУ = ЭлементыФормы.Найти(ИмяСтраницы); Если ЭУ = Неопределено Тогда Продолжить; КонецЕсли; Если ТипЗнч(Страница) = Тип("СтраницаПанели") Тогда ЗначениеСтраницы = Страница.Значение; Иначе ЗначениеСтраницы = Неопределено; КонецЕсли; Если Ложь Или НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя) <> Неопределено Или (Истина И ТипЗнч(ЗначениеСтраницы) = Тип("Структура") И ЗначениеСтраницы.Свойство("Рассчитано") И Не ЗначениеСтраницы.Рассчитано) Тогда Количество = "-"; Иначе Суффикс = ""; Количество = Неопределено; Если Ложь Или ТипЗнч(ЭУ) = Тип("ТабличноеПоле") Или ТипЗнч(ЭУ) = Тип("ТаблицаФормы") Тогда ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ЭУ); Если ТипЗнч(ЗначениеЭУ) = Тип("ДеревоЗначений") Тогда Количество = ЗначениеЭУ.Строки.Количество(); Суффикс = "*"; ИначеЕсли ТипЗнч(ЗначениеЭУ) = Тип("ДанныеФормыДерево") Тогда Количество = ЗначениеЭУ.ПолучитьЭлементы().Количество(); Суффикс = "*"; Иначе Попытка Количество = ЗначениеЭУ.Количество(); Исключение КонецПопытки; Если Количество = Неопределено Тогда // Компоновка Попытка Количество = ЗначениеЭУ.Элементы.Количество(); //Суффикс = "*"; Исключение КонецПопытки; КонецЕсли; КонецЕсли; //Если Количество = 0 Тогда // Попытка // КоличествоКолонок = ЗначениеЭУ.Колонки.Количество(); // Исключение // КоличествоКолонок = 1; // КонецПопытки; // Если КоличествоКолонок = 0 Тогда // Количество = "-"; // КонецЕсли; //КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокумента") Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокументаФормы") Тогда Количество = ?(ЭУ.ВысотаТаблицы > 0, 1, 0); ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокумента") Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокументаФормы") Тогда Количество = ?(ЭУ.КоличествоСтрок() > 0, 1, 0); ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемы") Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемыФормы") Тогда Количество = ЭУ.ЭлементыГрафическойСхемы.Количество(); ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("Панель") Или (Истина И ТипЗнч(ЭУ) = Тип("ГруппаФормы") И ЭУ.Вид = ВидГруппыФормы.Страницы) Тогда //Количество = ЭУ.Страницы.Количество(); //Если Количество = 1 Тогда // Если ЭУ.Страницы[0].Имя = "" Тогда // Количество = 0; // КонецЕсли; //КонецЕсли; Количество = ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭУ); КонецЕсли; Если ТипЗнч(Количество) = Тип("Число") Тогда ОбщееКоличество = ОбщееКоличество + Количество; КонецЕсли; КонецЕсли; Если ТаблицаСтраниц <> Неопределено Тогда СтрокаСтраницы = ТаблицаСтраниц.НайтиСтроки(Новый Структура("ИмяСтраницы", ИмяСтраницы)); Если СтрокаСтраницы.Количество() > 0 Тогда СтрокаСтраницы = СтрокаСтраницы[0]; СтрокаСтраницы.Количество = Количество; СтрокаСтраницы.Непустая = СтрокаСтраницы.Количество > 0; КонецЕсли; КонецЕсли; ОбновитьТекстПослеМаркераВСтрокеЛкс(Страница.Заголовок, , "" + Количество + Суффикс + ")", "("); КонецЦикла; Возврат ОбщееКоличество; КонецФункции // ОбновитьЗаголовкиСтраницПанелейЛкс() // <Описание процедуры> // // Параметры: // Ссылка – Ссылка, КлючЗаписи, КонстантаМенеджер; // ПолноеИмя - Строка - полное имя метаданных для константы. // Процедура ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс(Ссылка, ПолноеИмя = "") Экспорт Если ЛиКлючЗаписиРегистраЛкс(Ссылка) Тогда ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)); ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); ФормаСписка = ПолучитьФормуСпискаЛкс(ОбъектМетаданных.ПолноеИмя(),,,,,, Ссылка); ФормаСписка.Открыть(); ИначеЕсли ЛиКорневойТипКонстантыЛкс(ПолучитьПервыйФрагментЛкс(ПолноеИмя)) Тогда ОткрытьКонстантуВСпискеЛкс(ПолучитьПоследнийФрагментЛкс(ПолноеИмя)); Иначе ОткрытьЗначение(Ссылка); КонецЕсли; КонецПроцедуры // ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс() Процедура ОткрытьКонстантуВСпискеЛкс(ИмяКонстанты) Экспорт ФормаСписка = ПолучитьФормуЛкс("Обработка.ирРедакторКонстант.Форма"); ФормаСписка.НачальноеЗначениеВыбора = ИмяКонстанты; ФормаСписка.Открыть(); КонецПроцедуры Функция ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(Знач Элемент, Текст) Экспорт НачалоКолонки = 0; НачалоСтроки = 0; КонецКолонки = 0; КонецСтроки = 0; Элемент.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки); Элемент.Значение = Текст; Элемент.УстановитьГраницыВыделения(1, 1, КонецСтроки, КонецКолонки); Элемент.ВыделенныйТекст = Элемент.ВыделенныйТекст; Элемент.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки); КонецФункции Функция ПрочитатьЗначениеИзФайлаСКонтролемПотерьЛкс(ПолноеИмяФайла) Экспорт ФайлЗначения = Новый Файл(ПолноеИмяФайла); ПолученноеЗначение = ?(ФайлЗначения.Существует(), ЗначениеИзФайла(ПолноеИмяФайла), Неопределено); Если ПолученноеЗначение = Неопределено Тогда Возврат ПолученноеЗначение; КонецЕсли; СравнениеФайлов = Новый СравнениеФайлов; ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); Попытка // Антибаг платформы. ЗначениеВФайл на некоторых ошибках вызывает безусловное завершение работы http://devtool1c.ucoz.ru/forum/2-746-1 ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(ПолученноеЗначение); ЗначениеВФайл(ИмяВременногоФайла, ПолученноеЗначение); Успех = Истина; Исключение Сообщить("Не удалось сериализовать считанные из файла данные: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат ПолученноеЗначение; КонецПопытки; СравнениеФайлов.ПервыйФайл = ПолноеИмяФайла; СравнениеФайлов.ВторойФайл = ИмяВременногоФайла; СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное; Если Не СравнениеФайлов.Сравнить() Тогда Сообщить("При чтении из файла вероятно была потеряна часть информации", СтатусСообщения.Внимание); КонецЕсли; УдалитьФайлы(ИмяВременногоФайла); Возврат ПолученноеЗначение; КонецФункции #КонецЕсли //Для Объект = Неопределено возвращает Ложь, работает только для русского и английского языков платформы // Параметры: // КоличествоПараметров - нужно задать заведомо большее значение, чем может быть у метода Функция МетодРеализованЛкс(Объект, ИмяМетода) Экспорт Если Объект = Неопределено Тогда Возврат Ложь; КонецЕсли; Выражение = "Объект." + ИмяМетода + "(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)"; Попытка Выполнить(Выражение); Исключение Инфо = ИнформацияОбОшибке(); Описание = Инфо.Описание; //СообщитьИис(Описание); КонецПопытки; Результат = Ложь Или Описание = "Слишком много фактических параметров" Или Описание = "Too many actual parameters"; Возврат Результат; КонецФункции // Параметры: // КоличествоПроходов - Число(Н8,0) // КлючЗамера - Строка // ВыдатьСообщение - Булево // Функция НачатьЗамерЛкс(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров; Если Не ЗначениеЗаполнено(КлючЗамера) Тогда КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя; КонецЕсли; ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1); СтрокаЗамера = ТаблицаЗамеров.Добавить(); СтрокаЗамера.Ключ = КлючЗамера; #Если Клиент Тогда СтрокаЗамера.Отладчик = ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено; #КонецЕсли СтрокаЗамера.КоличествоПроходов = КоличествоПроходов; Если Ложь Или ВыдатьСообщение //Или СтрокаЗамера.Отладчик Тогда Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов; Если СтрокаЗамера.Отладчик Тогда Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!"; КонецЕсли; Сообщить(Сообщение); КонецЕсли; СтрокаЗамера.ДатаНачала = ПолучитьТекущееВремяВМиллисекундахЛкс(); Результат = КоличествоПроходов; Возврат Результат; КонецФункции // Параметры: // КлючЗамера - Строка - По умолчанию последний замер // Функция КончитьЗамерЛкс(Знач КлючЗамера = "") Экспорт ТекущееВремя = ПолучитьТекущееВремяВМиллисекундахЛкс(); ирПлатформа = ирКэш.Получить(); ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров; Если Не ЗначениеЗаполнено(КлючЗамера) Тогда Если ТаблицаЗамеров.Количество() > 0 Тогда СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1]; КонецЕсли; Иначе СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ"); КонецЕсли; Если СтрокаЗамера = Неопределено Тогда Возврат Неопределено; КонецЕсли; Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала; Длительность = Длительность / 1000; Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с"; Если СтрокаЗамера.КоличествоПроходов > 1 Тогда Среднее = Длительность / СтрокаЗамера.КоличествоПроходов; Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с"; КонецЕсли; Если Ложь Или СтрокаЗамера.Отладчик Или ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено Тогда Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!"; КонецЕсли; Сообщить(Сообщение); ТаблицаЗамеров.Удалить(СтрокаЗамера); Результат = Длительность; Возврат Результат; КонецФункции Функция ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора = Неопределено) Экспорт ВременнныйПостроительЗапроса = Новый ПостроительЗапроса; ВременнныйПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличноеПоле.Значение); Попытка ОтборСтрок = ТабличноеПоле.ОтборСтрок; Исключение КонецПопытки; Если ОтборСтрок <> Неопределено Тогда СкопироватьОтборПостроителяЛкс(ВременнныйПостроительЗапроса.Отбор, ОтборСтрок); КонецЕсли; Если СтруктураОтбора <> Неопределено Тогда Для Каждого КлючИЗначение Из СтруктураОтбора Цикл ВременнныйПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ).Установить(КлючИЗначение.Значение); КонецЦикла; КонецЕсли; Возврат ВременнныйПостроительЗапроса; КонецФункции Функция ПолучитьСтруктуруВыделенияТекстаЛкс() Экспорт Структура = Новый Структура(); Структура.Вставить("НачальнаяСтрока"); Структура.Вставить("НачальнаяКолонка"); Структура.Вставить("КонечнаяСтрока"); Структура.Вставить("КонечнаяКолонка"); Возврат Структура; КонецФункции Функция ПолеТекста_ПолучитьДиапазонВыделенияЛкс(ПолеТекста) Экспорт СтруктуруВыделения = ПолучитьСтруктуруВыделенияТекстаЛкс(); ПолеТекста.ПолучитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка, СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка); Возврат СтруктуруВыделения; КонецФункции Функция ПолеТекста_УстановитьДиапазонВыделенияЛкс(Знач ПолеТекста, Знач СтруктуруВыделения) Экспорт ПолеТекста.УстановитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка, СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка); Возврат Неопределено; КонецФункции // Копирует таблицу значений из исходной таблицы значений с удалением типа Null из описаний типов колонок. // Параметры: // ОбработатьТолькоКолонки - Строка - имена колонок разделенные запятыми // НеОбрабатыватьКолонки - Строка - имена колонок разделенные запятыми // // Возвращаемое значение: // ТаблицаЗначений // Функция ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Знач Таблица, ЗагружатьДанныеВНовуюТаблицу = Истина, ОбрабатыватьТолькоКолонки = "", НеОбрабатыватьКолонки = "") Экспорт Результат = Новый ТаблицаЗначений; НовыеКолонки = Результат.Колонки; ИсходныеКолонки = Таблица.Колонки; ИменаОбрабатываемыхКолонок = Новый Массив(); Если ОбрабатыватьТолькоКолонки <> "" Тогда ИменаОбрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбрабатыватьТолькоКолонки, ",", Истина); КонецЕсли; ИменаНеобрабатываемыхКолонок = Новый Массив(); Если НеОбрабатыватьКолонки <> "" Тогда ИменаНеобрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(НеОбрабатыватьКолонки, ",", Истина); КонецЕсли; Для Каждого Колонка Из ИсходныеКолонки Цикл Если Ложь Или (Истина И ОбрабатыватьТолькоКолонки <> "" И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено) Или (Истина И НеОбрабатыватьКолонки <> "" И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено) Тогда ОписаниеТипов = Колонка.ТипЗначения; Иначе ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL"); КонецЕсли; НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина); КонецЦикла; Если ЗагружатьДанныеВНовуюТаблицу Тогда ЗагрузитьВТаблицуЗначенийЛкс(Таблица, Результат); КонецЕсли; Возврат Результат; КонецФункции Функция ЛиСсылочныйОбъектМетаданных(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Истина) Экспорт Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда ПолноеИмя = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмя = ОбъектМД; КонецЕсли; МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя); Если Истина И Не ДляТабличнойЧастиПроверятьРодителя И МассивФрагментов.Количество() > 2 Тогда Возврат Ложь; КонецЕсли; КорневойТип = МассивФрагментов[0]; Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда Возврат Истина; ИначеЕсли Истина И МассивФрагментов.Количество() = 4 И КорневойТип = "ВнешнийИсточникДанных" Тогда Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные); Иначе Возврат Ложь; КонецЕсли; КонецФункции Функция ЛиРегистровыйОбъектМетаданных(ОбъектМД) Экспорт Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда ПолноеИмя = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмя = ОбъектМД; КонецЕсли; МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя); КорневойТип = МассивФрагментов[0]; Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда Возврат Истина; ИначеЕсли Истина И МассивФрагментов.Количество() = 4 И КорневойТип = "ВнешнийИсточникДанных" Тогда Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные); Иначе Возврат Ложь; КонецЕсли; КонецФункции Функция ЛиТипВнешнегоИсточникаДанных(Метаданные) Экспорт Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда ПолноеИмя = Метаданные.ПолноеИмя(); Иначе ПолноеИмя = Метаданные; КонецЕсли; КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмя); Возврат КорневойТип = "ВнешнийИсточникДанных"; КонецФункции Функция ПолучитьИмяТаблицыИзМетаданныхЛкс(Знач ОбъектМД, ЛиТаблицаИзменений = Ложь, ЛиДвиженияССубконтоДляРегистраБухгалтерии = Истина, ТолькоРазрешенные = Ложь) Экспорт Если ТипЗнч(ОбъектМД) <> Тип("Строка") Тогда ПолноеИмя = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмя = ОбъектМД; КонецЕсли; Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя); Если ТолькоРазрешенные Тогда Если ТипЗнч(ОбъектМД) = Тип("Строка") Тогда Если Фрагменты.Количество() > 1 Тогда ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]); // очень долгая операция, поэтому лучше не устанавливать флаг ТолькоРазрешенные Иначе //ОбъектМД = Метаданные[Фрагменты[0]]; ОбъектМД = Неопределено; КонецЕсли; КонецЕсли; Если Истина И ОбъектМД <> Неопределено И Не ПравоДоступа("Чтение", ОбъектМД) Тогда Возврат Неопределено; КонецЕсли; КонецЕсли; Если Истина И Фрагменты[0] = "Константа" И Фрагменты.Количество() = 2 И Не ЛиТаблицаИзменений Тогда Если Не ирКэш.ИндивидуальныеТаблицыКонстантДоступныЛкс() Тогда Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс("Константы"); КонецЕсли; КонецЕсли; Если Фрагменты.Количество() = 4 Тогда Если Ложь Или СтрокиРавныЛкс(Фрагменты[2], "ТабличнаяЧасть") Или СтрокиРавныЛкс(Фрагменты[2], "Перерасчет") //Или СтрокиРавныЛкс(Фрагменты[2], "Таблица") Тогда Фрагменты.Удалить(2); КонецЕсли; КонецЕсли; ИмяТаблицы = ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, "."); Если Истина И ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмя) И Не ЛиТаблицаИзменений И ЛиДвиженияССубконтоДляРегистраБухгалтерии Тогда ИмяТаблицы = ИмяТаблицы + ".ДвиженияССубконто"; КонецЕсли; Если ЛиТаблицаИзменений Тогда ИмяТаблицы = ИмяТаблицы + ".Изменения"; КонецЕсли; Возврат ИмяТаблицы; КонецФункции // ПолучитьИмяТаблицыИзМетаданныхЛкс() Функция ПолучитьОпределениеТаблицыБДДляИЗЛкс(ИмяТаблицы) Экспорт Результат = ИмяТаблицы; ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы); Если ТипТаблицы = "ДвиженияССубконто" Тогда Результат = Результат + "(,, {Регистратор.*, НомерСтроки, Активность})"; КонецЕсли; Возврат Результат; КонецФункции Процедура ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, выхМакетныйОбъект, выхТекущаяГруппаТипаМетаданных = Неопределено, выхКлючевыеПоля = Неопределено) Экспорт выхКлючевыеПоля = Новый Массив; ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы); Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Объект.")); выхТекущаяГруппаТипаМетаданных = "Ссылочный"; выхКлючевыеПоля.Добавить("Ссылка"); ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда выхМакетныйОбъект = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицы); выхТекущаяГруппаТипаМетаданных = "Регистр"; Для Каждого ЭлементОтбора Из выхМакетныйОбъект.Отбор Цикл выхКлючевыеПоля.Добавить(ЭлементОтбора.ПутьКДанным); КонецЦикла; ИначеЕсли ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "МенеджерЗначения.")); выхТекущаяГруппаТипаМетаданных = "Константа"; Иначе Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда выхТекущаяГруппаТипаМетаданных = "ВложеннаяТаблица"; КонецЕсли; //ВызватьИсключение "Макетный объект данных для таблицы типа " + ТипТаблицы + " не допустим"; КонецЕсли; КонецПроцедуры Функция ОписаниеТиповОбъектаИлиСтрокиБДПоИменамТаблицЛкс(Знач МассивИлиИмяТаблицыБД, Знач НуженТипОбъекта, РежимОбходаДанных = "Строки", Знач ТипТаблицы = Неопределено, выхПолноеИмяТаблицы = Неопределено) Экспорт МассивИменТаблицБД = Новый Массив(); Если ТипЗнч(МассивИлиИмяТаблицыБД) = Тип("Строка") Тогда ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(МассивИлиИмяТаблицыБД); МассивИменТаблицБД.Добавить(МассивИлиИмяТаблицыБД); Иначе МассивИменТаблицБД = МассивИлиИмяТаблицыБД; КонецЕсли; МассивТипов = Новый Массив(); Если Ложь Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Или ТипТаблицы = "Внешняя" Тогда Если РежимОбходаДанных = "КлючиОбъектов" Тогда РасширениеТипа = "Ссылка"; Иначе РасширениеТипа = "Объект"; КонецЕсли; Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, РасширениеТипа); МассивТипов.Добавить(Тип(ИмяТипа)); КонецЦикла; ИначеЕсли Ложь Или ирОбщий.ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы) Тогда Если РежимОбходаДанных = "КлючиОбъектов" Тогда РасширениеТипа = "Ссылка"; Иначе РасширениеТипа = "Объект"; КонецЕсли; Поля = ирОбщий.ПолучитьПоляТаблицыБДЛкс(МассивИменТаблицБД[0]); Поле = Поля.Найти("Ссылка", "Имя"); Для Каждого ТипЗначения Из Поле.ТипЗначения.Типы() Цикл ИмяТипа = ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(Метаданные.НайтиПоТипу(ТипЗначения), РасширениеТипа); МассивТипов.Добавить(Тип(ИмяТипа)); КонецЦикла; ИначеЕсли ТипТаблицы = "Точки" Тогда РасширениеТипа = "ТочкаМаршрутаБизнесПроцессаСсылка"; Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл ИмяТипа = СтрЗаменить(ИмяТаблицыБД, "БизнесПроцесс.", РасширениеТипа + "."); МассивТипов.Добавить(Тип(ИмяТипа)); КонецЦикла; ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(ТипТаблицы) Тогда РасширениеТипа = "Ссылка"; Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + "."); МассивТипов.Добавить(Тип(ИмяТипа)); КонецЦикла; ИначеЕсли ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипТаблицы) Тогда РасширениеТипа = "МенеджерЗначения"; Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл ИмяТипа = СтрЗаменить(ИмяТаблицыБД, ".", РасширениеТипа + "."); МассивТипов.Добавить(Тип(ИмяТипа)); КонецЦикла; ИначеЕсли ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл МассивФрагментов = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяТаблицыБД); выхПолноеИмяТаблицы = МассивФрагментов[0] + "." + МассивФрагментов[1]; Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда ИмяТипа = МассивФрагментов[0] + ТипТаблицы + "Строка." + МассивФрагментов[1]; Если ТипТаблицы = "ТабличнаяЧасть" Тогда ИмяТипа = ИмяТипа + "." + МассивФрагментов[2]; выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + МассивФрагментов[2]; Иначе выхПолноеИмяТаблицы = выхПолноеИмяТаблицы + "." + ТипТаблицы; КонецЕсли; МассивТипов.Добавить(Тип(ИмяТипа)); ИначеЕсли РежимОбходаДанных = "КлючиОбъектов" Тогда МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Ссылка." + МассивФрагментов[1])); Иначе МассивТипов.Добавить(Тип(МассивФрагментов[0] + "Объект." + МассивФрагментов[1])); КонецЕсли; КонецЦикла; ИначеЕсли Ложь Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда Если Не НуженТипОбъекта И РежимОбходаДанных = "Строки" Тогда РасширениеТипа = "Запись"; Иначе РасширениеТипа = "НаборЗаписей"; КонецЕсли; Для Каждого ИмяТаблицыБД Из МассивИменТаблицБД Цикл ТипЭлементаДанных = Тип(ирОбщий.ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяТаблицыБД, РасширениеТипа)); МассивТипов.Добавить(ТипЭлементаДанных); КонецЦикла; Иначе ВызватьИсключение "Неподдерживаемый тип таблицы """ + ТипТаблицы + """"; КонецЕсли; Результат = Новый ОписаниеТипов(МассивТипов); Возврат Результат; КонецФункции Функция ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмяМД) Экспорт Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД); Результат = Истина И Фрагменты.Количество() = 2 И (Ложь Или Фрагменты[0] = "AccountingRegister" Или Фрагменты[0] = "РегистрБухгалтерии"); Возврат Результат; КонецФункции // Создает тип из метаданных. // // Параметры: // Метаданные – ОбъектМетаданных; // *Расширение - Строка, "Ссылка" - расширение типа. // // Возвращаемое значение: // Тип. // Функция ПолучитьТипИзМетаданныхЛкс(ОбъектМД, Расширение = "Ссылка") Экспорт Возврат Тип(ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД, Расширение)); КонецФункции // ПолучитьТипИзМетаданных() Функция ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Экспорт ЭлементСостава = ОбщийРеквизит.Состав.Найти(ОбъектМетаданных); Результат = Истина И ЭлементСостава <> Неопределено И (Ложь Или ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Использовать Или (Истина И ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Авто И ОбщийРеквизит.АвтоИспользование = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита.Использовать)); Возврат Результат; КонецФункции Функция ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Знач Алгоритм) Экспорт Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда Алгоритм = "" + Алгоритм; Если Найти(Алгоритм, "-") > 0 Тогда // Передан GUID Алгоритм = Справочники.ирАлгоритмы.ПолучитьСсылку(Новый УникальныйИдентификатор(Алгоритм)); Иначе // Передано имя алгоритма Попытка Алгоритм = ПредопределенноеЗначение("Справочник.ирАлгоритмы." + Алгоритм); Исключение КонецПопытки; Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда Алгоритм = Справочники.ирАлгоритмы.НайтиПоНаименованию(Алгоритм, Истина); КонецЕсли; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(Алгоритм) Тогда ВызватьИсключение "Алгоритм по идентификатору """ + Алгоритм + """ не найден"; КонецЕсли; Возврат Алгоритм.ПолучитьОбъект(); КонецФункции //Если объекту не назначена ссылка, назначает эту ссылку Функция ПолучитьТочнуюСсылкуОбъектаЛкс(ОбъектБД) Экспорт Ссылка = ОбъектБД.Ссылка; Если Ссылка.Пустая() Тогда Ссылка = ОбъектБД.ПолучитьСсылкуНового(); Если Ссылка.Пустая() Тогда Ссылка = XMLЗначение(ТипЗнч(Ссылка), "" + Новый УникальныйИдентификатор); ОбъектБД.УстановитьСсылкуНового(Ссылка); КонецЕсли; КонецЕсли; Возврат Ссылка; КонецФункции Функция ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(Знач Текст) Экспорт Текст = Символы.ПС + Текст; Текст = СтрЗаменить(Текст, Символы.ПС, Символы.ПС + "|"); Текст = СтрЗаменить(Текст, """", """"""); Текст = """" + Текст + """"; Возврат Текст; КонецФункции // ПолучитьСтроковыйЛитералИзМногострочногоТекста() Функция ПолучитьВсеСтрокиДереваЗначенийЛкс(СтрокаИлиДеревоЗначений) Экспорт Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда ДеревоЗначений = СтрокаИлиДеревоЗначений.Владелец(); Иначе ДеревоЗначений = СтрокаИлиДеревоЗначений; КонецЕсли; Идентификатор = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); ДеревоЗначений.Колонки.Добавить(Идентификатор); ВсеСтроки = СтрокаИлиДеревоЗначений.Строки.НайтиСтроки(Новый Структура(Идентификатор,), Истина); ДеревоЗначений.Колонки.Удалить(Идентификатор); Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда ВсеСтроки.Добавить(СтрокаИлиДеревоЗначений); КонецЕсли; Возврат ВсеСтроки; КонецФункции // ПолучитьВсеСтрокиДереваЗначений() Функция СериализацииРавныЛкс(Таблица1, Таблица2) Экспорт Хмл1 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица1); Хмл2 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица2); Возврат (Хмл1 = Хмл2); КонецФункции // ВариантОбрезания - 1 // ВариантОбрезания - 2 Функция ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке = Неопределено, ВариантОбрезания = 2) Экспорт Если ИнформацияОбОшибке = Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); КонецЕсли; Если ВариантОбрезания = 1 Тогда ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; ИначеЕсли Истина И ВариантОбрезания = 2 И ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ИнформацияОбОшибке.Описание + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); Иначе ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; Возврат ОписаниеОшибки; КонецФункции // МаксимальнаяГлубинаПричины - на сколько уровней вниз надо опуститься, пока есть вложенная причина Функция ПредставлениеИнформацииОбОшибкеЛкс(Знач ИнформацияОбОшибке, Знач МаксимальнаяГлубинаПричины = 0, УбратьСтрокуКодаСПервогоУровня = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); #КонецЕсли ОписаниеОшибки = ""; Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда Для Счетчик = 1 По МаксимальнаяГлубинаПричины Цикл Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; #Если Сервер И Не Сервер Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); #КонецЕсли Иначе Прервать; КонецЕсли; КонецЦикла; Если УбратьСтрокуКодаСПервогоУровня Тогда ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); Иначе // Такое может случаться в свойстве ИнформацияОбОшибке объекта ФоновоеЗадание из-за ошибки платформы ОписаниеОшибки = "Описание ошибки отсутствует"; КонецЕсли; КонецЕсли; Возврат ОписаниеОшибки; КонецФункции // Первая строка табличного документа содержит заголовки Функция ПолучитьТаблицуИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок = Истина, ДлинаСтрокиТипаКолонки = 150, ВычислятьНетипизированныеЗначения = Ложь, ЛиВтораяСтрокаСодержитТипыЗначений = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент #КонецЕсли ТаблицаПриемник = Новый ТаблицаЗначений; НачальнаяСтрока = 1; Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда НачальнаяСтрока = НачальнаяСтрока + 1; КонецЕсли; Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда НачальнаяСтрока = НачальнаяСтрока + 1; КонецЕсли; ТипизированныеКолонки = Новый Соответствие; Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда ИмяКолонки = ТабличныйДокумент.Область(1, Счетчик).Текст; Иначе ИмяКолонки = "Колонка" + Счетчик; КонецЕсли; Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда ИменаТипов = ТабличныйДокумент.Область(2, Счетчик).Текст; Иначе ИменаТипов = ""; КонецЕсли; Если ЗначениеЗаполнено(ИменаТипов) Тогда ТипизированныеКолонки[Счетчик] = 1; КонецЕсли; ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов)); КонецЦикла; // Цикл перебора строк табличного документа ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы; //Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ВысотаТаблицы); Для НомерСтроки = НачальнаяСтрока По ВысотаТаблицы Цикл // Добавление строки результирующей таблицы НоваяСтрокаТЗ = ТаблицаПриемник.Добавить(); Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); ТекстЯчейки = Область.Текст; Если Не ЗначениеЗаполнено(ТекстЯчейки) Тогда Поддокумент = ТабличныйДокумент.ПолучитьОбласть(НомерСтроки, НомерКолонки); Если Поддокумент.Рисунки.Количество() > 0 Тогда ТекстЯчейки = Поддокумент.Рисунки[0].Картинка; КонецЕсли; КонецЕсли; ЗначениеЯчейки = Неопределено; Если ТипизированныеКолонки[НомерКолонки] <> Неопределено Тогда ОписаниеТиповКолонки = ТаблицаПриемник.Колонки[НомерКолонки - 1].ТипЗначения; Если ОписаниеТиповКолонки.СодержитТип(Тип("ОписаниеТипов")) Тогда Попытка ЗначениеЯчейки = Новый ОписаниеТипов(ТекстЯчейки); Исключение КонецПопытки; ИначеЕсли ОписаниеТиповКолонки.СодержитТип(Тип("Тип")) Тогда Попытка ЗначениеЯчейки = Тип(ТекстЯчейки); Исключение КонецПопытки; КонецЕсли; КонецЕсли; Если Ложь Или ВычислятьНетипизированныеЗначения Или (Истина И ТипизированныеКолонки[НомерКолонки] <> Неопределено И ЗначениеЯчейки = Неопределено) Тогда Попытка ЗначениеЯчейки = Вычислить(ТекстЯчейки); Исключение КонецПопытки; КонецЕсли; Если ЗначениеЯчейки = Неопределено Тогда ЗначениеЯчейки = ТекстЯчейки; КонецЕсли; НоваяСтрокаТЗ[НомерКолонки - 1] = ЗначениеЯчейки; КонецЦикла; КонецЦикла; Возврат ТаблицаПриемник; КонецФункции Процедура УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки, СхемаКомпоновки) Экспорт ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки)); #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы; Для НомерСтроки = 1 По ВысотаТаблицы Цикл Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ТипЗнч(Область.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда Для каждого ЗначениеПоля Из ДанныеРасшифровки.Элементы[Область.Расшифровка].ПолучитьПоля() Цикл Если Не ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда Продолжить; КонецЕсли; Область.Расшифровка = ЗначениеПоля.Значение; Прервать; КонецЦикла; КонецЕсли; КонецЦикла; КонецЦикла; КонецПроцедуры Функция ПолучитьИдентификаторТипаЛкс(Тип) Экспорт Результат = ПолучитьСтрокуМеждуМаркерамиЛкс("" + ЗначениеВСтрокуВнутр(Тип), ",", "}", Ложь); Возврат Результат; КонецФункции Функция ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(Знач ТекстПрограммы = "") Экспорт Если ПустаяСтрока(ТекстПрограммы) Тогда #Если Клиент Тогда ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс(); #Иначе ВызватьИсключение "Получение текста из буфера обмена возможно только на клиенте"; #КонецЕсли КонецЕсли; Параметры = Новый Структура(); ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой"); #Если Сервер И Не Сервер Тогда ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать(); #КонецЕсли ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно(); ПолеВстроенногоЯзыка.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина, ТекстПрограммы); СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический")); //СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова", "Свойство")); Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл Параметры.Вставить(СтрокаПеременной.Слово); КонецЦикла; Возврат Параметры; КонецФункции // КолонкиНабора - КоллекцияКолонокДереваЗначений, КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокРезультатаЗапроса Функция СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(Знач СхемаКомпоновкиДанных, Знач КолонкиНабора, Знач ИмяНабора = "Основной", Знач СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь) Экспорт #Если Сервер И Не Сервер Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; #КонецЕсли Результат = СхемаКомпоновкиДанных.НаборыДанных.Найти(ИмяНабора); Если Результат = Неопределено Тогда Результат = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных")); КонецЕсли; Результат.Имя = ИмяНабора; Результат.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя; Результат.ИмяОбъекта = ИмяНабора; Для Каждого ЭлементМетаданных Из КолонкиНабора Цикл Если Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаДереваЗначений") Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаТаблицыЗначений") Тогда ИмяПоля = ЭлементМетаданных.Имя; ЗаголовокПоля = ЭлементМетаданных.Заголовок; ИначеЕсли Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаРезультатаЗапроса") Тогда ИмяПоля = ЭлементМетаданных.Имя; ЗаголовокПоля = ИмяПоля; ИначеЕсли Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("ПолеНастройки") Тогда ИмяПоля = ЭлементМетаданных.Имя; ЗаголовокПоля = ЭлементМетаданных.Представление; ИначеЕсли Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("ДоступноеПолеОтбораКомпоновкиДанных") Тогда ИмяПоля = "" + ЭлементМетаданных.Поле; ЗаголовокПоля = ЭлементМетаданных.Заголовок; Иначе Продолжить; КонецЕсли; Поле = Результат.Поля.Найти(ИмяПоля); Если Поле = Неопределено Тогда Поле = Результат.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); КонецЕсли; ПутьКДанным = ИмяПоля; Если СоздаватьПапкиПолей Тогда ПутьКДанным = Результат.Имя + "." + ПутьКДанным; КонецЕсли; Поле.ПутьКДанным = ПутьКДанным; Поле.Поле = ИмяПоля; Поле.Заголовок = ЗаголовокПоля; Поле.ТипЗначения = ЭлементМетаданных.ТипЗначения; Если ЭлементМетаданных.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Поле.ВыражениеПредставления = "ирОбщий.РасширенноеПредставлениеЗначенияЛкс(" + ИмяПоля + ")"; КонецЕсли; Если Истина И СоздаватьРесурсыЧисловыхПолей И Поле.ТипЗначения.СодержитТип(Тип("Число")) Тогда Ресурс = СхемаКомпоновкиДанных.ПоляИтога.Добавить(); Ресурс.Выражение = "Сумма(" + ИмяПоля + ")"; Ресурс.ПутьКДанным = ИмяПоля; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Процедура ЗаполнитьПараметрыСхемыПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос) Экспорт #Если Сервер И Не Сервер Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; #КонецЕсли ОписанияПараметров = Запрос.НайтиПараметры(); // Здесь могут быть ложные ошибки синтаксического контроля Для Каждого ОписаниеПараметра Из ОписанияПараметров Цикл Если Не Запрос.Параметры.Свойство(ОписаниеПараметра.Имя) Тогда Запрос.Параметры.Вставить(ОписаниеПараметра.Имя); КонецЕсли; КонецЦикла; Для Каждого КлючИЗначение Из Запрос.Параметры Цикл ЗначениеПараметра = КлючИЗначение.Значение; Если ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда Список = Новый СписокЗначений; Список.ЗагрузитьЗначения(ЗначениеПараметра); ЗначениеПараметра = Список; КонецЕсли; ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти(КлючИЗначение.Ключ); Если ПараметрСхемы = Неопределено Тогда ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Добавить(); КонецЕсли; ПараметрСхемы.Имя = КлючИЗначение.Ключ; ПараметрСхемы.ДоступенСписокЗначений = ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений"); //Тип надо задавать, чтобы значение корректно записалось. Иначе ссылки будут преобразованы к строке. МассивТипов = Новый Массив; МассивТипов.Добавить(ТипЗнч(КлючИЗначение.Значение)); Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда ПараметрСхемы.ТипЗначения = Новый ОписаниеТипов(МассивТипов); КонецЕсли; ПараметрСхемы.Значение = ЗначениеПараметра; КонецЦикла; КонецПроцедуры Функция СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос, Знач ИмяНабора = "Основной", Представления = Неопределено) Экспорт НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновкиДанных.НаборыДанных, СхемаКомпоновкиДанных.ИсточникиДанных[0]); НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина; НаборДанных.Запрос = Запрос.Текст; Если Представления <> Неопределено Тогда Для Каждого КлючИЗначение Из Представления Цикл ПолеНабора = НаборДанных.Поля.Найти(КлючИЗначение.Ключ); Если ПолеНабора = Неопределено Тогда ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); КонецЕсли; ПолеНабора.Поле = КлючИЗначение.Ключ; ПолеНабора.ПутьКДанным = КлючИЗначение.Ключ; ПолеНабора.Заголовок = КлючИЗначение.Значение; КонецЦикла; КонецЕсли; ЗаполнитьПараметрыСхемыПоЗапросуЛкс(СхемаКомпоновкиДанных, Запрос); Возврат НаборДанных; КонецФункции // Представления - Структура Функция ПолучитьСхемуКомпоновкиПоЗапросуЛкс(Знач ЗапросИлиТекст, ИмяНабораДанных = "НаборДанных1", Представления = Неопределено) Экспорт Схема = Новый СхемаКомпоновкиДанных; ДобавитьЛокальныйИсточникДанныхЛкс(Схема); Если ТипЗнч(ЗапросИлиТекст) = Тип("Строка") Тогда Запрос = Новый Запрос; Запрос.Текст = ЗапросИлиТекст; Иначе Запрос = ЗапросИлиТекст; КонецЕсли; СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Схема, Запрос, ИмяНабораДанных, Представления); Возврат Схема; КонецФункции Функция ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(Знач ПолноеИмяИлиОбъектМД, ИмяНабораДанных = "НаборДанных1", ДобавитьАвтополеКоличествоСтрок = Истина, ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда ПолноеИмяМД = ПолноеИмяИлиОбъектМД; Иначе ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя(); КонецЕсли; ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД); Схема = ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность, ДобавитьАвтополеКоличествоСтрок, ИндексПараметраПериодичность, ПсевдонимТаблицы, ИменаВместоПредставлений); Возврат Схема; КонецФункции Функция ПолучитьПоляТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт Запрос = Новый Запрос; Запрос.Текст = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность) + " ГДЕ ЛОЖЬ"; Попытка ТаблицаРезультата = Запрос.Выполнить().Выгрузить(); Исключение ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.Текст = Запрос.Текст; Попытка ПостроительЗапроса.ЗаполнитьНастройки(); // Долгий способ пробуем только если быстрый не удался Исключение Если ВызыватьИсключениеПриОтсутствииПрав Тогда ВызватьИсключение; КонецЕсли; КонецПопытки; ТаблицаРезультата = Новый ТаблицаЗначений; Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл ТаблицаРезультата.Колонки.Добавить(ДоступноеПоле.ПутьКДанным, ДоступноеПоле.ТипЗначения); КонецЦикла; КонецПопытки; Если ТаблицаРезультата <> Неопределено Тогда ПоляТаблицы = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаРезультата).Колонки; КонецЕсли; Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя"); Результат.Колонки.Добавить("ТипЗначения"); Результат.Колонки.Добавить("Метаданные"); Результат.Колонки.Добавить("Заголовок"); Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл СтрокаПоля = Результат.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы); КонецЦикла; ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД); Если Истина И ТипТаблицы <> "ДвиженияССубконто" И ТипТаблицы <> "ВиртуальнаяТаблица" Тогда ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина); Если ОбъектМД <> Неопределено Тогда Если ТипТаблицы = "Внешняя" Тогда Для Каждого ПолеТаблицы Из ОбъектМД.Поля Цикл СтрокаПоля = Результат.Найти(ПолеТаблицы.Имя, "Имя"); Если СтрокаПоля <> Неопределено Тогда СтрокаПоля.Метаданные = ПолеТаблицы; Заголовок = ПолеТаблицы.Представление(); Если ЗначениеЗаполнено(Заголовок) Тогда СтрокаПоля.Заголовок = Заголовок; КонецЕсли; КонецЕсли; КонецЦикла; Иначе ПрефиксРеквизита = ОбъектМД.ПолноеИмя() + ".Реквизит."; РодительМД = ОбъектМД.Родитель(); Если Истина И ТипТаблицы <> "Перерасчет" И ТипТаблицы <> "Внешняя" И ТипЗнч(РодительМД) <> Тип("ОбъектМетаданныхКонфигурация") Тогда ОбъектМДФильтра = РодительМД; Иначе ОбъектМДФильтра = ОбъектМД; КонецЕсли; ФильтрМетаданных = Новый Массив; ФильтрМетаданных.Добавить(ОбъектМДФильтра); //Если ТипТаблицы = "ДвиженияССубконто" Тогда // ПолноеИмяТаблицыБД = Лев(ПолноеИмяТаблицыБД, СтрДлина(ПолноеИмяТаблицыБД) - СТрДлина(".ДвиженияССубконто")); //КонецЕсли; СтрокиСтруктурыТаблицы = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("ИмяТаблицы", ПолноеИмяТаблицыБД)); Если СтрокиСтруктурыТаблицы.Количество() = 0 Тогда Если Истина И ТипТаблицы <> "Изменения" И ТипТаблицы <> "Границы" И ТипТаблицы <> "Константа" И ТипТаблицы <> "ЗадачиПоИсполнителю" Тогда Сообщить("Не удалось найти в структуре хранения БД описание таблицы " + ПолноеИмяТаблицыБД); Иначе // Для отладки // Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы. // Сюда попадаем для границ последовательностей, у которых ошибочно пустое имя таблицы. Пустышка = 1; КонецЕсли; Иначе Если СтрокиСтруктурыТаблицы.Количество() > 1 Тогда Пустышка = 1; // Для отладки. Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы КонецЕсли; Для Каждого ПолеТаблицы Из СтрокиСтруктурыТаблицы[0].Поля Цикл Если Истина И ЗначениеЗаполнено(ПолеТаблицы.Метаданные) И (Ложь Или ПолеТаблицы.ИмяПоля <> "НомерСтроки" Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0) Тогда СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя"); Если СтрокаПоля <> Неопределено Тогда Если Найти(ПолеТаблицы.Метаданные, ПрефиксРеквизита) = 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 Тогда НеуникальныйКлюч = Новый Структура(ИменаКолонок); ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии); МассивНеуникальных.Добавить(НеуникальныйКлюч); КонецЕсли; КонецЦикла; Возврат МассивНеуникальных; КонецФункции // ПолучитьНеуникальныеЗначенияКолонки() Функция СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт НаборЗаписей = Новый (ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД)); Возврат НаборЗаписей; КонецФункции Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, РасширениеТипа = "НаборЗаписей") Экспорт Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД); Если Фрагменты.Количество() > 2 Тогда Если Фрагменты[0] = "РегистрРасчета" Тогда ИмяТипа = "Перерасчет" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[2]; ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда ИмяТипа = "РегистрБухгалтерии" + РасширениеТипа + "." + Фрагменты[1]; ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда ИмяТипа = "ВнешнийИсточникДанныхТаблица" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[3]; КонецЕсли; Иначе ИмяТипа = СтрЗаменить(ПолноеИмяТаблицыБД, ".", РасширениеТипа + "."); КонецЕсли; Возврат ИмяТипа; КонецФункции Функция ПолучитьТипКлючаЗаписиТаблицыЛкс(ПолноеИмяТаблицы) Экспорт ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы); Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда Результат = Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяТаблицы)); ИначеЕсли Истина И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) И ТипТаблицы <> "Перерасчет" И ТипТаблицы <> "Последовательность" Тогда Результат = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "КлючЗаписи.")); Иначе Результат = Тип("Неопределено"); КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ВернутьСтруктуру - Булево - возвращать структуру иначе список значений // КлючаНабораЗаписейРегистраСведений - Булево - для регистров сведений подчиненных регистратору вернуть ключ записываемого объекта // Функция ПолучитьСтруктуруКлючаТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВключатьНомерСтроки = Истина, ВернутьСтруктуру = Истина, ДляНабораЗаписейРегистраСведений = Истина) Экспорт ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД); МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД); СписокПолей = Новый СписокЗначений; Если Ложь Или ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка"); ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД); НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД); #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей(); #КонецЕсли Если Истина И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору И Не ДляНабораЗаписейРегистраСведений Тогда Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период"); КонецЕсли; Если ОбъектМД.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда СписокПолей.Добавить(НаборЗаписей.Отбор.Регистратор.ТипЗначения, "Регистратор"); КонецЕсли; Для Каждого Измерение Из ОбъектМД.Измерения Цикл СписокПолей.Добавить(Измерение.Тип, Измерение.Имя); КонецЦикла; КонецЕсли; Если СписокПолей.Количество() = 0 Тогда Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл Если Ложь Или ЭлементОтбора.Использование Или ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя); КонецЕсли; КонецЦикла; КонецЕсли; Если ВключатьНомерСтроки Тогда Если ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период"); ИначеЕсли Истина И ТипТаблицы <> "Перерасчет" И (Ложь Или Не ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) Или (ДляНабораЗаписейРегистраСведений И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору)) Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки"); КонецЕсли; КонецЕсли; ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка"); Если ВключатьНомерСтроки Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки"); КонецЕсли; ИначеЕсли ТипТаблицы = "Изменения" Тогда // Такой способ может быть долгим при частых вызовах ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.Текст = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицыБД + " КАК _Таблица_"; ПостроительЗапроса.ЗаполнитьНастройки(); Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл Если Ложь Или СтрокиРавныЛкс(ДоступноеПоле.ПутьКДанным, "НомерСообщения") Тогда Продолжить; КонецЕсли; СписокПолей.Добавить(ДоступноеПоле.ТипЗначения, ДоступноеПоле.ПутьКДанным); КонецЦикла; ИначеЕсли ТипТаблицы = "Внешняя" Тогда ТаблицаМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяТаблицыБД); Если ТаблицаМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные Тогда СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка"); Иначе НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД); Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя); КонецЦикла; КонецЕсли; ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда Поля = ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД); Поле = Поля.Найти("Ссылка", "Имя"); СписокПолей.Добавить(Поле.ТипЗначения, "Ссылка"); Иначе ВызватьИсключение "Полученияе структуры ключа таблицы БД типа " + ТипТаблицы + " не поддерживается"; КонецЕсли; Если ВернутьСтруктуру Тогда Результат = Новый Структура(); Для Каждого ЭлементСписка Из СписокПолей Цикл Результат.Вставить(ЭлементСписка.Представление, ЭлементСписка.Значение); КонецЦикла; Иначе Результат = СписокПолей; КонецЕсли; Возврат Результат; КонецФункции Функция ЦветТекстаНеактивностиЛкс() Экспорт Возврат Новый Цвет(100, 100, 100); КонецФункции // Для подчиненного регистра сведений выполняет чтение из БД // Результат - Структура Функция ПолучитьКлючНабораЗаписейИзКлючаЗаписиЛкс(КлючЗаписи, ПолноеИмяМДЭлемента = "") Экспорт Если Не ЗначениеЗаполнено(ПолноеИмяМДЭлемента) Тогда ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи)); ПолноеИмяМДЭлемента = ОбъектМД.ПолноеИмя(); Иначе ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМДЭлемента); КонецЕсли; СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента, Ложь,, Ложь); ЗаполнитьЗначенияСвойств(СтруктураКлюча, КлючЗаписи); ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяМДЭлемента); Если Истина И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда ДанныеСтроки = ПолучитьСтрокуТаблицыБДПоКлючуЛкс(ПолноеИмяМДЭлемента, СтруктураКлюча); СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента); ЗаполнитьЗначенияСвойств(СтруктураКлюча, ДанныеСтроки); КонецЕсли; Возврат СтруктураКлюча; КонецФункции Функция ПолучитьXMLКлючОбъектаБДЛкс(Знач ОбъектДанных, Знач ИспользоватьСсылкуДляСсылочных = Ложь) Экспорт Если ОбъектДанных = Неопределено Тогда Результат = "Неопределено"; Возврат Результат; КонецЕсли; ПредставлениеОбъекта = ""; Если ТипЗнч(ОбъектДанных) = Тип("УдалениеОбъекта") Тогда Класс = "Удаление"; Иначе Попытка ЭтоНовый = ОбъектДанных.ЭтоНовый(); Класс = "Ссылочный"; ПредставлениеОбъекта = "" + ОбъектДанных + ","; Исключение Попытка УникальныйИдентификатор = ОбъектДанных.УникальныйИдентификатор(); Класс = "Ссылочный"; Исключение Попытка Пустышка = ОбъектДанных.Модифицированность(); Класс = "НаборЗаписей"; Исключение Попытка Пустышка = ОбъектДанных.Значение; Класс = "Константы"; Исключение Класс = "Примитив"; КонецПопытки; КонецПопытки; КонецПопытки; КонецПопытки; Если Истина И Класс = "Ссылочный" И ИспользоватьСсылкуДляСсылочных Тогда Результат = ОбъектДанных; Возврат Результат; КонецЕсли; КонецЕсли; XMLКлюч = "" + XMLТип(ТипОбъектаБДЛкс(ОбъектДанных)).ИмяТипа + "("; Если Класс = "Ссылочный" Тогда Если ЭтоНовый = Истина Тогда УникальныйИдентификатор = "!" + ОбъектДанных.ПолучитьСсылкуНового().УникальныйИдентификатор(); КонецЕсли; Если УникальныйИдентификатор = Неопределено Тогда УникальныйИдентификатор = ОбъектДанных.Ссылка.УникальныйИдентификатор(); КонецЕсли; XMLКлюч = XMLКлюч + ПредставлениеОбъекта + УникальныйИдентификатор; ИначеЕсли Класс = "Удаление" Тогда XMLКлюч = XMLКлюч + ПолучитьXMLКлючОбъектаБДЛкс(ОбъектДанных.Ссылка); ИначеЕсли Класс = "НаборЗаписей" Тогда ПредставлениеОтбора = ""; Разделитель = ", "; Для Каждого ЭлементОтбора Из ОбъектДанных.Отбор Цикл Если ЭлементОтбора.Использование Тогда ПредставлениеОтбора = ПредставлениеОтбора + Разделитель + ЭлементОтбора.Имя + ":" + ПолучитьXMLКлючОбъектаБДЛкс(ЭлементОтбора.Значение); КонецЕсли; КонецЦикла; XMLКлюч = XMLКлюч + Сред(ПредставлениеОтбора, СтрДлина(Разделитель) + 1); ИначеЕсли Класс = "Константы" Тогда // Иначе // Примитивный тип XMLКлюч = XMLКлюч + ОбъектДанных; КонецЕсли; XMLКлюч = XMLКлюч + ")"; Результат = XMLКлюч; Возврат Результат; КонецФункции // Параметры: // Объект - ОбъектБД, ОбъектМД Функция ПолучитьТабличныеЧастиОбъектаЛкс(Объект) Экспорт Если Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда ОбъектМД = Метаданные.НайтиПоТипу(Объект._Тип); ОбъектБД = Объект.Данные; ИначеЕсли ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда ОбъектМД = Объект; ОбъектБД = Неопределено; Иначе ОбъектМД = Объект.Метаданные(); ОбъектБД = Объект; КонецЕсли; СтруктураТЧ = Новый Структура(); ЭтоСправочник = Метаданные.Справочники.Индекс(ОбъектМД) >= 0; Если Не ЛиСсылочныйОбъектМетаданных(ОбъектМД, Ложь) Тогда Возврат СтруктураТЧ; КонецЕсли; Для Каждого МетаТЧ из ОбъектМД.ТабличныеЧасти Цикл // Для реквизитов справочников, принадлежащих только группе или только элементу нужно игнорировать те объекты, для которых эти реквизиты не используются Если Истина И ОбъектБД <> Неопределено И ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМД) Тогда Если Ложь Или (Истина И ОбъектБД.ЭтоГруппа И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Или (Истина И Не ОбъектБД.ЭтоГруппа И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Тогда Продолжить КонецЕсли; КонецЕсли; СтруктураТЧ.Вставить(МетаТЧ.Имя, МетаТЧ.Представление()); КонецЦикла; Если Метаданные.ПланыСчетов.Индекс(ОбъектМД) >= 0 Тогда Если ОбъектМД.ВидыСубконто <> Неопределено Тогда СтруктураТЧ.Вставить("ВидыСубконто", "Виды субконто"); КонецЕсли; КонецЕсли; Если Метаданные.ПланыВидовРасчета.Индекс(ОбъектМД) >= 0 Тогда Если ОбъектМД.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.НеИспользовать Тогда СтруктураТЧ.Вставить("БазовыеВидыРасчета", "Базовые виды расчета"); КонецЕсли; СтруктураТЧ.Вставить("ВедущиеВидыРасчета", "Ведущие виды расчета"); Если ОбъектМД.ИспользованиеПериодаДействия Тогда СтруктураТЧ.Вставить("ВытесняющиеВидыРасчета", "Вытесняющие виды расчета"); КонецЕсли; КонецЕсли; Возврат СтруктураТЧ; КонецФункции Функция ЛиСтрокаСодержитВсеПодстрокиЛкс(Знач Строка, Знач Подстроки) Экспорт Если ТипЗнч(Подстроки) = Тип("Строка") Тогда Подстроки = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина); КонецЕсли; НСтрока = НРег(Строка); Для Каждого Фрагмент Из Подстроки Цикл Если Найти(НСтрока, Фрагмент) = 0 Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецФункции Функция ПолучитьСтрокуТаблицыБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча) Экспорт Запрос = Новый Запрос; ТекстЗапроса = "ВЫБРАТЬ Т.* ИЗ " + ПолноеИмяТаблицы + " КАК Т ГДЕ ИСТИНА "; Для Каждого КлючИЗначение Из СтруктураКлюча Цикл ТекстЗапроса = ТекстЗапроса + " И Т." + КлючИЗначение.Ключ + " = &" + КлючИЗначение.Ключ; КонецЦикла; СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураКлюча, Запрос.Параметры); Запрос.Текст = ТекстЗапроса; Таблица = Запрос.Выполнить().Выгрузить(); Если Таблица.Количество() > 1 Тогда ВызватьИсключение "По переданному ключу (" + ПолучитьПредставлениеСтруктурыЛкс(СтруктураКлюча) + ") найдено несколько строк таблицы"; ИначеЕсли Таблица.Количество() > 0 Тогда СтрокаРезультата = Таблица[0]; Иначе СтрокаРезультата = Неопределено; КонецЕсли; Возврат СтрокаРезультата; КонецФункции // Присваивает ячейке по указателю значение. Если после этого ячейка получает другое значение, то ячейке присваивается ее старое значение. Функция БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(П1, П2) Экспорт СтароеП1 = П1; П1 = П2; Если П1 <> П2 Тогда П1 = СтароеП1; Возврат Ложь; КонецЕсли; Возврат Истина; КонецФункции // БезопасноПрисвоитьПроизвольнуюСсылку() // ЛиНаходитьОбразующий - Булево - находить ближайший объект метаданных, если точный найти не удается Функция НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ЛиНаходитьОбразующий = Ложь) Экспорт Результат = Неопределено; Если Истина И Не ПустаяСтрока(ПолноеИмяТаблицыБД) И ПолноеИмяТаблицыБД <> "Константы" Тогда Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД); Если Фрагменты.Количество() < 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 Быстрый при небольшом количестве планов обмена, а при большом? ОбъектыМетаданныхСРегистрациейИзменений = ирКэш.ОбъектыМетаданныхСРегистрациейИзменений(); ЕстьТаблицаИзменений = ОбъектыМетаданныхСРегистрациейИзменений[ОбъектМетаданных.ПолноеИмя()] <> Неопределено; Возврат ЕстьТаблицаИзменений; КонецФункции Функция СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект) Экспорт Структура = Новый Структура; СтруктураОбменаДанными = СтруктураОбменаДаннымиОбъектаЛкс(Объект); Если СтруктураОбменаДанными <> Неопределено Тогда Структура.Вставить("ОбменДанными", СтруктураОбменаДанными); КонецЕсли; Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда ДополнительныеСвойства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 Тогда НужноВызватьИсключение = Ложь; КонецЕсли; КонецЕсли; Если Не НужноВызватьИсключение Тогда Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда //НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда //НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда //НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; КонецЕсли; КонецЕсли; #Если Клиент Тогда Если ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(НОписаниеОшибки, Ложь) Тогда ВызватьИсключение; КонецЕсли; #КонецЕсли Если НужноВызватьИсключение Тогда СостояниеОбъекта = ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект); Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта; Иначе НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда ВызватьИсключение НовоеОписаниеОшибки; Иначе ВызватьИсключение; КонецЕсли; КонецЕсли; КонецПопытки; КонецЦикла; КонецЕсли; КонецПроцедуры Функция ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта) Экспорт ЭтоИмитатор = Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И (Ложь Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей") Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторКонстантаМенеджер") Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект")); Возврат ЭтоИмитатор; КонецФункции Процедура УстановитьПометкуУдаленияОбъектаЛкс(Объект, НаСервере = Ложь, ЗначениеПометки = Истина, БезАвторегистрацииИзменений = Неопределено) Экспорт Если НаСервере Тогда ТипОбъекта = ТипЗнч(Объект); ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта); Если ЭтоИмитатор Тогда Объект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 //КонецЕсли; КонецЕсли; Если Объект = Неопределено Тогда Если ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта)) Тогда выхИдентификаторСсылки = КлючОбъекта.УникальныйИдентификатор(); ИначеЕсли Не СохранятьИдентификаторСсылки Тогда выхИдентификаторСсылки = Неопределено; КонецЕсли; Если КлючОбъекта <> "" Тогда ЭтоГруппаДляНового = КлючОбъекта = Истина; Попытка Объект = ирОбщий.СоздатьСсылочныйОбъектПоМетаданнымЛкс(мПолноеИмяМД, ЭтоГруппаДляНового, выхИдентификаторСсылки); Исключение // Может не быть прав на создание объекта Сообщить("Ошибка создания объекта: " + ОписаниеОшибки()); Возврат Неопределено; КонецПопытки; КонецЕсли; КонецЕсли; Данные = Объект; Методы = Объект; //#Если Не Клиент И Сервер Тогда Если НаСервере И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда ИмитаторОбъекта = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторСсылочныйОбъект"); #Если Сервер И Не Сервер Тогда ИмитаторОбъекта = Обработки.ирИмитаторСсылочныйОбъект.Создать(); #КонецЕсли ИмитаторОбъекта.Конструктор(Объект); Данные = ИмитаторОбъекта.Данные; Методы = ИмитаторОбъекта; КонецЕсли; //#КонецЕсли КонецЕсли; Иначе Если ЭтоКонстанта Тогда Объект = Новый (СтрЗаменить(ИмяОсновнойТаблицы, ".", "МенеджерЗначения.")); Иначе Объект = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяОсновнойТаблицы); #Если Сервер И Не Сервер Тогда Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей(); #КонецЕсли КлючОбъекта = ПолучитьКлючНабораЗаписейИзКлючаЗаписиЛкс(КлючОбъекта, ИмяОсновнойТаблицы); Для Каждого КлючИЗначение Из КлючОбъекта Цикл Объект.Отбор[КлючИЗначение.Ключ].Установить(КлючИЗначение.Значение); КонецЦикла; КонецЕсли; Данные = Объект; Методы = Объект; Если ЧитатьДанные Тогда Объект.Прочитать(); КонецЕсли; //#Если Не Клиент И Сервер Тогда Если НаСервере И Не ирКэш.ЛиПортативныйРежимЛкс()Тогда Если ЭтоКонстанта Тогда ИмитаторОбъекта = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторКонстантаМенеджер"); ИмитаторОбъекта.Конструктор(Объект); Иначе ИмитаторОбъекта = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторНаборЗаписей"); ИмитаторОбъекта.Конструктор(Объект); КонецЕсли; Данные = ИмитаторОбъекта.Данные; Методы = ИмитаторОбъекта; КонецЕсли; //#КонецЕсли КонецЕсли; Результат.Вставить("Данные", Данные); Результат.Вставить("Методы", Методы); Возврат Результат; КонецЕсли; Возврат Результат; КонецФункции Функция ТипОбъектаБДЛкс(ОбъектБД) Экспорт Результат = ТипЗнч(ОбъектБД); Если Результат = Тип("Структура") Тогда Имитатор = ОбъектБД.Методы; Иначе Имитатор = ОбъектБД; КонецЕсли; Результат = ТипЗнч(Имитатор); Если ЭтоТипИмитатораОбъектаЛкс(Результат) Тогда Результат = Имитатор._Тип; КонецЕсли; Возврат Результат; КонецФункции Функция КопияОбъектаБДЛкс(СтруктураОбъекта) Экспорт СтруктураОбъекта = СтруктураОбъекта.Методы.Скопировать(); Если ТипЗнч(СтруктураОбъекта) = Тип("Структура") Тогда Возврат СтруктураОбъекта; Иначе СтруктураОбъекта = Новый Структура; СтруктураОбъекта.Вставить("Методы", СтруктураОбъекта); СтруктураОбъекта.Вставить("Данные", СтруктураОбъекта); КонецЕсли; КонецФункции Функция СкопироватьТаблицуЛкс(ТаблицаИлиТабличнаяЧасть, ПараметрыОтбора = Неопределено, Колонки = Неопределено) Экспорт Если ТипЗнч(ТаблицаИлиТабличнаяЧасть) = Тип("ТаблицаЗначений") Тогда Результат = ТаблицаИлиТабличнаяЧасть.Скопировать(ПараметрыОтбора, Колонки); Иначе Результат = ТаблицаИлиТабличнаяЧасть.Выгрузить(ПараметрыОтбора, Колонки); КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект) Попытка ДополнительныеСвойства = Объект.ДополнительныеСвойства; Исключение ДополнительныеСвойства = Новый Структура; КонецПопытки; СостояниеОбъекта = ""; Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + КлючИЗначение.Значение; КонецЦикла; Возврат СостояниеОбъекта; КонецФункции // Позволяет перечитать объект грязным чтением, т.е. без учета блокировок. Не перечитывает свойство ВерсияДанных! // На выходе объект имеет модифицированноть. Для удаленного объекта возвращает Неопределено. Функция ПеречитатьОбъектЗапросомЛкс(Знач Объект) Экспорт ОбъектМД = Объект.Метаданные(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ * ИЗ " + ОбъектМД.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка); ТаблицаОбъекта = Запрос.Выполнить().Выгрузить(); Если ТаблицаОбъекта.Количество() > 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.cfg"); Если ФайлУказатель.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя); Текст = ТекстовыйДокумент.ПолучитьТекст(); НовыйКаталогКонфигурацииПриложения = ПолучитьСтрокуМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС); НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения); Если НовыйКаталог.Существует() Тогда КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения; КонецЕсли; КонецЕсли; КонецЕсли; Если СоздатьЕслиОтсутствует Тогда Файл = Новый Файл(КаталогКонфигурацииПриложения); Если Не Файл.Существует() Тогда СоздатьКаталог(КаталогКонфигурацииПриложения); КонецЕсли; КонецЕсли; Результат = КаталогКонфигурацииПриложения; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьТекстКонфигурационногоФайлаВнешнихСоединенийЛкс(АдресОтладчика = "") Экспорт ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(" | //| | |" ); Возврат ТекстовыйДокумент; КонецФункции Функция ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(); Иначе КаталогКонфигурацииПриложения = ПолучитьКаталогНастроекПриложения1СЛкс(Ложь); Результат = КаталогКонфигурацииПриложения + "\logcfg.xml"; Файл = Новый Файл(Результат); Если Файл.Существует() Тогда Возврат Результат; КонецЕсли; КаталогКонфигурацииПриложения = ПолучитьКаталогНастроекПриложения1СЛкс(Истина); Результат = КаталогКонфигурацииПриложения + "\logcfg.xml"; Файл = Новый Файл(Результат); Если Файл.Существует() Тогда Возврат Результат; КонецЕсли; Результат = Неопределено; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьКаталогТехножурналаЛкс(НаСервере = Ложь) Экспорт ИмяФайлаНастроекЖурнала = ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере); Если ЗначениеЗаполнено(ИмяФайлаНастроекЖурнала) Тогда ТекстХМЛ = ПрочитатьТекстИзФайлаЛкс(ИмяФайлаНастроекЖурнала, , НаСервере); ЧтениеХМЛ = Новый ЧтениеXML; ЧтениеХМЛ.УстановитьСтроку(ТекстХМЛ); ПостроительДом = Новый ПостроительDOM(); Попытка ДокументДОМ = ПостроительДом.Прочитать(ЧтениеХМЛ); Исключение Сообщить("Ошибка чтения настройки техножурнала: " + ОписаниеОшибки(), СтатусСообщения.Внимание); КонецПопытки; Если ДокументДОМ <> Неопределено Тогда Узлы = ДокументДом.ПолучитьЭлементыПоИмени("log"); Если Узлы.Количество() > 0 Тогда Атрибут = Узлы.Элемент(0).Атрибуты.ПолучитьИменованныйЭлемент("location"); Если Атрибут <> Неопределено Тогда Результат = Атрибут.ТекстовоеСодержимое; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиТехножурналВключенЛкс(НаСервере = Ложь, ВыводитьСообщения = Ложь) Экспорт КаталогЖурнала = ""; КаталогЖурналаВзятИзНастроекЧтения = Ложь; Если НаСервере Тогда #Если Клиент Тогда КаталогЖурнала = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогЖурналаСервера"); КаталогЖурналаВзятИзНастроекЧтения = Истина; #КонецЕсли КонецЕсли; Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда КаталогЖурнала = ПолучитьКаталогТехножурналаЛкс(НаСервере); КаталогЖурналаВзятИзНастроекЧтения = Ложь; КонецЕсли; Если ЗначениеЗаполнено(КаталогЖурнала) Тогда Если Не ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере, ВыводитьСообщения) Тогда Возврат Истина; Иначе Если ВыводитьСообщения Тогда Если КаталогЖурналаВзятИзНастроекЧтения Тогда Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в настройках чтения анализа техножурнала", СтатусСообщения.Внимание); Иначе Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в текущей настройке техножурнала", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; КонецЕсли; Иначе Если ВыводитьСообщения Тогда Если НаСервере Тогда Сообщить("Каталог техножурнала сервера не удалось прочитать из текущей настройки техножурнала и не задан в настройках чтения инструмента ""Анализ техножурнала"""); Иначе Сообщить("Каталог техножурнала клиента не удалось прочитать из текущей настройки техножурнала"); КонецЕсли; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьСообщения = Истина) Экспорт Если НаСервере Тогда Результат = ирСервер.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала); Иначе Результат = Ложь; ФайлКаталог = Новый Файл(КаталогЖурнала); Если Не ФайлКаталог.Существует() Тогда Результат = Истина; Иначе БлокирующиеФайлы = НайтиФайлы(КаталогЖурнала, "*.*"); Для Каждого БлокирующийФайл Из БлокирующиеФайлы Цикл Если Не БлокирующийФайл.ЭтоКаталог() Тогда Если ВыводитьСообщения Тогда ТекстСообщения = "В корне каталога """ + КаталогЖурнала + """ техножурнала "; Если НаСервере Тогда ТекстСообщения = ТекстСообщения + "сервера"; Иначе ТекстСообщения = ТекстСообщения + "клиента"; КонецЕсли; Сообщить(ТекстСообщения + " обнаружены блокирующие файлы. Для работы журнала их необходимо удалить.", СтатусСообщения.Внимание); КонецЕсли; Результат = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиКлиентЗапущенНаКомпьютереСервераЛкс() Экспорт Результат = НРег(ирСервер.ПолучитьИмяКомпьютераЛкс()) = НРег(ИмяКомпьютера()); Возврат Результат; КонецФункции Функция ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка = Неопределено, НаСервере = Ложь) Экспорт Если НаСервере Тогда ирСервер.ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка); Иначе ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(Текст); ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); ТекстовыйДокумент.Записать(ИмяВременногоФайла, Кодировка); мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли мПлатформа.ПереместитьФайлКакАдминистратор(ИмяВременногоФайла, ПолноеИмяФайла); КонецЕсли; КонецФункции Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено, НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка); Иначе ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ПолноеИмяФайла, Кодировка); Результат = ТекстовыйДокумент.ПолучитьТекст(); КонецЕсли; Возврат Результат; КонецФункции Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина, НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах); Иначе Файлы = НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах); Результат = Новый Массив; Для Каждого Файл Из Файлы Цикл Результат.Добавить(Файл.ПолноеИмя); КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ИзданиеПлатформы - Строка(0,П) // Функция ПолучитьКаталогПустойИнфобазыЛкс(Знач ИзданиеПлатформы = "") Экспорт Если Не ЗначениеЗаполнено(ИзданиеПлатформы) Тогда ИзданиеПлатформы = ирКэш.Получить().ИДВерсииПлатформы; КонецЕсли; ShellApplication = Новый COMobject("Shell.Application"); КаталогПустойИнфобазы = ShellApplication.NameSpace(28).Self.Path; КаталогПустойИнфобазы = КаталогПустойИнфобазы + "\1C\1Cv" + ИзданиеПлатформы + "\EmptyDB"; Результат = КаталогПустойИнфобазы; Возврат Результат; КонецФункции // Параметры: // СоздаватьБазуВСлучаеОтсутствия - Булево // Функция ПолучитьСтрокуСоединенияПустойИнфобазыЛкс(ИзданиеПлатформы = "", Знач СоздаватьБазуВСлучаеОтсутствия = Истина) Экспорт КаталогПустойИнфобазы = ПолучитьКаталогПустойИнфобазыЛкс(ИзданиеПлатформы); Если СоздаватьБазуВСлучаеОтсутствия Тогда ФайлПустойИнфобазы = Новый Файл(КаталогПустойИнфобазы + "\1CV8.1CD"); Если Не ФайлПустойИнфобазы.Существует() Тогда СтрокаПараметров = "CREATEINFOBASE File=" + КаталогПустойИнфобазы + ";"; //СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу"; ИмяФайлаЛога = ПолучитьИмяВременногоФайла(); СтрокаПараметров = СтрокаПараметров + " /out" + ИмяФайлаЛога; СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + СтрокаПараметров; ирКэш.Получить().ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска); //ВыполнитьСкрытуюКомандуОС КонецЕсли; КонецЕсли; СтрокаСоединения = "File=""" + КаталогПустойИнфобазы + """;"; Результат = СтрокаСоединения; Возврат Результат; КонецФункции Функция СоздатьФайловуюБазу1СЛкс(Знач КаталогИнфобазы = "", ИмяФайлаКонфигурации = "", УдалитьСуществующую = Ложь) Экспорт ФайлПустойИнфобазы = Новый Файл(КаталогИнфобазы + "\1CV8.1CD"); Если ФайлПустойИнфобазы.Существует() И УдалитьСуществующую Тогда УдалитьФайлы(КаталогИнфобазы); КонецЕсли; Если Не ФайлПустойИнфобазы.Существует() Тогда СтрокаПараметров = "CREATEINFOBASE File=""" + КаталогИнфобазы + """;"; // Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=1076785#1076785 СтрокаПараметров = СтрокаПараметров + "Q=Q"; Если ЗначениеЗаполнено(ИмяФайлаКонфигурации) Тогда СтрокаПараметров = СтрокаПараметров + " /UseTemplate """ + ИмяФайлаКонфигурации + """"; КонецЕсли; //СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу"; ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс(); ЗапуститьПриложение("""" + ПолноеИмяИсполняемогоФайла + """ " + СтрокаПараметров,, Истина);; КонецЕсли; Возврат ""; КонецФункции Функция ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс() Экспорт ПолноеИмяИсполняемогоФайла = "" + КаталогПрограммы() + "1cv8.exe"; Возврат ПолноеИмяИсполняемогоФайла; КонецФункции Функция ПолучитьСтрокуСКавычкамиДляКоманднойСтрокиЛкс(Строка) Экспорт Результат = """" + СтрЗаменить(Строка, """", """""") + """"; Возврат Результат; КонецФункции // Параметры: // СтрокаСоединенияБазы - Строка - пустая строка трактуется как строка соединения пустой инфобазы Функция ВыполнитьКомандуКонфигуратораЛкс(Знач КомандаКонфигуратора, Знач СтрокаСоединенияБазы = "", выхТекстЛога = "", ПодавлятьДиалоги = Ложь, Состояние = "", УдалитьСуществующуюПустуюИнфобазу = Ложь) Экспорт #Если Клиент Тогда Если ЗначениеЗаполнено(Состояние) Тогда Состояние(Состояние); КонецЕсли; #КонецЕсли Если Не ЗначениеЗаполнено(СтрокаСоединенияБазы) Тогда КаталогПустойИнфобазы = ПолучитьКаталогПустойИнфобазыЛкс(); СоздатьФайловуюБазу1СЛкс(КаталогПустойИнфобазы,, УдалитьСуществующуюПустуюИнфобазу); СтрокаСоединенияБазы = "File=""" + КаталогПустойИнфобазы + """;"; КонецЕсли; СтрокаСоединенияБазы = "/IBConnectionString" + ПолучитьСтрокуСКавычкамиДляКоманднойСтрокиЛкс(СтрокаСоединенияБазы); КодВозврата = Неопределено; ИмяФайлаЛога = ПолучитьИмяВременногоФайла("txt"); ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс(); ПараметрыПакетногоЗапуска = "DESIGNER /Out""" + ИмяФайлаЛога + """ " + СтрокаСоединенияБазы + " " + КомандаКонфигуратора; Если ПодавлятьДиалоги Тогда ПараметрыПакетногоЗапуска = ПараметрыПакетногоЗапуска + " /DisableStartupDialogs /DisableStartupMessages"; КонецЕсли; ЗапуститьПриложение("""" + ПолноеИмяИсполняемогоФайла + """ " + ПараметрыПакетногоЗапуска,, Истина, КодВозврата);; ФайлЛога = Новый Файл(ИмяФайлаЛога); Если ФайлЛога.Существует() Тогда ТекстовыйДокументЛога = Новый ТекстовыйДокумент; ТекстовыйДокументЛога.Прочитать(ФайлЛога.ПолноеИмя); выхТекстЛога = ТекстовыйДокументЛога.ПолучитьТекст(); КонецЕсли; Возврат КодВозврата = 0; КонецФункции // р5яф67оыйи Функция ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчикуЛкс(Знач ИдентификаторПроцессаОС) Экспорт ПараметрыЗапускаДляОтладки = ""; ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'"); КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine; ВычислительРегулярныхВыражений = Новый COMОбъект("VBScript.RegExp"); ВычислительРегулярныхВыражений.IgnoreCase = Истина; ВычислительРегулярныхВыражений.Pattern = "(/DebuggerUrl\s*.+?)( /|$)"; Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса); Если Вхождения.Count > 0 Тогда ПараметрыЗапускаДляОтладки = Вхождения.Item(0).SubMatches(0); КонецЕсли; ВычислительРегулярныхВыражений.Pattern = "(/Debug\s+.+?)( /|$)"; Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса); Если Вхождения.Count > 0 Тогда СтрокаОтладчика = Вхождения.Item(0).SubMatches(0);; Иначе СтрокаОтладчика = "/Debug"; КонецЕсли; ПараметрыЗапускаДляОтладки = ПараметрыЗапускаДляОтладки + " " + СтрокаОтладчика; Возврат ПараметрыЗапускаДляОтладки; КонецФункции // Создает COM объект клиента 1C и подключает его к базе по указанной строке соединения. // Параметры: // СтрокаСоединения - Строка // ИмяПользователя - Строка // ПарольПользователя - Строка // ТипCOMОбъекта - Строка, *"Application" - "Application" или "ComConnector" // Видимость - Булево - для Application // ОбработатьИсключениеПодключения - Булево, *Ложь - при Истина исключение обрабатывается внутри метода и возвращется его описание в качестве результата // ИмяСервераПроцессов - Строка - имя сервера, на котором создавать COM объект // // Возвращаемое значение: // COMОбъект - клиента 1C, Строка - описание исключения // Функция СоздатьСеансИнфобазы1С8Лкс(Знач СтрокаСоединения = "", Знач ИмяПользователя = "", Знач ПарольПользователя = "", Знач ТипCOMОбъекта = "Application", Знач Видимость = Ложь, Знач ОбработатьИсключениеПодключения = Ложь, ОписаниеОшибки = "", ИмяСервераПроцессов = "", КодРазрешения = "") Экспорт ДопСтрокаСоединения = ""; Если ЗначениеЗаполнено(ИмяПользователя) Тогда ДопСтрокаСоединения = ДопСтрокаСоединения + "Usr=""" + ИмяПользователя + """;" + "Pwd=""" + ПарольПользователя + """;"; КонецЕсли; Если ЗначениеЗаполнено(КодРазрешения) Тогда ДопСтрокаСоединения = ДопСтрокаСоединения + "UC=""" + КодРазрешения + """;"; КонецЕсли; #Если Клиент Тогда Состояние("Подключение к базе через COM..."); #КонецЕсли ИмяCOMКласса = "v" + ирКэш.Получить().ИДВерсииПлатформы; Если Найти(ТипCOMОбъекта, ".") = 0 Тогда ИмяCOMКласса = ИмяCOMКласса + "."; КонецЕсли; ИмяCOMКласса = ИмяCOMКласса + ТипCOMОбъекта; Попытка Соединение = Новый COMОбъект(ИмяCOMКласса, ИмяСервераПроцессов); Исключение ВызватьИсключение "Ошибка создания COM объекта " + ИмяCOMКласса + ": " + ОписаниеОшибки(); КонецПопытки; Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда СтрокаСоединения = СтрокаСоединенияИнформационнойБазы(); КонецЕсли; ПолнаяСтрокаСоединения = СтрокаСоединения + ДопСтрокаСоединения; Попытка РезультатСоединения = Соединение.Connect(ПолнаяСтрокаСоединения); Исключение #Если Клиент Тогда Состояние(""); #КонецЕсли Если ОбработатьИсключениеПодключения Тогда ОписаниеОшибки = ОписаниеОшибки(); Возврат ОписаниеОшибки; Иначе ВызватьИсключение; КонецЕсли; КонецПопытки; #Если Клиент Тогда Состояние(""); #КонецЕсли мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если Найти(ТипCOMОбъекта, "Application") > 0 Тогда #Если Клиент Тогда Состояние("Ожидание инициализации сеанса..."); Для Счетчик = 1 По 20 Цикл ОбработкаПрерыванияПользователя(); Попытка Соединение.Visible = Видимость; Прервать; Исключение // Тонкий клиент еще не готов ОписаниеОшибки = ОписаниеОшибки(); КонецПопытки; мПлатформа.Sleep(1); КонецЦикла; Состояние(""); Результат = Соединение; #КонецЕсли ИначеЕсли Найти(ТипCOMОбъекта, "ComConnector") > 0 Тогда Результат = РезультатСоединения; КонецЕсли; Возврат Результат; КонецФункции Функция ЗапуститьСеансПодПользователемЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта = "", РежимЗапуска = "Авто", КодРазрешения = "", СообщитьКоманднуюСтроку = Ложь, ОткрытьПортативныеИнструменты = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Истина, РазрешитьОтладку = Истина, ДополнительныеПараметры = "", РежимИнтерфейсаТакси = Ложь, Элевация = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь) Экспорт Если ЗначениеЗаполнено(ТипCOMОбъекта) Тогда Соединение = СоздатьСеансИнфобазы1С8Лкс(, ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта, Истина,,,, КодРазрешения); Иначе #Если Клиент Тогда //Если ирКэш.Получить().ВерсияПлатформы = 802015 Тогда // Предупреждение("В релиза 8.2.15 функция недоступна", 20); // Антибаг платформы 8.2.15 // Возврат; //КонецЕсли; Если РежимЗапуска = "Авто" Тогда // Антибаг платформы. При передачи этого режима в явном виде в некоторых случаях пароль в командной строке игнорируется ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяИнфобазы); Если ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий"; ИначеЕсли ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Тогда КонечныйРежимЗапуска = "ОбычноеПриложение"; Иначе //Авто Если Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий"; Иначе КонечныйРежимЗапуска = "ОбычноеПриложение"; КонецЕсли; КонецЕсли; Иначе КонечныйРежимЗапуска = РежимЗапуска; КонецЕсли; ПараметрыЗапуска = ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, КодРазрешения, Ложь, КонечныйРежимЗапуска, РазрешитьОтладку, ОчисткаКэшаКлиентСерверныхВызовов, ДополнительныеПараметры, СообщитьКоманднуюСтроку, , ОткрытьПортативныеИнструменты, РежимИнтерфейсаТакси, РазделениеДанных, ОтключитьАутентификациюОС); ТекущаяДата = ирСервер.ПолучитьТекущуюДатуЛкс(); Если КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий" Тогда СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8c.exe"" " + ПараметрыЗапуска; ЗапуститьПриложение(СтрокаЗапуска); Иначе Если Элевация Тогда Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + ПараметрыЗапуска; Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска,,,, Ложь, Истина); Иначе ЗапуститьСистему(ПараметрыЗапуска); КонецЕсли; КонецЕсли; Состояние("Ожидание запуска сеанса..."); Успех = Ложь; ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс(); Пока Не Успех Цикл ОбработкаПрерыванияПользователя(); Если ирСервер.ПолучитьТекущуюДатуЛкс() - ДатаПоследнегоВопроса >= 5 Тогда Ответ = Вопрос("Продолжить ожидание сеанса (5 сек)?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Нет Тогда Прервать; КонецЕсли; ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс(); КонецЕсли; Сеансы = ПолучитьСеансыИнформационнойБазы(); Успех = Ложь; Для Каждого Сеанс Из Сеансы Цикл Если Истина И Сеанс.НачалоСеанса >= ТекущаяДата И НРег(Сеанс.ИмяКомпьютера) = НРег(ИмяКомпьютера()) И Сеанс.Пользователь <> Неопределено И НРег(Сеанс.Пользователь.Имя) = НРег(ИмяПользователяИнфобазы) Тогда Успех = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЦикла; Состояние(""); #Иначе ВызватьИсключение "Запуск приложения допускается только на клиенте"; #КонецЕсли КонецЕсли; Возврат Соединение; КонецФункции // Параметры: // XML - // Тип - // ИспользоватьXDTO - // СообщатьОбОшибках - // Функция ВосстановитьОбъектИзСтрокиXMLЛкс(Знач ФайлИлиXML = "", Знач Тип = "", Знач ИспользоватьXDTO = Истина, Знач СообщатьОбОшибках = Истина) Экспорт Если Ложь Или ТипЗнч(ФайлИлиXML) = Тип("Файл") Или ЗначениеЗаполнено(ФайлИлиXML) Тогда ЧтениеXML = Новый ЧтениеXML; Если ТипЗнч(ФайлИлиXML) = Тип("Файл") Тогда ЧтениеXML.ОткрытьФайл(ФайлИлиXML.ПолноеИмя); Иначе ЧтениеXML.УстановитьСтроку(ФайлИлиXML); КонецЕсли; Попытка Если ИспользоватьXDTO Тогда Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Иначе Результат = ПрочитатьXML(ЧтениеXML); КонецЕсли; Исключение Если СообщатьОбОшибках Тогда Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное); КонецЕсли; ЧтениеXML.Закрыть(); КонецПопытки; // Антибаг платформы 8.2-8.3.6 СериализаторXDTO некорректно восстанавливает пустую табличную часть поверх непустой https://partners.v8.1c.ru/forum/t/1329468/m/1329468 Попытка Пустышка = Результат.Модифицированность(); МетаТЧи = Результат.Метаданные().ТабличныеЧасти; Исключение МетаТЧи = Новый Массив; КонецПопытки; Для Каждого МетаТЧ Из МетаТЧи Цикл ТЧ = Результат[МетаТЧ.Имя]; Если ТЧ.Количество() = 0 Тогда Попытка ТЧ.Вставить(0); Исключение // Недоступна по разделению группа/элемент с неадекватной ошибкой https://partners.v8.1c.ru/forum/t/1374212/m/1374212 Продолжить; КонецПопытки; ТЧ.Удалить(0); КонецЕсли; КонецЦикла; КонецЕсли; Если Результат = Неопределено Тогда Если ЗначениеЗаполнено(Тип) Тогда Результат = Новый (Тип); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ВосстановитьНастройкуКомпоновкиИзСтрокиXMLЛкс(Знач XML = "", Знач СообщатьОбОшибках = Истина) Экспорт Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(XML, Тип("НастройкиКомпоновкиДанных"), , СообщатьОбОшибках); Возврат Результат; КонецФункции // Параметры: // Объект - // ИспользоватьXDTO - // Функция СохранитьОбъектВВидеСтрокиXMLЛкс(Знач Объект, Знач ИспользоватьXDTO = Истина, ИмяФайла = "", СообщатьОбОшибках = Истина) Экспорт Поток = Новый ЗаписьXML; Если ЗначениеЗаполнено(ИмяФайла) Тогда Попытка Поток.ОткрытьФайл(ИмяФайла); Исключение ВызватьИсключение ОписаниеОшибки(); // Чтобы в диалоге "Вычислить выражение" полное описание показывалось КонецПопытки; Иначе Поток.УстановитьСтроку(); КонецЕсли; Попытка Если ИспользоватьXDTO Тогда СериализаторXDTO.ЗаписатьXML(Поток, Объект); Иначе ЗаписатьXML(Поток, Объект); КонецЕсли; Исключение Поток.Закрыть(); Если СообщатьОбОшибках Тогда ВызватьИсключение; КонецЕсли; Поток = Неопределено; КонецПопытки; Если Поток = Неопределено Тогда Результат = Неопределено; Иначе Результат = Поток.Закрыть(); КонецЕсли; Возврат Результат; КонецФункции Функция ЗаписатьОбъектДляОтладкиЛкс(Объект, АдресРезультата = Неопределено) Экспорт Если ТранзакцияАктивна() Тогда лАдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор); СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); Параметры = Новый Массив(); Параметры.Добавить(СтрокаХМЛ); Параметры.Добавить(лАдресРезультата); ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗаписатьОбъектДляОтладкиЛкс", Параметры,, "Запись объекта для отладки (ИР)"); ФоновоеЗадание.ОжидатьЗавершения(3); Результат = ПолучитьИзВременногоХранилища(лАдресРезультата); Иначе Если ТипЗнч(Объект) = Тип("Строка") Тогда Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(Объект); КонецЕсли; Если ТипЗнч(Объект) = Тип("Структура") Тогда Результат = "Объект для отладки"; ирОбщий.СохранитьЗначениеЛкс(Результат, Объект); Иначе Объект.Записать(); Результат = Объект.Ссылка; КонецЕсли; Если АдресРезультата <> Неопределено Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаЗначений, БазовоеИмяИлиСтрока, ИмяКлючевойКолонки = "Имя", ИмяДолжноБытьИдентификатором = Истина, ЗаменаПустойСтроки = "_", Знач ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке = 50) Экспорт ТекущийИндекс = 0; Если Ложь Или ТипЗнч(БазовоеИмяИлиСтрока) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(БазовоеИмяИлиСтрока) = Тип("СтрокаДереваЗначений") Тогда ИсключаемаяСтрока = БазовоеИмяИлиСтрока; БазовоеИмя = БазовоеИмяИлиСтрока[ИмяКлючевойКолонки]; //ТекущийИндекс = 1; Иначе БазовоеИмя = БазовоеИмяИлиСтрока; КонецЕсли; Если ИмяДолжноБытьИдентификатором Тогда ДопустимаяДлинаИдентификатора = ТаблицаЗначений.Колонки[ИмяКлючевойКолонки].ТипЗначения.КвалификаторыСтроки.Длина; Если Не ЗначениеЗаполнено(ДопустимаяДлинаИдентификатора) Тогда ДопустимаяДлинаИдентификатора = ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли БазовоеИмя = мПлатформа.ПолучитьИдентификаторИзПредставления(БазовоеИмя, ЗаменаПустойСтроки); БазовоеИмя = Лев(БазовоеИмя, ДопустимаяДлинаИдентификатора); Иначе Если ПустаяСтрока(БазовоеИмя) Тогда БазовоеИмя = ЗаменаПустойСтроки; КонецЕсли; КонецЕсли; Пока Истина Цикл ТекущийПсевдоним = БазовоеИмя + Формат(ТекущийИндекс, "ЧГ="); СтрокиОдноименных = ТаблицаЗначений.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ТекущийПсевдоним)); Если Ложь Или СтрокиОдноименных.Количество() = 0 Или (Истина И СтрокиОдноименных.Количество() = 1 И ИсключаемаяСтрока <> Неопределено И СтрокиРавныЛкс(ТекущийПсевдоним, ИсключаемаяСтрока[ИмяКлючевойКолонки]) ) Тогда Прервать; КонецЕсли; ТекущийИндекс = ТекущийИндекс + 1; КонецЦикла; Возврат ТекущийПсевдоним; КонецФункции // Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке // // Параметры: // ЭлементОтбора - <тип> - // Сравнение - <тип>, "" - // Значение - <тип> - // ЗначениеПо - <тип> - // Использование - <тип>, Истина - // ПриводитьТипДляНеопределено - <тип>, Истина - // // Возвращаемое значение: // Функция УстановитьЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Сравнение = "", Знач Значение, Знач ЗначениеПо = Неопределено, Знач Использование = Истина, Знач ПриводитьТипДляНеопределено = Истина) Экспорт Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда Значение = Новый Массив(Значение); КонецЕсли; Если ТипЗнч(Значение) = Тип("Массив") Тогда СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(Значение); Значение = СписокЗначений; ИначеЕсли Истина И ПриводитьТипДляНеопределено И Значение = Неопределено Тогда Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(Значение); КонецЕсли; // Вид сравнения Если СтрокиРавныЛкс(Сравнение, "Авто") Тогда Сравнение = ОпределитьВидСравненияПоЗначениюЛкс(Значение); ИначеЕсли ТипЗнч(Сравнение) = Тип("ВидСравнения") Тогда ИначеЕсли Истина И Сравнение <> Неопределено И Сравнение <> "" Тогда // Добавлено 25.03.2012 ВызватьИсключение "Неверный тип сравнения """ + ТипЗнч(Сравнение) + """"; Иначе Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда Сравнение = ВидСравнения.ВСписке; Иначе Сравнение = ВидСравнения.Равно; КонецЕсли; КонецЕсли; // Еще надо сделать автоопределение Сожержит, как у компоновки ЭлементОтбора.ВидСравнения = Сравнение; Попытка Если ЗначениеПо <> Неопределено Тогда ЭлементОтбора.ЗначениеС = Значение; ЭлементОтбора.ЗначениеПО = ЗначениеПо; Иначе ЭлементОтбора.Значение = Значение; КонецЕсли; Исключение ВызватьИсключение "Ошибка установки значения типа """ + ТипЗнч(Значение) + """ элементу отбора """ + ЭлементОтбора.Имя + """: " + ОписаниеОшибки(); КонецПопытки; Попытка ЭлементОтбора.Использование = Использование; Исключение // Сюда попадаем для элемента отбора набора записей с регистратором КонецПопытки; КонецФункции // Установить отбор по структуре // // Параметры: // Отбор - <тип> - // СтруктураОтбора - <тип> - // Сравнение - <тип>, "Авто" - // ДобавлятьСсылкуВПутьКДанным - <тип>, Ложь - // СброситьПередУстановкой - <тип>, Истина - // // Возвращаемое значение: // Функция УстановитьОтборПоСтруктуреЛкс(Знач Отбор, Знач СтруктураОтбора, Знач Сравнение = "Авто", Знач ДобавлятьСсылкуВПутьКДанным = Ложь, Знач СброситьПередУстановкой = Истина) Экспорт Если СброситьПередУстановкой Тогда Отбор.Сбросить(); КонецЕсли; Для Каждого КлючИЗначение Из СтруктураОтбора Цикл ПутьКДанным = КлючИЗначение.Ключ; Если ДобавлятьСсылкуВПутьКДанным Тогда ПутьКДанным = "Ссылка." + ПутьКДанным; КонецЕсли; НайтиДобавитьЭлементОтбораЛкс(Отбор, ПутьКДанным, Сравнение, КлючИЗначение.Значение, , , КлючИЗначение.Ключ); КонецЦикла; КонецФункции Процедура ЗаполнитьНаборЗаписейПоОтборуЛкс(НаборЗаписей) Экспорт #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей(); #КонецЕсли СтруктураЗначенийОтбора = Новый Структура; Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл Если ЭлементОтбора.Использование Тогда СтруктураЗначенийОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение); КонецЕсли; КонецЦикла; Для Каждого СтрокаНабора Из НаборЗаписей Цикл ЗаполнитьЗначенияСвойств(СтрокаНабора, СтруктураЗначенийОтбора); КонецЦикла; КонецПроцедуры // Параметры: // Объект - - Ссылочный объект или запись регистра // Отбор - Отбор // Функция УстановитьЗначенияРеквизитовПоОтборуЛкс(Объект, Отбор) Экспорт Для Каждого ЭлементОтбора Из Отбор Цикл Если Ложь Или Не ЭлементОтбора.Использование Или ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно Тогда Продолжить; КонецЕсли; ИмяРеквизита = ЭлементОтбора.Имя; ЗначениеОтбора = ЭлементОтбора.Значение; Попытка Объект[ИмяРеквизита] = ЗначениеОтбора; Исключение // Сюда попадаем например для ЭтоГруппа КонецПопытки; КонецЦикла; КонецФункции // Определить вид сравнения по значению // // Параметры: // Значение - <тип> - // РежимКомпоновки - <тип>, Ложь - // ДоступныеВидыСравнения - <тип>, Неопределено - // // Возвращаемое значение: // Функция ОпределитьВидСравненияПоЗначениюЛкс(Знач Значение, Знач РежимКомпоновки = Ложь, Знач ДоступныеВидыСравнения = Неопределено) Экспорт ТипЗначения = ТипЗнч(Значение); Если РежимКомпоновки Тогда КоллекцияВидовСравнения = ВидСравненияКомпоновкиДанных; Иначе КоллекцияВидовСравнения = ВидСравнения; КонецЕсли; Если ТипЗначения = Тип("СписокЗначений") Тогда Результат = КоллекцияВидовСравнения.ВСписке; ИначеЕсли Истина И ТипЗначения = Тип("Строка") И ДоступныеВидыСравнения <> Неопределено И ДоступныеВидыСравнения.НайтиПоЗначению(КоллекцияВидовСравнения.Содержит) <> Неопределено Тогда Результат = КоллекцияВидовСравнения.Содержит; Иначе Результат = КоллекцияВидовСравнения.Равно; ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения); Если ОбъектМД <> Неопределено Тогда ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя()); Если ТипТаблицы = "Справочник" Тогда Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда Если Значение.ЭтоГруппа Тогда Результат = КоллекцияВидовСравнения.ВИерархии; КонецЕсли; Иначе // иерархия элементов Результат = КоллекцияВидовСравнения.ВИерархии; КонецЕсли; ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда Если Значение.ЭтоГруппа Тогда Результат = КоллекцияВидовСравнения.ВИерархии; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке // // Параметры: // ОтборИлиОбъект - <тип> - // ПутьКДанным - <тип>, "" - // Сравнение - <тип>, "" - // Значение - <тип>, Неопределено - // ЗначениеПо - <тип>, Неопределено - // Использование - <тип>, Истина - // Имя - <тип>, "" - // Представление - <тип>, "" - // // Возвращаемое значение: // Функция НайтиДобавитьЭлементОтбораЛкс(Знач ОтборИлиОбъект, Знач ПутьКДанным = "", Знач Сравнение = "", Знач Значение = Неопределено, Знач ЗначениеПо = Неопределено, Знач Использование = Истина, Знач Имя = "", Знач Представление = "") Экспорт Если ТипЗнч(ОтборИлиОбъект) = Тип("Отбор") Тогда Отбор = ОтборИлиОбъект; Иначе Отбор = ОтборИлиОбъект.Отбор; КонецЕсли; // Ищем или добавляем новый элемент отбора ЭлементОтбора = Неопределено; //Если Имя <> Неопределено Тогда // ЭлементОтбора= Отбор.Найти(Имя); //КонецЕсли; Если Имя <> Неопределено Тогда Для Каждого ЭлОтбора Из Отбор Цикл Если Ложь Или ЭлОтбора.Имя = Имя Или ЭлОтбора.Представление = Имя Тогда ЭлементОтбора = ЭлОтбора; КонецЕсли; КонецЦикла; КонецЕсли; Если ЭлементОтбора = Неопределено Тогда Попытка ЭлементОтбора = Отбор.Добавить(ПутьКДанным, Имя, Представление); Исключение ВызватьИсключение "Ошибка добавления элемента отбора """ + ПутьКДанным + """ построителя запроса: " + ОписаниеОшибки(); КонецПопытки; КонецЕсли; УстановитьЭлементОтбораЛкс(ЭлементОтбора, Сравнение, Значение, ЗначениеПо, Использование); Результат = ЭлементОтбора; Возврат Результат; КонецФункции Процедура ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, Префикс = "Т") Экспорт #Если Сервер И Не Сервер Тогда Запрос = Новый Запрос; #КонецЕсли ТекстЗапроса = Запрос.Текст; Параметры = Новый Структура; СкопироватьУниверсальнуюКоллекциюЛкс(Запрос.Параметры, Параметры); Для Каждого КлючИЗначение Из Параметры Цикл Если Найти(КлючИЗначение.Ключ, Префикс) = 1 Тогда ВызватьИсключение "Начало имени параметра " + КлючИЗначение.Ключ + " совпадает с префиксом " + Префикс; КонецЕсли; НовоеИмя = Префикс + КлючИЗначение.Ключ; ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&" + КлючИЗначение.Ключ, "&" + НовоеИмя); Запрос.УстановитьПараметр(НовоеИмя, КлючИЗначение.Значение); КонецЦикла; Запрос.Текст = ТекстЗапроса; КонецПроцедуры // ТаблицаПараметров - ТаблицаЗначений, ТабличнаяЧасть Функция НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ЗначениеПараметра, ИмяПараметра = Неопределено, ОбновитьКопиюСвойстваВНижнемРегистре = Ложь) Экспорт Если ТипЗнч(ТаблицаПараметров) = Тип("ТаблицаЗначений") Тогда МакетТаблицы = ТаблицаПараметров; Иначе МакетТаблицы = ТаблицаПараметров.ВыгрузитьКолонки(); КонецЕсли; Строки = ТаблицаПараметров.НайтиСтроки(Новый Структура(ИмяКолонкиЗначения, ЗначениеПараметра)); Если Строки.Количество() > 0 Тогда Результат = Строки[0]; Иначе Если ТипЗнч(ЗначениеПараметра) = Тип("Строка") Тогда ИмяПараметра = ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаПараметров, "П", ИмяКолонкиИмени); Иначе ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеПараметра))); //Префикс = НРег(Лев(ОбъектМД.Имя, 1)); Префикс = ""; Если ИмяПараметра = Неопределено Тогда ИмяПараметра = "" + РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра); КонецЕсли; Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда ИмяПараметра = СтрЗаменить(ИмяТипа, ".", "") + "Пустая"; КонецЕсли; ИмяПараметра = Префикс + ирКэш.Получить().ПолучитьИдентификаторИзПредставления(ИмяПараметра); ДопустимаяДлинаСтроки = МакетТаблицы.Колонки[ИмяКолонкиИмени].ТипЗначения.КвалификаторыСтроки.Длина; Если ДопустимаяДлинаСтроки > 0 Тогда ИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки); КонецЕсли; КонецЕсли; СтруктураСвойствПараметра = Новый Структура; СтруктураСвойствПараметра.Вставить(ИмяКолонкиИмени, ИмяПараметра); Счетчик = 0; Пока ТаблицаПараметров.НайтиСтроки(СтруктураСвойствПараметра).Количество() > 0 Цикл Счетчик = Счетчик + 1; СтрокаНомера = "" + Счетчик; Если ДопустимаяДлинаСтроки > 0 Тогда лИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки - СтрДлина(СтрокаНомера)); Иначе лИмяПараметра = ИмяПараметра; КонецЕсли; СтруктураСвойствПараметра[ИмяКолонкиИмени] = лИмяПараметра + СтрокаНомера; КонецЦикла; СтруктураСвойствПараметра.Вставить("ЭтоВыражение", Ложь); СтруктураСвойствПараметра.Вставить(ИмяКолонкиЗначения, ЗначениеПараметра); СтрокаНовогоПараметра = ТаблицаПараметров.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаНовогоПараметра, СтруктураСвойствПараметра); Если ОбновитьКопиюСвойстваВНижнемРегистре Тогда ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаНовогоПараметра, ИмяКолонкиИмени); КонецЕсли; Результат = СтрокаНовогоПараметра; КонецЕсли; Возврат Результат; КонецФункции // ДобавитьПараметрЗначение() Функция ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицыИлиНаборЗаписей, КлючНабора, ДобавитьИЗаполнитьСтрокуНабора = Ложь) Экспорт Если ТипЗнч(ПолноеИмяТаблицыИлиНаборЗаписей) = Тип("Строка") Тогда НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыИлиНаборЗаписей); Иначе НаборЗаписей = ПолноеИмяТаблицыИлиНаборЗаписей; КонецЕсли; #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей(); #КонецЕсли //СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолучитьИмяТаблицыИзМетаданныхЛкс(НаборЗаписей.Метаданные()), Ложь); //Для Каждого ПолеКлюча Из СтруктураКлюча Цикл // ИмяПоля = ПолеКлюча.Ключ; // Попытка // ЗначениеКлюча = КлючНабора[ИмяПоля]; // Исключение // // Имеет смысл для регистров сведений // Продолжить; // КонецПопытки; // ЭлементОтбора = НаборЗаписей.Отбор[ИмяПоля]; // ЭлементОтбора.Значение = ЗначениеКлюча; // ЭлементОтбора.Использование = Истина; //КонецЦикла; Если ЛиКлючЗаписиРегистраЛкс(КлючНабора) Тогда КлючНабора = ПолучитьКлючНабораЗаписейИзКлючаЗаписиЛкс(КлючНабора, ПолноеИмяТаблицыИлиНаборЗаписей); КонецЕсли; Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл ИмяПоля = ЭлементОтбора.Имя; Попытка ЗначениеКлюча = КлючНабора[ИмяПоля]; Исключение // Имеет смысл для регистров сведений Продолжить; КонецПопытки; ЭлементОтбора.Значение = ЗначениеКлюча; ЭлементОтбора.Использование = Истина; КонецЦикла; Если ДобавитьИЗаполнитьСтрокуНабора Тогда ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючНабора); КонецЕсли; Возврат НаборЗаписей; КонецФункции // Получает копию таблицы значений с минимальными типами колонок для содержания всех данных. // Параметры: // ТаблицаДанных - ТаблицаЗначений // СужатьТолькоПроизвольныеКолонки - Булево - обрабатывать только колонки с пустым (произвольным) типом // ИмяКолонки - Строка - нужна только эта колонка // Функция ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Знач ТаблицаДанных, СужатьТолькоПроизвольныеКолонки = Ложь, ИмяКолонки = "") Экспорт #Если Сервер И Не Сервер Тогда ТаблицаДанных = Новый ТаблицаЗначений; #КонецЕсли ОставляемыеКолонки = ""; СужаемыеКолонки = Новый Массив(); Для Каждого КолонкаДанных Из ТаблицаДанных.Колонки Цикл Если ЗначениеЗаполнено(ИмяКолонки) И Не СтрокиРавныЛкс(ИмяКолонки, КолонкаДанных.Имя) Тогда Продолжить; КонецЕсли; Если Истина И СужатьТолькоПроизвольныеКолонки И КолонкаДанных.ТипЗначения.Типы().Количество() > 0 Тогда ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя; Иначе СужаемыеКолонки.Добавить(КолонкаДанных); КонецЕсли; КонецЦикла; //Состояние("Оптимизация типов колонок"); НовыеКолонки = Новый Структура; МетаданныеТаблицыИзменены = Ложь; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СужаемыеКолонки.Количество(), "Анализ колонок"); Для Каждого КолонкаДанных Из СужаемыеКолонки Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); Типы = Новый Массив; ТаблицаКолонки = ТаблицаДанных.Скопировать(, КолонкаДанных.Имя); ТаблицаКолонки.Свернуть(КолонкаДанных.Имя); СтароеОписаниеТипов = КолонкаДанных.ТипЗначения; Для Каждого СтрокаДанных Из ТаблицаКолонки Цикл ТипЗначения = ТипЗнч(СтрокаДанных[КолонкаДанных.Имя]); Если Истина И ТипЗначения <> Тип("Неопределено") И Типы.Найти(ТипЗначения) = Неопределено Тогда Типы.Добавить(ТипЗначения); КонецЕсли; КонецЦикла; Если Типы.Количество() = 0 Тогда Типы = КолонкаДанных.ТипЗначения.Типы(); Если Типы.Количество() = 0 Тогда Типы.ДОбавить(Тип("Булево")); Типы.ДОбавить(Тип("Число")); КонецЕсли; // Чтобы от супертипов через точку не было много соединений, оставляем только 2 типа Пока Типы.Количество() > 2 Цикл Типы.Удалить(0); КонецЦикла; КонецЕсли; Если Типы.Количество() <> СтароеОписаниеТипов.Типы().Количество() Тогда МетаданныеТаблицыИзменены = Истина; КонецЕсли; НовоеОписаниеТипов = Новый ОписаниеТипов(Типы, , , СтароеОписаниеТипов.КвалификаторыЧисла, СтароеОписаниеТипов.КвалификаторыСтроки, СтароеОписаниеТипов.КвалификаторыДаты); НовыеКолонки.Вставить(КолонкаДанных.Имя, НовоеОписаниеТипов); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если МетаданныеТаблицыИзменены Тогда Если ОставляемыеКолонки <> "" Тогда ТипизированнаяТаблица = ТаблицаДанных.Скопировать(, ОставляемыеКолонки); Иначе ТипизированнаяТаблица = Новый ТаблицаЗначений; КонецЕсли; Для Каждого КлючИЗначение Из НовыеКолонки Цикл ТипизированнаяТаблица.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение, ТаблицаДанных.Колонки[КлючИЗначение.Ключ].Заголовок); КонецЦикла; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаДанных.Количество() / 100, "Оптимизация таблицы"); Для Индекс = 0 По ТаблицаДанных.Количество() - 1 Цикл Если Индекс % 100 = 0 Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонецЕсли; Если ОставляемыеКолонки <> "" Тогда СтрокаТипизированнойТаблицы = ТипизированнаяТаблица[Индекс]; Иначе СтрокаТипизированнойТаблицы = ТипизированнаяТаблица.Добавить(); КонецЕсли; ЗаполнитьЗначенияСвойств(СтрокаТипизированнойТаблицы, ТаблицаДанных[Индекс]); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Иначе ТипизированнаяТаблица = ТаблицаДанных; КонецЕсли; Результат = ТипизированнаяТаблица; Возврат Результат; КонецФункции // ************************ // WMI Функция ПолучитьСтруктуруИзЗначенияWMIЛкс(ЗначениеWMI) Экспорт Результат = Новый Структура; Для каждого СвойствоWMI из ЗначениеWMI Цикл Если ТипЗнч(СвойствоWMI.Value) = Тип("COMSafeArray") Тогда ЗначениеСвойства = СвойствоWMI.Value.Выгрузить();// возможно массив надо будет переделать Иначе ЗначениеСвойства = СвойствоWMI.Value; //ИмяТипа = ПолучитьИмяТипаИзКвалификаторовWMIЛкс(СвойствоWMI); //Если СтрокиРавныЛкс(ИмяТипа, "Дата") Тогда Если СвойствоWMI.CIMTYPE = 101 Тогда //datetime ЗначениеСвойства = СтрокаДатыWMIВДатуЛкс(ЗначениеСвойства); КонецЕсли; КонецЕсли; Результат.Вставить(СвойствоWMI.Name, ЗначениеСвойства); КонецЦикла; Возврат Результат; КонецФункции Функция ПолучитьИмяТипаИзКвалификаторовWMIЛкс(Свойство) Экспорт ИмяТипа = ""; Попытка Квалификаторы = Свойство.Qualifiers_; Исключение // Нет у системных свойств Квалификаторы = Новый Массив(); КонецПопытки; Для Каждого Квалификатор Из Квалификаторы Цикл Если СтрокиРавныЛкс("CIMTYPE", Квалификатор.Name) Тогда ИмяТипа = Нрег(Квалификатор.Value); Прервать; КонецЕсли; КонецЦикла; Если Ложь Или Найти(ИмяТипа, "int") > 0 Тогда ИмяТипа = "Число"; ИначеЕсли Ложь Или Найти(ИмяТипа, "date") > 0 Или Найти(ИмяТипа, "time") > 0 Тогда ИмяТипа = "Дата"; ИначеЕсли Ложь Или Найти(ИмяТипа, "string") > 0 Или Найти(ИмяТипа, "char") > 0 Тогда ИмяТипа = "Строка"; ИначеЕсли ТипЗнч(ИмяТипа) = Тип("COMОбъект") Тогда ИмяТипа = "COMОбъект.{WbemScripting.SwbemLocator}." + ИмяТипа; КонецЕсли; Возврат ИмяТипа; КонецФункции Функция ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции, ИмяСвойства = "Description") Экспорт ОписаниеЭлемента = ""; Квалификаторы = ЭлементКоллекции.qualifiers_; Попытка КвалификаторОписание = Квалификаторы.item(ИмяСвойства); Исключение КвалификаторОписание = Неопределено; КонецПопытки; Если КвалификаторОписание <> Неопределено Тогда ОписаниеЭлемента = КвалификаторОписание.Value; КонецЕсли; Возврат ОписаниеЭлемента; КонецФункции Функция ПолучитьДокументациюСвойстваWMIЛкс(ИмяКласса, ИмяСвойства, СлужбаWMI = Неопределено) Экспорт Если СлужбаWMI = Неопределено Тогда СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(); КонецЕсли; wbemFlagUseAmendedQualifiers = 131072; //&H20000 ОписанияСвойств = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Properties_; Попытка ОписаниеСвойства = ОписанияСвойств.item(ИмяСвойства); Исключение Возврат ""; КонецПопытки; ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства); ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "CIMTYPE"); Если ТипЗначений <> Неопределено Тогда ТекстОписания = ТекстОписания + " |Type: " + ТипЗначений; КонецЕсли; ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "Units"); Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда ТекстОписания = ТекстОписания + " |Unit: " + ЕдиницаИзмерения; КонецЕсли; Возврат ТекстОписания; КонецФункции Функция ПолучитьДокументациюМетодаWMIЛкс(ИмяКласса, ИмяМетода, СлужбаWMI = Неопределено) Экспорт Если СлужбаWMI = Неопределено Тогда СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(); КонецЕсли; wbemFlagUseAmendedQualifiers = 131072; //&H20000 ОписанияМетодов = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Methods_; Попытка ОписаниеМетода = ОписанияМетодов.item(ИмяМетода); Исключение Возврат ""; КонецПопытки; ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода); ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "CIMTYPE"); Если ТипЗначений <> Неопределено Тогда ТекстОписания = ТекстОписания + " |Type: " + ТипЗначений; КонецЕсли; ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "Units"); Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда ТекстОписания = ТекстОписания + " |Unit: " + ЕдиницаИзмерения; КонецЕсли; Возврат ТекстОписания; КонецФункции // Параметры: // СтрокаДаты - Строка(0,П) // Функция СтрокаДатыWMIВДатуЛкс(Знач СтрокаДаты = "") Экспорт Если Не ЗначениеЗаполнено(СтрокаДаты) Тогда Возврат Дата(1,1,1); Иначе Строка = Лев(СтрокаДаты, 4) + Сред(СтрокаДаты, 5, 2) + Сред(СтрокаДаты, 7, 2) + Сред (СтрокаДаты, 9, 2) + Сред(СтрокаДаты, 11, 2) + Сред(СтрокаДаты, 13, 2); Попытка Результат = Дата(Строка); Исключение Сообщить("Ошибка преобразования даты WMI из строки """ + СтрокаДаты + """: " + ОписаниеОшибки()); Возврат Дата(1,1,1); КонецПопытки; Результат = Результат + Вычислить("0." + Сред(СтрокаДаты, 16, 6)); КонецЕсли; Возврат Результат; КонецФункции // WMI // ************************* // ************************ // ADO Функция ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С = Неопределено) Экспорт Если РезультатТаблица = Неопределено Тогда РезультатТаблица = Новый ТаблицаЗначений; КонецЕсли; мПлатформа = ирКэш.Получить(); FieldКолонка = Новый Соответствие; Для каждого Field Из РезультатRecordset.Fields Цикл Если ПустаяСтрока(Field.Name) Тогда ИмяКолонки = ":?"; Для о=1 По СтрДлина(Field.Name)-1 Цикл ИмяКолонки = ИмяКолонки + "?"; КонецЦикла; Иначе ИмяКолонки = Field.Name; КонецЕсли; Если Не ЛиИмяПеременнойЛкс(ИмяКолонки) Тогда ИмяКолонки = мПлатформа.ПолучитьИдентификаторИзПредставления(ИмяКолонки); КонецЕсли; // контроль полей - двойников по именам НомерДвойника=0; Пока РезультатТаблица.Колонки.Найти(ИмяКолонки + Формат(НомерДвойника,"ЧГ=0")) <> Неопределено Цикл НомерДвойника = НомерДвойника + 1; КонецЦикла; ИмяКолонки = ИмяКолонки + Формат(НомерДвойника, "ЧГ=0"); Если Типизировать1С = Истина Тогда Тип1С = FieldADO_ПолучитьТип1CЛкс(Field); Иначе Тип1С = Неопределено; КонецЕсли; //Если Тип1С=Неопределено Тогда // Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,,"["+Name+"]"); //Иначе Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,Тип1С); //КонецЕсли; FieldКолонка.Вставить(Field, Колонка); КонецЦикла; Возврат FieldКолонка; КонецФункции // Выгружает результат запроса ADO (объект 'ADODB.Recordset') в таблицу значений с выводом прогресса состояния выгрузки Функция ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С = Ложь, БинарныеВСтроку = Ложь, RecordsAffected = 0, ИгнорироватьНеподдерживаемыеТипы = Ложь, ЗагружатьЭлементов = Неопределено, СмещениеГода = 0) Экспорт РезультатТаблица = Новый ТаблицаЗначений; Если РезультатRecordset = Неопределено Тогда Возврат РезультатТаблица; КонецЕсли; Если ЗначениеЗаполнено(ЗагружатьЭлементов) Тогда КоличествоЭлементов = Мин(ЗагружатьЭлементов, РезультатRecordset.RecordCount); Иначе КоличествоЭлементов = РезультатRecordset.RecordCount; КонецЕсли; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Загрузка результата"); Если РезультатRecordset.State = 0 Тогда // Выполнена команда РезультатТаблица.Колонки.Добавить("ExecutionInfo",, "Информация о выполнении:"); Стр = РезультатТаблица.Добавить(); Стр.ExecutionInfo = "Число записей, обработанных запросом: " + RecordsAffected; Иначе FieldКолонка = ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С); // Открыта выборка ТипCOMSafeArray = Тип("COMSafeArray"); adBinaryType = ирОбщий.intTypeADOЛкс("adBinary"); adVarBinaryType = ирОбщий.intTypeADOЛкс("adVarBinary"); adLongVarBinaryType = ирОбщий.intTypeADOЛкс("adLongVarBinary"); ПервыйРаз = Истина; Счетчик = 0; Если РезультатRecordset.EOF() = 0 И РезультатRecordset.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 *** // подбирает описание типа 1С, соответствующее типу ADO Функция ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision0,NumericScale0, Справочно = Ложь) Экспорт Тип1С = Неопределено; Если Precision0 > 0 И NumericScale0 >= 0 Тогда Если Precision0 < NumericScale0 Тогда // кривой вариант настроек типа ADO (может иногда возвращаться провайдерами данных) Precision = Precision0 + NumericScale0; Иначе Precision = Precision0; КонецЕсли; UseМаксЧисло = (Precision > 32); Иначе // совсем кривой вариант UseМаксЧисло = Истина; КонецЕсли; NumericScale = ?(NumericScale0 < 0, 0, NumericScale0); NumericScaleM = ?(NumericScale > 10, 10, NumericScale); Если Type = intTypeADOЛкс("adEmpty") Тогда ИначеЕсли Type = intTypeADOЛкс("adSmallInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adInteger") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adSingle") Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adDouble") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision+NumericScale, NumericScale, ДопустимыйЗнак.Любой)); Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adCurrency")Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adDate") Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата)); ИначеЕсли Type = intTypeADOЛкс("adBSTR") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adIDispatch")Тогда ИначеЕсли Type = intTypeADOЛкс("adError") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adBoolean") Тогда Тип1С = Новый ОписаниеТипов("Булево"); ИначеЕсли Type = intTypeADOЛкс("adVariant") Тогда ИначеЕсли Type = intTypeADOЛкс("adIUnknown")Тогда ИначеЕсли Type = intTypeADOЛкс("adDecimal") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adTinyInt") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedTinyInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedSmallInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adBigInt") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedBigInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adFileTime")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adGUID") Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("УникальныйИдентификатор"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adBinary") Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("Двоичныеданные"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adChar") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adWChar") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adNumeric") Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adUserDefined")Тогда ИначеЕсли Type = intTypeADOЛкс("adDBDate") Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата)); ИначеЕсли Type = intTypeADOЛкс("adDBTime") Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Время)); ИначеЕсли Type = intTypeADOЛкс("adDBTimeStamp")Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)); ИначеЕсли Type = intTypeADOЛкс("adChapter") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adPropVariant")Тогда ИначеЕсли Type = intTypeADOЛкс("adVarNumeric")Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adVarChar") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adLongVarChar")Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adVarWChar")Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adLongVarWChar")Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adVarBinary")Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("Двоичныеданные"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adLongVarBinary")Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("Двоичныеданные"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("AdArray") Тогда Иначе // Тип1С = Неопределено; КонецЕсли; Возврат Тип1С; КонецФункции // ПреобразоватьТипADO_Тип1СЛкс() // возвращает описание типа 1С, соответствующее типу объекта ADODB.Field // значение Неопределено соответствует значению произвольного типа 1С Функция FieldADO_ПолучитьТип1CЛкс(FieldADOЛкс, Справочно = Ложь) Экспорт Попытка Type = FieldADOЛкс.Type; DefinedSize = FieldADOЛкс.DefinedSize; Precision = FieldADOЛкс.Precision; NumericScale = FieldADOЛкс.NumericScale; Исключение Возврат Неопределено; КонецПопытки; Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,DefinedSize,Precision,NumericScale, Справочно); КонецФункции // возвращает описание типа 1С, соответствующее типу объекта ADODB.Parameter // значение Неопределено соответствует значению произвольного типа 1С Функция ParameterADO_ПолучитьТип1CЛкс(ParameterADOЛкс) Экспорт Попытка Type = ParameterADOЛкс.Type; Size = ParameterADOЛкс.Size; Precision = ParameterADOЛкс.Precision; NumericScale = ParameterADOЛкс.NumericScale; Исключение Возврат Неопределено; КонецПопытки; Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision,NumericScale); КонецФункции // возвращает структуру с полями объекта ADODB.Field Функция FieldADOЛкс(стрName,стрType,чисDefinedSize,чисPrecision,чисNumericScale,Value=Неопределено) Экспорт ПолеADO = Новый Структура("Name,Type,DefinedSize,Precision,NumericScale,Value"); ТипЧисло = Тип("Число"); Если стрName <> Неопределено Тогда ПолеADO.Вставить("Name",СокрЛП(стрName)); КонецЕсли; Если стрType <> Неопределено Тогда Если ТипЗнч(стрType) = ТипЧисло Тогда // дополнительный контроль числа на допустимое значение ПолеADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType))); Иначе ПолеADO.Вставить("Type",intTypeADOЛкс(стрType)); КонецЕсли; КонецЕсли; Если чисDefinedSize <> Неопределено Тогда Если ТипЗнч(чисDefinedSize)=ТипЧисло Тогда ПолеADO.Вставить("DefinedSize",Цел(чисDefinedSize)); Иначе ПолеADO.Вставить("DefinedSize",0); КонецЕсли; КонецЕсли; Если чисPrecision <> Неопределено Тогда Если ТипЗнч(чисPrecision)=ТипЧисло Тогда ПолеADO.Вставить("Precision",Цел(чисPrecision)); Иначе ПолеADO.Вставить("Precision",0); КонецЕсли; КонецЕсли; Если чисNumericScale <> Неопределено Тогда Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда ПолеADO.Вставить("NumericScale",Цел(чисNumericScale)); Иначе ПолеADO.Вставить("NumericScale",0); КонецЕсли; КонецЕсли; Если Value <> Неопределено Тогда ПолеADO.Вставить("Value",Value); КонецЕсли; Возврат ПолеADO; КонецФункции // возвращает структуру с полями объекта ADODB.Parameter Функция ParameterADOЛкс(стрName,стрDirection,стрType,чисSize,чисNumericScale,чисPrecision,чисAttributes=0,Value=Неопределено) Экспорт ПараметрADO = Новый Структура("Name,Direction,Type,Size,NumericScale,Precision,Attributes,Value"); ТипЧисло = Тип("Число"); Если стрName <> Неопределено Тогда ПараметрADO.Вставить("Name",СокрЛП(стрName)); КонецЕсли; Если чисAttributes <> Неопределено Тогда Если ТипЗнч(чисAttributes)=ТипЧисло И чисAttributes > 0 Тогда ПараметрADO.Вставить("Attributes",Цел(чисAttributes)); КонецЕсли; КонецЕсли; Если стрDirection <> Неопределено Тогда Если ТипЗнч(стрDirection) = ТипЧисло Тогда // дополнительный контроль числа на допустимое значение ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(strDirectionParADOЛкс(стрDirection))); Иначе ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(стрDirection)); КонецЕсли; КонецЕсли; Если стрType <> Неопределено Тогда Если ТипЗнч(стрType) = ТипЧисло Тогда // дополнительный контроль числа на допустимое значение ПараметрADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType))); Иначе ПараметрADO.Вставить("Type",intTypeADOЛкс(стрType)); КонецЕсли; КонецЕсли; Если чисSize <> Неопределено Тогда Если ТипЗнч(чисSize)=ТипЧисло Тогда ПараметрADO.Вставить("Size",Цел(чисSize)); Иначе ПараметрADO.Вставить("Size",0); КонецЕсли; КонецЕсли; Если чисNumericScale <> Неопределено Тогда Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда ПараметрADO.Вставить("NumericScale",Цел(чисNumericScale)); Иначе ПараметрADO.Вставить("NumericScale",0); КонецЕсли; КонецЕсли; Если чисPrecision <> Неопределено Тогда Если ТипЗнч(чисPrecision)=ТипЧисло Тогда ПараметрADO.Вставить("Precision",Цел(чисPrecision)); Иначе ПараметрADO.Вставить("Precision",0); КонецЕсли; КонецЕсли; Если Value <> Неопределено Тогда ПараметрADO.Вставить("Value",Value); КонецЕсли; Возврат ПараметрADO; КонецФункции Функция DigitDECtoHEXЛкс(ЦыфраD) Если ЦыфраD=0 Тогда Возврат "0"; ИначеЕсли ЦыфраD>=1 И ЦыфраD<=9 Тогда Возврат ""+ЦыфраD; ИначеЕсли ЦыфраD=10 Тогда Возврат "A"; ИначеЕсли ЦыфраD=11 Тогда Возврат "B"; ИначеЕсли ЦыфраD=12 Тогда Возврат "C"; ИначеЕсли ЦыфраD=13 Тогда Возврат "D"; ИначеЕсли ЦыфраD=14 Тогда Возврат "E"; ИначеЕсли ЦыфраD=15 Тогда Возврат "F"; Иначе Возврат "?"; КонецЕсли; КонецФункции Функция DigitHEXtoDECЛкс(ЦыфраH) Если ЦыфраH="0" ИЛИ ЦыфраH="1" ИЛИ ЦыфраH="2" ИЛИ ЦыфраH="3" ИЛИ ЦыфраH="4" ИЛИ ЦыфраH="5" ИЛИ ЦыфраH="6" ИЛИ ЦыфраH="7" ИЛИ ЦыфраH="8" ИЛИ ЦыфраH="9" Тогда Возврат Цел(ЦыфраH); ИначеЕсли ЦыфраH="a" ИЛИ ЦыфраH="A" Тогда Возврат 10; ИначеЕсли ЦыфраH="b" ИЛИ ЦыфраH="B" Тогда Возврат 11; ИначеЕсли ЦыфраH="c" ИЛИ ЦыфраH="C" Тогда Возврат 12; ИначеЕсли ЦыфраH="d" ИЛИ ЦыфраH="D" Тогда Возврат 13; ИначеЕсли ЦыфраH="e" ИЛИ ЦыфраH="E" Тогда Возврат 14; ИначеЕсли ЦыфраH="f" ИЛИ ЦыфраH="F" Тогда Возврат 15; Иначе Возврат -1; КонецЕсли; КонецФункции Функция СтрокаHEXtoINTЛкс(Знач СтрокаH) Экспорт ПрефиксH = Лев(СтрокаH,2); Если ПрефиксH="0x" ИЛИ ПрефиксH="0X" ИЛИ ПрефиксH="0х" ИЛИ ПрефиксH="0Х" Тогда СтрокаH=Сред(СтрокаH,3); КонецЕсли; Если ПустаяСтрока(СтрокаH) Тогда Возврат 0; КонецЕсли; ДлинаH=СтрДлина(СтрокаH); ЧислоD=0; Для о = 1 По ДлинаH Цикл ЦыфраH = Сред(СтрокаH,о,1); ЦифраD = DigitHEXtoDECЛкс(ЦыфраH); Если ЦифраD<0 Тогда Возврат -1; // нарушение формата 16-тиричного числа КонецЕсли; ЧислоD = 16*ЧислоD + ЦифраD; КонецЦикла; Возврат ЧислоD; КонецФункции // преобразует 16-тиричную строку в COMSafeArray Функция СтрокаHEXtoCOMSafeArrayЛкс(Знач СтрокаH) Экспорт ПрефиксH = Лев(СтрокаH,2); Если Ложь Или ПрефиксH="0x" ИЛИ ПрефиксH="0X" ИЛИ ПрефиксH="0х" ИЛИ ПрефиксH="0Х" Тогда СтрокаH=Сред(СтрокаH,3); КонецЕсли; Байты =СтрДлина(СтрокаH); Байты = 2*Окр(Байты/2,0,1); ArrayДанные = Новый Массив; Поза=1; Для о=1 По Байты Цикл ДваБайт = Сред(СтрокаH,Поза,2); ЗначInt = СтрокаHEXtoINTЛкс(ДваБайт); Если ЗначInt<0 Тогда Возврат Неопределено; КонецЕсли; ArrayДанные.Добавить(ЗначInt); Поза=Поза+2; КонецЦикла; Array = Новый COMSafeArray(ArrayДанные,"VT_UI1",Байты/2); Возврат Array; КонецФункции // преобразует объект УникальныйИдентификатор в COMSafeArray Функция GUIDToCOMSafeArrayЛкс(GUID) Экспорт ГУИД = СтрЗаменить(GUID,"-",Символы.ПС); Если СтрЧислоСтрок(ГУИД)<>5 Тогда // нарушена каноническая структура строки ГУИД: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12) Возврат Неопределено; // вдруг ... КонецЕсли; // Соответсвие байтов в поле BINARY(16) с частями ГУИД: 4,5,3,2,1 - проверено для 1с-8.1.14 СтрокаH = СтрПолучитьСтроку(ГУИД,4) + СтрПолучитьСтроку(ГУИД,5)+ СтрПолучитьСтроку(ГУИД,3)+ СтрПолучитьСтроку(ГУИД,2)+ СтрПолучитьСтроку(ГУИД,1); //Сообщить("ГУИД = "+ГУИД); //Сообщить("СтрокаH = "+СтрокаH); Возврат СтрокаHEXtoCOMSafeArrayЛкс(СтрокаH); КонецФункции // преобразует значение уникального идентификатора ссылки в COMSafeArray Функция СсылкаToCOMSafeArrayЛкс(Ссылка) Экспорт Попытка ГУИД = СокрЛП(Ссылка.УникальныйИдентификатор()); Исключение // переданное значение не ссылка Возврат Неопределено; КонецПопытки; Возврат GUIDToCOMSafeArrayЛкс(ГУИД); КонецФункции // преобразоваение значения COMSafeArray, содержащие 2-байтовые целые в шестнадцатиричную строку Функция BinaryCOMSafeArrayToHEXЛкс(Array) Экспорт СтрHEX=""; Если ТипЗнч(Array)<>Тип("COMSafeArray") Тогда Возврат "?COMSafeArray?"; КонецЕсли; Массив=Array.Выгрузить(); Для каждого Слово Из Массив Цикл Если ТипЗнч(Слово)=Тип("Число") Тогда Слово=Цел(Слово); Если (Слово<0)ИЛИ(Слово>255) Тогда СтрHEX=СтрHEX+"??"; Иначе Байт1=Слово%16; Байт2=Цел(Слово/16); СтрHEX=СтрHEX+DigitDECtoHEXЛкс(Байт2)+DigitDECtoHEXЛкс(Байт1); КонецЕсли; Иначе СтрHEX=СтрHEX+"??"; КонецЕсли; КонецЦикла; Возврат "0x"+СтрHEX; КонецФункции // возвращает свойства параметра ADO из переданной структуры // с автоматическим подбором значений свойств по значению 1С (если свойство неопределено) Процедура ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils=Неопределено) Перем ТипЗначения1С; Если ТипЗнч(стТипADO)=Тип("Структура") Тогда стТипADO.Свойство("Direction",Direction); стТипADO.Свойство("Type",Type); стТипADO.Свойство("Precision",Precision); стТипADO.Свойство("NumericScale",NumericScale); стТипADO.Свойство("Size",Size); стТипADO.Свойство("Attributes",Attributes); стТипADO.Свойство("ТипЗначения1С",ТипЗначения1С); КонецЕсли; Если Истина И ТипЗнч(ТипЗначения1С) = Тип("ОписаниеТипов") И ТипЗначения1С.Типы().Количество() > 0 И НЕ ТипЗначения1С.СодержитТип(ТипЗнч(Значение1С)) Тогда // приведем значение 1С к указанному типу (актуально для значений Null, возвращаемых запросами 1С) Значение1С = ТипЗначения1С.ПривестиЗначение(Значение1С); КонецЕсли; Если Direction=Неопределено Тогда Direction=1; // 1 - входящий(Default) ... или 0 - неизвестно ??? КонецЕсли; Тип1С=ТипЗнч(Значение1С); Попытка Ссылка = Значение1С.Ссылка; Исключение Ссылка = Неопределено; Попытка // перечисления стоят особняком среди "ссылочных" типов МетаДата = Значение1С.Метаданные(); Если Метаданные.Перечисления.Содержит(МетаДата) Тогда Ссылка = Значение1С; КонецЕсли; Исключение КонецПопытки; КонецПопытки; Если Type=Неопределено Тогда // попытаемся подобрать по типу 1С Если Тип1С=Тип("Число") Тогда //Type = 4; // adSingle //Type = 5; // adDouble //Type = 14; // adDecimal //Type = 131; // adNumeric //Type = 139; // adVarNumeric Если Цел(Значение1С)=Значение1С Тогда Если ?(Значение1С<0,-1,1)*Значение1С <= 2147483647 Тогда // 2^32-1 Type = intTypeADOЛкс("adInteger"); // 3 Иначе Type = intTypeADOЛкс("adBigInt"); // 20 КонецЕсли; Иначе Type = 14; // adDecimal КонецЕсли; ИначеЕсли Тип1С=Тип("Строка") Тогда //Type = 129; // adChar //Type = 130; // adWChar //Type = 200; // adVarChar //Type = 201; // adLongVarChar //Type = 202; // adVarWChar //Type = 203; // adLongVarWChar Если СтрДлина(Значение1С)<=4000 Тогда Type = intTypeADOЛкс("adVarChar"); // 200 Иначе Type = intTypeADOЛкс("adLongVarChar"); // 201 КонецЕсли; ИначеЕсли Тип1С=Тип("Дата") Тогда //Type = 134; // adDBTime Если НачалоДня(Значение1С)=Значение1С Тогда Type = intTypeADOЛкс("adDBDate"); // 133 Иначе Type = intTypeADOЛкс("adDBTimeStamp"); // 135 КонецЕсли; ИначеЕсли Тип1С=Тип("Булево") Тогда Type = intTypeADOЛкс("adBoolean"); // 11 ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда Type = intTypeADOЛкс("adBinary"); // 128 Size = 16; Иначе Если Ссылка <> Неопределено Тогда // ссылочный тип - преобразуем в COMSafeArray Type = intTypeADOЛкс("adBinary"); // 128 Size = 16; Иначе Type = intTypeADOЛкс("adEmpty"); // 0? (Default) КонецЕсли; КонецЕсли; КонецЕсли; // ADOUtils.V8DateToDBDate( Дата ) // с учетом YearOffset // ADOUtils.BooleanParameter( Значение ) // COMSafeArray(1) // ADOUtils.TypeParameter( Значение ) // COMSafeArray(1) *_TYPE // ADOUtils.TableNumberParameter( Значение ) // COMSafeArray(4) *_RTRef // ADOUtils.DataVersionParameter( Значение ) // COMSafeArray(8) _Version // ADOUtils.RRefParameter( Значение ) // COMSafeArray(16) *IDRRef Если Ложь Или Type = intTypeADOЛкс("adBinary") // 128 Или Type = intTypeADOЛкс("adVarBinary") Тогда // 204 //Если ADOUtils = Неопределено Тогда // ADOUtils = ПолучитьADOUtils(); // Если ADOUtils = Неопределено Тогда // ADOUtils = Null; // для избежания повторных инициализаций // КонецЕсли; //КонецЕсли; Если Ссылка <> Неопределено Тогда // ссылочный тип - преобразуем в COMSafeArray(16) ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка); //Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда // ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка); //Иначе // ЗначениеADO = ADOUtils.RRefParameter(Ссылка); //КонецЕсли; ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда // ГУИД - преобразуем в COMSafeArray(16) ЗначениеADO = GUIDToCOMSafeArrayЛкс(Значение1С); ИначеЕсли Тип1С=Тип("Булево") Тогда // Булево - преобразуем в COMSafeArray(1) ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00")); //Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда // ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00")); //Иначе // ЗначениеADO = ADOUtils.BooleanParameter(Значение1С); //КонецЕсли; Иначе КонецЕсли; КонецЕсли; Если Precision=Неопределено Тогда Если Ложь Или Type = intTypeADOЛкс("adDecimal") // 14 ИЛИ Type = intTypeADOЛкс("adNumeric") // 131 ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139 Тогда Precision = СтрДлина(СтрЗаменить(Строка(Значение1С)," ","")); КонецЕсли; КонецЕсли; Если NumericScale=Неопределено Тогда Если Ложь Или Type = intTypeADOЛкс("adDecimal") // 14 ИЛИ Type = intTypeADOЛкс("adNumeric") // 131 ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139 Тогда NumericScale = СтрДлина(Строка(Значение1С-Цел(Значение1С))); КонецЕсли; КонецЕсли; Если Size=Неопределено Тогда Если Ложь Или Type = intTypeADOЛкс("adChar") // 129 ИЛИ Type = intTypeADOЛкс("adWChar") // 130 ИЛИ Type = intTypeADOЛкс("adVarChar") // 200 //ИЛИ Type = intTypeADOЛкс("adLongVarChar") // 201 ИЛИ Type = intTypeADOЛкс("adVarWChar") // 202 //ИЛИ Type = intTypeADOЛкс("adLongVarWChar") // 203 Тогда Size = СтрДлина(Значение1С); КонецЕсли; КонецЕсли; КонецПроцедуры // создает массив объектов ADODB.Parameter по списку параметров ADO и по списку типов ADO Функция ParametersArrayПолучитьЛкс(стПараметры,стПарТипADO, ADOUtils = Неопределено) Экспорт ParametersArray = Новый Массив; ТипаМассив = Тип("Массив"); ТипаСоответствие = Тип("Соответствие"); cтПараметрыТип = ТипЗнч(стПараметры); cтПарТипADOТип = ТипЗнч(стПарТипADO); Если стПараметры = Неопределено Тогда Возврат ParametersArray; ИначеЕсли cтПараметрыТип = ТипаМассив ИЛИ cтПараметрыТип = ТипаСоответствие Тогда Если стПарТипADO <> Неопределено И cтПарТипADOТип <> cтПараметрыТип Тогда ВызватьИсключение( "Тип значения списка типов параметров ADO ('"+cтПарТипADOТип+"') не равен |типу значения списка параметров запроса ('"+cтПараметрыТип+"') !"); КонецЕсли; Иначе ВызватьИсключение( "Не предусмотренный тип значения списка параметров запроса ('"+cтПараметрыТип+"') !"); КонецЕсли; ОбъектЗапрос = Новый COMОбъект("ADODB.Command"); Индекс = 0; Для каждого Параметр Из стПараметры Цикл Если cтПараметрыТип = ТипаМассив Тогда ПараметрИмя = Неопределено; Значение1С = Параметр; ИначеЕсли cтПараметрыТип = ТипаСоответствие Тогда ПараметрИмя = СокрЛП(Параметр.Ключ); Значение1С = Параметр.Значение; Иначе Продолжить; КонецЕсли; Индекс = Индекс + 1; стТипADO=Неопределено; Если cтПарТипADOТип=ТипаМассив Тогда Если Индекс<=стПарТипADO.Количество()-1 Тогда стТипADO = стПарТипADO.Получить(Индекс); КонецЕсли; ИначеЕсли cтПарТипADOТип = ТипаСоответствие Тогда стТипADO = стПарТипADO.Получить(Параметр.Ключ); КонецЕсли; ЗначениеADO = Неопределено; Attributes = Неопределено; Direction = Неопределено; Type = Неопределено; Precision = Неопределено; NumericScale = Неопределено; Size = Неопределено; // прочитаем свойства параметра ADO по полученной структуре типа и значению 1С ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils); // создадим параметр ADO и заполним его свойства Parameter = ОбъектЗапрос.CreateParameter(); Если НЕ ПустаяСтрока(Type) Тогда Parameter.Type=Type; КонецЕсли; Если НЕ ПустаяСтрока(Direction) Тогда Parameter.Direction=Direction; КонецЕсли; Если НЕ ПустаяСтрока(Size) Тогда Parameter.Size=Size; КонецЕсли; Если НЕ ПустаяСтрока(Attributes) Тогда Parameter.Attributes=Attributes; КонецЕсли; Если НЕ ПустаяСтрока(ПараметрИмя) Тогда Parameter.Name = ПараметрИмя; КонецЕсли; Если ЗначениеADO = Неопределено Тогда Parameter.Value=Значение1С; // преобразование не явное Иначе Parameter.Value=ЗначениеADO; КонецЕсли; // добавим в массив ParametersArray.Добавить(Parameter); КонецЦикла; Возврат ParametersArray; КонецФункции // ParametersArrayПолучитьЛкс() // формирует массив или соответствие со значениями параметров запроса из строки таблицы значений Функция стПараметры_Получить_ТЗЛкс(тзПараметры,СтрокаПараметров,NamedParameters,Знач ParametersPrefix) Экспорт Если NamedParameters=Истина Тогда ParametersPrefix=СокрЛП(ParametersPrefix); стПараметры=Новый Соответствие; Для каждого Колонка Из тзПараметры.Колонки Цикл стПараметры.Вставить(ParametersPrefix+Колонка.Имя,СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка))); КонецЦикла; Иначе стПараметры=Новый Массив; Для каждого Колонка Из тзПараметры.Колонки Цикл стПараметры.Добавить(СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка))); КонецЦикла; КонецЕсли; Возврат стПараметры; КонецФункции // стПараметры_Получить_ТЗЛкс() // добавляет и устанавливает объект ADODB.Parameter в коллекцию параметров // если не заданы свойства параметра ADO, делается попытка их подбора по типу значения 1С Функция ADODBCommand_УстановитьПараметрПо1СЛкс(ОбъектЗапрос,Инициализация,Индекс,Name,стТипADO,Значение1С,ADOUtils,ЕррорИнфо) Экспорт ЗначениеADO=Неопределено; Attributes=Неопределено; Direction=Неопределено; Type=Неопределено; Precision=Неопределено; NumericScale=Неопределено; Size=Неопределено; // прочитаем свойства параметра ADO из переданной структуры по значению 1С ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils); ЕррорИнфо=""; Попытка Если ОбъектЗапрос.Prepared = Ложь ИЛИ Инициализация <> Ложь Тогда // инициализация параметров запроса Добавить = Ложь; Если Name = Неопределено Тогда // по переданному индексу параметра Parameter = ОбъектЗапрос.CreateParameter(); Добавить = Истина; // создаем без имени Иначе // по переданному имени параметра Попытка // если уже есть параметр с именем - используем его Parameter = ОбъектЗапрос.Parameters.Item(Name); Исключение Parameter = Неопределено; КонецПопытки; Если Parameter = Неопределено Тогда // если нет - создаем с указанным именем Parameter = ОбъектЗапрос.CreateParameter(); Parameter.Name = Name; Добавить = Истина; КонецЕсли; КонецЕсли; Если НЕ ПустаяСтрока(Type) Тогда Parameter.Type=Type; КонецЕсли; Если НЕ ПустаяСтрока(Direction) Тогда Parameter.Direction=Direction; КонецЕсли; Если НЕ ПустаяСтрока(Size) Тогда Parameter.Size=Size; КонецЕсли; Если НЕ ПустаяСтрока(Attributes) И Attributes <> 0 Тогда Parameter.Attributes=Attributes; КонецЕсли; Если Добавить = Истина Тогда ОбъектЗапрос.Parameters.Append(Parameter); КонецЕсли; Иначе // установка параметра предварительно подготовленного параметризованного запроса Если Name = Неопределено Тогда // по переданному индексу параметра Parameter = ОбъектЗапрос.Parameters.Item(Индекс); Иначе // по переданному имени параметра Parameter = ОбъектЗапрос.Parameters.Item(Name); КонецЕсли; КонецЕсли; Если ЗначениеADO = Неопределено Тогда Parameter.Value=Значение1С; // преобразование не явное Иначе Parameter.Value=ЗначениеADO; КонецЕсли; Исключение ЕррорИнфо=ОписаниеОшибки(); Возврат Ложь; КонецПопытки; Возврат Истина; КонецФункции // ^^^ УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ^^^ // *** ПЕРЕЧИСЛЕНИЯ ADO *** // возвращает строковое представление типа параметра ADO(свойства Direction) по его числовому значению Функция strDirectionParADOЛкс(intTypeADOЛкс) Экспорт intType = Цел(intTypeADOЛкс); Если intType = 0 Тогда Возврат "adParamUnknown"; // Direction unknown ИначеЕсли intType = 1 Тогда Возврат "adParamInput"; // Input parameter (Default) ИначеЕсли intType = 2 Тогда Возврат "adParamOutput"; // Output parameter ИначеЕсли intType = 3 Тогда Возврат "adParamInputOutput"; // Input and output parameter ИначеЕсли intType = 4 Тогда Возврат "adParamReturnValue"; // Return value Иначе Возврат "adParamInput"; // как 1 КонецЕсли; КонецФункции // возвращает числовое значения типа параметра ADO(свойства Direction) по его числовому представлению Функция intDirectionParADOЛкс(strTypeADOЛкс) Экспорт strType = НРег(strTypeADOЛкс); Если strType = Нрег("adParamUnknown") Тогда Возврат 0; // Direction unknown ИначеЕсли strType = Нрег("adParamInput") Тогда Возврат 1; // Input parameter (Default) ИначеЕсли strType = Нрег("adParamOutput") Тогда Возврат 2; // Output parameter ИначеЕсли strType = Нрег("adParamInputOutput") Тогда Возврат 3; // Input and output parameter ИначеЕсли strType = Нрег("adParamReturnValue") Тогда Возврат 4; // Return value Иначе Возврат 1; // adParamInput КонецЕсли; КонецФункции // возвращает строковое представление типа значения ADO по его числовому значению Функция strTypeADOЛкс(intTypeADOЛкс) Экспорт intType = Цел(intTypeADOЛкс); Если intType = 0 Тогда Возврат "adEmpty"; // no value ИначеЕсли intType = 2 Тогда Возврат "adSmallInt"; // 2-byte signed integer ИначеЕсли intType = 3 Тогда Возврат "adInteger"; // 4-byte signed integer ИначеЕсли intType = 4 Тогда Возврат "adSingle"; // single-precision floating-point value ИначеЕсли intType = 5 Тогда Возврат "adDouble"; // double-precision floating-point value ИначеЕсли intType = 6 Тогда Возврат "adCurrency"; // currency value ИначеЕсли intType = 7 Тогда Возврат "adDate"; // number of days since December 30, 1899 + the fraction of a day ИначеЕсли intType = 8 Тогда Возврат "adBSTR"; // null-terminated character string ИначеЕсли intType = 9 Тогда Возврат "adIDispatch"; // pointer to an IDispatch interface on a COM object(currently not supported by ADO) ИначеЕсли intType = 10 Тогда Возврат "adError"; // 32-bit error code ИначеЕсли intType = 11 Тогда Возврат "adBoolean"; // boolean value ИначеЕсли intType = 12 Тогда Возврат "adVariant"; // automation Variant(currently not supported by ADO) ИначеЕсли intType = 13 Тогда Возврат "adIUnknown"; // pointer to an IUnknown interface on a COM object(currently not supported by ADO) ИначеЕсли intType = 14 Тогда Возврат "adDecimal"; // exact numeric value with a fixed precision and scale ИначеЕсли intType = 16 Тогда Возврат "adTinyInt"; // 1-byte signed integer ИначеЕсли intType = 17 Тогда Возврат "adUnsignedTinyInt"; // 1-byte unsigned integer ИначеЕсли intType = 18 Тогда Возврат "adUnsignedSmallInt"; // 2-byte unsigned integer ИначеЕсли intType = 19 Тогда Возврат "adUnsignedInt"; // 4-byte unsigned integer ИначеЕсли intType = 20 Тогда Возврат "adBigInt"; // 8-byte signed integer ИначеЕсли intType = 21 Тогда Возврат "adUnsignedBigInt"; // 8-byte unsigned integer ИначеЕсли intType = 64 Тогда Возврат "adFileTime"; // number of 100-nanosecond intervals since January 1,1601 ИначеЕсли intType = 72 Тогда Возврат "adGUID"; // globally unique identifier (GUID) ИначеЕсли intType = 128 Тогда Возврат "adBinary"; // binary value ИначеЕсли intType = 129 Тогда Возврат "adChar"; // string value ИначеЕсли intType = 130 Тогда Возврат "adWChar"; // null-terminated Unicode character string ИначеЕсли intType = 131 Тогда Возврат "adNumeric"; // exact numeric value with a fixed precision and scale ИначеЕсли intType = 132 Тогда Возврат "adUserDefined"; // user-defined variable ИначеЕсли intType = 133 Тогда Возврат "adDBDate"; // date value (yyyymmdd) ИначеЕсли intType = 134 Тогда Возврат "adDBTime"; // time value (hhmmss) ИначеЕсли intType = 135 Тогда Возврат "adDBTimeStamp"; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths) ИначеЕсли intType = 136 Тогда Возврат "adChapter"; // 4-byte chapter value that identifies rows in a child rowset ИначеЕсли intType = 138 Тогда Возврат "adPropVariant"; // automation PROPVARIANT ИначеЕсли intType = 139 Тогда Возврат "adVarNumeric"; // numeric value(Parameter object only) ИначеЕсли intType = 200 Тогда Возврат "adVarChar"; // string value (Parameter object only) ИначеЕсли intType = 201 Тогда Возврат "adLongVarChar"; // long string value ИначеЕсли intType = 202 Тогда Возврат "adVarWChar"; // null-terminated Unicode character string ИначеЕсли intType = 203 Тогда Возврат "adLongVarWChar"; // long null-terminated Unicode string value ИначеЕсли intType = 204 Тогда Возврат "adVarBinary"; // binary value (Parameter object only) ИначеЕсли intType = 205 Тогда Возврат "adLongVarBinary"; // long binary value ИначеЕсли intType = 8192 Тогда Возврат "AdArray"; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type Иначе Возврат "adEmpty"; // как 0 КонецЕсли; КонецФункции // возвращает числовое значение типа значения ADO по его строковому представлению Функция intTypeADOЛкс(strTypeADOЛкс) Экспорт strType = НРег(strTypeADOЛкс); Если strType = НРег("adEmpty") Тогда Возврат 0; // no value ИначеЕсли strType = НРег("adSmallInt") Тогда Возврат 2; // 2-byte signed integer ИначеЕсли strType = НРег("adInteger") Тогда Возврат 3; // 4-byte signed integer ИначеЕсли strType = НРег("adSingle") Тогда Возврат 4; // single-precision floating-point value ИначеЕсли strType = НРег("adDouble") Тогда Возврат 5; // double-precision floating-point value ИначеЕсли strType = НРег("adCurrency") Тогда Возврат 6; // currency value ИначеЕсли strType = НРег("adDate") Тогда Возврат 7; // number of days since December 30, 1899 + the fraction of a day ИначеЕсли strType = НРег("adBSTR") Тогда Возврат 8; // null-terminated character string ИначеЕсли strType = НРег("adIDispatch") Тогда Возврат 9; // pointer to an IDispatch interface on a COM object(currently not supported by ADO) ИначеЕсли strType = НРег("adError") Тогда Возврат 10; // 32-bit error code ИначеЕсли strType = НРег("adBoolean") Тогда Возврат 11; // boolean value ИначеЕсли strType = НРег("adVariant") Тогда Возврат 12; // automation Variant(currently not supported by ADO) ИначеЕсли strType = НРег("adIUnknown") Тогда Возврат 13; // pointer to an IUnknown interface on a COM object(currently not supported by ADO) ИначеЕсли strType = НРег("adDecimal") Тогда Возврат 14; // exact numeric value with a fixed precision and scale ИначеЕсли strType = НРег("adTinyInt") Тогда Возврат 16; // 1-byte signed integer ИначеЕсли strType = НРег("adUnsignedTinyInt") Тогда Возврат 17; // 1-byte unsigned integer ИначеЕсли strType = НРег("adUnsignedSmallInt") Тогда Возврат 18;// 2-byte unsigned integer ИначеЕсли strType = НРег("adUnsignedInt") Тогда Возврат 19; // 4-byte unsigned integer ИначеЕсли strType = НРег("adBigInt") Тогда Возврат 20; // 8-byte signed integer ИначеЕсли strType = НРег("adUnsignedBigInt") Тогда Возврат 21; // 8-byte unsigned integer ИначеЕсли strType = НРег("adFileTime") Тогда Возврат 64; // number of 100-nanosecond intervals since January 1,1601 ИначеЕсли strType = НРег("adGUID") Тогда Возврат 72; // globally unique identifier (GUID) ИначеЕсли strType = НРег("adBinary") Тогда Возврат 128; // binary value ИначеЕсли strType = НРег("adChar") Тогда Возврат 129; // string value ИначеЕсли strType = НРег("adWChar") Тогда Возврат 130; // null-terminated Unicode character string ИначеЕсли strType = НРег("adNumeric") Тогда Возврат 131; // exact numeric value with a fixed precision and scale ИначеЕсли strType = НРег("adUserDefined") Тогда Возврат 132; // user-defined variable ИначеЕсли strType = НРег("adDBDate") Тогда Возврат 133; // date value (yyyymmdd) ИначеЕсли strType = НРег("adDBTime") Тогда Возврат 134; // time value (hhmmss) ИначеЕсли strType = НРег("adDBTimeStamp") Тогда Возврат 135; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths) ИначеЕсли strType = НРег("adChapter") Тогда Возврат 136; // 4-byte chapter value that identifies rows in a child rowset ИначеЕсли strType = НРег("adPropVariant") Тогда Возврат 138; // automation PROPVARIANT ИначеЕсли strType = НРег("adVarNumeric") Тогда Возврат 139; // numeric value(Parameter object only) ИначеЕсли strType = НРег("adVarChar") Тогда Возврат 200; // string value (Parameter object only) ИначеЕсли strType = НРег("adLongVarChar") Тогда Возврат 201; // long string value ИначеЕсли strType = НРег("adVarWChar") Тогда Возврат 202; // null-terminated Unicode character string ИначеЕсли strType = НРег("adLongVarWChar") Тогда Возврат 203; // long null-terminated Unicode string value ИначеЕсли strType = НРег("adVarBinary") Тогда Возврат 204; // binary value (Parameter object only) ИначеЕсли strType = НРег("adLongVarBinary") Тогда Возврат 205; // long binary value ИначеЕсли strType = НРег("AdArray") Тогда Возврат 8192; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type Иначе Возврат 0; // adEmpty КонецЕсли; КонецФункции // возвращает числовое значение типа курсора по его строковому представлению Функция strCursorTypeЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = -1 Тогда Возврат "adOpenUnspecified"; // Does not specify the type of cursor ИначеЕсли intV = 0 Тогда Возврат "adOpenForwardOnly"; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default) ИначеЕсли intV = 1 Тогда Возврат "adOpenKeyset"; // Uses a keyset cursor. Like a dynamic cursor, except... ИначеЕсли intV = 2 Тогда Возврат "adOpenDynamic"; // Uses a dynamic cursor ИначеЕсли intV = 3 Тогда Возврат "adOpenStatic"; // Uses a static cursor Иначе Возврат "adOpenForwardOnly"; // как 0 КонецЕсли; КонецФункции // возвращает строковое представление типа курсора по его числовому значению Функция intCursorTypeЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adOpenUnspecified") Тогда Возврат -1; // Does not specify the type of cursor ИначеЕсли strV = Нрег("adOpenForwardOnly") Тогда Возврат 0; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default ИначеЕсли strV = Нрег("adOpenKeyset") Тогда Возврат 1; // Uses a keyset cursor. Like a dynamic cursor, except... ИначеЕсли strV = Нрег("adOpenDynamic") Тогда Возврат 2; // Uses a dynamic cursor ИначеЕсли strV = Нрег("adOpenStatic") Тогда Возврат 3; // Uses a static cursor Иначе Возврат 0; // adOpenForwardOnly КонецЕсли; КонецФункции // возвращает числовое значение местоположения курсора по его строковому представлению Функция strCursorLocationЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = 1 Тогда Возврат "adUseNone"; // Does not use cursor services ИначеЕсли intV = 2 Тогда Возврат "adUseServer"; // Uses a server-side cursor (Default) ИначеЕсли intV = 3 Тогда Возврат "adParamOutput"; // Uses a client-side cursor supplied by a local cursor library Иначе Возврат "adUseServer"; // как 2 КонецЕсли; КонецФункции // возвращает строковое представление местоположения курсора по его числовому значению Функция intCursorLocationЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adUseNone") Тогда Возврат 1; // Does not use cursor services ИначеЕсли strV = Нрег("adUseServer") Тогда Возврат 2; // Uses a server-side cursor (Default) ИначеЕсли strV = Нрег("adParamOutput") Тогда Возврат 3; // Uses a client-side cursor supplied by a local cursor library Иначе Возврат 2; // adUseServer КонецЕсли; КонецФункции // возвращает числовое значение типа блокировки данных по его строковому представлению Функция strLockTypeЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = -1 Тогда Возврат "adLockUnspecified"; // Unspecified type of lock. Clones inherits lock type from the original Recordset ИначеЕсли intV = 1 Тогда Возврат "adLockReadOnly"; // Read-only records ИначеЕсли intV = 2 Тогда Возврат "adLockPessimistic"; // Pessimistic locking, record by record. The provider lock records immediately after editing ИначеЕсли intV = 3 Тогда Возврат "adLockOptimistic"; // Optimistic locking, record by record. The provider lock records only when calling update ИначеЕсли intV = 4 Тогда Возврат "adLockBatchOptimistic"; // Optimistic batch updates. Required for batch update mode Иначе Возврат "adLockUnspecified"; // как -1 КонецЕсли; КонецФункции // возвращает строковое представление типа блокировки данных по его числовому значению Функция intLockTypeЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adLockUnspecified") Тогда Возврат -1; // Unspecified type of lock ИначеЕсли strV = Нрег("adLockReadOnly") Тогда Возврат 1; // Read-only records ИначеЕсли strV = Нрег("adLockPessimistic") Тогда Возврат 2; // Pessimistic locking, record by record. The provider lock records immediately after editing ИначеЕсли strV = Нрег("adLockOptimistic") Тогда Возврат 3; // Optimistic locking, record by record. The provider lock records only when calling update ИначеЕсли strV = Нрег("adLockBatchOptimistic") Тогда Возврат 4; // Optimistic batch updates. Required for batch update mode Иначе Возврат -1; // adLockUnspecified КонецЕсли; КонецФункции // возвращает числовое значение опции MarshalOptions по его строковому представлению Функция strMarshalOptionsЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = 0 Тогда Возврат "adMarshalAll"; // Returns all rows (Default) ИначеЕсли intV = 1 Тогда Возврат "adMarshalModifiedOnly"; // Returns only modified rows Иначе Возврат "adMarshalAll"; // как 0 КонецЕсли; КонецФункции // возвращает строковое представление опции MarshalOptions по его числовому значению Функция intMarshalOptionsЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adMarshalAll") Тогда Возврат 0; // Returns all rows (Default) ИначеЕсли strV = Нрег("adMarshalModifiedOnly") Тогда Возврат 1; // Returns only modified rows Иначе Возврат 0; // adMarshalAll КонецЕсли; КонецФункции // возвращает строковое представление типа команды ADO по его числовому значению Функция strCommandTypeADOЛкс(intTypeADOЛкс) Экспорт Если ТипЗнч(intTypeADOЛкс) = Тип("Число") Тогда intType = Цел(intTypeADOЛкс); Иначе intType = 0; КонецЕсли; Если intType = -1 Тогда Возврат "adCmdUnspecified"; // Unspecified type of command ИначеЕсли intType = 1 Тогда Возврат "adCmdText"; // строка оператора T-SQL ИначеЕсли intType = 2 Тогда Возврат "adCmdTable"; // имя таблицы для выборки строк ИначеЕсли intType = 4 Тогда Возврат "adCmdStoredProc"; // имя хранимой процедуры ИначеЕсли intType = 8 Тогда Возврат "adCmdUnknown"; // неизвестно, проверять провайдером (Default) ИначеЕсли intType = 256 Тогда Возврат "adCmdFile"; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only) ИначеЕсли intType = 512 Тогда Возврат "adCmdTableDirect"; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only) Иначе Возврат "adCmdUnknown"; // как 8 КонецЕсли; КонецФункции // возвращает числовое значение типа команды ADO по его строковому представлению Функция intCommandTypeADOЛкс(strTypeADOЛкс) Экспорт strType = Нрег(strTypeADOЛкс); Если strType = Нрег("adCmdUnspecified") Тогда Возврат -1; // Unspecified type of command ИначеЕсли strType = Нрег("adCmdText") Тогда Возврат 1; // строка оператора T-SQL ИначеЕсли strType = Нрег("adCmdTable") Тогда Возврат 2; // имя таблицы для выборки строк ИначеЕсли strType = Нрег("adCmdStoredProc") Тогда Возврат 4; // имя хранимой процедуры ИначеЕсли strType = Нрег("adCmdUnknown") Тогда Возврат 8; // неизвестно, проверять провайдером (Default) ИначеЕсли strType = Нрег("adCmdFile") Тогда Возврат 256; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only) ИначеЕсли strType = Нрег("adCmdTableDirect") Тогда Возврат 512; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only) Иначе Возврат 8; // adCmdUnknown КонецЕсли; КонецФункции // возвращает строковое представление типа команды ADO по его числовому значению Функция strExecuteOptionЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = -1 Тогда Возврат "adOptionUnspecified"; // Unspecified command ИначеЕсли intV = 16 Тогда Возврат "adAsyncExecute"; // The command should execute asynchronously ИначеЕсли intV = 32 Тогда Возврат "adAsyncFetch"; // The remaining rows after specified in the CacheSize should be retrieved asynchronously ИначеЕсли intV = 64 Тогда Возврат "adAsyncFetchNonBlocking"; // The main thread never blocks while retrieving. ИначеЕсли intV = 128 Тогда Возврат "adExecuteNoRecords"; // Discard, not return retrieved rows (with Command or Connection.Execute only) ИначеЕсли intV = 256 Тогда Возврат "adExecuteStream"; // The results of a command execution is a stream (with Connection.Execute only) ИначеЕсли intV = 512 Тогда Возврат "adExecuteRecord"; // Return a single row as a Record object Иначе Возврат "adOptionUnspecified"; // как -1 КонецЕсли; КонецФункции // возвращает числовое значение типа команды ADO по его строковому представлению Функция intExecuteOptionЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adOptionUnspecified") Тогда Возврат -1; // Unspecified command ИначеЕсли strV = Нрег("adAsyncExecute") Тогда Возврат 16; // The command should execute asynchronously ИначеЕсли strV = Нрег("adAsyncFetch") Тогда Возврат 32; // The remaining rows after specified in the CacheSize should be retrieved asynchronously ИначеЕсли strV = Нрег("adAsyncFetchNonBlocking") Тогда Возврат 64; // The main thread never blocks while retrieving ИначеЕсли strV = Нрег("adExecuteNoRecords") Тогда Возврат 128; // Discard, not return retrieved rows (with Command or Connection.Execute only) ИначеЕсли strV = Нрег("adExecuteStream") Тогда Возврат 256; // The results of a command execution is a stream (with Connection.Execute only) ИначеЕсли strV = Нрег("adExecuteRecord") Тогда Возврат 512; // Return a single row as a Record object Иначе Возврат -1; // adOptionUnspecified КонецЕсли; КонецФункции // возвращает строковое представление опции аттрибутов параметра ADO по числовому значению опции Функция strParameterADOAttributesЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = 16 Тогда Возврат "adParamSigned"; // The parameter will accept signed values. ИначеЕсли intV = 64 Тогда Возврат "adParamNullAble"; // The parameter will accept null values. ИначеЕсли intV = 128 Тогда Возврат "adParamLong"; // The parameter will accept long binary data. Иначе Возврат "adParamSigned"; // как 16 КонецЕсли; КонецФункции // возвращает числовое значение оцции аттрибутов параметра ADO по строковому представлению опции Функция intParameterADOAttributesЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adParamSigned") Тогда Возврат 16; // The parameter will accept signed values. ИначеЕсли strV = Нрег("adParamNullAble") Тогда Возврат 64; // The parameter will accept null values. ИначеЕсли strV = Нрег("adParamLong") Тогда Возврат 128; // The parameter will accept long binary data. Иначе Возврат 16; // adParamSigned КонецЕсли; КонецФункции // ^^^ ПЕРЕЧИСЛЕНИЯ ADO ^^^ // ADO // ************************ // В платформе все корневые элементы древовидных структур содержат в свойстве Родитель Неопределено. // Поэтому возникает неудобство при работе с этим свойством, заключающееся в необходимости часто проверять его значение на Неопределено. // Параметры: // СтрокаДерева - СтрокаДереваЗначений, <Элемент любого иерархического объекта, имеющий родителя> // Дерево - <Иерархический объект, которому принадлежит элемент> - для дерева значений не нужно передавать // Функция ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево = Неопределено) Экспорт Родитель = СтрокаДерева.Родитель; Если Родитель = Неопределено Тогда Если Дерево = Неопределено Тогда Родитель = СтрокаДерева.Владелец(); Иначе Родитель = Дерево; КонецЕсли; КонецЕсли; Возврат Родитель; КонецФункции // Результат - Неопределено, "*", Число Функция ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение) Экспорт Если Не ЭтоКоллекцияЛкс(Значение) Тогда КоличествоЭлементов = Неопределено; Иначе КоличествоЭлементов = "*"; Если ТипЗнч(Значение) = Тип("COMSafeArray") Тогда КоличествоЭлементов = Значение.GetLength(); ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда Попытка КоличествоЭлементов = Значение.Count; Исключение КонецПопытки; КонецЕсли; Если КоличествоЭлементов = "*" Тогда Попытка КоличествоЭлементов = Значение.Количество(); Исключение КонецПопытки; КонецЕсли; КонецЕсли; Возврат КоличествоЭлементов; КонецФункции Функция ЭтоКоллекцияЛкс(Значение) Экспорт // Антибаг платформы 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1017316#1017316 Если Значение = ПараметрыСеанса Тогда Возврат Истина; КонецЕсли; Попытка Для Каждого _Элемент Из Значение Цикл Прервать; КонецЦикла; ЭтоКоллекция = Истина; Исключение ЭтоКоллекция = Ложь; КонецПопытки; Возврат ЭтоКоллекция; КонецФункции Функция ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД) Экспорт Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД); ТипМетаданных = Фрагменты[0]; ИмяОбъекта = Фрагменты[1]; Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда ТипОбъекта = Тип(ТипМетаданных + "Объект." + ИмяОбъекта); Иначе КэшТиповВнешнихМетаданных = ирПортативный.мКэшТиповВнешнихМетаданных; ВнешнийОбъект = КэшТиповВнешнихМетаданных[ПолноеИмяМД]; Если ВнешнийОбъект <> Неопределено Тогда ТипОбъекта = ТипЗнч(ВнешнийОбъект); КонецЕсли; КонецЕсли; Если ТипОбъекта <> Неопределено Тогда Результат = Новый (ТипОбъекта); Иначе Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных); ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(ИмяОбъекта, ТипМетаданных); Попытка Результат = Менеджер.Создать(ПолноеИмяФайла, Ложь); //// Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1442085/m/1442085 //Если ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Тогда // Пустышка = Результат.ПолучитьФорму(); //КонецЕсли; Исключение // Это очень помогает при ошибках функций режима отладки ВызватьИсключение ОписаниеОшибки(); КонецПопытки; Если Истина И КэшТиповВнешнихМетаданных <> Неопределено // Такой прием ко всем нельзя применять, т.к. при получении формы у разных экземпляров будет возвращаться всегда форма первого экземпляра, если она открыта И (Ложь Или ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Или ИмяОбъекта = "ирПлатформа") Тогда КэшТиповВнешнихМетаданных[ПолноеИмяМД] = Результат; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьПолноеИмяМДТипаЛкс(Тип) Экспорт ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип); Если ОбъектМетаданных <> Неопределено Тогда Результат = ОбъектМетаданных.ПолноеИмя(); Если ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Тогда Результат = Результат + ".Точки"; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции #КонецЕсли #Если Не ТонкийКлиент И Не ВебКлиент И Клиент Тогда Процедура ПоказатьНеуникальныеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач СтрокаКлюча = "") Экспорт НеуникальныеКлючи = ПолучитьНеуникальныеКлючиТаблицыЛкс(ТабличноеПоле.Значение, СтрокаКлюча); ТекстСообщения = "Найдено " + НеуникальныеКлючи.Количество() + " неуникальных ключей строк"; Если НеуникальныеКлючи.Количество() > 0 Тогда ВыделитьСтрокиТабличногоПоляПоКлючуЛкс(ТабличноеПоле, НеуникальныеКлючи[0], СтрокаКлюча); ТекстСообщения = ТекстСообщения + ". Выделены строки первого ключа"; //ЭтаФорма.ТекущийЭлемент = ТабличноеПоле; КонецЕсли; Сообщить(ТекстСообщения); КонецПроцедуры Функция ПолучитьКоординатыСтрокиДереваЛкс(СтрокаДерева, ИмяКлючевойКолонки = "") Экспорт Координаты = Новый Массив(); Родитель = СтрокаДерева; Пока Родитель <> Неопределено Цикл Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда Координата = Родитель[ИмяКлючевойКолонки]; Иначе Координата = ПолучитьРодителяСтрокиДереваЛкс(Родитель).Строки.Индекс(Родитель); КонецЕсли; Координаты.Вставить(0, Координата); Родитель = Родитель.Родитель; КонецЦикла; Возврат Координаты; КонецФункции Функция ПолучитьСтрокуДереваПоКоординатамЛкс(Дерево, Координаты, ИмяКлючевойКолонки = "") Экспорт СтрокаДерева = Дерево; Для Каждого Координата Из Координаты Цикл Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда СтрокаДерева = СтрокаДерева.Строки.Найти(Координата, ИмяКлючевойКолонки); Иначе СтрокаДерева = СтрокаДерева.Строки[Координата]; КонецЕсли; КонецЦикла; Возврат СтрокаДерева; КонецФункции Процедура УстановитьТекстПоляСохраняяПозициюЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт НачальнаяКолонка = 0; НачальнаяСтрока = 0; КонечнаяКолонка = 0; КонечнаяСтрока = 0; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекст); ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); КонецПроцедуры Функция ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL, АдресЧужойСхемыБД = "") Экспорт Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЗначениеSDBL, ":"); Если Фрагменты.Количество() < 2 Тогда Возврат Неопределено; КонецЕсли; СтрокаНомераТаблицы = Фрагменты[0]; ИдентификаторОбъекта = Фрагменты[1]; ПолноеИмяМД = ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомераТаблицы, АдресЧужойСхемыБД); ОбъектМетаданныхНайден = Истина; Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда ПолноеИмяМД = "НеизвестныйСсылочныйТип" + СтрокаНомераТаблицы; ОбъектМетаданныхНайден = Ложь; КонецЕсли; Результат = ПолноеИмяМД + "._" + ИдентификаторОбъекта; Если ОбъектМетаданныхНайден И Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда //СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(Ложь); // Этот способ не работал для перечислений //УникальныйИдентификатор = Новый УникальныйИдентификатор(ПолучитьГУИДПрямойИзИнверсногоЛкс(Фрагменты[1])); //Массив = Новый Массив(); //Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда // Массив.Добавить(УникальныйИдентификатор); //КонецЕсли; //Значение = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)), Массив); // ПустаяСсылка = Новый (Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД))); ПустаяСсылкаВнутр = ЗначениеВСтрокуВнутр(ПустаяСсылка); ФрагментыПустойСсылки = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПустаяСсылкаВнутр, ":"); СсылкаВнутр = ФрагментыПустойСсылки[0] + ":" + ИдентификаторОбъекта + "}"; Попытка Результат = ЗначениеИзСтрокиВнутр(СсылкаВнутр); Исключение // Например, если Фрагменты[1] содержит неверное число символов КонецПопытки; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомерТаблицы, АдресЧужойСхемыБД = "") Экспорт СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(,, АдресЧужойСхемыБД); #Если Сервер И Не Сервер Тогда СтруктураБД = Новый ТаблицаЗначений; #КонецЕсли СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданныхЛкс(, АдресЧужойСхемыБД); Для Каждого СтрокаШаблона Из СловарьШаблоновМетаданных.НайтиСтроки(Новый Структура("Значение", 1)) Цикл ИмяКандидат = СтрЗаменить(СтрокаШаблона.Ключ, "1", СтрокаНомерТаблицы); СтрокаСтруктуры = СтруктураБД.Найти(ИмяКандидат, "КраткоеИмяТаблицыХранения"); Если СтрокаСтруктуры <> Неопределено Тогда Возврат СтрокаСтруктуры.Метаданные; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции Функция ПолучитьИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки) Экспорт Попытка ТипЗначения = ДанныеСтроки.ТипЗначения; Исключение ТипЗначения = Неопределено; КонецПопытки; ИндексКартинки = -1; Если Ложь Или ДанныеСтроки.ТипСлова = "Ключевое слово" Или ДанныеСтроки.ТипСлова = "Конструкция" Тогда ИндексКартинки = 13; ИначеЕсли ТипЗначения = "Имя типа" Тогда ИндексКартинки = 12; ИначеЕсли ДанныеСтроки.ТипСлова = "Метод" Тогда Попытка Пустышка = ДанныеСтроки.Успех; ЕстьУспех = Истина; Исключение ЕстьУспех = Ложь; КонецПопытки; Если Ложь Или (Истина И ЕстьУспех И (Ложь Или ДанныеСтроки.ТаблицаСтруктурТипов = Неопределено Или ДанныеСтроки.ТаблицаСтруктурТипов.Количество() = 0 Или ДанныеСтроки.ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = "")) Или (Истина И Не ЕстьУспех И ДанныеСтроки.ТипЗначения = "") Тогда Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 0; ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда ИндексКартинки = 6; //ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда // ИндексКартинки = 9; Иначе ИндексКартинки = 3; КонецЕсли; Иначе Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 1; ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда ИндексКартинки = 7; //ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда // ИндексКартинки = 10; Иначе ИндексКартинки = 4; КонецЕсли; КонецЕсли; ИначеЕсли ДанныеСтроки.ТипСлова = "Свойство" Тогда Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 2; ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда ИндексКартинки = 8; //ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда // ИндексКартинки = 11; Иначе ИндексКартинки = 5; КонецЕсли; ИначеЕсли ДанныеСтроки.ТипСлова = "Таблица" Тогда ИндексКартинки = 14; ИначеЕсли ДанныеСтроки.ТипСлова = "Поле" Тогда Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 15; Иначе ИндексКартинки = 16; КонецЕсли; ИначеЕсли ДанныеСтроки.ТипСлова = "Группа" Тогда ИндексКартинки = 18; КонецЕсли; Возврат ИндексКартинки; КонецФункции // Эта обертка нужно для возможности привязать ее к команде панели инструментов Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт ОтладитьОтложенныйОбъектЛкс(); КонецПроцедуры Процедура ОтладитьОтложенныйОбъектЛкс(СсылкаИлиИмяФайла = Неопределено, УдалитьОбъектПослеУспешногоОткрытия = Ложь) Экспорт #Если Сервер И Не Сервер Тогда Ссылка = Справочники.ирОбъектыДляОтладки.ПустаяСсылка(); #КонецЕсли СтруктураПараметров = Неопределено; Если СсылкаИлиИмяФайла = Неопределено Тогда СсылкаИлиИмяФайла = ПолучитьТекстИзБуфераОбменаОСЛкс(); ЕстьСправочник = Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено; Если Не ВвестиСтроку(СсылкаИлиИмяФайла, "Введите результат сохранения объекта") Тогда Если ЕстьСправочник Тогда СсылкаИлиИмяФайла = ВыбратьСсылкуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки,, Ложь); Иначе ПутьДляФайловОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс(); Расширение = ПолучитьРасширениеФайловДляОтладкиЛкс(); лПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, "Файлы объектов для отладки",, ПутьДляФайловОбъектовДляОтладки); Если лПолноеИмяФайла <> Неопределено Тогда СсылкаИлиИмяФайла = "Файл """ + лПолноеИмяФайла + """"; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда Возврат; КонецЕсли; Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда ирПлатформа = ирКэш.Получить(); ВычислительРегулярныхВыражений = ирПлатформа.RegExp; ВычислительРегулярныхВыражений.Pattern = "Объект ""(.+)""|Файл ""(.+)""|Пользователь ""(.+)"""; Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла); Если Результат.Count = 0 Тогда Возврат; КонецЕсли; Если Результат.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); КонецЕсли; КонецПроцедуры Функция ПолныйИдентификаторСсылкиЛкс(Знач ЗначениеЯчейки) Экспорт ИдентификаторСсылки = ПолучитьИдентификаторСсылкиЛкс(ЗначениеЯчейки); Возврат ИдентификаторСсылки; КонецФункции Функция ЦветФонаЯчеекПустыхЗначенийЛкс() Экспорт ЦветПустых = Новый Цвет(250, 255, 250); //WebЦвета.Роса; Возврат ЦветПустых; КонецФункции Функция ПолучитьИдентификаторСсылкиЛкс(Ссылка, ВместеСТипом = Ложь) Экспорт ИдентификаторСсылки = Неопределено; XMLТип = XMLТипЗнч(Ссылка); Если Истина И XMLТип <> Неопределено И Найти(XMLТип.ИмяТипа, "Ref.") > 0 Тогда Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда ИдентификаторСсылки = "{" + ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ЗначениеВСтрокуВнутр(Ссылка), "," + Символы.ПС + "{", "}" + Символы.ПС + "}") + "}"; ИдентификаторСсылки = СтрЗаменить(ИдентификаторСсылки, Символы.ПС, ""); Иначе ИдентификаторСсылки = XMLСтрока(Ссылка); КонецЕсли; КонецЕсли; Если ВместеСТипом И ИдентификаторСсылки <> Неопределено Тогда ИдентификаторСсылки = ИдентификаторСсылки + "." + XMLТип.ИмяТипа; КонецЕсли; Возврат ИдентификаторСсылки; КонецФункции Функция ПолучитьИдентификаторЗначенияЛкс(Значение) Экспорт ИдентификаторЗначения = ПолучитьИдентификаторСсылкиЛкс(Значение); Если ИдентификаторЗначения = Неопределено Тогда ИдентификаторЗначения = Формат(Значение, "ЧН=; ДП=; БЛ="); КонецЕсли; Возврат ИдентификаторЗначения; КонецФункции Процедура ТабличноеПолеВставитьКолонкуНомерСтрокиЛкс(Знач ТабличноеПоле) Экспорт ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс(); Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиНомерСтроки) = Неопределено Тогда КолонкаТП = ТабличноеПоле.Колонки.Вставить(0); КолонкаТП.Имя = ИмяКолонкиНомерСтроки; КолонкаТП.ТекстШапки = "№"; КолонкаТП.ПодсказкаВШапке = "Номер элемента в пределах родителя (служебная)"; КолонкаТП.ТолькоПросмотр = Истина; КолонкаТП.Ширина = 3; КонецЕсли; КонецПроцедуры // ОбновитьТаблицуКолонок() Процедура _РасширенныйВыборПравогоЗначенияОтбораКомпоновкиЛкс(ТабличноеПолеОтбора) Экспорт ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока; Если Ложь Или ТекущаяСтрока = Неопределено Или ТипЗнч(ТекущаяСтрока) = Тип("ОтборКомпоновкиДанных") Или ТипЗнч(ТекущаяСтрока) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда Возврат; КонецЕсли; ЗначениеОтбора = ТекущаяСтрока.ПравоеЗначение; КолонкаТП = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента; ТабличноеПолеОтбора.ТекущаяКолонка = КолонкаТП; Если ТипЗнч(ЗначениеОтбора) <> Тип("СписокЗначений") Тогда Если ЛиСсылкаНаОбъектБДЛкс(ЗначениеОтбора, Ложь) Тогда ТабличноеПолеОтбора.ИзменитьСтроку(); ирОбщий.ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеОтбора)),,, КолонкаТП.ЭлементУправления, Истина,, ЗначениеОтбора); КонецЕсли; Иначе Результат = ирОбщий.ОткрытьЗначениеЛкс(ЗначениеОтбора, Истина); Если Результат Тогда ТекущаяСтрока.ПравоеЗначение = ЗначениеОтбора; ТекущаяСтрока.Использование = Истина; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка) Экспорт МассивСостояний = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс(); Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда ТекстКнопки = Кнопка.Текст; Иначе ТекстКнопки = Кнопка.Заголовок; КонецЕсли; Если ТекстКнопки = МассивСостояний[2] Тогда Кнопка.Пометка = Ложь; НовыйТекстКнопки = МассивСостояний[0]; Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирПусто"); ИначеЕсли ТекстКнопки = МассивСостояний[1] Тогда Кнопка.Пометка = Истина; НовыйТекстКнопки = МассивСостояний[2]; Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирИдентификатор"); Иначе//Если ТекстКнопки = МассивСостояний[0] Тогда Кнопка.Пометка = Истина; НовыйТекстКнопки = МассивСостояний[1]; Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирПусто"); КонецЕсли; Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда Кнопка.Текст = НовыйТекстКнопки; Иначе Кнопка.Заголовок = НовыйТекстКнопки; КонецЕсли; КонецПроцедуры Функция ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс() Экспорт МассивСостояний = Новый Массив; МассивСостояний.Добавить("Не отображать"); МассивСостояний.Добавить("Отображать пустые"); МассивСостояний.Добавить("Отображать пустые и идентификаторы"); Возврат МассивСостояний; КонецФункции Процедура ПрименитьИзмененияИЗакрытьФормуЛкс(ЭтаФорма, ЗначениеВыбора = Неопределено) Экспорт ЭтаФорма.Модифицированность = Ложь; Если Ложь Или ЭтаФорма.ВладелецФормы <> Неопределено Или Не ЭтаФорма.Открыта() Тогда ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора); КонецЕсли; Если ЭтаФорма.Открыта() Тогда ЭтаФорма.Закрыть(ЗначениеВыбора); КонецЕсли; //Если ЭтаФорма.Открыта() Тогда // ЭтаФорма.Закрыть(ЗначениеВыбора); //Иначе//Если ЭтаФорма.МодальныйРежим Тогда // ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора); //КонецЕсли; КонецПроцедуры // ПрименитьИзмененияИЗакрытьФорму() Функция НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Знач Слово, ЯзыкПрограммы = 0, ПоискСУчетомТипаСлова = Истина) Экспорт мПлатформа = ирКэш.Получить(); мПлатформа.ИнициализацияОписанияМетодовИСвойств(); МассивВозможныхТиповСлова = Новый Массив; МассивВозможныхТиповСлова.Добавить("Конструктор"); Слово = НРег(Слово); Если Ложь Или Не ПоискСУчетомТипаСлова Или Прав(Слово, 1) = "(" Тогда Если Прав(Слово, 1) = "(" Тогда Слово = ПолучитьСтрокуБезКонцаЛкс(Слово, 1); КонецЕсли; МассивВозможныхТиповСлова.Добавить("Метод"); КонецЕсли; Если Ложь Или Не ПоискСУчетомТипаСлова Или Прав(Слово, 1) <> "(" Тогда МассивВозможныхТиповСлова.Добавить("Свойство"); МассивВозможныхТиповСлова.Добавить("Конструкция"); МассивВозможныхТиповСлова.Добавить("Событие"); МассивВозможныхТиповСлова.Добавить("Таблица"); КонецЕсли; ТаблицаСтруктурВозможныхТиповКонтекста = мПлатформа.ПолучитьНовуюТаблицуСтруктурТипа(); Для Каждого ВозможныйТипСлова Из МассивВозможныхТиповСлова Цикл Если ВозможныйТипСлова = "Конструктор" Тогда КлючПоиска = Новый Структура("ТипКонтекста, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, ""); Иначе КлючПоиска = Новый Структура("НСлово, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, ""); КонецЕсли; НайденныеСтроки = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоиска); Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока)); КонецЦикла; НайденныеСтроки = мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(КлючПоиска); Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока)); КонецЦикла; КонецЦикла; КлючПоиска = Новый Структура("НСлово, ЯзыкПрограммы", Слово, ЯзыкПрограммы); НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока)); КонецЦикла; Возврат ТаблицаСтруктурВозможныхТиповКонтекста; КонецФункции // НайтиВозможныеСтрокиОписанияСлова() // Открывает форму синтакс-помощника и загружает в нее нужную страницу, подсвечивая заданную строку. // // Параметры: // ВнутреннийПутьКОписанию – Строка – внутренний путь к странице синтакс-помощника; // СтрокаДляПодсветки – Строка – которую нужно подсветить в тексте страницы. // // Возвращаемое значение: // Форма. // Функция ОткрытьСтраницуСинтаксПомощникаЛкс(ВнутреннийПутьКОписанию, СтрокаДляПодсветки = "", ВладелецФормы = Неопределено, КлючУникальности = Неопределено) Экспорт Если ВнутреннийПутьКОписанию = "" Тогда Возврат Неопределено; КонецЕсли; ФормаСправка = ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , , КлючУникальности); ФормаСправка.ВладелецФормы = ВладелецФормы; ФормаСправка.ОткрытьАдрес(ВнутреннийПутьКОписанию, СтрокаДляПодсветки); ФормаСправка.ВладелецФормы = Неопределено; Возврат ФормаСправка; КонецФункции // ОткрытьСтраницуСинтаксПомощникаЛкс() // Обходит строки табличного поля и имитирует редактирование и выбор пользователем заданного значения. // // Параметры: // ТабличноеПоле - ТабличноеПоле; // ЗначениеОбработки - Произвольные - значение, которое будем записывать в ячейки; // *ФормаИнициатор - Форма, *Неопределено - форма, от имени которой будет записывать; // *ТипИсточника – Строка, *Неопределено – "ТаблицаЗначений", "ТабличнаяЧасть"; // *Колонка – КолонкаТабличногоПоля, *Неопределено – колонка в которой обходим ячейки, по умолчанию текущая; // *ТолькоВыделенныеСтроки - Булево, *Истина - обходить только выделенные строки. // Процедура УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, ЗначениеОбработки, ФормаИнициатор = Неопределено, Знач ТипИсточника = Неопределено, Знач Колонка = Неопределено, Знач ТолькоВыделенныеСтроки = Истина, Знач ИнтерактивноеУстановка = Истина) Экспорт Если Колонка = Неопределено Тогда Колонка = ТабличноеПоле.ТекущаяКолонка; Иначе ТабличноеПоле.ТекущаяКолонка = Колонка; КонецЕсли; ЗначениеТабличногоПоля = ТабличноеПоле.Значение; Если ТипИсточника = "" Тогда ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; ЕстьОтборСтрок = Ложь Или ТипИсточника = "ТабличнаяЧасть" Или ТипИсточника = "НаборЗаписей"; Если ТолькоВыделенныеСтроки Тогда Если Истина И ТабличноеПоле.ВыделенныеСтроки.Количество() = 1 И ТипИсточника <> "ДеревоЗначений" Тогда ТекстОтбора = ""; Если ЕстьОтборСтрок Тогда ТекстОтбора = " удовлетворяющие отбору"; КонецЕсли; Ответ = Вопрос("Выделена только одна строка. Хотите обработать все" + ТекстОтбора + " строки?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Да Тогда ТолькоВыделенныеСтроки = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; КлючиСтрокДляОбработки = Новый Массив; Если ТолькоВыделенныеСтроки Тогда Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл КлючиСтрокДляОбработки.Добавить(ВыделеннаяСтрока); КонецЦикла; Иначе Если ЕстьОтборСтрок Тогда Построитель = Новый ПостроительЗапроса; Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЗначениеТабличногоПоля); Построитель.ВыбранныеПоля.Очистить(); Построитель.ВыбранныеПоля.Добавить("НомерСтроки"); СкопироватьОтборПостроителяЛкс(Построитель.Отбор, ТабличноеПоле.ОтборСтрок); ТаблицаРезультата = Построитель.Результат.Выгрузить(); Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл КлючиСтрокДляОбработки.Добавить(СтрокаРезультата.НомерСтроки - 1); КонецЦикла; ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда Для Каждого СтрокаТаблицы Из ТабличноеПоле.Значение Цикл КлючиСтрокДляОбработки.Добавить(СтрокаТаблицы); КонецЦикла; КонецЕсли; КонецЕсли; Индикатор = ПолучитьИндикаторПроцессаЛкс(КлючиСтрокДляОбработки.Количество(), "Групповая установка значения"); // Нужно встать на редактируемую колонку, чтобы сработал режим редактирования Для Каждого КлючСтроки Из КлючиСтрокДляОбработки Цикл ОбработатьИндикаторЛкс(Индикатор); Если ТипЗнч(КлючСтроки) = Тип("Число") Тогда ТекущаяСтрока = ТабличноеПоле.Значение[КлючСтроки]; Иначе ТекущаяСтрока = КлючСтроки; КонецЕсли; Если ТипЗнч(ЗначениеОбработки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(ЗначениеОбработки.Параметры, ТекущаяСтрока); НовоеЗначение = ВычислитьВыражение(ЗначениеОбработки.Формула, ЗначениеОбработки.Параметры); Иначе НовоеЗначение = ЗначениеОбработки; КонецЕсли; Если ИнтерактивноеУстановка Тогда ТабличноеПоле.ТекущаяСтрока = ТекущаяСтрока; //ТабличноеПоле.ИзменитьСтроку(); ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение, ФормаИнициатор,,, Ложь); ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь); Иначе ТекущаяСтрока[Колонка.Имя] = НовоеЗначение; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(Индикатор); КонецПроцедуры Функция ОбщийТипДанныхТабличногоПоляЛкс(Знач ТабличноеПоле, ПреобразоватьТипДанныхФормы = Ложь, выхСтруктураТипа = Неопределено) Экспорт мПлатформа = ирКэш.Получить(); ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле); Если ПреобразоватьТипДанныхФормы Тогда ТипЗначенияТабличногоПоля = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ТабличноеПоле).Типы()[0]; Иначе ТипЗначенияТабличногоПоля = ТипЗнч(ЗначениеТабличногоПоля); КонецЕсли; Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда ТипИсточника = "ТаблицаЗначений"; ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда ТипИсточника = "ДеревоЗначений"; ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДанныеФормыКоллекция") Тогда ТипИсточника = "ТаблицаЗначений"; ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДанныеФормыДерево") Тогда ТипИсточника = "ДеревоЗначений"; Иначе мПлатформа.ИнициализацияОписанияМетодовИСвойств(); выхСтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля); Если Ложь Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВидыСубконто") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "БазовыеВидыРасчета") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВедущиеВидыРасчета") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВытесняющиеВидыРасчета") > 0 Тогда ТипИсточника = "ТабличнаяЧасть"; ИначеЕсли Найти(выхСтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда ТипИсточника = "НаборЗаписей"; ИначеЕсли Найти(выхСтруктураТипа.ИмяОбщегоТипа, "Список.") > 0 Тогда ТипИсточника = "Список"; ИначеЕсли выхСтруктураТипа.ИмяОбщегоТипа = "ДинамическийСписок" Тогда //ТипИсточника = "ДинамическийСписок"; ТипИсточника = "Список"; КонецЕсли; КонецЕсли; Возврат ТипИсточника; КонецФункции // ИнтерактивноУстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗ() Функция ТаблицаЗначенийИзТабличногоПоляЛкс(Знач ИсточникДействий, МассивСтрок = Неопределено) Экспорт ИмяТипаЗначения = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ИсточникДействий); Если ИмяТипаЗначения = "Список" Тогда Возврат Неопределено; КонецЕсли; ЗначениеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ИсточникДействий); Если ТипЗнч(ИсточникДействий) = Тип("ТабличноеПоле") Тогда Если ТипЗнч(ЗначениеТабличногоПоля) = Тип("ТаблицаЗначений") Тогда ВыгрузкаРезультата = ЗначениеТабличногоПоля.Скопировать(МассивСтрок); Иначе ВыгрузкаРезультата = ЗначениеТабличногоПоля.Выгрузить(МассивСтрок); КонецЕсли; Иначе ТипЗначенияТаблицы = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ИсточникДействий).Типы()[0]; ИмяОбщегоТипа = ОбщийТипДанныхТабличногоПоляЛкс(ИсточникДействий, Истина); ОбъектМДТаблицы = Метаданные.НайтиПоТипу(ТипЗначенияТаблицы); Если ОбъектМДТаблицы <> Неопределено Тогда ВыгрузкаРезультата = Новый ТаблицаЗначений; Если ИмяОбщегоТипа = "ТабличнаяЧасть" Тогда // Через поля таблицы БД нельзя, т.к. у ТЧ может не быть проекции в БД Для Каждого МетаРеквизит Из ОбъектМДТаблицы.Реквизиты Цикл ВыгрузкаРезультата.Колонки.Добавить(МетаРеквизит.Имя, МетаРеквизит.Тип, МетаРеквизит.Представление()); КонецЦикла; Иначе ПоляТаблицыБД = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ОбъектМДТаблицы); Для Каждого ПолеБД Из ПоляТаблицыБД Цикл ВыгрузкаРезультата.Колонки.Добавить(ПолеБД.Имя, ПолеБД.ТипЗначения, ПолеБД.Заголовок); КонецЦикла; КонецЕсли; Иначе ВыгрузкаРезультата = ДанныеФормыВЗначение(ЗначениеТабличногоПоля, Тип(ИмяТипаЗначения)); #Если Сервер И Не Сервер Тогда ВыгрузкаРезультата = Новый ТаблицаЗначений; #КонецЕсли ВыгрузкаРезультата.Очистить(); // Лишняя работа для единообразия КонецЕсли; КоллекцияСтрок = ЗначениеТабличногоПоля; Если МассивСтрок <> Неопределено Тогда КоллекцияСтрок = Новый Массив; Для Каждого ИдентификаторСтроки Из МассивСтрок Цикл КоллекцияСтрок.Добавить(ИсточникДействий.ДанныеСтроки(ИдентификаторСтроки)); КонецЦикла; КонецЕсли; Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл ЗаполнитьЗначенияСвойств(ВыгрузкаРезультата.Добавить(), СтрокаКоллекции); КонецЦикла; КонецЕсли; Возврат ВыгрузкаРезультата; КонецФункции // Параметры: // ЭтаФорма - Форма // ТабличноеПоле - ТабличноеПоле // КлючевоеПоле - Строка // ЗначениеКлюча - // СообщатьОбУспехе - Булево // Функция УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач ЗначениеКлюча = Неопределено, Знач СообщатьОбУспехе = Ложь, АктивизироватьТабличноеПолеПриУспехе = Ложь) Экспорт ТипИсточника = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле); Если Ложь Или ТипИсточника = "ТаблицаЗначений" Или ТипИсточника = "ТабличнаяЧасть" Или ТипИсточника = "НаборЗаписей" Тогда ДанныеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле); #Если Сервер И Не Сервер Тогда ДанныеТабличногоПоля = Новый ТаблицаЗначений; #КонецЕсли Если КлючевоеПоле <> Неопределено Тогда НайденныеСтроки = ДанныеТабличногоПоля.НайтиСтроки(Новый Структура(КлючевоеПоле, ЗначениеКлюча)); Иначе НайденныеСтроки = ДанныеТабличногоПоля; КонецЕсли; Если НайденныеСтроки.Количество() > 0 Тогда НайденнаяСтрока = НайденныеСтроки[0]; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда НайденнаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор(); КонецЕсли; КонецЕсли; ЭтоКлиентскийИсточникДанных = Истина; ИначеЕсли ТипИсточника = "ДеревоЗначений" Тогда НайденнаяСтрока = ТабличноеПоле.Значение.Строки.Найти(ЗначениеКлюча, КлючевоеПоле, Истина); ЭтоКлиентскийИсточникДанных = Истина; Иначе НайденнаяСтрока = ЗначениеКлюча; Отбор = ТабличноеПоле.Значение.Отбор; ЭтоКлиентскийИсточникДанных = Ложь; КонецЕсли; Если Не ЭтоКлиентскийИсточникДанных Тогда МетаданныеИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ Т.ПометкаУдаления ИЗ " + МетаданныеИсточника.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", НайденнаяСтрока); СтрокаЕстьВИсточникеДанных = Не Запрос.Выполнить().Пустой(); Иначе СтрокаЕстьВИсточникеДанных = НайденнаяСтрока <> Неопределено; КонецЕсли; Если СтрокаЕстьВИсточникеДанных Тогда ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока; Иначе Сообщить("Строка не найдена в источнике данных"); КонецЕсли; Если ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока Тогда Если АктивизироватьТабличноеПолеПриУспехе Тогда ЭтаФорма.ТекущийЭлемент = ТабличноеПоле; КонецЕсли; Результат = Истина; Иначе ТекстСообщения = "Строка найдена в источнике данных, но не найдена в табличном поле"; Если Отбор <> Неопределено Тогда ТекстСообщения = ТекстСообщения + " с учетом отбора " + Отбор; КонецЕсли; Сообщить(ТекстСообщения, СтатусСообщения.Внимание); Результат = Ложь; КонецЕсли; Возврат Результат; КонецФункции Функция КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда КлючУникальности = ЭтаФорма.КлючУникальности; Иначе КлючУникальности = ЭтаФорма.мКлючУникальности; КонецЕсли; Результат = ИмяФормыИзФормыЛкс(ЭтаФорма) + "." + КлючУникальности + ".ПоследниеВыбранные"; Возврат Результат; КонецФункции // Параметры: // ЭтаФорма - Форма // КнопкаПодменю - Кнопка - подменю, в которое будут добавлены кнопки // Процедура ПоследниеВыбранныеЗаполнитьПодменюЛкс(Знач ЭтаФорма, КнопкаПодменю) Экспорт КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма); ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения); Если ТипЗнч(КнопкаПодменю) = Тип("КнопкаКоманднойПанели") Тогда КнопкаПодменю.Кнопки.Очистить(); Иначе ОчиститьПодчиненныеЭлементыФормыЛкс(КнопкаПодменю); КонецЕсли; Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда Возврат; КонецЕсли; ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс(); Для Счетчик = ЗапоминатьПоследниеВыбранные По ПоследниеВыбранные.Количество() - 1 Цикл ПоследниеВыбранные.Удалить(ЗапоминатьПоследниеВыбранные); КонецЦикла; Для каждого ЭлементСписка Из ПоследниеВыбранные Цикл ИмяКнопки = "_" + ПоследниеВыбранные.Индекс(ЭлементСписка); Если ТипЗнч(КнопкаПодменю) = Тип("КнопкаКоманднойПанели") Тогда Кнопка = КнопкаПодменю.Кнопки.Добавить(); Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; Кнопка.Имя = ИмяКнопки; //Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто; Кнопка.Текст = ЭлементСписка.Представление; Попытка Кнопка.Действие = Новый Действие("ПоследниеВыбранныеНажатие"); Исключение Прервать; КонецПопытки; Иначе ИмяКнопки = КнопкаПодменю.Имя + ИмяКнопки; Кнопка = ЭтаФорма.Элементы.Добавить(ИмяКнопки, Тип("КнопкаФормы"), КнопкаПодменю); //Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто; Кнопка.Заголовок = ЭлементСписка.Представление; Попытка Кнопка.ИмяКоманды = "ПоследниеВыбранныеНажатие"; Исключение Прервать; КонецПопытки; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ПоследниеВыбранныеНажатиеЛкс(Знач ЭтаФорма, ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач Кнопка) Экспорт //КлючСтроки = ЗначениеИзСтрокиВнутр(Кнопка.Имя); КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма); ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения); Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда Возврат; КонецЕсли; ИндексЭлементаСписка = Число(Сред(Кнопка.Имя, 2)); Если ПоследниеВыбранные.Количество() <= ИндексЭлементаСписка Тогда Возврат; КонецЕсли; КлючСтроки = ПоследниеВыбранные[ИндексЭлементаСписка].Значение; СтрокаНайдена = ирОбщий.УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(ЭтаФорма, ТабличноеПоле, КлючевоеПоле, КлючСтроки,, Истина); Если СтрокаНайдена И ЭтаФорма.РежимВыбора Тогда Ответ = Вопрос("Выбрать установленную строку?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда ЭтаФорма.ОповеститьОВыборе(КлючСтроки); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ПоследниеВыбранныеДобавитьЛкс(ЭтаФорма, ВыбранноеЗначение) Экспорт ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс(); Если Истина И ЗапоминатьПоследниеВыбранные <> Неопределено И ЗапоминатьПоследниеВыбранные > 0 Тогда КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма); ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения); Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда ПоследниеВыбранные = Новый СписокЗначений; КонецЕсли; Если ТипЗнч(ВыбранноеЗначение) <> Тип("Массив") Тогда МассивВыбранныхСтрок = Новый Массив; МассивВыбранныхСтрок.Добавить(ВыбранноеЗначение); Иначе // Такое предположительно происходит из-за ошибки в платформе МассивВыбранныхСтрок = ВыбранноеЗначение; КонецЕсли; Для Каждого СтрокаИзМассива Из МассивВыбранныхСтрок Цикл Индекс = ПоследниеВыбранные.НайтиПоЗначению(СтрокаИзМассива); Если Индекс <> Неопределено Тогда ПоследниеВыбранные.Удалить(Индекс); КонецЕсли; КлючСтроки = СтрокаИзМассива; ПредставленияКлюча = ПредставлениеСсылкиСУчетомВладельцаЛкс(КлючСтроки); ПоследниеВыбранные.Вставить(0, КлючСтроки, ПредставленияКлюча); КонецЦикла; ирОбщий.СохранитьЗначениеЛкс(КлючЗначения, ПоследниеВыбранные); КонецЕсли; КонецПроцедуры Функция КоличествоЗапоминаемыхПоследнихВыбранныхЛкс() Возврат 10; КонецФункции Функция ПредставлениеСсылкиСУчетомВладельцаЛкс(Знач Ссылка) Экспорт ПредставленияКлюча = "" + Ссылка; Попытка Владелец = Ссылка.Владелец; Исключение // Нет доступа КонецПопытки; Если ЗначениеЗаполнено(Владелец) Тогда ПредставленияКлюча = "[" + ПредставлениеСсылкиСУчетомВладельцаЛкс(Владелец) + "]" + ПредставленияКлюча; КонецЕсли; Возврат ПредставленияКлюча; КонецФункции Процедура ОформитьФонТекущейСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт Если Элемент.ТекущаяСтрока = ДанныеСтроки Тогда ОформлениеСтроки.ЦветФона = WebЦвета.СветлоНебесноГолубой; КонецЕсли; КонецПроцедуры Функция ПроверитьЗапуститьОтладчик(Знач ВремяОжиданияЗапуска = 5) Экспорт ИдентификаторПроцессаОтладчика = Неопределено; Платформа = ирКэш.Получить(); ПортОтладки = Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика); Если ИдентификаторПроцессаОтладчика = Неопределено Тогда //Если Не УФ(сПроверитьДоступностьКонфигуратора) Тогда // Сообщить("Конфигуратор уже открыт, но отладка не подключена. Выполните подключение отладчика вручную"); // Перейти ~Конец; //КонецЕсли; // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164 Если Платформа.ВерсияПлатформы = 802015 Тогда Предупреждение("Из-за ошибки платформы 8.2.15 запуск и подключение отладчика необходимо выполнять вручную", 20); Возврат Неопределено; КонецЕсли; Если ПортОтладки = Неопределено Тогда Предупреждение("Включите разрешение отладки в главном меню ""Сервис/Параметры/Системные"" и повторите операцию снова"); Возврат Неопределено; КонецЕсли; ПараметрыЗапуска = "CONFIG /DEBUG /DEBUGTARGET""tcp://127.0.0.1:" + ПортОтладки + """"; ЗапуститьСистему(ПараметрыЗапуска); Платформа.Sleep(ВремяОжиданияЗапуска); Если ИдентификаторПроцессаОтладчика = Неопределено Тогда ИдентификаторПроцессаОтладчика = 0; КонецЕсли; Пока Истина Цикл Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика); Если ИдентификаторПроцессаОтладчика = Неопределено Тогда Ответ = Вопрос("Отладчик еще не подключился. Повторить снова?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда Продолжить; КонецЕсли; КонецЕсли; Прервать; КонецЦикла; Иначе Платформа.АктивизироватьОкноПроцесса1С8(Число(ИдентификаторПроцессаОтладчика)); КонецЕсли; Если ИдентификаторПроцессаОтладчика <> Неопределено Тогда Результат = Число(ИдентификаторПроцессаОтладчика); КонецЕсли; Возврат Результат; КонецФункции Процедура ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка; Иначе ТекущаяКолонка = ТабличноеПоле.ТекущийЭлемент; КонецЕсли; Если ТекущаяКолонка = Неопределено Тогда Возврат; КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ИмяКолонки = ТекущаяКолонка.Данные; Иначе ИмяКолонки = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущаяКолонка, Истина); КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Возврат; КонецЕсли; ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ИмяКолонки]; XMLТип = XMLТипЗнч(ЗначениеЯчейки); Если XMLТип = Неопределено Тогда Возврат; КонецЕсли; Если Найти(XMLТип.ИмяТипа, "Ref.") = 0 Тогда Возврат; КонецЕсли; //Если Ложь // Или Найти(XMLТип.ИмяТипа, "EnumRef.") > 0 // Или Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 //Тогда // ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеЯчейки)),, Истина,,,, ЗначениеЯчейки); //Иначе ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеЯчейки); //КонецЕсли; КонецПроцедуры Функция ОткрытьСсылкуВРедактореОбъектаБДЛкс(КлючОбъекта, пИскомоеЗначение = Неопределено) Экспорт Форма = ПолучитьФормуСсылки(КлючОбъекта, пИскомоеЗначение); Форма.Открыть(); Возврат Форма; КонецФункции Функция ОткрытьОбъектВРедактореОбъектаБДЛкс(ОбъектБД, пИскомоеЗначение = Неопределено, КлючУникальности = Неопределено) Экспорт Если КлючУникальности = Неопределено Тогда КлючУникальности = Новый УникальныйИдентификатор; КонецЕсли; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", ОбъектБД); ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Ложь); ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", пИскомоеЗначение); Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючУникальности); #Если Сервер И Не Сервер Тогда Форма = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы); Форма.Открыть(); Возврат Форма; КонецФункции Функция ПолучитьФормуСсылки(КлючОбъекта, пИскомоеЗначение = Неопределено) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", КлючОбъекта); ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Истина); ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", пИскомоеЗначение); Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючОбъекта); #Если Сервер И Не Сервер Тогда Форма = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы); Возврат Форма; КонецФункции Процедура НайтиИПоказатьСсылкиНаОбъектБД(СсылкаНаКоторуюИщемСсылки) Экспорт ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", СсылкаНаКоторуюИщемСсылки); Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы); #Если Сервер И Не Сервер Тогда Форма = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы); Форма.Открыть(); Форма.НайтиИПоказатьСсылкиВФорме(); КонецПроцедуры // НайтиСсылки() // ВариантПросмотра - Строка - "Компактный", "ЯзыкЗапросов", "ВстроенныйЯзык", ... Функция ПолучитьФормуТекстаЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт Если КлючУникальности = Неопределено Тогда КлючУникальности = Новый УникальныйИдентификатор(); КонецЕсли; ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("Текст", ВладелецФормы, КлючУникальности); ФормаПросмотра.НачальноеЗначениеВыбора = Текст; ФормаПросмотра.РекомендуемыйВариант = ВариантПросмотра; ФормаПросмотра.ТолькоПросмотр = ТолькоПросмотр; Если Не ЗначениеЗаполнено(Заголовок) Тогда //Заголовок = ФормаПросмотра.Заголовок; Заголовок = ""; // Чтобы при повторном открытии не оставался старый текст КонецЕсли; ФормаПросмотра.Заголовок = Заголовок; Возврат ФормаПросмотра; КонецФункции Функция ОткрытьТекстЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт ФормаПросмотра = ПолучитьФормуТекстаЛкс(Текст, Заголовок, ВариантПросмотра, ТолькоПросмотр, КлючУникальности, ВладелецФормы); ФормаПросмотра.Открыть(); Возврат ФормаПросмотра; КонецФункции Процедура ПолеВводаТекста_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда СтандартнаяОбработка = Ложь; ФормаРедактора = ирКэш.Получить().ПолучитьФорму("Текст", Элемент, Новый УникальныйИдентификатор); ФормаРедактора.РежимВыбора = Истина; ФормаРедактора.НачальноеЗначениеВыбора = Элемент.Значение; ФормаРедактора.Открыть(); КонецЕсли; КонецПроцедуры // Для управляемой формы возвращает путь относительно родителя Функция ПутьКДаннымКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Колонка = Неопределено) Экспорт Если Колонка = Неопределено Тогда Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда Колонка = ТабличноеПоле.ТекущаяКолонка; Иначе Колонка = ТабличноеПоле.ТекущийЭлемент; КонецЕсли; КонецЕсли; Если ТипЗнч(Колонка) = Тип("ПолеФормы") Тогда ДанныеКолонки = ПутьКДаннымЭлементаУправляемойФормыЛкс(Колонка, Истина); ИначеЕсли Колонка <> Неопределено Тогда ДанныеКолонки = Колонка.Данные; Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда ДанныеКолонки = Колонка.ДанныеФлажка; Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда Если Ложь Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ДанныеКолонки = Колонка.ДанныеКартинки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ДанныеКолонки; КонецФункции Процедура ТабличноеПоле_ОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(Знач ТабличноеПоле) Экспорт Если ТабличноеПоле.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли; ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда Возврат; КонецЕсли; ДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле); НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДанныеТабличногоПоля, "Пользовательские"); Попытка Отбор = НастройкиСписка.Отбор; Исключение Отбор = ТабличноеПоле.ОтборСтрок; КонецПопытки; //Отбор = Новый ("Отбор"); Если ТипЗнч(Отбор) = Тип("Отбор") Тогда ЭлементОтбора = Отбор[ДанныеКолонки]; ДоступноеПоле = ЭлементОтбора; ТекущееЗначениеОтбора = ЭлементОтбора.Значение; Иначе ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Отбор, ДанныеКолонки,,,,, Ложь); ДоступноеПоле = Отбор.ДоступныеПоляОтбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ДанныеКолонки)); ТекущееЗначениеОтбора = ЭлементОтбора.ПравоеЗначение; КонецЕсли; ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки]; Если ЭлементОтбора.Использование Тогда Если Ложь Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно Тогда Если Ложь Или ТипЗнч(ЗначениеЯчейки) <> Тип("Булево") Или ДоступноеПоле.ТипЗначения.Типы().Количество() > 1 Тогда СписокЗначений = Новый СписокЗначений; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда НовыйВидСравения = ВидСравнения.НеВСписке; Иначе НовыйВидСравения = ВидСравненияКомпоновкиДанных.НеВСписке; КонецЕсли; СписокЗначений.Добавить(ТекущееЗначениеОтбора); СписокЗначений.Добавить(ЗначениеЯчейки); ЭлементОтбора.ВидСравнения = НовыйВидСравения; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.Значение = СписокЗначений; Иначе ЭлементОтбора.ПравоеЗначение = СписокЗначений; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке Тогда СписокЗначений = ТекущееЗначениеОтбора; СписокЗначений.Добавить(ЗначениеЯчейки); // Для обновления отбора ЭлементОтбора.Использование = Ложь; ЭлементОтбора.Использование = Истина; ИначеЕсли Ложь Или ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке Тогда СписокЗначений = ТекущееЗначениеОтбора; СписокЗначений.Удалить(СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки)); // Для обновления отбора ЭлементОтбора.Использование = Ложь; ЭлементОтбора.Использование = Истина; Иначе ЭлементОтбора.Использование = Ложь; КонецЕсли; КонецЕсли; Если Не ЭлементОтбора.Использование Тогда ЭлементОтбора.Использование = Истина; Если Истина И ДоступноеПоле.ТипЗначения.СодержитТип(Тип("Строка")) И ДоступноеПоле.ТипЗначения.КвалификаторыСтроки.Длина = 0 Тогда Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда // Особенность платформы Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит; Иначе ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит; КонецЕсли; Иначе Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит; Иначе ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит; КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно; Иначе ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно; КонецЕсли; КонецЕсли; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.Значение = ЗначениеЯчейки; Иначе ЭлементОтбора.ПравоеЗначение = ЗначениеЯчейки; КонецЕсли; КонецЕсли; КонецПроцедуры Функция ЗагрузитьЗначениеИзФайлаЛкс(Расширение = "", ОписаниеФормата = "", Сжатие = Истина) Экспорт ПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, ОписаниеФормата); Если ПолноеИмяФайла = Неопределено Тогда Возврат Неопределено; КонецЕсли; Если Сжатие Тогда ВременныйКаталог = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ВременныйКаталог); ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла); ЗипЧтение.ИзвлечьВсе(ВременныйКаталог); ПолноеИмяФайла = ВременныйКаталог + "\" + ЗипЧтение.Элементы[0].Имя; КонецЕсли; ЧтениеХМЛ = Новый ЧтениеXML; ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла); Попытка //Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла); Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ); Исключение Сообщить(ОписаниеОшибки()); Результат = Неопределено; КонецПопытки; ЧтениеХМЛ.Закрыть(); Если Сжатие Тогда УдалитьФайлы(ВременныйКаталог, "*"); КонецЕсли; Возврат Результат; КонецФункции Функция СохранитьЗначениеВФайлИнтерактивноЛкс(Значение, Расширение = "", ОписаниеФормата = "", Сжатие = Истина, УровеньСжатия = Неопределено) Экспорт ПолноеИмяФайла = ВыбратьФайлЛкс(Ложь, Расширение, ОписаниеФормата); Если ПолноеИмяФайла = Неопределено Тогда Возврат Неопределено; КонецЕсли; Результат = СохранитьЗначениеВФайлЛкс(Значение, ПолноеИмяФайла, Сжатие, УровеньСжатия); Возврат Результат; КонецФункции Функция СохранитьЗначениеВФайлЛкс(Знач Значение, Знач ПолноеИмяФайла, Сжатие = Ложь, УровеньСжатия = Неопределено) Экспорт ЗаписьХМЛ = Новый ЗаписьXML; ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла); Попытка //ЗначениеВФайл(ВыборФайла.ПолноеИмяФайла, Значение); СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение); Результат = Истина; Исключение Сообщить(ОписаниеОшибки()); Результат = Ложь; КонецПопытки; ЗаписьХМЛ.Закрыть(); Если Сжатие Тогда ВременныйКаталог = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ВременныйКаталог); Файл = Новый Файл(ПолноеИмяФайла); ИмяВременногоФайла = ВременныйКаталог + "\" + Файл.Имя; ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла); ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия); ЗаписьЗип.Добавить(ИмяВременногоФайла); ЗаписьЗип.Записать(); УдалитьФайлы(ВременныйКаталог, "*"); КонецЕсли; Возврат Результат; КонецФункции Функция ВыбратьРедактируемыйТипЛкс(ОграничениеТипа = Неопределено, ТолькоПросмотр = Ложь, НачальноеЗначениеВыбора = Неопределено) Экспорт Если ОграничениеТипа = Неопределено Тогда ОграничениеТипа = Новый ОписаниеТипов; КонецЕсли; ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов"); ФормаРедактора.ОграничениеТипа = ОграничениеТипа; ФормаРедактора.НачальноеЗначениеВыбора = НачальноеЗначениеВыбора; ФормаРедактора.МножественныйВыбор = Ложь; ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр; РезультатВыбора = ФормаРедактора.ОткрытьМодально(); Возврат РезультатВыбора; КонецФункции // РедактироватьДопустимыеТипы() Функция РедактироватьОписаниеРедактируемыхТиповЛкс(ОграничениеТипаИлиПолеВвода, ТолькоПросмотр = Ложь) Экспорт Если ТипЗнч(ОграничениеТипаИлиПолеВвода) = Тип("ОписаниеТипов") Тогда ВладелецФормы = Неопределено; ОграничениеТипа = ОграничениеТипаИлиПолеВвода; Иначе ВладелецФормы = ОграничениеТипаИлиПолеВвода; ОграничениеТипа = ОграничениеТипаИлиПолеВвода.Значение; КонецЕсли; ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы); //ФормаРедактора.ОграничениеТипа = ОграничениеТипа; ФормаРедактора.НачальноеЗначениеВыбора = ОграничениеТипа; ФормаРедактора.МножественныйВыбор = Истина; ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр; РезультатВыбора = ФормаРедактора.ОткрытьМодально(); Возврат РезультатВыбора; КонецФункции // РедактироватьДопустимыеТипы() // ПолноеИмяНачальногоТипаВыбора - Строка - полное имя метаданного Функция ОткрытьПодборСВыборомТипаЛкс(ВладелецФормы, ОписаниеТипов = Неопределено, Знач НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Истина) Экспорт Если ТипЗнч(ОписаниеТипов) = Тип("Строка") Тогда ДоступныеОбъекты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОписаниеТипов, ",", Истина); ИначеЕсли ОписаниеТипов <> Неопределено Тогда ДоступныеОбъекты = Новый Массив(); Для Каждого Тип Из ОписаниеТипов.Типы() Цикл ДоступныеОбъекты.Добавить(ПолучитьПолноеИмяМДТипаЛкс(Тип)); КонецЦикла; КонецЕсли; Если НачальноеЗначениеВыбора <> Неопределено Тогда ТипНачальногоЗначенияВыбора = ТипОбъектаБДЛкс(НачальноеЗначениеВыбора); ПолноеИмяНачальногоТипаВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипНачальногоЗначенияВыбора); КонецЕсли; Если Ложь Или ДоступныеОбъекты = Неопределено Или ДоступныеОбъекты.Количество() = 0 Или ДоступныеОбъекты.Количество() > 1 Тогда Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы); лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты); лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ПолноеИмяНачальногоТипаВыбора); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; Результат = Форма.ОткрытьМодально(); Если Результат = Неопределено Тогда Возврат Неопределено; КонецЕсли; ПолноеИмяМД = Результат.ПолноеИмяОбъекта; Иначе ПолноеИмяМД = ДоступныеОбъекты[0]; КонецЕсли; Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда Возврат Неопределено; КонецЕсли; Если ПолноеИмяНачальногоТипаВыбора <> ПолноеИмяМД Тогда НачальноеЗначениеВыбора = Неопределено; КонецЕсли; ТекущаяСтрока = Неопределено; Отбор = Неопределено; Если НачальноеЗначениеВыбора <> Неопределено Тогда ИмяXMLТипа = СериализаторXDTO.XMLТип(ТипНачальногоЗначенияВыбора).ИмяТипа; Если Ложь Или Найти(ИмяXMLТипа, "Ref.") > 0 Или Найти(ИмяXMLТипа, "RecordKey.") > 0 Тогда ТекущаяСтрока = НачальноеЗначениеВыбора; Иначе Отбор = НачальноеЗначениеВыбора.Методы.Отбор; КонецЕсли; КонецЕсли; ФормаВыбора = ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, Истина, Истина, ТекущаяСтрока); Возврат ФормаВыбора; КонецФункции Функция ПолучитьФормуВыбораОбъектаМетаданныхЛкс(ВладелецФормы, КлючУникальности, НачальноеЗначениеВыбора, МножественныйВыбор = Ложь, ОтображатьСсылочныеОбъекты = Ложь, ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь, ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь, ТолькоИспользованиеПолнотекстовогоПоиска = Ложь) Экспорт Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы, КлючУникальности); лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора); лСтруктураПараметров.Вставить("ОтображатьКонстанты", ОтображатьКонстанты); лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", ОтображатьВыборочныеТаблицы); лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", ОтображатьТаблицыИзменений); лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", ОтображатьТабличныеЧасти); лСтруктураПараметров.Вставить("ОтображатьРегистры", ОтображатьРегистры); лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ОтображатьПоследовательности); лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", ОтображатьСсылочныеОбъекты); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ОтображатьВнешниеИсточникиДанных); лСтруктураПараметров.Вставить("МножественныйВыбор", МножественныйВыбор); лСтруктураПараметров.Вставить("ЗапретитьВыбиратьСсылочныеОбъекты", ЗапретитьВыбиратьСсылочныеОбъекты); лСтруктураПараметров.Вставить("ТолькоИспользованиеПолнотекстовогоПоиска", ТолькоИспользованиеПолнотекстовогоПоиска); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; Возврат Форма; КонецФункции Функция ПолучитьФормуВыбораТаблицыСтруктурыБДЛкс(ЛиИменаБД, ИмяТаблицыХранения = "") Экспорт Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСтруктураХраненияБД.Форма",,, Истина); Форма.РежимВыбора = Истина; Форма.ПараметрИмяТаблицыХранения = ИмяТаблицыХранения; Форма.ПараметрПоказыватьSDBL = Не ЛиИменаБД; Форма.ПараметрПоказыватьСУБД = ЛиИменаБД; Возврат Форма КонецФункции Функция РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаXMLАлгоритма, ВнешниеПараметры = Неопределено) Экспорт СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма); Результат = РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры); Если Результат Тогда СтрокаXMLАлгоритма = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураАлгоритма); КонецЕсли; Возврат Результат; КонецФункции // Открыть редактирование текста алгоритма с параметрами в консоли кода // Парамерты: // СтруктураАлгоритма - Структура - возвращаемый // "ТекстАлгоритма" - Строка - текст алгоритма, // "ВнутренниеПараметры" - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внутренними (значения определяются при редактировании) параметрами алгоритма; // ВнешниеПараметры* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внешними (значения определяются при каждом выполнении) параметрами алгоритма; // Методы* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаМетодовПодсказкиЛкс с дополнительными методами доступными в алгоритме; // Результат - Булево - принял ли изменения пользователь Функция РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры = Неопределено, Методы = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ВнешниеПараметры = Новый ТаблицаЗначений; #КонецЕсли ОбработкаКонсольКода = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКода"); ФормаКонсоли = ОбработкаКонсольКода.ПолучитьФорму(); Если ВнешниеПараметры <> Неопределено Тогда КопияПараметров = ВнешниеПараметры.Скопировать(); Если КопияПараметров.Колонки.Найти("Значение") = Неопределено Тогда КопияПараметров.Колонки.Добавить("Значение"); КонецЕсли; Если КопияПараметров.Колонки.Найти("Фиксированный") = Неопределено Тогда КопияПараметров.Колонки.Добавить("Фиксированный"); КонецЕсли; КопияПараметров.ЗаполнитьЗначения(Истина, "Фиксированный"); ФормаКонсоли.мСписокВнешнихПараметров = КопияПараметров; КонецЕсли; Если СтруктураАлгоритма <> Неопределено Тогда Если СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда ФормаКонсоли.ПараметрТекст = СтруктураАлгоритма.ТекстАлгоритма; КонецЕсли; Если СтруктураАлгоритма.Свойство("ВнутренниеПараметры") Тогда ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, КопияПараметров, Новый Структура("Вход", Истина)); КонецЕсли; КонецЕсли; ФормаКонсоли.мМетоды = Методы; ФормаКонсоли.мРежимРедактора = Истина; ФормаКонсоли.ОткрытьМодально(); РезультатФормы = ФормаКонсоли.РезультатФормы; Результат = РезультатФормы <> Неопределено; Если Результат Тогда ВнутренниеПараметры = РезультатФормы.Параметры.Скопировать(Новый Структура("Вход, Выход, Фиксированный", Истина, Ложь, Ложь), "Имя, Значение"); СтруктураАлгоритма = Новый Структура("ТекстАлгоритма, ВнутренниеПараметры", РезультатФормы.Текст, ВнутренниеПараметры); КонецЕсли; Возврат Результат; КонецФункции // Конструктор таблицы параметров алгоритма // Результат - ТаблицаЗначений - колонки "Имя, Значение, Вход, Выход, ТипЗначения, Комментарий" Функция НоваяТаблицаПараметровАлгоритмаЛкс() Экспорт Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Значение"); Результат.Колонки.Добавить("Вход", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("Выход", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов")); Результат.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ТаблицаСтруктурТипов"); Возврат Результат; КонецФункции // Конструктор таблицы методов контекстной подсказки // Результат - ТаблицаЗначений - колонки "Имя, ТипЗначения" Функция НоваяТаблицаМетодовПодсказкиЛкс() Экспорт Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов")); Результат.Колонки.Добавить("ТаблицаСтруктурТипов"); Возврат Результат; КонецФункции Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П0 = null, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null) Экспорт СтрокаСобытия = ТаблицаСобытий.Найти(ИмяСобытия, "ИмяСобытия"); СтрокаXMLАлгоритма = СтрокаСобытия.Алгоритм; Если Не ЗначениеЗаполнено(СтрокаXMLАлгоритма) Тогда Возврат Истина; КонецЕсли; Если ТаблицаСобытий.Колонки.Найти("АлгоритмОбъект") = Неопределено Тогда ТаблицаСобытий.Колонки.Добавить("АлгоритмОбъект"); КонецЕсли; АлгоритмОбъект = СтрокаСобытия.АлгоритмОбъект; Если АлгоритмОбъект = Неопределено Тогда Попытка АлгоритмОбъект = ДесериализоватьАлгоритмОбъектЛкс(СтрокаXMLАлгоритма); Исключение ВызватьИсключение "Ошибка десериализации алгоритма для события " + ИмяСобытия + ": " + ОписаниеОшибки(); КонецПопытки; АлгоритмОбъект.Наименование = ИмяСобытия; ЗагрузитьВТаблицуЗначенийЛкс(СтрокаСобытия.Параметры, АлгоритмОбъект.Параметры); СтрокаСобытия.АлгоритмОбъект = АлгоритмОбъект; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Попытка Результат = мПлатформа.ВыполнитьМетодАлгоритма(АлгоритмОбъект, 0, П0, П1, П2, П3, П4, П5, П6, П7); Исключение //выхОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки()); выхОписаниеОшибки = ОписаниеОшибки(); Возврат Ложь; КонецПопытки; Возврат Истина; КонецФункции Функция ДесериализоватьАлгоритмОбъектЛкс(Знач СтрокаXMLАлгоритма) Экспорт СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма); АлгоритмОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторАлгоритмОбъект"); #Если Сервер И Не Сервер Тогда АлгоритмОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать(); #КонецЕсли АлгоритмОбъект.ТекстАлгоритма = СтруктураАлгоритма.ТекстАлгоритма; ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, АлгоритмОбъект.Параметры, Новый Структура("Вход", Истина)); Возврат АлгоритмОбъект; КонецФункции Процедура ОформитьЯчейкуАлгоритмаВТабличномПолеЛкс(Знач ОформлениеСтроки, ИмяКолонки = "Алгоритм") Экспорт Если ЗначениеЗаполнено(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки]) Тогда СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки],,, Ложь); Если СтруктураАлгоритма <> Неопределено И СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда ОформлениеСтроки.Ячейки[ИмяКолонки].УстановитьТекст(СокрП(СтруктураАлгоритма.ТекстАлгоритма)); КонецЕсли; КонецЕсли; КонецПроцедуры // ИсторияФайлов - СписокЗначений // Кнопки - КнопкиКоманднойПанели Процедура ОбновитьПодменюИсторииФайловЛкс(ИсторияФайлов, Кнопки, ИмяДействия = "ОткрытьФайлИзИстории") Экспорт Кнопки.Очистить(); ДлинаПредставления = 100; ДействиеКнопки = Новый Действие(ИмяДействия); Для Каждого СтрокаФайла Из ИсторияФайлов Цикл Файл = Новый Файл(СтрокаФайла.Значение); ДлинаПути = ДлинаПредставления - СтрДлина(Файл.Имя); Представление = Лев(Файл.Имя, ДлинаПредставления); Если ДлинаПути > 0 Тогда Если ДлинаПути < СтрДлина(Файл.Путь) + 3 Тогда Представление = Лев(Файл.Путь, ДлинаПути) + "...\" + Представление; Иначе Представление = Файл.Путь + Представление; КонецЕсли; КонецЕсли; КнопкаФайла = Кнопки.Добавить("_" + Формат(ИсторияФайлов.Индекс(СтрокаФайла), "ЧГ=;ЧН="), ТипКнопкиКоманднойПанели.Действие, Представление, ДействиеКнопки); КонецЦикла; КонецПроцедуры Процедура ДобавитьВИсториюЭлементЛкс(СписокИстории, ЗначениеЭлемента, РазмерИстории = 20) Экспорт ЭлементИстории = СписокИстории.НайтиПоЗначению(ЗначениеЭлемента); Если ЭлементИстории <> Неопределено Тогда СписокИстории.Удалить(ЭлементИстории); КонецЕсли; СписокИстории.Вставить(0, ЗначениеЭлемента); Пока СписокИстории.Количество() > РазмерИстории Цикл СписокИстории.Удалить(РазмерИстории); КонецЦикла; КонецПроцедуры Процедура ПоместитьТекстВБуферОбменаОСЛкс(Текст) Экспорт // http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241 Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов //Документ = Новый COMОбъект("HTMLFILE"); Окно = Документ.parentWindow; Окно.ClipboardData.SetData("Text", Текст); Конецпроцедуры Функция ПолучитьТекстИзБуфераОбменаОСЛкс() Экспорт // http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241 Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов //Документ = Новый COMОбъект("HTMLFILE"); Окно = Документ.parentWindow; Результат = Окно.ClipboardData.GetData("Text"); Возврат Результат; КонецФункции Функция ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ПолноеИмяМД) Экспорт Возврат ирОбщий.ВосстановитьЗначениеЛкс("ирДинамическийСписок.ВместоОсновной." + ПолноеИмяМД) <> Ложь; КонецФункции // УстановитьОбъектМетаданных() // Параметры: // Отбор - Структура, Отбор, *Неопределено Функция ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь, МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, Модально = Ложь, ПользовательскийОтбор = Неопределено) Экспорт ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор); Если ФормаСписка = Неопределено Тогда Возврат Неопределено; КонецЕсли; Если Модально Тогда Результат = ФормаСписка.ОткрытьМодально(); Возврат Результат; Иначе ФормаСписка.Открыть(); Возврат ФормаСписка; КонецЕсли; КонецФункции // Параметры: // Отбор - Структура, Отбор, *Неопределено Функция ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь, МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, ПользовательскийОтбор = Неопределено) Экспорт мПлатформа = ирКэш.Получить(); Если ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("ОбъектМетаданных") Тогда ИмяТаблицы = ИмяТаблицыИлиМДИлиТип.ПолноеИмя(); ИначеЕсли ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("Тип") Тогда ИмяТаблицы = ПолучитьПолноеИмяМДТипаЛкс(ИмяТаблицыИлиМДИлиТип); Иначе ИмяТаблицы = ИмяТаблицыИлиМДИлиТип; КонецЕсли; ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы); //МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД); Если Ложь Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Или ТипТаблицы = "Изменения" Или ТипТаблицы = "Перерасчет" //Или ТипТаблицы = "Внешняя" //Или МассивФрагментов.Количество() > 2 Тогда Сообщить("Для таблицы " + ИмяТаблицы + " форма списка не предусмотрена"); Возврат Неопределено; КонецЕсли; Если ИспользоватьДинамическийСписокИР = Неопределено Тогда ИспользоватьДинамическийСписокИР = ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ИмяТаблицы); КонецЕсли; Если Истина И РежимВыбора = Истина И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда ИспользоватьДинамическийСписокИР = Истина; // Потому что у форм списков регистров режим выбора можно включить только через основной элемент управления КонецЕсли; Если ТипТаблицы = "Точки" Тогда ИспользоватьДинамическийСписокИР = Истина; КонецЕсли; Если ИспользоватьДинамическийСписокИР = Неопределено Тогда Ответ = Вопрос("Хотите использовать Динамический список (ИР)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет); ИспользоватьДинамическийСписокИР = Ответ = КодВозвратаДиалога.Да; КонецЕсли; Если ПользовательскийОтбор <> Неопределено Тогда ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных; ПользовательскийОтборКомпоновки = ПользовательскиеНастройки.Элементы.Добавить(Тип("ОтборКомпоновкиДанных")); Если ТипЗнч(ПользовательскийОтбор) = Тип("Отбор") Тогда Для Каждого ЭлементОтбора Из ПользовательскийОтбор Цикл Если ЭлементОтбора.Использование Тогда СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель"); Если СтрокаВидаСравнения = Неопределено Тогда // %%%% Здесь можно добавить интеллекта Продолжить; КонецЕсли; НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ПользовательскийОтборКомпоновки, ЭлементОтбора.Имя, ЭлементОтбора.Значение, СтрокаВидаСравнения.Компоновка); КонецЕсли; КонецЦикла; Иначе СкопироватьОтборЛюбойЛкс(ПользовательскийОтборКомпоновки, ПользовательскийОтбор); КонецЕсли; КонецЕсли; Если ТипЗнч(Отбор) = Тип("Отбор") Тогда СтруктураОтбора = Новый Структура; Для Каждого ЭлементОтбора Из Отбор Цикл Если ЭлементОтбора.Использование Тогда Если ЭлементОтбора.ВидСравнения = ВидСравнения.Равно Тогда СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение); КонецЕсли; КонецЕсли; КонецЦикла; Иначе СтруктураОтбора = Отбор; КонецЕсли; ПараметрыФормы = Новый Структура("РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока, Отбор, ПользовательскиеНастройки", РежимВыбора, МножественныйВыбор, Не МножественныйВыбор, ТекущаяСтрока, СтруктураОтбора, ПользовательскиеНастройки); Если Истина И ИспользоватьДинамическийСписокИР И ТипТаблицы <> "Внешняя" Тогда КлючУникальности = ИмяТаблицы; ПараметрыФормы.Вставить("ИмяТаблицы", ИмяТаблицы); //Если Не РежимВыбора Тогда // КлючУникальности = Новый УникальныйИдентификатор; //КонецЕсли; ФормаСписка = ПолучитьФормуЛкс("Обработка.ирДинамическийСписок.Форма", ПараметрыФормы, ВладелецФормы, КлючУникальности); ФормаСписка.РежимВыбора = РежимВыбора; // Чтобы заголовок сразу правильный сформировался ФормаСписка.УстановитьОбъектМетаданных(ИмяТаблицы); ОтборДинамическогоСписка = ФормаСписка.Отбор(); ПользовательскийОтборДинамическогоСписка = ФормаСписка.ПользовательскийОтбор(); Иначе Если РежимВыбора Тогда Попытка ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаВыбора", ПараметрыФормы, ВладелецФормы); Исключение // Например у регистров нет форм выбора КонецПопытки; КонецЕсли; Если ФормаСписка = Неопределено Тогда ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаСписка", ПараметрыФормы, ВладелецФормы); КонецЕсли; Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда Попытка ОтборДинамическогоСписка = ФормаСписка.Отбор; Исключение КонецПопытки; КонецЕсли; КонецЕсли; Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда ФормаСписка.РежимВыбора = РежимВыбора; ФормаСписка.ЗакрыватьПриВыборе = Не МножественныйВыбор; ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока; Попытка ФормаСписка.МножественныйВыбор = МножественныйВыбор; Исключение // Есть не у всех форм КонецПопытки; Попытка ФормаСписка.ПараметрТекущаяСтрока = ТекущаяСтрока; Исключение // Есть не у всех форм КонецПопытки; КонецЕсли; Если Истина И ОтборДинамическогоСписка <> Неопределено И Отбор <> Неопределено Тогда СкопироватьОтборЛюбойЛкс(ОтборДинамическогоСписка, Отбор); КонецЕсли; Если Истина И ПользовательскийОтборДинамическогоСписка <> Неопределено И ПользовательскийОтбор <> Неопределено Тогда СкопироватьОтборЛюбойЛкс(ПользовательскийОтборДинамическогоСписка, ПользовательскийОтбор); КонецЕсли; Возврат ФормаСписка; КонецФункции Процедура ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(ПолеВвода, Знач КлючИстории, Знач ЗапоминатьПоследние = 20, Знач НеЗапоминатьПустыеТипизированные = Истина) Экспорт ЗначениеПоля = ДанныеЭлементаФормыЛкс(ПолеВвода); Если Ложь Или (Истина И Не НеЗапоминатьПустыеТипизированные И ЗначениеПоля <> ПолеВвода.ТипЗначения.ПривестиЗначение(Неопределено)) Или ЗначениеЗаполнено(ЗначениеПоля) Тогда НовоеЗначениеXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ЗначениеПоля); Если СтрДлина(НовоеЗначениеXML) > 1000 Тогда Возврат; КонецЕсли; Если ТипЗнч(КлючИстории) <> Тип("Строка") Тогда КлючИстории = ИмяФормыИзФормыЛкс(КлючИстории); КонецЕсли; КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения"; ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючНастройки); Если ТипЗнч(ПоследниеЗначения) <> Тип("Массив") Тогда ПоследниеЗначения = Новый Массив; КонецЕсли; ПоследниеЗначенияXML = Новый Массив; Для Каждого Значение Из ПоследниеЗначения Цикл ПоследниеЗначенияXML.Добавить(СохранитьОбъектВВидеСтрокиXMLЛкс(Значение)); КонецЦикла; Индекс = ПоследниеЗначенияXML.Найти(НовоеЗначениеXML); Если Индекс <> Неопределено Тогда ПоследниеЗначения.Удалить(Индекс); КонецЕсли; ПоследниеЗначения.Вставить(0, ЗначениеПоля); Для Счетчик = ЗапоминатьПоследние По ПоследниеЗначения.ВГраница() Цикл ПоследниеЗначения.Удалить(ЗапоминатьПоследние); КонецЦикла; СохранитьЗначениеЛкс(КлючНастройки, ПоследниеЗначения); ПолеВвода.СписокВыбора.Очистить(); Для Каждого Значение Из ПоследниеЗначения Цикл НовыйЭлемент = ПолеВвода.СписокВыбора.Добавить(Значение); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ПолеВводаСИсториейВыбора_НачалоВыбораИзСпискаЛкс(ПолеВвода, Знач КлючИстории) Экспорт // Запоминать последние Если ТипЗнч(КлючИстории) <> Тип("Строка") Тогда КлючИстории = ИмяФормыИзФормыЛкс(КлючИстории); КонецЕсли; КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения"; ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючНастройки); Если ТипЗнч(ПоследниеЗначения) = Тип("Массив") Тогда ПолеВвода.СписокВыбора.Очистить(); Для Каждого Значение Из ПоследниеЗначения Цикл НовыйЭлемент = ПолеВвода.СписокВыбора.Добавить(Значение); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт СтандартнаяОбработка = Ложь; ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); ВыборФайла.Каталог = Элемент.Значение; Если Не ВыборФайла.Выбрать() Тогда Возврат; КонецЕсли; ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, ВыборФайла.Каталог); КонецПроцедуры Функция ОткрытьСсылкуВСпискеЛкс(Ссылка) Экспорт ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя(); СтруктураПараметры = Новый Структура; СтруктураПараметры.Вставить("ТекущаяСтрока", Ссылка); ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор); ФормаСписка.Открыть(); Возврат ФормаСписка; КонецФункции // ИменаКолонок - Строка - имена колонок через запятую Процедура ТабличноеПоле_ОтобразитьФлажкиЛкс(ОформлениеСтроки, Знач ИменаКолонок) Экспорт Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина); КонецЕсли; Для Каждого ИмяКолонки Из ИменаКолонок Цикл Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки]; //Если Ячейка.ТолькоПросмотр Тогда // Продолжить; //КонецЕсли; Если ТипЗнч(Ячейка.Значение) = Тип("Булево") Тогда Ячейка.УстановитьФлажок(Ячейка.Значение); Ячейка.УстановитьТекст(""); КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ТабличноеПоле__ПриИзмененииФлажкаЛкс(Элемент, Знач Колонка) Экспорт Если ТипЗнч(Колонка.ЭлементУправления) = Тип("ПолеВвода") Тогда ОформлениеСтроки = Элемент.ОформлениеСтроки(Элемент.ТекущаяСтрока); Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя]; Если Не Ячейка.ТолькоПросмотр Тогда Если Истина И Колонка.Данные = "" И Колонка.ДанныеФлажка = "" Тогда Колонка.ЭлементУправления.Значение = Не Ячейка.Значение; //ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение); Иначе //МетаданныеТипа = глПолучитьМетаданныеТипа(ТипЗнч(Элемент.Значение), "ТипСписка", Истина); //РедактированиеВДиалоге = Ложь; //Если Истина // И МетаданныеТипа <> Неопределено // И МетаданныеТипа.КлассМетаданных.Предок = оСсылочный //Тогда // Попытка // ВыбранныйСпособРедактирования = Элемент.СпособРедактирования; // Исключение // КонецПопытки; // РедактированиеВДиалоге = ВыбранныйСпособРедактирования <> СпособРедактированияСписка.ВСписке; //КонецЕсли; //РазрешитьИзменение = Истина; //Если РедактированиеВДиалоге Тогда //Иначе //Элемент.ЗакончитьРедактированиеСтроки(Ложь); Элемент.ИзменитьСтроку(); ЗначениеЯчейки = Колонка.ЭлементУправления.Значение; Если ТипЗнч(ЗначениеЯчейки) = Тип("Булево") Тогда ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ЗначениеЯчейки, , , Ложь); //Элемент.ТекущаяКолонка = Колонка; КонецЕсли; Элемент.ЗакончитьРедактированиеСтроки(Ложь); //КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Функция ПолучитьПиктограммуТипаЛкс(Тип) Экспорт ИмяОбщегоТипа = Неопределено; КлючПоиска = Новый Структура("ИД", ПолучитьИдентификаторТипаЛкс(Тип)); мПлатформа = ирКэш.Получить(); мПлатформа.ИнициализацияОписанияМетодовИСвойств(); НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда ИмяОбщегоТипа = НайденныеСтроки[0].Слово; Иначе //СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип); //ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; ОбъектМД = Метаданные.НайтиПоТипу(Тип); Если ОбъектМД <> Неопределено Тогда ТекущееИмяТипа = ОбъектМД.ПолноеИмя(); ИмяОбщегоТипа = ПолучитьПервыйФрагментЛкс(ТекущееИмяТипа); КонецЕсли; КонецЕсли; Картинка = Неопределено; Если ИмяОбщегоТипа <> Неопределено Тогда ИмяКартинки = "ир" + ПолучитьПервыйФрагментЛкс(ИмяОбщегоТипа); Попытка Картинка = ПолучитьОбщуюКартинкуЛкс(ИмяКартинки); Исключение ИмяКартинки = ИмяОбщегоТипа; Попытка Картинка = БиблиотекаКартинок[ИмяКартинки]; Исключение КонецПопытки; КонецПопытки; КонецЕсли; Возврат Картинка; КонецФункции Функция ПрочитатьДополнительныеПоляСсылающихсяОбъектовЛкс(Знач ТабличноеПоле, Знач КомпоновщикДопПолей, Знач ТаблицаДанных = Неопределено, ИмяПоляСсылки = "Данные") Экспорт #Если Сервер И Не Сервер Тогда КомпоновщикДопПолей = Новый КомпоновщикНастроекКомпоновкиДанных; #КонецЕсли Если ТаблицаДанных = Неопределено Тогда ТаблицаДанных = ДанныеЭлементаФормыЛкс(ТабличноеПоле); КонецЕсли; КомпоновщикДопПолей.Восстановить(СпособВосстановленияНастроекКомпоновкиДанных.Полное); МассивДопПолей = Новый Структура(); ДопустимоеЧислоДопПолей = 5; Счетчик = 1; СтрокаПорядка = ""; СтрокаВыбора = ""; Для Каждого ПолеПорядка Из КомпоновщикДопПолей.Настройки.Порядок.Элементы Цикл Если ПолеПорядка.Использование Тогда ИмяПоля = "" + ПолеПорядка.Поле; ИмяКолонки = "Реквизит" + Счетчик; ДоступноеПоле = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(ПолеПорядка.Поле); Если Счетчик > ДопустимоеЧислоДопПолей Тогда Сообщить("Дополнительное поле """ + ДоступноеПоле.Заголовок + """ пропущено, т.к. допускается не более " + ДопустимоеЧислоДопПолей + " полей"); Продолжить; КонецЕсли; МассивДопПолей.Вставить(ИмяКолонки, ИмяПоля); КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки]; КолонкаТП.Видимость = Истина; КолонкаТП.ТекстШапки = ДоступноеПоле.Заголовок; Если СтрокаПорядка <> "" Тогда СтрокаПорядка = СтрокаПорядка + ","; КонецЕсли; СтрокаПорядка = СтрокаПорядка + ИмяКолонки + " "; Если ПолеПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда СтрокаПорядка = СтрокаПорядка + "Возр"; Иначе СтрокаПорядка = СтрокаПорядка + "Убыв"; КонецЕсли; СтрокаВыбора = СтрокаВыбора + ", | Т." + ИмяПоля + " КАК " + ИмяКолонки; Счетчик = Счетчик + 1; КонецЕсли; КонецЦикла; Если Не ЗначениеЗаполнено(СтрокаПорядка) Тогда СтрокаПорядка = "Дата"; КонецЕсли; Для Счетчик = Счетчик По ДопустимоеЧислоДопПолей Цикл ИмяКолонки = "Реквизит" + Счетчик; Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки]; Иначе КолонкаТП = ТабличноеПоле.ПодчиненныеЭлементы[ТабличноеПоле.Имя + ИмяКолонки]; КонецЕсли; КолонкаТП.Видимость = Ложь; КонецЦикла; СтандартныеРеквизиты = Новый Структура; СтандартныеРеквизиты.Вставить("ПометкаУдаления", "ЛОЖЬ"); СтандартныеРеквизиты.Вставить("Проведен", "ЛОЖЬ"); СтандартныеРеквизиты.Вставить("ЭтоГруппа", "ЛОЖЬ"); СтандартныеРеквизиты.Вставить("Дата", "ДАТАВРЕМЯ(1,1,1)"); Для Каждого КлючИЗначение Из СтандартныеРеквизиты Цикл ИмяРеквизита = КлючИЗначение.Ключ; Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект." + ИмяРеквизита)) = Неопределено Тогда Продолжить; КонецЕсли; СтрокаВыбора = СтрокаВыбора + ", | ЕСТЬNULL(Т.Объект." + ИмяРеквизита + ", " + КлючИЗначение.Значение + ") КАК " + ИмяРеквизита; КонецЦикла; Если ТипЗнч(ТаблицаДанных) <> Тип("ТаблицаЗначений") Тогда //КопияТаблицыДанных = ТаблицаДанных.Выгрузить(, ИмяПоляСсылки); КопияТаблицыДанных = ТаблицаЗначенийИзТабличногоПоляЛкс(ТабличноеПоле); Иначе КопияТаблицыДанных = ТаблицаДанных; КонецЕсли; КопияТаблицыДанных = ирОбщий.ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КопияТаблицыДанных,, ИмяПоляСсылки); ОписаниеТиповСсылки = КопияТаблицыДанных.Колонки[ИмяПоляСсылки].ТипЗначения; ПорцияОбъектов = Новый ТаблицаЗначений; ПорцияОбъектов.Колонки.Добавить("Объект", ОписаниеТиповСсылки); ПорцияОбъектов.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число")); РазмерПорции = 10000; КоличествоПорций = Цел(ТаблицаДанных.Количество() / РазмерПорции) + 1; Запрос = Новый Запрос; ТекстЗапроса = " |ВЫБРАТЬ Т.* ПОМЕСТИТЬ Т ИЗ &Т КАК Т; |ВЫБРАТЬ Т.Объект, Т.Индекс" + СтрокаВыбора + " |ИЗ Т КАК Т"; Запрос.Текст = ТекстЗапроса; ИндексСтроки = 0; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоПорций, "Чтение дополнительных полей"); ДоступноеПолеОбъект = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект")); Для СчетчикПорций = 1 По КоличествоПорций Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); ПорцияОбъектов.Очистить(); Для Счетчик = 1 По РазмерПорции Цикл Если ИндексСтроки = ТаблицаДанных.Количество() Тогда Прервать; КонецЕсли; СтрокаОбъекта = ТаблицаДанных[ИндексСтроки]; ИндексСтроки = ИндексСтроки + 1; Если Ложь Или ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]) = Тип("Строка") Или СтрокаОбъекта[ИмяПоляСсылки] = Неопределено Или ДоступноеПолеОбъект = Неопределено Или Не ДоступноеПолеОбъект.ТипЗначения.СодержитТип(ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки])) Тогда СтрокаОбъекта.ИндексКартинки = 12; // Регистр сведений Продолжить; КонецЕсли; СтрокаПорции = ПорцияОбъектов.Добавить(); СтрокаПорции.Объект = СтрокаОбъекта[ИмяПоляСсылки]; СтрокаПорции.Индекс = ИндексСтроки - 1; КонецЦикла; Запрос.УстановитьПараметр("Т", ПорцияОбъектов); РезультатЗапроса = Запрос.Выполнить(); РеквизитыПорции = РезультатЗапроса.Выгрузить(); Для Каждого СтрокаПорции Из РеквизитыПорции Цикл СтрокаОбъекта = ТаблицаДанных[СтрокаПорции.Индекс]; СтрокаОбъекта.ИндексКартинки = ирОбщий.ПолучитьИндексКартинкиСсылкиЛкс(СтрокаПорции.Объект, Истина, СтрокаПорции); ЗаполнитьЗначенияСвойств(СтрокаОбъекта, СтрокаПорции); КонецЦикла; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); СтрокаПорядка = "Метаданные," + СтрокаПорядка; Возврат СтрокаПорядка; КонецФункции Процедура ОбновитьДоступныеПоляДляДополнительныхПолейЛкс(Знач ТаблицаДанных, Знач КомпоновщикДопПолей, Знач ТабличноеПолеДоступныхПолей) Экспорт //Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() = 0 Тогда Если ТипЗнч(ТаблицаДанных) = Тип("ТаблицаЗначений") Тогда ПолныеИменаМД = ТаблицаДанных.Скопировать(, "Метаданные"); Иначе ПолныеИменаМД = ТаблицаДанных.Выгрузить(, "Метаданные"); КонецЕсли; ПолныеИменаМД.Свернуть("Метаданные"); ПолныеИменаМД = ПолныеИменаМД.ВыгрузитьКолонку(0); МассивТипов = Новый Массив(); Для Каждого ПолноеИмяМД Из ПолныеИменаМД Цикл Если ТипЗнч(ПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда ПолноеИмяМД = ПолноеИмяМД.ПолноеИмя(); КонецЕсли; Попытка Тип = Тип(ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД)); Исключение Продолжить; КонецПопытки; МассивТипов.Добавить(Тип); КонецЦикла; Если МассивТипов.Количество() > 0 Тогда КоллекцияПолей = Новый Массив(); КоллекцияПолей.Добавить(Новый Структура("Имя, ТипЗначения", "Объект", Новый ОписаниеТипов(МассивТипов))); ТекстЗапроса = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей); СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиПоЗапросуЛкс(ТекстЗапроса); Иначе СхемаКомпоновки = Новый СхемаКомпоновкиДанных; КонецЕсли; Если ТипЗнч(ТабличноеПолеДоступныхПолей) = Тип("ТабличноеПоле") Тогда ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки); Иначе ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПолеДоступныхПолей); ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПоместитьВоВременноеХранилище(СхемаКомпоновки), ЭтаФорма.УникальныйИдентификатор); КонецЕсли; КомпоновщикДопПолей.Инициализировать(ИсточникДоступныхНастроек); Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() > 0 Тогда #Если Клиент И Не Сервер Тогда ТабличноеПолеДоступныхПолей.Развернуть(КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы[0]); #КонецЕсли КонецЕсли; //КонецЕсли; КонецПроцедуры // ИменаКолонок - Строка - имена колонок через запятую Процедура ТабличноеПоле_ОтобразитьПиктограммыТиповЛкс(ОформлениеСтроки, ИменаКолонок) Экспорт Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина); КонецЕсли; Для Каждого ИмяКолонки Из ИменаКолонок Цикл Ячейка = ОформлениеСтроки.Ячейки.Найти(ИмяКолонки); //:Ячейка=Новый("ОформлениеЯчейки") Если Ячейка <> Неопределено Тогда ДанныеКартинки = Ячейка.Значение; Если ТипЗнч(ДанныеКартинки) = Тип("ПолеКомпоновкиДанных") Тогда Продолжить; КонецЕсли; СсылкаКартинка = Неопределено; ТипЗначения = ТипЗнч(ДанныеКартинки); Если Истина И ТипЗначения = Тип("Булево") И Ячейка.ОтображатьФлажок Тогда Продолжить; КонецЕсли; КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения); Если КартинкаТипа <> Неопределено Тогда Ячейка.УстановитьКартинку(КартинкаТипа); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Функция ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ТабличноеПоле); //ТипЗначенияТабличногоПоля = ТипЗнч(ИсточникДействий.Значение); //ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаИзКонкретногоТипа, ТипЗначенияТабличногоПоля); Попытка Количество = ЗначениеЭУ.Количество(); Попытка Отбор = ТабличноеПоле.ОтборСтрок; Исключение КонецПопытки; Исключение Попытка //Коллекция компоновки Количество = ЗначениеЭУ.Элементы.Количество(); //Суффикс = "*"; Исключение Попытка //Или ИмяОбщегоТипа = "ДеревоЗначений" Количество = ЗначениеЭУ.Строки.Количество(); Суффикс = "*"; Исключение // ДинамическийСписок ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); ИмяСлужебногоПоля = "СлужебноеПоле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); НовыйМассив.Добавить(Элемент); КонецЦикла; Возврат НовыйМассив; КонецФункции Функция ПолучитьСтруктуруВосстановленияКонсолиЛкс(ИмяИлиОбъектКонсоли) Экспорт Если ТипЗнч(ИмяИлиОбъектКонсоли) = Тип("Строка") Тогда ИмяКонсоли = ИмяИлиОбъектКонсоли; Иначе ИмяКонсоли = ИмяИлиОбъектКонсоли.Метаданные().Имя; КонецЕсли; Структура = Новый Структура(); Структура.Вставить("БлокировкаВосстановления", Неопределено); ПрефиксИмениФайлаВосстановления = ИмяКонсоли + "_" + ИмяПользователя() + "_"; Структура.Вставить("ПрефиксИмениФайлаВосстановления", ПрефиксИмениФайлаВосстановления); ИмяФайлаВосстановления = ирКэш.Получить().КаталогФайловогоКэша + "\" + ПрефиксИмениФайлаВосстановления + Формат(НомерСеансаИнформационнойБазы(), "ЧЦ=8; ЧВН=; ЧГ=") + ".tmp"; Структура.Вставить("ФайлВосстановления", Новый Файл(ИмяФайлаВосстановления)); Возврат Структура; КонецФункции Функция СохранитьФайлВКонсолиСВосстановлениемЛкс(ДиалогВыбораФайла, Знач ИмяСохраняемогоФайла, ИмяОткрытогоФайла = "", ДанныеДляФайла, СтруктураВосстановления, ЗапрашиватьИмяФайла = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ДиалогВыбораФайла = Новый ДиалогВыбораФайла(); #КонецЕсли ФайлВосстановления = СтруктураВосстановления.ФайлВосстановления; ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления; БлокировкаВосстановления = СтруктураВосстановления.БлокировкаВосстановления; СохранитьФайл = Истина; Если НРег(ИмяСохраняемогоФайла) <> НРег(ФайлВосстановления.ПолноеИмя) Тогда // Здесь можно вставить проверочную сериализацию+десериализацию ФайлВыбран = Истина; лФайл = Новый Файл(ИмяОткрытогоФайла); ДиалогВыбораФайла.ПолноеИмяФайла = ИмяСохраняемогоФайла; Если Ложь Или ПустаяСтрока(ИмяСохраняемогоФайла) Или ЗапрашиватьИмяФайла Или Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда Пока Истина Цикл Если ДиалогВыбораФайла.Выбрать() Тогда лФайл = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла); Если Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда КодОтвета = Вопрос("Это имя файла зарезервировано. Хотите выбрать другое?", РежимДиалогаВопрос.ОКОтмена); Если КодОтвета = КодВозвратаДиалога.ОК Тогда Продолжить; Иначе ФайлВыбран = Ложь; Прервать; КонецЕсли; КонецЕсли; ИмяСохраняемогоФайла = ДиалогВыбораФайла.ПолноеИмяФайла; ФайлВыбран = Истина; Прервать; Иначе ФайлВыбран = Ложь; СохранитьФайл = Ложь; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Иначе ФайлВыбран = Ложь; КонецЕсли; Если СохранитьФайл Тогда Если Истина И НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) И БлокировкаВосстановления <> Неопределено Тогда БлокировкаВосстановления = Неопределено; КонецЕсли; Если Не ЗначениеВФайл(ИмяСохраняемогоФайла, ДанныеДляФайла) Тогда Сообщить("Ошибка записи файла """ + ИмяСохраняемогоФайла + """", СтатусСообщения.Внимание); ФайлВыбран = Ложь; КонецЕсли; Если НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) Тогда БлокировкаВосстановления = Новый ЗаписьТекста(ИмяСохраняемогоФайла,,,Истина); КонецЕсли; КонецЕсли; Возврат ФайлВыбран; КонецФункции Функция ПроверитьВыбратьФайлВосстановленияКонсолиЛкс(СтруктураВосстановления) Экспорт ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления; СписокВосстановления = Новый СписокЗначений; ФайлыВосстановления = НайтиФайлы(ирКэш.Получить().КаталогФайловогоКэша, ПрефиксИмениФайлаВосстановления + "*.tmp"); Для Каждого ФайлВосстановления Из ФайлыВосстановления Цикл #Если Сервер И Не Сервер Тогда ФайлВосстановления = Новый Файл(); #КонецЕсли Попытка ФайлВосстановления.УстановитьВремяИзменения(ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс()); //Пустышка = Новый ЗаписьТекста(ФайлВосстановления.ПолноеИмя, , , Истина); Исключение // Файла заблокирован и значит сессия продолжается. Продолжить; КонецПопытки; СписокВосстановления.Добавить(ФайлВосстановления.ПолноеИмя, "" + (ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс()) + " - " + ФайлВосстановления.ИмяБезРасширения); КонецЦикла; ИмяФайлаВосстановления = ""; Если СписокВосстановления.Количество() > 0 Тогда СписокВосстановления.СортироватьПоПредставлению(НаправлениеСортировки.Убыв); СписокВосстановления.Добавить("<Удалить все файлы восстановления>"); ВыбранныйЭлемент = СписокВосстановления.ВыбратьЭлемент("Вы можете открыть файл восстановления прерванной сессии"); Если ВыбранныйЭлемент <> Неопределено Тогда Если ВыбранныйЭлемент.Значение = "<Удалить все файлы восстановления>" Тогда Для Каждого ЭлементСписка Из СписокВосстановления Цикл Если ВыбранныйЭлемент = ЭлементСписка Тогда Продолжить; КонецЕсли; УдалитьФайлы(ЭлементСписка.Значение); КонецЦикла; Иначе ИмяФайлаВосстановления = ВыбранныйЭлемент.Значение; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИмяФайлаВосстановления; КонецФункции Процедура УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(СтруктураВосстановления) Экспорт СтруктураВосстановления.БлокировкаВосстановления = Неопределено; Попытка УдалитьФайлы(СтруктураВосстановления.ФайлВосстановления.ПолноеИмя); Исключение КонецПопытки; КонецПроцедуры Процедура СчитатьПорциюВыборкиВТаблицуЛкс(Выборка, ТаблицаПриемник, Знач РазмерПорции = 9999, СчитыватьЧерезКопиюТаблицы = Истина, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый Запрос; Выборка = Пустышка.Выполнить(); #КонецЕсли Если СчитыватьЧерезКопиюТаблицы Тогда // Иначе добавление и заполнение строк при связи с табличным полем будет дольше выполняться КопияТаблицыПриемника = ТаблицаПриемник.Скопировать(); Если СсылкаНаБуфернуюТаблицу <> Неопределено Тогда СсылкаНаБуфернуюТаблицу.Вставить("Таблица", КопияТаблицыПриемника); КонецЕсли; Иначе КопияТаблицыПриемника = ТаблицаПриемник; КонецЕсли; КоличествоРезультата = Выборка.Количество(); Несчитано = КоличествоРезультата - КопияТаблицыПриемника.Количество(); Если Ложь Или РазмерПорции > Несчитано Или РазмерПорции = 0 Тогда РазмерПорции = Несчитано; КонецЕсли; Если Несчитано = РазмерПорции Тогда ПредставлениеПроцесса = "Загрузка выборки"; Иначе ПредставлениеПроцесса = "Загрузка порции выборки"; КонецЕсли; #Если Клиент Тогда Индикатор = ПолучитьИндикаторПроцессаЛкс(РазмерПорции, ПредставлениеПроцесса); #КонецЕсли КолонкиВложенныхТаблиц = Новый Массив(); Для Каждого Колонка Из Выборка.Владелец().Колонки Цикл Если Колонка.ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда КолонкиВложенныхТаблиц.Добавить(Колонка.Имя); КонецЕсли; КонецЦикла; ЕстьКолонкиВложенныхТаблиц = КолонкиВложенныхТаблиц.Количество() > 0; РазмерПорцииОсталось = РазмерПорции; Пока Выборка.Следующий() Цикл НоваяСтрока = КопияТаблицыПриемника.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка); Если ЕстьКолонкиВложенныхТаблиц Тогда Для Каждого КолонкаВложеннойТаблицы Из КолонкиВложенныхТаблиц Цикл НоваяСтрока[КолонкаВложеннойТаблицы] = Выборка[КолонкаВложеннойТаблицы].Выгрузить(); КонецЦикла; КонецЕсли; Если РазмерПорцииОсталось > 0 Тогда РазмерПорцииОсталось = РазмерПорцииОсталось - 1; Если РазмерПорцииОсталось = 0 Тогда Прервать; КонецЕсли; КонецЕсли; #Если Клиент Тогда ОбработатьИндикаторЛкс(Индикатор); #КонецЕсли КонецЦикла; Если РазмерПорции = Несчитано Тогда Выборка = Неопределено; КонецЕсли; #Если Клиент Тогда ОсвободитьИндикаторПроцессаЛкс(); #КонецЕсли ТаблицаПриемник = КопияТаблицыПриемника; КонецПроцедуры // СчитатьПорциюРезультата() // ТабличноеПоле определяется как источник действий командной панели. // Параметру ВыборкаРезультата внутри присваивается значение! Процедура ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатЗапроса, ВыборкаРезультата, КоманднаяПанель, ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", БезопасныйПорогКоличестваСтрок = 100000, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда лЗапрос = Новый Запрос; РезультатЗапроса = лЗапрос.Выполнить(); #КонецЕсли //БезопасныйПорогКоличестваСтрок = 1; // Для отладки ВыборкаРезультата = РезультатЗапроса.Выбрать(); ТабличноеПоле = КоманднаяПанель.ИсточникДействий; Если Ложь Или БезопасныйПорогКоличестваСтрок = 0 Или ВыборкаРезультата.Количество() < БезопасныйПорогКоличестваСтрок Тогда ВыборкаРезультата = Неопределено; КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Ложь; ТабличноеПоле.Значение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой); Попытка Выполнить("ЭтаФорма." + ИмяОбработчикаОбновления + "()"); Исключение ВызватьИсключение ОписаниеОшибки(); КонецПопытки; Иначе ТабличноеПоле.Значение = Новый ТаблицаЗначений; Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл ТипЗначения = Колонка.ТипЗначения; Если ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений"); КонецЕсли; ТабличноеПоле.Значение.Колонки.Добавить(Колонка.Имя, ТипЗначения, Колонка.Имя, Колонка.Ширина); КонецЦикла; ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина); СчитатьПорциюВыборкиВТаблицуЛкс(ВыборкаРезультата, ТабличноеПоле.Значение, БезопасныйПорогКоличестваСтрок, , СсылкаНаБуфернуюТаблицу); КонецЕсли; КонецПроцедуры // ТабличноеПоле определяется как источник действий командной панели. Процедура ЗагрузитьВыборкуВТабличноеПолеПолностьюЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина); ТабличноеПоле = КоманднаяПанель.ИсточникДействий; СчитатьПорциюВыборкиВТаблицуЛкс(мВыборкаРезультата, ТабличноеПоле.Значение, 0, , СсылкаНаБуфернуюТаблицу); КонецПроцедуры // Параметру КоличествоРезультата внутри присваивается значение! Процедура ПослеЗагрузкиВыборкиВТабличноеПолеЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт ТабличноеПоле = КоманднаяПанель.ИсточникДействий; Если ТипЗнч(мВыборкаРезультата) = Тип("COMОбъект") Тогда КоличествоРезультата = 0; Попытка КоличествоРезультата = мВыборкаРезультата.Count; Исключение Если мВыборкаРезультата.State <> 0 Тогда КоличествоРезультата = мВыборкаРезультата.RecordCount; КонецЕсли; КонецПопытки; ВсеСчитано = КоличествоРезультата = ТабличноеПоле.Значение.Количество(); ИначеЕсли ТипЗнч(мВыборкаРезультата) = Тип("ВыборкаИзРезультатаЗапроса") Тогда КоличествоРезультата = мВыборкаРезультата.Количество(); Если СсылкаНаБуфернуюТаблицу <> Неопределено И СсылкаНаБуфернуюТаблицу.Свойство("Таблица") Тогда ТабличноеПоле.Значение = СсылкаНаБуфернуюТаблицу.Таблица; КонецЕсли; ВсеСчитано = Ложь; Иначе КоличествоРезультата = ТабличноеПоле.Значение.Количество(); ВсеСчитано = Истина; КонецЕсли; ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, ТабличноеПоле.Значение.Количество(), КоличествоРезультата, ВсеСчитано); КонецПроцедуры Функция ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(ПолноеИмяТаблицы, ИмяКолонки, ЗначениеОтбора, МаксимальнаяПорция = 0) Экспорт ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицы); #Если Сервер И Не Сервер Тогда ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки; #КонецЕсли ТекстПоля = ""; ПсевдонимТаблицы = "Т"; Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл Если Ложь Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Продолжить; КонецЕсли; Если ЗначениеЗаполнено(ТекстПоля) Тогда ТекстПоля = ТекстПоля + ", "; КонецЕсли; ТекстПоля = ТекстПоля + ПсевдонимТаблицы + "." + ПолеТаблицыБД.Имя; КонецЦикла; ТекстПервые = ""; Если МаксимальнаяПорция > 0 Тогда ТекстПервые = " ПЕРВЫЕ " + Формат(МаксимальнаяПорция, "ЧГ=") + " "; КонецЕсли; ТекстЗапроса = " |ВЫБРАТЬ " + ТекстПервые + " " + ТекстПоля + " |ИЗ " + ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяТаблицы) + " КАК " + ПсевдонимТаблицы + " |{ГДЕ " + ПсевдонимТаблицы + "." + ИмяКолонки + "}"; Построитель = Новый ПостроительЗапроса(ТекстЗапроса); Если ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда ЭлементОтбора = Построитель.Отбор.Добавить(ИмяКолонки); ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке; ЭлементОтбора.Значение = ЗначениеОтбора; ЭлементОтбора.Использование = Истина; Иначе Построитель.Отбор.Добавить(ИмяКолонки).Установить(ЗначениеОтбора); КонецЕсли; Возврат Построитель; КонецФункции Функция ЗагрузитьСвязанныеСтрокиТаблицыБДЛкс(ЭтаФорма, ТабличноеПолеСвязанныхКолонок, ТабличноеПолеСвязанныхСтрок, КоманднаяПанельСвязанныхСтрок, мВыборкаРезультатаСтрокиТаблицы, ЗначениеОтбора) Экспорт СтрокаСвязаннойКолонки = ТабличноеПолеСвязанныхКолонок.ТекущаяСтрока; Если СтрокаСвязаннойКолонки = Неопределено Тогда Возврат Неопределено; КонецЕсли; ЭтаФорма.СтрокиТаблицыБД = Новый ТаблицаЗначений; ТабличноеПолеСвязанныхСтрок.СоздатьКолонки(); //Если ЗначениеОтбора = Неопределено Тогда // ЗначениеОтбора = СтрокаСвязаннойКолонки.Ссылка; //КонецЕсли; Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора); //ЧислоСтрокДляЗагрузки = ирОбщий.КонтрольРазмераВыборкиПользователемЛкс(Построитель); //Если ЧислоСтрокДляЗагрузки > 0 Тогда // Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора, ЧислоСтрокДляЗагрузки); //КонецЕсли; //// http://partners.v8.1c.ru/forum/thread.jsp?id=1034151#1034151 ////МаксимальныйРазмер = 500000; ////Построитель = ПолучитьПостроительВыборкиСвязанныхСтрок(, МаксимальныйРазмер); // Антибаг 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1017264#1017264 Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда Если Истина И СтрокаСвязаннойКолонки.ТипТаблицы = "Изменения" И Найти(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, "РегистрСведений.") = 1 Тогда Если Метаданные.ОбщиеРеквизиты.Количество() > 0 Тогда Возврат Неопределено; КонецЕсли; //Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл // ВыбранноеПоле = Построитель.ВыбранныеПоля.Найти(ОбщийРеквизит.Имя); // Если Истина // И ВыбранноеПоле <> Неопределено // И ОбъектМетаданных.Измерения.Найти(ОбщийРеквизит.Имя) = Неопределено // Тогда // Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда // Построитель.ВыбранныеПоля.Удалить(ВыбранноеПоле); // КонецЕсли; // КонецЕсли; //КонецЦикла; КонецЕсли; КонецЕсли; Попытка РезультатСтрокиТаблицы = Построитель.Результат; Исключение // Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1031481#1031481 Сообщить(ОписаниеОшибки()); Возврат Неопределено; КонецПопытки; ирОбщий.ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатСтрокиТаблицы, мВыборкаРезультатаСтрокиТаблицы, КоманднаяПанельСвязанныхСтрок); //Если СтрокиТаблицыБД.Количество() = МаксимальныйРазмер Тогда // Сообщить("Были выбраны первые " + МаксимальныйРазмер + " строк таблицы"); //КонецЕсли; СтруктураОтбора = Новый Структура("ПолноеИмяТаблицы, ИмяКолонки", СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки); ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаСвязаннойКолонки); ТабличноеПолеСвязанныхСтрок.СоздатьКолонки(); ТабличноеПолеСвязанныхСтрок.ТекущаяКолонка = ТабличноеПолеСвязанныхСтрок.Колонки[СтрокаСвязаннойКолонки.ИмяКолонки]; Для Каждого КолонкаТП Из ТабличноеПолеСвязанныхСтрок.Колонки Цикл КолонкаТП.ТолькоПросмотр = Истина; КонецЦикла; Попытка ИскомаяСсылка = СтрокаСвязаннойКолонки.Ссылка Исключение ИскомаяСсылка = Неопределено; КонецПопытки; Если ИскомаяСсылка <> Неопределено Тогда ТекущаяСтрока = ТабличноеПолеСвязанныхСтрок.Значение.Найти(ИскомаяСсылка, СтрокаСвязаннойКолонки.ИмяКолонки); Если ТекущаяСтрока <> Неопределено Тогда ТабличноеПолеСвязанныхСтрок.ТекущаяСтрока = ТекущаяСтрока; КонецЕсли; КонецЕсли; Возврат СтрокаСвязаннойКолонки.ПолноеИмяТаблицы; КонецФункции Процедура ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоЗагружено, КоличествоРезультата, ВсеСчитано) Экспорт Если ВсеСчитано Тогда СтрокаКоличествоРезультата = "" + КоличествоЗагружено; ПолеСтрокиКоличестваРезультата.ЦветФона = Новый Цвет(); Иначе СтрокаКоличествоРезультата = "" + КоличествоЗагружено + "/" + КоличествоРезультата; ПолеСтрокиКоличестваРезультата.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаВычисляемогоЗначения"); КонецЕсли; ПолеСтрокиКоличестваРезультата.Значение = СтрокаКоличествоРезультата; КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Не ВсеСчитано; КонецПроцедуры // Формирует макет компоновки и извлекает из него запрос // Параметры: // Схема - СхемаКомпоновкиДанных // НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных // ДобавлятьУпорядочивание - Булево // ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один // выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура, // где ключи - имена колонок, а значения - полные имена полей // // Результат - Запрос // Функция ПолучитьЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновкиДанных, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "", ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт НастройкаКомпоновкиДанных = ПолучитьКопиюОбъектаЛкс(НастройкаКомпоновкиДанных); #Если Сервер И Не Сервер Тогда НастройкаКомпоновкиДанных = Новый НастройкиКомпоновкиДанных #КонецЕсли Если НастройкаКомпоновкиДанных.Структура.Количество() = 0 Тогда НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура); КонецЕсли; Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ДобавитьВыбранноеПоле); КонецЕсли; Если Не СПредставлениямиСсылок Тогда Для Каждого ВыбранноеПоле Из НастройкаКомпоновкиДанных.Выбор.Элементы Цикл Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда ВызватьИсключение "Неподдерживаемый тип выбранного поля - " + ТипЗнч(ВыбранноеПоле); КонецЕсли; Если ВыбранноеПоле.Использование Тогда НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации КонецЕсли; КонецЦикла; НастройкаКомпоновкиДанных.Выбор.Элементы.Очистить(); КонецЕсли; СтрокаПорядка = ПолучитьСтрокуПорядкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Порядок); НастройкаКомпоновкиДанных.Порядок.Элементы.Очистить(); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновкиДанных, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей); Запрос = Новый Запрос; Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда Сообщить("В макете компоновки обнаружено более одного запроса"); КонецЕсли; ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос; Если ДобавлятьУпорядочивание Тогда Если ЗначениеЗаполнено(СтрокаПорядка) Тогда ТекстЗапроса = ТекстЗапроса + " |//Секция_Упорядочить. Этот комментарий используется в коде |УПОРЯДОЧИТЬ ПО | " + СтрокаПорядка; КонецЕсли; Если Ложь Или Автоупорядочивание //Или ЗначениеЗаполнено(СтрокаПорядка) Тогда ТекстЗапроса = ТекстЗапроса + " |//Секция_Упорядочить. Этот комментарий используется в коде |АВТОУПОРЯДОЧИВАНИЕ"; КонецЕсли; КонецЕсли; Запрос.Текст = ТекстЗапроса; Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение); КонецЦикла; Если ПрефиксИменПараметров <> "" Тогда ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров); КонецЕсли; Если выхСхемаКолонок <> Неопределено Тогда //выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки); // НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0]; Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным); КонецЦикла; Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным); КонецЦикла; КонецЕсли; Возврат Запрос; КонецФункции Функция ПолучитьТекстОтбораЗапросаКомпоновкиЛкс(ЗапросСОтбором, ПсевдонимТаблицыПередГДЕ = "Т") Экспорт ТекстОтбораДублей = ПолучитьПоследнийФрагментЛкс(ЗапросСОтбором.Текст, "КАК " + ПсевдонимТаблицыПередГДЕ + " |ГДЕ", Ложь); Если Не ЗначениеЗаполнено(ТекстОтбораДублей) Тогда ТекстОтбораДублей = " ИСТИНА "; КонецЕсли; Возврат ТекстОтбораДублей; КонецФункции // Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений. // Параметры: // СхемаКомпоновки - СхемаКомпоновкиДанных // НастройкаКомпоновки - НастройкиКомпоновкиДанных // КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений // ВнешниеНаборыДанных - Структура // ТолькоСоздатьКолонки - Булево // СхемаКолонок - Структура - Если Неопределено, то не возвращается // МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено. // ОтключитьОбщиеИтоги - Булево // РежимОтладки - Булево // Функция СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(Знач СхемаКомпоновки, Знач НастройкаКомпоновки, КоллекцияЗначений = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, Знач ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено, Знач МаксимальноеЧислоСтрокРезультата = 0, Знач ОтключитьОбщиеИтоги = Истина, Знач РежимОтладки = Ложь, ПроверятьДоступностьПолей = Ложь) Экспорт Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда //ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); //ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура); КонецЕсли; Если ОтключитьОбщиеИтоги Тогда НастройкаКомпоновки.ПараметрыВывода.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВертикальноеРасположениеОбщихИтогов"), РасположениеИтоговКомпоновкиДанных.Нет); КонецЕсли; Если Ложь Или КоллекцияЗначений = Неопределено Или ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений") Или ТипЗнч(КоллекцияЗначений) = Тип("Массив") Тогда КоллекцияРезультата = Новый ТаблицаЗначений; Иначе КоллекцияРезультата = КоллекцияЗначений; КонецЕсли; Если РежимОтладки Тогда ОтладитьЛкс(СхемаКомпоновки, Ложь, НастройкаКомпоновки, ВнешниеНаборыДанных); //Возврат Неопределено; КонецЕсли; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; Попытка МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей); Исключение //ИнформацияОбОшибке = ИнформацияОбОшибке(); //Если глКэш.ЭтоВидимоеПриложение Тогда // ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); //Иначе // ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); //КонецЕсли; ВызватьИсключение; Возврат Неопределено; КонецПопытки; //ИсследоватьЛкс(МакетКомпоновки, Ложь); //ОтладитьЛкс(МакетКомпоновки, Ложь); //Возврат Неопределено; Если МаксимальноеЧислоСтрокРезультата > 0 Тогда // Здесь тратится дополнительное ощутимое время на предварительный запрос. ирПлатформа = ирКэш.Получить(); ГрубоеКоличествоСтрокРезультата = ирПлатформа.ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки(МакетКомпоновки); Если ГрубоеКоличествоСтрокРезультата > МаксимальноеЧислоСтрокРезультата Тогда Сообщить("Настройки компоновки приводят к слишком большой выборке данных. Попробуйте задать более сильные ограничения."); Возврат Неопределено; КонецЕсли; КонецЕсли; //Антибаг платформы 1.14. Удаляем дубли ячеек по именам колонок в макете. //ИсследоватьЛкс(МакетКомпоновки, Ложь); ОписанияМакетовОбластей = МакетКомпоновки.Макеты; Если ОписанияМакетовОбластей.Количество() > 0 Тогда ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки; КоличествоЯчеек = ЯчейкиЗаголовка.Количество(); СтруктураКолонок = Новый Структура; ИндексЯчейки = 0; Пока ИндексЯчейки < КоличествоЯчеек Цикл ЯчейкаКолонки = ЯчейкиЗаголовка[ИндексЯчейки]; ИмяКолонки = ЯчейкаКолонки.Имя; //ИмяКолонки = ирПлатформа.ПолучитьИдентификаторИзПредставления(ЯчейкаКолонки.Имя); // От этого варианта отказались из-за портативности ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_"); ИмяКолонки = СтрЗаменить(ИмяКолонки, "]", ""); ИмяКолонки = СтрЗаменить(ИмяКолонки, "[", ""); ИмяКолонки = СтрЗаменить(ИмяКолонки, " ", "_"); ЯчейкаКолонки.Имя = ИмяКолонки; Если СтруктураКолонок.Свойство(ИмяКолонки) Тогда Для ИндексМакета = 1 По ОписанияМакетовОбластей.Количество() - 1 Цикл МакетСтроки = ОписанияМакетовОбластей[ИндексМакета]; МакетСтроки.Макет.Ячейки.Удалить(ИндексЯчейки); КонецЦикла; ЯчейкиЗаголовка.Удалить(ИндексЯчейки); КоличествоЯчеек = КоличествоЯчеек - 1; Иначе ИндексЯчейки = ИндексЯчейки + 1; СтруктураКолонок.Вставить(ИмяКолонки); КонецЕсли; КонецЦикла; КонецЕсли; Если СхемаКолонок <> Неопределено Тогда // Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных СхемаКолонок.Очистить(); Если ЯчейкиЗаголовка <> Неопределено Тогда КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество(); Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл // Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205 // http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023 ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс]; Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда Продолжить; КонецЕсли; ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение; Если ПараметрЯчейки = Неопределено Тогда Продолжить; КонецЕсли; Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение; ПозицияТочки = Найти(Выражение, "."); Если Ложь Или ПозицияТочки = 0 Или Найти(Выражение, " ") > 0 Или Найти(Выражение, "(") > 0 Тогда //ИмяПоля = ""; Продолжить; Иначе ИмяПоля = Сред(Выражение, ПозицияТочки + 1); КонецЕсли; СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля); Прервать; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; Если ТолькоСоздатьКолонки Тогда КоллекцияЗначений.Колонки.Очистить(); ЯчейкиЗаголовка = МакетКомпоновки.Макеты[0].Макет.Ячейки; Для Каждого Ячейка Из ЯчейкиЗаголовка Цикл //КолонкаКоллекции = КоллекцияЗначений.Колонки.Найти(Ячейка.Имя); //Если КолонкаКоллекции = Неопределено Тогда КоллекцияЗначений.Колонки.Добавить(Ячейка.Имя, Ячейка.ТипЗначения, Ячейка.Заголовок,); //КонецЕсли; КонецЦикла; Иначе ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, , Истина); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; ПроцессорВывода.УстановитьОбъект(КоллекцияРезультата); ПроцессорВывода.Вывести(ПроцессорКомпоновки); КонецЕсли; //ИсследоватьЛкс(КоллекцияРезультата); Если ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений") Тогда Есть0 = КоллекцияРезультата.Колонки.Количество() > 0; Есть1 = КоллекцияРезультата.Колонки.Количество() > 1; Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл НовыйЭлемент = КоллекцияЗначений.Добавить(); Если Есть0 Тогда НовыйЭлемент.Значение = СтрокаРезультата[0]; КонецЕсли; Если Есть1 Тогда НовыйЭлемент.Представление = СтрокаРезультата[1]; КонецЕсли; КонецЦикла; ИначеЕсли ТипЗнч(КоллекцияЗначений) = Тип("Массив") Тогда Если КоллекцияРезультата.Колонки.Количество() > 0 Тогда Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл КоллекцияЗначений.Добавить(СтрокаРезультата[0]); КонецЦикла; КонецЕсли; Иначе КоллекцияЗначений = КоллекцияРезультата; КонецЕсли; Результат = КоллекцияЗначений; Возврат Результат; КонецФункции Функция НайтиПоказатьСтрокуВПолеТекстовогоДокументаЛкс(Форма, ПолеТекстовогоДокумента, СтрокаПоиска) Экспорт Позиция = Найти(Нрег(ПолеТекстовогоДокумента.ПолучитьТекст()), Нрег(СтрокаПоиска)); Если Позиция > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Позиция, Позиция + СтрДлина(СтрокаПоиска)); Форма.ТекущийЭлемент = ПолеТекстовогоДокумента; Результат = Истина; Иначе Если СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1); КонецЕсли; Результат = Ложь; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // Элемент - ПолеТабличногоДокумента // Функция ПолеТабличногоДокумента_ПолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт Сумма = 0; СчетчикЯчеекСуммы = 0; СчетчикЯчеекОбщий = 0; ВыделенныеОбласти = Элемент.ВыделенныеОбласти; ЕстьИгнорированныеОбласти = Ложь; НачальноеКоличество = ВыделенныеОбласти.Количество(); Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти]; Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда Продолжить; КонецЕсли; ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1); СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти; Если ПлощадьОбласти < 10000 Тогда Для НомерКолонки = Область.Лево по Область.Право Цикл Для НомерСтроки = Область.Верх по Область.Низ Цикл ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; Попытка Число = Число(ОбластьЯчейки.Текст); Исключение Продолжить; КонецПопытки; Сумма = Сумма + Число; СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1; КонецЦикла; КонецЦикла; Иначе ЕстьИгнорированныеОбласти = Истина; КонецЕсли; КонецЦикла; СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы; Сумма = "" + Сумма; Если ЕстьИгнорированныеОбласти Тогда СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?"; Сумма = Сумма + "+?"; КонецЕсли; Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + ""; Возврат Текст; КонецФункции // Параметры: // Таблица - ТаблицаЗначений - может быть модифицирована здесь, поэтому нужно передавать копию, если нужна неизменность Функция ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(ТаблицаЗначений, Знач Приемник = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхКолонок = Истина, АвтофиксацияШапки = Истина, ВстроитьЗначенияВРасшифровки = Истина, ОтображатьПустые = Ложь, ДобавлятьКолонкиИдентификаторов = Ложь, ДобавлятьКолонкиТипов = Ложь, ДобавлятьКолонкиПредставлений = Ложь, Знач ВыбранныеКолонки = Неопределено, ИмяТекущейКолонки = "", ВыводВТаблицуЗначений = Ложь, Отладка = Ложь) Экспорт ТребоватьТипЛкс(ТаблицаЗначений, Тип("ТаблицаЗначений")); ирПлатформа = ирКэш.Получить(); Если ДобавлятьКолонкиТипов Или ДобавлятьКолонкиИдентификаторов Тогда //ТаблицаЗначений = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаЗначений); ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(ТаблицаЗначений); КонецЕсли; #Если Сервер И Не Сервер Тогда ирПлатформа = Обработки.ирПлатформа.Создать(); ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ВнешниеНаборыДанных = Новый Структура("Основной", ТаблицаЗначений); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; КолонкиИдентификаторов = Новый Массив; КолонкиТипов = Новый Массив; Если ВыбранныеКолонки = Неопределено Тогда ВыбранныеКолонки = Новый Массив; Для Каждого Колонка Из КолонкиИсточникаДанныхЛкс(ТаблицаЗначений) Цикл ВыбранныеКолонки.Добавить(Колонка.Имя); КонецЦикла; КонецЕсли; //ПримитивныеТипы = Новый Массив; //ПримитивныеТипы.Добавить(Тип("Число")); //ПримитивныеТипы.Добавить(Тип("Строка")); //ПримитивныеТипы.Добавить(Тип("Дата")); //ПримитивныеТипы.Добавить(Тип("Булево")); //ПримитивныеТипы.Добавить(Тип("Неопределено")); //ПримитивныеТипы.Добавить(Тип("Null")); //ПримитивныеТипы.Добавить(Тип("УникальныйИдентификатор")); ИменаТипов = Новый Структура; ПозицииКолонок = Новый Структура; ИндексТекущейКолонки = 0; Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда Продолжить; КонецЕсли; Колонка = ТаблицаЗначений.Колонки.Найти(ВыбраннаяКолонка); Если Колонка = Неопределено Тогда // Например "ИдентификаторСсылкаЛкс" в таблице формы Продолжить; КонецЕсли; ТипыКолонки = Колонка.ТипЗначения.Типы(); ПозицииКолонок.Вставить(Колонка.Имя, НастройкаКомпоновки.Выбор.Элементы.Количество()); Если ДобавлятьКолонкиПредставлений Тогда НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка); КонецЕсли; Если Ложь Или ОтображатьПустые Или (Истина И ДобавлятьКолонкиТипов И ТипыКолонки.Количество() > 1) Тогда КолонкиТипов.Добавить(Колонка.Имя); ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ВыбраннаяКолонка + "_ИмяТипаЗначения_", Новый ОписаниеТипов("Строка"), Колонка.Заголовок + " (тип)"); Если ДобавлятьКолонкиТипов Тогда НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка + "_ИмяТипаЗначения_"); КонецЕсли; ИменаТиповКолонки = Новый Соответствие; Для Каждого Тип Из ТипыКолонки Цикл ИменаТиповКолонки.Вставить(Тип, ПредставлениеТипаЛкс(Тип, Колонка.ТипЗначения, Истина)); КонецЦикла; ИменаТипов.Вставить(Колонка.Имя, ИменаТиповКолонки); КонецЕсли; Если ДобавлятьКолонкиИдентификаторов Тогда ЕстьСсылочныйТип = ТипыКолонки.Количество() = 0; Если Не ЕстьСсылочныйТип Тогда Для Каждого Тип Из ТипыКолонки Цикл Если ЛиТипСсылкиБДЛкс(Тип, Ложь) Тогда ЕстьСсылочныйТип = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если ЕстьСсылочныйТип Тогда Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество(); КонецЕсли; КолонкиИдентификаторов.Добавить(Колонка.Имя); ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ВыбраннаяКолонка + "_ИдентификаторЗначения_", Новый ОписаниеТипов("Строка"), Колонка.Заголовок + " (идентификатор)"); НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка + "_ИдентификаторЗначения_"); КонецЕсли; КонецЕсли; Если ОтображатьПустые Тогда ПустыеЗначения = Новый Массив; ПустыеЗначения.Добавить(Неопределено); ПустыеЗначения.Добавить(0); ПустыеЗначения.Добавить(Дата(1,1,1)); ПустыеЗначения.Добавить(Ложь); ПустыеЗначения.Добавить(""); Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл Если Ложь Или Колонка.ТипЗначения.Типы().Количество() = 0 Или Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение)) Тогда ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить(); ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение)); //ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс()); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, , ВидСравненияКомпоновкиДанных.НеЗаполнено); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, ПустоеЗначение, ВидСравненияКомпоновкиДанных.Равно); ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить(); ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка); КонецЕсли; КонецЦикла; // Отдельно для особенного Null ПустоеЗначение = Null; Если Истина И Колонка.ТипЗначения.Типы().Количество() > 0 И Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение)) Тогда ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить(); ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение)); //ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс()); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка + "_ИмяТипаЗначения_", "Null", ВидСравненияКомпоновкиДанных.Равно); ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить(); ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка); КонецЕсли; КонецЕсли; КонецЦикла; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЗначений.Количество(), "Заполнение доп. колонок"); Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); Для Каждого ИмяКолонки Из КолонкиТипов Цикл Если Ложь Или ДобавлятьКолонкиТипов Или СтрокаТаблицы[ИмяКолонки] = Null Тогда СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])]; КонецЕсли; КонецЦикла; Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = ПолучитьИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; КонецЦикла; Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура); КонецЕсли; СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхКолонок); Если Отладка Тогда ОтладитьЛкс(СхемаКомпоновки, , НастройкаКомпоновки, ВнешниеНаборыДанных); Возврат Неопределено; КонецЕсли; Если ВыводВТаблицуЗначений Тогда Приемник = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных); //Приемник = ТаблицаЗначений.Скопировать(, "..."); Иначе Приемник = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных, ДанныеРасшифровки, АвтофиксацияШапки,, ВстроитьЗначенияВРасшифровки); #Если Сервер И Не Сервер Тогда Приемник = Новый ТабличныйДокумент; #КонецЕсли Если ЗначениеЗаполнено(ИмяТекущейКолонки) Тогда Приемник.ТекущаяОбласть = Приемник.Область(2, ПозицииКолонок[ИмяТекущейКолонки] + 1); КонецЕсли; Для Счетчик = 1 По ВыбранныеКолонки.Количество() Цикл ИмяКолонки = ВыбранныеКолонки[Счетчик - 1]; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Продолжить; КонецЕсли; Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки); Если Колонка <> Неопределено Тогда Приемник.Область(1, ПозицииКолонок[ИмяКолонки] + 1).Примечание.Текст = "Типы значений: " + РасширенноеПредставлениеЗначенияЛкс(Колонка.ТипЗначения); КонецЕсли; КонецЦикла; КонецЕсли; Возврат Приемник; КонецФункции Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено, ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь) Экспорт #Если Сервер И Не Сервер Тогда НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; #КонецЕсли Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура); КонецЕсли; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; Если ДанныеРасшифровки = Неопределено Тогда ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных; КонецЕсли; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, ДанныеРасшифровки,,, ПроверятьДоступностьПолей); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина); Если ТабличныйДокумент = Неопределено Тогда ТабличныйДокумент = Новый ТабличныйДокумент; КонецЕсли; ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки); Если ВстроитьЗначенияПолейВРасшифровки Тогда Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); ИдентификаторРасшифровки = Ячейка.Расшифровка; Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля(); Если ЗначенияПолей.Количество() > 0 Тогда Ячейка.Расшифровка = ЗначенияПолей[0].Значение; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; Возврат ТабличныйДокумент; КонецФункции // мВнешниеНаборыДанных - Структура, Неопределено - не очищается Функция ДополнитьСтруктуруВнешихНаборовДанныхПустышкамиЛкс(лСхемаКомпоновкиДанных, мВнешниеНаборыДанных = Неопределено) Экспорт Если мВнешниеНаборыДанных = Неопределено Тогда мВнешниеНаборыДанных = Новый Структура(); КонецЕсли; // Создадим пустышки внешних наборов данных, если они не переданы ОбъектТаблица = 0; Для Каждого НаборДанных Из лСхемаКомпоновкиДанных.НаборыДанных Цикл Если ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда Если НаборДанных.ИмяОбъекта = "" Тогда Продолжить; КонецЕсли; Если Не мВнешниеНаборыДанных.Свойство(НаборДанных.ИмяОбъекта, ОбъектТаблица) Тогда ОбъектТаблица = Новый ТаблицаЗначений; КонецЕсли; Попытка КолонкиОбъектаТаблицы = ОбъектТаблица.Колонки; Исключение // Тогда это табличная часть, но возможно и тут будет исключение КолонкиОбъектаТаблицы = ОбъектТаблица.ВыгрузитьКолонки().Колонки; КонецПопытки; Если КолонкиОбъектаТаблицы.Количество() > 0 Тогда Продолжить; КонецЕсли; Для Каждого Поле Из НаборДанных.Поля Цикл Если ТипЗнч(Поле) = Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда Если КолонкиОбъектаТаблицы.Найти(Поле.Поле) = Неопределено Тогда КолонкиОбъектаТаблицы.Добавить(Поле.Поле, Поле.ТипЗначения); КонецЕсли; КонецЕсли; КонецЦикла; мВнешниеНаборыДанных.Вставить(НаборДанных.ИмяОбъекта, ОбъектТаблица); КонецЕсли; КонецЦикла; Возврат мВнешниеНаборыДанных; КонецФункции Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Истина) Экспорт Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент); ТекущееЗначение = ДанныеЭлементаФормыЛкс(Элемент); Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение, Ложь) Тогда НачальноеЗначениеВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ТекущееЗначение)); КонецЕсли; лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; ЗначениеВыбора = Форма.ОткрытьМодально(); Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда лПолноеИмяОбъекта = Неопределено; Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда ИмяТипаСсылки = ИмяТипаИзПолногоИмениМДЛкс(лПолноеИмяОбъекта, "Ссылка"); ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки); НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено); ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение); Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда //Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,,, Элемент, Истина); //КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; СтандартнаяОбработка = Ложь; Возврат НовоеЗначение; КонецФункции // Результат - значение выбранного типа, но не обязательно выбранное (выбор типа выполняется синхронно, а значения - асинхронно) Функция ПолеВвода_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, ИгнорироватьОписаниеТипов = Ложь) Экспорт РезультатВыбора = ДанныеЭлементаФормыЛкс(Элемент); Если Истина И ИгнорироватьОписаниеТипов И (Ложь Или ТипЗнч(РезультатВыбора) = Тип("Строка") Или РезультатВыбора = Неопределено) Тогда РезультатВыбора = ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка); ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(РезультатВыбора, Ложь) Тогда СтандартнаяОбработка = Ложь; ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РезультатВыбора)),,, Элемент, Истина,, РезультатВыбора); Иначе // Тут надо делать выбор из диалога плоского списка типов КонецЕсли; Возврат РезультатВыбора; КонецФункции // Для "Ссылка.Организация" вернет "Организация", для "Основание.Контрагент" вернет "ОснованиеКонтрагент" // Параметры: // ИмяПоля - Строка Функция ПолучитьИмяКолонкиРезультатаПоИмениПоляЛкс(Знач ИмяПоля) Экспорт Начало = "Ссылка."; ДлинаНачала = СтрДлина(Начало); Если СтрокиРавныЛкс(Лев(ИмяПоля, ДлинаНачала), Начало) Тогда ИмяПоля = Сред(ИмяПоля, ДлинаНачала + 1); КонецЕсли; ИмяПоля = СтрЗаменить(ИмяПоля, ".", ""); Возврат ИмяПоля; КонецФункции Процедура ДобавитьМногострочнуюСтрокуВТекстЛкс(СобираемыйТекст, Выражение, Смещение, СНовойСтроки = Ложь, ОбрезатьЛевыеПустые = Ложь) Экспорт Если СНовойСтроки Тогда СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение; КонецЕсли; СобираемыйТекст = СобираемыйТекст + СтрПолучитьСтроку(Выражение, 1); Для Счетчик = 2 По СтрЧислоСтрок(Выражение) Цикл ТекущаяСтрока = СтрПолучитьСтроку(Выражение, Счетчик); Если ОбрезатьЛевыеПустые Тогда ТекущаяСтрока = СокрЛ(ТекущаяСтрока); КонецЕсли; СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение + ТекущаяСтрока; КонецЦикла; КонецПроцедуры Функция ПолучитьИндексКартинкиТипаЛкс(ОписаниеТипов) Экспорт Если ОписаниеТипов = Неопределено Тогда Возврат 14; КонецЕсли; Типы = ОписаниеТипов.Типы(); Если Типы.Количество() = 1 Тогда КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Типы[0]); Если Типы[0] = Тип("Число") Тогда ИндексКартинки = 0; ИначеЕсли Типы[0] = Тип("Строка") Тогда ИндексКартинки = 1; ИначеЕсли Типы[0] = Тип("Дата") Тогда ИндексКартинки = 2; ИначеЕсли Типы[0] = Тип("Булево") Тогда ИндексКартинки = 3; ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда ИндексКартинки = 19; ИначеЕсли Типы[0] = Тип("Тип") Тогда ИндексКартинки = 20; ИначеЕсли КорневойТип = "Справочник" Тогда ИндексКартинки = 7; ИначеЕсли КорневойТип = "Документ" Тогда ИндексКартинки = 8; ИначеЕсли КорневойТип = "Перечисление" Тогда ИндексКартинки = 9; ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда ИндексКартинки = 10; ИначеЕсли КорневойТип = "ПланСчетов" Тогда ИндексКартинки = 11; ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда ИндексКартинки = 12; ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда ИндексКартинки = 13; ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда ИндексКартинки = 14; ИначеЕсли КорневойТип = "Задача" Тогда ИндексКартинки = 15; Иначе ИндексКартинки = 16; КонецЕсли; Иначе ИндексКартинки = 16; КонецЕсли; Возврат ИндексКартинки; КонецФункции // Получает строку для установки порядка компоновки. // // Параметры: // ПорядокКомпоновки – ПорядокКомпоновкиДанных. // // Возвращаемое значение: // Строка - для установки порядка. // Функция ПолучитьВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1C") Экспорт Строка = ""; Если СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда СтрокаВозр = "Возр"; СтрокаУбыв = "Убыв"; Иначе СтрокаВозр = "Asc"; СтрокаУбыв = "Desc"; КонецЕсли; Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл Если Ложь Или Не ЭлементПорядка.Использование Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных") Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле Тогда Продолжить; КонецЕсли; ИмяПоля = "" + ЭлементПорядка.Поле; Если СимволЗаменыТочки <> Неопределено Тогда ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки); КонецЕсли; Строка = Строка + ", " + ИмяПоля + " "; Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда Строка = Строка + СтрокаВозр; Иначе Строка = Строка + СтрокаУбыв; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 3); КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс() Функция ПолучитьПреставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт Представление = ""; Если СочетаниеКлавиш.Alt Тогда Представление = Представление + "Alt+"; КонецЕсли; Если СочетаниеКлавиш.Ctrl Тогда Представление = Представление + "Ctrl+"; КонецЕсли; Если СочетаниеКлавиш.Shift Тогда Представление = Представление + "Shift+"; КонецЕсли; Представление = Представление + СочетаниеКлавиш.Клавиша; Возврат Представление; КонецФункции //////////////////////////////// // ФОРМЫ Процедура ИнициализироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы) Экспорт // Проверяем режим модальности мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли // Проверка контроля модальности СпрашиватьОПерезапуске = Истина; Список = Новый СписокЗначений; Попытка Список.ВыбратьЭлемент(); Исключение СпрашиватьОПерезапуске = Ложь; КонецПопытки; Если Ложь Или мПлатформа.ИДВерсииПлатформы = "82" Или мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина Или Метаданные.РежимИспользованияМодальности = Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.Использовать Тогда Если Не СпрашиватьОПерезапуске Тогда ВызватьИсключение "При запуске приложения из конфигуратора автоматически включается контроль модальности. |Запустите приложение другим способом, чтобы разрешить модальность."; КонецЕсли; Иначе ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС(); ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'"); КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine; мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина; Если Ложь Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckModal") > 0 //Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckExtensionsAndAddInsSyncCalls") > 0 Тогда Если СпрашиватьОПерезапуске Тогда Ответ = Вопрос("Сеанс запущен с проверкой модальности. Хотите перезапустить его с отключением проверки?", РежимДиалогаВопрос.ДаНет, 10, КодВозвратаДиалога.Нет); Иначе Ответ = КодВозвратаДиалога.Да; КонецЕсли; Если Ответ = КодВозвратаДиалога.Да Тогда ПараметрыЗапуска = ирОбщий.ПолучитьПоследнийФрагментЛкс(КоманднаяСтрокаПроцесса, ".exe"""); ПараметрыЗапуска = СтрЗаменить(ПараметрыЗапуска, "/EnableCheckModal", ""); //ПараметрыЗапуска = СтрЗаменить(ПараметрыЗапуска, "/EnableCheckExtensionsAndAddInsSyncCalls", ""); Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """"; КонецЕсли; ЗапуститьПриложение("1cv8.exe " + ПараметрыЗапуска, КаталогПрограммы()); Если СпрашиватьОПерезапуске Тогда ЗавершитьРаботуСистемы(); Иначе ТекстСообщения = "При запуске сеанса из конфигуратора автоматически включается контроль модальности. Запущен новый сеанс без контроля модальности."; Выполнить("ПоказатьПредупреждение(, ТекстСообщения)"); КонецЕсли; Возврат; КонецЕсли; КонецЕсли; КонецЕсли; #Если (ТолстыйКлиентОбычноеПриложение ИЛИ ТолстыйКлиентУправляемоеПриложение) И Не Сервер Тогда // Проверка компиляции общих модулей с обработчиками событий Если мПлатформа.мПроверкаКомпиляцииОбщихМодулейВыполнялась <> Истина Тогда СписокМодулей = Новый Структура; ОбщиеМодули = Метаданные.ОбщиеМодули; #Если ТолстыйКлиентУправляемоеПриложение Тогда ИмяКлиента = "Управляемое"; #Иначе ИмяКлиента = "Обычное"; #КонецЕсли ИмяСвойства = "Клиент" + ИмяКлиента + "Приложение"; Для Каждого Подписка Из Метаданные.ПодпискиНаСобытия Цикл МетаМодуль = ОбщиеМодули.Найти(ирОбщий.ПолучитьПервыйФрагментЛкс(Подписка.Обработчик)); Если МетаМодуль = Неопределено Тогда // Некорректная подписка Продолжить; КонецЕсли; Если Не МетаМодуль[ИмяСвойства] И Не МетаМодуль.ВызовСервера Тогда СписокМодулей.Вставить(МетаМодуль.Имя); КонецЕсли; КонецЦикла; Если СписокМодулей.Количество() > 0 Тогда Если ИмяКлиента = "Управляемое" Тогда Сообщить("Для работы с инструментами в этой конфигурации рекомендуется использовать режим запуска ""Обычное приложение""."); КонецЕсли; Сообщить("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на события.", СтатусСообщения.Внимание); Сообщить("Поэтому при работе инструментов возможны ошибки ""При подписке * на событие * произошла ошибка. Обработчик события не найден."""); Если ИмяКлиента = "Обычное" Тогда Сообщить("Необходимо в конфигураторе установить ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение""."); КонецЕсли; Сообщить("Необходимо установить флажок ""Клиент (" + ИмяКлиента + " приложение)"" или ""Вызова сервера"" и обеспечить компиляцию у общих модулей:"); Для Каждого КлючИЗначение Из СписокМодулей Цикл Сообщить("- " + КлючИЗначение.Ключ); КонецЦикла; КонецЕсли; мПлатформа.мПроверкаКомпиляцииОбщихМодулейВыполнялась = Истина; #Если ТолстыйКлиентОбычноеПриложение Тогда Если Истина И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение И Не Метаданные.ИспользоватьУправляемыеФормыВОбычномПриложении Тогда Сообщить("Рекомендуется включить в свойствах конфигурации флажок ""Использовать управляемые формы в обычном приложении"""); КонецЕсли; #КонецЕсли КонецЕсли; #КонецЕсли //// Проверяем защиту от опасных действий //// Здесь это делать бесполезно, т.к. она срабатывает раньше //Если Истина // И ирКэш.ЛиПортативныйРежимЛкс() // И мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась <> Истина // //И мПлатформа.ВерсияПлатформы < 803010 // Когда в платформе исправят проблему, тогда и отключим //Тогда // ТекущийПользовательБазы = ПользователиИнформационнойБазы.ТекущийПользователь(); // Попытка // ЗащитаОтОпасныхДействий = ТекущийПользовательБазы.ЗащитаОтОпасныхДействий; // Исключение // ЗащитаОтОпасныхДействий = Неопределено; // КонецПопытки; // Если Истина // И ЗначениеЗаполнено(ТекущийПользовательБазы.Имя) // И ЗащитаОтОпасныхДействий <> Неопределено // И ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина // Тогда // Ответ = Вопрос("У текущего пользователя базы включена защита от опасных действий. // |Для корректной работы с инструментами ее рекомендуется отключить. Сделать это (сеанс будет перезапущен)?", РежимДиалогаВопрос.ДаНет, 10, РежимДиалогаВопрос.Нет); // Если Ответ = КодВозвратаДиалога.Да Тогда // ТекущийПользовательБазы.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь; // ТекущийПользовательБазы.Записать(); // ПараметрыЗапуска = ""; // Если ирКэш.ЛиПортативныйРежимЛкс() Тогда // ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """"; // КонецЕсли; // ЗавершитьРаботуСистемы(, Истина, ПараметрыЗапуска); // КонецЕсли; // КонецЕсли; // мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась = Истина; //КонецЕсли; НастроитьЭлементыФормыЛкс(ЭтаФорма); Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма); мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы); мСвойстваФормы.Вставить("НеготовыеСтраницы", Новый СписокЗначений); Если ирКэш.ЛиПортативныйРежимЛкс() Тогда Контейнер = Новый Структура(); Оповестить("ирПолучитьБазовуюФорму", Контейнер); Если Не Контейнер.Свойство("ирПортативный") Тогда БазоваяФорма = ирПортативный.ПолучитьФорму(); БазоваяФорма.Открыть(); КонецЕсли; #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + мПлатформа.ПолучитьИдентификаторИзПредставления(ПолноеИмяФормы) + "(ЭтаФорма)"; Выполнить(СтрокаВызова); Иначе МетаФорма = Метаданные.НайтиПоПолномуИмени(ПолноеИмяФормы); Если МетаФорма = Неопределено Тогда Сообщить("Метаформа не найдена по полному имени """ + ПолноеИмяФормы + """", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура НастроитьЭлементыФормыЛкс(ЭтаФорма) Экспорт мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); КнопкиВсехДействийКомандныхПанелей = Новый Соответствие; ИмяКнопки = "СтруктураКоманднойПанели"; ИмяОсновногоРеквизита = "ОсновнойОбъект"; Попытка ОсновнойРеквизит = ЭтаФорма[ИмяОсновногоРеквизита]; Исключение КонецПопытки; Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл Если ОсновнойРеквизит <> Неопределено Тогда Попытка Данные = ЭлементФормы.Данные; Исключение Данные = ""; КонецПопытки; Если Не ПустаяСтрока(Данные) И Найти(Данные, ".") = 0 Тогда Если Не ЗначениеЗаполнено(ЭлементФормы.Подсказка) Тогда РеквизитОбъекта = ОсновнойРеквизит.Метаданные().Реквизиты.Найти(Данные); Если РеквизитОбъекта <> Неопределено Тогда ЭлементФормы.Подсказка = РеквизитОбъекта.Подсказка; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Встраиваем кнопки структуры командной панели КоманднаяПанель = Неопределено; ВстроитьВНачало = Истина; Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда КоманднаяПанель = ЭлементФормы; Если Не КоманднаяПанель.Видимость Тогда Продолжить; КонецЕсли; //ИначеЕсли ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда // КоманднаяПанель = ЭлементФормы.КонтекстноеМеню; Иначе Попытка // В контекстных меню функция маловостребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок КоманднаяПанель = ЭлементФормы.КонтекстноеМеню; ВстроитьВНачало = Ложь; Исключение КонецПопытки; КонецЕсли; Если Истина И КоманднаяПанель <> Неопределено И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено Тогда НужноВстроить = Ложь; КоличествоКнопок = 0; Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда КоличествоКнопок = КоличествоКнопок + 1; Если КоличествоКнопок > 4 Тогда НужноВстроить = Истина; Прервать; КонецЕсли; КонецЕсли; Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда НужноВстроить = Истина; Прервать; КонецЕсли; КонецЦикла; Если НужноВстроить Тогда Если ВстроитьВНачало Тогда КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0); Иначе КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Добавить(); КонецЕсли; КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки; КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; КнопкаСтруктураКоманднойПанели.Картинка = ПолучитьОбщуюКартинкуЛкс("ирКоманднаяПанель"); КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто; КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели"; КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели"; Попытка КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие"); Исключение // В этой форме нет обработчика Возврат; КонецПопытки; КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель); КонецЕсли; КонецЕсли; Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда НастроитьТабличноеПолеЛкс(ЭлементФормы); КонецЕсли; КонецЦикла; мСвойстваФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей); КонецПроцедуры Процедура НастроитьТабличноеПолеЛкс(Знач ЭлементФормы) Экспорт // Возвращаем старый стиль шапок колонок, при котором видна текущая колонка Если ЭлементФормы.Колонки.Количество() > 0 Тогда // Антифича платформы 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=898034 Если ЭлементФормы.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда ЭлементФормы.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка]; Если Кнопка <> Неопределено Тогда Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда // Для контекстных меню КоманднаяПанель = КоманднаяПанель.Кнопки[0]; КонецЕсли; КонецЕсли; ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы"); ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель; ФормаСтруктуры.Форма = ЭтаФорма; ФормаСтруктуры.ОткрытьМодально(); КонецПроцедуры Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма) Экспорт ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы"); ФормаСтруктуры.Форма = ЭтаФорма; ФормаСтруктуры.ОткрытьМодально(); КонецПроцедуры Функция ОткрытьФормуСоединенияСУБДЛкс(Автоподключение = Ложь) Экспорт ФормаПодключения = ирКэш.Получить().ПолучитьФорму("ПараметрыСоединенияСУБД"); ФормаПодключения.Автоподключение = Автоподключение; ФормаПодключения.ЗаполнитьПараметры(); Если Автоподключение И Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда ФормаПодключения.ОткрытьМодально(); КонецЕсли; Возврат ФормаПодключения; КонецФункции #КонецЕсли Функция ВосстановитьЗначениеЛкс(КлючНастроек) Экспорт #Если ТонкийКлиент Или ВебКлиент Тогда Возврат ВосстановитьЗначениеЛкс(КлючНастроек); #Иначе Результат = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), КлючНастроек); #Если Клиент Тогда Если Результат = Неопределено Тогда // Импорт из старого хранилища настроек Результат = ВосстановитьЗначение(КлючНастроек); Если Результат <> Неопределено Тогда СохранитьЗначениеЛкс(КлючНастроек, Результат); СохранитьЗначение(КлючНастроек, Неопределено); КонецЕсли; КонецЕсли; #КонецЕсли Возврат Результат; #КонецЕсли КонецФункции Функция СохранитьЗначениеЛкс(КлючНастроек, Значение) Экспорт #Если ТонкийКлиент Или ВебКлиент Тогда ирСервер.СохранитьЗначениеЛкс(КлючНастроек, Значение); #Иначе ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Значение); #КонецЕсли КонецФункции Процедура ДобавитьИндексВТаблицуЛкс(ТаблицаЗначений, Знач СтрокаИндекса) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ИндексНайден = Ложь; Для Каждого Индекс Из ТаблицаЗначений.Индексы Цикл Если "" + Индекс = СтрокаИндекса Тогда ИндексНайден = Истина; Прервать; КонецЕсли; КонецЦикла; Если Не ИндексНайден Тогда ТаблицаЗначений.Индексы.Добавить(СтрокаИндекса); КонецЕсли; КонецПроцедуры // вВыполнитьОбработку() Функция ЛиПустаяПодгруппаRegExpЛкс(Подгруппа) Экспорт Результат = Ложь Или Подгруппа = Неопределено Или Подгруппа = ""; Возврат Результат; КонецФункции Процедура ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Объект, ИмяСвойства = "Имя") Экспорт Объект["Н" + ИмяСвойства] = НРег(Объект[ИмяСвойства]); КонецПроцедуры Функция ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки) Экспорт #Если Сервер И Не Сервер Тогда МакетКомпоновки = Новый МакетКомпоновкиДанных; #КонецЕсли СхемаКолонок = Новый Структура; // Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных ОписанияМакетовОбластей = МакетКомпоновки.Макеты; Если ОписанияМакетовОбластей.Количество() > 0 Тогда ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки; Если ЯчейкиЗаголовка <> Неопределено Тогда КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество(); Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл // Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205 // http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023 ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс]; Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда Продолжить; КонецЕсли; ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение; Если ПараметрЯчейки = Неопределено Тогда Продолжить; КонецЕсли; Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение; ПозицияТочки = Найти(Выражение, "."); Если Ложь Или ПозицияТочки = 0 Или Найти(Выражение, " ") > 0 Или Найти(Выражение, "(") > 0 Тогда //ИмяПоля = ""; Продолжить; Иначе ИмяПоля = Сред(Выражение, ПозицияТочки + 1); КонецЕсли; СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля); Прервать; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; Возврат СхемаКолонок; КонецФункции Функция ПолучитьТекущуюДатуЛкс(НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.ПолучитьТекущуюДатуЛкс(); Иначе Результат = ТекущаяДата(); КонецЕсли; Возврат Результат; КонецФункции Функция СтрокиРавныЛкс(Знач Строка1, Знач Строка2, СУчетомРегистра = Ложь, БезПравыхНепечатныхСимволов = Ложь) Экспорт Если Не СУчетомРегистра Тогда Строка1 = НРег(Строка1); Строка2 = НРег(Строка2); КонецЕсли; Если БезПравыхНепечатныхСимволов Тогда Строка1 = СокрП(Строка1); Строка2 = СокрП(Строка2); КонецЕсли; Результат = Строка1 = Строка2; Возврат Результат; КонецФункции // Разделяет URL по составным частям: протокол, сервер, путь к ресурсу. // // Параметры: // URL - Строка - ссылка на ресурс в сети Интернет // // Возвращаемое значение: // Структура: // Протокол - Строка - протокол доступа к ресурсу // ИмяСервера - Строка - сервер, на котором располагается ресурс // ПутьКФайлуНаСервере - Строка - путь к ресурсу на сервере // Функция РазделитьURLЛкс(Знач URL) Экспорт СтруктураURL = СтруктураURIЛкс(URL); Результат = Новый Структура; Результат.Вставить("Протокол", ?(ПустаяСтрока(СтруктураURL.Схема), "http", СтруктураURL.Схема)); Результат.Вставить("ИмяСервера", СтруктураURL.ИмяСервера); Результат.Вставить("ПутьКФайлуНаСервере", СтруктураURL.ПутьНаСервере); Возврат Результат; КонецФункции // Разбирает строку URI на составные части и возвращает в виде структуры. // На основе RFC 3986. // // Параметры: // СтрокаURI - Строка - ссылка на ресурс в формате: <схема>://<логин>:<пароль>@<хост>:<порт>/<путь>?<параметры>#<якорь> // // Возвращаемое значение: // Структура - составные части URI согласно формату: // * Схема - Строка // * Логин - Строка // * Пароль - Строка // * ИмяСервера - Строка - часть <хост>:<порт> входного параметра // * Хост - Строка // * Порт - Строка // * ПутьНаСервере - Строка - часть <путь>?<параметры>#<якорь> входного параметра // Функция СтруктураURIЛкс(Знач СтрокаURI) Экспорт СтрокаURI = СокрЛП(СтрокаURI); // схема Схема = ""; Позиция = Найти(СтрокаURI, "://"); Если Позиция > 0 Тогда Схема = НРег(Лев(СтрокаURI, Позиция - 1)); СтрокаURI = Сред(СтрокаURI, Позиция + 3); КонецЕсли; // строка соединения и путь на сервере СтрокаСоединения = СтрокаURI; ПутьНаСервере = ""; Позиция = Найти(СтрокаСоединения, "/"); Если Позиция > 0 Тогда ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1); СтрокаСоединения = Лев(СтрокаСоединения, Позиция - 1); КонецЕсли; // информация пользователя и имя сервера СтрокаАвторизации = ""; ИмяСервера = СтрокаСоединения; Позиция = Найти(СтрокаСоединения, "@"); Если Позиция > 0 Тогда СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1); ИмяСервера = Сред(СтрокаСоединения, Позиция + 1); КонецЕсли; // логин и пароль Логин = СтрокаАвторизации; Пароль = ""; Позиция = Найти(СтрокаАвторизации, ":"); Если Позиция > 0 Тогда Логин = Лев(СтрокаАвторизации, Позиция - 1); Пароль = Сред(СтрокаАвторизации, Позиция + 1); КонецЕсли; // хост и порт Хост = ИмяСервера; Порт = ""; Позиция = Найти(ИмяСервера, ":"); Если Позиция > 0 Тогда Хост = Лев(ИмяСервера, Позиция - 1); Порт = Сред(ИмяСервера, Позиция + 1); КонецЕсли; Результат = Новый Структура; Результат.Вставить("Схема", Схема); Результат.Вставить("Логин", Логин); Результат.Вставить("Пароль", Пароль); Результат.Вставить("ИмяСервера", ИмяСервера); Результат.Вставить("Хост", Хост); Результат.Вставить("Порт", ?(ПустаяСтрока(Порт), Неопределено, Число(Порт))); Результат.Вставить("ПутьНаСервере", ПутьНаСервере); Возврат Результат; КонецФункции // Поиск числа в строке // // Параметры: // ИсходнаяСтрока - Строка, строка в которой ищется число // ПозицияЧисла - Число, позиция начала числа // КоличествоСимволов - Число, количество символов числа // // Возвращаемое значение: // Булево - Истина, число найдено // Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, ПозицияЧисла, КоличествоСимволов) Экспорт ПозицияЧисла = 0; КоличествоСимволов = 0; ДлинаСтроки = СтрДлина(ИсходнаяСтрока); Для Сч = 1 По ДлинаСтроки Цикл ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1)); Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда Если ПозицияЧисла = 0 Тогда ПозицияЧисла = Сч; КоличествоСимволов = 1; Иначе КоличествоСимволов = КоличествоСимволов + 1; КонецЕсли; Иначе Если ПозицияЧисла <> 0 Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Возврат ПозицияЧисла > 0; КонецФункции // НайтиЧислоВСтроке() Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт #Если Клиент Тогда Если ВыводитьПредупрежденияИСообщения Тогда Ответ = КодВозвратаДиалога.ОК; Если НаСервере Тогда ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала); Иначе ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала); КонецЕсли; Если ОбщийРазмер > 0 Тогда Ответ = Вопрос("Действительно удалить рекурсивно все файлы (" + Формат(Цел(ОбщийРазмер/1000000), "ЧН=") + "МБ) в каталоге журнала?", РежимДиалогаВопрос.ОКОтмена); КонецЕсли; Если Ответ <> КодВозвратаДиалога.ОК Тогда Возврат; КонецЕсли; КонецЕсли; Если НаСервере Тогда ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения); Возврат; КонецЕсли; #КонецЕсли ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина); Если ФайлыЖурнала.Количество() > 0 Тогда СчетчикНеудаленных = 0; Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл Попытка УдалитьФайлы(ФайлЖурнала.ПолноеИмя); Исключение СчетчикНеудаленных = СчетчикНеудаленных + 1; КонецПопытки; КонецЦикла; Если ВыводитьПредупрежденияИСообщения Тогда Если СчетчикНеудаленных > 0 Тогда Сообщить("" + СчетчикНеудаленных + " файлов техножурнала удалить не удалось"); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс() Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги); ОбщийРазмер = 0; Для Каждого Файл Из Файлы Цикл Если Файл.ЭтоКаталог() Тогда Продолжить; КонецЕсли; ОбщийРазмер = ОбщийРазмер + Файл.Размер(); КонецЦикла; Возврат ОбщийРазмер; КонецФункции // Выполняет копирование файлов рекурсивно Процедура СкопироватьФайлыЛкс(КаталогИсточник, КаталогПриемник) Экспорт Файлы = НайтиФайлы(КаталогИсточник, "*.*"); Для Каждого Файл Из Файлы Цикл ФайлПриемник = Новый Файл(КаталогПриемник + "\" + Файл.Имя); Если Файл.ЭтоКаталог() Тогда СоздатьКаталог(ФайлПриемник.ПолноеИмя); СкопироватьФайлыЛкс(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя); Продолжить; КонецЕсли; КопироватьФайл(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя); КонецЦикла; КонецПроцедуры Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка") Экспорт Если Родитель = Неопределено Тогда Возврат; КонецЕсли; ТекСостояние = Родитель[ИмяДанныхФлажка]; НайденыВключенные = Ложь; НайденыВыключенные = Ложь; Для каждого Строка из Родитель.Строки Цикл ЗначениеФлажка = Строка[ИмяДанныхФлажка]; Если ЗначениеФлажка = 0 Тогда НайденыВыключенные = Истина; ИначеЕсли ЗначениеФлажка = 1 Тогда НайденыВключенные = Истина; ИначеЕсли ЗначениеФлажка = 2 Тогда НайденыВключенные = Истина; НайденыВыключенные = Истина; Прервать; КонецЕсли; Если НайденыВключенные И НайденыВыключенные Тогда Прервать; КонецЕсли; КонецЦикла; Если НайденыВключенные И НайденыВыключенные Тогда Включить = 2; ИначеЕсли НайденыВключенные И (Не НайденыВыключенные) Тогда Включить = 1; ИначеЕсли (Не НайденыВключенные) И НайденыВыключенные Тогда Включить = 0; ИначеЕсли (Не НайденыВключенные) И (Не НайденыВыключенные) Тогда Включить = 2; КонецЕсли; Если Включить = ТекСостояние Тогда Возврат; Иначе Родитель[ИмяДанныхФлажка] = Включить; УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка); КонецЕсли; КонецПроцедуры Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт ТекСостояние = ТекСтрока[ИмяДанныхФлажка]; Подчиненные = ТекСтрока.Строки; Если ТекСостояние = 2 Тогда ТекСтрока[ИмяДанныхФлажка] = 0; КонецЕсли; Если Подчиненные.Количество() > 0 Тогда Для каждого Строка из Подчиненные Цикл Строка[ИмяДанныхФлажка] = ТекСостояние; УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка); КонецЦикла; КонецЕсли; КонецПроцедуры // Разбирает строку на две части: до подстроки разделителя и после // // Параметры: // Стр - разбираемая строка // Разделитель - подстрока-разделитель // Режим - 0 - разделитель в возвращаемые подстроки не включается // 1 - разделитель включается в левую подстроку // 2 - разделитель включается в правую подстроку // // Возвращаемое значение: // Правая часть строки - до символа-разделителя // Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт ПраваяЧасть = ""; ПозРазделителя = Найти(Стр, Разделитель); ДлинаРазделителя = СтрДлина(Разделитель); Если ПозРазделителя > 0 Тогда ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя)); Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1))); КонецЕсли; Возврат(ПраваяЧасть); КонецФункции // вОтделитьРазделителем() // Проверяет попадание даты внутрь интервала всключая границы Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт ЛиДатаВНеИнтервале = Ложь Или (Истина И ЗначениеЗаполнено(НачалоПериода) И ПроверяемаяДата < НачалоПериода) Или (Истина И ЗначениеЗаполнено(КонецПериода) И ПроверяемаяДата > КонецПериода); Возврат Не ЛиДатаВНеИнтервале; КонецФункции // Проверяет попадание даты внутрь интервала исключая границы Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт ПустаяДата = Дата("00010101"); ЛиДатаВНеИнтервале = Ложь Или (Истина И НачалоПериода <> ПустаяДата И ПроверяемаяДата <= НачалоПериода) Или (Истина И КонецПериода <> ПустаяДата И ПроверяемаяДата >= КонецПериода); Возврат Не ЛиДатаВНеИнтервале; КонецФункции Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт ПроверочныйФайл = Новый Файл(Каталог); Попытка ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог(); Исключение Если ВыводитьСообщения Тогда Сообщить("Указанный путь """ + Каталог + """ не доступен: " + ОписаниеОшибки()); КонецЕсли; Возврат Ложь; КонецПопытки; Если Не ЭтоКаталог Тогда Если ВыводитьСообщения Тогда Сообщить("Указанный путь """ + Каталог + """ не является каталогом"); КонецЕсли; Возврат Ложь; КонецЕсли; Возврат Истина; КонецФункции // ЛиКаталогДоступен() Функция ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(СтрокаРасширений, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт Расширения = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаРасширений, ",", Истина); Результат = ""; Для Каждого Расширение Из Расширения Цикл Если Результат <> "" Тогда Результат = Результат + "|"; КонецЕсли; ОписаниеРасширения = "(*." + Расширение + ")|*." + Расширение; Если ЗначениеЗаполнено(ОписаниеФормата) Тогда ОписаниеРасширения = ОписаниеФормата + " " + ОписаниеРасширения; КонецЕсли; Результат = Результат + ОписаниеРасширения; КонецЦикла; Если РазрешитьВсеФайлы Тогда Результат = Результат + "|Все файлы (*.*)|*.*"; КонецЕсли; Возврат Результат; КонецФункции // Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных // в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана. // Фиксированные коллекции превращаются в нефиксированные. // // Параметры: // КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция; // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник. // // Возвращаемое значение: // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник. // Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт ТипКоллекции = ТипЗнч(КоллекцияИсточник); Если Ложь Или ТипКоллекции = Тип("Массив") Или ТипКоллекции = Тип("ФиксированныйМассив") #Если Не ТонкийКлиент И Не ВебКлиент Тогда Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных") #КонецЕсли Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Массив; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл КоллекцияПриемник.Добавить(Элемент); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Структура") Или ТипКоллекции = Тип("ФиксированнаяСтруктура") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Структура; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Соответствие") Или ТипКоллекции = Тип("ФиксированноеСоответствие") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Соответствие; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый СписокЗначений; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент); КонецЦикла; Возврат КоллекцияПриемник; #Если Не ТонкийКлиент И Не ВебКлиент Тогда ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки(); КонецЕсли; ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник); Возврат КоллекцияПриемник; #КонецЕсли Иначе Сообщить("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """"); Возврат Неопределено; КонецЕсли; КонецФункции // СкопироватьУниверсальнуюКоллекциюЛкс() #Если Не ТонкийКлиент И Не ВебКлиент Тогда Функция ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ОбязательныеДляПроверкиИмена = """") Экспорт Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли МассивИмен = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбязательныеДляПроверкиИмена, ",", Истина, Ложь); ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст); Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы); КонецЦикла; Возврат МассивИмен; КонецФункции // ПолВТ() Процедура СкопироватьДеревоЛкс(ИсходноеДерево, НовоеДерево, ОчиститьПередЗагрузкой = Истина) Экспорт Если ОчиститьПередЗагрузкой Тогда НовоеДерево.Строки.Очистить(); КонецЕсли; Если ИсходноеДерево.Строки.Количество() = 0 Тогда Возврат; КонецЕсли; Для каждого СтрокаДерева из ИсходноеДерево.Строки Цикл НоваяСтрока = НовоеДерево.Строки.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева); СкопироватьДеревоЛкс(СтрокаДерева, НоваяСтрока, ОчиститьПередЗагрузкой = Истина); КонецЦикла; КонецПроцедуры Функция СоздатьСамоудаляющийсяКомандныйФайлЛкс(Знач ТекстКомандногоФайла = "", Знач КраткоеИмяФайла = "") Экспорт Если ЗначениеЗаполнено(КраткоеИмяФайла) Тогда ПолноеИмяФайла = КаталогВременныхФайлов() + КраткоеИмяФайла + ".bat"; Иначе ПолноеИмяФайла = ПолучитьИмяВременногоФайла("bat"); КонецЕсли; ТекстКомандногоФайла = ТекстКомандногоФайла + " |del """ + ПолноеИмяФайла + """ |"; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстКомандногоФайла); ТекстовыйДокумент.Записать(ПолноеИмяФайла, КодировкаТекста.OEM); Результат = ПолноеИмяФайла; Возврат Результат; КонецФункции // Проверить уникальность строк ТЧ по колонке // // Параметры: // Объект - <тип> - // ИмяТаблицы - <тип> - // ИмяКолонки - <тип>, "" - // // Возвращаемое значение: // Функция ПроверитьУникальностьСтрокТЧПоКолонкеЛкс(Объект, ИмяТаблицы, ИмяКолонки = "", ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено, МассивИсключений = Неопределено) Экспорт Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ИмяКолонки = Объект.Метаданные().ТабличныеЧасти[ИмяТаблицы].Реквизиты[0].Имя; КонецЕсли; Если Истина И МассивИсключений <> Неопределено И ИгнорироватьРегистрДляПростогоСтрокогоТипа Тогда НовыйМассивИсключений = Новый Массив; Для Каждого ИсключаемоеЗначение Из МассивИсключений Цикл Если ТипЗнч(ИсключаемоеЗначение) = Тип("Строка") Тогда ИсключаемоеЗначение = НРег(ИсключаемоеЗначение); КонецЕсли; НовыйМассивИсключений.Добавить(ИсключаемоеЗначение); КонецЦикла; МассивИсключений = НовыйМассивИсключений; КонецЕсли; Успех = Истина; НеуникальныеЗначения = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Объект[ИмяТаблицы], ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа, ОтборСтрок); Для Каждого НеуникальноеЗначение Из НеуникальныеЗначения Цикл Если Истина И МассивИсключений <> Неопределено И МассивИсключений.Найти(НеуникальноеЗначение) <> Неопределено Тогда Продолжить; КонецЕсли; Сообщить("Значение """ + НеуникальноеЗначение + """ встречается в колонке """ + ИмяКолонки + """ более одного раза среди активных строк", СтатусСообщения.Внимание); Успех = Ложь; КонецЦикла; Возврат Успех; КонецФункции Функция ПолучитьПроцессОСЛкс(Знач ИдентификаторПроцесса = Неопределено, Знач НачалоПроцесса = Неопределено, Знач Компьютер = Неопределено, ВызватьИсключениеПриОшибкеПодключенияWMI = Истина, ДопустимоеОтклонениеВремени = 2, МаркерВКоманднойСтроке = Неопределено, ИмяИсполняемогоФайла = Неопределено) Экспорт Если СтрокиРавныЛкс(ИдентификаторПроцесса, "текущий") Тогда ИдентификаторПроцесса = ирКэш.Получить().ПолучитьИдентификаторПроцессаОС(); КонецЕсли; Попытка WMIЛокатор = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер); Исключение Если ВызватьИсключениеПриОшибкеПодключенияWMI Тогда ВызватьИсключение; КонецЕсли; ОписаниеОшибки = ОписаниеОшибки(); Сообщить(ОписаниеОшибки, СтатусСообщения.Внимание); WMIЛокатор = Неопределено; КонецПопытки; Если WMIЛокатор = Неопределено Тогда Возврат Неопределено; КонецЕсли; // ТекстОтбора = "1=1 AND"; Синтаксис WQL такого не допускает ТекстОтбора = ""; Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " ProcessID = " + XMLСтрока(ИдентификаторПроцесса); КонецЕсли; Если ЗначениеЗаполнено(МаркерВКоманднойСтроке) Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " CommandLine LIKE '%" + МаркерВКоманднойСтроке + "%'"; КонецЕсли; Если ЗначениеЗаполнено(ИмяИсполняемогоФайла) Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " Name = '" + ИмяИсполняемогоФайла + "'"; КонецЕсли; Если НачалоПроцесса <> Неопределено Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " CreationDate >= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса - ДопустимоеОтклонениеВремени); ТекстОтбора = ТекстОтбора + " AND CreationDate <= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса + 1 + ДопустимоеОтклонениеВремени); КонецЕсли; Результат = "Процесс ОС с отбором (" + ТекстОтбора + ") не найден"; ТекстЗапросаWQL = "Select * from Win32_Process Where " + ТекстОтбора; ВыборкаПроцессовОС = WMIЛокатор.ExecQuery(ТекстЗапросаWQL); Для Каждого ПроцессОС Из ВыборкаПроцессовОС Цикл Результат = ПроцессОС; Прервать; КонецЦикла; Возврат Результат; КонецФункции Функция ЭтоЛокальныйКомпьютерЛкс(Компьютер) Экспорт Результат = Ложь Или Не ЗначениеЗаполнено(Компьютер) Или Компьютер = "." Или СтрокиРавныЛкс(Компьютер, "localhost") Или Компьютер = "127.0.0.1" #Если Не ВебКлиент Тогда Или СтрокиРавныЛкс(Компьютер, ИмяКомпьютера()) #КонецЕсли ; Возврат Результат; КонецФункции Функция ПолучитьЛитералДатыДляWQLЛкс(Знач Результат) Экспорт Результат = Результат - СмещениеСтандартногоВремени(); Результат = "'" + Формат(Результат, "ДФ='yyyyMMdd HH:mm:ss'; ДП=") + "'"; Возврат Результат КонецФункции Функция ПолучитьФайлWMIЛкс(ПолноеИмяФайла, КомпьютерИлиИмя = Неопределено) Экспорт СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(КомпьютерИлиИмя); ФайлыWMI = СлужбаWMI.ExecQuery("Select * from CIM_Datafile where name='" + ЗаменитьСлешиНаДвойныеЛкс(ПолноеИмяФайла) + "'"); Для каждого ФайлWMI Из ФайлыWMI цикл КонецЦикла; Возврат ФайлWMI; КонецФункции // ПолучитьФайлWMIИис() Процедура ЗаполнитьДоступныеСборкиПлатформыЛкс(СборкиПлатформы, Компьютер = "", ТипыComКлассов = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда СборкиПлатформы = Обработки.ирУправлениеСлужбамиСерверов1С.Создать().СборкиПлатформы; #КонецЕсли // Оба варианта пришлось оставить, т.к. WMI вариант очень долгий Если ирОбщий.ЭтоИмяЛокальногоСервераЛкс(Компьютер) Тогда Инсталлер = Новый COMОбъект("WindowsInstaller.Installer"); Продукты = Инсталлер.Products; Иначе СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер); Если СлужбаWMI = Неопределено Тогда Возврат; КонецЕсли; Продукты = СлужбаWMI.ExecQuery("SELECT * FROM Win32_Product WHERE Vendor LIKE '1C' OR Vendor LIKE '1С'"); КонецЕсли; Для Каждого Продукт Из Продукты Цикл Если ЭтоИмяЛокальногоСервераЛкс(Компьютер) Тогда Попытка ПубликаторПродукта = Инсталлер.ProductInfo(Продукт, "Publisher"); Исключение Продолжить; КонецПопытки; Если Истина И ПубликаторПродукта <> "1C" // латинские буквы И ПубликаторПродукта <> "1С" // русские буквы И ПубликаторПродукта <> "1С-Софт" // русские буквы Тогда Продолжить; КонецЕсли; //НаименованиеПродукта = Инсталлер.ProductInfo(Продукт, "ProductName"); КаталогВерсии = Инсталлер.ProductInfo(Продукт, "InstallLocation"); //СтрокаРелиза = Инсталлер.ProductInfo(Продукт, "VersionString"); Иначе КаталогВерсии = Продукт.InstallLocation; КонецЕсли; СтрокаТаблицыСборок = СборкиПлатформы.Добавить(); СтрокаТаблицыСборок.Каталог = КаталогВерсии; ФайлПолученияВерсии = Неопределено; Если ТипыComКлассов <> Неопределено Тогда Для Каждого ТипКласса Из ТипыComКлассов Цикл //Если Метаданные().ТабличныеЧасти.СборкиПлатформы.Реквизиты.Найти(ВыборкаКлассов.Имя) = Неопределено Тогда // Продолжить; //КонецЕсли; ФайлКомпоненты = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\" + ТипКласса.КлючевойФайл, Компьютер); СтрокаТаблицыСборок[ТипКласса.Имя] = ФайлКомпоненты <> Неопределено; Если СтрокаТаблицыСборок[ТипКласса.Имя] Тогда ФайлПолученияВерсии = ФайлКомпоненты; КонецЕсли; КонецЦикла; КонецЕсли; ФайлСерверногоПриложения = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\ragent.exe", Компьютер); СтрокаТаблицыСборок.Сервер = ФайлСерверногоПриложения <> Неопределено; Если СтрокаТаблицыСборок.Сервер Тогда ФайлПолученияВерсии = ФайлСерверногоПриложения; КонецЕсли; Если ФайлПолученияВерсии <> Неопределено Тогда СтрокаТаблицыСборок.ФайлыСуществуют = Истина; СтрокаТаблицыСборок.x64 = ирКэш.Это64битнаяОСЛкс() И Найти(СтрокаТаблицыСборок.Каталог, "(x86)") = 0; СтрокаТаблицыСборок.СборкаПлатформы = ФайлПолученияВерсии.Version; СтрокаВерсии = ФайлПолученияВерсии.Version; Если ЗначениеЗаполнено(СтрокаВерсии) Тогда СтрокаТаблицыСборок.СборкаПлатформы = СтрокаВерсии; Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаВерсии); ИзданиеПлатформы = Фрагменты[0] + "." + Фрагменты[1]; СтрокаТаблицыСборок.ИзданиеПлатформы = ИзданиеПлатформы; СтрокаТаблицыСборок.Порядок = Фрагменты[0] * 10000000 + Фрагменты[1] * 1000000 + Фрагменты[2] * 10000 + Фрагменты[3]; КонецЕсли; КонецЕсли; КонецЦикла; СборкиПлатформы.Сортировать("Порядок Убыв, ФайлыСуществуют Убыв, СборкаПлатформы Убыв, x64"); КонецПроцедуры Функция ЗаменитьСлешиНаДвойныеЛкс(Строка) Экспорт Результат = СтрЗаменить(Строка, "\", "\\"); Возврат Результат; КонецФункции Функция ПолучитьТекстРезультатаКомандыОСЛкс(Знач СтрокаКоманды = "", ОжидатьЗавершения = Истина, Знач ИмяКомпьютера = "", Элевация = Ложь) Экспорт Платформа = ирКэш.Получить(); Если Ложь Тогда Платформа = Обработки.ирПлатформа.Создать(); КонецЕсли; ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла("txt")); Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаКоманды, ФайлРезультата.Путь,, ФайлРезультата.Имя, ОжидатьЗавершения, Элевация); Если ОжидатьЗавершения Тогда Если ФайлРезультата.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, КодировкаТекста.OEM); УдалитьФайлы(ФайлРезультата.ПолноеИмя); Результат = ТекстовыйДокумент.ПолучитьТекст(); Иначе Результат = Неопределено; КонецЕсли; Иначе Результат = ФайлРезультата.ПолноеИмя; КонецЕсли; Возврат Результат; КонецФункции Процедура ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, НичегоНеДелатьБезТранзакции = Ложь) Экспорт Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(НаборЗаписей)); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); КорневойТип = ПолучитьПервыйФрагментЛкс(ПространствоБлокировок); Если ирОбщий.ПолучитьТипТаблицыБДЛкс(ПространствоБлокировок) = "Перерасчет" Тогда Возврат; //ПространствоБлокировок = ОбъектМД.Родитель().ПолноеИмя(); КонецЕсли; Если Ложь Или Не ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей"; КонецЕсли; ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл Если ЭлементОтбора.Использование Тогда ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, ЭлементОтбора.Значение); КонецЕсли; КонецЦикла; Блокировка.Заблокировать(); КонецПроцедуры Процедура ЗаблокироватьСсылкуВТранзакцииЛкс(СсылочныйОбъект, НичегоНеДелатьБезТранзакции = Ложь) Экспорт Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = СсылочныйОбъект.Метаданные(); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылочныйОбъект.Ссылка); Блокировка.Заблокировать(); КонецПроцедуры Процедура ЗаблокироватьКонстантуЛкс(КонстантаМенеджерЗначения, НичегоНеДелатьБезТранзакции = Ложь) Экспорт Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(КонстантаМенеджерЗначения)); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); Блокировка.Заблокировать(); КонецПроцедуры Функция ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиИменаБД = Ложь, ЭтоТабличнаяЧасть = Ложь, ИспользоватьИмяПоляВместоПустогоПредставления = Ложь) Экспорт ПредставлениеПоля = СтрокаПоля.ИмяПоля; Если ПустаяСтрока(ПредставлениеПоля) Тогда Если ЛиИменаБД Тогда // Антибаг платформы. У некоторых полей почему то пустое имя, а должно быть непустое. https://partners.v8.1c.ru/forum/topic/1275356#m_1275356 Если ЭтоТабличнаяЧасть Тогда Если ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_KeyField") Тогда ПредставлениеПоля = "НомерСтроки"; ИначеЕсли Найти(СтрокаПоля.ИмяПоляХранения, "IDRRef") > 0 Тогда ПредставлениеПоля = "Ссылка"; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(ПредставлениеПоля) Тогда Если ЛиИменаБД Тогда НИмяПоляХранения = НРег(СтрокаПоля.ИмяПоляХранения); НМаркерПоляТипаЗначения = НРег("TYPE"); НМаркерПоляТипаСсылки = НРег("TRef"); //МаркерПоляЗначенияСсылки = НРег("RRef"); Если Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаСсылки)) = НМаркерПоляТипаСсылки Тогда ПредставлениеПоля = ПредставлениеПоля + "_ТипСсылки"; ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаЗначения)) = НМаркерПоляТипаЗначения Тогда ПредставлениеПоля = ПредставлениеПоля + "_ТипЗначения"; //ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляЗначенияСсылки)) = НМаркерПоляЗначенияСсылки Тогда // ПредставлениеПоля = ПредставлениеПоля + "_Ссылка"; КонецЕсли; КонецЕсли; ИначеЕсли ИспользоватьИмяПоляВместоПустогоПредставления Тогда ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения; КонецЕсли; Возврат ПредставлениеПоля; КонецФункции Функция ПолучитьПредставлениеСтруктурыЛкс(Структура) Экспорт #Если Сервер И Не Сервер Тогда Структура = Новый Структура; #КонецЕсли ПредставлениеСтруктуры = ""; Для Каждого КлючИЗначение Из Структура Цикл Если ПредставлениеСтруктуры <> "" Тогда ПредставлениеСтруктуры = ПредставлениеСтруктуры + ", "; КонецЕсли; ПредставлениеСтруктуры = ПредставлениеСтруктуры + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение; КонецЦикла; Возврат ПредставлениеСтруктуры; КонецФункции Функция ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаСтруктурыБД, ЛиСтруктураДанныхВИменахБД = Ложь, СтрокаТаблицыХранения, ЛиПредставлениеВИменахБД = Ложь) Экспорт ЭтоТабличнаяЧасть = СтрокаТаблицыХранения.Назначение = "ТабличнаяЧасть"; ПредставлениеИндекса = ""; Разделитель = ""; Для каждого СтрокаПоля Из СтрокаИндексаСтруктурыБД.Поля Цикл Если ЛиПредставлениеВИменахБД Тогда ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения; Иначе ПредставлениеПоля = ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиСтруктураДанныхВИменахБД, ЭтоТабличнаяЧасть, Истина); КонецЕсли; ПредставлениеИндекса = ПредставлениеИндекса + Разделитель + ПредставлениеПоля; Разделитель = ", "; КонецЦикла; Возврат ПредставлениеИндекса; КонецФункции Процедура ОбработатьВыборкуСтруктурыХраненияБДЛкс(Знач Результат, ЛиИменаБД = Ложь, ВычислитьИменаИндексов = Истина) Экспорт #Если Сервер И Не Сервер Тогда Результат = Новый ТаблицаЗначений; #КонецЕсли //Результат.Колонки.ИмяТаблицыХранения.Имя = "ИмяТаблицыХраненияСРегистромБукв"; Результат.Колонки.Добавить("КраткоеИмяТаблицыХранения", Новый ОписаниеТипов("Строка")); //Результат.Колонки.Добавить("ИмяТаблицыХранения", Новый ОписаниеТипов("Строка")); Для Каждого СтрокаТаблицыХранения Из Результат Цикл // Антибаг платформы 8.2.16 У ряда назначений таблиц ИмяТаблицы пустое http://partners.v8.1c.ru/forum/thread.jsp?id=1090307#1090307 Если ПустаяСтрока(СтрокаТаблицыХранения.ИмяТаблицы) Тогда МетаПолноеИмяТаблицы = ""; Если ЗначениеЗаполнено(СтрокаТаблицыХранения.Метаданные) Тогда МетаПолноеИмяТаблицы = СтрокаТаблицыХранения.Метаданные + "."; КонецЕсли; Если СтрокаТаблицыХранения.Назначение = "РегистрацияИзменений" Тогда СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + "Изменения"; Иначе СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + СтрокаТаблицыХранения.Назначение; КонецЕсли; КонецЕсли; //СтрокаТаблицыХранения.ИмяТаблицыХранения = НРег(ирОбщий.ПолучитьПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХраненияСРегистромБукв)); // В режим ЛиИменаБД=Ложь Document209.VT2672->VT2672 СтрокаТаблицыХранения.КраткоеИмяТаблицыХранения = НРег(ирОбщий.ПолучитьПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХранения)); Если ВычислитьИменаИндексов Тогда СтрокаТаблицыХранения.Индексы.Колонки.Добавить("ИмяИндекса", Новый ОписаниеТипов("Строка")); Для Каждого СтрокаИндексаХранения Из СтрокаТаблицыХранения.Индексы Цикл ПредставлениеИндекса = ирОбщий.ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаХранения, ЛиИменаБД, СтрокаТаблицыХранения); СтрокаИндексаХранения.ИмяИндекса = "Индекс(" + ПредставлениеИндекса + ")"; КонецЦикла; КонецЕсли; КонецЦикла; Результат.Индексы.Добавить("КраткоеИмяТаблицыХранения"); КонецПроцедуры Функция ПолучитьСтруктуруХраненияБДЛкс(Знач ОтборПоМетаданным = Неопределено, ЛиИменаБД = Ложь, ВычислитьИменаИндексов = Истина, АдресЧужойСхемыБД = "") Экспорт Если ОтборПоМетаданным = Неопределено Тогда #Если Клиент Тогда Состояние("Получение структуры БД"); #КонецЕсли ИначеЕсли ТипЗнч(ОтборПоМетаданным) <> Тип("Массив") Тогда Массив = Новый Массив; Массив.Добавить(ОтборПоМетаданным); ОтборПоМетаданным = Массив; КонецЕсли; Если ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда СтруктураСхемы = ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД); Если ЛиИменаБД Тогда ГлавнаяТаблица = СтруктураСхемы.СУБД; Иначе ГлавнаяТаблица = СтруктураСхемы.SDBL; КонецЕсли; Если ОтборПоМетаданным <> Неопределено Тогда Результат = ГлавнаяТаблица.СкопироватьКолонки(); Если ГлавнаяТаблица.Индексы.Количество() = 0 Тогда ГлавнаяТаблица.Индексы.Добавить("Метаданные"); КонецЕсли; Для Каждого ИмяМД Из ОтборПоМетаданным Цикл Для Каждого СтрокаТаблицы Из ГлавнаяТаблица.НайтиСтроки("Метаданные", ИмяМД) Цикл ЗаполнитьЗначенияСвойств(Результат.Добавить(), СтрокаТаблицы); КонецЦикла; КонецЦикла; Иначе Результат = ГлавнаяТаблица; КонецЕсли; Иначе Результат = ПолучитьСтруктуруХраненияБазыДанных(ОтборПоМетаданным, ЛиИменаБД); КонецЕсли; ОбработатьВыборкуСтруктурыХраненияБДЛкс(Результат, ЛиИменаБД, ВычислитьИменаИндексов); Если ОтборПоМетаданным = Неопределено Тогда #Если Клиент Тогда Состояние(""); #КонецЕсли КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД) Экспорт Если Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда Возврат Неопределено; Иначе Результат = ПолучитьИзВременногоХранилища(АдресЧужойСхемыБД); КонецЕсли; Возврат Результат; КонецФункции Процедура ОбновитьПовторноИспользуемыеЗначенияЛкс() Экспорт Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ирПортативный.ОбновитьПовторноИспользуемыеЗначенияЛкс(); Иначе ОбновитьПовторноИспользуемыеЗначения(); КонецЕсли; КонецПроцедуры Функция ПолучитьСовместимоеЗначениеПараметраЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт Результат = ЗначениеПараметра; ТипЗначенияПараметра = ТипЗнч(Результат); Если Истина И ТипЗначенияПараметра = Тип("Массив") И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда СписокЗначений = Новый СписокЗначений; ПреобразованиеУспешно = Истина; Для Каждого ЭлементМассива Из ЗначениеПараметра Цикл Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда СписокЗначений.Добавить(ЭлементМассива); Иначе ПреобразованиеУспешно = Ложь; Прервать; КонецЕсли; КонецЦикла; Если ПреобразованиеУспешно Тогда Результат = СписокЗначений; Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из массива в список значений", СтатусСообщения.Внимание); КонецЕсли; Иначе МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра); Если МетаданныеТипаЗначения <> Неопределено Тогда ТипТаблицы = ПолучитьТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя()); Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда Результат = ЗначениеПараметра.Выгрузить(); Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из табличной части в таблицу значений", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда #Если Сервер И Не Сервер Тогда ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов; #КонецЕсли Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(ЗначениеПараметра); Если Результат <> ЗначениеПараметра Тогда Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано """ + ЗначениеПараметра + """->""" + Результат + """", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт ТекстЗапроса = ДинамическийСписок.ТекстЗапроса; Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица; КонецЕсли; Запрос = Новый Запрос(ТекстЗапроса); выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; ТекущаяГруппировка = выхНастройкаКомпоновки; Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл Если ПолеГруппировки.Использование Тогда ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле); КонецЕсли; КонецЦикла; НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура); Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл Если ДоступноеПоле.Папка Тогда Продолжить; КонецЕсли; НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле); КонецЦикла; НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(выхНастройкаКомпоновки); НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Отбор); НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Параметры); НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Порядок); НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.УсловноеОформление); выхНастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO); выхСхема = ПолучитьСхемуКомпоновкиПоЗапросуЛкс(Запрос); КонецПроцедуры // Если передана НастройкаКомпоновкиПриемник, то в качестве результата вернется ее копия! Функция СкопироватьНастройкиКомпоновкиЛкс(НастройкаКомпоновкиИлиДинамическийСписокИсточник, Знач НастройкаКомпоновкиПриемник = Неопределено, КопироватьОтбор = Ложь, КопироватьПараметры = Ложь, КопироватьПорядок = Ложь, КопироватьУсловноеОформление = Ложь) Экспорт #Если Сервер И Не Сервер Тогда НастройкаКомпоновкиИсточник = Новый НастройкиКомпоновкиДанных; #КонецЕсли Если НастройкаКомпоновкиПриемник = Неопределено Тогда НастройкаКомпоновкиПриемник = Новый НастройкиКомпоновкиДанных; КонецЕсли; Если ТипЗнч(НастройкаКомпоновкиИлиДинамическийСписокИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор; Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыДанных; УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление; Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок; Иначе // ДинамическийСписок Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор; Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Параметры; УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление; Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок; КонецЕсли; НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновкиПриемник); Если КопироватьОтбор Тогда НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор); КонецЕсли; Если КопироватьПараметры Тогда НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(Параметры); КонецЕсли; Если КопироватьПорядок Тогда НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление); КонецЕсли; Если КопироватьУсловноеОформление Тогда НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление); КонецЕсли; НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO); Возврат НастройкаКомпоновкиПриемник; КонецФункции // СкопироватьОтборКомпоновкиЛкс() Функция ПолучитьРасширениеФайловДляОтладкиЛкс() Экспорт Результат = "deb"; Возврат Результат; КонецФункции Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Наименование = "") Если Не ЗначениеЗаполнено(Наименование) Тогда Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + СтруктураПараметров.Объект; КонецЕсли; Успех = Ложь; ДоступноФоновоеЗадание = Не (Истина И ТранзакцияАктивна() И ирКэш.ЭтоФайловаяБазаЛкс() // В файловой базе даже 8.3 не получится, т.к. там не истинной параллельности //И (Ложь // Или РежимСовместимостиМеньше8_3_4Лкс() // Или ирКэш.ЭтоФоновоеЗаданиеЛкс()) ); Если Истина И Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено И ДоступноФоновоеЗадание Тогда Попытка ХранимоеЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров); ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент(); ОбъектДляОтладки.Наименование = Наименование; ОбъектДляОтладки.XML = ХранимоеЗначение; выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки); Успех = Истина; Исключение Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки(); КонецПопытки; Если Успех Тогда Результат = "Данные помещены в справочник ""Объекты для отладки"". Скопируйте эту строку и используйте команду ""Отладить отложенный объект""." + " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")"; КонецЕсли; Иначе //выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор); //Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""." //+ " Адрес """ + выхОбъектДляОтладки + """"; КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Успех = Ложь; Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда РасширениеФайловДляОтладки = ПолучитьРасширениеФайловДляОтладкиЛкс(); Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Наименование = Платформа.ПолучитьИдентификаторИзПредставления(Наименование); ИмяФайла = КаталогОбъектовДляОтладки + "\" + Наименование + "." + РасширениеФайловДляОтладки; ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла); Попытка СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя); Успех = Истина; Исключение Сообщить("Ошибка сохранения файла для отладки: " + ОписаниеОшибки()); КонецПопытки; Если Успех Тогда выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя; Результат = "Данные помещены в файл. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""." + " Файл """ + выхОбъектДляОтладки + """"; КонецЕсли; Иначе Сообщить("Рекомендуется в общих настройках инструментов задать каталог объектов для отладки."); КонецЕсли; Если Не Успех Тогда Если ТранзакцияАктивна() И Не ДоступноФоновоеЗадание Тогда Попытка ОтменитьТранзакцию(); Успех = Истина; Исключение // Системная транзакция записи объекта КонецПопытки; Если Не Успех Тогда Результат = "Невозможно отменить транзакцию записи объекта для сохранения объекта для отладки в общие настройки"; Иначе Сообщить("Транзакция была отменена для сохранения объекта для отладки в общие настройки"); КонецЕсли; Иначе Успех = Истина; КонецЕсли; Если Успех Тогда Успех = Ложь; Попытка КлючНастройки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураПараметров); Успех = Истина; Исключение Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки(); КонецПопытки; КонецЕсли; Если Успех Тогда Результат = "Данные помещены в настройку """ + КлючНастройки + """. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""." + " Пользователь """ + ИмяПользователя() + """"; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьКаталогОбъектовДляОтладкиЛкс(ДляСервера = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ирПортативный = Обработки.ирПортативный.Создать(); #КонецЕсли Если ирКэш.ЛиПортативныйРежимЛкс() Тогда КаталогОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс(); Иначе //ИмяФайла = ПолучитьИмяВременногоФайла(РасширениеФайловДляОтладки); КаталогОбъектовДляОтладки = ВосстановитьЗначениеЛкс("КаталогОбъектовДляОтладки"); #Если Клиент Тогда Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда КаталогОбъектовДляОтладки = ирКэш.Получить().КаталогФайловогоКэша; КонецЕсли; #КонецЕсли КонецЕсли; Возврат КаталогОбъектовДляОтладки; КонецФункции Функция ИмяПродуктаЛкс() Экспорт Возврат "ИнструментыРазработчикаTormozit"; КонецФункции Функция ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Параметры) Экспорт // Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525 //СтруктураЗапроса.Параметры = ПолучитьКопиюОбъектаЛкс(Объект.Параметры); Структура = Новый Структура(); Для Каждого КлючИЗначение Из Параметры Цикл ЗначениеПараметра = ПолучитьСовместимоеЗначениеПараметраЛкс(КлючИЗначение.Значение, КлючИЗначение.Ключ); Структура.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(ЗначениеПараметра)); КонецЦикла; Возврат Структура; КонецФункции Функция СкопироватьЗапросЛкс(ЗапросИсточник, ЗапросПриемник = Неопределено) Экспорт Если ЗапросПриемник = Неопределено Тогда ЗапросПриемник = Новый Запрос; КонецЕсли; ЗапросПриемник.Текст = ЗапросИсточник.Текст; ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ЗапросИсточник.Параметры, ЗапросПриемник.Параметры); Возврат ЗапросПриемник; КонецФункции // СкопироватьЗапросЛкс() Функция ПолучитьТекстЗапросаВсехТиповСсылокЛкс(ИмяВременнойТаблицы = "ВсеТипыСсылок", Знач ОписаниеТипов = Неопределено) Экспорт Если ОписаниеТипов = Неопределено Тогда ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс(); КонецЕсли; #Если Сервер И Не Сервер Тогда ОписаниеВсехТипов = Новый ОписаниеТипов; #КонецЕсли ТекстТаблицыТипов = ""; Для Каждого Тип Из ОписаниеТипов.Типы() Цикл ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя(); НоваяСтрока = "ВЫБРАТЬ ТИП(" + ПолноеИмя + ") КАК Тип, """ + ПолноеИмя + """ КАК Имя" + Символы.ПС; Если ТекстТаблицыТипов <> "" Тогда ТекстТаблицыТипов = ТекстТаблицыТипов + "ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС; Иначе Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда НоваяСтрока = НоваяСтрока + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС; КонецЕсли; КонецЕсли; ТекстТаблицыТипов = ТекстТаблицыТипов + НоваяСтрока; КонецЦикла; //ТекстТаблицыТипов = ТекстТаблицыТипов + " ИНДЕКСИРОВАТЬ ПО Тип"; // По такому типу поля нельзя индексировать Возврат ТекстТаблицыТипов; КонецФункции Функция ПолучитьТекстЗапросаДатВДиапазонеЛкс(ИмяВременнойТаблицы = "ДатыДиапазона") Экспорт Текст = "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d) КАК Период |"; Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда Текст = Текст + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС; КонецЕсли; Текст = Текст + "ИЗ | (ВЫБРАТЬ 0 КАК a | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК aa | ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК b | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК bb | ПО (ИСТИНА) | ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК c | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК cc | ПО (ИСТИНА) | ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ | 0 КАК d | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК dd | ПО (ИСТИНА) |ГДЕ | aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)"; Возврат Текст; КонецФункции Функция ПолучитьСобственноеВнешнееСоединениеЛкс(ИнициализироватьИнтерфейсИР = Ложь, выхИнтерфейсИР = Неопределено) Экспорт ИмяПользователяВнешнегоСоединения = ""; ПарольПользователяВнешнегоСоединения = ""; Если ПользователиИнформационнойБазы.ПолучитьПользователей().Количество() > 0 Тогда ИмяПользователяВнешнегоСоединения = ИмяПользователя() + "_ВнешнееСоединение"; Попытка ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяВнешнегоСоединения); Исключение Сообщить("Не удалось выполнить поиск служебного пользователя: " + ОписаниеОшибки()); // Разделенная база в неразделенном сеансе Возврат Неопределено; КонецПопытки; Если ПользовательИБ = Неопределено Тогда ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя(); ПользовательИБ.Имя = ИмяПользователяВнешнегоСоединения; ПользовательИБ.ПолноеИмя = ИмяПользователяВнешнегоСоединения; Сообщить("Создан служебный пользователь ИБ с именем """ + ИмяПользователяВнешнегоСоединения + """"); КонецЕсли; ТекущийПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь(); ЗаполнитьЗначенияСвойств(ПользовательИБ, ТекущийПользовательИБ,, "Имя, ПолноеИмя"); ПользовательИБ.Роли.Очистить(); Для Каждого Роль Из ТекущийПользовательИБ.Роли Цикл ПользовательИБ.Роли.Добавить(Роль); КонецЦикла; ПарольПользователяВнешнегоСоединения = "" + Новый УникальныйИдентификатор; ПользовательИБ.ПоказыватьВСпискеВыбора = Ложь; ПользовательИБ.АутентификацияОС = Ложь; ПользовательИБ.АутентификацияСтандартная = Истина; ПользовательИБ.Пароль = ПарольПользователяВнешнегоСоединения; ПользовательИБ.Записать(); КонецЕсли; Результат = ЗапуститьСеансПодПользователемЛкс(ИмяПользователяВнешнегоСоединения, ПарольПользователяВнешнегоСоединения, "ComConnector"); Если ирКэш.ЛиПортативныйРежимЛкс() Тогда выхИнтерфейсИР = Результат.ВнешниеОбработки.Создать(ирПортативный.ИспользуемоеИмяФайла, Ложь); Иначе выхИнтерфейсИР = Результат; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ТабличныйДокумент - ТабличныйДокумент // ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных // Поля - Строка(0,П), Массив - Если строка, то через запятую перечисленные имена полей. // Область - ВыделенныеОбластиТабличногоДокумента, Массив, ОбластьЯчеекТабличногоДокумента - Если не указано, используются выделенные области // Функция ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, Знач ДанныеРасшифровки = Неопределено, Знач Поля = "", Знач Область = Неопределено) Экспорт Перем ЭтотОбъект, Результат; //НАЧАЛО.СЕРВИС Если Истина И ТипЗнч(Поля) = Тип("Строка") И Не ПустаяСтрока(Поля) Тогда МассивИменПолей = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Поля, ",", Истина); ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда МассивИменПолей = Поля; Иначе МассивИменПолей = Новый Массив; КонецЕсли; ТаблицаРезультата = Неопределено; МассивСсылок = Новый Массив; АвтоПоля = МассивИменПолей.Количество() = 0; Если ТипЗнч(Область) = Тип("Неопределено") Тогда КоллекцияОбластей = ТабличныйДокумент.ВыделенныеОбласти; ИначеЕсли ТипЗнч(Область) = Тип("Массив") Тогда КоллекцияОбластей = Область; ИначеЕсли ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда КоллекцияОбластей = Новый Массив; КоллекцияОбластей.Добавить(Область); КонецЕсли; Если ДанныеРасшифровки <> Неопределено Тогда ЭлементыРасшифровки = ДанныеРасшифровки.Элементы; КонецЕсли; НачальноеКоличество = КоллекцияОбластей.Количество(); Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл Область = КоллекцияОбластей[НачальноеКоличество - СчетчикВыделенныеОбласти]; Если Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Колонки Тогда Лево = Область.Лево; Право = Область.Право; Верх = 1; Низ = ТабличныйДокумент.ВысотаТаблицы; ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Строки Тогда Лево = 1; Право = ТабличныйДокумент.ШиринаТаблицы; Верх = Область.Верх; Низ = Область.Низ; ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда Лево = Область.Лево; Право = Область.Право; Верх = Область.Верх; Низ = Область.Низ; Иначе Продолжить; КонецЕсли; Для НомерСтроки = Верх по Низ Цикл КлючПолучен = Ложь; СтруктураПолей = Новый Структура; Для НомерКолонки = Лево по Право Цикл ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; Расшифровка = ОбластьЯчейки.Расшифровка; Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда Если ЭлементыРасшифровки = Неопределено Тогда ВызватьИсключение "В табличном документа найден идентификатор расшифровки, но не переданы данные расшифровки"; КонецЕсли; ЭлементРасшифровкиПоля = ЭлементыРасшифровки[Расшифровка]; Если НомерСтроки = Верх Тогда Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; Для Каждого ИмяПоля Из МассивИменПолей Цикл ТаблицаРезультата.Колонки.Добавить(ИмяПоля); КонецЦикла; КонецЕсли; Если АвтоПоля Тогда ИмяПоля = ЭлементРасшифровкиПоля.ПолучитьПоля()[0].Поле; МассивИменПолей.Добавить(ИмяПоля); ИмяКолонки = СтрЗаменить(ИмяПоля, ".", ""); Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда ТаблицаРезультата.Колонки.Добавить(ИмяКолонки); КонецЕсли; КонецЕсли; КонецЕсли; КлючПолучен = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровкиПоля, МассивИменПолей, СтруктураПолей); Если Истина И КлючПолучен И (Ложь Или НомерКолонки = Право Или Не АвтоПоля) Тогда Прервать; КонецЕсли; ИначеЕсли ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Расшифровка, Ложь) Тогда ИмяКолонки = "Ссылка"; СтруктураПолей = Новый Структура(ИмяКолонки, Расшифровка); КлючПолучен = Истина; Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; КонецЕсли; Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда ТаблицаРезультата.Колонки.Добавить(ИмяКолонки); КонецЕсли; КонецЕсли; КонецЦикла; Если КлючПолучен Тогда Если ТаблицаРезультата.НайтиСтроки(СтруктураПолей).Количество() = 0 Тогда ЗаполнитьЗначенияСвойств(ТаблицаРезультата.Добавить(), СтруктураПолей); КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; КонецЕсли; Результат = ТаблицаРезультата; Возврат Результат; КонецФункции // Извлекаемые значения помещаются в структуру // Параметры: // ЭлементРасшифровкиПоля - ЭлементРасшифровкиКомпоновкиДанныхГруппировка, ЭлементРасшифровкиКомпоновкиДанныхПоля // Поля - Строка(0,П), Массив // СтруктураПолей - Структура // Функция ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровкиПоля, Знач Поля = "", Знач СтруктураПолей = Неопределено) Экспорт Если СтруктураПолей = Неопределено Тогда СтруктураПолей = Новый Структура; КонецЕсли; Если Истина И ТипЗнч(Поля) = Тип("Строка") И Не ПустаяСтрока(Поля) Тогда МассивИменПолей = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Поля, ",", Истина); ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда МассивИменПолей = Поля; Иначе МассивИменПолей = Новый Массив; КонецЕсли; Результат = Ложь; Если ТипЗнч(ЭлементРасшифровкиПоля) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда ТекущиеЗначенияПолей = ЭлементРасшифровкиПоля.ПолучитьПоля(); Если ТекущиеЗначенияПолей.Количество() > 0 Тогда //ЗначениеПоля = ТекущиеЗначенияПолей[0]; Для Каждого ИмяПоля Из МассивИменПолей Цикл ЗначениеПоля = ТекущиеЗначенияПолей.Найти(ИмяПоля); ИмяСвойства = СтрЗаменить(ИмяПоля, ".", ""); Если Истина И ЗначениеПоля <> Неопределено И Не СтруктураПолей.Свойство(ИмяСвойства) Тогда СтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение); Если СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда Результат = Истина; Прервать КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если Не Результат Тогда РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей(); Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, СтруктураПолей); Если Результат Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьСоединениеСУБД(ИмяСервера = "", ИмяБД = "", ИмяПользователя = "", Пароль = "") Экспорт #Если Клиент Тогда Если Не ЗначениеЗаполнено(ИмяСервера) Тогда ФормаПодключения = ОткрытьФормуСоединенияСУБДЛкс(Истина); Возврат ФормаПодключения.Соединение; КонецЕсли; #КонецЕсли КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли ИсточникДанных = КонсольЗапросов.ПолучитьСтруктуруИсточникаДанныхADO(); ИсточникДанных.Платформа = 11; // ADO-SQLOLEDB ИсточникДанных.БазаСервер = ИмяСервера; ИсточникДанных.БазаИмя = ИмяБД; ИсточникДанных.АутентификацияОС = Не ЗначениеЗаполнено(ИмяПользователя); ИсточникДанных.Пользователь = ИмяПользователя; ИсточникДанных.Пароль = Пароль; СоединениеADO = Неопределено; ОшибкиПодключения = Неопределено; Если Не КонсольЗапросов.ConnectADO(ИсточникДанных, СоединениеADO,, ОшибкиПодключения) Тогда СообщениеОбОшибке = "Ошибки подключения к серверу MSSQL:"; Для каждого ОшибкаПодключения Из ОшибкиПодключения Цикл СообщениеОбОшибке = СообщениеОбОшибке + Символы.ПС + ОшибкаПодключения; КонецЦикла; Сообщить(СообщениеОбОшибке); СоединениеADO = Неопределено; КонецЕсли; Возврат СоединениеADO; КонецФункции Функция ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ИмяЗапроса = "Запрос для отладки", Параметры = Неопределено, Автоподключение = Ложь) Экспорт КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли КонсольЗапросов.ОткрытьЗапросБД(ТекстЗапроса, ИмяЗапроса, Параметры, Автоподключение); КонецФункции Функция HTTPСоединение(ИмяСервера) Экспорт Попытка Результат = Новый HTTPСоединение(ИмяСервера); Исключение // Антибаг платформы https://bugboard.v8.1c.ru/error/000013833.html Результат = Новый HTTPСоединение(ИмяСервера,,,, Новый ИнтернетПрокси(Ложь)); КонецПопытки; Возврат Результат; КонецФункции Процедура ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(ИмяФайлаВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляТекущейВнешнейОбработки, ДатаИзмененияВнешнейОбработки, НаСервере = Ложь) Экспорт Если НаСервере Тогда ирСервер.ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(ИмяФайлаВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляТекущейВнешнейОбработки, ДатаИзмененияВнешнейОбработки); Иначе мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда Сообщить("В общих настройках инструментов не задан каталог объектов для отладки! Сохранение внешней обработки не выполнено.", СтатусСообщения.Внимание); Возврат; КонецЕсли; ИмяФайлаВнешнейОбработки = КаталогОбъектовДляОтладки + "\" + ИмяВнешнейОбработки + ".epf"; ФайлВнешнейОбработки = Новый Файл(ИмяФайлаВнешнейОбработки); Если Ложь Или (Истина И ФайлВнешнейОбработки.Существует() И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() > ДатаИзмененияВнешнейОбработки И мПлатформа.ФайловыйКэшАлгоритмовДопускаетРедактирование) Или (Истина И ФайлВнешнейОбработки.Существует() И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() = ДатаИзмененияВнешнейОбработки И ТекстМодуляТекущейВнешнейОбработки = ТекстМодуля) Тогда Возврат; КонецЕсли; мПлатформа.СформироватьВнешнююОбработку(ИмяВнешнейОбработки, ФайлВнешнейОбработки, ТекстМодуля); ДатаИзмененияВнешнейОбработки = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс(); КонецЕсли; КонецПроцедуры Процедура ЗаписатьДокументDOMВФайлЛкс(Знач ДокументДом, Знач ИмяФайла) Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.ОткрытьФайл(ИмяФайла); ЗаписьДом = Новый ЗаписьDOM; ЗаписьДом.Записать(ДокументДом, ЗаписьXML); ЗаписьXML.Закрыть(); КонецПроцедуры Функция ПрочитатьФайлВДокументDOMЛкс(Знач ИмяФайла) Экспорт ЧтениеXML = Новый ЧтениеXML; ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, Ложь); ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения); ПостроительДом = Новый ПостроительDOM(); ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML); ЧтениеXML.Закрыть(); Возврат ДокументДОМ; КонецФункции Функция АдаптироватьРасширениеЛкс(ТолькоПриНаличииПодключенныхКоманд = Ложь) Экспорт #Если ТонкийКлиент Или ВебКлиент Тогда Результат = ирСервер.АдаптироватьРасширениеЛкс(); Возврат Результат; #КонецЕсли ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс()); Если ТолькоПриНаличииПодключенныхКоманд Тогда ЕстьПодключенныеКоманды = Ложь; Если ПометкиКоманд <> Неопределено Тогда Для Каждого КлючИЗначение Из ПометкиКоманд Цикл Если КлючИЗначение.Значение = Истина Тогда ЕстьПодключенныеКоманды = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если Не ЕстьПодключенныеКоманды Тогда Возврат Ложь; КонецЕсли; КонецЕсли; ЭтотРасширение = ирКэш.ЭтотРасширениеКонфигурацииЛкс(); #Если Сервер И Не Сервер Тогда ЭтотРасширение = РасширенияКонфигурации.Создать(); #КонецЕсли ИмяРасширения = ЭтотРасширение.Имя; ТипВсеСсылки = ирОбщий.ПолучитьОписаниеТиповВсеСсылкиЛкс(); ТипВсеПланыОбмена = ПланыОбмена.ТипВсеСсылки(); ТекстовыйДокумент = Новый ТекстовыйДокумент; КаталогВыгрузкиРасширения = ПолучитьИмяВременногоФайла(); ИмяФайлаСпискаВыгрузкиРасширения = ПолучитьИмяВременногоФайла("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"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя); //ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ЧтоЗаменять = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстФайла, "", "",, Истина); НаЧтоЗаменять = " | " + ирОбщий.ПолучитьПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + " | Adopted | | | "; ТекстФайла = СтрЗаменить(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ЧтоЗаменять = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМД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 """ + ИмяРасширения + """", СтрокаСоединенияИнформационнойБазы(), ТекстЛога); Если Не Успех Тогда Сообщить(ТекстЛога); Возврат Ложь; КонецЕсли; ЭтотРасширение.Записать(Новый ДвоичныеДанные(КонечныйФайл)); Возврат Истина; КонецФункции #КонецЕсли #Если Клиент И Не ТонкийКлиент И Не ВебКлиент Тогда Процедура ОткрытьОднократноАдаптациюРасширенияЛкс() Экспорт ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс()); Если ПометкиКоманд = Неопределено Тогда ПометкиКоманд = Новый Структура; ХранилищеОбщихНастроек.Сохранить(, "ирАдаптацияРасширения.ПометкиКоманд", ПометкиКоманд,, ирОбщий.ИмяПродуктаЛкс()); ОткрытьФормуМодально("ОбщаяФорма.ирАдаптацияРасширения", Новый Структура("Автооткрытие", Истина)); КонецЕсли; КонецПроцедуры Функция ПодтверждениеОперацииСУБДЛкс() Экспорт Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы и нарушение лицензионного соглашения 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].ИмяПоля = ПредопределенноеПоле Тогда ЭлементПорядка.Доступность = Истина; Прервать; КонецЕсли; КонецЦикла; Если ЭлементПорядка.Доступность Тогда НовыйПорядок = ПредопределенноеПоле; Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; Если ЗначениеЗаполнено(НовыйПорядок) Тогда // Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки (антибаг платформы) ДинамическийСписок.Порядок.Установить(НовыйПорядок); КонецЕсли; //Компоновщик = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ОбъектМД.ПолноеИмя()); //#Если Сервер И Не Сервер Тогда // Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных; //#КонецЕсли //Для Каждого ПолеВыбора Из Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл // Если ПолеВыбора.Папка Тогда // Продолжить; // КонецЕсли; //КонецЦикла; КонецЕсли; Если ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда КолонкаИдентификатора = КолонкиТП.Добавить("ИдентификаторСсылкиЛкс"); КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки"; КонецЕсли; Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда КолонкаИдентификатора = КолонкиТП.Добавить("ИмяПредопределенныхДанных"); КолонкаИдентификатора.ТекстШапки = "Имя предопределенных данных"; КолонкаИдентификатора.Видимость = Ложь; КонецЕсли; НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним); КонецПроцедуры Процедура НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение)); ПоляТаблицы = ПолучитьПоляТаблицыМДЛкс(ОбъектМД.ПолноеИмя()); Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл Колонка = ОсновнойЭУ.Колонки.Найти(ПолеТаблицы.Имя); Если Колонка = Неопределено Тогда Продолжить; КонецЕсли; Если РежимИмяСиноним Тогда Колонка.ТекстШапки = ПолеТаблицы.Имя; Иначе Колонка.ТекстШапки = ПолеТаблицы.Заголовок; КонецЕсли; КонецЦикла; КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка() Процедура НастроитьЗаголовкиАвтоТаблицыФормыДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ); ПоляТаблицы = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ДинамическийСписок.ОсновнаяТаблица); ПоляТаблицы = ПоляТаблицы.Скопировать(); СтрокаПоляИденитификатора = ПоляТаблицы.Добавить(); СтрокаПоляИденитификатора.Имя = "ИдентификаторСсылкиЛкс"; СтрокаПоляИденитификатора.Заголовок = "Идентификатор ссылки"; Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл Колонка = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ПолеТаблицы.Имя); Если Колонка = Неопределено Тогда Продолжить; КонецЕсли; Если РежимИмяСиноним Тогда Колонка.Заголовок = ПолеТаблицы.Имя; Иначе Колонка.Заголовок = ПолеТаблицы.Заголовок; КонецЕсли; КонецЦикла; КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка() // Параметры // МетаданныеКолонок - КоллекцияОбъектовМетаданных, ТаблицаЗначений - для таблицы значений используются колонки Имя и Метаданные Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияТиповКолонок = Неопределено, МетаданныеКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено, ТолькоПросмотр = Ложь) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда Если ОписанияТиповКолонок = Неопределено Тогда ОписанияТиповКолонок = ТабличноеПоле.Значение.Колонки; КонецЕсли; Иначе Если ОписанияТиповКолонок = Неопределено Тогда ОписанияТиповКолонок = ирСервер.ПолучитьТаблицуДочернихРеквизитовЛкс(ТабличноеПоле); КонецЕсли; КонецЕсли; Для Каждого КолонкаТаблицы Из ОписанияТиповКолонок Цикл Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда КолонкаТабличногоПоля = ТабличноеПоле.Колонки.Найти(КолонкаТаблицы.Имя); Иначе КолонкаТабличногоПоля = ТабличноеПоле.ПодчиненныеЭлементы.Найти(ТабличноеПоле.Имя + КолонкаТаблицы.Имя); КонецЕсли; Если КолонкаТабличногоПоля = Неопределено Тогда Продолжить; КонецЕсли; Если КолонкаТабличногоПоля.Видимость Тогда Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда ТабличноеПоле.ТекущаяКолонка = КолонкаТабличногоПоля; КонецЕсли; Иначе Если ТабличноеПоле.ТекущийЭлемент = Неопределено Тогда ТабличноеПоле.ТекущийЭлемент = КолонкаТабличногоПоля; КонецЕсли; КонецЕсли; КонецЕсли; Если ТолькоПросмотр Тогда КолонкаТабличногоПоля.ТолькоПросмотр = Истина; КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ТипыРеквизита = КолонкаТаблицы.ТипЗначения.Типы(); Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда КолонкаТабличногоПоля.Данные = ""; КолонкаТабличногоПоля.ДанныеФлажка = КолонкаТаблицы.Имя; КолонкаТабличногоПоля.РежимРедактирования = РежимРедактированияКолонки.Непосредственно; КолонкаТабличногоПоля.Ширина = 3; Иначе Если КолонкаТаблицы.Ширина > 0 Тогда КолонкаТабличногоПоля.Ширина = Мин(КолонкаТаблицы.Ширина, 50); // Почему то в редакторе таблицы значений не работала автоширина (-1) КонецЕсли; Если КолонкаТабличногоПоля.Ширина = 0 Тогда КолонкаТабличногоПоля.Ширина = 3; // Для 8.2 необходимо, иначе колонки будут не видны КонецЕсли; КонецЕсли; Если МетаданныеКолонок <> Неопределено Тогда Если ТипЗнч(МетаданныеКолонок) = Тип("КоллекцияОбъектовМетаданных") Тогда Метареквизит = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя); Иначе СтрокаПоля = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя, "Имя"); Если СтрокаПоля <> Неопределено Тогда Метареквизит = СтрокаПоля.Метаданные; Иначе Метареквизит = Неопределено; КонецЕсли; КонецЕсли; Если Метареквизит <> Неопределено Тогда Попытка Подсказка = Метареквизит.Подсказка; Исключение // У графы журнала нет подсказки Подсказка = Неопределено; КонецПопытки; Если Подсказка <> Неопределено Тогда КолонкаТабличногоПоля.ПодсказкаВШапке = Подсказка; Если Метареквизит.МногострочныйРежим Тогда КолонкаТабличногоПоля.ЭлементУправления.МногострочныйРежим = Метареквизит.МногострочныйРежим; КолонкаТабличногоПоля.ЭлементУправления.РасширенноеРедактирование = Метареквизит.РасширенноеРедактирование; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ДоступныеПоляВыбора <> Неопределено Тогда ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя)); Если ДоступноеПоле <> Неопределено Тогда ТекстШапки = ДоступноеПоле.Заголовок; Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда КолонкаТабличногоПоля.ТекстШапки = ТекстШапки; Иначе КолонкаТабличногоПоля.Заголовок = ТекстШапки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // ДобавитьСтраницуТЧ() Процедура ФормаОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда Если ЭтаФорма.Открыта() Тогда ЭтаФорма.Закрыть(); Если ЭтаФорма.Открыта() Тогда Параметр.Отказ = Истина; КонецЕсли; КонецЕсли; ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда Если ЭтаФорма.Открыта() Тогда Параметр.Ответ = Истина; КонецЕсли; ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда Попытка Сообщить(ЭтаФорма.Имя); Исключение Попытка Сообщить(ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя()); Исключение Сообщить("Неизвестная форма"); КонецПопытки; КонецПопытки; КонецЕсли; КонецПроцедуры Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт СтандартнаяОбработка = Ложь; Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда ЗапуститьПриложение(ИмяФайла); КонецЕсли; КонецПроцедуры // Создает новый экземпляр обработки и открывает его форму. // // Параметры: // Объект - ОбработкаОбъект, ОтчетОбъект. // // Возвращаемое значение: // Форма. // Функция ОткрытьНовоеОкноОбработкиЛкс(ЭтотОбъект) Экспорт Если ТипЗнч(ЭтотОбъект) = Тип("УправляемаяФорма") Тогда Результат = ПолучитьФормуЛкс(ЭтотОбъект.ИмяФормы,,, Новый УникальныйИдентификатор); Иначе Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать(); Иначе ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя(); НовыйОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбъекта); КонецЕсли; Результат = НовыйОбъект.ПолучитьФорму(); КонецЕсли; Результат.Открыть(); Возврат Результат; КонецФункции // ОткрытьНовоеОкноОбработкиЛкс() Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено, ТолькоВнешниеФормы = Ложь) Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда //ирПортативный #Если Сервер И Не Сервер Тогда // Такой прием нужен для обхода ошибка компиляции в портативном режиме Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно); //ирПортативный #КонецЕсли Иначе Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяФормы); Если Не ТолькоВнешниеФормы Тогда ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]); КонецЕсли; Если ОбъектМД = Неопределено Тогда ТипМетаданных = Фрагменты[0]; Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных); ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных); Если Истина И СтрокиРавныЛкс(Фрагменты[2], "Форма") И Фрагменты.Количество() = 4 Тогда ИмяФормы = Фрагменты[3]; Иначе ИмяФормы = Неопределено; КонецЕсли; Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность); Иначе Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ОткрытьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно); Форма.Открыть(); Возврат Форма; КонецФункции Функция ПолучитьОбщуюКартинкуЛкс(Имя) Экспорт Если ирКэш.ЛиПортативныйРежимЛкс() Тогда Результат = ирПортативный.ПолучитьОбщуюКартинкуЛкс(Имя); Иначе Результат = БиблиотекаКартинок[Имя]; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьЦветСтиляЛкс(ИмяЦвета) Экспорт //Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя); Если ИмяЦвета = "ирТекстИнформационнойНадписи" Тогда Возврат Новый Цвет(83, 106, 194); ИначеЕсли ИмяЦвета = "ирЦветФонаЧередованияСтрок" Тогда Возврат WebЦвета.МятныйКрем; ИначеЕсли ИмяЦвета = "ирЦветФонаВычисляемогоЗначения" Тогда Возврат WebЦвета.ГолубойСКраснымОттенком; ИначеЕсли ИмяЦвета = "ирЦветФонаОшибки" Тогда Возврат Новый Цвет(255, 245, 245); ИначеЕсли ИмяЦвета = "ирЦветФонаРасширенногоПредставленияЗначения" Тогда Возврат Новый Цвет(255, 255, 180); Иначе Результат = ЦветаСтиля[ИмяЦвета]; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // Значение - // ОчиститьПередУстановкой - Булево // УстановитьТекст - Булево // УстановитьЗначение - Булево // Функция БуферОбмена_УстановитьЗначениеЛкс(Знач Значение = "", Знач ОчиститьПередУстановкой = Истина, Знач УстановитьТекст = Истина, Знач УстановитьЗначение = Истина) Экспорт WinAPI = ирКэш.ПолучитьWinAPI(); Если ОчиститьПередУстановкой Тогда WinAPI.OpenClipboard(0); WinAPI.EmptyClipboard(); WinAPI.CloseClipboard(); КонецЕсли; CF_TEXT = 1; CF_UNICODETEXT = 13; CF_OEMTEXT = 7; Если УстановитьЗначение Тогда ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс(); ВнутреннееЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение,,, Ложь); БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, ФорматБуфераОбмена1С); КонецЕсли; Если УстановитьТекст Тогда ВнутреннееЗначение = "" + Значение; // Может тормозить из-за обращений к БД Если ВнутреннееЗначение <> "" Тогда БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, CF_UNICODETEXT); КонецЕсли; КонецЕсли; КонецФункции // Параметры: // ВнутреннееЗначение - // ФорматЗначения - Число(0,0) - CF_TEXT = 1; // ПомещатьВКодировкеUTF8 - Булево - Иначе используется UNICODE // Функция БуферОбмена_УстановитьДанныеПоФорматуЛкс(Знач ВнутреннееЗначение, Знач ФорматЗначения = 1, Знач ПомещатьВКодировкеUTF8 = Ложь) Экспорт WinAPI = ирКэш.ПолучитьWinAPI(); ВнутреннееЗначение = "" + ВнутреннееЗначение; КоличествоСимволов = СтрДлина(ВнутреннееЗначение); ПромежуточныйТекст = WinAPI.StrPtr(ВнутреннееЗначение, "s"); GMEM_DDESHARE = 8192; // &H2000; Дескриптор = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 2); Указатель = WinAPI.GlobalLock(Дескриптор); WinAPI.MultiByteToWideChar(0, 0, ПромежуточныйТекст, -1, Указатель, КоличествоСимволов + 1); Если ПомещатьВКодировкеUTF8 Тогда Дескриптор2 = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 1); Указатель2 = WinAPI.GlobalLock(Дескриптор2); CP_UTF8 = 65001; // UTF-8 translation WinAPI.WideCharToMultiByte(CP_UTF8, 0, Указатель, -1, Указатель2, КоличествоСимволов + 1); WinAPI.GlobalUnlock(Дескриптор); Указатель = Указатель2; Дескриптор = Указатель2; КонецЕсли; WinAPI.OpenClipboard(0); WinAPI.SetClipboardData(ФорматЗначения, Дескриптор); WinAPI.CloseClipboard(); WinAPI.GlobalUnlock(Дескриптор); КонецФункции // Параметры: // ФорматЗначения - Число(0,0) - CF_TEXT = 1; // Кодировка - Строка(0,П) - w (по умолчанию), s, z. Значения s и z нужны для чтения строки в ANSI- или OEM-кодировке, при этом она конвертируется в Юникод // Функция БуферОбмена_ПолучитьДанныеПоФорматуЛкс(Знач ФорматЗначения = 1, Знач Кодировка = "w") Экспорт WinAPI = ирКэш.ПолучитьWinAPI(); WinAPI.OpenClipboard(0); Дескриптор = WinAPI.GetClipboardData(ФорматЗначения); Если Дескриптор <> 0 Тогда Указатель = WinAPI.GlobalLock(Дескриптор); Результат = WinAPI.StrGet(Указатель, Кодировка); WinAPI.GlobalUnlock(Дескриптор); Иначе Результат = ""; КонецЕсли; WinAPI.CloseClipboard(); Возврат Результат; КонецФункции Функция БуферОбмена_ПолучитьЗначениеЛкс() Экспорт ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс(); СтрокаXML = БуферОбмена_ПолучитьДанныеПоФорматуЛкс(ФорматБуфераОбмена1С); Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXML,,, Ложь); Возврат Результат; КонецФункции Функция БуферОбмена_ПолучитьТекстЛкс() Экспорт CF_UNICODETEXT = 13; Результат = БуферОбмена_ПолучитьДанныеПоФорматуЛкс(CF_UNICODETEXT); Возврат Результат; КонецФункции // Параметры: // ПолеВвода - ПолеВвода // Значение - // Текст - Строка(0,П) // Функция ВставитьЗначениеВПолеВводаЛкс(Знач ПолеВвода, Знач Значение, Знач Текст = "") Экспорт Результат = Ложь; Если Истина И Значение <> Неопределено И Не ПолеВвода.ТолькоПросмотр Тогда ТипНовогоЗначения = ТипЗнч(Значение); Если Ложь Или ТипЗнч(ПолеВвода.Значение) = ТипНовогоЗначения Или ПолеВвода.ОграничениеТипа.Типы().Количество() = 0 Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения) Тогда Результат = ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, Значение); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка // Кнопка - КнопкаКоманднойПанели // СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром. // ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма // Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент; Текст = БуферОбмена_ПолучитьТекстЛкс(); Значение = БуферОбмена_ПолучитьЗначениеЛкс(); ПродолжитьОбработку = Истина; ТипЗначения = ТипЗнч(Значение); Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда Если Не ЭтаФорма.ТолькоПросмотр Тогда Если ТипЗначения = Тип("Массив") Тогда Значение = Значение[0]; КонецЕсли; ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение, Текст); Если ПродолжитьОбработку И ЗначениеЗаполнено(ТекущийЭлементФормы.Данные) Тогда // Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора Попытка ЭтаФорма[ТекущийЭлементФормы.Данные] = Значение; Исключение КонецПопытки; КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда Попытка РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге; Исключение РедактированиеВДиалоге = Ложь; КонецПопытки; Если Истина И Не РедактированиеВДиалоге И Не ЭтаФорма.ТолькоПросмотр И Не ТекущийЭлементФормы.ТолькоПросмотр И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено Тогда ДобавитьСтроку = Истина И ТекущийЭлементФормы.ТекущиеДанные = Неопределено И ТекущийЭлементФормы.ИзменятьСоставСтрок; Если Истина И Значение <> Неопределено И ТекущийЭлементФормы.ИзменятьСоставСтрок И Не ДобавитьСтроку Тогда Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет); ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да; КонецЕсли; Если ДобавитьСтроку Тогда ИмяТекущейКолонки = ТекущийЭлементФормы.ТекущаяКолонка.Имя; ТекущийЭлементФормы.ДобавитьСтроку(); ТекущийЭлементФормы.ТекущаяКолонка = ТекущийЭлементФормы.Колонки[ИмяТекущейКолонки]; КонецЕсли; Если ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строку при вызове команды и иногда установке текущей колонки КонецЕсли; Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда ПолеВвода = ТекущийЭлементФормы.ТекущаяКолонка.ЭлементУправления; Если ТипЗнч(ПолеВвода) = Тип("ПолеВвода") Тогда Если ТипЗначения = Тип("Массив") Тогда Значение = Значение[0]; КонецЕсли; ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ПолеВвода, Значение, Текст); ИмяКолонкиДанных = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы); Если ПродолжитьОбработку И ЗначениеЗаполнено(ИмяКолонкиДанных) Тогда // Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора Если ТипЗнч(ТекущийЭлементФормы.ТекущиеДанные) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда ИмяКолонкиДанных = ПолучитьПервыйФрагментЛкс(ИмяКолонкиДанных, "Для"); КонецЕсли; Попытка ТекущийЭлементФормы.ТекущиеДанные[ИмяКолонкиДанных] = Значение; Исключение КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ПродолжитьОбработку Тогда мПлатформа = ирКэш.Получить(); мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш); Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет); //ирПлатформа.WshShell.SendKeys("^v^м", 20); //англ.v,русс.м WinAPI = ирКэш.ПолучитьWinAPI(); ДескрипторОкнаФокуса = WinAPI.GetActiveWindow(); WinAPI.EnableWindow(ДескрипторОкнаФокуса); WM_KEYDOWN = 256; //0x0100 WM_KEYUP = 257; //0x0101 WM_COPY = 757; //0x0301 WM_CHAR = 258; //0x0102 WM_PASTE = 758; //0x0302 WM_GETTEXT = 13; //0x000D VK_CONTROL = 17; // CTRL KEY_V = 86; // V WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1); WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_V, 1); Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1); КонецЕсли; Если WinAPI.GetAsyncKeyState(KEY_V) = 0 Тогда WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_V, 1); КонецЕсли; ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина); КонецЕсли; КонецФункции // Параметры: // ЭтаФорма - Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма // НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка // Кнопка - КнопкаКоманднойПанели // СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром. // ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма // Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент; Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда Значение = ТекущийЭлементФормы.Значение; //Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст; Если ТипЗнч(Значение) = Тип("Строка") Тогда Значение = Неопределено; КонецЕсли; ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда //:ТекущийЭлементФормы = Новый ("ТабличноеПоле") Если Истина И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено Тогда Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя]; Значение = Ячейка.Значение; //Если ТипЗнч(Значение) = Тип("Строка") Тогда ////Если ОписаниеТиповВсеРедактируемыеТипыЛкс().СодержитТип(ТипЗнч(Значение)) Тогда // ОбъектМДСписка = Метаданные.НайтиПоТипу(ТипЗнч(ТекущийЭлементФормы.Значение)); // Если ОбъектМДСписка <> Неопределено Тогда // Если ЛиКорневойТипСсылкиЛкс(ПолучитьПервыйФрагментЛкс(ОбъектМДСписка.ПолноеИмя())) Тогда // КлючеваяКолонкаДанных = "Ссылка"; // КонецЕсли; // КонецЕсли; // ТипСтроки = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока); // Если КлючеваяКолонкаДанных <> Неопределено Тогда // Значение = Новый Массив; // Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл // Значение.Добавить(ВыделеннаяСтрока[КлючеваяКолонкаДанных]); // КонецЦикла; // ИначеЕсли ТипСтроки = Тип("ДоступноеПолеКомпоновкиДанных") Тогда // Значение = Новый Массив; // Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл // Значение.Добавить(ВыделеннаяСтрока); // КонецЦикла; // Иначе // Значение = Неопределено; // КонецЕсли; //КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда #Если Сервер И Не Сервер Тогда ТекущийЭлементФормы = Новый ТабличныйДокумент; #КонецЕсли Попытка ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки; Исключение ДанныеРасшифровки = Неопределено; КонецПопытки; Если Истина И ДанныеРасшифровки <> Неопределено И ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка]; Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда Продолжить; КонецЕсли; Значение = ЗначениеПоля.Значение; Прервать; КонецЦикла; КонецЕсли; КонецЕсли; мПлатформа = ирКэш.Получить(); мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш); Если Значение <> Неопределено Тогда мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ИмяМетода", "БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс"); мПлатформа.ПараметрыОбработчикаОжидания.Вставить("Значение", Значение); мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ОчиститьПередУстановкой", Ложь); мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьТекст", Ложь); мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьЗначение", Истина); КонецЕсли; Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет); //ирПлатформа.WshShell.SendKeys("^c^с"); //англ.C,русс.С WinAPI = ирКэш.ПолучитьWinAPI(); ДескрипторОкнаФокуса = WinAPI.GetActiveWindow(); WinAPI.EnableWindow(ДескрипторОкнаФокуса); WM_KEYDOWN = 256; //0x0100 WM_KEYUP = 257; //0x0101 WM_COPY = 757; //0x0301 WM_CHAR = 258; //0x0102 WM_PASTE = 758; //0x0302 WM_GETTEXT = 13; //0x000D VK_CONTROL = 17; // CTRL KEY_C = 67; // С WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1); WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_C, 1); Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1); КонецЕсли; Если WinAPI.GetAsyncKeyState(KEY_C) = 0 Тогда WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_C, 1); КонецЕсли; ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина); КонецФункции Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле); Форма.НастройкиСписка = НастройкиСписка; Форма.ОткрытьМодально(); КонецФункции Процедура Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма) Экспорт ЭлементыФормы = ЭтаФорма.ЭлементыФормы; ИмяКоманднойПанели = "КП_ПолеВвода"; КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели); Если КонтекстноеМенюФормы = Неопределено Тогда КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели); КонтекстноеМенюФормы.Видимость = Ложь; КонецЕсли; //лПлатформа = ирКэш.Получить(); //МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды"); //КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода; //ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы); КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(КонтекстноеМенюФормы); Для Каждого ЭлементФормы Из ЭлементыФормы Цикл Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда Попытка КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню; Исключение // Поле ввода принадлежит не панели, поэтому у него нет свойства Продолжить; КонецПопытки; Если КонтекстноеМеню = Неопределено Тогда //ЭлементФормы.АвтоКонтекстноеМеню = Ложь; ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы; КонецЕсли; КонецЕсли; КонецЦикла; ДействияФормы = ЭлементыФормы.Найти("ДействияФормы"); Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда ПанельФормы = ЭтаФорма.Панель; Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь); ДействияФормы.ИсточникДействий = ЭтаФорма; ПанельФормы.КонтекстноеМеню = ДействияФормы; Иначе ДействияФормы = ПанельФормы.КонтекстноеМеню; КонецЕсли; КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(ДействияФормы); КонецЕсли; КонецПроцедуры Процедура Форма_ПриЗакрытииЛкс(ЭтаФорма) Экспорт // У некоторых из-за большого объема данных в настройках пользователя это вызывает большие задержки //ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс"); КонецПроцедуры Процедура КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(Знач КоманднаяПанельПолеВвода) КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить("МакетФормы"); КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; Попытка КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие"); Исключение КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать); Возврат; КонецПопытки; КнопкаКопировать.Имя = "БуферОбмена_Копировать"; КнопкаКопировать.Текст = "Копировать значение"; КнопкаКопировать.Подсказка = "Копировать значение в буфер обмена"; КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка; КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина); КнопкаКопировать.Картинка = ПолучитьОбщуюКартинкуЛкс("ирКопировать"); // Здесь в расширении будет неявное обращение к серверу https://partners.v8.1c.ru/forum/topic/1635523 КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить(); КнопкаВставить.Имя = "БуферОбмена_Вставить"; КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; КнопкаВставить.Текст = "Вставить значение"; КнопкаВставить.Подсказка = "Вставить значение из буфера обмена"; КнопкаВставить.Пояснение = КнопкаВставить.Подсказка; КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина); КнопкаВставить.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие"); КнопкаВставить.Картинка = ПолучитьОбщуюКартинкуЛкс("ирВставить"); // Здесь в расширении будет неявное обращение к серверу https://partners.v8.1c.ru/forum/topic/1635523 КонецПроцедуры Процедура УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка) Экспорт Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда БуферОбмена_КопироватьЛкс(ЭтаФорма, Кнопка); ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда БуферОбмена_ВставитьЛкс(ЭтаФорма, Кнопка); КонецЕсли; КонецПроцедуры Процедура УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры) Экспорт Параметры.Кнопка.СочетаниеКлавиш = Параметры.СочетаниеКлавиш; КонецПроцедуры Процедура БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс(Параметры) Экспорт БуферОбмена_УстановитьЗначениеЛкс(Параметры.Значение, Параметры.ОчиститьПередУстановкой, Параметры.УстановитьТекст, Параметры.УстановитьЗначение); УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры); КонецПроцедуры Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт мПлатформа = ирКэш.Получить(); ПараметрыОбработчикаОжидания = мПлатформа.ПараметрыОбработчикаОжидания; Выполнить(ПараметрыОбработчикаОжидания.ИмяМетода + "(ПараметрыОбработчикаОжидания)"); мПлатформа.ПараметрыОбработчикаОжидания = Неопределено; КонецПроцедуры // Родственник ВернутьПостоянныйПарольПользователяЛкс // Пароль устанавливается временный и опционально роль ирРазработчик Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина, ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска = Истина) Экспорт #Если Сервер И Не Сервер Тогда ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя(); #КонецЕсли мПлатформа = ирКэш.Получить(); НужноВернутьАутентификациюОС = Ложь; НужноВернутьАутентификациюПаролем = Ложь; НужноВернутьПароль = Ложь; НужноВернутьЗащитуОтОпасныхДействий = Ложь; УдалитьРольРазработчикИР = Ложь; Если ПодменитьПарольНаВремяЗапуска Тогда Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда Сообщить("Назначение временного пароля собственному пользователю не допускается"); Возврат Неопределено; КонецЕсли; мhash = ПользовательИБ.СохраняемоеЗначениеПароля; Если ПользовательИБ.АутентификацияОС = Истина Тогда ПользовательИБ.АутентификацияОС = Ложь; НужноВернутьАутентификациюОС = Истина; КонецЕсли; Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда ПользовательИБ.АутентификацияСтандартная = Истина; НужноВернутьАутентификациюПаролем = Истина; КонецЕсли; Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ"; ПользовательИБ.Пароль = Пароль; НужноВернутьПароль = Истина; КонецЕсли; Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда УдалитьРольРазработчикИР = Истина; ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик); КонецЕсли; КонецЕсли; Если ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска Тогда Если мПлатформа.ВерсияПлатформы > 803009 И ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь; НужноВернутьЗащитуОтОпасныхДействий = Истина; КонецЕсли; КонецЕсли; ПользовательИБ.Записать(); НаборПараметров = Новый Структура(); НаборПараметров.Вставить("mHash", мhash); НаборПараметров.Вставить("НужноВернутьАутентификациюПаролем", НужноВернутьАутентификациюПаролем); НаборПараметров.Вставить("НужноВернутьАутентификациюОС", НужноВернутьАутентификациюОС); НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ); НаборПараметров.Вставить("НужноВернутьПароль", НужноВернутьПароль); НаборПараметров.Вставить("НужноВернутьЗащитуОтОпасныхДействий", НужноВернутьЗащитуОтОпасныхДействий); НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР); НаборПараметров.Вставить("Имя", ПользовательИБ.Имя); НаборПараметров.Вставить("Пароль", Пароль); Возврат НаборПараметров; КонецФункции // Родственник УстановитьВременныеСвойстваПользователюИБЛкс Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт; //УстановитьПривилегированныйРежим(Истина); Если НаборПараметров <> Неопределено Тогда мhash = НаборПараметров.mhash; НужноВернутьАутентификациюПаролем = НаборПараметров.НужноВернутьАутентификациюПаролем; НужноВернутьАутентификациюОС = НаборПараметров.НужноВернутьАутентификациюОС; НужноВернутьПароль = НаборПараметров.НужноВернутьПароль; НужноВернутьЗащитуОтОпасныхДействий = НаборПараметров.НужноВернутьЗащитуОтОпасныхДействий; ПользовательИБ = НаборПараметров.ПользовательИБ; УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР; Иначе Возврат; КонецЕсли; Если НужноВернутьПароль Тогда ПользовательИБ.СохраняемоеЗначениеПароля = мHash; КонецЕсли; Если НужноВернутьАутентификациюПаролем Тогда ПользовательИБ.АутентификацияСтандартная = Ложь; КонецЕсли; Если НужноВернутьАутентификациюОС Тогда ПользовательИБ.АутентификацияОС = Истина; КонецЕсли; Если НужноВернутьЗащитуОтОпасныхДействий Тогда ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина; КонецЕсли; Если УдалитьРольРазработчикИР Тогда ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик); КонецЕсли; ПользовательИБ.Записать(); КонецПроцедуры Функция ОткрытьМенеджерТабличногоПоляЛкс(ТабличноеПоле, ЭтаФорма, АктивизироватьСтраницу = "") Экспорт ФормаМенеджера = ирКэш.Получить().ПолучитьФорму("МенеджерТабличногоПоля", ЭтаФорма); ФормаМенеджера.УстановитьСвязь(ТабличноеПоле, , АктивизироватьСтраницу); Возврат ФормаМенеджера; КонецФункции Процедура ОткрытьСвязанныйСеансТонкогоКлиентаЛкс() Экспорт Результат = ирКэш.ПолучитьСеансТонкогоКлиентаЛкс(); Результат.Visible = Истина; Окна = Результат.ПолучитьОкна(); СписокОткрытыхОбъектов = Новый СписокЗначений; Для Каждого Окно Из Окна Цикл Попытка Содержимое = Окно.Содержимое; Исключение // В 8.2 нет такого свойства Продолжить; КонецПопытки; Для Каждого Форма Из Содержимое Цикл Попытка СсылкаCOM = Форма.Parameters.Key; Исключение СсылкаCOM = Неопределено; КонецПопытки; Если СсылкаCOM <> Неопределено Тогда ФрагментыИмениТипа = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Форма.FormName); МассивПараметров = Новый Массив; МассивПараметров.Добавить(Новый УникальныйИдентификатор(Результат.String(СсылкаCOM.УникальныйИдентификатор()))); Ссылка = Новый (Тип(ФрагментыИмениТипа[0] + "Ссылка." + ФрагментыИмениТипа[1]), МассивПараметров); СписокОткрытыхОбъектов.Добавить(Ссылка, ФрагментыИмениТипа[0] + "." + ФрагментыИмениТипа[1] + " - " + Ссылка); КонецЕсли; КонецЦикла; КонецЦикла; Если СписокОткрытыхОбъектов.Количество() > 0 Тогда СписокОткрытыхОбъектов.СортироватьПоПредставлению(); ВыбранныйЭлемент = СписокОткрытыхОбъектов.ВыбратьЭлемент("Выберите объект для открытия в редакторе объекта БД"); Если ВыбранныйЭлемент <> Неопределено Тогда ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранныйЭлемент.Значение); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ОповеститьОЗаписиОбъектаЛкс(ТипОбъекта, Источник = Неопределено) Экспорт Оповестить("ЗаписанОбъект", ТипОбъекта, Источник); ОповеститьОбИзменении(ТипОбъекта); КонецПроцедуры Функция ОткрытьОбъектМетаданныхЛкс(ОбъектИлиПолноеИмяМД) Экспорт Если ТипЗнч(ОбъектИлиПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда ОбъектМД = ОбъектИлиПолноеИмяМД; Иначе ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиПолноеИмяМД); КонецЕсли; #Если Сервер И Не Сервер Тогда ОбъектМД = Метаданные.НайтиПоТипу(); #КонецЕсли Если ОбъектМД = Неопределено Тогда Возврат Неопределено; КонецЕсли; ПолноеИмяМД = ОбъектМД.ПолноеИмя(); Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД); Если Фрагменты.Количество() = 2 Тогда Форма = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма"); Форма.ПараметрИмяОбъектаМетаданных = ПолноеИмяМД; Форма.ПрименитьПараметрыФормы(); КонецЕсли; Возврат Форма; КонецФункции Процедура ВыделитьПервыеСтрокиДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач Количество, Знач НастройкиСписка = Неопределено) Экспорт ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле); ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы,,,,,,, Количество); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; Если НастройкиСписка = Неопределено Тогда НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок); КонецЕсли; ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор); ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок); СтруктураКлюча = ирОбщий.ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,, Ложь); Для Каждого ЭлементСписка Из СтруктураКлюча Цикл ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ЭлементСписка.Представление); КонецЦикла; КлючиСтрок = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки); ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КлючиСтрок.Количество(), "Выделение"); Для Каждого КлючСтроки Из КлючиСтрок Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); ВыделенныеСтроки.Добавить(ирОбщий.ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, КлючСтроки)); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если КлючиСтрок.Количество() <> Количество Тогда Сообщить("Выделены все отобранные элементы, но меньшим количеством " + XMLСтрока(КлючиСтрок.Количество())); КонецЕсли; КонецПроцедуры Функция ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, выхПолноеИмяМД = "") Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда //выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле); ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма); ПолноеИмяТаблицы = ЭтаФорма.мСлужебныеДанные.ОсновныеТаблицыСписков[ПутьКДаннымСписка]; ОбъектМД = НайтиОбъектМетаданныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы); Если ОбъектМД <> Неопределено Тогда выхПолноеИмяМД = ОбъектМД.ПолноеИмя(); КонецЕсли; Иначе выхПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя(); КонецЕсли; ПолноеИмяТаблицы = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД); Возврат ПолноеИмяТаблицы; КонецФункции Функция ОбработкаОбъектИзФормыЛкс(ЭтаФорма) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда ОбработкаОбъект = ЭтаФорма; Иначе //ОбработкаОбъект = ЭтаФорма.РеквизитФормыВЗначение("фОбъект"); Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЭтаФорма.ИмяФормы); ОбработкаОбъект = ДанныеФормыВЗначение(ЭтаФорма.фОбъект, Тип("ОбработкаОбъект." + Фрагменты[1])); КонецЕсли; Возврат ОбработкаОбъект; КонецФункции Функция ПолучитьАдресСтрокиДереваЗначенийЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт КлючиУровней = Новый Массив(); ТекущаяСтрока = СтрокаДерева; Пока ТекущаяСтрока <> Неопределено Цикл КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]); ТекущаяСтрока = ТекущаяСтрока.Родитель; КонецЦикла; Возврат КлючиУровней; КонецФункции Функция ПолучитьАдресСтрокиДереваФормыЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт КлючиУровней = Новый Массив(); ТекущаяСтрока = СтрокаДерева; Пока ТекущаяСтрока <> Неопределено Цикл КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]); ТекущаяСтрока = ТекущаяСтрока.ПолучитьРодителя(); КонецЦикла; Возврат КлючиУровней; КонецФункции #КонецЕсли #Если Клиент Тогда Процедура ОткрытьСписокИнструментовЛкс() Экспорт #Если ВебКлиент Тогда Сообщить("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая"); #Иначе ФормаСпискаИнструментов = ПолучитьФормуЛкс("Обработка.ирПортативный.Форма.Форма"); ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = Истина; ФормаСпискаИнструментов.Открыть(); #КонецЕсли КонецПроцедуры Процедура СохранитьНастройкиПользователяЛкс() Экспорт #Если ВебКлиент Тогда Сообщить("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая"); #Иначе СохранитьНастройкиПользователя(); #КонецЕсли КонецПроцедуры Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда Сообщить("Команда недоступна в варианте Расширение"); Возврат; КонецЕсли; #Если ВебКлиент Тогда Сообщить("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая"); #Иначе Форма = ирКэш.Получить().ПолучитьФорму("НастройкиАлгоритмов"); Форма.Открыть(); #КонецЕсли КонецПроцедуры Процедура ОткрытьАдминистративнаяРегистрацияCOMЛкс() Экспорт #Если ВебКлиент Тогда Сообщить("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ФормаУправляемая"); #Иначе Форма = ирКэш.Получить().ПолучитьФорму("АдминистративнаяРегистрацияCOM"); Форма.Открыть(); #КонецЕсли КонецПроцедуры #КонецЕсли // Получает первый фрагмент, отделяемый разделителем от строки. // Написана для оптимизации по скорости. // // Параметры: // пСтрока - Строка - которую разбиваем; // *пРазделитель - Строка, "." - символ-разделитель; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина. // // Возвращаемое значение: // - Строка - первый фрагмент строки; // Неопределено - в строке не обнаружен разделитель. // Функция ПолучитьПервыйФрагментЛкс(пСтрока, пРазделитель = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт Позиция = Найти(пСтрока, пРазделитель); Если Позиция > 0 Тогда Возврат Лев(пСтрока, Позиция - 1); Иначе Если пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; Иначе Возврат ""; КонецЕсли; КонецЕсли; КонецФункции // ПолучитьПервыйФрагментЛкс() // Получает последний фрагмент, отделяемый разделителем от строки. // // Параметры: // пСтрока - Строка - в которой ищем; // *пМаркер – Строка, "." – отсекающий маркер; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки // в случае, если маркер не найден. // // Возвращаемое значение: // Неопределено - маркер не найден; // – Число – позиция маркера. // Функция ПолучитьПоследнийФрагментЛкс(пСтрока, пМаркер = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт Подстрока = пСтрока; МаркерНайден = Ложь; Пока пМаркер <> "" Цикл Позиция = Найти(Подстрока, пМаркер); Если Позиция = 0 Тогда Прервать; КонецЕсли; МаркерНайден = Истина; Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер)); КонецЦикла; Если Истина И Не МаркерНайден И пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; ИначеЕсли МаркерНайден Тогда Возврат Подстрока; Иначе Возврат ""; КонецЕсли; КонецФункции // ПолучитьПоследнийФрагментЛкс() Процедура ДобавитьЕслиНужноПравыйСлешВФайловыйПутьЛкс(КаталогИсполняемыхФайлов) Экспорт Если Прав(КаталогИсполняемыхФайлов, 1) <> "\" Тогда КаталогИсполняемыхФайлов = КаталогИсполняемыхФайлов + "\"; КонецЕсли; КонецПроцедуры // Проверяет правильность заполнения реквизитов объекта // Параметры: // Объект - // ОбязательныеПоля - Строка(0,П), Массив // Отказ - Булево // Заголовок - Строка(0,П) // // Возвращаемое значение: Булево - истина, если проверка пройдена успешно Функция ПроверитьЗаполнениеРеквизитовОбъектаЛкс(Знач Объект, Знач ОбязательныеПоля = "", Отказ = Ложь) Экспорт Результат = Истина; Попытка ОбменДаннымиЗагрузка = Объект.ОбменДанными.Загрузка; Исключение ОбменДаннымиЗагрузка = Ложь; КонецПопытки; Если ОбменДаннымиЗагрузка Тогда Возврат Результат; КонецЕсли; Если ТипЗнч(ОбязательныеПоля) = Тип("Строка") Тогда МассивПолей = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбязательныеПоля, ",", Истина); ОбязательныеПоля = Новый Соответствие; Для каждого Значение Из МассивПолей Цикл ОбязательныеПоля[Значение] = ""; КонецЦикла; //ОбязательныеПоля = Новый Структура(ОбязательныеПоля); КонецЕсли; РеквизитыМД = Объект.Метаданные().Реквизиты; Для каждого КлючЗначение Из ОбязательныеПоля Цикл ПутьКДанным = КлючЗначение.Ключ; Значение = Вычислить("Объект." + ПутьКДанным); Если Не ЗначениеЗаполнено(Значение) Тогда // надо ругаться Если Не ЗначениеЗаполнено(КлючЗначение.Значение) Тогда Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКДанным); ИндексСтрокиТЧ = Неопределено; Если Фрагменты.Количество() > 1 Тогда ИндексСтрокиТЧ = ПолучитьСтрокуМеждуМаркерамиЛкс(Фрагменты[0], "[", "]", Ложь); Если ЗначениеЗаполнено(ИндексСтрокиТЧ) Тогда ИндексСтрокиТЧ = Число(ИндексСтрокиТЧ); //ИмяТЧ = ПолучитьПервыйФрагментИис(Фрагменты[0], "["); КонецЕсли; КонецЕсли; //ПредставлениеРеквизита = РеквизитыМД[КлючЗначение.Ключ].Представление(); ПредставлениеРеквизита = СокрЛП(Фрагменты[Фрагменты.ВГраница()]); СтрокаСообщения = "Не заполнено значение реквизита """ + ПредставлениеРеквизита + """"; Если ЗначениеЗаполнено(ИндексСтрокиТЧ) Тогда СтрокаСообщения = СтрокаСообщения + " в строке №" + Формат(ИндексСтрокиТЧ + 1, "ЧГ="); КонецЕсли; Иначе СтрокаСообщения = КлючЗначение.Значение; КонецЕсли; Отказ = Истина; Сообщить(СтрокаСообщения, СтатусСообщения.Внимание); Результат = Ложь; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ОписанияТиповПересекаютсяЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов1 = Новый ОписаниеТипов; ОписаниеТипов2 = Новый ОписаниеТипов; #КонецЕсли Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл Если Истина И ИсключаяПримитивныеТипы И (Ложь Или Тип = Тип("Булево") Или Тип = Тип("Строка") Или Тип = Тип("Число") Или Тип = Тип("Дата")) Тогда Продолжить; КонецЕсли; Если ОписаниеТипов2.СодержитТип(Тип) Тогда Возврат Истина; КонецЕсли; КонецЦикла; Возврат Ложь; КонецФункции // Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка. // // Параметры: // Строка – Строка. // // Возвращаемое значение: // Булево. // Функция ЛиИмяПеременнойЛкс(Строка) Экспорт Если ПустаяСтрока(Строка) Тогда Возврат Ложь; КонецЕсли; Пустышка = Новый Структура; Попытка Пустышка.Вставить(Строка); Возврат Истина; Исключение Возврат Ложь; КонецПопытки; КонецФункции // ЛиИмяПеременнойЛкс() // Пространство имен текущей конфигурации. // Возвращаемое значение: // Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config"; КонецФункции Функция БезопасноПолучитьЗначениеСвойстваЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка); ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы); ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка]; Возврат ЗаголовокЭлемента; КонецФункции Функция ВосстановитьТекущуюСтрокуТаблицыФормыЛкс(ТаблицаФормы, Знач КлючТекущейСтроки, ДанныеТаблицы = Неопределено, ИмяКлючевойКолонки = "Ссылка") Экспорт Если КлючТекущейСтроки <> Неопределено Тогда Если ДанныеТаблицы = Неопределено Тогда ДанныеТаблицы = ТаблицаФормы.Значение; КонецЕсли; Если ТипЗнч(КлючТекущейСтроки) <> Тип("Структура") Тогда КлючТекущейСтроки = Новый Структура(ИмяКлючевойКолонки, КлючТекущейСтроки); КонецЕсли; НайденныеСтроки = ДанныеТаблицы.НайтиСтроки(КлючТекущейСтроки); Если НайденныеСтроки.Количество() > 0 Тогда Строка = НайденныеСтроки[0]; Попытка ИдентификаторСтроки = Строка.ПолучитьИдентификатор(); Исключение ИдентификаторСтроки = Строка; КонецПопытки; ТаблицаФормы.ТекущаяСтрока = ИдентификаторСтроки; Возврат Истина; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции Функция ПолучитьКлючТекущейСтрокиЛкс(ТаблицаФормы, ИмяКлючевойКолонки = "Ссылка") Экспорт ТекущиеДанные = ТаблицаФормы.ТекущиеДанные; Если ТекущиеДанные <> Неопределено Тогда КлючТекущейСтроки = ТекущиеДанные[ИмяКлючевойКолонки]; КонецЕсли; Возврат КлючТекущейСтроки; КонецФункции Процедура ДинамическийСписок_ОбъектМетаданных_НачалоВыбора(ЭтаФорма, Элемент, СтандартнаяОбработка) Экспорт СтандартнаяОбработка = Ложь; Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, ЭтаФорма); лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ЭтаФорма.фОбъект.ОбъектМетаданных); лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина); лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина); лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина); лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма")); лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма")); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма")); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; Форма.ОткрытьМодально(); КонецПроцедуры Процедура РедакторОбъектаБД_ИмяТаблицы_НачалоВыбора(ЭтаФорма, Элемент, СтандартнаяОбработка) Экспорт СтандартнаяОбработка = Ложь; Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, ЭтаФорма); лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ЭтаФорма.фОбъект.ИмяОсновнойТаблицы); лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина); лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Ложь); лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина); лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина); лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; Форма.ОткрытьМодально(); КонецПроцедуры Функция ИмяФормыИзФормыЛкс(ЭтаФорма) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда Результат = СлужебныеДанныеФормыЛкс(ЭтаФорма).ИмяФормы; Иначе Результат = ЭтаФорма.ИмяФормы; КонецЕсли; Возврат Результат; КонецФункции Функция СлужебныеДанныеФормыЛкс(ЭтаФорма) Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда Результат = ЭтаФорма.Панель.Страницы[0].Значение; Если Результат = Неопределено Тогда Результат = Новый Структура(); ЭтаФорма.Панель.Страницы[0].Значение = Результат; КонецЕсли; Иначе Результат = ЭтаФорма.мСлужебныеДанные; КонецЕсли; Возврат Результат; КонецФункции Процедура ОчиститьПодчиненныеЭлементыФормыЛкс(Знач Родитель, КоличествоНеудаляемых = 1) Экспорт Если ТипЗнч(Родитель) = Тип("Панель") Тогда Родитель.Страницы.Очистить(); ИначеЕсли ТипЗнч(Родитель) = Тип("ТабличноеПоле") Тогда Родитель.Колонки.Очистить(); Иначе ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Родитель); ПодчиненныеЭлементы = Родитель.ПодчиненныеЭлементы; НачальноеКоличество = ПодчиненныеЭлементы.Количество(); Для Счетчик = 1 По НачальноеКоличество Цикл ПодчиненныйЭлемент = ПодчиненныеЭлементы[НачальноеКоличество - Счетчик]; Если ПодчиненныеЭлементы.Количество() > КоличествоНеудаляемых Тогда ЭтаФорма.Элементы.Удалить(ПодчиненныйЭлемент); Иначе // Статистически добавленные нельзя удалять ПодчиненныйЭлемент.Видимость = Ложь; КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры Процедура УстановитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы; #Если Сервер И Не Сервер Тогда НеготовыеСтраницы = Новый СписокЗначений; #КонецЕсли ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя); Если ЭлементСписка <> Неопределено И Готовность Тогда НеготовыеСтраницы.Удалить(ЭлементСписка); ИначеЕсли ЭлементСписка = Неопределено И Не Готовность Тогда НеготовыеСтраницы.Добавить(Страница.Имя); КонецЕсли; КонецПроцедуры Функция ПолучитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы; #Если Сервер И Не Сервер Тогда НеготовыеСтраницы = Новый СписокЗначений; #КонецЕсли ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя); Результат = ЭлементСписка = Неопределено; Возврат Результат; КонецФункции Процедура СоздатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, ЗаменитьКолонкуНомерСтроки = Ложь) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ТабличноеПоле.СоздатьКолонки(); Если ЗаменитьКолонкуНомерСтроки И ТабличноеПоле.Значение.Колонки.Найти("НомерСтроки") <> Неопределено Тогда ТабличноеПоле.Колонки.НомерСтроки.Данные = ""; ТабличноеПоле.Колонки.НомерСтроки.ТолькоПросмотр = Истина; КонецЕсли; Иначе ОчиститьПодчиненныеЭлементыФормыЛкс(ТабличноеПоле, 0); ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле); ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле); РеквизитыТаблицы = ЭтаФорма.ПолучитьРеквизиты(ПутьКДанным); Для Каждого РеквизитТаблицы Из РеквизитыТаблицы Цикл ПолеФормы = ЭтаФорма.Элементы.Добавить(ТабличноеПоле.Имя + РеквизитТаблицы.Имя, Тип("ПолеФормы"), ТабличноеПоле); ПолеФормы.Вид = ВидПоляФормы.ПолеВвода; Попытка ПолеФормы.ПутьКДанным = ПутьКДанным + "." + РеквизитТаблицы.Имя; Исключение // При РеквизитТаблицы.Имя = "КоличествоСтрок" КонецПопытки; КонецЦикла; КонецЕсли; КонецПроцедуры Функция ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Знач Строка = Неопределено) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда Если Строка = Неопределено Тогда Строка = ТабличноеПоле.ТекущиеДанные; КонецЕсли; Иначе Если Строка = Неопределено Тогда Строка = ТабличноеПоле.ТекущаяСтрока; КонецЕсли; Если Строка <> Неопределено Тогда ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле); #Если Сервер И Не Сервер Тогда ДанныеТаблицы = Новый ТаблицаЗначений; #КонецЕсли Строка = ДанныеТаблицы.НайтиПоИдентификатору(Строка); КонецЕсли; КонецЕсли; Возврат Строка; КонецФункции Функция ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементФормы, ВызыватьИсключение = Истина) Экспорт Попытка ТипЗначения = ЭлементФормы.ТипЗначения; Исключение // Упр ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы); Попытка ТипЗначения = ЭтаФорма.мСлужебныеДанные.ТипыЗначений[ЭлементФормы.Имя]; Исключение Если ВызыватьИсключение Тогда ВызватьИсключение; КонецЕсли; КонецПопытки; КонецПопытки; Возврат ТипЗначения; КонецФункции // Чтобы функция возвращала правильное значение, в форме должен быть // выполнен общий обработчик формы _ПриСозданииНаСервереИис. // // Параметры: // Поле - <тип> - // // Возвращаемое значение: // Функция ДанныеЭлементаФормыЛкс(Элемент, выхПутьКДанным = "") Экспорт Попытка // Обычная форма Данные = Элемент.Значение; Попытка выхПутьКДанным = Элемент.Данные; Исключение // Колонка табличного поля выхПутьКДанным = Неопределено; КонецПопытки; Возврат Данные; Исключение КонецПопытки; ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Элемент, Тип("УправляемаяФорма")); // Переменная ЭтаФорма используется в Вычислить ниже выхПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Элемент, , ЭтаФорма); Если Не ЗначениеЗаполнено(выхПутьКДанным) Тогда //ВызватьИсключение "Для элемента формы " + Элемент.Имя + " не найден путь к данным"; Возврат Неопределено; КонецЕсли; Попытка Данные = Вычислить("ЭтаФорма." + выхПутьКДанным); Исключение //ВызватьИсключение "Ошибка получения данных " + выхПутьКДанным + " элемента формы " + Элемент.Имя + ": " + ОписаниеОшибки(); Возврат Неопределено; КонецПопытки; Возврат Данные; КонецФункции Функция ИдентификаторСтрокиТабличногоПоляЛкс(Знач НоваяСтрока) Экспорт Если Ложь Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементКоллекции") Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементДерева") Тогда НоваяСтрока = НоваяСтрока.ПолучитьИдентификатор(); КонецЕсли; Возврат НоваяСтрока; КонецФункции Функция НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт Структура = Новый Структура(Свойство); Для каждого Элемент Из Коллекция Цикл Если Истина И ТипЭлемента <> Неопределено И ТипЗнч(Элемент) <> ТипЭлемента Тогда Продолжить; КонецЕсли; ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство); Если Структура[Свойство] = Значение Тогда Результат = Элемент; Прервать; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции /////////////////////////////////////////////////// // Управляемые формы // Рекурсивно идет вверх до родителя нужного типа // Параметры: // ТипРодителя - Тип, *Неопределено - Неопределено=Тип("УправляемаяФорма") Возвращаемое значение: // Функция РодительЭлементаУправляемойФормыЛкс(Знач Элемент, ТипРодителя = Неопределено) Экспорт ТипУправляемаяФорма = Тип("УправляемаяФорма"); Если ТипРодителя = Неопределено Тогда ТипРодителя = ТипУправляемаяФорма; КонецЕсли; Пока ТипЗнч(Элемент) <> ТипРодителя Цикл Если ТипЗнч(Элемент) = ТипУправляемаяФорма Тогда Элемент = Неопределено; Прервать; КонецЕсли; //Попытка Элемент = Элемент.Родитель; //Исключение // Родитель = Неопределено; // Прервать; //КонецПопытки; КонецЦикла; Возврат Элемент; КонецФункции // Путь - можно передавать как полный путь к реквизиту, так и путь к родительскому реквизиту // // Параметры: // ЭтаФорма - <тип> - // Путь - <тип>, "" - // ИмяРеквизита - <тип>, "" - // // Возвращаемое значение: // Функция ПолучитьРеквизитФормыЛкс(ЭтаФорма, Знач Путь = "", Знач ИмяРеквизита = "") Экспорт Если Не ЗначениеЗаполнено(ИмяРеквизита) Тогда Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Путь); ИмяРеквизита = Фрагменты[Фрагменты.Количество() - 1]; Фрагменты.Удалить(Фрагменты.Количество() - 1); Путь = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, "."); КонецЕсли; Результат = Неопределено; РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты(Путь); Для Каждого РеквизитФормы Из РеквизитыФормы Цикл Если НРег(РеквизитФормы.Имя) = Нрег(ИмяРеквизита) Тогда Результат = РеквизитФормы; Прервать; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // ПолучитьРеквизитФормы() // Получить тип реквизита формы // // Параметры: // ЭтаФорма - <тип> - // Путь - <тип>, "" - // ИмяРеквизита - <тип> - // // Возвращаемое значение: // Функция ПолучитьТипРеквизитаФормыЛкс(ЭтаФорма, Путь = "", ИмяРеквизита = "") Экспорт РеквизитФормы = ПолучитьРеквизитФормыЛкс(ЭтаФорма, Путь, ИмяРеквизита); Результат = РеквизитФормы.ТипЗначения.Типы()[0]; Возврат Результат; КонецФункции // ПолучитьРеквизитФормы() // Получить путь К данным элемента управляемой формы. Чтобы функция возвращала правильное значение, в форме должен быть // выполнен общий обработчик формы _ПриСозданииНаСервереИис. // // Параметры: // Поле - <тип> - // // Возвращаемое значение: // Функция ПутьКДаннымЭлементаУправляемойФормыЛкс(Знач Поле, ОтносительноРодителя = Ложь, Знач ЭтаФорма = Неопределено) Экспорт Если ЭтаФорма = Неопределено Тогда ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Поле, Тип("УправляемаяФорма")); КонецЕсли; ПутьКДаннымПоля = ""; Если Поле <> ЭтаФорма Тогда Если Не ЭтаФорма.мСлужебныеДанные.ПутиКДанным.Свойство(Поле.Имя, ПутьКДаннымПоля) Тогда ПутьКДаннымПоля = ""; КонецЕсли; Если ОтносительноРодителя Тогда ПутьКДаннымПоля = ПолучитьПоследнийФрагментЛкс(ПутьКДаннымПоля); КонецЕсли; КонецЕсли; Возврат ПутьКДаннымПоля; КонецФункции Процедура СкопироватьКнопкиКоманднойПанелиУправляемойФормыЛкс(Знач КоманднаяПанельИсточник, Знач КоманднаяПанельПриемник, Знач ПрефиксИмени) Экспорт ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(КоманднаяПанельИсточник); ЭлементыФормы = ЭтаФорма.Элементы; Для Каждого КнопкаОбразец Из КоманднаяПанельИсточник.ПодчиненныеЭлементы Цикл Если Ложь Или ТипЗнч(КнопкаОбразец) = Тип("ГруппаФормы") Или Не ЗначениеЗаполнено(КнопкаОбразец.ИмяКоманды) Тогда // Это - системная команда Продолжить; КонецЕсли; ИмяНовойКнопки = ПрефиксИмени + КнопкаОбразец.Имя; НоваяКнопка = ЭлементыФормы.Добавить(ИмяНовойКнопки, ТипЗнч(КнопкаОбразец), КоманднаяПанельПриемник); ЗаполнитьЗначенияСвойств(НоваяКнопка, КнопкаОбразец,, "Имя"); КонецЦикла; КонецПроцедуры Функция НайтиСтрокуДереваФормыПоАдресуЛкс(НачальнаяСтрока, КлючиУровней, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт ТекущаяСтрока = НачальнаяСтрока; Уровень = 0; Для Уровень = 0 По КлючиУровней.Количество() - 1 Цикл ЭлементыДерева = ТекущаяСтрока.ПолучитьЭлементы(); лТекущаяСтрока = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыДерева, ИмяКлючевойКолонки, КлючиУровней[Уровень]); Если лТекущаяСтрока <> Неопределено Тогда ТекущаяСтрока = лТекущаяСтрока; Иначе Прервать; КонецЕсли; КонецЦикла; Возврат ТекущаяСтрока; КонецФункции