//////////////////////////////////////////////////////////////////////////////// // Подсистема "Инструменты разработчика" // Авторское право (с) 2007-2020, Старых С.А. // Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме, // с модификациями или без, при соблюдении следующих условий: // - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском // праве, этот список условий и нижеследующий отказ от гарантий. // - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об // авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других // материалах, поставляемых при распространении. // // ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ" // БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, // ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ, // ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ // ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО // РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ // ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ, // НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА // ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ // ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ. //ирПортативный Перем ирПортативный Экспорт; //ирПортативный Перем ирОбщий Экспорт; //ирПортативный Перем ирСервер Экспорт; //ирПортативный Перем ирКэш Экспорт; //ирПортативный Перем ирПривилегированный Экспорт; //////////////////////////////////////////////////////////////////////////////// // ОТЛАДКА #Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда // Присваивает первому параметру второй. // Удобно вызывать из отладчика через диалог "Вычислить выражение". // // Параметры: // П1 – Произвольный – параметр1; // П2 – Произвольный – параметр2; // // Возвращаемое значение: // П2 – Не используется. // Функция ПрЛкс(п1, п2 = Неопределено) Экспорт п1 = п2; Возврат п1; КонецФункции // Присвоить() // Выполняет программный код, переданный как параметр. // Остальные Параметры могут участвовать в теле этого кода. // Удобно использовать в отладчике. // // Параметры: // П1 – Произвольный – параметр1; // П2 – Произвольный – параметр2; // П3 – Произвольный – параметр3; // П4 – Произвольный – параметр4; // // Возвращаемое значение: // Неопределено – Не используется. // Функция ДуЛкс(Знач ТекстПрограммы, п1 = 0, п2 = 0, п3 = 0, п4 = 0) Экспорт Перем Р; Попытка Выполнить(ТекстПрограммы); Исключение Возврат ОписаниеОшибки(); КонецПопытки; Возврат Р; КонецФункции // Ду() // На клиенте открывает консоль кода с передачей туда всех своих параметров. На сервере сразу выполняет код. // Изменения параметров возвращаются в вызывающий контекст в модальном режиме. // // Параметры: // ТекстПрограммы - Строка - программный код для передачи в консоль кода или выполнения; // РежимОперации – Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда); // СтрокаИменПараметров – Строка - имена параметров для консоли кода через запятую, если не указаны, то будут оригинальные П*; // П* – Произвольный - параметры для использования при выполнении программного кода; // // Возвращаемое значение: // Строка - описание ошибок. // Функция ОперироватьЛкс(Знач ТекстПрограммы = "", Знач РежимОперации = 0, СтрокаИменПараметров= "", П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда Возврат СообщениеПользователюНетПраваИРЛкс(); КонецЕсли; КонецЕсли; #Если Сервер И Не Клиент Тогда РежимОперации = 2; #КонецЕсли МассивИмен = СтрРазделитьЛкс(СтрокаИменПараметров, ",", Истина); Если МассивИмен.Количество() > 0 Тогда Если МассивИмен[0] = "" Тогда МассивИмен.Удалить(0); КонецЕсли; КонецЕсли; ЧислоПараметров = 9; ПереданныеПараметры = Новый СписокЗначений; Для Счетчик = 1 По ЧислоПараметров Цикл ИмяПараметра = "П" + Счетчик; ЗначениеПараметра = Вычислить(ИмяПараметра); Если Ложь Или ЗначениеПараметра <> Null // Опасный трюк в интерактивном режиме. Отрезает параметры, переданные, но имеющие значение Null. Или РежимОперации = 2 Тогда ПсевдонимПараметра = ИмяПараметра; Если МассивИмен.Количество() > Счетчик - 1 Тогда ПсевдонимПараметра = МассивИмен[Счетчик - 1]; КонецЕсли; ПереданныеПараметры.Добавить(ЗначениеПараметра, ПсевдонимПараметра); КонецЕсли; КонецЦикла; Если РежимОперации < 2 Тогда #Если Клиент Тогда ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма", , , Новый УникальныйИдентификатор); ФормаОтладки.мРежимРедактора = Истина; ФормаОтладки.мСписокВнешнихПараметров = ПереданныеПараметры; ФормаОтладки.ПараметрТекст = ТекстПрограммы; Если РежимОперации = 0 Тогда ФормаОтладки.Открыть(); Возврат Неопределено; КонецЕсли; ПолученныеПараметры = ФормаОтладки.ОткрытьМодально(); Если ПолученныеПараметры = Неопределено Тогда Возврат Неопределено; КонецЕсли; #КонецЕсли Иначе ТекстПрограммы = ТекстПрограммы + ";"; Для Индекс = 0 По ПереданныеПараметры.Количество() - 1 Цикл ВнешнийПараметр = ПереданныеПараметры[Индекс]; ТекстПрограммы = ВнешнийПараметр.Представление + "=" + "_АлгоритмОбъект[" + Индекс + "].Значение;" + Символы.ПС + ТекстПрограммы; ТекстПрограммы = ТекстПрограммы + Символы.ПС + "_АлгоритмОбъект[" + Индекс + "].Значение = " + ВнешнийПараметр.Представление + ";"; КонецЦикла; ВыполнитьАлгоритм(ТекстПрограммы, ПереданныеПараметры); ПолученныеПараметры = ПереданныеПараметры; КонецЕсли; ОписаниеОшибок = ""; НовоеЗначение = Неопределено; Для Счетчик = 1 По ЧислоПараметров Цикл ИмяПараметра = "П" + Счетчик; НовоеЗначение = Неопределено; Если ПолученныеПараметры.Количество() > Счетчик - 1 Тогда НовоеЗначение = ПолученныеПараметры[Счетчик - 1].Значение; КонецЕсли; Если Вычислить(ИмяПараметра) <> НовоеЗначение Тогда Попытка Выполнить(ИмяПараметра + " = НовоеЗначение"); Исключение ПсевдонимПараметра = ИмяПараметра; Если МассивИмен.Количество() > Счетчик - 1 Тогда ПсевдонимПараметра = МассивИмен[Счетчик - 1]; КонецЕсли; ОписаниеОшибки = "Ошибка возвращения параметра " + ПсевдонимПараметра + ": " + ОписаниеОшибки(); ОписаниеОшибок = ОписаниеОшибок + ОписаниеОшибки; СообщитьЛкс(ОписаниеОшибки); КонецПопытки; КонецЕсли; КонецЦикла; Возврат ОписаниеОшибок; КонецФункции // Подготавливает строку для помещения всех переменных в структуру с целью ее дальнейшего вычисления в отладчике "Вычислить(Пер())". // Изменения параметров возвращаются в вызывающий контекст. // // Параметры: // ТекстПрограммы - Строка, *"" - программный код для анализа, берется из буфера обмена если пустой. // // Возвращаемое значение: // Строка для вычисления в отладчике. // Функция ПерЛкс(Знач ТекстПрограммы = "") Экспорт Параметры = ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(ТекстПрограммы); СтрокаИменПараметров = ""; Для Каждого КлючИЗначение Из Параметры Цикл Если СтрокаИменПараметров <> "" Тогда СтрокаИменПараметров = СтрокаИменПараметров + ", "; КонецЕсли; СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ; КонецЦикла; СтрокаРезультата = "Новый Структура(""" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")"; Возврат СтрокаРезультата; КонецФункции // Функция получает таблицу значений из указанной временной таблицы из менеджера временных таблиц, // либо структуру из всех входящих в запрос временных таблиц. // Используется для просмотра временных таблиц серверного менеджера временных таблиц в отладчике. // Параметры: // ЗапросИлиМенеджерВременныхТаблиц - Запрос, МенеджерВременныхТаблиц // ИменаВременныхТаблиц - Строка, *"" - имена существующих, но возможно не используемых в тексте запроса временных таблиц через запятую // ДопустимоеЧислоСтрок - Число, *500000 - выбирать из временной таблицы не более этого числа строк // // Результат - ТаблицаЗначений, Структура // Функция ПолВТЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ИменаВременныхТаблиц = "", ДопустимоеЧислоСтрок = 500000) Экспорт МассивИмен = ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(ЗапросИлиМенеджерВременныхТаблиц, ИменаВременныхТаблиц); Результат = Новый Структура(); Запрос = Новый Запрос; Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц; Иначе Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц; КонецЕсли; ТекстЗапроса = " |ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ДопустимоеЧислоСтрок) + " | * |ИЗ | ИмяВременнойТаблицы |"; Для Каждого ИмяВременнойТаблицы Из МассивИмен Цикл Если Не ЛиИмяПеременнойЛкс(ИмяВременнойТаблицы) Тогда Продолжить; КонецЕсли; Если Результат.Свойство(ИмяВременнойТаблицы) Тогда Продолжить; КонецЕсли; Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяВременнойТаблицы", ИмяВременнойТаблицы); Попытка РезультатЗапроса = Запрос.Выполнить(); Исключение Продолжить; КонецПопытки; Результат.Вставить(ИмяВременнойТаблицы, РезультатЗапроса.Выгрузить()); КонецЦикла; Возврат Результат; КонецФункции // Начать трассу в технологическом журнале. Сам технологический журнал надо заранее включить. Функция ТехНЛкс() Экспорт АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс(); Если АнализТехножурнала.НачатьТрассу("Отладчик") Тогда Возврат "Трасса техножурнала начата"; Иначе Возврат "Техножурнал не включен. Невозможно начать трассу."; КонецЕсли; КонецФункции // Кончить трассу в технологическом журнале и показать ее анализ Функция ТехКЛкс() Экспорт АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс(); Если АнализТехножурнала.КончитьТрассу() Тогда //АнализТехножурнала.ПоказатьТрассу(); Возврат "Трасса техножурнала кончена. Для ее анализа откройте в режиме предприятия ""Анализ техножурнала"""; Иначе Возврат "Трасса техножурнала не была начата ранее."; КонецЕсли; КонецФункции #Если Клиент Тогда // Подготавливает строку для вызова Оперировать() в отладчике. Вызвается путем вычисления "Вычислить(Поп())". // Изменения параметров возвращаются в вызывающий контекст. // // Параметры: // ТекстПрограммы - Строка, *"" - программный код для передачи в консоль кода или выполнения, берется из буфера обмена если пустой; // РежимОперации – Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда); // // Возвращаемое значение: // Строка для вычисления в отладчике. // Функция ПопЛкс(Знач ТекстПрограммы = "", РежимОперации = 1) Экспорт Если ПустаяСтрока(ТекстПрограммы) Тогда ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс(); КонецЕсли; Параметры = Новый Структура(); ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой"); #Если Сервер И Не Сервер Тогда ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать(); #КонецЕсли ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно(); Пока Истина Цикл ИнформацияОбОшибке = ПолеВстроенногоЯзыка.ПолучитьИнформациюОбОшибке(ТекстПрограммы); Если ИнформацияОбОшибке = Неопределено Тогда Прервать; КонецЕсли; НеопределеннаяПеременная = ирКэш.Получить().ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке); Если Не ЗначениеЗаполнено(НеопределеннаяПеременная) Тогда Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; Если Не Параметры.Свойство(НеопределеннаяПеременная) Тогда Параметры.Вставить(НеопределеннаяПеременная); ПолеВстроенногоЯзыка.ДобавитьСловоЛокальногоКонтекста(НеопределеннаяПеременная); КонецЕсли; КонецЦикла; СтрокаИменПараметров = ""; Для Каждого КлючИЗначение Из Параметры Цикл Если СтрокаИменПараметров <> "" Тогда СтрокаИменПараметров = СтрокаИменПараметров + ", "; КонецЕсли; СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ; КонецЦикла; НовыйТекст = ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы); СтрокаРезультата = "Оперировать(" + НовыйТекст + ", " + РежимОперации + ", " + """" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")"; Возврат СтрокаРезультата; КонецФункции // Обертка Оперировать. Модально открывает консоль кода с передачей туда всех своих параметров. // Удобно вызывать из отладчика через диалог "Вычислить выражение". // Изменения параметров возвращаются в вызывающий контекст. // // Параметры: // П* – Произвольный; // // Возвращаемое значение: // Неопределено. // Функция ОпЛкс(П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null) Экспорт Возврат ОперироватьЛкс(, Истина, , П1, П2, П3, П4, П5); КонецФункции // Оп() // Открывает консоль кода с передачей туда структуры параметров. // Изменения параметров возвращаются в структуру, но не в вызывающий контекст. // // Параметры: // ТекстПрограммы - Строка; // Модально – Булево - открывать окно модально; // СтруктураПараметров – Структура - ключи соответсвуют именам параметов, а значения их значениям. // // Возвращаемое значение: // Неопределено. // Функция ОперироватьСтруктуройЛкс(Знач ТекстПрограммы = "", Модально = Ложь, Знач СтруктураПараметров = Неопределено) Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда Возврат СообщениеПользователюНетПраваИРЛкс(); КонецЕсли; КонецЕсли; Если Истина И ПустаяСтрока(ТекстПрограммы) И СтруктураПараметров <> Неопределено И СтруктураПараметров.Количество() = 1 Тогда Для Каждого КлючИЗначение Из СтруктураПараметров Цикл ТекстПрограммы = КлючИЗначение.Ключ; КонецЦикла; КонецЕсли; ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма",,, Новый УникальныйИдентификатор); //ФормаОтладки.мСписокВнешнихПараметров = СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураПараметров); ПередаваемыеПараметры = Новый СписокЗначений; Если СтруктураПараметров <> Неопределено Тогда Для Каждого КлючИЗначение Из СтруктураПараметров Цикл ПередаваемыеПараметры.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ); КонецЦикла; ФормаОтладки.мСписокВнешнихПараметров = ПередаваемыеПараметры; КонецЕсли; ФормаОтладки.мРежимРедактора = Истина; ФормаОтладки.ПараметрТекст = ТекстПрограммы; Если Не Модально Тогда ФормаОтладки.Открыть(); Возврат ФормаОтладки; КонецЕсли; ПолученныеПараметры = ФормаОтладки.ОткрытьМодально(); Если ПолученныеПараметры = Неопределено Тогда Возврат Неопределено; КонецЕсли; Если СтруктураПараметров <> Неопределено Тогда //ЗаполнитьЗначенияСвойств(СтруктураПараметров, ПолученныеПараметры); Для Каждого ПолученныйПараметр Из ПолученныеПараметры Цикл СтруктураПараметров.Вставить(ПолученныйПараметр.Представление, ПолученныйПараметр.Значение); КонецЦикла; КонецЕсли; Возврат Неопределено; КонецФункции // РП() // Обертка ОперироватьСтруктурой. Модально открывает консоль кода с передачей туда всех своих параметров. // Удобно вызывать из отладчика через диалог "Вычислить выражение". // Изменения параметров возвращаются в структуру, но не в вызывающий контекст. // // Параметры: // СтруктураПараметров – Структура - ключи соответсвуют именам параметов, а значения их значениям. // // Возвращаемое значение: // Неопределено. // Функция ОпсЛкс(Знач СтруктураПараметров) Экспорт Возврат ОперироватьСтруктуройЛкс(, Истина, СтруктураПараметров); КонецФункции // Опс() // Выводит в окно сообщений переданное значение вместе с типом и заданным представлением. // // Параметры: // Значение - Произвольный; // *Представление – Строка, *"" - представление наблюдаемого значения. // Процедура НаблюдатьЛкс(Знач Значение, Представление = "") Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда Возврат; КонецЕсли; КонецЕсли; Строка = Представление + " = " + "<" + ТипЗнч(Значение) + ">" + "[" + Значение + "]"; СообщитьЛкс(Строка); КонецПроцедуры // Наблюдать() #КонецЕсли // Открывает нужную консоль для редактирования сложного объекта. // Варианты использования в зависимости от типа параметра Объект: // Запрос, COMОбъект, HttpСоединение - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов // ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов // ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов // СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов // МакетКомпоновкиДанных - открытвает запросы макета компоновки в консоли запросов // ОтчетОбъект - открывает схему и настройки компоновки отчета в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов // РегистрСведенийНаборЗаписей - открывает группировку таблицы набора записей по измерениям // // Параметры: // Объект – Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, МакетКомпоновкиДанных, ОтчетОбъект, ADODB.Command, ADODB.Connection, HttpСоединение, РегистрСведенийНаборЗаписей - исследуемый объект; // Модально – Булево - открывать окно модально, должно быть Истина для использования функции в отладчике; // НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц - НастройкиКомпоновкиДанных, Строка, *Неопределено - // если первый параметр СхемаКомпоновкиДанных, то настройки компоновки, // если первый параметр WMI или ADODB.Connection, то текст запроса, // если первый параметр HttpСоединение, то HttpЗапрос, // если первый параметр Запрос, имена временных таблиц разделенных запятыми; // ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки; // ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение // объектов отладки во временное хранилище; // ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки - Число, *500000 - допустимое количество строк во всех временных таблицах запроса // для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате; // Наименование - Строка - наименование сохраняемого объекта отложенной отладки; // // Возвращаемое значение: // Неопределено. // Функция ОтладитьЛкс(Знач Объект, Модально = Ложь, Знач НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, ОтложенноеВыполнение = Ложь, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000, выхОбъектДляОтладки = Неопределено, Наименование = "") Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда Возврат СообщениеПользователюНетПраваИРЛкс(); КонецЕсли; КонецЕсли; #Если Не Клиент Тогда ОтложенноеВыполнение = Истина; #КонецЕсли #Если ТолстыйКлиентУправляемоеПриложение Тогда Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ОтложенноеВыполнение = Истина; КонецЕсли; #КонецЕсли ТребоватьТипЛкс(Модально, "Модально", Тип("Булево")); ТребоватьТипЛкс(ОтложенноеВыполнение, "ОтложенноеВыполнение", Тип("Булево")); ТребоватьТипЛкс(ВнешниеНаборыДанных, "ВнешниеНаборыДанных", Тип("Неопределено"), Тип("Структура")); ТребоватьТипЛкс(НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, "НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц", Тип("Неопределено"), Тип("Строка"), Тип("НастройкиКомпоновкиДанных"), Тип("HTTPЗапрос")); Если Не ОтложенноеВыполнение Тогда #Если Клиент Тогда ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект)); Если Ложь Или ТипЗнч(Объект) = Тип("Запрос") Или ТипЗнч(Объект) = Тип("COMОбъект") Тогда КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект, , , Модально, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц); ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально); ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда КонсольПостроителейОтчетов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольПостроителейОтчетов"); #Если Сервер И Не Сервер Тогда КонсольПостроителейОтчетов = Обработки.ирКонсольПостроителейОтчетов.Создать(); #КонецЕсли Результат = КонсольПостроителейОтчетов.ОткрытьДляОтладки(Объект, Модально); ИначеЕсли Ложь Или ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Или ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда КонсольКомпоновкиДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных"); #Если Сервер И Не Сервер Тогда КонсольКомпоновкиДанных = Обработки.ирКонсольКомпоновокДанных.Создать(); #КонецЕсли Результат = КонсольКомпоновкиДанных.ОткрытьДляОтладки(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, Модально); ИначеЕсли Истина И ОбъектМД <> Неопределено И Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда КонсольКомпоновкиДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКомпоновокДанных"); #Если Сервер И Не Сервер Тогда КонсольКомпоновкиДанных = Обработки.ирКонсольКомпоновокДанных.Создать(); Объект = КонсольКомпоновкиДанных; #КонецЕсли Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда Возврат "У отчета не установлена схема компоновки данных"; КонецЕсли; Результат = КонсольКомпоновкиДанных.ОткрытьДляОтладки(Объект.СхемаКомпоновкиДанных, Объект.КомпоновщикНастроек.ПолучитьНастройки(), ВнешниеНаборыДанных, Модально); ИначеЕсли Истина И ОбъектМД <> Неопределено И Метаданные.РегистрыСведений.Индекс(ОбъектМД) <> -1 Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей(); мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений"); ФормаРедактирования.НачальноеЗначениеВыбора = Объект.Выгрузить(); ФормаРедактирования.Открыть(); ОткрытьГруппировкуТабличногоПоляЛкс(ФормаРедактирования.ЭлементыФормы.ПолеТаблицы,, СтрСоединитьЛкс(ЗначенияСвойстваКоллекцииЛкс(Объект.Метаданные().Измерения))); ИначеЕсли ТипЗнч(Объект) = Тип("HTTPСоединение") Тогда КонсольHttpЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольHttpЗапросов"); #Если Сервер И Не Сервер Тогда КонсольHttpЗапросов = Обработки.ирКонсольHttpЗапросов.Создать(); #КонецЕсли Результат = КонсольHttpЗапросов.ОткрытьДляОтладки(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, Модально); ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда Возврат "Отладка динамического списка доступна только на сервере"; Иначе Возврат "Не поддерживаемый тип """ + ТипЗнч(Объект) + """ первого параметра"; КонецЕсли; #КонецЕсли Иначе СтруктураПараметров = СтруктураОбъектаДляОтладкиЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки); Если СтруктураПараметров.Объект <> Неопределено Тогда Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование); Иначе Если Результат = Неопределено Тогда Результат = "Отложенная отладка объекта типа """ + ТипЗнч(Объект) + """ не поддерживается"; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция СтруктураОбъектаДляОтладкиЛкс(Знач Объект, Знач НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, Знач ВнешниеНаборыДанных, Знач ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000) Экспорт ТребоватьТипЛкс(ВнешниеНаборыДанных, "ВнешниеНаборыДанных", Тип("Неопределено"), Тип("Структура")); ТребоватьТипЛкс(НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, "НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц", Тип("Неопределено"), Тип("Строка"), Тип("НастройкиКомпоновкиДанных")); СтруктураПараметров = Новый Структура("Объект, НастройкаКомпоновки, ВнешниеНаборыДанных, ТипОбъекта"); Результат = Неопределено; Если ТипЗнч(Объект) = Тип("Запрос") Тогда СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса"); ВременныеТаблицы = Неопределено; Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда ВременныеТаблицы = ПолВТЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки); Результат = ""; Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл Если Результат <> "" Тогда Результат = Результат + ", "; КонецЕсли; Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда Результат = Результат + КлючИЗначение.Ключ; КонецЕсли; КонецЦикла; Если Результат <> "" Тогда Результат = "Временные таблицы " + Результат + " были сохранены частично!"; КонецЕсли; СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы; КонецЕсли; СтруктураЗапроса.Текст = Объект.Текст; СтруктураЗапроса.ТипЗапроса = "Обычный"; СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Объект.Параметры); СтруктураПараметров.Объект = СтруктураЗапроса; СтруктураПараметров.ТипОбъекта = "Запрос"; ИначеЕсли ТипЗнч(Объект) = Тип("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"; СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц; КонецЕсли; СтруктураПараметров.ТипОбъекта = "COMОбъект"; ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда СтруктураЗапроса = Новый Структура("Текст, Параметры"); ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос()); СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(СтруктураЗапроса.Параметры); СтруктураПараметров.Объект = СтруктураЗапроса; СтруктураПараметров.ТипОбъекта = "Запрос"; ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда СтруктураПараметров.Вставить("Объект", Объект); СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных); СтруктураПараметров.ТипОбъекта = "МакетКомпоновкиДанных"; ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда Результат = "Отложенная отладка построителя отчета не поддерживается"; ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда СтруктураПараметров.Вставить("Объект", Объект); СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц); СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных); СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных"; ИначеЕсли ТипЗнч(Объект) = Тип("HTTPСоединение") Тогда #Если Сервер И Не Сервер Тогда Объект = Новый HttpСоединение; #КонецЕсли ИменаСвойств = "Сервер, Порт, Пользователь, Пароль, Таймаут, Защищенное, ИспользоватьАутентификациюОС"; СтруктураСоединения = Новый Структура(ИменаСвойств); ЗаполнитьЗначенияСвойств(СтруктураСоединения, Объект, ИменаСвойств); Если ТипЗнч(НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц) = Тип("HTTPЗапрос") Тогда ИменаСвойств = "АдресРесурса, Заголовки"; СтруктураЗапроса = Новый Структура(ИменаСвойств); ЗаполнитьЗначенияСвойств(СтруктураЗапроса, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ИменаСвойств); КонецЕсли; СтруктураПараметров.Вставить("Объект", СтруктураСоединения); СтруктураПараметров.Вставить("НастройкаКомпоновки", СтруктураЗапроса); СтруктураПараметров.ТипОбъекта = "HttpСоединение"; ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда #Если Не Сервер Тогда Возврат "Отладка динамического списка доступна только на сервере"; #КонецЕсли НастройкаКомпоновки = Неопределено; Схема = Неопределено; ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Объект, НастройкаКомпоновки, Схема); СтруктураПараметров.Вставить("Объект", Схема); СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки); СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных"; Иначе ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Объект)); Если ОбъектМД <> Неопределено Тогда Если Метаданные.Отчеты.Индекс(ОбъектМД) <> -1 Тогда Если Объект.СхемаКомпоновкиДанных = Неопределено Тогда Возврат "У отчета не установлена схема компоновки данных"; Иначе СтруктураПараметров.Вставить("Объект", Объект.СхемаКомпоновкиДанных); СтруктураПараметров.Вставить("НастройкаКомпоновки", Объект.КомпоновщикНастроек.ПолучитьНастройки()); СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных); СтруктураПараметров.ТипОбъекта = "СхемаКомпоновкиДанных"; КонецЕсли; ИначеЕсли Метаданные.РегистрыСведений.Индекс(ОбъектМД) <> -1 Тогда СтруктураПараметров.Вставить("Объект", Объект); КонецЕсли; КонецЕсли; КонецЕсли; СтруктураПараметров.Вставить("ТипОперации", "Отладить"); СтруктураПараметров.Вставить("ИмяПользователя", ИмяПользователя()); Возврат СтруктураПараметров; КонецФункции Функция СнимокОбъектаДляОтладкиЛкс(Знач Объект, Знач НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, Знач ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000) Экспорт СтруктураПараметров = СтруктураОбъектаДляОтладкиЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки); Результат = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров); Возврат Результат; КонецФункции // Обертка ирОбщий.ОтладитьЛкс(). Модально (на клиенте) или отложенно (на сервере) открывает нужную консоль для редактирования/отладки объекта. // Удобно вызывать из отладчика через диалог "Вычислить выражение". Функция ОтЛкс(Знач Объект, Знач НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь, Наименование = "") Экспорт Результат = ОтладитьЛкс(Объект, Истина, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, ОтложеннаяОтладка,,, Наименование); Возврат Результат; КонецФункции // Открывает исследователь объектов. // // Параметры: // Объект – Произвольный, *Неопределено - объект, который будет исследован; // Модально – Булево - открывать окно модально; // КакКоллекцию – Булево, *Ложь - исследовать как коллекцию вместо объекта. // // Возвращаемое значение: // Сам объект. // Функция ИсследоватьЛкс(Знач Объект = Неопределено, Модально = Ложь, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда Возврат СообщениеПользователюНетПраваИРЛкс(); КонецЕсли; КонецЕсли; #Если Не Клиент Тогда ОтложенноеВыполнение = Истина; #КонецЕсли #Если ТолстыйКлиентУправляемоеПриложение Тогда Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ОтложенноеВыполнение = Истина; КонецЕсли; #КонецЕсли ТребоватьТипЛкс(Модально, "Модально", Тип("Булево")); ТребоватьТипЛкс(КакКоллекцию, "КакКоллекцию", Тип("Булево")); ТребоватьТипЛкс(ОтложенноеВыполнение, "ОтложенноеВыполнение", Тип("Булево")); Если Не ОтложенноеВыполнение Тогда ИсследовательОбъектов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИсследовательОбъектов"); #Если Сервер И Не Сервер Тогда ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать(); #КонецЕсли Если КакКоллекцию Тогда Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально); Иначе Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально); КонецЕсли; Если Результат <> Неопределено Тогда Объект = Результат; КонецЕсли; Иначе СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию, СериализацияФабрикой", , Модально, КакКоллекцию, Ложь); Наименование = "" + Объект; Если Истина И ТипЗнч(Объект) <> Тип("ОбъектXDTO") И ТипЗнч(Объект) <> Тип("ЗначениеXDTO") Тогда Попытка ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров); Исключение ОбъектXDTO = Неопределено; КонецПопытки; Иначе СтруктураПараметров.СериализацияФабрикой = Истина; Попытка Объект = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); Исключение Объект = Неопределено; КонецПопытки; ОбъектXDTO = Объект; КонецЕсли; Если ОбъектXDTO <> Неопределено Тогда СтруктураПараметров.Вставить("ТипОперации", "Исследовать"); СтруктураПараметров.Вставить("Объект", Объект); выхОбъектДляОтладки = Неопределено; Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование); Иначе Результат = "Отложенная отладка объекта такого типа не поддерживается"; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Исследовать() // Обертка Исследовать. Модально открывает объект в исследователе объектов // Удобно вызывать из отладчика через диалог "Вычислить выражение". Функция ИсЛкс(Знач Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт Возврат ИсследоватьЛкс(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение); КонецФункции // Ис() // Возвращает текст из файла Функция ФайлЛкс(Знач ИмяФайла, Знач Кодировка = "") Экспорт Текст = Новый ТекстовыйДокумент; Попытка Текст.Прочитать(ИмяФайла, Кодировка); Результат = Текст.ПолучитьТекст(); Исключение Результат = ОписаниеОшибки(); КонецПопытки; Возврат Результат; КонецФункции // Удаляет все элементы коллекции с возможностью оставить один элемент. // Параметры: // ОставитьЭлементИлиИндекс - Число, Строка, *Неопределено - при Число Или Строка оставляется элемент с таким ключом (0 - первый), иначе удаляется все Функция СокрКолЛкс(Коллекция, ОставитьЭлементИлиКлюч = Неопределено) Экспорт Если Ложь Или ТипЗнч(ОставитьЭлементИлиКлюч) = Тип("Число") Или ТипЗнч(ОставитьЭлементИлиКлюч) = Тип("Строка") Тогда Если ОставитьЭлементИлиКлюч = 0 Тогда ОставитьЭлемент = "<Первый>"; Иначе ОставитьЭлемент = Коллекция[ОставитьЭлементИлиКлюч]; КонецЕсли; Иначе Попытка Коллекция.Очистить(); Возврат Истина; Исключение ОставитьЭлемент = Неопределено; КонецПопытки; КонецЕсли; МассивКУдалению = Новый Массив; Для Каждого Элемент Из Коллекция Цикл Если ОставитьЭлемент = "<Первый>" Или ОставитьЭлемент = Элемент Тогда ОставитьЭлемент = Элемент; Продолжить; КонецЕсли; Если Ложь Или ТипЗнч(Коллекция) = Тип("Структура") Или ТипЗнч(Коллекция) = Тип("Соответствие") Тогда МассивКУдалению.Добавить(Элемент.Ключ); Иначе МассивКУдалению.Добавить(Элемент); КонецЕсли; КонецЦикла; Для Каждого УдаляемыйЭлемент Из МассивКУдалению Цикл Коллекция.Удалить(УдаляемыйЭлемент); КонецЦикла; КонецФункции #КонецЕсли // ОТЛАДКА //////////////////////////////////////////////////////////////////////////////// Функция НомерВерсииПлатформыЛкс(Знач СтрокаВерсии, Знач ВключаяНомерСборки = Ложь) Экспорт Фрагменты = ирОбщий.СтрРазделитьЛкс(СтрокаВерсии); #Если Сервер И Не Сервер Тогда Фрагменты = Новый Массив; #КонецЕсли Для Счетчик = Фрагменты.Количество() По 4 Цикл Фрагменты.Добавить("0"); КонецЦикла; Результат = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]); // 6 цифр Если ВключаяНомерСборки Тогда Результат = Результат * 10000 + Число(Фрагменты[3]); // 10 цифр КонецЕсли; Возврат Результат; КонецФункции Функция АдресОсновногоСайтаЛкс() Экспорт Возврат "devtool1c.ucoz.ru"; КонецФункции Функция АдресСайтаЗадачЛкс() Экспорт Возврат "https://www.hostedredmine.com/projects/devtool1c"; КонецФункции Функция СообщениеПользователюНетПраваИРЛкс() Экспорт Возврат "Нет права использования функции. Добавьте пользователю """ + ИмяПользователя() + """ роль из подсистемы ""Инструменты разработчика""."; КонецФункции // РП() // Выполняет текст алгоритма. // // Параметры: // ТекстДляВыполнения – Строка; // _АлгоритмОбъект - СправочникОбъект // *СтруктураПараметров - Структура, *Неопределено. // Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null, _П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт Перем Результат; Выполнить(_ТекстДляВыполнения); Возврат Результат; КонецФункции Функция ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт Перем Результат; Выполнить(_ТекстДляВыполнения); Возврат Результат; КонецФункции Процедура ВыполнитьАлгоритмВКонтекстеЛкс(ТекстДляВыполнения, СтруктураПараметров, НаСервере = Ложь, ЧерезВнешнююОбработку = Ложь, ИмяФайлаВнешнейОбработки = "", ЛиСинтаксическийКонтроль = Ложь, ВремяНачала = Неопределено, АдресПараметровВыхода = Неопределено, Знач ВерсияАлгоритма = Неопределено) Экспорт #Если Сервер И Не Клиент Тогда КонтекстВыполнения = ирОбщий; #Иначе Если НаСервере Тогда КонтекстВыполнения = ирСервер; Иначе КонтекстВыполнения = ирОбщий; КонецЕсли; #КонецЕсли Если Истина И Не ЛиСинтаксическийКонтроль И ЧерезВнешнююОбработку Тогда КонтекстВыполнения.ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, ВремяНачала, ВерсияАлгоритма); Иначе ВремяНачала = ирОбщий.ТекущееВремяВМиллисекундахЛкс(); КонтекстВыполнения.ВыполнитьАлгоритм(ТекстДляВыполнения, СтруктураПараметров); КонецЕсли; Если ЗначениеЗаполнено(АдресПараметровВыхода) Тогда СтруктураПараметров.Вставить("Служебный_ВремяНачала", ВремяНачала); ПоместитьВоВременноеХранилище(СтруктураПараметров, АдресПараметровВыхода); КонецЕсли; КонецПроцедуры Функция ВычислитьВыражение(Выражение9124327783, Параметры = Неопределено, НаСервере9124327783 = Ложь) Экспорт // Здесь должен быть максимально чистный контекст выполнения Если НаСервере9124327783 Тогда Результат9124327783 = ирСервер.ВычислитьВыражение(Выражение9124327783, Параметры); Иначе Если Параметры = Неопределено Тогда Результат9124327783 = ВычислитьВыражениеБезПараметровЛкс(Выражение9124327783); Иначе Результат9124327783 = Вычислить(Выражение9124327783); КонецЕсли; КонецЕсли; Возврат Результат9124327783; КонецФункции Функция ВычислитьВыражениеБезПараметровЛкс(Выражение9124327783) Экспорт Возврат Вычислить(Выражение9124327783); КонецФункции Функция ПолучитьПриглашениеОткрытьОтладчикЛкс() Экспорт Возврат "Если нет кнопки ""Подробно"", разрешите отладку. Нажмите кнопку ""Подробно"", а затем ""Конфигуратор"", чтобы начать отладку!"; КонецФункции Процедура ОткрытьОтладчикЛкс() Экспорт #Если ВебКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #Иначе ВызватьИсключение ПолучитьПриглашениеОткрытьОтладчикЛкс(); #КонецЕсли КонецПроцедуры Процедура ПерейтиКОпределениюМетодаВКонфигуратореЛкс(Знач СтрокаВызоваМетодаБезСкобок) Экспорт ТекстМодуля = СтрокаВызоваМетодаБезСкобок + "();"; ИмяВнешнейОбработки = "ПереходВКонфигураторе." + СтрокаВызоваМетодаБезСкобок; ИмяФайла = КаталогВременныхФайлов() + ИмяВнешнейОбработки + ".epf"; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФайлВнешнейОбработки = Новый Файл(ИмяФайла); мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля); мПлатформа.ОткрытьМодульВнешнейОбработкиВОтладчике(ИмяФайла, 1,, Истина ); КонецПроцедуры Процедура ПерейтиКОбъектуМетаданныхВКонфигуратореЛкс(Знач ПолноеИмя) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Фрагменты = СтрРазделитьЛкс(ПолноеИмя); СтрокаТипаМетаобъекта = мПлатформа.ПолучитьСтрокуТипаМетаОбъектов(Фрагменты[0]); Если СтрокаТипаМетаобъекта = Неопределено Тогда Возврат; КонецЕсли; ТекстМодуля = СтрокаТипаМетаобъекта.Множественное + "." + Фрагменты[1]; ИмяВнешнейОбработки = "ПереходВКонфигураторе." + ПолноеИмя; ИмяФайла = КаталогВременныхФайлов() + ИмяВнешнейОбработки + ".epf"; ФайлВнешнейОбработки = Новый Файл(ИмяФайла); мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля); мПлатформа.ОткрытьМодульВнешнейОбработкиВОтладчике(ИмяФайла, 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); СтрокаТипов = ""; Для Каждого Тип Из Массив Цикл Если ТипЗначения = Тип Тогда Возврат; КонецЕсли; Если Тип = Неопределено Тогда Прервать; КонецЕсли; Если СтрокаТипов <> "" Тогда СтрокаТипов = СтрокаТипов + ", "; КонецЕсли; СтрокаТипов = СтрокаТипов + Тип; КонецЦикла; Текст = ""; Если ЗначениеЗаполнено(ИмяПараметра) Тогда Текст = Текст + "Для параметра """ + ИмяПараметра + """ "; КонецЕсли; Текст = Текст + "Получено значение типа """ + ТипЗначения + """ вместо ожидаемых типов: " + СтрокаТипов + "."; ВызватьИсключение Текст; КонецПроцедуры #Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда Функция ЗагрузитьЗначениеИзФайлаЛкс(Знач ПолноеИмяФайла, Знач Сжатие = Ложь) Экспорт Если Сжатие Тогда ВременныйКаталог = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ВременныйКаталог); ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла); ЗипЧтение.ИзвлечьВсе(ВременныйКаталог); ПолноеИмяФайла = ВременныйКаталог + "\" + ЗипЧтение.Элементы[0].Имя; КонецЕсли; ЧтениеХМЛ = Новый ЧтениеXML; ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла); Попытка //Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла); Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ); Исключение СообщитьЛкс(ОписаниеОшибки()); Результат = Неопределено; КонецПопытки; ЧтениеХМЛ.Закрыть(); Если Сжатие Тогда УдалитьФайлы(ВременныйКаталог, "*"); КонецЕсли; Если ТипЗнч(Результат) = Тип("Структура") И Результат.Свойство("ВложенноеНесериализуемоеЗначение") Тогда Результат = Результат.ВложенноеНесериализуемоеЗначение.Получить(); КонецЕсли; Возврат Результат; КонецФункции Функция СохранитьЗначениеВФайлЛкс(Знач Значение, Знач ПолноеИмяФайла, Сжатие = Ложь, УровеньСжатия = Неопределено) Экспорт ЗаписьХМЛ = Новый ЗаписьXML; ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла); Результат = Истина; Попытка //ЗначениеВФайл(ПолноеИмяФайла, Значение); СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение); Исключение ЗаписьХМЛ.Закрыть(); ЗаписьХМЛ = Новый ЗаписьXML; ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла); Значение = Новый Структура("ВложенноеНесериализуемоеЗначение", Новый ХранилищеЗначения(Значение)); Попытка СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение); СообщитьЛкс("При сохранении данных в файл использована сериализация через хранилище значения из-за наличия недопустимых символов XML"); Исключение СообщитьЛкс(ОписаниеОшибки()); Результат = Ложь; КонецПопытки; КонецПопытки; ЗаписьХМЛ.Закрыть(); Если Результат И Сжатие Тогда ВременныйКаталог = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ВременныйКаталог); Файл = Новый Файл(ПолноеИмяФайла); ИмяВременногоФайла = ВременныйКаталог + "\" + Файл.Имя; ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла); ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия); ЗаписьЗип.Добавить(ИмяВременногоФайла); ЗаписьЗип.Записать(); УдалитьФайлы(ВременныйКаталог, "*"); КонецЕсли; Возврат Результат; КонецФункции Функция КомпоновщикТаблицыМетаданныхЛкс(Знач ПолноеИмяМД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт СхемаКомпоновкиДанных = ирОбщий.ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(ПолноеИмяМД,, Ложь,, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ИменаВместоПредставлений); #Если Сервер И Не Сервер Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; #КонецЕсли Попытка ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных); Исключение // Антибаг платформы 8.2.18 // Ошибка при вызове конструктора (ИсточникДоступныхНастроекКомпоновкиДанных) // ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных); //по причине: //Ошибка получения информации набора данных //по причине: //Ошибка в запросе набора данных //по причине: //{(1, 17)}: Неверное присоединение //ВЫБРАТЬ Т.* ИЗ <>КАК Т ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД); Если ОбъектМД = Неопределено Тогда // Возможно эта логика уже есть в какой то функции лПолноеИмяМД = ПолноеИмяМД; Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД); Если Фрагменты.Количество() > 1 Тогда Фрагменты.Удалить(Фрагменты.Количество() - 1); лПолноеИмяМД = ирОбщий.СтрСоединитьЛкс(Фрагменты, "."); КонецЕсли; ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(лПолноеИмяМД); КонецЕсли; Если Ложь Или ОбъектМД = Неопределено Или Не ПравоДоступа("Чтение", ОбъектМД) Тогда Если ВызыватьИсключениеПриОтсутствииПрав Тогда ВызватьИсключение "Таблица отсутствует или нет прав на ее чтение """ + ПолноеИмяМД + """"; Иначе Возврат Неопределено; КонецЕсли; Иначе ВызватьИсключение; КонецЕсли; КонецПопытки; КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек); // Для сравнения скорости в отладчике. Примерно та же скорость через построитель. //ПсевдонимТаблицы = "Т"; //ПолноеИмяИлиОбъектМД = ПолноеИмяМД; //Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда // ПолноеИмяМД = ПолноеИмяИлиОбъектМД; //Иначе // ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя(); //КонецЕсли; //ПолноеИмяТаблицыБД = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД); //Если ИндексПараметраПериодичность <> Неопределено Тогда // ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "("; // Для Индекс = 1 По ИндексПараметраПериодичность Цикл // ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + ","; // КонецЦикла; // ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + ВыражениеПараметраПериодичность + ")"; //КонецЕсли; //ТекстЗапроса = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы; //Построитель = Новый ПостроительЗапроса(ТекстЗапроса); //Построитель.ЗаполнитьНастройки(); Возврат КомпоновщикНастроек; КонецФункции Функция ЕстьНекорректныеЭлементыВКомпоновщикеНастроекЛкс(Знач ПроверочныйКомпоновщик, выхСтрокаТекущихНастроек = "", выхСтрокаИсправленныхНастроек = "") Экспорт выхСтрокаТекущихНастроек = СохранитьОбъектВВидеСтрокиXMLЛкс(ПроверочныйКомпоновщик.Настройки); ПроверочныйКомпоновщик.Восстановить(); выхСтрокаИсправленныхНастроек = СохранитьОбъектВВидеСтрокиXMLЛкс(ПроверочныйКомпоновщик.Настройки); ЕстьНекорректныеЭлементы = выхСтрокаИсправленныхНастроек <> выхСтрокаТекущихНастроек; Возврат ЕстьНекорректныеЭлементы; КонецФункции Процедура ОбработкаПолученияФормыЛкс(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка, ЕстьУправляемаяФорма = Ложь) Экспорт Если ЕстьУправляемаяФорма Тогда Возврат; КонецЕсли; #Если Сервер Тогда ПроверитьФлажокИспользоватьОбычныеФормыВУправляемомПриложенииЛкс(); #КонецЕсли СтандартнаяОбработка = Ложь; ТекущийСеанс = ирКэш.ТекущийСеансЛкс(); Если ТекущийСеанс <> Неопределено И Не ирОбщий.СтрокиРавныЛкс(ТекущийСеанс.ИмяПриложения, "1CV8") Тогда ВыбраннаяФорма = "Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"; СтандартнаяОбработка = Ложь; КонецЕсли; КонецПроцедуры Процедура ПроверитьФлажокИспользоватьОбычныеФормыВУправляемомПриложенииЛкс() Экспорт Если Не Метаданные.ИспользоватьОбычныеФормыВУправляемомПриложении Тогда СообщитьЛкс("Для использования отчетов подсистемы запустите обычное приложение либо в свойствах конфигурации установите флажок ""Использовать обычные формы в управляемом приложении"" | доступный в режиме ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение""."); КонецЕсли; КонецПроцедуры Функция ВыполнитьАлгоритмЧерезВнешнююОбработкуЛкс(ИмяФайлаВнешнейОбработки, СтруктураПараметров, выхВремяНачала = Неопределено, ВерсияАлгоритма = Неопределено) Экспорт #Если Сервер И Не Клиент Тогда Файл = Новый Файл(ИмяФайлаВнешнейОбработки); Если Не Файл.Существует() Тогда КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда ВызватьИсключение "файл внешней обработки алгоритма не доступен на сервере. Рекомендуется в общих настройках инструментов задать сетевой каталог объектов для отладки."; КонецЕсли; КонецЕсли; #КонецЕсли ВнешняяОбработка = ВнешниеОбработки.Создать(ИмяФайлаВнешнейОбработки, Ложь); Если ВерсияАлгоритма <> Неопределено И ВнешняяОбработка.ВерсияАлгоритма() <> ВерсияАлгоритма Тогда // Антибаг 8.3.11.2700-?. Testplatform@1c.ru - Support #17972. В обычном приложении на клиенте при повторном создании с одним именем файла и внутренней версией используются метаданные первой обработки в сеансе. СообщитьЛкс("Внешняя обработка не обновилась в кэше процесса 1С. Для ее обновления рекомендуется выполнить перезапуск процесса.", СтатусСообщения.Внимание); КонецЕсли; ОбщиеМодули = ПолучитьСтруктуруОсновныхОбщихМодулейЛкс(); выхВремяНачала = ирОбщий.ТекущееВремяВМиллисекундахЛкс(); ВнешняяОбработка.мМетод(СтруктураПараметров, ОбщиеМодули); //Возврат Результат; КонецФункции Функция ТекстМодуляСгенерированнойВнешнейОбработки(ПолноеИмяФайла) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Файл = Новый Файл(ПолноеИмяФайла); Текст = мПлатформа.ТекстМодуляСгенерированнойВнешнейОбработки(Файл); Возврат Текст; КонецФункции Функция ПолучитьСтруктуруОсновныхОбщихМодулейЛкс() Экспорт ОбщиеМодули = Новый Структура; ОбщиеМодули.Вставить("ирОбщий", ирОбщий); ОбщиеМодули.Вставить("ирКэш", ирКэш); ОбщиеМодули.Вставить("ирСервер", ирСервер); Возврат ОбщиеМодули; КонецФункции // ВыполнитьЛокально() Процедура ОбновитьТипЗначенияВСтрокеТаблицыЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиИлиОписаниеТипов = "ОписаниеТипов", Знач ИмяКолонкиТипаЗначения = "ТипЗначения", Знач ИмяКолонкиИмяТипаЗначения = "ИмяТипаЗначения", Знач Колонки = Неопределено, Знач РасширенноеЗначение = Неопределено) Экспорт Если Колонки = Неопределено Тогда Колонки = ТекущаяСтрока.Владелец().Колонки; Иначе ТребоватьТипЛкс(Колонки, Тип("ТаблицаЗначений"), Тип("КоллекцияКолонокТаблицыЗначений"), Тип("КоллекцияКолонокДереваЗначений"), Тип("КоллекцияКолонокРезультатаЗапроса"), , Тип("КоллекцияОбъектовМетаданных")); #Если Сервер И Не Сервер Тогда Колонки = Новый ТаблицаЗначений; Колонки = Колонки.Колонки; #КонецЕсли КонецЕсли; Если ЗначениеЗаполнено(ИмяКолонкиЗначения) Тогда РасширенноеЗначение = ТекущаяСтрока[ИмяКолонкиЗначения]; КонецЕсли; ТипЗначения = ТипЗнч(РасширенноеЗначение); Если ТипЗнч(ИмяКолонкиИлиОписаниеТипов) <> Тип("ОписаниеТипов") Тогда КолонкаОписанияТипов = Колонки.Найти(ИмяКолонкиИлиОписаниеТипов); Если КолонкаОписанияТипов <> Неопределено Тогда ИмяКолонкиИлиОписаниеТипов = ТекущаяСтрока[ИмяКолонкиИлиОписаниеТипов]; Иначе ИмяКолонкиИлиОписаниеТипов = Неопределено; КонецЕсли; КонецЕсли; Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения, "Имя") <> Неопределено; Иначе ЕстьКолонкаТипЗначения = Колонки.Найти(ИмяКолонкиТипаЗначения) <> Неопределено; КонецЕсли; Если ЕстьКолонкаТипЗначения Тогда ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Ложь); КонецЕсли; Если ТипЗнч(Колонки) = Тип("ТаблицаЗначений") Тогда ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения, "Имя") <> Неопределено; Иначе ЕстьКолонкаИмяТипаЗначения = Колонки.Найти(ИмяКолонкиИмяТипаЗначения) <> Неопределено; КонецЕсли; Если ЕстьКолонкаИмяТипаЗначения Тогда ТекущаяСтрока[ИмяКолонкиИмяТипаЗначения] = ПредставлениеТипаЛкс(ТипЗначения, ИмяКолонкиИлиОписаниеТипов, Истина); КонецЕсли; КонецПроцедуры Функция ПараметрыЗапускаПриложения1СЛкс(Знач ИмяПользователяИнфобазы = "", Знач ПарольПользователяИнфобазы = "", КодРазрешения = "", РежимКонфигуратора = Ложь, РежимЗапуска = "ОбычноеПриложение", РазрешитьОтладку = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Ложь, ДополнительныеПараметры = "", СообщитьСтрокуПараметров = Истина, СтрокаСоединения = "", ОткрытьПортативныеИнструменты = Ложь, РежимИнтерфейсаТакси = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь, КодЯзыка = "") Экспорт Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда СтрокаСоединения = СтрокаСоединенияИнформационнойБазы(); КонецЕсли; ПараметрыЗапуска = ""; Если РежимКонфигуратора Тогда ПараметрыЗапуска = ПараметрыЗапуска + " CONFIG"; Иначе ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE"; КонецЕсли; ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """"; Если ЗначениеЗаполнено(ИмяПользователяИнфобазы) Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /N""" + ИмяПользователяИнфобазы + """"; КонецЕсли; Если ОтключитьАутентификациюОС Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /WA-"; КонецЕсли; Если ЗначениеЗаполнено(ПарольПользователяИнфобазы) Тогда СтрокаПараметраПароля = "/P""" + ПарольПользователяИнфобазы + """"; СтрокаЗаменыПароля = "/P""" + "***" + """"; ПараметрыЗапуска = ПараметрыЗапуска + " " + СтрокаПараметраПароля; КонецЕсли; ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """"; Если Не РежимКонфигуратора Тогда Если РазрешитьОтладку Тогда ПараметрыЗапускаДляОтладки = ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчикуЛкс(); ПараметрыЗапуска = ПараметрыЗапуска + " " + ПараметрыЗапускаДляОтладки; КонецЕсли; Если ОчисткаКэшаКлиентСерверныхВызовов Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /ClearCache"; КонецЕсли; Если РежимИнтерфейсаТакси Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /iTaxi"; КонецЕсли; Если ОткрытьПортативныеИнструменты И ирКэш.ЛиПортативныйРежимЛкс() Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """"; КонецЕсли; Если СтрокиРавныЛкс(РежимЗапуска, "Авто") Тогда // Из-за этого иногда долго стартует почему то ПараметрыЗапуска = ПараметрыЗапуска + " /AppAutoCheckMode"; // Автоматический выбор типа приложения для запуска ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "ОбычноеПриложение") Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication"; ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТолстый") Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication"; ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТонкий") Тогда //ПараметрыЗапуска = ПараметрыЗапуска + "/IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """"; КонецЕсли; Если ЗначениеЗаполнено(РазделениеДанных) Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /Z""" + РазделениеДанных + """"; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(КодЯзыка) Тогда ПараметрыЗапуска = ПараметрыЗапуска + " /L""" + КодЯзыка + """"; КонецЕсли; Если ЗначениеЗаполнено(ДополнительныеПараметры) Тогда ПараметрыЗапуска = ПараметрыЗапуска + " " + ДополнительныеПараметры; КонецЕсли; Если СообщитьСтрокуПараметров Тогда СообщитьЛкс(СтрЗаменить(ПараметрыЗапуска, СтрокаПараметраПароля, СтрокаЗаменыПароля)); КонецЕсли; Возврат ПараметрыЗапуска; КонецФункции Функция СоздатьСсылочныйОбъектПоМетаданнымЛкс(ОбъектИлиИмяМД, ЭтоГруппаДляНового = Ложь, ИдентификаторСсылки = Неопределено, ЗаполнитьРеквизитыЗначениямиЗаполнения = Ложь) Экспорт УстановитьПривилегированныйРежим(Истина); Менеджер = ПолучитьМенеджерЛкс(ОбъектИлиИмяМД); Если ТипЗнч(ОбъектИлиИмяМД) = Тип("ОбъектМетаданных") Тогда ОбъектМД = ОбъектИлиИмяМД; Иначе ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиИмяМД); КонецЕсли; ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ИмяТипаМетаданного = ПеревестиВРусский(ПервыйФрагментЛкс(ПолноеИмяМД)); Попытка Если ИмяТипаМетаданного = "Справочник" Или ИмяТипаМетаданного = "ПланВидовХарактеристик" Тогда Если ЭтоГруппаДляНового Тогда Объект = Менеджер.СоздатьГруппу(); Иначе Объект = Менеджер.СоздатьЭлемент(); КонецЕсли; ИначеЕсли ИмяТипаМетаданного = "Документ" Тогда Объект = Менеджер.СоздатьДокумент(); ИначеЕсли ИмяТипаМетаданного = "Задача" Тогда Объект = Менеджер.СоздатьЗадачу(); ИначеЕсли ИмяТипаМетаданного = "БизнесПроцесс" Тогда Объект = Менеджер.СоздатьБизнесПроцесс(); ИначеЕсли ИмяТипаМетаданного = "ПланОбмена" Тогда Объект = Менеджер.СоздатьУзел(); ИначеЕсли ИмяТипаМетаданного = "ПланВидовРасчета" Тогда Объект = Менеджер.СоздатьВидРасчета(); ИначеЕсли ИмяТипаМетаданного = "ПланСчетов" Тогда Объект = Менеджер.СоздатьСчет(); ИначеЕсли ИмяТипаМетаданного = "ВнешнийИсточникДанных" Тогда Объект = Менеджер.СоздатьОбъект(); Иначе ВызватьИсключение "Неизвестный тип метаданных """ + ИмяТипаМетаданного + """"; КонецЕсли; Исключение #Если Клиент Тогда ОписаниеОшибки = ОписаниеОшибки(); Если Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И Найти(ОписаниеОшибки, "Обработчик события не найден") > 0 Тогда СообщитьЛкс("Рекомендуется в общих параметрах записи включить флажок ""Объекты на сервере"""); КонецЕсли; #КонецЕсли ВызватьИсключение; КонецПопытки; Если ИдентификаторСсылки = Неопределено Тогда ИдентификаторСсылки = Новый УникальныйИдентификатор(); КонецЕсли; Объект.УстановитьСсылкуНового(Менеджер.ПолучитьСсылку(ИдентификаторСсылки)); Если ЗаполнитьРеквизитыЗначениямиЗаполнения Тогда Объект.Заполнить(Неопределено); КонецЕсли; Возврат Объект; КонецФункции Функция СтрокаПустогоИдентификатораЛкс() Экспорт Возврат "00000000-0000-0000-0000-000000000000"; КонецФункции Функция ИмяТипаИзПолногоИмениМДЛкс(Знач ПолноеИмяИлиОбъектМД, Знач ПодтипРус = "Ссылка") Экспорт Если ТипЗнч(ПолноеИмяИлиОбъектМД) <> Тип("Строка") Тогда ПолноеИмяИлиОбъектМД = ПолноеИмяИлиОбъектМД.ПолноеИмя(); КонецЕсли; Фрагменты = СтрРазделитьЛкс(ПолноеИмяИлиОбъектМД); Если Фрагменты.Количество() = 3 Тогда ИмяТипа = ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяИлиОбъектМД); Иначе ПервоеСлово = ""; ИменаМД = ""; Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл ПервоеСлово = ПервоеСлово + Фрагменты[(Счетчик - 1) * 2]; ИменаМД = ИменаМД + "." + Фрагменты[(Счетчик - 1) * 2 + 1]; КонецЦикла; Подтип = ПеревестиСтроку(ПодтипРус); ИмяТипа = ПервоеСлово + Подтип + ИменаМД; КонецЕсли; Возврат ИмяТипа; КонецФункции Функция ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД, Знач ПодтипРус = "Ссылка") Экспорт Если Найти(ИмяТаблицыБД, "." + ПеревестиСтроку("Точки")) > 0 Тогда ОписаниеТаблицыБД = ОписаниеТаблицыБДЛкс(ИмяТаблицыБД); КонецЕсли; Если Истина И ОписаниеТаблицыБД <> Неопределено И ОписаниеТаблицыБД.Тип = "Точки" Тогда Если ПодтипРус = "Ссылка" Тогда Фрагменты = СтрРазделитьЛкс(ИмяТаблицыБД); Результат = ПеревестиСтроку("ТочкаМаршрутаБизнесПроцессаСсылка") + "." + Фрагменты[1]; КонецЕсли; Иначе ПолноеИмяМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицыБД); Если ПолноеИмяМД <> Неопределено Тогда Результат = ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД, ПодтипРус); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Возвращает имя типа, который будет использован в xml файле для указанного объекта метаданных // Используется при поиске и замене ссылок при загрузке, при модификации схемы current-config при записи // // Параметры: // Значение - Объект метаданных или Ссылка // // Возвращаемое значение: // Строка - Строка вида CatalogRef.Валюты, описывающая объект метаданных // Функция XMLТипСсылкиЛкс(Знач ОбъектМДИлиСсылка) Экспорт Если ТипЗнч(ОбъектМДИлиСсылка) = Тип("ОбъектМетаданных") Тогда Ссылка = Новый (ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ОбъектМДИлиСсылка)); Иначе Ссылка = ОбъектМДИлиСсылка; КонецЕсли; Результат = СериализаторXDTO.XMLТипЗнч(Ссылка).ИмяТипа; Возврат Результат; КонецФункции Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, Знач ПодтипРус = "НаборЗаписей") Экспорт Подтип = ПеревестиСтроку(ПодтипРус); Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД); Если Фрагменты.Количество() > 2 Тогда Если Фрагменты[0] = ПеревестиСтроку("РегистрРасчета") Тогда ИмяТипа = ПеревестиСтроку("Перерасчет") + Подтип + "." + Фрагменты[1] + "." + Фрагменты[2]; ИначеЕсли Фрагменты[0] = ПеревестиСтроку("РегистрБухгалтерии") Тогда ИмяТипа = ПеревестиСтроку("РегистрБухгалтерии") + Подтип + "." + Фрагменты[1]; ИначеЕсли Фрагменты[0] = ПеревестиСтроку("ВнешнийИсточникДанных") Тогда ИмяТипа = ПеревестиСтроку("ВнешнийИсточникДанныхТаблица") + Подтип + "." + Фрагменты[1] + "." + Фрагменты[3]; КонецЕсли; Иначе ИмяТипа = СтрЗаменить(ПеревестиСтроку(Фрагменты[0]) + "." + Фрагменты[1], ".", Подтип + "."); КонецЕсли; Возврат ИмяТипа; КонецФункции Функция ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки = Неопределено) Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда Возврат Объект.ЗаменитьИдентификаторОбъекта(); КонецЕсли; Если ИдентификаторСсылки = Неопределено Тогда ИдентификаторСсылки = Новый УникальныйИдентификатор; КонецЕсли; // Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=967697#967697 //Объект = СериализаторXDTO.ЗаписатьXDTO(Объект); //Объект.Ref = ИдентификаторСсылки; //Объект.IsFolder = ЭтоГруппаДляНового; //Объект = СериализаторXDTO.ПрочитатьXDTO(Объект); // // Этот метод опасный, т.к. может привести к нежелательным изменениям в объекте! ЗаписьХмл = Новый ЗаписьXML; ЗаписьХмл.УстановитьСтроку(); ЗаписатьXML(ЗаписьХмл, Объект); СтрокаХмл = ЗаписьХмл.Закрыть(); Попытка ТекущийИДСсылки = XMLСтрока(Объект.Ссылка); Исключение // Внешний источник данных ТекущийИДСсылки = ""; КонецПопытки; Если ЗначениеЗаполнено(ТекущийИДСсылки) Тогда ИмяЭлементаСсылки = "Ref"; СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаСсылки + ">" + ТекущийИДСсылки + "", "<" + ИмяЭлементаСсылки + ">" + XMLСтрока(ИдентификаторСсылки) + ""); //ИмяЭлементаЭтоГруппа = "IsFolder"; //Если Найти(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">") > 0 Тогда // СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(Объект.IsFolder) + "", // "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(ЭтоГруппаДляНового) + ""); //КонецЕсли; КонецЕсли; ЧтениеХмл = Новый ЧтениеXML; ЧтениеХмл.УстановитьСтроку(СтрокаХмл); Объект = ПрочитатьXML(ЧтениеХмл); Возврат Объект; КонецФункции Функция НедоступноИзменениеПоляСсылочногоОбъектаЛкс(Знач ИмяПоля) Экспорт НедоступноИзменениеПоля = Ложь Или Нрег(ИмяПоля) = Нрег("Ссылка") Или Нрег(ИмяПоля) = Нрег("ВерсияДанных") Или Нрег(ИмяПоля) = Нрег("ЭтоГруппа") //Или Нрег(ИмяПоля) = Нрег("ЭтотУзел") // ошибочно помечен как нередактируемый в синтакс-помощнике Или Нрег(ИмяПоля) = Нрег("Предопределенный"); Возврат НедоступноИзменениеПоля; КонецФункции // Функция - Параметры доступа к объекту МДЛкс // // Параметры: // Право - - // МетаОбъект - - // РольИлиПользователь - - // выхПраваНеПрименимы - - // выхИмяПоля - Строка - Неопределено - сначала подбор полей Ссылка, Период; "" - сразу получаем все поля и берем первое // // Возвращаемое значение: // - // Функция ПараметрыДоступаКОбъектуМДЛкс(Знач Право, Знач МетаОбъект, Знач РольИлиПользователь = Неопределено, выхПраваНеПрименимы = Ложь, выхИмяПоля = Неопределено) Экспорт Если выхИмяПоля = Неопределено Тогда ИменаПолей = Новый Массив; ИменаПолей.Добавить("Ссылка"); ИменаПолей.Добавить("Период"); Для Каждого ИмяПоля Из ИменаПолей Цикл Попытка ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, ИмяПоля, РольИлиПользователь); Прервать; Исключение КонецПопытки; КонецЦикла; ИначеЕсли выхИмяПоля <> "" Тогда Попытка ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, выхИмяПоля, РольИлиПользователь); Исключение КонецПопытки; КонецЕсли; Если ПараметрыДоступа = Неопределено Тогда Попытка ПоляТаблицы = ПолучитьПоляТаблицыМДЛкс(МетаОбъект, Ложь,,, Ложь); ИмяПоля = ПоляТаблицы[0].Имя; ПараметрыДоступа = ПараметрыДоступа(Право, МетаОбъект, ИмяПоля, РольИлиПользователь); выхИмяПоля = ИмяПоля; Исключение // Например это Обработка, Перечисление ОписаниеОшибки = ОписаниеОшибки(); // Для отладки ПараметрыДоступа = Неопределено; // Баг 8.3.13 Эта функция возвращает Истина даже для некорректных комбинаций параметров //Попытка // ПараметрыДоступа = ПравоДоступа(КлючИЗначение.Ключ, МетаОбъект, Роль); //Исключение выхПраваНеПрименимы = Истина; //КонецПопытки; КонецПопытки; КонецЕсли; Возврат ПараметрыДоступа; КонецФункции Функция ЕстьОграниченияДоступаКСтрокамТаблицыНаЧтениеЛкс(Знач ОбъектМД) Экспорт ЕстьПраваДоступаКСтрокам = Ложь; ПараметрыДоступа = ПараметрыДоступаКОбъектуМДЛкс("Чтение", ОбъектМД); Если ПараметрыДоступа = Неопределено Тогда Возврат Ложь; КонецЕсли; #Если Сервер И Не Сервер Тогда ПараметрыДоступа = ПараметрыДоступа(); #КонецЕсли Если ПараметрыДоступа.Доступность Тогда ЕстьПраваДоступаКСтрокам = ПараметрыДоступа.ОграничениеУсловием; КонецЕсли; Возврат ЕстьПраваДоступаКСтрокам; КонецФункции Функция ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс(РазрешитьВПортативномВарианте = Истина) Экспорт Результат = Истина И (Ложь Или Не ирКэш.ЛиПортативныйРежимЛкс() Или РазрешитьВПортативномВарианте И ирПортативный.ЛиСерверныйМодульДоступенЛкс()) И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение; Возврат Результат; КонецФункции Функция СкопироватьКолонкиКоллекцииЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда КоллекцияИсточник = Новый ТаблицаЗначений; #КонецЕсли Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый (ТипЗнч(КоллекцияИсточник)); КонецЕсли; #Если Сервер И Не Сервер Тогда КоллекцияПриемник = Новый ТаблицаЗначений; #КонецЕсли Для Каждого Колонка Из КоллекцияИсточник.Колонки Цикл Если КоллекцияПриемник.Колонки.Найти(Колонка.Имя) <> Неопределено Тогда Продолжить; КонецЕсли; КоллекцияПриемник.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения, Колонка.Заголовок, Колонка.Ширина); КонецЦикла; Возврат КоллекцияПриемник; КонецФункции // ПропускатьДвиженияВнеПланаОбмена - Булево - при РегистрироватьДвиженияВместеСДокументом = Истина позволяет управлять поведением для тех движений, которые не входят в план обмена, // Если Истина, то такие движения пропускаются, иначе вызывается исключение Функция ПланыОбменаИзменитьРегистрациюЛкс(УзелИлиМассив, КлючОбъекта, НовоеЗначение = Истина, РегистрироватьДвиженияВместеСДокументом = Ложь, ДвиженияВместеСПоследовательностями = Ложь, ПропускатьДвиженияВнеПланаОбмена = Истина, ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла = Ложь) Экспорт Если КлючОбъекта = Неопределено Тогда ВызватьИсключение "Изменение регистрации всех данных недопустимо"; КонецЕсли; Если ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда ОбъектМД = КлючОбъекта; Иначе ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(КлючОбъекта)); КонецЕсли; Если РегистрироватьДвиженияВместеСДокументом Тогда ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ЭтоДокумент = ЛиКорневойТипДокументаЛкс(ПервыйФрагментЛкс(ПолноеИмяМД)); КонецЕсли; Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент И ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ " + ПолноеИмяМД + " КАК Т"); МассивОбъектов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0); Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МассивОбъектов.Количество(), "Изменение регистрации"); Иначе МассивОбъектов = Новый Массив; МассивОбъектов.Добавить(КлючОбъекта); КонецЕсли; Если ТипЗнч(УзелИлиМассив) = Тип("Массив") Тогда Если УзелИлиМассив.Количество() > 0 Тогда ОдинУзелОбмена = УзелИлиМассив[0]; Иначе ОдинУзелОбмена = Неопределено; КонецЕсли; МассивУзлов = УзелИлиМассив; Иначе ОдинУзелОбмена = УзелИлиМассив; МассивУзлов = Новый Массив; МассивУзлов.Добавить(УзелИлиМассив); КонецЕсли; Если Не ЗначениеЗаполнено(ОдинУзелОбмена) Тогда СообщитьЛкс("Не указан узел для регистрации изменений"); Возврат Ложь; КонецЕсли; Если ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла Тогда УзлыДляРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов); Если УзлыДляРегистрации.Количество() = 0 Тогда Возврат Истина; КонецЕсли; Иначе УзлыДляРегистрации = МассивУзлов; КонецЕсли; Успех = Истина; НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс(); Для Каждого Объект Из МассивОбъектов Цикл Если Индикатор <> Неопределено Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонецЕсли; Если ТипЗнч(Объект) = Тип("Структура") Тогда Объект = Объект.Методы; КонецЕсли; ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, Объект, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы); Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина); Для Каждого МетаРегистр из ОбъектыМД Цикл Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда Если ПропускатьДвиженияВнеПланаОбмена Тогда Продолжить; Иначе ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя; КонецЕсли; КонецЕсли; ИмяТаблицыБДРегистра = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(МетаРегистр); ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра); СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ИмяТаблицыБДРегистра, Новый Структура(ИмяПоляОтбора, Объект.Ссылка),, Ложь); ИзменитьРегистрациюОбъектаДляУзлаЛкс(УзлыДляРегистрации, СтруктураНабораЗаписей.Методы, НовоеЗначение, ОдинУзелОбмена, НомерВерсииПлатформы); КонецЦикла; КонецЕсли; КонецЦикла; Если Индикатор <> Неопределено Тогда ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; Возврат Успех; КонецФункции Процедура ИзменитьРегистрациюОбъектаДляУзлаЛкс(Знач УзлыДляРегистрации, Знач Объект, Знач НовоеЗначение, Знач ОдинУзелОбменаДляПроверки, Знач НомерВерсииПлатформы = "") Экспорт ТипОбъекта = ТипЗнч(Объект); ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта); Если ЭтоИмитатор Тогда ОбъектXML = Объект.Снимок(); ирСервер.ИзменитьРегистрациюОбъектаДляУзлаЛкс(ОбъектXML, ТипОбъекта, УзлыДляРегистрации, НовоеЗначение, ОдинУзелОбменаДляПроверки, НомерВерсииПлатформы); Иначе Если НовоеЗначение Тогда ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, Объект); Если НомерВерсииПлатформы = Неопределено Тогда НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс(); КонецЕсли; // Антибаг платформы 8.2.17-8.3.4 Если Истина И НомерВерсииПлатформы < 803005 И ТипЗнч(Объект) <> Тип("ОбъектМетаданных") И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбменаДляПроверки, Объект) Тогда Успех = Ложь; СообщитьЛкс("Не удалось зарегистрировать изменение """ + Объект + """ из-за ошибки платформы, исправленной в 8.3.5"); КонецЕсли; Иначе ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, Объект); КонецЕсли; КонецЕсли; КонецПроцедуры Функция ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов, ТолькоУзлыСАвторегистрацией = Ложь) Экспорт УзлыДляРегистрации = Новый Массив; Для Каждого ПроверяемыйУзел Из МассивУзлов Цикл ЭлементСостава = ПроверяемыйУзел.Метаданные().Состав.Найти(ОбъектМД); Если Истина И ЭлементСостава <> Неопределено И (Ложь Или Не ТолькоУзлыСАвторегистрацией Или ЭлементСостава.АвтоРегистрация = АвтоРегистрацияИзменений.Разрешить) Тогда УзлыДляРегистрации.Добавить(ПроверяемыйУзел); КонецЕсли; КонецЦикла; Возврат УзлыДляРегистрации; КонецФункции // Копирует регистрацию изменений с узла источника на узлы приемники. Опционально каждый тип данных отдельно равномерно распределяется по узлам приемникам. // Параметры: // НомерСообщения - Неопределено - брать номер отправленного с узла, Null - не фильтровать но номеру сообщения, иначе выбираются все изменения с номером равным или меньшим заданного // Возвращаемое значение: Массив - количество изменений зарегистрированных по каждому узлу Функция СкопироватьРаспределитьРегистрациюИзмененийПоУзламЛкс(УзелИсточник, УзлыПриемники, Распределять = Ложь, НомерСообщения = Null, МассивМетаданных = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда УзелИсточник = ПланыОбмена.Полный.ПустаяСсылка(); УзлыПриемники = Новый Массив; #КонецЕсли #Если Клиент Тогда СостояниеЛкс("Выбираем все изменения для узла..."); #КонецЕсли Если НомерСообщения = Неопределено Тогда НомерСообщения = УзелИсточник.НомерОтправленного; КонецЕсли; Результат = Новый Массив; Для Счетчик = 1 По УзлыПриемники.Количество() Цикл Если Распределять И ТипЗнч(УзлыПриемники[Счетчик - 1]) <> ТипЗнч(УзелИсточник) Тогда ВызватьИсключение "Нельзя распределять на узлы другого плана обмена"; КонецЕсли; Результат.Добавить(0); КонецЦикла; Запрос = Новый Запрос; Запрос.УстановитьПараметр("Узел", УзелИсточник); Запрос.УстановитьПараметр("НомерСообщения", НомерСообщения); МетаПланОбмена = УзелИсточник.Метаданные(); ТекстЗапроса = ""; ТипыДанныхЗапросов = Новый Массив; Для Каждого ЭлементСостава Из МетаПланОбмена.Состав Цикл МетаОбъект = ЭлементСостава.Метаданные; Если Ложь Или МетаОбъект = Неопределено Или (Истина И МассивМетаданных <> Неопределено И МассивМетаданных.Найти(МетаОбъект) = Неопределено) Тогда Продолжить; КонецЕсли; Если ТекстЗапроса <> "" Тогда ТекстЗапроса = ТекстЗапроса + ";" + Символы.ПС; КонецЕсли; ПолноеИмяМД = МетаОбъект.ПолноеИмя(); ТипыДанныхЗапросов.Добавить(ПолноеИмяМД); ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(ПолноеИмяМД, ".Перерасчет.", ".") + ".Изменения"; ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ * |ИЗ | " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений |ГДЕ | РегистрацияИзменений.Узел = &Узел"; Если НомерСообщения <> Null Тогда ТекстЗапроса = ТекстЗапроса = " И НомерСообщения <= &НомерСообщения"; КонецЕсли; КонецЦикла; Если ТекстЗапроса <> "" Тогда Запрос.Текст = ТекстЗапроса; РезультатПакета = Запрос.ВыполнитьПакет(); ИндикаторСостава = ПолучитьИндикаторПроцессаЛкс(РезультатПакета.Количество(), "Распределение изменений"); Для ИндексЗапроса = 0 По РезультатПакета.ВГраница() Цикл ОбработатьИндикаторЛкс(ИндикаторСостава); РезультатЗапроса = РезультатПакета[ИндексЗапроса]; #Если Сервер И Не Сервер Тогда РезультатЗапроса1 = Новый Запрос; РезультатЗапроса = РезультатЗапроса1.Выполнить(); #КонецЕсли ПолноеИмяМД = ТипыДанныхЗапросов[ИндексЗапроса]; //Если Ложь // Или РезультатЗапроса.Колонки.Найти("НомерСообщения1") <> Неопределено // Или РезультатЗапроса.Колонки.Найти("Узел1") <> Неопределено //Тогда // ВызватьИсключение "В таблице " + ПолноеИмяМД + " в основной отбор включены измерения с запрещенными именами (НомерСообщения, Узел)"; //КонецЕсли; ТаблицаКорректна = Истина; Для Каждого КолонкаРезультата Из РезультатЗапроса.Колонки Цикл Если Не ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, КолонкаРезультата.Имя) Тогда СообщитьЛкс("Изменения таблицы " + ПолноеИмяМД + " не были скопированы, т.к. она имеет некорректное поле " + КолонкаРезультата.Имя + ", порожденное конфликтом имен полей"); ТаблицаКорректна = Ложь; Прервать; КонецЕсли; КонецЦикла; Если Не ТаблицаКорректна Тогда Продолжить; КонецЕсли; МакетныйОбъект = ""; ТекущаяГруппаТипаМетаданных = ""; Выборка = РезультатЗапроса.Выбрать(); ИндексУзла = 0; КоличествоЭлементов = Выборка.Количество(); Если КоличествоЭлементов > 0 Тогда Если Распределять Тогда УзлыРегистрации = УзлыПриемники; Иначе УзлыРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД), УзлыПриемники); Если УзлыРегистрации.Количество() < УзлыПриемники.Количество() Тогда СообщитьЛкс("Изменения таблицы " + ПолноеИмяМД + " были скопированы не на все узлы, т.к. некоторые планы обмена приемников не содержат ее."); КонецЕсли; КонецЕсли; Если УзлыРегистрации.Количество() > 0 Тогда ИндикаторТаблицы = ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПолноеИмяМД); ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМД, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); //, КлючевыеПоля Пока Выборка.Следующий() Цикл ОбработатьИндикаторЛкс(ИндикаторТаблицы); Объект = ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Выборка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Ложь, "НомерСообщения, Узел"); // Регистрация Если Распределять Тогда УзелПриемник = УзлыРегистрации[ИндексУзла]; ПланыОбменаИзменитьРегистрациюЛкс(УзелПриемник, Объект); Результат[ИндексУзла] = Результат[ИндексУзла] + 1; ИндексУзла = ИндексУзла + 1; Если ИндексУзла = УзлыРегистрации.Количество() Тогда ИндексУзла = 0; КонецЕсли; Иначе ПланыОбменаИзменитьРегистрациюЛкс(УзлыРегистрации, Объект); Результат[0] = Результат[0] + 1; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; Возврат Результат; КонецФункции Функция ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, ИмяПоля) Экспорт Если Ложь Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "Узел1") Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "НомерСообщения1") Тогда //ПолноеИмяРегистра = ирОбщий.СтрокаМеждуМаркерамиЛкс(ПолноеИмяТаблицыБД,, ".Изменения"); КорневойТип = ПервыйФрагментЛкс(ПолноеИмяМД); Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМД); Если ОбъектМД <> Неопределено Тогда Если ОбъектМД.Измерения.Найти("" + ИмяПоля) = Неопределено Тогда Возврат Ложь; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Истина; КонецФункции // ИгнорироватьКолонки - Строка - имена колонок через запятую, которые не будут учитываться Функция ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Знач ДанныеСтроки, Знач МакетныйОбъект, Знач ТекущаяГруппаТипаМетаданных, СчитатьДанныеОбъекта = Истина, Знач ИгнорироватьКолонки = "", Заблокировать = Ложь, ОбъектыНаСервере = Неопределено) Экспорт Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда СтруктураОбъекта = ДанныеСтроки.Ссылка; Если Заблокировать Тогда ЗаблокироватьСсылкуВТранзакцииЛкс(СтруктураОбъекта); КонецЕсли; Если СчитатьДанныеОбъекта Тогда СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(СтруктураОбъекта.Метаданные().ПолноеИмя(), СтруктураОбъекта,,, ОбъектыНаСервере); КонецЕсли; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда Если ЛиКлючЗаписиРегистраЛкс(ДанныеСтроки) Тогда ДанныеСтроки = ирОбщий.ДанныеСтрокиРегистраИзКлючаЗаписиЛкс(ДанныеСтроки); КонецЕсли; СтруктураОбъекта = МакетныйОбъект; Если ЗначениеЗаполнено(ИгнорироватьКолонки) Тогда ИгнорироватьКолонки = Нрег(ИгнорироватьКолонки) + ","; КонецЕсли; Для Каждого ЭлементОтбора Из СтруктураОбъекта.Методы.Отбор Цикл Если Найти(ИгнорироватьКолонки, НРег(ЭлементОтбора.Имя) + ",") > 0 Тогда Продолжить; КонецЕсли; Попытка ЗначениеПоля = ДанныеСтроки[ЭлементОтбора.Имя]; Исключение // Независимый регистр сведений, у измерения не включен ОсновнойОтбор Продолжить; КонецПопытки; ЭлементОтбора.Значение = ЗначениеПоля; ЭлементОтбора.Использование = Истина; КонецЦикла; Если Заблокировать Тогда ЗаблокироватьНаборЗаписейПоОтборуЛкс(СтруктураОбъекта); КонецЕсли; Если СчитатьДанныеОбъекта Тогда СтруктураОбъекта.Методы.Прочитать(); КонецЕсли; ИначеЕсли ТекущаяГруппаТипаМетаданных = "Константа" Тогда СтруктураОбъекта = МакетныйОбъект; Если Заблокировать Тогда ЗаблокироватьКонстантуЛкс(СтруктураОбъекта); КонецЕсли; Если СчитатьДанныеОбъекта Тогда СтруктураОбъекта.Методы.Прочитать(); КонецЕсли; КонецЕсли; Возврат СтруктураОбъекта; КонецФункции // Добавляет глобальные переменные и методы в контекст поля текстового документа с контекстной подсказкой. // // Параметры // ПолеТекстовогоДокументаСКонтекстнойПодсказкой - ОбработкаОбъект.ПолеТекстовогоДокументаСКонтекстнойПодсказкой. // Процедура ИнициализироватьГлобальныйКонтекстПодсказкиЛкс(ПолеТекстовогоДокументаСКонтекстнойПодсказкой) Экспорт #Если Сервер И Не Сервер Тогда ПолеТекстовогоДокументаСКонтекстнойПодсказкой = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать(); #КонецЕсли Если ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ЯзыкПрограммы = 1 Тогда Возврат; КонецЕсли; ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ОчиститьТаблицуСловЛокальногоКонтекста(); ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьПравилоВычисленияФункции( "ирКПА", "ПравилоВычисленияТипаЗначенияКПА"); МассивГлобальныхПеременных = Новый Массив; МассивГлобальныхПеременных.Добавить("ирПлатформа"); Для Каждого ИмяГлобальнойПеременной Из МассивГлобальныхПеременных Цикл Попытка ГлобальнаяПеременная = ВычислитьВыражение(ИмяГлобальнойПеременной); Исключение // ирПлатформа может отсутствовать Продолжить; КонецПопытки; МассивТипов = Новый Массив; МассивТипов.Добавить(ТипЗнч(ГлобальнаяПеременная)); ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста( ИмяГлобальнойПеременной, "Свойство", Новый ОписаниеТипов(МассивТипов), ГлобальнаяПеременная, Истина); КонецЦикла; СтруктураГлобальныхФункций = Новый Структура; СтруктураГлобальныхФункций.Вставить("Исследовать", Тип("Число")); СтруктураГлобальныхФункций.Вставить("Отладить", Тип("Число")); СтруктураГлобальныхФункций.Вставить("Оперировать", Тип("Число")); СтруктураГлобальныхФункций.Вставить("Наблюдать"); Для Каждого ЭлементГлобальнойФункции Из СтруктураГлобальныхФункций Цикл Если ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("Тип") Тогда МассивТипов = Новый Массив; МассивТипов.Добавить(ЭлементГлобальнойФункции.Значение); ОписаниеТипов = Новый ОписаниеТипов(МассивТипов); ИначеЕсли ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("ОписаниеТипов") Тогда ОписаниеТипов = ЭлементГлобальнойФункции.Значение; КонецЕсли; ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста( ЭлементГлобальнойФункции.Ключ, "Метод", ОписаниеТипов); КонецЦикла; КонецПроцедуры // ИнициализироватьГлобальныйКонтекстПодсказкиЛкс() // Параметры - ТаблицаЗначений с колонкой Имя Функция ПроверитьТаблицуПараметровЛкс(Параметры, Заголовок = "") Экспорт Результат = Истина; Если Параметры.Количество() = 0 Тогда Возврат Результат; КонецЕсли; Для Каждого СтрокаПараметра Из Параметры Цикл Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда Результат = Ложь; СообщитьЛкс(Заголовок + "Имя параметра """ + СтрокаПараметра.Имя + """ некорректно", СтатусСообщения.Внимание); КонецЕсли; КонецЦикла; НеуникальныеИмена = НеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя"); Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл СообщитьЛкс(Заголовок + "Параметр """ + НеуникальноеИмя + """ встречается более одного раза", СтатусСообщения.Внимание); Результат = Ложь; КонецЦикла; Возврат Результат; КонецФункции // ПараметрыКорректны() // Возможно нужно объединить с ПолучитьМетаданныеЛкс Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт Объект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД); Результат = Объект.Метаданные(); Возврат Результат; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С МЕТАДАННЫМИ И ТИПАМИ // Получает тип из описания типов, типа или значения. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Тип - найденный тип. // Функция ПолучитьТипОбъектаЛкс(пОбъект) ТипОбъекта = Тип("Неопределено"); ТипПараметра = ТипЗнч(пОбъект); Если ТипПараметра = Тип("ОписаниеТипов") Тогда Если пОбъект.Типы().Количество() > 0 Тогда ТипОбъекта = пОбъект.Типы()[0]; КонецЕсли; ИначеЕсли ТипПараметра <> Тип("Тип") Тогда ТипОбъекта = ТипПараметра; Иначе ТипОбъекта = пОбъект; КонецЕсли; Возврат ТипОбъекта; КонецФункции // ПолучитьТипОбъектаЛкс() // Проверяет, является ли строка именем корневого типа объекта БД. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом объекта БД; // Ложь – иначе. // Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(Знач КорневойТип) Экспорт Если Найти(КорневойТип, ".") > 0 Тогда КорневойТип = ПервыйФрагментЛкс(КорневойТип); КонецЕсли; Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "БизнесПроцесс" ИЛИ КорневойТип = "Задача" ИЛИ КорневойТип = "Документ" ИЛИ КорневойТип = "ПланВидовРасчета" ИЛИ КорневойТип = "ПланВидовХарактеристик" ИЛИ КорневойТип = "ПланОбмена" ИЛИ КорневойТип = "ПланСчетов" ИЛИ КорневойТип = "Справочник" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипКонстантыЛкс(Знач КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "Константа" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипПланаОбменаЛкс(Знач КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "ПланОбмена" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипДокументаЛкс(Знач КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "Документ" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипБизнесПроцессаЛкс(Знач КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "БизнесПроцесс" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли строка именем корневого типа ссылки. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом ссылки; // Ложь – иначе. // Функция ЛиКорневойТипСсылкиЛкс(Знач КорневойТип, ИсключаяСсылкиМетаданных = Ложь, ИсключаяВнешниеИсточникиДанных = Ложь) Экспорт Если Найти(КорневойТип, ".") > 0 Тогда КорневойТип = ПервыйФрагментЛкс(КорневойТип); КонецЕсли; Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Перечисление" ИЛИ Не ИсключаяСсылкиМетаданных И КорневойТип = "Точки" // Грязно ИЛИ Не ИсключаяВнешниеИсточникиДанных И КорневойТип = "ВнешнийИсточникДанных" // Грязно ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли строка именем корневого типа регистра БД. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом регистра БД; // Ложь – иначе. // Функция ЛиКорневойТипРегистраБДЛкс(Знач КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "РегистрСведений" ИЛИ КорневойТип = "РегистрНакопления" ИЛИ КорневойТип = "РегистрБухгалтерии" ИЛИ КорневойТип = "ДвиженияССубконто" ИЛИ КорневойТип = "РегистрРасчета" ИЛИ КорневойТип = "Перерасчет" ИЛИ (Истина И СчитатьПоследовательностьРегистром И КорневойТип = "Последовательность") Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если КорневойТип = "РегистрРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если КорневойТип = "РегистрСведений" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если КорневойТип = "РегистрБухгалтерии" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипРегистраНакопленияЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если КорневойТип = "РегистрНакопления" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если КорневойТип = "Последовательность" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если КорневойТип = "Перечисление" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт Если КодСимвола(ТипТаблицы, 1) < 128 Тогда ТипТаблицы = ПеревестиВРусский(ТипТаблицы); КонецЕсли; Если Ложь ИЛИ ТипТаблицы = "Перечисление" ИЛИ ТипТаблицы = "Точки" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипРегистраБДЛкс() Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "ЖурналДокументов" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь ИЛИ КорневойТип = "КритерийОтбора" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Или ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли строка именем типа вложенной таблицы БД. // // Параметры: // ТипТаблицы - Строка, Неопределено - имя типа таблицы. // // Возвращаемое значение: // Булево. // Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт Если КодСимвола(ТипТаблицы, 1) < 128 Тогда ТипТаблицы = ПеревестиВРусский(ТипТаблицы); КонецЕсли; Если Ложь ИЛИ ТипТаблицы = "ТабличнаяЧасть" ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиТипВложеннойТаблицыБДЛкс() Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт Если КодСимвола(ТипТаблицы, 1) < 128 Тогда ТипТаблицы = ПеревестиВРусский(ТипТаблицы); КонецЕсли; Если Ложь ИЛИ ТипТаблицы = "ВидыСубконто" ИЛИ ТипТаблицы = "БазовыеВидыРасчета" ИЛИ ТипТаблицы = "ВедущиеВидыРасчета" ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, корневой тип на наличие реквизита "Код". // // Параметры: // КорневойТип - Строка, Произвольный. // // Возвращаемое значение: // Истина – реквизит "Код" имеется; // Ложь – иначе. // Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь Или КорневойТип = "ПланВидовХарактеристик" Или КорневойТип = "ПланОбмена" Или КорневойТип = "ПланСчетов" Или КорневойТип = "ПланРасчета" Или КорневойТип = "Справочник" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс() // Проверяет, корневой тип на наличие реквизита "Предопределенный". // // Параметры: // КорневойТип - Строка, Произвольный. // // Возвращаемое значение: // Истина – реквизит "Предопределенный" имеется; // Ложь – иначе. // Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланСчетов" Или КорневойТип = "ПланВидовХарактеристик" Или КорневойТип = "ПланВидовРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс() // Проверяет, метаданные на иерархию. // Иначе говоря проверяется начилие реквизита "Родитель". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией; // Ложь – иначе. // Функция ЛиМетаданныеИерархическогоОбъектаЛкс(пМетаданныеТипа) Экспорт КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа); Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь Или КорневойТип = "ПланСчетов" Или (Истина И (Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланВидовХарактеристик") И пМетаданныеТипа.Иерархический) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс() // Проверяет, метаданные на иерархию. // Иначе говоря проверяется начилие реквизита "Родитель". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией; // Ложь – иначе. // Функция ЛиМетаданныеПодчиненногоОбъектаЛкс(пМетаданныеТипа) Экспорт КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа); Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Истина И (Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланВидовХарактеристик") И пМетаданныеТипа.Владельцы.Количество() > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс() // Проверяет, метаданные на иерархию с группами. // Иначе говоря проверяется начилие реквизита "ЭтоГруппа". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией групп; // Ложь – иначе. // Функция ЛиМетаданныеОбъектаСГруппамиЛкс(пМетаданныеТипа) Экспорт //ТипТаблицы = ТипТаблицыБДЛкс(пМетаданныеТипа); КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа, Истина); Если КодСимвола(КорневойТип, 1) < 128 Тогда КорневойТип = ПеревестиВРусский(КорневойТип); КонецЕсли; Если Ложь Или (Истина И КорневойТип = "Справочник" И пМетаданныеТипа.Иерархический И пМетаданныеТипа.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов) Или (Истина И КорневойТип = "ПланВидовХарактеристик" И пМетаданныеТипа.Иерархический) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли значение ссылкой на объект БД. // // Параметры: // пЗначение – ОбъектМетаданных, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является ссылкой на объект БД; // Ложь – значение не является ссылкой на объект БД. // Функция ЛиСсылкаНаОбъектБДЛкс(пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт //Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьКорневойТипКонфигурацииЛкс(пЗначение, Истина)); Результат = ЛиТипСсылкиБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных); Возврат Результат; КонецФункции // ЛиСсылкаНаОбъектБДЛкс Функция ЛиТипСсылкиБДЛкс(Тип, ИсключаяСсылкиМетаданных = Истина) Экспорт Результат = Ложь; ХмлТип = XMLТип(Тип); Если ХмлТип <> Неопределено Тогда Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда Если Ложь Или Не ИсключаяСсылкиМетаданных Или (Истина И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0 И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0) Тогда Результат = Истина; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиТипОбъектаБДЛкс(Тип) Экспорт Результат = Ложь; ХмлТип = XMLТип(Тип); Если ХмлТип <> Неопределено Тогда Если Ложь Или Найти(ХмлТип.ИмяТипа, "Object.") > 0 Или Найти(ХмлТип.ИмяТипа, "RecordSet.") > 0 Или Найти(ХмлТип.ИмяТипа, "ValueManager.") > 0 Тогда Результат = Истина; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт XMLТип = XMLТип(Тип); Если XMLТип <> Неопределено Тогда Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда Возврат Истина; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции // Получить структуру отбора по связям И параметрам выбора // // Параметры: // ЭтотОбъект - <тип> - // ПолеФормыИлиРеквизитМетаданных - <тип> - // ДляОчистки - <тип>, Ложь - // // Возвращаемое значение: // Функция ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ЭтотОбъект, ПолеФормыИлиРеквизитМетаданных, ДляОчистки = Ложь) Экспорт Попытка СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора; Исключение Возврат Новый Структура(); КонецПопытки; ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора; Результат = Новый Структура("Отбор", Новый Структура); Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл #Если Сервер И Не Сервер Тогда СвязьПараметраВыбора = Новый СвязьПараметраВыбора; #КонецЕсли Если Истина И ДляОчистки И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять Тогда Продолжить; КонецЕсли; Попытка ЗначениеДанных = Вычислить("ЭтотОбъект." + СвязьПараметраВыбора.ПутьКДанным); Исключение // Например поле таблицы или на сервере текущая строка таблицы Продолжить; КонецПопытки; УстановитьВложенноеСвойствоСтруктурыЛкс(Результат, СвязьПараметраВыбора.Имя, ЗначениеДанных); КонецЦикла; Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл #Если Сервер И Не Сервер Тогда ПараметрВыбора = Новый ПараметрВыбора; #КонецЕсли УстановитьВложенноеСвойствоСтруктурыЛкс(Результат, ПараметрВыбора.Имя, ПараметрВыбора.Значение); КонецЦикла; Результат = Результат.Отбор; // Возможно потом перейдем везде на передачу полной структуры Возврат Результат; КонецФункции Процедура УстановитьВложенноеСвойствоСтруктурыЛкс(Знач НачальнаяСтруктура, Знач ПолноеИмяСвойства, Знач ЗначениеДанных) Фрагменты = СтрРазделитьЛкс("_." + ПолноеИмяСвойства); ТекущаяСтруктура = Новый Структура("_", НачальнаяСтруктура); Для Индекс = 0 По Фрагменты.Вграница() - 1 Цикл ТекущаяСтруктура = ТекущаяСтруктура[Фрагменты[Индекс]]; Если Не ТекущаяСтруктура.Свойство(Фрагменты[Индекс + 1]) Тогда ТекущаяСтруктура.Вставить(Фрагменты[Индекс + 1], Новый Структура); КонецЕсли; КонецЦикла; ТекущаяСтруктура[Фрагменты[Фрагменты.Вграница()]] = ЗначениеДанных; КонецПроцедуры // Проверяет, является ли значение ссылкой на значение перечисления. // // Параметры: // пЗначение – Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является ссылкой на объект БД; // Ложь – значение не является ссылкой на объект БД. // Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт Возврат (ПолучитьКорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление"); КонецФункции // ЛиСсылкаНаПеречислениеЛкс() // Проверяет, является ли ключом записи регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип ключа записи регистра подтвержден; // Ложь – тип ключа записи регистра не подтвержден. // Функция ЛиКлючЗаписиРегистраЛкс(Объект) Экспорт ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("КлючЗаписи"); Результат = Истина И ТипОбразец <> Неопределено И ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":"), " ") = ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":"), " "); Возврат Результат; КонецФункции // ЛиКлючЗаписиРегистраЛкс() &НаКлиенте Функция ЛиКлючСсылкиИлиРегистраЛкс(Знач Объект) Экспорт Возврат Ложь Или ЛиСсылкаНаОбъектБДЛкс(Объект) Или ЛиКлючЗаписиРегистраЛкс(Объект); КонецФункции // Проверяет, является ли записью регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип записи регистра подтвержден; // Ложь – тип записи регистра не подтвержден. // Функция ЛиЗаписьРегистраЛкс(Объект) Экспорт ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("Запись"); Результат = Истина И ТипОбразец <> Неопределено И ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":"), " ") = ирОбщий.ПоследнийФрагментЛкс(ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":"), " "); Возврат Результат; КонецФункции // ЛксЛиКлючЗаписиБД() // Проверяет, является ли набором записей регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип набора записей регистра подтвержден; // Ложь – тип набора записей регистра не подтвержден. // Функция ЛиНаборЗаписейРегистраЛкс(Объект) Экспорт ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("НаборЗаписей"); Результат = Истина И ТипОбразец <> Неопределено И ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":") = ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":"); Возврат Результат; КонецФункции // ЛиНаборЗаписейРегистраЛкс() // Проверяет, является ли менеджером записи регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип менеджер записи регистра подтвержден; // Ложь – тип менеджер записи регистра не подтвержден. // Функция ЛиМенеджерЗаписиРегистраЛкс(Объект) Экспорт ТипОбразец = ирКэш.ПервыйПроизводныйТипРегистраЛкс("МенеджерЗаписи"); Результат = Истина И ТипОбразец <> Неопределено И ирОбщий.ПервыйФрагментЛкс("" + ТипОбразец, ":") = ирОбщий.ПервыйФрагментЛкс("" + ПолучитьТипОбъектаЛкс(Объект), ":"); Возврат Результат; КонецФункции // Проверяет, является ли субконтом описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип субконто подтвержден; // Ложь – тип субконто не подтвержден. // Функция ЛиСубконтоЛкс(пОбъект) Экспорт ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект); Маркер = "субконто:"; Если Найти(Строка(ТипОбъекта), Маркер) > 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 Тогда Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Если ЛиСТабличнымиЧастями Тогда #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть; КонецЕсли; #КонецЕсли Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл Если Ложь Или ЛиВключатьНедоступные Или Не ИерархияГрупп Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента Или (Истина И ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Или (Истина И Не ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Тогда СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Если ЛиСортировать Тогда СписокРеквизитов.СортироватьПоПредставлению(); КонецЕсли; Возврат СписокРеквизитов; КонецФункции // ПолучитьСписокРеквизитовОбъектаБДЛкс() Функция ИмяФайлаСпискаИнфобазПользователяОСЛкс() Экспорт App = Новый COMОбъект("Shell.Application"); AppData = App.Namespace(26).Self.Path; ИмяФайлаСписка = AppData + "\1C\1CEStart\ibases.v8i"; Возврат ИмяФайлаСписка; КонецФункции // Описатель - ОбъектМетаданных - его реквизиты переносятся в коллекцию в качестве элементов для структуры и в качестве колонок для дерева или таблицы // - Коллекция с элементами РеквизитФормы, ОбъектМетаданных:Реквизит // ИсходнаяКоллекция - ТаблицаЗначений, ДеревоЗначений, Структура - по умолчанию создается ТаблицаЗначений // Функция УстановитьМетаданныеКоллекцииЛкс(Описатель, ИсходнаяКоллекция = Неопределено) Экспорт Если ИсходнаяКоллекция = Неопределено Тогда ИсходнаяКоллекция = Новый ТаблицаЗначений; КонецЕсли; ТипИсходнойКоллекции = ТипЗнч(ИсходнаяКоллекция); Если Ложь Или ТипИсходнойКоллекции = Тип("ДеревоЗначений") Или ТипИсходнойКоллекции = Тип("ТаблицаЗначений") Тогда Коллекция = ИсходнаяКоллекция.Колонки; Колонки = Коллекция; Иначе//Если ТипИсходнойКоллекции = Тип("Структура") Тогда Коллекция = ИсходнаяКоллекция; Если ТипЗнч(ИсходнаяКоллекция) = Тип("Структура") Тогда Пустышка = Новый ТаблицаЗначений; Колонки = Пустышка.Колонки; Иначе Колонки = Коллекция; КонецЕсли; КонецЕсли; Если ТипЗнч(Описатель) = Тип("ОбъектМетаданных") Тогда Реквизиты = Описатель.Реквизиты; Иначе Реквизиты = Описатель; КонецЕсли; Для Каждого Реквизит Из Реквизиты Цикл Если ТипЗнч(Реквизит) = Тип("РеквизитФормы") Тогда Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Заголовок); ИначеЕсли ТипЗнч(Реквизит) = Тип("ОбъектМетаданных") Тогда Колонки.Добавить(Реквизит.Имя, Реквизит.Тип, Реквизит.Представление()); ИначеЕсли ТипЗнч(Реквизит) = Тип("ПолеНастройки") Тогда Колонки.Добавить(Реквизит.Имя, Реквизит.ТипЗначения, Реквизит.Представление); Иначе ВызватьИсключение "Неизвестный тип описания реквизита """ + ТипЗнч(Реквизит) + """"; КонецЕсли; КонецЦикла; Если ТипЗнч(Коллекция) = Тип("Структура") Тогда Для Каждого Колонка Из Колонки Цикл Коллекция.Вставить(Колонка.Имя, Колонка.ТипЗначения.ПривестиЗначение(Неопределено)); КонецЦикла; КонецЕсли; Возврат ИсходнаяКоллекция; КонецФункции Функция ПолучитьСписокБазПользователяОСЛкс(Знач ПолноеИмяФайла = Неопределено, ВычислятьРазмерыКаталогов = Ложь, ВычислятьПоследнегоПользователя = Ложь, ТаблицаПриемник = Неопределено) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если ТаблицаПриемник = Неопределено Тогда Результат = мПлатформа.СписокБазПользователя.ВыгрузитьКолонки(); Иначе Результат = ТаблицаПриемник; КонецЕсли; #Если Сервер И Не Сервер Тогда Результат = мПлатформа.СписокБазПользователя; #КонецЕсли Если ПолноеИмяФайла = Неопределено Тогда лПолноеИмяФайла = ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс(); Если ЗначениеЗаполнено(лПолноеИмяФайла) Тогда ПолучитьСписокБазПользователяОСЛкс(лПолноеИмяФайла,,, Результат); КонецЕсли; лПолноеИмяФайла = ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс(); Если ЗначениеЗаполнено(лПолноеИмяФайла) Тогда ПолучитьСписокБазПользователяОСЛкс(лПолноеИмяФайла,,, Результат); КонецЕсли; ПолноеИмяФайла = ИмяФайлаСпискаИнфобазПользователяОСЛкс(); КонецЕсли; Если ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Тогда КолонкаConnect = Неопределено; Иначе КолонкаConnect = Результат.Колонки.Connect; КонецЕсли; Файл = Новый Файл(ПолноеИмяФайла); ДобавленныеСтроки = Новый Массив; Если Файл.Существует() Тогда ЧтениеФайла = Новый ЧтениеТекста; Попытка ЧтениеФайла.Открыть(ПолноеИмяФайла, КодировкаТекста.UTF8); СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку(); Исключение // Файл существует, но недоступен http://www.hostedredmine.com/issues/882846 ОписаниеОшибки = ОписаниеОшибки(); // Для отладки СтрокаИзФайла = Неопределено; КонецПопытки; Пока СтрокаИзФайла <> Неопределено Цикл Если СтрДлина(СокрЛП(СтрокаИзФайла)) Тогда ТекущаяСтрока = СокрЛП(СтрокаИзФайла); Если Лев(ТекущаяСтрока, 1) = "[" Тогда НовоеНаименование = Сред(ТекущаяСтрока, 2, СтрДлина(ТекущаяСтрока) - 2); // Убираем квадратные скобки вначале и вконце Если КолонкаConnect = Неопределено Тогда НоваяСтрока = Результат.Найти(НРег(НовоеНаименование), "КлючСтроки"); Если НоваяСтрока <> Неопределено Тогда НоваяСтрока = Неопределено; СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку(); Продолжить; КонецЕсли; КонецЕсли; НоваяСтрока = Результат.Добавить(); НоваяСтрока.ФайлСписка = ПолноеИмяФайла; НоваяСтрока.Наименование = НовоеНаименование; ДобавленныеСтроки.Добавить(НоваяСтрока); КонецЕсли; ИмяКолонки = ПервыйФрагментЛкс(ТекущаяСтрока, "=", Ложь); Если НоваяСтрока <> Неопределено И ЗначениеЗаполнено(ИмяКолонки) Тогда Колонка = Результат.Колонки.Найти(ИмяКолонки); Если Колонка <> Неопределено Тогда ПредставлениеЗначения = Сред(ТекущаяСтрока, СтрДлина(ИмяКолонки + "=") + 1); ЗначениеПараметра = Колонка.ТипЗначения.ПривестиЗначение(ПредставлениеЗначения); НоваяСтрока[Колонка.Имя] = ЗначениеПараметра; Если Колонка = КолонкаConnect Тогда СуществующаяСтрока = Результат.Найти(НРег(ЗначениеПараметра), "КлючСтроки"); Если СуществующаяСтрока <> Неопределено Тогда Результат.Удалить(НоваяСтрока); ДобавленныеСтроки.Удалить(ДобавленныеСтроки.ВГраница()); НоваяСтрока = Неопределено; СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку(); Продолжить; КонецЕсли; КонецЕсли; Иначе Пустышка = 0; // Для отладки КонецЕсли; КонецЕсли; КонецЕсли; СтрокаИзФайла = ЧтениеФайла.ПрочитатьСтроку(); КонецЦикла; КонецЕсли; КаталогФайловыхКэшей = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(); КаталогНастроекИнфобаз = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(Ложь); Для Каждого СтрокаТЧ Из ДобавленныеСтроки Цикл СтрокаТЧ.КаталогКэша = КаталогФайловыхКэшей + "\" + СтрокаТЧ.ID; СтрокаТЧ.КаталогНастроек = КаталогНастроекИнфобаз + "\" + СтрокаТЧ.ID; Если ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Тогда СтрокаТЧ.КлючСтроки = НРег(СтрокаТЧ.Наименование); Иначе СтрокаТЧ.КлючСтроки = НРег(СтрокаТЧ.Connect); КонецЕсли; СтрокаТЧ.НСтрокаСоединения = НРег(СтрокаТЧ.Connect); СтрокаСоединенияКластера = НСтр(СтрокаТЧ.Connect, "Srvr"); //СтруктураURI = СтруктураURIЛкс(СтрокаСоединенияКластера); // Здесь может быть строка одновременно нескольких кластеров - tcp://rocket:1541,tcp://rocket1:1741 //СтрокаТЧ.ИмяКомпьютера = ПервыйФрагментЛкс(СтруктураURI.ИмяСервера, ":"); Если ВычислятьПоследнегоПользователя Тогда ИмяФайлаПоследнегоПользователя = СтрокаТЧ.КаталогНастроек + "\def.usr"; ФайлПоследнегоПользователя = Новый Файл(ИмяФайлаПоследнегоПользователя); Если ФайлПоследнегоПользователя.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлПоследнегоПользователя.ПолноеИмя); СтрокаТЧ.ПоследнийПользователь = СтрокаМеждуМаркерамиЛкс(ТекстовыйДокумент.ПолучитьТекст(), "{""", """}"); КонецЕсли; КонецЕсли; Если ВычислятьРазмерыКаталогов Тогда СтрокаТЧ.РазмерКэшаКБ = ВычислитьРазмерКаталогаЛкс(СтрокаТЧ.КаталогКэша) / 1024; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс() Экспорт Результат = ирКэш.НомерВерсииПлатформыЛкс() > 803000; Возврат Результат; КонецФункции Функция КлючБазыВСпискеПользователяЛкс(выхКлючомЯвляетсяСтрокаСоединения = Ложь) Экспорт выхКлючомЯвляетсяСтрокаСоединения = Не ЛиИдентификацияБазыВСпискеПоНаименованиюЛкс(); КлючБазыВСпискеПользователя = ирКэш.КлючБазыВСпискеПользователяИзКоманднойСтрокиЛкс(); Если Не ЗначениеЗаполнено(КлючБазыВСпискеПользователя) Тогда КлючБазыВСпискеПользователя = СтрокаСоединенияИнформационнойБазы(); выхКлючомЯвляетсяСтрокаСоединения = Истина; КонецЕсли; Возврат КлючБазыВСпискеПользователя; КонецФункции Функция ИмяФайлаОбщегоСпискаИнфобазТекущегоПользователяОСЛкс(ИмяКонфигФайла = "") Экспорт ShellApplication = Новый COMobject("Shell.Application"); ВсеЮзеры = ShellApplication.NameSpace(26).Self.Path; ИмяКонфигФайла = ВсеЮзеры + "\1C\1CEStart\1CEStart.cfg"; Текст = Новый ТекстовыйДокумент; Текст.Прочитать(ИмяКонфигФайла); СписокИмен = ""; Для Счетчик = 1 По СтрЧислоСтрок(Текст.ПолучитьТекст()) Цикл СтрокаТекста = СокрЛ(Текст.ПолучитьСтроку(Счетчик)); Если Найти(СтрокаТекста, "CommonInfoBases") = 1 Тогда Результат = Сред(СтрокаТекста, Найти(СтрокаТекста, "=") + 1); Прервать; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ИмяФайлаОбщегоСпискаИнфобазВсехПользователейОСЛкс(ИмяКонфигФайла = "") Экспорт ShellApplication = Новый COMobject("Shell.Application"); ВсеЮзеры = ShellApplication.NameSpace(35).Self.Path; ИмяКонфигФайла = ВсеЮзеры + "\1C\1CEStart\1CEStart.cfg"; Текст = Новый ТекстовыйДокумент; Текст.Прочитать(ИмяКонфигФайла); СписокИмен = ""; Для Счетчик = 1 По СтрЧислоСтрок(Текст.ПолучитьТекст()) Цикл СтрокаТекста = СокрЛ(Текст.ПолучитьСтроку(Счетчик)); Если Найти(СтрокаТекста, "CommonInfoBases") = 1 Тогда Результат = Сред(СтрокаТекста, Найти(СтрокаТекста, "=") + 1); Прервать; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр". // // Параметры: // Порядок – Порядок. // // Возвращаемое значение: // Строка - для установки порядка. // Функция ПолучитьСтрокуПорядкаЛкс(Порядок) Экспорт Строка = ""; Для Каждого ЭлементПорядка Из Порядок Цикл Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " "; Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда Строка = Строка + "возр"; Иначе Строка = Строка + "убыв"; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 2); КонецФункции // ПолучитьСтрокуПорядкаЛкс() // Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода. // Безопасность заключается в том, что нет свойств локального контекста // и недоступны доопределенные Свойства глобального контекста. // // Параметры: // ТекстДляВыполнения – Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Выполнить(ТекстДляВыполнения); КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс() // Получает копию произвольного объекта. Копирование производится через сериализацию. // // Параметры: // пОбъект – Произвольное – сохраняемое значение; // ИспользоватьXDTO - Булево - выполнять через ОбъектXDTO, для типов компоновки данных работает быстрее в 2 раза, но не у всех типов есть XDTO отображение, позволяет обходить платформенные ошибки десериализации компоновки // Истина - не делает глубокого копирования! Применять в основном имеет смысл только для объектов системы компоновки данных // // Возвращаемое значение: // Произвольный - копия объекта. // Функция КопияОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт Если ИспользоватьXDTO Тогда // Быстрее в 2 раза Попытка НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект)); Исключение // 7ы78аывраы0ав8 // https://partners.v8.1c.ru/forum/t/1918496/m/1918496 // Антибаг платформы 8.3.17-+ В настройках компоновки в элементах отбора с видом сравнения "ВСписке" в правых значениях поля компоновки при десериализации возникает ошибка. // Чтобы ее обойти оборачиваем каждое такое поле в массив СтрокаХмл = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(пОбъект); ДокументДом = ирОбщий.ПрочитатьТекстВДокументDOMЛкс(СтрокаХмл); #Если Сервер И Не Сервер Тогда ДокументДом = Новый ДокументDOM; #КонецЕсли РазыменовательПИ = Новый РазыменовательПространствИменDOM("w", "http://v8.1c.ru/8.1/data-composition-system/settings"); РезультатХПути = ДокументДом.ВычислитьВыражениеXPath("//w:comparisonType[text()='InList' or text()='NotInList']/following-sibling::w:right[@xsi:type='dcscor:Field']", ДокументДом, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов); Пока Истина Цикл УзелПравогоЗначенияОтбора = РезультатХПути.ПолучитьСледующий(); Если УзелПравогоЗначенияОтбора = Неопределено Тогда Прервать; КонецЕсли; ПрефиксЯдра = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://v8.1c.ru/8.1/data/core"); ПрефиксТипов = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://www.w3.org/2001/XMLSchema-instance"); ПрефиксКомпоновки = УзелПравогоЗначенияОтбора.НайтиПрефикс("http://v8.1c.ru/8.1/data-composition-system/core"); НовыйВложенныйУзел = ДокументДом.СоздатьЭлемент("http://v8.1c.ru/8.1/data/core", ПрефиксЯдра + ":Value"); НовыйВложенныйУзел.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", ПрефиксТипов + ":type", ПрефиксКомпоновки + ":Field"); НовыйВложенныйУзел.ТекстовоеСодержимое = УзелПравогоЗначенияОтбора.ПервыйДочерний.ТекстовоеСодержимое; УзелПравогоЗначенияОтбора.УдалитьДочерний(УзелПравогоЗначенияОтбора.ПервыйДочерний); УзелПравогоЗначенияОтбора.УдалитьУзелАтрибута(УзелПравогоЗначенияОтбора.Атрибуты[0]); УзелПравогоЗначенияОтбора.ДобавитьДочерний(НовыйВложенныйУзел); УзелПравогоЗначенияОтбора.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", ПрефиксТипов + ":type", ПрефиксЯдра + ":Array"); КонецЦикла; СтрокаХМЛ = ирОбщий.ЗаписатьДокументDOMВСтрокуЛкс(ДокументДом); НовыйОбъект = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаХМЛ); КонецПопытки; Иначе НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект)); КонецЕсли; Возврат НовыйОбъект; КонецФункции Процедура ВосстановитьОтборыКомпоновкиПослеДесериализацииЛкс(Знач НастройкаИлиГруппаОтбора) Экспорт Если ТипЗнч(НастройкаИлиГруппаОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда #Если Сервер И Не Сервер Тогда НастройкаИлиГруппаОтбора = Новый НастройкиКомпоновкиДанных; #КонецЕсли ГруппаОтбора = НастройкаИлиГруппаОтбора.Отбор; Иначе ГруппаОтбора = НастройкаИлиГруппаОтбора; КонецЕсли; #Если Сервер И Не Сервер Тогда ГруппаОтбора = Новый НастройкиКомпоновкиДанных; ГруппаОтбора = НастройкаИлиГруппаОтбора.Отбор; #КонецЕсли // https://partners.v8.1c.ru/forum/t/1623191/m/1623191 Для Каждого ЭлементОтбора Из ГруппаОтбора.Элементы Цикл Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда ВосстановитьОтборыКомпоновкиПослеДесериализацииЛкс(ЭлементОтбора); Продолжить; КонецЕсли; Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("Массив") Тогда МассивЗначенияОтбора = ЭлементОтбора.ПравоеЗначение; ИначеЕсли Истина И ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("СписокЗначений") И ЭлементОтбора.ПравоеЗначение.Количество() = 1 И ТипЗнч(ЭлементОтбора.ПравоеЗначение[0].Значение) = Тип("Массив") Тогда МассивЗначенияОтбора = ЭлементОтбора.ПравоеЗначение[0].Значение; Иначе МассивЗначенияОтбора = Неопределено; КонецЕсли; Если МассивЗначенияОтбора <> Неопределено Тогда СписокЗначений = Новый СписокЗначений; Для Каждого ЭлементМассива Из МассивЗначенияОтбора Цикл Если ТипЗнч(ЭлементМассива) = Тип("ПолеКомпоновкиДанных") Тогда // 7ы78аывраы0ав8 // https://partners.v8.1c.ru/forum/t/1918496/m/1918496 СписокЗначений = ЭлементМассива; Прервать; КонецЕсли; СписокЗначений.Добавить(ЭлементМассива); КонецЦикла; ЭлементОтбора.ПравоеЗначение = СписокЗначений; КонецЕсли; КонецЦикла; КонецПроцедуры // Находит элемент коллекции по свойству "ПутьКДанным". // // Параметры: // пКоллекция – Коллекция – все элементы которой имеют свойство "ПутьКДанным"; // пПутьКДанным – Строка – искомое значение. // // Возвращаемое значение: // – ЭлементКоллекции; // Неопределено - не найден. // Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт СуществующаяСтрока = Неопределено; Для Каждого ЭлементКоллеции Из пКоллекция Цикл Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда СуществующаяСтрока = ЭлементКоллеции; Прервать; КонецЕсли; КонецЦикла; Возврат СуществующаяСтрока; КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс() // Находит поле настройки по пути к данным. // // Параметры: // пПоляНастройки – ПоляНастройки; // пПутьКДанным – Строка – путь к данным поля в виде разыменовывания; // *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю. // // Возвращаемое значение: // ПолеНастройки – найденное поле; // Неопределено - иначе. // Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт ПоляНастройки = пПоляНастройки; МассивФрагментов = СтрРазделитьЛкс(пПутьКДанным); ТекущееПоле = Неопределено; Для Каждого Фрагмент Из МассивФрагментов Цикл пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент; ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю); Если ТекущееПоле = Неопределено Тогда Прервать; КонецЕсли; ПоляНастройки = ТекущееПоле.Поля; КонецЦикла; Возврат ТекущееПоле; КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс() // Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно. // // Параметры: // пЭлементОтбораПриемник – ЭлементОтбора – куда копируем; // пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем. // Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование"); МассивСвойствЭлементаОтбора = Новый Массив; МассивСвойствЭлементаОтбора.Добавить("ВидСравнения"); МассивСвойствЭлементаОтбора.Добавить("Значение"); МассивСвойствЭлементаОтбора.Добавить("ЗначениеС"); МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо"); Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл Значение = пЭлементОтбораИсточник[Свойство]; Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда пЭлементОтбораПриемник[Свойство] = Значение; КонецЕсли; КонецЦикла; КонецПроцедуры // СкопироватьЭлементОтбораЛкс() Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено, Знач ПроверятьДоступностьПолей = Ложь, Знач ДоступныеПоляОтбора = Неопределено, ТолькоИспользуемые = Истина, ОчищатьПриемник = Истина) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый НастройкиКомпоновкиДанных; ОтборКомпоновкиДанных = Пустышка.Отбор; #КонецЕсли Если СоответствиеИмен = Неопределено Тогда СоответствиеИмен = Новый ТаблицаЗначений(); СоответствиеИмен.Колонки.Добавить("Источник"); //СоответствиеИмен.Колонки.Добавить("Приемник"); КонецЕсли; Если ДоступныеПоляОтбора = Неопределено Тогда ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора; КонецЕсли; Если ОчищатьПриемник Тогда ОтборКомпоновкиДанных.Элементы.Очистить(); КонецЕсли; ИндексГраницы = ЭлементыОтбора.Количество() - 1; ИзмененныеЭлементыОтбора = Новый Массив; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл Если Истина И ТолькоИспользуемые И Не ЭлементОтбора.Использование Тогда Продолжить; КонецЕсли; Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда ПриемникОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных")); ЗаполнитьЗначенияСвойств(ПриемникОтбора, ЭлементОтбора); ТрансформироватьОтборВОтборКомпоновкиЛкс(ПриемникОтбора, ЭлементОтбора.Элементы, СоответствиеИмен, ПроверятьДоступностьПолей, ДоступныеПоляОтбора, ТолькоИспользуемые); Продолжить; КонецЕсли; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных") Тогда Продолжить; КонецЕсли; //ПутьКДаннымЛевый = Неопределено; //Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда ПутьКДаннымЛевый = "" + ЭлементОтбора.ЛевоеЗначение; //Иначе // ЛевоеЗначение = ЭлементОтбора.ЛевоеЗначение; //КонецЕсли; ПутьКДаннымПравый = Неопределено; Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда ПутьКДаннымПравый = "" + ЭлементОтбора.ПравоеЗначение; Иначе ПравоеЗначение = ЭлементОтбора.ПравоеЗначение; КонецЕсли; Иначе ПутьКДаннымЛевый = ЭлементОтбора.ПутьКДанным; ПутьКДаннымПравый = Неопределено; ПравоеЗначение = ЭлементОтбора.Значение; КонецЕсли; //Если ПутьКДаннымЛевый <> Неопределено Тогда МассивФрагментов = СтрРазделитьЛкс(ПутьКДаннымЛевый); СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник"); Если СтрокаИсточника <> Неопределено Тогда МассивФрагментов[0] = СтрокаИсточника.Приемник; КонецЕсли; ПутьКДанным = СтрСоединитьЛкс(МассивФрагментов, "."); Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда лВидСравнения = ЭлементОтбора.ВидСравнения; Иначе СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель"); Если СтрокаВидаСравнения = Неопределено Тогда Если ЭлементОтбора.ВидСравнения = ВидСравнения.Интервал Тогда НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.Больше,, Ложь, ЭлементОтбора.Использование); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.Меньше,, Ложь, ЭлементОтбора.Использование); ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы Тогда НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.БольшеИлиРавно,, Ложь, ЭлементОтбора.Использование); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.МеньшеИлиРавно,, Ложь, ЭлементОтбора.Использование); ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяНачало Тогда НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.БольшеИлиРавно,, Ложь, ЭлементОтбора.Использование); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.Меньше,, Ложь, ЭлементОтбора.Использование); ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяОкончание Тогда НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеС, ВидСравненияКомпоновкиДанных.Больше,, Ложь, ЭлементОтбора.Использование); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ОтборКомпоновкиДанных.Элементы, ПутьКДанным, ЭлементОтбора.ЗначениеПо, ВидСравненияКомпоновкиДанных.МеньшеИлиРавно,, Ложь, ЭлементОтбора.Использование); КонецЕсли; Продолжить; КонецЕсли; лВидСравнения = СтрокаВидаСравнения.Компоновка; КонецЕсли; ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным); ПолеОтбора = Неопределено; Для Каждого лЭлементОтбора Из ОтборКомпоновкиДанных.Элементы Цикл Если Истина И ТипЗнч(лЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") И лЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки И ИзмененныеЭлементыОтбора.Найти(лЭлементОтбора) = Неопределено Тогда ПолеОтбора = лЭлементОтбора; ИзмененныеЭлементыОтбора.Добавить(ПолеОтбора); Прервать; КонецЕсли; КонецЦикла; Если ПолеОтбора = Неопределено Тогда ДоступноеПоле = ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки); Если Истина И ПроверятьДоступностьПолей И ДоступноеПоле = Неопределено Тогда Продолжить; КонецЕсли; ПолеОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ПолеОтбора.ЛевоеЗначение = ПолеКомпоновки; КонецЕсли; //Иначе // ПолеОтбора.ПравоеЗначение = ЛевоеЗначение; //КонецЕсли; Если ПутьКДаннымПравый <> Неопределено Тогда МассивФрагментов = СтрРазделитьЛкс(ПутьКДаннымПравый); СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник"); Если СтрокаИсточника <> Неопределено Тогда МассивФрагментов[0] = СтрокаИсточника.Приемник; КонецЕсли; ПутьКДанным = СтрСоединитьЛкс(МассивФрагментов, "."); ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным); ПолеОтбора.ПравоеЗначение = ПолеКомпоновки; Иначе ПолеОтбора.ПравоеЗначение = ПравоеЗначение; КонецЕсли; ПолеОтбора.ВидСравнения = лВидСравнения; ПолеОтбора.Использование = ЭлементОтбора.Использование; КонецЦикла; КонецФункции // Порт СкопироватьОтборЛкс. Процедура СкопироватьОтборЛюбойЛкс(пОтборПриемник, пОтборИсточник, ТолькоИспользуемые = Ложь, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт Если Истина И ТипЗнч(пОтборИсточник) = Тип("Отбор") И ТипЗнч(пОтборПриемник) = Тип("Отбор") Тогда СкопироватьОтборПостроителяЛкс(пОтборПриемник, пОтборИсточник, , ТолькоИспользуемые, ОчищатьПриемник); ИначеЕсли Истина И ТипЗнч(пОтборИсточник) = Тип("Структура") И ТипЗнч(пОтборПриемник) = Тип("Отбор") Тогда Для Каждого КлючИЗначение Из пОтборИсточник Цикл ЭлементОтбора = пОтборПриемник.Найти(КлючИЗначение.Ключ); Если ЭлементОтбора <> Неопределено Тогда УстановитьЭлементОтбораЛкс(ЭлементОтбора,, КлючИЗначение.Значение); КонецЕсли; КонецЦикла; ИначеЕсли Истина И ТипЗнч(пОтборИсточник) = Тип("ОтборКомпоновкиДанных") И ТипЗнч(пОтборПриемник) = Тип("ОтборКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(пОтборПриемник, пОтборИсточник, ПроверятьДоступность, ОчищатьПриемник); ИначеЕсли Истина И ТипЗнч(пОтборИсточник) = Тип("Структура") И ТипЗнч(пОтборПриемник) = Тип("ОтборКомпоновкиДанных") Тогда Для Каждого КлючИЗначение Из пОтборИсточник Цикл ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(пОтборПриемник, КлючИЗначение.Ключ, КлючИЗначение.Значение); #Если Сервер И Не Сервер Тогда ЭлементОтбора = Новый НастройкиКомпоновкиДанных; ЭлементОтбора = ЭлементОтбора.Отбор.Элементы.Добавить(); #КонецЕсли ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора); КонецЦикла; ИначеЕсли Истина И ТипЗнч(пОтборИсточник) = Тип("Отбор") И ТипЗнч(пОтборПриемник) = Тип("ОтборКомпоновкиДанных") Тогда ТрансформироватьОтборВОтборКомпоновкиЛкс(пОтборПриемник, пОтборИсточник,, ПроверятьДоступность,, ТолькоИспользуемые, ОчищатьПриемник); КонецЕсли; КонецПроцедуры // СкопироватьОтборДинамическогоСпискаЛкс() // Важно: установка идентификатора должна выполняться в конце настройки элемента, // иначе он будет скопирован в пользовательские настройки частично заполненным. Процедура ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементНастроек, ИД = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый НастройкиКомпоновкиДанных; ЭлементНастроек = Пустышка.Отбор; #КонецЕсли Представление = "" + ЭлементНастроек; Если ТипЗнч(ЭлементНастроек) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда Если ЗначениеЗаполнено(ЭлементНастроек.Представление) Тогда Представление = ЭлементНастроек.Представление; Иначе Представление = ЭлементНастроек.ЛевоеЗначение; КонецЕсли; КонецЕсли; Попытка ЭлементНастроек.ПредставлениеПользовательскойНастройки = Представление; Исключение // Это ОтборКомпоновкиДанных внутри пользовательских настроек КонецПопытки; Если ЗначениеЗаполнено(ИД) Тогда УИД = Новый УникальныйИдентификатор(ИД); Иначе УИД = Новый УникальныйИдентификатор; КонецЕсли; ЭлементНастроек.ИдентификаторПользовательскойНастройки = УИД; КонецПроцедуры // Копирует элементы из одной коллекции в другую // Процедура СкопироватьЭлементыКомпоновкиЛкс(ПриемникЗначения, ИсточникЗначения, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт Если Ложь Или ТипЗнч(ИсточникЗначения) = Тип("УсловноеОформлениеКомпоновкиДанных") ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ВариантыПользовательскогоПоляВыборКомпоновкиДанных") ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ОформляемыеПоляКомпоновкиДанных") ИЛИ ТипЗнч(ИсточникЗначения) = Тип("ЗначенияПараметровДанныхКомпоновкиДанных") Тогда СоздаватьПоТипу = Ложь; Иначе СоздаватьПоТипу = Истина; КонецЕсли; ПриемникЭлементов = ПриемникЗначения.Элементы; ИсточникЭлементов = ИсточникЗначения.Элементы; Если ОчищатьПриемник Тогда ПриемникЭлементов.Очистить(); КонецЕсли; Для каждого ЭлементИсточник Из ИсточникЭлементов Цикл Если ТипЗнч(ЭлементИсточник) = Тип("ЭлементПорядкаКомпоновкиДанных") Тогда // Элементы порядка добавляем в начало Индекс = ИсточникЭлементов.Индекс(ЭлементИсточник); ЭлементПриемник = ПриемникЭлементов.Вставить(Индекс, ТипЗнч(ЭлементИсточник)); Иначе Если СоздаватьПоТипу Тогда ЭлементПриемник = ПриемникЭлементов.Добавить(ТипЗнч(ЭлементИсточник)); Иначе ЭлементПриемник = ПриемникЭлементов.Добавить(); КонецЕсли; КонецЕсли; ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник); // В некоторых коллекциях необходимо заполнить другие коллекции Если ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Поля, ЭлементИсточник.Поля); СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор); ЗаполнитьЭлементыКомпоновкиЛкс(ЭлементПриемник.Оформление, ЭлементИсточник.Оформление); ИначеЕсли ТипЗнч(ИсточникЭлементов) = Тип("КоллекцияВариантовПользовательскогоПоляВыборКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Отбор, ЭлементИсточник.Отбор); КонецЕсли; // В некоторых элементах коллекции необходимо заполнить другие коллекции Если ТипЗнч(ЭлементИсточник) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник, ЭлементИсточник); ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник, ЭлементИсточник); ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыборКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(ЭлементПриемник.Варианты, ЭлементИсточник.Варианты); ИначеЕсли ТипЗнч(ЭлементИсточник) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда ЭлементПриемник.УстановитьВыражениеДетальныхЗаписей (ЭлементИсточник.ПолучитьВыражениеДетальныхЗаписей()); ЭлементПриемник.УстановитьВыражениеИтоговыхЗаписей(ЭлементИсточник.ПолучитьВыражениеИтоговыхЗаписей()); ЭлементПриемник.УстановитьПредставлениеВыраженияДетальныхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияДетальныхЗаписей ()); ЭлементПриемник.УстановитьПредставлениеВыраженияИтоговыхЗаписей(ЭлементИсточник.ПолучитьПредставлениеВыраженияИтоговыхЗаписей ()); КонецЕсли; КонецЦикла; КонецПроцедуры // Заполняет элементы одной коллекции из другой // Процедура ЗаполнитьЭлементыКомпоновкиЛкс(ПриемникЗначения, ИсточникЗначения, ПервыйУровень = Неопределено) Экспорт Если ТипЗнч(ПриемникЗначения) = Тип("КоллекцияЗначенийПараметровКомпоновкиДанных") Тогда КоллекцияЗначений = ИсточникЗначения; Иначе КоллекцияЗначений = ИсточникЗначения.Элементы; КонецЕсли; Для каждого ЭлементИсточник Из КоллекцияЗначений Цикл Если ПервыйУровень = Неопределено Тогда ЭлементПриемник = ПриемникЗначения.НайтиЗначениеПараметра(ЭлементИсточник.Параметр); Иначе ЭлементПриемник = ПервыйУровень.НайтиЗначениеПараметра(ЭлементИсточник.Параметр); КонецЕсли; Если ЭлементПриемник = Неопределено Тогда Продолжить; КонецЕсли; ЗаполнитьЗначенияСвойств(ЭлементПриемник, ЭлементИсточник); Если ТипЗнч(ЭлементИсточник) = Тип("ЗначениеПараметраКомпоновкиДанных") Тогда Если ЭлементИсточник.ЗначенияВложенныхПараметров.Количество() <> 0 Тогда ЗаполнитьЭлементыКомпоновкиЛкс(ЭлементПриемник.ЗначенияВложенныхПараметров, ЭлементИсточник.ЗначенияВложенныхПараметров, ПриемникЗначения); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // Копирует объект Отбор в другой объект Отбор. // Если нужно, в приемнике создаются отсутствующие элементы отбора. // // Параметры: // пОтборПриемник – Отбор – куда копируем; // пОтборИсточник - Отбор, Структура - откуда копируем; // пСоздаватьОтсутствующие - Булево, *Ложь - признак создания отсутствующих элементов отбора в приемнике. // Процедура СкопироватьОтборПостроителяЛкс(ОтборПриемник, ОтборИсточник, СоздаватьОтсутствующие = Истина, ТолькоИспользуемые = Ложь, ОчищатьПриемник = Ложь) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый ПостроительЗапроса; ОтборПриемник = Пустышка.Отбор; #КонецЕсли Если ОчищатьПриемник Тогда ОтборПриемник.Сбросить(); КонецЕсли; //Если пСоздаватьОтсутствующие Тогда // ДоступныеПоля = пОтборПриемник.ПолучитьДоступныеПоля(); //КонецЕсли; Для Каждого ЭлементОтбораИсточника Из ОтборИсточник Цикл Если Истина И ТолькоИспользуемые И Не ЭлементОтбораИсточника.Использование Тогда Продолжить; КонецЕсли; Если ТипЗнч(ЭлементОтбораИсточника) = Тип("КлючИЗначение") Тогда ЭлементОтбораИсточника = ЭлементОтбораИсточника.Значение; КонецЕсли; //Если ЭлементОтбораИсточника.Имя = "" Тогда // СообщитьЛкс("Невозможно определить элемент отбора приемника при копировании отбора.", // СтатусСообщения.Внимание); // Продолжить; //КонецЕсли; ЭлементОтбораПриемника = ОтборПриемник.Найти(ЭлементОтбораИсточника.Имя); Если ЭлементОтбораПриемника = Неопределено Тогда Если Истина И СоздаватьОтсутствующие //И НайтиПолеНастройкиПоПутиКДаннымЛкс(ДоступныеПоля, ЭлементОтбораИсточника.ПутьКДанным) <> Неопределено Тогда Попытка ЭлементОтбораПриемника = ОтборПриемник.Добавить(ЭлементОтбораИсточника.ПутьКДанным, ЭлементОтбораИсточника.Имя); Исключение Продолжить; КонецПопытки; Иначе Продолжить; КонецЕсли; КонецЕсли; СкопироватьЭлементОтбораЛкс(ЭлементОтбораПриемника, ЭлементОтбораИсточника); КонецЦикла; КонецПроцедуры // Получает инвертированный вид сравнения. // // Параметры: // ВидСравнения – ВидСравнения. // // Возвращаемое значение: // ВидСравнения; // Функция ПолучитьИнвертированныйВидСравненияЛкс(ВидСравненияП) Экспорт МассивИнвертируемыхТиповСравнения = Новый Массив; МассивИнвертируемыхТиповСравнения.Добавить("ВИерархии"); МассивИнвертируемыхТиповСравнения.Добавить("ВСписке"); МассивИнвертируемыхТиповСравнения.Добавить("Равно"); МассивИнвертируемыхТиповСравнения.Добавить("Содержит"); МассивИнвертируемыхТиповСравнения.Добавить("ВСпискеПоИерархии"); Для Каждого ТипСравнения Из МассивИнвертируемыхТиповСравнения Цикл ПрямойТипСравнения = Вычислить("ВидСравнения." + ТипСравнения); Если ПрямойТипСравнения = ВидСравненияП Тогда Возврат Вычислить("ВидСравнения.Не" + ТипСравнения); КонецЕсли; ОбратныйТипСравнения = Вычислить("ВидСравнения.Не" + ТипСравнения); Если ОбратныйТипСравнения = ВидСравненияП Тогда Возврат Вычислить("ВидСравнения." + ТипСравнения); КонецЕсли; КонецЦикла; Возврат ВидСравненияП; КонецФункции // ПолучитьИнвертированныйВидСравненияЛкс() // Копирует один порядок в другой. Приемник перед копированием очищается. // // Параметры: // пПорядокПриемник – Порядок – куда копируем; // пПорядокИсточник - Порядок - откуда копируем. // Процедура СкопироватьПорядокПостроителяЛкс(пПорядокПриемник, пПорядокИсточник) Экспорт пПорядокПриемник.Очистить(); Для Каждого ЭлементПорядка Из пПорядокИсточник Цикл пПорядокПриемник.Добавить(ЭлементПорядка.ПутьКДанным, ЭлементПорядка.Имя, , ЭлементПорядка.Направление); КонецЦикла; КонецПроцедуры // СкопироватьПорядокЛкс() // Трансформирует порядок в порядок компоновки. // // Параметры: // ПорядокКомпоновки – ПорядокКомпоновкиДанных; // Порядок - Порядок. // Процедура ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокКомпоновки, Порядок) Экспорт ЭлементыКомпоновки = ПорядокКомпоновки.Элементы; ЭлементыКомпоновки.Очистить(); Для Каждого Элемент Из Порядок Цикл ЭлементКомпоновки = ЭлементыКомпоновки.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных")); ЭлементКомпоновки.Использование = Истина; ЭлементКомпоновки.Поле = Новый ПолеКомпоновкиДанных(Элемент.ПутьКДанным); Если Элемент.Направление = НаправлениеСортировки.Возр Тогда ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр; Иначе//Если Элемент.Направление = НаправлениеСортировки.Убыв Тогда ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв; КонецЕсли; КонецЦикла; КонецПроцедуры // ТрансформироватьПорядокВПорядокКомпоновкиЛкс() Процедура СкопироватьПорядокЛюбойЛкс(ПорядокПриемник, ПорядокИсточник, ТолькоИспользуемые = Ложь, ПроверятьДоступность = Ложь, ОчищатьПриемник = Истина) Экспорт Если Истина И ТипЗнч(ПорядокИсточник) = Тип("Порядок") И ТипЗнч(ПорядокПриемник) = Тип("Порядок") Тогда СкопироватьПорядокПостроителяЛкс(ПорядокПриемник, ПорядокИсточник); ИначеЕсли Истина И ТипЗнч(ПорядокИсточник) = Тип("ПорядокКомпоновкиДанных") И ТипЗнч(ПорядокПриемник) = Тип("ПорядокКомпоновкиДанных") Тогда СкопироватьЭлементыКомпоновкиЛкс(ПорядокПриемник, ПорядокИсточник,, ОчищатьПриемник); ИначеЕсли Истина И ТипЗнч(ПорядокИсточник) = Тип("Порядок") И ТипЗнч(ПорядокПриемник) = Тип("ПорядокКомпоновкиДанных") Тогда ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокПриемник, ПорядокИсточник); КонецЕсли; КонецПроцедуры // СкопироватьПорядокЛкс() // Возвращает текущее время в миллисекундах. // // Параметры: // Нет. // // Возвращаемое значение: // Число. // Функция ТекущееВремяВМиллисекундахЛкс() Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Результат = мПлатформа.ПолучитьТекущееВремяВМиллисекундах(); Возврат Результат; КонецФункции // Выполняет запрос. Опционально сообщает его текст и время выполнения. // Удобно для оптимизации. // // Параметры: // Запрос – Запрос; // *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения. // *Заголовок - Строка, *"" - название запроса. // // Возвращаемое значение: // РезультатЗапроса. // Функция ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка = Ложь, Заголовок = "") Экспорт Если ЛиОтладка Тогда ВремяНачала = ТекущееВремяВМиллисекундахЛкс(); КонецЕсли; Результат = Запрос.Выполнить(); Если ЛиОтладка Тогда Текст = Новый ТекстовыйДокумент; Текст.УстановитьТекст(Запрос.Текст); Текст.Показать(Заголовок + " - " + Строка(ТекущееВремяВМиллисекундахЛкс() - ВремяНачала) + " мс"); КонецЕсли; Возврат Результат; КонецФункции // ВыполнитьЗамеритьЗапросЛкс() // Получает константу языка запросов заданного типа с учетом квалификаторов описания типов. // // Параметры: // ТипПоля – Тип; // ОписаниеТипов - ОписаниеТипов - для обращения к квалифицаторам. // // Возвращаемое значение: // Строка. // Функция ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, ОписаниеТипов = Неопределено) Экспорт Если ТипПоля = Тип("Строка") Тогда Результат = "ВЫРАЗИТЬ("""" КАК СТРОКА(" + Формат(ОписаниеТипов.КвалификаторыСтроки.Длина, "ЧН=; ЧГ=") + "))"; ИначеЕсли ТипПоля = Тип("Число") Тогда Результат = "ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Формат(ОписаниеТипов.КвалификаторыЧисла.Разрядность, "ЧН=; ЧГ=") + ", " + Формат(ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти, "ЧН=; ЧГ=") + "))"; ИначеЕсли ТипПоля = Тип("Дата") Тогда Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда Результат = "ДАТАВРЕМЯ(1,1,1)"; Иначе Результат = "ДАТАВРЕМЯ(1,1,1,0,0,0)"; КонецЕсли; ИначеЕсли ТипПоля = Тип("Булево") Тогда Результат = "ЛОЖЬ"; ИначеЕсли ТипПоля = Тип("NULL") Тогда Результат = "NULL"; ИначеЕсли ТипПоля = Тип("НЕОПРЕДЕЛЕНО") Тогда Результат = "НЕОПРЕДЕЛЕНО"; ИначеЕсли ТипПоля = Тип("ВидДвиженияНакопления") Тогда Результат = "ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)"; ИначеЕсли ТипПоля = Тип("ВидДвиженияБухгалтерии") Тогда Результат = "ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)"; ИначеЕсли ТипПоля = Тип("ВидСчета") Тогда Результат = "ЗНАЧЕНИЕ(ВидСчета.Активный)"; Иначе МетаданныеТипаПоля = Метаданные.НайтиПоТипу(ТипПоля); Если МетаданныеТипаПоля <> Неопределено Тогда // Антибаг платформы 8.1.10.50 Если ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеТипаПоля) = "ПланОбмена" Тогда Результат = "НЕОПРЕДЕЛЕНО"; Возврат Результат; КонецЕсли; Результат = "ЗНАЧЕНИЕ(" + МетаданныеТипаПоля.ПолноеИмя() + ".ПустаяСсылка)"; Иначе //СообщитьЛкс("Неизвестный тип поля при формировании имитатора результата: " + ТипПоля, СтатусСообщения.Важное); Результат = "NULL"; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьКонстантуТипаЗапроса() // Возвращает текст запроса только из констант, дающий идентичный переданному набор колонок. // // Параметры: // КоллекцияПолей – КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокДереваЗначений, КоллекцияКолонокРезультатаЗапроса. // // Возвращаемое значение: // Текст. // Функция ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей) Экспорт // Формирование запроса-имитатора ОписаниеПолей = ""; Для Каждого Колонка Из КоллекцияПолей Цикл ОписаниеПолей = ОписаниеПолей + ", "; МассивТипов = Колонка.ТипЗначения.Типы(); НачальноеКоличество = МассивТипов.Количество(); Для СчетчикМассивТипов = 1 По НачальноеКоличество Цикл ТипПоля = МассивТипов[НачальноеКоличество - СчетчикМассивТипов]; Если ТипПоля = Тип("NULL") Тогда МассивТипов.Удалить(НачальноеКоличество - СчетчикМассивТипов); КонецЕсли; КонецЦикла; // Этот стиль строго фиксирован и0ие90цаун787 ОписаниеПолей = ОписаниеПолей + "ВЫБОР"; ЭтоПервыйТип = Истина; Для Каждого ТипПоля Из МассивТипов Цикл Если ЭтоПервыйТип Тогда УсловиеТипа = " КОГДА ""!ИмяПоля!""=""" + Колонка.Имя + """"; ЭтоПервыйТип = Ложь; Иначе УсловиеТипа = " КОГДА ЛОЖЬ"; КонецЕсли; ОписаниеПолей = ОписаниеПолей + УсловиеТипа + " ТОГДА " + ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, Колонка.ТипЗначения); КонецЦикла; ОписаниеПолей = ОписаниеПолей + " КОНЕЦ КАК " + Колонка.Имя; // запрещенные имена например "Соединение" так вызывают ошибку? КонецЦикла; Результат = "ВЫБРАТЬ " + Сред(ОписаниеПолей, 3); Возврат Результат; КонецФункции // Присваивает первому параметру второй в случае их неравенства. // Удобно использовать для избежания установки признака модифицированности // объекта в случае присвоения реквизиту объекта его же значения. // // Параметры: // Переменная – Произвольный – переменная, которой нужно присвоить значение; // Значение – Произвольный – присваиваемое значение; // // Возвращаемое значение: // Переменная – Произвольный - конечное значение переменной. // Функция ПрисвоитьЕслиНеРавноЛкс(Переменная, Значение, выхМодифицированность = Неопределено) Экспорт Если Переменная <> Значение Тогда Переменная = Значение; выхМодифицированность = Истина; КонецЕсли; Возврат Переменная; КонецФункции // Получает индекс картинки отражающей корневой тип и статус ссылки. // Индекс потом используется с общей картинкой ЛксСостояниеСсылки. // // Параметры: // пСсылка – Ссылка – целевая; // *пЛиОпределятьСтатусСсылки - Булево, *Неопределено - признак необходимости определения статуса. // // Возвращаемое значение: // – Число – индекс картинки. // Функция ПолучитьИндексКартинкиСсылкиЛкс(Ссылка, ЛиОпределятьСтатусСсылки = Неопределено, ЗначенияРеквизитов = Неопределено) Экспорт Если ЛиОпределятьСтатусСсылки = Неопределено Тогда //пЛиОпределятьСтатусСсылки = ПараметрыСеанса.ЛксОпределятьСтатусСсылкиПриВыводе; ЛиОпределятьСтатусСсылки = Ложь; КонецЕсли; Если ЗначенияРеквизитов = Неопределено Тогда ЗначенияРеквизитов = Ссылка; КонецЕсли; КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Ссылка); ИндексКартинки = -1; Если КорневойТип = "Документ" Тогда ИндексКартинки = 0; Если ЛиОпределятьСтатусСсылки Тогда Попытка Проведен = ЗначенияРеквизитов.Проведен; Исключение Проведен = Ложь; КонецПопытки; Попытка ПометкаУдаления = ЗначенияРеквизитов.ПометкаУдаления; Исключение ПометкаУдаления = Ложь; КонецПопытки; Если Проведен = Истина Тогда ИндексКартинки = 0; ИначеЕсли ПометкаУдаления = Истина Тогда ИндексКартинки = 1; Иначе ИндексКартинки = 2; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "Справочник" Тогда ИндексКартинки = 3; Если ЛиОпределятьСтатусСсылки Тогда Попытка ЭтоГруппа = ЗначенияРеквизитов.ЭтоГруппа; Исключение ЭтоГруппа = Ложь; КонецПопытки; Если ЗначенияРеквизитов.ПометкаУдаления Тогда ИндексКартинки = ?(ЭтоГруппа = Истина, 6, 4); Иначе ИндексКартинки = ?(ЭтоГруппа = Истина, 5, 3); КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "Задача" Тогда ИндексКартинки = 7; Если ЛиОпределятьСтатусСсылки Тогда Если ЗначенияРеквизитов.ПометкаУдаления Тогда ИндексКартинки = 8; Иначе ИндексКартинки = 7; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда ИндексКартинки = 9; Если ЛиОпределятьСтатусСсылки Тогда Если ЗначенияРеквизитов.ПометкаУдаления Тогда ИндексКартинки = 10; Иначе ИндексКартинки = 9; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "ПланОбмена" Тогда ИндексКартинки = 15; Если ЛиОпределятьСтатусСсылки Тогда Если ЗначенияРеквизитов.ПометкаУдаления Тогда ИндексКартинки = 16; Иначе ИндексКартинки = 15; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда ИндексКартинки = 19; //Если пЛиОпределятьСтатусСсылки Тогда // Если ЗначенияРеквизитов.ПометкаУдаления Тогда // ИндексКартинки = 20; // Иначе // ИндексКартинки = 19; // КонецЕсли; //КонецЕсли; ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда ИндексКартинки = 17; Если ЛиОпределятьСтатусСсылки Тогда Если ЗначенияРеквизитов.ПометкаУдаления Тогда ИндексКартинки = 18; Иначе ИндексКартинки = 17; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "Перечисление" Тогда ИндексКартинки = 11; ИначеЕсли КорневойТип = "РегистрСведений" Тогда ИндексКартинки = 12; ИначеЕсли КорневойТип = "Константа" Тогда ИндексКартинки = 14; КонецЕсли; Возврат ИндексКартинки; КонецФункции // ПолучитьИндексКартинкиСсылкиЛкс() // Добавляет в таблицу значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт Если ТаблицаИсточник = ТаблицаПриемник Тогда ВызватьИсключение "Нельзя загружать коллекцию в саму себя"; КонецЕсли; СтрокаСовпадающихКолонок = ""; Разделитель = ","; Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда КолонкиИсточника = ТаблицаИсточник.Колонки; Иначе КолонкиИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаИсточник)).Реквизиты; КонецЕсли; ЛиПриемникТЧ = ТипЗнч(ТаблицаПриемник) <> Тип("ТаблицаЗначений"); Если ЛиПриемникТЧ Тогда КолонкиПриемника = ТаблицаПриемник.ВыгрузитьКолонки().Колонки; Иначе КолонкиПриемника = ТаблицаПриемник.Колонки; КонецЕсли; ИмяПоляНомерСтроки = ПеревестиСтроку("НомерСтроки"); // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для каждого Колонка Из КолонкиПриемника Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если Истина И (Ложь Или Не ЛиПриемникТЧ Или Колонка.Имя <> ИмяПоляНомерСтроки) И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для каждого Колонка Из КолонкиПриемника Цикл   Если СтруктураНовыхЗначений <> Неопределено Тогда   Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда   Продолжить;   КонецЕсли;   КонецЕсли;   Если Истина   И (Ложь   Или Не ЛиПриемникТЧ   Или Колонка.Имя <> ИмяПоляНомерСтроки)   И КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено   Тогда   СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя;   КонецЕсли;   КонецЦикла;   СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок); //Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл // СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива]; //КонецЦикла; Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений); КонецЕсли; КонецЦикла; КонецПроцедуры // ЗагрузитьВТаблицуЗначенийЛкс() // Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВДеревоЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ДеревоИсточник = Новый ДеревоЗначений; ДеревоПриемник = Новый ДеревоЗначений; #КонецЕсли СтрокаСовпадающихКолонок = ""; Разделитель = ","; КолонкиИсточника = ДеревоИсточник.Колонки; Для каждого Колонка Из ДеревоПриемник.Колонки Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); ЗагрузитьВСтрокиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок); КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс() // Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаРодительИсточника, СтрокаРодительПриемника, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт СтрокиПриемника = СтрокаРодительПриемника.Строки; Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл СтрокаПриемника = СтрокиПриемника.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок); Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений); КонецЕсли; ЗагрузитьВСтрокиДереваЗначенийЛкс(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок); КонецЦикла; КонецПроцедуры // ЗагрузитьВДеревоЗначенийЛкс() // Выводит сообщение пользователю. Способ вывода определяется модальным режимом. // В модальном режиме используется Предупреждение(), в немодальном СообщитьЛкс(). // // Параметры: // ТекстСообщения – Строка; // МодальныйРежим – Булево, *Ложь; // *Статус - СтатусСообщения, *Неопределено. // Процедура СообщитьСУчетомМодальностиЛкс(ТекстСообщения, МодальныйРежим = Ложь, Статус = Неопределено) Экспорт Если Статус = Неопределено Тогда Статус = СтатусСообщения.Обычное; КонецЕсли;; #Если Клиент Тогда Если МодальныйРежим Тогда Предупреждение(ТекстСообщения); Иначе #КонецЕсли СообщитьЛкс(ТекстСообщения, Статус); #Если Клиент Тогда КонецЕсли; #КонецЕсли КонецПроцедуры // СообщитьСУчетомМодальностиЛкс() // Сообщает итог индикации (длительность). // // Параметры: // Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс. // Процедура СообщитьИтогИндикацииЛкс(Индикатор) Экспорт ТекущаяДата = ТекущаяДата(); ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса; //Часов = Цел(ПрошлоВремени / 3600); //Осталось = ПрошлоВремени - (Часов * 3600); //Минут = Цел(ПрошлоВремени / 60); //Секунд = Цел(Цел(ПрошлоВремени - (Минут * 60))); //ПрошлоВремениСтрока = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":" // + Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":" // + Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН="); ПрошлоВремениСтрока = формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП="); ТекстСообщения = Индикатор.ПредставлениеПроцесса + " завершено, обработано " + Индикатор.Счетчик + " элементов за " + ПрошлоВремениСтрока + " (" + ПрошлоВремени + " сек)."; Если Индикатор.Счетчик > 0 Тогда ТекстСообщения = ТекстСообщения + " Грубое среднее время обработки элемента - " + Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН=") + " мс"; КонецЕсли; СообщитьЛкс(ТекстСообщения); КонецПроцедуры // ОбработатьИндикаторЛкс() // Получает более подробное представление значения, чем штатное приведение к строковому типу. // // Параметры: // Значение – Произвольный – что нужно представить. // // Возвращаемое значение: // Строка – представление. // Функция РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля = Неопределено, ДобавлятьПредставлениеТипа = Ложь, РасширенноеПредставлениеХранилищЗначений = Ложь, ВозвращатьПредставлениеСсылки = Истина) Экспорт Результат = ""; Разделитель = ", "; КоличествоЭлементов = ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение); Если КоличествоЭлементов <> Неопределено Тогда Результат = "(" + КоличествоЭлементов + ")"; КонецЕсли; Если ТипЗнч(Значение) = Тип("Граница") Тогда Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение; ИначеЕсли ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Значение)) Тогда Результат = "" + Значение; Если Не ЗначениеЗаполнено(Результат) Тогда Результат = "(" + Значение.Имя + ")"; КонецЕсли; ИначеЕсли ТипЗнч(Значение) = Тип("ОписаниеТипов") Тогда #Если Сервер И Не Сервер Тогда Значение = Новый ОписаниеТипов; #КонецЕсли ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 20; Коллекция = Значение.Типы(); Для Каждого Тип Из Коллекция Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + ПредставлениеТипаЛкс(Тип, Значение); МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "..."; Прервать; КонецЕсли; КонецЦикла; Если Коллекция.Количество() > 1 Тогда Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")"; Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; КонецЕсли; Результат = Результат + ПредставлениеКоллекции; ИначеЕсли Ложь Или ТипЗнч(Значение) = Тип("Массив") Или ТипЗнч(Значение) = Тип("ФиксированныйМассив") Или ТипЗнч(Значение) = Тип("СписокЗначений") Тогда ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 20; НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс(); Для Каждого ЭлементМассива Из Значение Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель; КонецЕсли; Если Истина И НомерВерсииПлатформы >= 803006 И ТипЗнч(ЭлементМассива) = Тип("РасширениеКонфигурации") Тогда // http://www.hostedredmine.com/issues/881633 ПредставлениеЭлемента = "" + ТипЗнч(ЭлементМассива); Иначе ПредставлениеЭлемента = "" + ЭлементМассива; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + ПредставлениеЭлемента; МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "..."; Прервать; КонецЕсли; КонецЦикла; Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; Результат = Результат + ПредставлениеКоллекции; ИначеЕсли ТипЗнч(Значение) = Тип("ТабличныйДокумент") Тогда #Если Сервер И Не Сервер Тогда Значение = Новый ТабличныйДокумент; #КонецЕсли Результат = "" + ТипЗнч(Значение) + "(" + Значение.ВысотаТаблицы + ")"; ИначеЕсли Ложь Или ТипЗнч(Значение) = Тип("Структура") Или ТипЗнч(Значение) = Тип("Соответствие") Тогда ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 20; Для Каждого КлючИЗначение Из Значение Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение; МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "..."; Прервать; КонецЕсли; КонецЦикла; Если ДобавлятьПредставлениеТипа Тогда Результат = Результат + ТипЗнч(Значение); КонецЕсли; Если ЗначениеЗаполнено(Результат) Тогда Результат = Результат + ": "; КонецЕсли; Результат = Результат + ПредставлениеКоллекции; ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда ирПлатформа = ирКэш.Получить(); ИмяОбщегоТипа = ирПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(Значение); ПолноеИмяОсновногоКласса = СтрокаМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь); ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", ""); Результат = Результат + ИмяОбщегоТипа; ИначеЕсли Истина И РасширенноеПредставлениеХранилищЗначений И ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда Результат = Результат + ТипЗнч(Значение); ВложенноеЗначение = Значение.Получить(); Результат = Результат + ": " + ВложенноеЗначение; ИначеЕсли ТипЗнч(Значение) = Тип("Файл") Тогда Результат = Результат + ТипЗнч(Значение); Результат = Результат + ": " + Значение.ПолноеИмя; //ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда // Результат = Результат + """" + Значение + """"; Иначе СтрокаФормата = ""; Если КолонкаТабличногоПоля <> Неопределено Тогда СтрокаФормата = КолонкаТабличногоПоля.Формат; // Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался //Если Истина // И ПустаяСтрока(СтрокаФормата) // И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода") //Тогда // КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла; // СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти; //КонецЕсли; КонецЕсли; Если ВозвращатьПредставлениеСсылки Или Не ЛиСсылкаНаОбъектБДЛкс(Значение) Тогда Результат = Результат + Формат(Значение, СтрокаФормата); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПредставлениеСвязейПараметровВыбораЛкс(Связи) Экспорт #Если Сервер И Не Сервер Тогда Связи = Новый ФиксированныйМассив(); #КонецЕсли Результат = ""; Для Каждого Связь Из Связи Цикл #Если Сервер И Не Сервер Тогда Связь = Новый СвязьПараметраВыбора; #КонецЕсли Если Результат <> "" Тогда Результат = Результат + ", "; КонецЕсли; Результат = Результат + Связь.ПутьКДанным; КонецЦикла; Возврат Результат; КонецФункции Функция ПредставлениеТипаЛкс(Знач Тип, Знач ОписаниеТипов = Неопределено, ИспользоватьИмя = Ложь) Если ИспользоватьИмя Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип); ПредставлениеТипа = мПлатформа.ПолучитьСтрокуКонкретногоТипа(СтруктураТипа); Иначе ПредставлениеТипа = "" + Тип; КонецЕсли; Если ОписаниеТипов <> Неопределено Тогда Если Тип = Тип("Число") Тогда ПредставлениеТипа = ПредставлениеТипа + "(" + ОписаниеТипов.КвалификаторыЧисла.Разрядность + "," + ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")"; ИначеЕсли Тип = Тип("Строка") Тогда ПредставлениеТипа = ПредставлениеТипа + "(" + XMLСтрока(ОписаниеТипов.КвалификаторыСтроки.Длина) + ")"; ИначеЕсли Тип = Тип("Дата") Тогда Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда ПредставлениеКвалификатора = "В"; ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда ПредставлениеКвалификатора = "ДВ"; ИначеЕсли ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда ПредставлениеКвалификатора = "Д"; КонецЕсли; ПредставлениеТипа = ПредставлениеТипа + "(" + ПредставлениеКвалификатора + ")"; КонецЕсли; КонецЕсли; Возврат ПредставлениеТипа; КонецФункции // ЛксПолучитьПредставлениеЗначение() // Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств. // Отсутствие свойства приравнивается к значению Неопределено. // // Параметры: // Первый – Произвольный – первый объект для сравнения; // Второй – Произвольный – первый объект для сравнения; // СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения. // // Возвращаемое значение: // Булево – Равны ли значения всех указанных свойств. // Функция СравнитьЗначенияСвойствЛкс(Первый, Второй, СвойстваДляСравнения) Экспорт Структура1 = Новый Структура(СвойстваДляСравнения); ЗаполнитьЗначенияСвойств(Структура1, Первый); Структура2 = Новый Структура(СвойстваДляСравнения); ЗаполнитьЗначенияСвойств(Структура2, Второй); Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2); Возврат Результат; КонецФункции // СравнитьЗначенияСвойствЛкс() Функция КоличествоОшибокВЖурналеЛкс(Знач Начало, Знач Конец, Знач СтруктураОтбора, Знач МаксимальныйРазмерВыгрузки = Неопределено) Экспорт АнализЖурналаРегистрации = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализЖурналаРегистрации"); #Если Сервер И Не Сервер Тогда АнализЖурналаРегистрации = Обработки.ирАнализЖурналаРегистрации.Создать(); #КонецЕсли СобытияЗадания = АнализЖурналаРегистрации.ПолучитьДанные(Начало, Конец, СтруктураОтбора, МаксимальныйРазмерВыгрузки); КоличествоОшибокВЖурнале = СобытияЗадания.Количество(); Возврат КоличествоОшибокВЖурнале; КонецФункции #Если Клиент Тогда Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина); лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина); лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина); лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина); лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина); лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина); лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина); лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина); лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина); лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина); лСтруктураПараметров.Вставить("МножественныйВыбор", Истина); лДоступныеОбъекты = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле); лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД); лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД); Если ЭтоКолонкаПолногоИмениМД Тогда ДоступныеОбъекты = Новый Массив; Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл СреднееИмяМД = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); ДоступныеОбъекты.Добавить(СреднееИмяМД); КонецЦикла; Иначе //лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина); //лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина); ДоступныеОбъекты = лДоступныеОбъекты; КонецЕсли; ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД]; Если Истина И ЭлементОтбора.Использование И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Тогда лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения(); Если ЭтоКолонкаПолногоИмениМД Тогда НачальноеЗначениеВыбора = Новый Массив; Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл СреднееИмяМД = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); НачальноеЗначениеВыбора.Добавить(СреднееИмяМД); КонецЦикла; Иначе НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора; КонецЕсли; Иначе НачальноеЗначениеВыбора = ДоступныеОбъекты; КонецЕсли; мПлатформа = ирКэш.Получить(); Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных"); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора); лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; ЗначениеВыбора = Форма.ОткрытьМодально(); Если ЗначениеВыбора <> Неопределено Тогда Если ЭтоКолонкаПолногоИмениМД Тогда ТаблицаВсехТаблицБД = ирКэш.ТаблицаВсехТаблицБДЛкс(); МассивИменМД = Новый Массив; Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя"); Если СтрокаОписанияТаблицы <> Неопределено Тогда МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД); Иначе МассивИменМД.Добавить(СреднееИмяМД); КонецЕсли; КонецЦикла; Иначе МассивИменМД = ЗначениеВыбора; КонецЕсли; СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(МассивИменМД); ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке; ЭлементОтбора.Значение = СписокЗначений; ЭлементОтбора.Использование = Истина; КонецЕсли; КонецПроцедуры Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма"); Дерево = Новый ДеревоЗначений; Дерево.Колонки.Добавить("Объект"); Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов"); НачатьТранзакцию(); Попытка Для Каждого Объект Из Объекты Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КопияОбъекта = Объект.Ссылка.ПолучитьОбъект(); ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта); Попытка КопияОбъекта.ОбменДанными.Загрузка = Истина; Исключение СообщитьЛкс("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается"); Возврат; КонецПопытки; КопияОбъекта.Записать(); СтрокаГруппы = Дерево.Строки.Добавить(); СтрокаЭлемента = СтрокаГруппы.Строки.Добавить(); СтрокаЭлемента[0] = КопияОбъекта.Ссылка; СтрокаЭлемента = СтрокаГруппы.Строки.Добавить(); СтрокаЭлемента[0] = Объект; КонецЦикла; Исключение ОтменитьТранзакцию(); ВызватьИсключение; КонецПопытки; ЗафиксироватьТранзакцию(); ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь); ФормаОбработки.ОтключатьКонтрольЗаписи = Истина; ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь; КонецПроцедуры // ПередОткрытием() // Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно. // Иными словам колонка отображает данные, хранимые отдельно. // // Параметры: // ОформлениеЯчейки – ОформлениеЯчейки // Значение - Произвольный - значение для отображения. // Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт Если Значение = Неопределено Тогда Значение = ОформлениеЯчейки.Значение; КонецЕсли; Если ВыводитьПиктограммуТипа Тогда ТипЗначения = ТипЗнч(Значение); Если Истина И ТипЗначения = Тип("Булево") И ОформлениеЯчейки.ОтображатьФлажок Тогда // Иначе КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения); Если КартинкаТипа <> Неопределено Тогда ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа); КонецЕсли; КонецЕсли; КонецЕсли; РасширенноеПредставление = РасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля); Если Ложь Или ОформлениеЯчейки.Текст = РасширенноеПредставление Тогда Возврат; КонецЕсли; //ОформлениеЯчейки.ТолькоПросмотр = Истина; //ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения"); ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление); КонецПроцедуры // Находит файлы в иерархии заданного каталога локальной файловой системы. // // Параметры: // Путь – Строка; // Маска – Строка. // // Возвращаемое значение: // Массив – элементы типа Файл. // Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт НайденныеКаталоги = НайтиФайлы(Путь, "*.*"); МассивРезультатов = Новый Массив; Для каждого НайденныйФайл Из НайденныеКаталоги Цикл Если НайденныйФайл.ЭтоКаталог() Тогда МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска)); КонецЕсли; КонецЦикла; МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска)); Результат = Новый Массив; Для Каждого ЭлементРезультат Из МассивРезультатов Цикл Для Каждого Файл Из ЭлементРезультат Цикл Результат.Добавить(Файл); КонецЦикла; КонецЦикла; Возврат Результат; КонецФункции // НайтиФайлыВИерархииЛкс() // Проверяет, является ли тип типом элемента формы. // // Параметры: // пТип – Тип – проверяемый тип. // // Возвращаемое значение: // Истина – тип элемента формы подтвержден; // Ложь – тип элемента формы не подтвержден. // Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт Если Ложь ИЛИ пТип = Тип("Индикатор") ИЛИ пТип = Тип("Кнопка") ИЛИ пТип = Тип("КоманднаяПанель") ИЛИ пТип = Тип("Надпись") ИЛИ пТип = Тип("Панель") ИЛИ пТип = Тип("Переключатель") ИЛИ пТип = Тип("ПолеВвода") ИЛИ пТип = Тип("ПолеВыбора") ИЛИ пТип = Тип("ПолеСписка") ИЛИ пТип = Тип("ПолеТекстовогоДокумента") ИЛИ пТип = Тип("ПолеТабличногоДокумента") ИЛИ пТип = Тип("ПолосаРегулирования") ИЛИ пТип = Тип("ТабличноеПоле") ИЛИ пТип = Тип("РамкаГруппы") ИЛИ пТип = Тип("Флажок") Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиТипЭлементаФормыЛкс() // Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно. // // Параметры: // *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено; // *СтартоваяСтрока - Число, *0 - стартовое смещение строки; // *СтартоваяКолонка - Число, *0 - стартовое смещение колонки; // *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса; // *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо СообщитьЛкс(). // *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено; // *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка. // // Возвращаемое значение: // Строка – истинное описание ошибки. // Функция ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента = Неопределено, СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено, ИмяМодуля = Неопределено, ПредставлениеКонтекста = "") Экспорт НомерСтроки = 0; Если ИмяМодуля <> Неопределено Тогда Вступление = Символы.Таб; Иначе Вступление = ""; КонецЕсли; Если ИнформацияОбОшибке = Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); КонецЕсли; ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(ОписаниеОшибки, Истина, ЛиМодально); Если Истина И ЯзыкПрограммы = 0 И ИмяМодуля <> Неопределено И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Возврат ОписаниеОшибки; КонецЕсли; Если ЯзыкПрограммы = 2 Тогда Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; Выражение = ""; Если Выражение = "" Тогда Маркер = "Ошибка в выражении """; Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3); КонецЕсли; КонецЕсли; Если Выражение = "" Тогда Маркер = "Поле не найдено """; Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда МаркерНайден = Истина; Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1); КонецЕсли; КонецЕсли; Если Выражение <> "" Тогда ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст(); ПозицияВыражения = Найти(ТекстПоля, Выражение); Если ПозицияВыражения > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение)); Пустышка = 0; НомерСтроки = 0; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка); КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ИнформацияОбОшибке.Причина <> Неопределено И ИнформацияОбОшибке.ИмяМодуля <> "" И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ФигурноеОписаниеОшибки = СтрокаМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь); Если ФигурноеОписаниеОшибки <> Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И ИнформацияОбОшибке.ИмяМодуля <> "" И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; МаксимальныйНомерСтроки = 100000; Если ПолеТекстовогоДокумента <> Неопределено Тогда МаксимальныйНомерСтроки = ПолеТекстовогоДокумента.КоличествоСтрок(); КонецЕсли; ФигурноеОписаниеОшибки = СтрокаМеждуМаркерамиЛкс(ИнформацияОбОшибке.Описание, "{", "}", Ложь); ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если НомерСтроки = 0 Тогда НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки); Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда СтрокаКоординатыОшибки = СтрокаМеждуМаркерамиЛкс(ФигурноеОписаниеОшибки, "(", ")", Ложь); Если СтрокаКоординатыОшибки <> Неопределено Тогда НомерКолонки = 0; МассивФрагментов = СтрРазделитьЛкс(СтрокаКоординатыОшибки, ","); СтрокаНомерСтроки = МассивФрагментов[0]; Попытка НомерСтроки = Число(СтрокаНомерСтроки); Исключение КонецПопытки; НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки); Если МассивФрагментов.Количество() > 1 Тогда СтрокаНомерКолонки = МассивФрагментов[1]; Попытка НомерКолонки = Число(СтрокаНомерКолонки); Исключение КонецПопытки; НомерКолонки = НомерКолонки + СтартоваяКолонка; КонецЕсли; Если НомерСтроки = 0 Тогда НомерКолонки = 1; НомерСтроки = 1; КонецЕсли; ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")"); КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И НомерСтроки <= 0 Тогда Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки; Иначе ОписаниеОшибки = "Ошибка без описания"; КонецЕсли; Иначе ОписаниеОшибки = "Строка кода " + НомерСтроки + ": " + ОписаниеОшибки; КонецЕсли; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; ТекстСообщения = ""; Если ПолеТекстовогоДокумента <> Неопределено Тогда Если НомерСтроки > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 150); КонецЕсли; ТекстСообщения = ТекстСообщения + ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста; ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки; ПолныйТекстСообщения = Вступление + ТекстСообщения; Если ЛиМодально Тогда Предупреждение(ТекстСообщения); Иначе СообщитьЛкс(ПолныйТекстСообщения, СтатусСообщения.Важное); КонецЕсли; Иначе ПолныйТекстСообщения = Вступление + ТекстСообщения; Если ЛиМодально Тогда Предупреждение(ОписаниеОшибки); Иначе СообщитьЛкс(ПолныйТекстСообщения, СтатусСообщения.Важное); КонецЕсли; КонецЕсли; Возврат ПолныйТекстСообщения; КонецФункции Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт Результат = Ложь; Если Истина //И (Ложь // Или Не ирКэш.ЛиПортативныйРежимЛкс() // Или ирПортативный.ЛиСерверныйМодульДоступенЛкс()) И Найти(ОписаниеОшибки, "мутабельн") > 0 И Найти(ОписаниеОшибки, "Записать") > 0 Тогда ТекстСообщения = "Чтобы избежать ошибки передачи мутабельного значения при записи объектов, используйте "; Если ЭтоПроизвольныйАлгоритм Тогда ТекстСообщения = ТекстСообщения + "функцию ""ирОбщий.ЗаписатьОбъектЛкс(Объект, Истина)"""; Иначе ТекстСообщения = ТекстСообщения + "опцию ""Запись на сервере"" инструмента"; КонецЕсли; Если ирКэш.ЛиПортативныйРежимЛкс() И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс() Тогда ТекстСообщения = ТекстСообщения + ", которая станет доступной после указания пользователя внешнего соединения в настройках инструментов"; КонецЕсли; Если ЛиМодально Тогда Предупреждение(ТекстСообщения); Иначе СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание); КонецЕсли; Результат = Истина; КонецЕсли; Возврат Результат; КонецФункции // ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс() // Рассчитыват и устанавливает ширину колонок табличного документа. Ориентирована на обработку // результата построителя отчета. // // Параметры: // ТабличныйДокумент – ТабличныйДокумент; // *ЛиМинимальный – Булево, *Ложь – признак установки необходимой ширины, иначе достаточной; // *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием; // *ШиринаОбластиПолей - Число, *0 - ширина области полей (не показателей); // *РассчитыватьШиринуКолонкиПоНазванию - Булево, *Истина - признак расчета ширины колонки по названию; // *МинимальнаяШиринаКолонкиПоказатель - Число, *10 - минимальная ширина колонки показателя; // *ПорогКоличестваЯчеекДляАнализа - Число, *100000 - пороговое количество ячеек для анализа (усечение по высоте). // Процедура УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(ТабличныйДокумент, ЛиМинимальный = Ложь, ЛиИгнорироватьОбрезание = Ложь, ШиринаОбластиПолей = 0, РассчитыватьШиринуКолонкиПоНазванию = Ложь, МинимальнаяШиринаКолонкиПоказатель = 10, ПорогКоличестваЯчеекДляАнализа = 10000) Экспорт Перем МаксимальнаяШиринаКолонки; Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных; Перем ОбластьШапки, ОбластьПодвала; Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста; Перем КоличествоУровнейГруппировокСтрок, Отступ; Перем ШириныКолонок; СтрокаСостояния = "Расчет ширины колонок табличного документа "; КоличествоОбновленийСостояния = 10; // Ограничение максимальной ширины колонки МаксимальнаяШиринаКолонки = 50; // Массив, в который будут помещаться ширины колонок ШириныКолонок = Новый Массив; // Получим количество уровней группировок в отчете для учета автоматического отступа КоличествоУровнейГруппировокСтрок = ТабличныйДокумент.КоличествоУровнейГруппировокСтрок(); // Инициализируем начальные строки НачальнаяСтрока = 0; НачалоДанных = 0; // Найдем в результирующем документе область шапки таблицы ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаТаблицы"); Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины НачальнаяСтрока = ОбластьШапки.Верх; НачалоДанных = ОбластьШапки.Низ + 1; Иначе // Если область шапки таблицы не найдена, найдем область шапки строк ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаСтрок"); Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины НачальнаяСтрока = ОбластьШапки.Верх; НачалоДанных = ОбластьШапки.Низ + 1; КонецЕсли; КонецЕсли; // Получим область подвала отчета и вычислим конечную строку расчета ОбластьПодвала = ТабличныйДокумент.Области.Найти("Подвал"); Если ТипЗнч(ОбластьПодвала) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Область подвала найдена КонечнаяСтрока = ОбластьПодвала.Верх - 1; Иначе // Область подвала не найдена КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы; КонецЕсли; СтарыйПрогресс = 0; КоличествоЯчеекПоказателейДляРасчета = (КонечнаяСтрока - НачальнаяСтрока) * (ТабличныйДокумент.ШиринаТаблицы - 1); Если КоличествоЯчеекПоказателейДляРасчета > ПорогКоличестваЯчеекДляАнализа Тогда КонечнаяСтрока = Мин(КонечнаяСтрока, ПорогКоличестваЯчеекДляАнализа / (ТабличныйДокумент.ШиринаТаблицы - 1)); КонецЕсли; // Переберем все колонки отчета Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ПрогрессКолонок = ТекущаяКолонка / ТабличныйДокумент.ШиринаТаблицы / КонечнаяСтрока; АвтоОтступ = 0; // Переберем строки, которые будут использованы для расчета ширин колонок Для ТекущаяСтрока = НачальнаяСтрока По КонечнаяСтрока Цикл ОбработкаПрерыванияПользователя(); Прогресс = КоличествоОбновленийСостояния * ПрогрессКолонок * ТекущаяСтрока; Если Прогресс - СтарыйПрогресс >= 1 Тогда СтарыйПрогресс = Прогресс; СостояниеЛкс(СтрокаСостояния + Цел(100 * ПрогрессКолонок * ТекущаяСтрока) + "%"); КонецЕсли; ШиринаКолонки = 0; // Получим область текущей ячейки ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка); Если ОбластьЯчейки.Лево <> ТекущаяКолонка Или ОбластьЯчейки.Верх <> ТекущаяСтрока Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; // Данная ячейка обрезает текст Если Истина И ЛиИгнорироватьОбрезание И ОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Обрезать Тогда Продолжить; КонецЕсли; Если КоличествоУровнейГруппировокСтрок > 0 И ТекущаяСтрока = НачалоДанных Тогда // Для первой строки с данными получим значение автоотступа АвтоОтступ = ОбластьЯчейки.АвтоОтступ; КонецЕсли; // Получим текст ячейки ТекстЯчейки = ОбластьЯчейки.Текст; КоличествоСтрокВТекстеЯчейки = СтрЧислоСтрок(ТекстЯчейки); ТекстЯчейкиТД = Новый ТекстовыйДокумент; ТекстЯчейкиТД.УстановитьТекст(ТекстЯчейки); // Для каждой строки из текста ячейки рассчитаем количество символов в строке Для НомерСтрокиТекста = 1 По КоличествоСтрокВТекстеЯчейки Цикл ШиринаТекстаЯчейки = СтрДлина(ТекстЯчейкиТД.ПолучитьСтроку(НомерСтрокиТекста)); Если Истина И НЕ РассчитыватьШиринуКолонкиПоНазванию И ТекущаяСтрока < НачалоДанных И ШиринаТекстаЯчейки > 0 Тогда ШиринаТекстаЯчейки = МинимальнаяШиринаКолонкиПоказатель; КонецЕсли; // Если используется автоотступ, то прибавим к ширине ячейки его величину Если АвтоОтступ <> Неопределено И АвтоОтступ > 0 Тогда ШиринаТекстаЯчейки = ШиринаТекстаЯчейки + КоличествоУровнейГруппировокСтрок * АвтоОтступ; КонецЕсли; ШиринаКолонки = Макс(ШиринаКолонки, ШиринаТекстаЯчейки); КонецЦикла; Если ШиринаКолонки > МаксимальнаяШиринаКолонки Тогда // Ограничим ширину колонки ШиринаКолонки = МаксимальнаяШиринаКолонки; КонецЕсли; Если ШиринаКолонки <> 0 Тогда // Ширина колонки рассчитана // Определим, сколько ячеек по ширине используется в области для текущей ячейки КоличествоКолонок = ОбластьЯчейки.Право - ОбластьЯчейки.Лево; // Переберем все ячейки, расположенные в области Для НомерКолонки = 0 По КоличествоКолонок Цикл Если ШириныКолонок.ВГраница() >= ТекущаяКолонка - 1 + НомерКолонки Тогда // В массиве ширин колонок уже был элемент для текущей колонки Если ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Неопределено Тогда // Значение ширины колонки еще не было установлено ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = ШиринаКолонки / (КоличествоКолонок + 1); Иначе // Значение ширины колонки уже было установлено // Вычислим максимум ширины колонки ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Макс(ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки], ШиринаКолонки / (КоличествоКолонок + 1)); КонецЕсли; Иначе // В массиве ширин колонок еще не было элемента для данной колонки // Добавим элемент в массив ширин колонок ШириныКолонок.Вставить(ТекущаяКолонка - 1 + НомерКолонки, ШиринаКолонки / (КоличествоКолонок + 1)); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; // Конец цикла перебора строк КонецЦикла; // Конец цикла перебора колонок // Переберем все элементы в массиве вычисленных ширин колонок Для ТекущаяКолонка = 0 По ШириныКолонок.ВГраница() Цикл Если ШиринаОбластиПолей >= ТекущаяКолонка Тогда УстановитьМинимальнуюШирину = Ложь; Иначе УстановитьМинимальнуюШирину = ЛиМинимальный; КонецЕсли; Если ШириныКолонок[ТекущаяКолонка] <> Неопределено Тогда ОбластьКолонки = ТабличныйДокумент.Область(, ТекущаяКолонка + 1, НачалоДанных, ТекущаяКолонка + 1); // Ширина колонок установлена // Установим ширину области ячеек Если УстановитьМинимальнуюШирину Тогда ОбластьКолонки.ШиринаКолонки = Макс(ШириныКолонок[ТекущаяКолонка] + 1, МинимальнаяШиринаКолонкиПоказатель); Иначе ОбластьКолонки.ШиринаКолонки = ШириныКолонок[ТекущаяКолонка] + 1; КонецЕсли; КонецЕсли; КонецЦикла; СостояниеЛкс(""); КонецПроцедуры // УстановитьАвтоширинуКолонокТабличногоДокументаЛкс() // Устанавливает отбор построителя по расшифровке, содержащей NULL'ы. // Устанавливает значение каждого NULL элемента отбора в "<Отсутствует>" и вид сравнения в "Равно". // Для измерений, которые могут содержать значенение "NULL" в запросах в секции условий построителя следует // писать "ЕСТЬNULL(ПутьКДаннымИзмерения, "<Отсутствует>") КАК ИмяИзмерения". // // Параметры: // пПостроительОтчета – ПостроительОтчета – чей отбор обрабатываем; // пРасшифровка - Структура - расшифровка. // Процедура УстановитьОтборПостроителяПриРасшифровкеЛкс(пПостроительОтчета, пРасшифровка) Экспорт Для каждого ЭлементРасшифровки Из пРасшифровка Цикл Если ЭлементРасшифровки.Значение = NULL Тогда ЭлементОтбора = пПостроительОтчета.Отбор[ЭлементРасшифровки.Ключ]; Если ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка")) Тогда ЭлементОтбора.Значение = "<Отсутствует>"; Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.Равно; КонецЕсли; Иначе СообщитьЛкс("Запрос не поддерживает расшифровку по отсутствующему значению элемента отбора """ + ЭлементОтбора.Представление + """!"); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // УстановитьОтборПостроителяПриРасшифровкеЛкс() // Получает копию построителя отчетов. // // Параметры: // Оригинал – ПостроительОтчета. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ПолучитьКопиюПостроителяОтчетаЛкс(Оригинал, ВосстанавливатьНастройки = Истина) Экспорт Копия = Новый ПостроительОтчета; Для Каждого ДоступноеПоле Из Оригинал.ДоступныеПоля Цикл ЗаполнитьЗначенияСвойств(Копия.ДоступныеПоля.Добавить(ДоступноеПоле.Имя, ДоступноеПоле.Представление), ДоступноеПоле); КонецЦикла; Если ВосстанавливатьНастройки Тогда Копия.Текст = Оригинал.Текст; Копия.ЗаполнитьНастройки(); // Баг платформы. Без этого почему то иногда измерения не восстанавливаются! Копия.УстановитьНастройки(Оригинал.ПолучитьНастройки()); КонецЕсли; Возврат Копия; КонецФункции // ПолучитьКопиюПостроителяОтчетаЛкс() // Возвращает менеджер временных таблиц, в котором создана временная таблица по переданному источнику. // // Параметры: // ВнешнийИсточник – ТаблицаЗначений; // ИмяТаблицы – Строка; // *МенеджерВременныхТаблиц – МенеджерВременныхТаблиц, *Неопределено. // // Возвращаемое значение: // МенеджерВременныхТаблиц. // Функция ПолучитьВременнуюТаблицуЛкс(ВнешнийИсточник, ИмяТаблицы, МенеджерВременныхТаблиц = Неопределено) Экспорт Если МенеджерВременныхТаблиц = Неопределено Тогда МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; КонецЕсли; ТекстВЫБРАТЬ = ""; Для Каждого Колонка Из ВнешнийИсточник.Колонки Цикл ТекстВЫБРАТЬ = ТекстВЫБРАТЬ + ", " + Колонка.Имя; КонецЦикла; ТекстЗапроса = "ВЫБРАТЬ " + Сред(ТекстВЫБРАТЬ, 3); ТекстЗапроса = ТекстЗапроса + " ПОМЕСТИТЬ " + ИмяТаблицы; ТекстЗапроса = ТекстЗапроса + " ИЗ &ВнешнийИсточник КАК ВнешнийИсточник"; Запрос = Новый Запрос(ТекстЗапроса); Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; Запрос.УстановитьПараметр("ВнешнийИсточник", ВнешнийИсточник); Запрос.Выполнить(); Возврат МенеджерВременныхТаблиц; КонецФункции // ПолучитьВременнуюТаблицуЛкс() Процедура ПанельИнструментовОПодсистемеЛкс() Экспорт ОткрытьСправкуПоПодсистемеЛкс(); КонецПроцедуры // Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицой или деревом значений. // Процедура ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ТабличноеПоле) Экспорт Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда Возврат; КонецЕсли; ФормаОбработки = ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма"); Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; СписокВыбора = Новый СписокЗначений; СписокВыбора.Добавить(0, "Создать группы дублей из пар неправильных значений текущей и правильных значений следующей колонок"); СписокВыбора.Добавить(1, "Создать одну группу дублей из значений текущей колонки выделенных строк"); //СписокВыбора.Добавить(2, "Создать правила замены значений из текущей колонки на значения следующей колонки"); ВыбранныйВариант = СписокВыбора.ВыбратьЭлемент("Выберите вариант"); Если ВыбранныйВариант = Неопределено Тогда Возврат; КонецЕсли; Если ВыбранныйВариант.Значение = 1 Тогда Если ВыделенныеСтроки.Количество() = 0 Тогда Возврат ; КонецЕсли; ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Возврат; КонецЕсли; МассивСсылок = Новый Массив; Для Каждого Строка Из ВыделенныеСтроки Цикл ЗначениеСтроки = Строка[ИмяКолонки]; ТипЗначения = ТипЗнч(ЗначениеСтроки); Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда Продолжить; КонецЕсли; МассивСсылок.Добавить(ЗначениеСтроки); КонецЦикла; ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок,, 0); ИначеЕсли ВыбранныйВариант.Значение = 0 Тогда ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка; Если Ложь Или ТекущаяКолонка = Неопределено Или ТекущаяКолонка.Данные = "" Тогда Возврат; КонецЕсли; ИндексКолонки = ТабличноеПоле.Колонки.Индекс(ТекущаяКолонка); Если ТабличноеПоле.Колонки.Количество() = ИндексКолонки + 1 Тогда Возврат; КонецЕсли; СледующаяКолонка = ТабличноеПоле.Колонки[ИндексКолонки + 1]; Если СледующаяКолонка.Данные = "" Тогда Возврат; КонецЕсли; ФормаОбработки.ОткрытьСЗаполнениемГруппДублейПоТаблицеПар(ТабличноеПоле.Значение, ТекущаяКолонка.Данные, СледующаяКолонка.Данные); КонецЕсли; ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя); КонецЕсли; КонецПроцедуры // ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс() //////////////////////////////////////////////////////////////////////////////// // ТЕХНОЛОГИЯ КОМПОНЕНТ // Возвращает кнопку командной панели компоненты по ее имени из макета. // // Параметры: // ОбъектКомпоненты - ОбработкаОбъект - компонента; // КраткоеИмяКнопки – Строка - имя кнопки из макета компоненты; // *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей. // // Возвращаемое значение: // Кнопка. // Функция ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Знач КоманднаяПанель = Неопределено) Экспорт Если КоманднаяПанель = Неопределено Тогда КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель; КонецЕсли; Если КоманднаяПанель = Неопределено Тогда // Был вызван деструктор Возврат Неопределено; КонецЕсли; ПолноеИмяКнопки = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяКнопки); Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки); Если Кнопка = Неопределено Тогда Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда Продолжить; КонецЕсли; Кнопка = ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю); Если Кнопка <> Неопределено Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Возврат Кнопка; КонецФункции // ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс() // Формирует имя элемента управления экземпляра компоненты. // // Параметры: // ИмяКласса – Строка; // ИмяЭкземпляра - Строка; // КраткоеИмяЭлементаУправления – Строка. // // Возвращаемое значение: // Строка - имя. // Функция СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КраткоеИмяЭлементаУправления) Экспорт Возврат ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) + КраткоеИмяЭлементаУправления; КонецФункции Функция ПрефиксИменЭлементовЭкземпляраКомпонентыЛкс(ОбъектКомпоненты) Экспорт Возврат ОбъектКомпоненты.ИмяКласса + "_" + ОбъектКомпоненты.Имя + "_"; КонецФункции // СформироватьИмяЭлементаУправленияЭкземпляраЛкс() // <Описание функции> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() Экспорт ТаблицаСобытий = Новый ТаблицаЗначений; ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта"); ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма"); ТаблицаСобытий.Колонки.Добавить("ИмяСобытия"); ТаблицаСобытий.Колонки.Добавить("Компонента"); ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика"); Возврат ТаблицаСобытий; КонецФункции // ПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпонентыЛкс() // Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника. // // Параметры: // ОбъектКомпоненты - ОбработкаОбъект - компонента; // КнопкиМакета – КоллекцияКнопокКоманднойПанели – источник; // КнопкиПриемника – КоллекцияКнопокКоманднойПанели – приемник; // *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено; // Процедура ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника, ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено) Экспорт КнопкиПриемника = КнопкаПриемника.Кнопки; ИмяКласса = ОбъектКомпоненты.ИмяКласса; Если ДействияКнопокКомпонент = Неопределено Тогда ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие"); Иначе ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель")); ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей; ДопКнопкиКоманднойПанели = Новый Массив; ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели); ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие") КонецЕсли; ИмяЭкземпляра = ОбъектКомпоненты.Имя; Для Каждого КнопкаМакета Из КнопкиМакета Цикл Кнопка = Неопределено; Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда Если Истина И Строка(КнопкаМакета.Действие) = "" Тогда // Это пустое действие Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки); ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя"); Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя); //Попытка Кнопка.Действие = ДействиеТранслятор; //Исключение // ОписаниеОшибки = ОписаниеОшибки(); // Для отладки // Возврат; //КонецПопытки; Если ДействияКнопокКомпонент <> Неопределено Тогда СтрокаДействия = ДействияКнопокКомпонент.Добавить(); СтрокаДействия.Кнопка = Кнопка; СтрокаДействия.Компонента = ОбъектКомпоненты; ВызовОбработчика = "Действие_"; Если ОбщийПриемник = Неопределено Тогда ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя; Иначе ВызовОбработчика = ВызовОбработчика + ОбщийПриемник; КонецЕсли; СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)"; КонецЕсли; Иначе Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие); // Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда Кнопка.Картинка = КнопкаМакета.Картинка; КонецЕсли; ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Картинка"); КонецЕсли; КонецЕсли; Если Кнопка = Неопределено Тогда Кнопка = КнопкиПриемника.Добавить(); ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя"); Кнопка.Имя = СформироватьИмяЭлементаУправленияЭкземпляраЛкс(ОбъектКомпоненты, КнопкаМакета.Имя); Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник); КонецЕсли; КонецЕсли; Если Истина И ДействияКнопокКомпонент <> Неопределено И ЭтоКоманднаяПанель Тогда ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя); КонецЕсли; КонецЦикла; КонецПроцедуры // ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс() // Возвращает имя экземляра компоненты, которой принадлежит элемент управления. // // Параметры: // ЭлементУправления – ЭлементУправления. // // Возвращаемое значение: // Строка - имя. // Функция ПолучитьИмяЭкземпляраЛкс(ЭлементУправления) Экспорт Результат = СтрРазделитьЛкс(ЭлементУправления.Имя, "_")[1]; Возврат Результат; КонецФункции // ПолучитьИмяЭкземпляраЛкс() // Устанавливает свойство у элементов именованной коллекции. // // Параметры: // Коллекция – Любая индексированная коллекция; // МассивИлиСтрока – Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр; // Свойство – Строка - имя Свойства которое нужно установить; // ЗначениеСвойства – Произвольный. // Процедура УстановитьСвойствоВКоллекцииЛкс(Коллекция, МассивИлиСтрока = Неопределено, Свойство, ЗначениеСвойства) Экспорт ДоступенИндексСвойств = Лев(Свойство, 1) <> "-"; Если МассивИлиСтрока <> Неопределено Тогда Если ТипЗнч(МассивИлиСтрока) = Тип("Строка") Тогда МассивИндексов = СтрРазделитьЛкс(МассивИлиСтрока, ",", Истина); Иначе МассивИндексов = МассивИлиСтрока; КонецЕсли; Для Каждого ИмяЭлемента Из МассивИндексов Цикл ЭлементКоллекции = Коллекция[ИмяЭлемента]; Если ДоступенИндексСвойств Тогда ЭлементКоллекции[Свойство] = ЗначениеСвойства; Иначе Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства"); КонецЕсли; КонецЦикла; Иначе Для Каждого ЭлементКоллекции Из Коллекция Цикл Если ДоступенИндексСвойств Тогда ЭлементКоллекции[Свойство] = ЗначениеСвойства; Иначе Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства"); КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры // УстановитьСвойствоВКоллекцииЛкс() Процедура ПриПолученииДанныхТабличногоПоляКолонокЛкс(ОформленияСтрок, ИмяКолонкиОписанияТипов = "ТипЗначения") Экспорт Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки; Если ДанныеСтроки = Неопределено Тогда Продолжить; КонецЕсли; ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки[ИмяКолонкиОписанияТипов]); Если ИндексКартинки <> Неопределено Тогда ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки[ИмяКолонкиОписанияТипов].ИндексКартинки = ИндексКартинки; КонецЕсли; КонецЦикла; КонецПроцедуры // Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки. // // Параметры: // ОформленияСтрок – ОформленияСтрок. // Процедура ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс(ОформленияСтрок, ТабличноеПолеВыбранныхПолей = Неопределено) Экспорт Если Истина И ТабличноеПолеВыбранныхПолей <> Неопределено И ОформленияСтрок[0].Ячейки.Найти("Использовано") <> Неопределено Тогда ВсеПоляВыбранныхПолей = ирОбщий.ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(ТабличноеПолеВыбранныхПолей.Значение,,, Истина); КонецЕсли; КартинкаРеквизита = ирКэш.КартинкаПоИмениЛкс("ирРеквизит"); Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки; Если ДанныеСтроки = Неопределено Тогда Продолжить; КонецЕсли; ЯчейкаТипа = ОформлениеСтроки.Ячейки.Найти("Тип"); Если ЯчейкаТипа <> Неопределено Тогда ОформлениеСтроки.Ячейки.Тип.УстановитьТекст(ДанныеСтроки.ТипЗначения); КонецЕсли; ИндексКартинки = Неопределено; Попытка ЭтоПапка = ДанныеСтроки.Папка; ЭтоРесурс = ДанныеСтроки.Ресурс; Исключение ЭтоПапка = Ложь; ЭтоРесурс = Ложь; КонецПопытки; Если ЭтоПапка Тогда ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0; Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл Если Не ДоступноеПоле.Ресурс Тогда ПапкаСРесурсами = Ложь; Прервать; КонецЕсли; КонецЦикла; Если ПапкаСРесурсами Тогда ИндексКартинки = 17; КонецЕсли; КонецЕсли; Если Не ЭтоРесурс И Не ЭтоПапка Тогда ИндексКартинки = ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки.ТипЗначения); КонецЕсли; Если ИндексКартинки <> Неопределено Тогда ОформлениеСтроки.Ячейки[0].ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки[0].ИндексКартинки = ИндексКартинки; КонецЕсли; Если Истина И ВсеПоляВыбранныхПолей <> Неопределено И ВсеПоляВыбранныхПолей.Найти(ДанныеСтроки.Поле) <> Неопределено Тогда ОформлениеСтроки.Ячейки.Использовано.УстановитьКартинку(КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецПроцедуры // ПриПолученииДанныхДоступныхПолейКомпоновкиЛкс() // Подключает обработчики событий для табличного поля отбора компоновки данных. // // Параметры: // ТабличноеПоле – ТабличноеПоле – отбора компоновки. // Процедура ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс(ТабличноеПоле) Экспорт Если ТабличноеПоле.ПолучитьДействие("ПриПолученииДанных") <> Неопределено Тогда СообщитьЛкс("Обнаружено переопределение обработчика ПриПолученииДанных табличного поля " + ТабличноеПоле.Имя); КонецЕсли; ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей")); ТабличноеПоле.Колонки[0].КартинкиСтрок = ирКэш.КартинкаПоИмениЛкс("ирТипыДоступныхПолейКомпоновки"); КонецПроцедуры // ПодключитьОбработчикиСобытийДоступныхПолейКомпоновкиЛкс() Процедура УстановитьПолеВПравомЗначенииЭлементаОтбораЛкс(Знач ТабличноеПолеОтбора, Знач ТабличноеПолеДоступныхПолей = Неопределено) Экспорт Если ТабличноеПолеДоступныхПолей <> Неопределено И ТабличноеПолеДоступныхПолей.ТекущаяСтрока <> Неопределено Тогда ПолеКомпоновки = ТабличноеПолеДоступныхПолей.ТекущаяСтрока.Поле; Иначе ПолеКомпоновки = Новый ПолеКомпоновкиДанных(""); КонецЕсли; ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока; Если ТипЗнч(ТекущаяСтрока) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда Если ТипЗнч(ТекущаяСтрока.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных") Или ЗначениеЗаполнено("" + ПолеКомпоновки) Тогда ТекущаяСтрока.ПравоеЗначение = ПолеКомпоновки; КонецЕсли; ТабличноеПолеОтбора.ТекущаяКолонка = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента; КонецЕсли; КонецПроцедуры // Получает макет компоновки данных по схеме с использованием временных таблиц. // // Параметры: // Схема – СхемаКомпоновкиДанных; // Настройки - НастройкиКомпоновкиДанных; // *ВнешниеНаборыДанных – Структура, *Неопределено - туда добавляются временные таблицы; // *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено; // *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов. // // Возвращаемое значение: // МакетКомпоновкиДанных. // Функция ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс(Схема, Настройки, ВнешниеНаборыДанных = Неопределено, ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено, ПроверятьДоступностьПолей = Ложь) Экспорт RegExp = Новый COMОбъект("VBScript.RegExp"); RegExp.Global = Истина; RegExp.MultiLine = Истина; RegExp.IgnoreCase = Истина; // Допустим 1 уровень скобок. шСкобки = "\([^\)\(]*?\)"; RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(.*?)""\)"; Если ВнешниеНаборыДанных = Неопределено Тогда ВнешниеНаборыДанных = Новый Структура; КонецЕсли; Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; // Выполним создание всех временных таблиц. Временной таблицей считаем набор данных запрос, // имя которого начинается с "@". Наборы данных временных таблиц удаляются из предварительной схемы. ПредварительнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема)); НаборыДанныхСхемы = ПредварительнаяСхема.НаборыДанных; ЕстьВременныеТаблицы = Ложь; НачальноеКоличество = НаборыДанныхСхемы.Количество(); Для СчетчикНаборыДанныхСхемы = 1 По НачальноеКоличество Цикл НаборДанных = НаборыДанныхСхемы[НачальноеКоличество - СчетчикНаборыДанныхСхемы]; Если Истина И Лев(НаборДанных.Имя, 1) = "@" И ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда ВременнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема)); // Кривое копирование набора данных в новую схемы, где он будет один. ВременнаяСхема.СвязиНаборовДанных.Очистить(); НаборыДанныхВременнойСхемы = ВременнаяСхема.НаборыДанных; НаборыДанныхВременнойСхемыВГраница = НаборыДанныхВременнойСхемы.Количество() - 1; Для СчетчикВременнойСхемы = 0 По НаборыДанныхВременнойСхемыВГраница Цикл НаборДанныхВременнойСхемы = НаборыДанныхВременнойСхемы[НаборыДанныхВременнойСхемыВГраница - СчетчикВременнойСхемы]; Если НаборДанныхВременнойСхемы.Имя <> НаборДанных.Имя Тогда НаборыДанныхВременнойСхемы.Удалить(НаборДанныхВременнойСхемы); КонецЕсли; КонецЦикла; Для Каждого ПолеНабора Из НаборыДанныхВременнойСхемы[0].Поля Цикл ПолеНабора.ОграничениеИспользования.Поле = Ложь; ПолеНабора.ВыражениеПредставления = ПолеНабора.ПутьКДанным; КонецЦикла; КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ВременнаяСхема)); КомпоновщикНастроек.ЗагрузитьНастройки(Настройки); КомпоновщикНастроек.Настройки.Структура.Очистить(); КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить(); КомпоновщикНастроек.Восстановить(); ВременныеНастройки = КомпоновщикНастроек.Настройки; // Установим использование параметров Для Каждого ЭлементПараметра Из ВременныеНастройки.ПараметрыДанных.Элементы Цикл ЭлементПараметра.Использование = Истина; КонецЦикла; // Установим структуру и выбранные поля ЭлементСтруктуры = ВременныеНастройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); Для Каждого ДоступноеПоле Из ВременныеНастройки.ДоступныеПоляВыбора.Элементы Цикл // Чтобы пропустить системные папки Если Не ДоступноеПоле.Папка Тогда НовоеВыбранноеПоле = ВременныеНастройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле; НовоеВыбранноеПоле.Использование = Истина; КонецЕсли; КонецЦикла; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ВременнаяСхема, ВременныеНастройки,,,, ПроверятьДоступностьПолей); Запрос.Текст = МакетКомпоновкиДанных.НаборыДанных[0].Запрос; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение); КонецЦикла; Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1"); ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя); //// Недоступные поля набора данных цепляются в настройках при совпадаении имен с выбранными полями //// http://partners.v8.1c.ru/forum/thread.jsp?id=514094 //Для Каждого Поле Из НаборДанных.Поля Цикл // Поле.ПутьКДанным = "_поле_" + Поле.ПутьКДанным; //КонецЦикла; НаборыДанныхСхемы.Удалить(НаборДанных); ЕстьВременныеТаблицы = Истина; КонецЕсли; КонецЦикла; Если Не ЕстьВременныеТаблицы Тогда Если ЛиОтладка Тогда ВремяНачалаКомпоновкиМакета = ТекущееВремяВМиллисекундахЛкс(); КонецЕсли; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, Настройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей); Если ЛиОтладка Тогда СообщитьЛкс("Компоновка макета - " + Строка(ТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс"); КонецЕсли; Иначе // Выполним получение результата предварительного запроса КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПредварительнаяСхема)); КомпоновщикНастроек.ЗагрузитьНастройки(Настройки); КомпоновщикНастроек.Восстановить(); ПредварительныеНастройки = КомпоновщикНастроек.Настройки; Если ЛиОтладка Тогда ВремяНачалаКомпоновкиМакета = ТекущееВремяВМиллисекундахЛкс(); КонецЕсли; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, ПредварительныеНастройки, ДанныеРасшифровки, СвойМакетОформления,, ПроверятьДоступностьПолей); Если ЛиОтладка Тогда СообщитьЛкс("Компоновка макета - " + Строка(ТекущееВремяВМиллисекундахЛкс() - ВремяНачалаКомпоновкиМакета) + " мс"); КонецЕсли; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение); КонецЦикла; СтруктураНаборовДанныхЗапросовМакета = ВсеНаборыДанныхЗапросовКомпоновкиЛкс(МакетКомпоновкиДанных.НаборыДанных); Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных; Запрос.Текст = НаборДанных.Запрос; Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1"); РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя); ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса); КонецЦикла; // Получение конечного макета Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец; НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных; НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных")); // Копируем Свойства набора данных запроса в набор данных объекта ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос); НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя; Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл ПолеРезультата = НаборДанныхОбъект.Поля.Добавить(); ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала); ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль); КонецЦикла; КоллекцияВладелец.Удалить(НаборДанныхЗапрос); КонецЦикла; КонецЕсли; // Баг платформы. Пустая дата превращается в Неопределено. Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл Если ПараметрСхемы.ОграничениеИспользования Тогда Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя); ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение); КонецЕсли; КонецЕсли; КонецЦикла; Возврат МакетКомпоновкиДанных; КонецФункции // ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс() #КонецЕсли Функция ПолучитьКоличествоИзмененийПоУзлуЛкс(Узел, МассивМетаданных = Неопределено) Экспорт #Если Клиент Тогда СостояниеЛкс("Вычисление количества изменений на узле..."); #КонецЕсли Запрос = Новый Запрос; Запрос.УстановитьПараметр("Узел", Узел); МетаПланОбмена = Узел.Метаданные(); ТекстЗапроса = ""; Для Каждого ЭлементСОстава Из МетаПланОбмена.Состав Цикл МетаОбъект = ЭлементСОстава.Метаданные; Если Ложь Или МетаОбъект = Неопределено Или (Истина И МассивМетаданных <> Неопределено И МассивМетаданных.Найти(МетаОбъект) = Неопределено) Тогда Продолжить; КонецЕсли; Если ТекстЗапроса <> "" Тогда ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС; КонецЕсли; ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(МетаОбъект.ПолноеИмя(), ".Перерасчет.", ".") + ".Изменения"; ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ Количество(*) КАК Количество |ИЗ | " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений |ГДЕ | РегистрацияИзменений.Узел = &Узел |"; КонецЦикла; Если ТекстЗапроса <> "" Тогда Запрос.Текст = ТекстЗапроса; ТаблицаКоличестваИзменений = Запрос.Выполнить().Выгрузить(); КоличествоИзменений = ТаблицаКоличестваИзменений.Итог("Количество"); Иначе КоличествоИзменений = 0; КонецЕсли; #Если Клиент Тогда СостояниеЛкс(""); #КонецЕсли Возврат КоличествоИзменений; КонецФункции // Параметры: // СтрокаТаблицыИлиДерева - СтрокаТаблицыЗначений, СтрокаДереваЗначений, ВыборкаИзРезультатаЗапроса // Результат - Структура Функция СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(СтрокаТаблицыИлиДереваИлиВыборки) Экспорт Результат = Новый Структура; Для Каждого МетаРеквизит Из СтрокаТаблицыИлиДереваИлиВыборки.Владелец().Колонки Цикл Результат.Вставить(МетаРеквизит.Имя, СтрокаТаблицыИлиДереваИлиВыборки[МетаРеквизит.Имя]); КонецЦикла; Возврат Результат; КонецФункции // Получает структуру свойств объекта по имени типа или объекту. // Свойства должны располагаться в порядке: // - общие, // - ролевые в порядке невлияния на предшествующие. // // Параметры: // пОбъект - Произвольный - имя типа или сам объект; // пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения. // // Возвращаемое значение: // – Структура – свойств. // Функция ПолучитьСтруктуруСвойствОбъектаЛкс(пОбъект, пЛиДляСохранения = Ложь) Экспорт СтруктураСвойств = Новый Структура; ТипОбъекта = ТипЗнч(пОбъект); МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта); Если МетаОбъект <> Неопределено Тогда КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект, Истина); Если Ложь ИЛИ КорневойТип = "Обработка" ИЛИ КорневойТип = "Отчет" Тогда Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; КонецЕсли; Если ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; КонецЕсли; Если Истина И ТипОбъекта <> Тип("Тип") И ТипОбъекта <> Тип("ОписаниеТипов") И ТипОбъекта <> Тип("ОбъектМетаданных") Тогда Если ПолучитьКорневойТипСпискаЛкс(ТипОбъекта) <> Неопределено Тогда СтруктураСвойств.Вставить("Колонки"); СтруктураСвойств.Вставить("Порядок"); СтруктураСвойств.Вставить("Отбор"); ИначеЕсли ЛиНаборЗаписейРегистраЛкс(ТипОбъекта) Тогда СтруктураСвойств.Вставить("Отбор"); КонецЕсли; КонецЕсли; //ИначеЕсли Ложь // ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели") // ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля") // ИЛИ ТипОбъекта = Тип("СтраницыПанели") // ИЛИ ТипОбъекта = Тип("ЭлементыФормы") // ИЛИ ТипОбъекта = Тип("ПоляНастройки") //Тогда // Для Каждого Элемент Из пОбъект Цикл // СтруктураСвойств.Вставить(Элемент.Имя); // КонецЦикла; // ИначеЕсли Ложь Или ТипОбъекта = Тип("СтрокаТаблицыЗначений") Или ТипОбъекта = Тип("СтрокаДереваЗначений") Тогда Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; #Если Клиент Тогда ИначеЕсли ЛиТипЭлементаФормыЛкс(ТипОбъекта) Тогда СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("ИзменяетДанные"); СтруктураСвойств.Вставить("ПервыйВГруппе"); СтруктураСвойств.Вставить("ПропускатьПриВводе"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КонтекстноеМеню"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("Лево"); СтруктураСвойств.Вставить("Верх"); СтруктураСвойств.Вставить("Высота"); СтруктураСвойств.Вставить("Ширина"); КонецЕсли; СтруктураСвойств.Вставить("Подсказка"); СтруктураСвойств.Вставить("ПорядокОбхода"); СтруктураСвойств.Вставить("ПорядокОтображения"); СтруктураСвойств.Вставить("ПрозрачныйФон"); СтруктураСвойств.Вставить("Рамка"); Если ТипОбъекта = Тип("Кнопка") Тогда СтруктураСвойств.Вставить("РежимМеню"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("МногострочныйРежим"); СтруктураСвойств.Вставить("ПоложениеКартинки"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("Шрифт"); СтруктураСвойств.Вставить("Кнопки"); ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда СтруктураСвойств.Вставить("АвтоЗаполнение"); СтруктураСвойств.Вставить("Вспомогательная"); СтруктураСвойств.Вставить("ВыравниваниеКнопок"); СтруктураСвойств.Вставить("ИсточникДействий"); СтруктураСвойств.Вставить("Кнопки"); СтруктураСвойств.Вставить("Ориентация"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда СтруктураСвойств.Вставить("БегущаяСтрока"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ГиперСсылка"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Панель") Тогда СтруктураСвойств.Вставить("Страницы"); СтруктураСвойств.Вставить("АвтоПорядокОбхода"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("ОтображениеЗакладок"); СтруктураСвойств.Вставить("ПорядокОбхода"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("РаспределятьПоСтраницам"); СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("ТекущаяСтраница"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ВыбираемоеЗначение"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ПоложениеЗаголовка"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ОграничениеТипа"); СтруктураСвойств.Вставить("КнопкаВыбора"); СтруктураСвойств.Вставить("РежимВыбораИзСписка"); СтруктураСвойств.Вставить("КнопкаСпискаВыбора"); СтруктураСвойств.Вставить("СписокВыбора"); СтруктураСвойств.Вставить("АвтоВыборНезаполненного"); СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного"); СтруктураСвойств.Вставить("АвтоПереносСтрок"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("БыстрыйВыбор"); СтруктураСвойств.Вставить("ВыбиратьТип"); СтруктураСвойств.Вставить("ВыборГруппИЭлементов"); СтруктураСвойств.Вставить("ВыборНезаполненного"); СтруктураСвойств.Вставить("ВыборПоВладельцу"); СтруктураСвойств.Вставить("ВыделенныйТекст"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ВысотаСпискаВыбора"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КартинкаКнопкиВыбора"); СтруктураСвойств.Вставить("КнопкаОткрытия"); СтруктураСвойств.Вставить("КнопкаОчистки"); СтруктураСвойств.Вставить("КнопкаРегулирования"); СтруктураСвойств.Вставить("МаксимальноеЗначение"); СтруктураСвойств.Вставить("Маска"); СтруктураСвойств.Вставить("МинимальноеЗначение"); СтруктураСвойств.Вставить("МногострочныйРежим"); СтруктураСвойств.Вставить("ОтметкаНезаполненного"); СтруктураСвойств.Вставить("РасширенноеРедактирование"); СтруктураСвойств.Вставить("РедактированиеТекста"); СтруктураСвойств.Вставить("РежимВыбораНезаполненного"); СтруктураСвойств.Вставить("РежимПароля"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ШиринаСпискаВыбора"); СтруктураСвойств.Вставить("Шрифт"); СтруктураСвойств.Вставить("ЭлементСвязиПоТипу"); СтруктураСвойств.Вставить("Значение"); ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ВысотаСпискаВыбора"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КартинкаКнопкиВыбора"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("КнопкаВыбора"); СтруктураСвойств.Вставить("КнопкаОткрытия"); СтруктураСвойств.Вставить("КнопкаОчистки"); СтруктураСвойств.Вставить("КнопкаРегулирования"); СтруктураСвойств.Вставить("СписокВыбора"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ШиринаСпискаВыбора"); СтруктураСвойств.Вставить("Значение"); ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ОтображатьКартинку"); СтруктураСвойств.Вставить("ОтображатьПометку"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ТекущаяСтрока"); ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда // **** Доделать СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("АвтоВводНовойСтроки"); СтруктураСвойств.Вставить("АвтоКонтекстноеМеню"); СтруктураСвойств.Вставить("АвтоОбновление"); СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию"); СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку"); СтруктураСвойств.Вставить("Дерево"); СтруктураСвойств.Вставить("ИерархическийПросмотр"); СтруктураСвойств.Вставить("ИзменятьАвтоОбновление"); СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр"); СтруктураСвойств.Вставить("ИзменятьСпособРедактирования"); СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя"); СтруктураСвойств.Вставить("ПериодАвтоОбновления"); СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки"); СтруктураСвойств.Вставить("РодительВерхнегоУровня"); СтруктураСвойств.Вставить("РежимВыбора"); СтруктураСвойств.Вставить("РежимВыделения"); СтруктураСвойств.Вставить("РежимВыделенияСтроки"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("СпособРедактирования"); СтруктураСвойств.Вставить("ТекущийРодитель"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("Колонки"); СтруктураСвойств.Вставить("НастройкаОтбора"); СтруктураСвойств.Вставить("НастройкаПорядка"); СтруктураСвойств.Вставить("ТекущаяКолонка"); СтруктураСвойств.Вставить("ТекущаяСтрока"); СтруктураСвойств.Вставить("ТекущиеДанные"); СтруктураСвойств.Вставить("ВыделенныеСтроки"); // **** //ВертикальнаяПолосаПрокрутки //ВертикальныеЛинии //Вывод //ВысотаПодвала //ВысотаШапки //ГоризонтальнаяПолосаПрокрутки //ГоризонтальныеЛинии //ИзменятьНастройкуКолонок //ИзменятьПозициюКолонок //ИзменятьПорядокСтрок //ИзменятьСоставСтрок //НачальноеОтображениеДерева //НачальноеОтображениеСписка //Подвал //ПропускатьПриВводе //РазрешитьНачалоПеретаскивания //РазрешитьПеретаскивание //РежимВводаСтрок //ФиксацияСлева //ФиксацияСправа //ЦветТекста //ЦветТекстаВыделения //ЦветТекстаКнопки //ЦветТекстаПодвала //ЦветТекстаШапки //ЦветФона //ЦветФонаВыделения //ЦветФонаКнопки //ЦветФонаПодвала //ЦветФонаЧередованияСтрок //ЦветФонаШапки //ЧередованиеЦветовСтрок //Шапка //Ширина //Шрифт //ШрифтПодвала //ШрифтШапки ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ОтображатьВыделение"); СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания"); СтруктураСвойств.Вставить("РазрешитьПеретаскивание"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("ЦветРамки"); ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда СтруктураСвойств.Вставить("ТриСостояния"); СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ПоложениеЗаголовка"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаПоля"); КонецЕсли; ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда СтруктураСвойств.Вставить("ТипКнопки"); СтруктураСвойств.Вставить("Действие"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("ИзменяетДанные"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КнопкаПоУмолчанию"); СтруктураСвойств.Вставить("Кнопки"); СтруктураСвойств.Вставить("Отображение"); СтруктураСвойств.Вставить("Подсказка"); СтруктураСвойств.Вставить("Пометка"); СтруктураСвойств.Вставить("ПорядокКнопок"); СтруктураСвойств.Вставить("Пояснение"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("Текст"); ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КартинкаЗаголовка"); СтруктураСвойств.Вставить("Раскрыта"); ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда СтруктураСвойств.Вставить("АвтоВысотаЯчейки"); СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного"); СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ВысотаЯчейки"); СтруктураСвойств.Вставить("ГиперСсылка"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ДанныеФлажка"); СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КартинкаПодвала"); СтруктураСвойств.Вставить("КартинкаШапки"); СтруктураСвойств.Вставить("КартинкиСтрок"); СтруктураСвойств.Вставить("ОтображатьВПодвале"); СтруктураСвойств.Вставить("ОтображатьВШапке"); СтруктураСвойств.Вставить("ОтображатьИерархию"); СтруктураСвойств.Вставить("ПодсказкаВШапке"); СтруктураСвойств.Вставить("Положение"); СтруктураСвойств.Вставить("ПропускатьПриВводе"); СтруктураСвойств.Вставить("РежимРедактирования"); СтруктураСвойств.Вставить("ТекстПодвала"); СтруктураСвойств.Вставить("ТекстШапки"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ТриСостоянияФлажка"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветТекстаПодвала"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветТекстаШапки"); СтруктураСвойств.Вставить("ЦветФонаПодвала"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ЦветФонаШапки"); СтруктураСвойств.Вставить("Ширина"); СтруктураСвойств.Вставить("ШрифтПодвала"); СтруктураСвойств.Вставить("ШрифтТекста"); СтруктураСвойств.Вставить("ШрифтШапки"); СтруктураСвойств.Вставить("ЭлементУправления"); СтруктураСвойств.Вставить("ИзменениеРазмера"); СтруктураСвойств.Вставить("ИзменятьВидимость"); СтруктураСвойств.Вставить("ИзменятьНастройку"); СтруктураСвойств.Вставить("ИзменятьПозицию"); ИначеЕсли ТипОбъекта = Тип("Форма") Тогда СтруктураСвойств.Вставить("АвтоЗаголовок"); СтруктураСвойств.Вставить("Высота"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ЗакрыватьПриВыборе"); СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца"); СтруктураСвойств.Вставить("ИзменениеРазмера"); СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна"); СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна"); СтруктураСвойств.Вставить("КартинкаЗаголовка"); СтруктураСвойств.Вставить("КлючУникальности"); СтруктураСвойств.Вставить("МножественныйВыбор"); СтруктураСвойств.Вставить("Модифицированность"); СтруктураСвойств.Вставить("НачальноеЗначениеВыбора"); СтруктураСвойств.Вставить("Панель"); СтруктураСвойств.Вставить("ПоведениеКлавишиEnter"); СтруктураСвойств.Вставить("ПоложениеОкна"); СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна"); СтруктураСвойств.Вставить("РазрешитьСоединятьОкно"); СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное"); СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное"); СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся"); СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное"); СтруктураСвойств.Вставить("РежимВыбора"); СтруктураСвойств.Вставить("РежимРабочегоСтола"); СтруктураСвойств.Вставить("СоединяемоеОкно"); СтруктураСвойств.Вставить("СостояниеОкна"); СтруктураСвойств.Вставить("СпособОтображенияОкна"); СтруктураСвойств.Вставить("Стиль"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("Ширина"); СтруктураСвойств.Вставить("ЭлементыФормы"); СтруктураСвойств.Вставить("ТекущийЭлемент"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("ВладелецФормы"); СтруктураСвойств.Вставить("МодальныйРежим"); КонецЕсли; ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПостроительОтчета") ИЛИ пОбъект = "ПостроительОтчета" Тогда СтруктураСвойств.Вставить("Текст"); СтруктураСвойств.Вставить("ДоступныеПоля"); СтруктураСвойств.Вставить("ВыбранныеПоля"); СтруктураСвойств.Вставить("ИзмеренияКолонки"); СтруктураСвойств.Вставить("ИзмеренияСтроки"); СтруктураСвойств.Вставить("Отбор"); СтруктураСвойств.Вставить("Параметры"); // не все ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета") ИЛИ пОбъект = "ИзмерениеПостроителяОтчета" Тогда СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("ТипИзмерения"); // не все #КонецЕсли ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПолеНастройки") ИЛИ пОбъект = "ПолеНастройки" Тогда СтруктураСвойств.Вставить("Измерение"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Отбор"); СтруктураСвойств.Вставить("Поле"); СтруктураСвойств.Вставить("Порядок"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("СписокЗначений"); СтруктураСвойств.Вставить("ТипЗначения"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("Поля"); СтруктураСвойств.Вставить("Родитель"); КонецЕсли; ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета") ИЛИ пОбъект = "ПолеПостроителяОтчета" Тогда СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ЭлементОтбора") ИЛИ пОбъект = "ЭлементОтбора" Тогда СтруктураСвойств.Вставить("ВидСравнения"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ЗначениеПо"); СтруктураСвойств.Вставить("ЗначениеС"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Использование"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("ТипЗначения"); КонецЕсли; Возврат СтруктураСвойств; КонецФункции // ПолучитьСтруктуруСвойствОбъектаЛкс() // Переустанавливает значения недоступных параметров из схемы (антибаг платформы). // // Параметры: // СхемаКомпоновкиДанных – СхемаКомпоновкиДанных; // КомпоновщикНастроек – КомпоновщикНастроекКомпоновкиДанных. // Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт #Если Сервер И Не Сервер Тогда КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; #КонецЕсли Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр); Если Истина И ПараметрСхемы <> Неопределено И ПараметрСхемы.ОграничениеИспользования Тогда //Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда // Попытка // ЗначениеПараметра.Значение = Вычислить(); // Исключение // КонецПопытки; //Иначе ЗначениеПараметра.Значение = ПараметрСхемы.Значение; //КонецЕсли; //ЗначениеПараметра.Использование = Истина; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт ПолеКоличества = "КоличествоСтрокАвто"; ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить(); ВычисляемоеПоле.Выражение = "1"; ВычисляемоеПоле.Заголовок = "Количество строк (авто)"; ВычисляемоеПоле.ПутьКДанным = ПолеКоличества; РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить(); РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества; РесурсКоличествоЗаписей.Выражение = "Сумма(1)"; КонецПроцедуры // Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений. // // Параметры: // СтруктураТаблиц – Структура – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь, ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт Если СхемаКомпоновкиДанных = Неопределено Тогда СхемаКомпоновкиДанных = СоздатьСхемуКомпоновкиЛкс(); КонецЕсли; Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл КолонкиНабора = КолонкиИсточникаДанныхЛкс(КлючИЗначение.Значение); СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КолонкиНабора, КлючИЗначение.Ключ, СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей); КонецЦикла; Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных); КонецЕсли; Возврат СхемаКомпоновкиДанных; КонецФункции Функция СоздатьСхемуКомпоновкиЛкс() Экспорт СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных); Возврат СхемаКомпоновкиДанных; КонецФункции Функция КолонкиИсточникаДанныхЛкс(Знач ИсточникДанных) Если Ложь Или ТипЗнч(ИсточникДанных) = Тип("ДеревоЗначений") Или ТипЗнч(ИсточникДанных) = Тип("ТаблицаЗначений") Тогда КолонкиНабора = ИсточникДанных.Колонки; Иначе КолонкиНабора = ИсточникДанных.ВыгрузитьКолонки().Колонки; КонецЕсли; Возврат КолонкиНабора; КонецФункции // СоздатьСхемуПоТаблицамЗначенийЛкс() // Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки. // // Параметры: // ПоляНастройки – ПоляНастройки – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "Основной") Экспорт Если СхемаКомпоновкиДанных = Неопределено Тогда СхемаКомпоновкиДанных = СоздатьСхемуКомпоновкиЛкс(); КонецЕсли; #Если Сервер И Не Сервер Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; #КонецЕсли НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных")); НаборДанных.Имя = ИмяНабора; НаборДанных.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя; НаборДанных.ИмяОбъекта = ИмяНабора; Для Каждого ПолеНастройки Из ПоляНастройки Цикл Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); Поле.ПутьКДанным = ПолеНастройки.Имя; Поле.Поле = ПолеНастройки.ПутьКДанным; Поле.Заголовок = ПолеНастройки.Представление; Поле.ТипЗначения = ПолеНастройки.ТипЗначения; ОграничениеИспользования = Поле.ОграничениеИспользования; ОграничениеИспользования.Поле = Не ПолеНастройки.Поле; ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор; ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок; ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение; ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0; ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов; ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения; КонецЦикла; Возврат СхемаКомпоновкиДанных; КонецФункции // СоздатьСхемуПоПолямНастройкиЛкс() // Параметры: // Поле - // Доступность - // ПрименитьГруппировка - // ПрименитьПоле - // ПрименитьПорядок - // ПрименитьУсловие - // Возвращаемое значение: // Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач ПолеИлиОграничениеИспользования, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина, Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт МассивГруппОграничений = Новый Массив; Если ТипЗнч(ПолеИлиОграничениеИспользования) = Тип("ОграничениеИспользованияПоляСхемыКомпоновкиДанных") Тогда МассивГруппОграничений.Добавить(ПолеИлиОграничениеИспользования); Иначе Поле = ПолеИлиОграничениеИспользования; МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования); Попытка МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов); Исключение КонецПопытки; КонецЕсли; Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл Если ПрименитьГруппировка Тогда ОграничениеИспользования.Группировка = Ограничивать; КонецЕсли; Если ПрименитьПоле Тогда ОграничениеИспользования.Поле = Ограничивать; КонецЕсли; Если ПрименитьПорядок Тогда ОграничениеИспользования.Порядок = Ограничивать; КонецЕсли; Если ПрименитьУсловие Тогда ОграничениеИспользования.Условие = Ограничивать; КонецЕсли; КонецЦикла; КонецФункции // Функция добавляет в схему компоновки источник данных с типом "Local" Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить(); ИсточникДанных.Имя = "ИсточникДанных1"; ИсточникДанных.ТипИсточникаДанных = "Local"; Возврат ИсточникДанных; КонецФункции // Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "Основной") Экспорт НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")); НаборДанных.Имя = ИмяНабораДанных; НаборДанных.ИсточникДанных = ИсточникДанных.Имя; Возврат НаборДанных; КонецФункции // Конструктор массива через Параметры. // // Параметры: // *п... – Произвольный – элементы массива. // // Возвращаемое значение: // Массив - полученный массив. // Функция БыстрыйМассивЛкс( п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено, п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено, п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено, п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено ) Экспорт Перем М; М = Новый Массив(); Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли; Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли; Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли; Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли; Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли; Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли; Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли; Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли; Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли; Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли; Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли; Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли; Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли; Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли; Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли; Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли; Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли; Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли; Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли; Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли; Возврат М; КонецФункции // БыстрыйМассивЛкс() Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт Если Ложь Или ТипЗнч(Значение) = Тип("ТабличныйДокумент") Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент") Тогда Документ = Значение; Иначе Документ = Новый ТекстовыйДокумент; Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда Значение = Значение.Получить(); КонецЕсли; Если ТипЗнч(Значение) <> Тип("Строка") И ПолучатьXMLПредставлениеДляНеизвестныхТипов Тогда Представление = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение); Представление = ДекодироватьТекстИзXMLЛкс(Представление); Иначе Представление = Значение; КонецЕсли; Документ.УстановитьТекст(Представление); КонецЕсли; Путь = ПолучитьИмяВременногоФайла(Название); Документ.Записать(Путь); Возврат Путь; КонецФункции // Получает строку путем отсечения заданного числа последних символов. // // Параметры: // пСтрока – Строка – исходная; // пДлинаКонца - Число, *1 - количество отсекаемых символов; // // Возвращаемое значение: // – Строка. // Функция СтрокаБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт Если СтрДлина(пСтрока) < пДлинаКонца Тогда Возврат ""; Иначе Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца); КонецЕсли; КонецФункции Функция СтрокаБезПоследнегоФрагментаЛкс(Знач Строка, Знач Разделитель = ".") Экспорт Фрагменты = СтрРазделитьЛкс(Строка); #Если Сервер И Не Сервер Тогда Фрагменты = Новый Массив; #КонецЕсли Фрагменты.Удалить(Фрагменты.ВГраница()); Результат = СтрСоединитьЛкс(Фрагменты, Разделитель); Возврат Результат; КонецФункции // Получает значения параметров из строки. // // Параметры: // СтрокаПараметров - Строка - строка, содержащая параметры, каждый из которых представляет собой // фрагмент вида <Имя параметра>=<Значение>, где: // Имя параметра - имя параметра; // Значение - его значение. // Фрагменты отделяются друг от друга символами ';'. // Если значение содержит пробельные символы, то оно должно быть заключено в двойные // кавычки ("). // Например: // "File=""c:\InfoBases\Trade""; Usr=""Director"";" // Разделитель - Строка - символ, которым фрагменты отделяются друг от друга. // // Возвращаемое значение: // Структура - значения параметров, где ключ - имя параметра, значение - значение параметра. // // Пример: // Результат = СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки("File=""c:\InfoBases\Trade""; Usr=""Director"";""", ";"); // - вернет структуру: // ключ "File" и значение "c:\InfoBases\Trade" // ключ "Usr" и значение "Director". // Функция ЗначенияПараметровИзСтрокиЛкс(Знач СтрокаПараметров, Знач Разделитель = ";") Экспорт Результат = Новый Структура; ОписаниеПараметра = ""; НайденоНачалоСтроки = Ложь; НомерПоследнегоСимвола = СтрДлина(СтрокаПараметров); Для НомерСимвола = 1 По НомерПоследнегоСимвола Цикл Символ = Сред(СтрокаПараметров, НомерСимвола, 1); Если Символ = """" Тогда НайденоНачалоСтроки = Не НайденоНачалоСтроки; КонецЕсли; Если Символ <> Разделитель Или НайденоНачалоСтроки Тогда ОписаниеПараметра = ОписаниеПараметра + Символ; КонецЕсли; Если Символ = Разделитель И Не НайденоНачалоСтроки Или НомерСимвола = НомерПоследнегоСимвола Тогда Позиция = Найти(ОписаниеПараметра, "="); Если Позиция > 0 Тогда ИмяПараметра = СокрЛП(Лев(ОписаниеПараметра, Позиция - 1)); ЗначениеПараметра = СокрЛП(Сред(ОписаниеПараметра, Позиция + 1)); ЗначениеПараметра = СтрокаИзВыраженияВстроенногоЯзыкаЛкс(ЗначениеПараметра); Результат.Вставить(ИмяПараметра, ЗначениеПараметра); КонецЕсли; ОписаниеПараметра = ""; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // Получает представление из идентификатора по правилу // "Дебиторка_По_контрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства". // После символа "_" регистр не меняется, а сам символ заменяется на " ". // // Параметры: // ИсходнаяСтрока – Строка – идентификатор. // // Возвращаемое значение: // – Строка – представление. // Функция ПолучитьПредставлениеИзИдентификатораЛкс(ИсходнаяСтрока) Экспорт СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1); Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1); ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1); СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1); ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1); Если ТекущийСимвол = "_" Тогда СтрокаВозврата = СтрокаВозврата + " "; Продолжить; ИначеЕсли Истина И ВРЕГ(ТекущийСимвол) = ТекущийСимвол // В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку. //И ПредыдущийСимвол <> " " Тогда Если Ложь ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол ИЛИ (Истина И ПредыдущийСимвол <> "_" И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол И ВРЕГ(СледующийСимвол) <> СледующийСимвол) Тогда СтрокаВозврата = СтрокаВозврата + " "; Если Ложь ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол Тогда ТекущийСимвол = НРЕГ(ТекущийСимвол); КонецЕсли; КонецЕсли; КонецЕсли; СтрокаВозврата = СтрокаВозврата + ТекущийСимвол; КонецЦикла; Возврат СтрокаВозврата; КонецФункции // ПолучитьПредставлениеИзИдентификатораЛкс() // Преобразует строку для использования в регулярных выражениях. // Производится // // Параметры: // пТекст – Строка. // // Возвращаемое значение: // Строка – для вставки в регулярные выражения. // Функция ПреобразоватьТекстДляРегулярныхВыраженийЛкс(пТекст) Экспорт Текст = пТекст; СтрокаСлужебныхСимволов = "\[]^$()?*+.|"; // "\" должен быть первым Для Счетчик = 1 По СтрДлина(СтрокаСлужебныхСимволов) Цикл СпецСимвол = Сред(СтрокаСлужебныхСимволов, Счетчик, 1); Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол); КонецЦикла; Возврат Текст; КонецФункции // ПреобразоватьТекстДляРегулярныхВыраженийЛкс() // Шаблон для вызова //Вхождения = ирОбщий.НайтиРегулярноеВыражениеЛкс(Текст, Шаблон); //#Если Сервер И Не Сервер Тогда // Вхождения = Обработки.ирПлатформа.Создать().ВхожденияРегулярногоВыражения; //#КонецЕсли //Для каждого Вхождение Из Вхождения Цикл //КонецЦикла; Функция НайтиРегулярноеВыражениеЛкс(Знач Текст, Знач Шаблон, Знач ИменаПодгрупп = "", Знач ИскатьВсеВхождения = Истина, Знач ИгнорироватьРегистрБукв = Истина, Знач МногострочныйРежим = Ложь, ВызыватьИсключение = Истина, БезПодгрупп = Ложь) Экспорт //Вычислитель = Новый COMОбъект("VBScript.RegExp"); Вычислитель = ирКэш.ВычислительРегулярныхВыраженийЛкс(); Вычислитель.IgnoreCase = ИгнорироватьРегистрБукв; Вычислитель.Global = ИскатьВсеВхождения; Вычислитель.Multiline = МногострочныйРежим; Вычислитель.Pattern = Шаблон; Попытка Вхождения = Вычислитель.Execute(Текст); Исключение Если Не ВызыватьИсключение Тогда Возврат ОписаниеОшибки(); Иначе ВызватьИсключение; КонецЕсли; КонецПопытки; Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("ТекстВхождения"); Результат.Колонки.Добавить("ПозицияВхождения"); Результат.Колонки.Добавить("ДлинаВхождения"); Результат.Колонки.Добавить("Подгруппы"); #Если Сервер И Не Сервер Тогда Результат = Обработки.ирПлатформа.Создать().ВхожденияРегулярногоВыражения; #КонецЕсли ИндексПервойКолонкиПодгруппы = Результат.Колонки.Количество(); Если Не БезПодгрупп Тогда ИменаПодгруппМассив = СтрРазделитьЛкс(ИменаПодгрупп, ",", Истина, Ложь); Для Каждого ИмяПодгруппы Из ИменаПодгруппМассив Цикл Если Результат.Колонки.Найти(ИмяПодгруппы) <> Неопределено Тогда ВызватьИсключение "Имя """ + ИмяПодгруппы + """ добавляемой колонки подгруппы результатов поиска не уникально"; КонецЕсли; Результат.Колонки.Добавить(ИмяПодгруппы); КонецЦикла; КоличествоИменПодгрупп = ИменаПодгруппМассив.Количество(); КонецЕсли; ДобавитьКолонкиПодгрупп = КоличествоИменПодгрупп = 0; Для Каждого Вхождение Из Вхождения Цикл //Если Результат.Количество() = 0 Тогда // Для ИндексПодгруппы = ИменаПодгруппМассив.Количество() По Вхождение.SubMatches.Count - 1 Цикл // Результат.Колонки.Добавить("Подгруппа" + XMLСтрока(ИндексПодгруппы)); // КонецЦикла; //КонецЕсли; СтрокаРезультата = Результат.Добавить(); СтрокаРезультата.ТекстВхождения = Вхождение.Value; СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex; СтрокаРезультата.ДлинаВхождения = Вхождение.Length; Если Не БезПодгрупп Тогда Подгруппы = Новый Массив; Для ИндексПодгруппы = 0 По Вхождение.SubMatches.Count - 1 Цикл Если ДобавитьКолонкиПодгрупп Тогда Результат.Колонки.Добавить("Подгруппа" + ИндексПодгруппы); КоличествоИменПодгрупп = КоличествоИменПодгрупп + 1; КонецЕсли; Если ИндексПодгруппы < КоличествоИменПодгрупп Тогда СтрокаРезультата[ИндексПервойКолонкиПодгруппы + ИндексПодгруппы] = Вхождение.SubMatches(ИндексПодгруппы); КонецЕсли; Подгруппы.Добавить(Вхождение.SubMatches(ИндексПодгруппы)); КонецЦикла; СтрокаРезультата.Подгруппы = Подгруппы; Если ДобавитьКолонкиПодгрупп Тогда ДобавитьКолонкиПодгрупп = Ложь; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // Преобразует строку для правого операнда оператора ПОДОБНО языка запросов. // // Параметры: // пТекст – Строка. // // Возвращаемое значение: // Строка. // Функция ПреобразоватьСтрокуДляПОДОБНОЛкс(Знач Результат, Спецсимвол = "~") Экспорт ЗарезервированныеСимволы = Новый Массив; ЗарезервированныеСимволы.Добавить("~"); //ЗарезервированныеСимволы.Добавить("%"); ЗарезервированныеСимволы.Добавить("_"); ЗарезервированныеСимволы.Добавить("["); ЗарезервированныеСимволы.Добавить("-"); ЗарезервированныеСимволы.Добавить("]"); Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол); КонецЦикла; Возврат Результат; КонецФункции // ПреобразоватьСтрокуДляПОДОБНОЛкс() // Получает строку путем повтора переданной строки заданное количество раз. // // Параметры: // СтрокаДляПовтора – Строка; // ЧислоПовторов – Число. // // Возвращаемое значение: // Строка. // Функция СтрокаПовторомЛкс(СтрокаДляПовтора, ЧислоПовторов) Экспорт Результат = ""; Для Счетчик = 1 По ЧислоПовторов Цикл Результат = Результат + СтрокаДляПовтора; КонецЦикла; Возврат Результат; КонецФункции // СтрокаПовторомЛкс() // Обновляет в строковом свойстве объекта часть, которая следует за маркером. // Если маркер не находится, то он добавляется. // // Параметры: // пОбъект – Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке; // *пИмяСвойства – Строка, *"" – имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке; // пНовыйТекст - Строка - новая часть, которая следует за разделителем; // *пМаркер - Строка, *"," - маркер. // Процедура ОбновитьТекстПослеМаркераВСтрокеЛкс(пОбъектИлиСвойство, Знач пИмяСвойства = "", Знач НовыйТекст, Знач пМаркер = ", ", Знач ОбрезатьПосле = 100) Экспорт Если пИмяСвойства <> "" Тогда СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства]; Иначе СтараяСтрока = пОбъектИлиСвойство; КонецЕсли; ПозицияРазделителя = Найти(СтараяСтрока, пМаркер); Если ПозицияРазделителя = 0 Тогда ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1; КонецЕсли; Если ЗначениеЗаполнено(ОбрезатьПосле) Тогда НовыйТекст = ПредставлениеЗначенияСОграничениемДлиныЛкс(НовыйТекст, ОбрезатьПосле); КонецЕсли; НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + НовыйТекст; Если пИмяСвойства <> "" Тогда ПрисвоитьЕслиНеРавноЛкс(пОбъектИлиСвойство[пИмяСвойства], НоваяСтрока); Иначе ПрисвоитьЕслиНеРавноЛкс(пОбъектИлиСвойство, НоваяСтрока); КонецЕсли; КонецПроцедуры // Результат - Строка - длинна не более ПорогДлины Функция ПредставлениеЗначенияСОграничениемДлиныЛкс(Знач Значение, Знач ПорогДлины = 100, МаркерОтрезки = "...") Экспорт ПредставлениеЗначения = "" + Значение; Если СтрДлина(ПредставлениеЗначения) > ПорогДлины Тогда ПредставлениеЗначения = Лев(ПредставлениеЗначения, ПорогДлины - СтрДлина(МаркерОтрезки)) + МаркерОтрезки; КонецЕсли; Возврат ПредставлениеЗначения; КонецФункции // Заменяет текущее выделение в поле текстового документа новым текстом. // После этого устанавливает выделение на вставленный фрагмент. // // Параметры: // ПолеТекстовогоДокумента - ПолеТекстовогоДокумента; // НовыйТекст – Строка. // Процедура ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт Перем НачальнаяСтрока; Перем НачальнаяКолонка; Перем КонечнаяСтрока; Перем КонечнаяКолонка; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, НачальнаяСтрока, НачальнаяКолонка); НачальнаяГраница = СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) + 1; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст; КонечнаяГраница = НачальнаяГраница + СтрДлина(НовыйТекст); Если КонечнаяГраница > СтрДлина(ПолеТекстовогоДокумента.ПолучитьТекст()) Тогда КонечнаяГраница = КонечнаяГраница - 1; КонецЕсли; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяГраница, КонечнаяГраница); КонецПроцедуры // ЗаменитьВыделенныйТекстСохраняяГраницыВыделенияЛкс() // Взято отсюда http://infostart.ru/public/100845/ // ИсходныеДанные - <примитивное значение>, ДвоичныеДАнные, ХранилищеЗначения // // Возвращаемое значение // Число Функция ВычислитьХэшЛкс(ИсходныеДанные, Хэш=5381, М=33, Разрядность=18446744073709551616) Экспорт // приведем к строке Если ТипЗнч(ИсходныеДанные) = Тип("ДвоичныеДанные") Тогда СтрокаДляКодирования = Base64Строка(ИсходныеДанные); ИначеЕсли ТипЗнч(ИсходныеДанные) = Тип("ХранилищеЗначения") Тогда СтрокаДляКодирования = ЗначениеВСтрокуВнутр(ИсходныеДанные); Иначе СтрокаДляКодирования = Строка(ИсходныеДанные); КонецЕсли; ДлинаБлока = 11; НачПозиция = 1; ДлинаСтроки = СтрДлина(СтрокаДляКодирования); Пока НачПозиция <= ДлинаСтроки Цикл СтрокаБлока = Сред(СтрокаДляКодирования, НачПозиция, ДлинаБлока); ДлинаПодстроки = СтрДлина(СтрокаБлока); Если ДлинаПодстроки = ДлинаБлока Тогда Хэш = ((((((((((( Хэш*М + КодСимвола(СтрокаБлока, 1))*М + КодСимвола(СтрокаБлока, 2))*М + КодСимвола(СтрокаБлока, 3))*М + КодСимвола(СтрокаБлока, 4))*М + КодСимвола(СтрокаБлока, 5))*М + КодСимвола(СтрокаБлока, 6))*М + КодСимвола(СтрокаБлока, 7))*М + КодСимвола(СтрокаБлока, 8))*М + КодСимвола(СтрокаБлока, 9))*М + КодСимвола(СтрокаБлока, 10))*М + КодСимвола(СтрокаБлока, 11)) Иначе Для к = 1 По ДлинаПодстроки Цикл Хэш = М * Хэш + КодСимвола(СтрокаБлока, к) КонецЦикла КонецЕсли; Хэш = Хэш % Разрядность; НачПозиция = НачПозиция + ДлинаБлока КонецЦикла; Возврат Хэш; КонецФункции Функция ПолучитьГУИДИнверсныйИзПрямогоЛкс(ПрямойГУИД) Экспорт С = СтрЗаменить(ПрямойГУИД, "-", ""); Возврат Сред(С,17,16)+Сред(С,13,4)+Сред(С,9,4)+Сред(С,1,4)+Сред(С,5,4); КонецФункции Функция ПолучитьГУИДПрямойИзИнверсногоЛкс(ИнверсныйГУИД) Экспорт С = ИнверсныйГУИД; Возврат Сред(С,25,8)+"-"+Сред(С,21,4)+"-"+Сред(С,17,4)+"-"+Сред(С,1,4)+"-"+Сред(С,5,12); КонецФункции Функция ОписаниеТиповПланОбменаСсылкаЛкс(ВключаяТипыРасширений = Истина) Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку( " | cc:ExchangePlanRef |"); Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Если ВключаяТипыРасширений И ирКэш.НомерРежимаСовместимостиЛкс() >= 803011 И ПравоДоступа("АдминистрированиеРасширенийКонфигурации", Метаданные) Тогда ТипыРасширений = ирКэш.ТипыРасширенийКонфигурацииЛкс("ПланОбмена"); Результат = Новый ОписаниеТипов(Результат, ТипыРасширений); КонецЕсли; Возврат Результат; КонецФункции Функция ОписаниеТиповВсеСсылкиЛкс(ВключаяТипыРасширений = Истина) Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку( " | cc:AnyRef |"); Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Если ВключаяТипыРасширений И ирКэш.НомерРежимаСовместимостиЛкс() >= 803011 И ПравоДоступа("АдминистрированиеРасширенийКонфигурации", Метаданные) Тогда ТипыРасширений = ирКэш.ТипыРасширенийКонфигурацииЛкс(); Результат = Новый ОписаниеТипов(Результат, ТипыРасширений); КонецЕсли; Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803001 Тогда Для Каждого ВнешнийИсточникДанных Из Вычислить("ВнешниеИсточникиДанных") Цикл // Для компиляции на платформе 8.2.13- Результат = Новый ОписаниеТипов(Результат, ВнешнийИсточникДанных.Таблицы.ТипВсеСсылки().Типы()); КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции Функция ОписаниеТиповВсеРедактируемыеТипыЛкс() Экспорт ОписаниеТипов = ОписаниеТиповВсеСсылкиЛкс(); ДополнительныеТипы = Новый Массив(); ДополнительныеТипы.Добавить(Тип("Строка")); ДополнительныеТипы.Добавить(Тип("Число")); ДополнительныеТипы.Добавить(Тип("Дата")); ДополнительныеТипы.Добавить(Тип("Булево")); ДополнительныеТипы.Добавить(Тип("СписокЗначений")); ДополнительныеТипы.Добавить(Тип("Массив")); ДополнительныеТипы.Добавить(Тип("ОписаниеТипов")); ДополнительныеТипы.Добавить(Тип("МоментВремени")); ДополнительныеТипы.Добавить(Тип("Граница")); ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала")); ДополнительныеТипы.Добавить(Тип("СтандартныйПериод")); ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений")); ДополнительныеТипы.Добавить(Тип("ДеревоЗначений")); ДополнительныеТипы.Добавить(Тип("ТабличныйДокумент")); ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления")); ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии")); ДополнительныеТипы.Добавить(Тип("ВидСчета")); ДополнительныеТипы.Добавить(Тип("Тип")); ДополнительныеТипы.Добавить(Тип("Null")); ДополнительныеТипы.Добавить(Тип("ПолеКомпоновкиДанных")); //ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация //ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор")); ДополнительныеТипы.Добавить(Тип("ХранилищеЗначения")); ДополнительныеТипы.Добавить(Тип("ДвоичныеДанные")); // Из-за бага платформы отключены //ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления")); //ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления")); КвалификаторыЧисла = Новый КвалификаторыЧисла; //(25, 5); // Важно! ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла); Возврат ОписаниеТипов; КонецФункции Функция ЭтоОписаниеТиповПростогоСсылочногоТипаЛкс(Знач ОписаниеТипов, БезУчетаNULL = Истина) Экспорт Если БезУчетаNULL Тогда ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, , "NULL"); КонецЕсли; ЭтоОписаниеТиповПростогоСсылочногоТипа = ОписаниеТипов.Типы().Количество() = 1 И ирОбщий.ЛиТипСсылкиБДЛкс(ОписаниеТипов.Типы()[0]); Возврат ЭтоОписаниеТиповПростогоСсылочногоТипа; КонецФункции Функция РежимСовместимостиМеньше8_3_4Лкс() Экспорт Возврат ирКэш.НомерРежимаСовместимостиЛкс() < 803004; КонецФункции Процедура ДобавитьКолонкуЕслиНетЛкс(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено, Заголовок = Неопределено, Ширина = 0) Экспорт Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда Возврат; КонецЕсли; КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина); КонецПроцедуры // ДобавитьКолонкуЕслиНетЛкс() Функция Дерево_ПутьМассивомЛкс(СтрокаДерева, ИмяКлючевойКолонки = "") Экспорт Координаты = Новый Массив(); Родитель = СтрокаДерева; Пока Родитель <> Неопределено Цикл Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда Координата = Родитель[ИмяКлючевойКолонки]; Иначе Координата = ПолучитьРодителяСтрокиДереваЛкс(Родитель).Строки.Индекс(Родитель); КонецЕсли; Координаты.Вставить(0, Координата); Родитель = Родитель.Родитель; КонецЦикла; Возврат Координаты; КонецФункции Функция Дерево_НайтиПоПутиМассивомЛкс(Дерево, Координаты, ИмяКлючевойКолонки = "") Экспорт #Если Сервер И Не Сервер Тогда Дерево = Новый ДеревоЗначений; #КонецЕсли СтрокаДерева = Дерево; Для Каждого Координата Из Координаты Цикл Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда СтрокаДерева = СтрокаДерева.Строки.Найти(Координата, ИмяКлючевойКолонки); Иначе СтрокаДерева = СтрокаДерева.Строки[Координата]; КонецЕсли; КонецЦикла; Возврат СтрокаДерева; КонецФункции // Результат - Массив Функция ПолучитьАдресСтрокиДереваЗначенийЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт КлючиУровней = Новый Массив(); ТекущаяСтрока = СтрокаДерева; Пока ТекущаяСтрока <> Неопределено Цикл КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]); ТекущаяСтрока = ТекущаяСтрока.Родитель; КонецЦикла; Возврат КлючиУровней; КонецФункции // Результат - Массив Функция ПолучитьАдресСтрокиДереваФормыЛкс(Знач СтрокаДерева, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт КлючиУровней = Новый Массив(); ТекущаяСтрока = СтрокаДерева; Пока ТекущаяСтрока <> Неопределено Цикл КлючиУровней.Вставить(0, ТекущаяСтрока[ИмяКлючевойКолонки]); ТекущаяСтрока = ТекущаяСтрока.ПолучитьРодителя(); КонецЦикла; Возврат КлючиУровней; КонецФункции // Параметры: // ИмяКолонки - Строка - если задать пустое значение, то будет использован индекс строк дерева // ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее Функция Дерево_ПутьСтрокойЛкс(СтрокаДерева, ИмяКолонки = "Имя", ИгнорироватьПростойПервыйУровень = Ложь, Разделитель = ".", Дерево = Неопределено) Экспорт Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Родитель = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево); Если Ложь Или ТипЗнч(Родитель) = Тип("ДеревоЗначений") Или ТипЗнч(Родитель) = Тип("СтрокаДереваЗначений") Тогда Результат = Родитель.Строки.Индекс(СтрокаДерева); ИначеЕсли Ложь Или ТипЗнч(Родитель) = Тип("ОтборКомпоновкиДанных") Или ТипЗнч(Родитель) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Или ТипЗнч(Родитель) = Тип("ДоступныеПоляКомпоновкиДанных") Или ТипЗнч(Родитель) = Тип("ДоступноеПолеКомпоновкиДанных") Или ТипЗнч(Родитель) = Тип("ДоступноеПолеОтбораКомпоновкиДанных") Тогда Результат = Родитель.Элементы.Индекс(СтрокаДерева); ИначеЕсли Ложь Или ТипЗнч(Родитель) = Тип("ДанныеФормыДерево") Или ТипЗнч(Родитель) = Тип("ДанныеФормыЭлементДерева") Тогда Результат = Родитель.ПолучитьЭлементы().Индекс(СтрокаДерева); Иначе ВызватьИсключение "Неподдерживаемый тип элемента дерева - " + ТипЗнч(Родитель); КонецЕсли; Иначе Результат = СтрокаДерева[ИмяКолонки]; КонецЕсли; Попытка Родитель = СтрокаДерева.Родитель; Исключение Родитель = СтрокаДерева.ПолучитьРодителя(); КонецПопытки; Если Родитель = Неопределено Тогда Если Истина И ИгнорироватьПростойПервыйУровень И СтрокаДерева.Владелец().Строки.Количество() = 1 Тогда Результат = Неопределено; КонецЕсли; Иначе РезультатСверху = Дерево_ПутьСтрокойЛкс(Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень, Разделитель, Дерево); Если РезультатСверху <> Неопределено Тогда Результат = РезультатСверху + Разделитель + Результат; КонецЕсли; КонецЕсли; Возврат XMLСтрока(Результат); КонецФункции // Параметры: // ИмяКолонки - Строка - если задать пустое значение, то будет использован индекс строк дерева // ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее Функция Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева, ИмяКолонки = "Имя", Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт Если Истина И ИгнорироватьПростойПервыйУровень И ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений") И СтрокаДерева.Строки.Количество() = 1 Тогда Возврат Дерево_НайтиПоПутиСтрокойЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Сред(Путь, 2)); КонецЕсли; ТекущийУровень = ПервыйФрагментЛкс(Путь); Если Не ЗначениеЗаполнено(ТекущийУровень) Тогда Возврат СтрокаДерева; КонецЕсли; ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2); Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ЗначениеИндекса = Число(ТекущийУровень); Если Ложь Или ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений") Или ТипЗнч(СтрокаДерева) = Тип("СтрокаДереваЗначений") Тогда Если СтрокаДерева.Строки.Количество() > ЗначениеИндекса Тогда ТекущаяСтрока = СтрокаДерева.Строки[ЗначениеИндекса]; КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(СтрокаДерева) = Тип("ОтборКомпоновкиДанных") Или ТипЗнч(СтрокаДерева) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Или ТипЗнч(СтрокаДерева) = Тип("ДоступныеПоляКомпоновкиДанных") Или ТипЗнч(СтрокаДерева) = Тип("ДоступноеПолеКомпоновкиДанных") Или ТипЗнч(СтрокаДерева) = Тип("ДоступноеПолеОтбораКомпоновкиДанных") Тогда Если СтрокаДерева.Элементы.Количество() > ЗначениеИндекса Тогда ТекущаяСтрока = СтрокаДерева.Элементы[ЗначениеИндекса]; КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(СтрокаДерева) = Тип("ДанныеФормыДерево") Или ТипЗнч(СтрокаДерева) = Тип("ДанныеФормыЭлементДерева") Тогда Если СтрокаДерева.ПолучитьЭлементы().Количество() > ЗначениеИндекса Тогда ТекущаяСтрока = СтрокаДерева.ПолучитьЭлементы()[ЗначениеИндекса]; КонецЕсли; Иначе ВызватьИсключение "Неподдерживаемый тип элемента дерева - " + ТипЗнч(СтрокаДерева); КонецЕсли; Иначе ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки); КонецЕсли; Если ТекущаяСтрока <> Неопределено Тогда Возврат Дерево_НайтиПоПутиСтрокойЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть); Иначе Возврат СтрокаДерева; КонецЕсли; КонецФункции // Дерево_НайтиПоПутиСтрокойЛкс() // Процедура заполняет колонку дерева значением. // // Параметры // ЭлементДЗ - ДеревоЗначений; // ИмяКолонки - Строка; // ЗначениеКолонки - Произвольный. // Процедура ЗаполнитьКолонкуДереваЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки; ЗаполнитьКолонкуДереваЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки); КонецЦикла; КонецПроцедуры // ЗаполнитьКолонкуДереваЛкс // Процедура удаляет все строки дерева со значением в колонке. // // Параметры // ЭлементДЗ - ДеревоЗначений; // ИмяКолонки - Строка; // ЗначениеКолонки - Произвольный. // Процедура УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт НачальноеКоличество = ЭлементДЗ.Строки.Количество(); Для Счетчик = 1 По НачальноеКоличество Цикл ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик]; Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока); Иначе УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки); КонецЕсли; КонецЦикла; КонецПроцедуры // УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция ДекодироватьТекстИзXMLЛкс(Текст) Экспорт //{ Заменяем символы, критичные для XML //Текст = СтрЗаменить(Текст,"&","&"); //Текст = СтрЗаменить(Текст,"<","<"); //Текст = СтрЗаменить(Текст,">",">"); ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку("<ф>" + Текст + ""); ЧтениеXML.Прочитать(); ЧтениеXML.Прочитать(); Результат = ЧтениеXML.Значение; Возврат Результат; КонецФункции // ПолучитьТекстИзXMLЛкс() Функция КодироватьТекстВXMLЛкс(Текст) Экспорт Если Текст = "" Тогда Возврат ""; КонецЕсли; //{ Заменяем символы, критичные для XML //выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&"); //выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","<"); //выхХМЛТело = СтрЗаменить(выхХМЛТело,">",">"); ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(""); ЗаписьXML.ЗаписатьНачалоЭлемента("ф"); ЗаписьXML.ЗаписатьТекст(Текст); ЗаписьXML.ЗаписатьКонецЭлемента(); Результат = СтрокаМеждуМаркерамиЛкс(ЗаписьXML.Закрыть(), "<ф>", "", Ложь); Возврат Результат; КонецФункции Функция СтрокаВнутрВХМЛТелоЛкс(вхСтрока, выхХМЛТело = Неопределено) Экспорт //{ Получение одной длинной строки выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,""); выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,""); //} выхХМЛТело = КодироватьТекстВXMLЛкс(выхХМЛТело); //{ Замена одинарных символов выхХМЛТело = СтрЗаменить(выхХМЛТело,",",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"{",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"}",""); //} //{ Удаляем лишние блоки и выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""); //} //{ Добавляем перенос строки к и к для удобства поиска различий выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС); выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС); //} Возврат выхХМЛТело; КонецФункции Функция НоваяВКОбщаяЛкс() Экспорт Попытка ВК = Новый ("AddIn.ирОбщая.AddIn"); Исключение Это64битныйПроцесс = ирКэш.Это64битныйПроцессЛкс(); ИмяМакета = "ВК"; Если Это64битныйПроцесс Тогда ИмяМакета = ИмяМакета + "64"; Иначе ИмяМакета = ИмяМакета + "32"; КонецЕсли; Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ДвоичныеДанные = ирПортативный.ПолучитьМакет(ИмяМакета); Иначе ДвоичныеДанные = Обработки.ирПортативный.ПолучитьМакет(ИмяМакета); КонецЕсли; АдресКомпоненты = ПолучитьИмяВременногоФайла("dll"); ДвоичныеДанные.Записать(АдресКомпоненты); //АдресКомпоненты = "D:\VC\Native_Comp_RDT\binWin32\AddInNative.dll"; // Для отладки Результат = ПодключитьВнешнююКомпоненту(АдресКомпоненты, "ирОбщая", ТипВнешнейКомпоненты.Native); Если Не Результат Тогда ВызватьИсключение "Не удалось подключить внешнюю компоненту Общая"; КонецЕсли; ВК = Новый ("AddIn.ирОбщая.AddIn"); КонецПопытки; Возврат ВК; КонецФункции // Получает структуру для индикации прогресса цикла. // // Параметры: // КоличествоПроходов – Число - максимальное значение счетчика; // ПредставлениеПроцесса – Строка, *"Выполнено" – отображаемое название процесса; // КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора; // ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса; // РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс. // МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений, // эта реализация не поддерживает дробные значения; // ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации // // Возвращаемое значение: // Структура - которую потом нужно будет передавать в метод ОбработатьИндикаторЛкс. // Функция ПолучитьИндикаторПроцессаЛкс(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение", Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1, ТаблицаИндикаторов = Неопределено) Экспорт ирПлатформа = ирКэш.Получить(); Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда //#Если Клиент Тогда // СостояниеЛкс(ПредставлениеПроцесса + "..."); //#КонецЕсли КоличествоПроходов = 0; КонецЕсли; КоличествоПроходов = Цел(КоличествоПроходов); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если ТаблицаИндикаторов.Количество() = 0 Тогда #Если Клиент Тогда ПодключитьГлобальныйОбработчикОжиданияЛкс("ОсвободитьВсеИндикаторыПроцессовОтложенноЛкс"); #КонецЕсли ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов"; КонецЕсли; Индикатор = ТаблицаИндикаторов.Добавить(); Индикатор.КоличествоПроходов = КоличествоПроходов; Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса; Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя; Индикатор.РазрешитьПрерывание = РазрешитьПрерывание; Индикатор.ДатаНачалаПроцесса = ТекущаяДата(); Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления; Индикатор.ДатаСледующегоОбновления = Индикатор.ДатаНачалаПроцесса + Индикатор.МинимальныйПериодОбновления; Если КоличествоОбновлений > 0 Тогда Шаг = КоличествоПроходов / КоличествоОбновлений; Иначе Шаг = 0; КонецЕсли; Индикатор.Шаг = Шаг; //Индикатор.СледующийСчетчик = 0; //Индикатор.Счетчик = 0; Возврат Индикатор; КонецФункции // ПолучитьИндикаторПроцессаЛкс() Функция ПолучитьТекстСостоянияИндикатораЛкс(Индикатор) Экспорт Счетчик = Индикатор.Счетчик; Если Истина И Индикатор.ЛиВыводитьВремя И Счетчик > 0 И Счетчик < Индикатор.КоличествоПроходов Тогда ТекущаяДата = ТекущаяДата(); ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса; Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1); ОсталосьДней = Цел(Осталось / (24*60*60)); ТекстОсталось = ", Осталось: "; Если ОсталосьДней > 0 Тогда ТекстОсталось = ТекстОсталось + ОсталосьДней + "д"; КонецЕсли; ТекстОсталось = ТекстОсталось + Формат(Дата(1,1,1) + Осталось, "ДЛФ=T"); Иначе ТекстОсталось = ""; КонецЕсли; Если Индикатор.КоличествоПроходов > 0 Тогда ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось; Иначе ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " "; КонецЕсли; Возврат ТекстСостояния; КонецФункции // Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния) // Параметры: // СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор // ВывестиИтогИндикации - Булево // ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове // Процедура ОсвободитьИндикаторПроцессаЛкс(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если Индикатор = Неопределено Тогда Если ТаблицаИндикаторов.Количество() > 0 Тогда Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1]; КонецЕсли; КонецЕсли; ИзменялосьСостояние = Индикатор <> Неопределено И ЗначениеЗаполнено(Индикатор.ТекстСостояния); Если Индикатор <> Неопределено Тогда Если ВывестиИтогИндикации Тогда СообщитьИтогИндикацииЛкс(Индикатор); КонецЕсли; Если ТаблицаИндикаторов <> Неопределено Тогда Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда ТаблицаИндикаторов.Удалить(Индикатор); КонецЕсли; КонецЕсли; КонецЕсли; Если ИзменялосьСостояние Тогда Если Ложь Или ТаблицаИндикаторов = Неопределено Или ТаблицаИндикаторов.Количество() = 0 Тогда НовоеСостояние = ""; Иначе НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния; КонецЕсли; #Если Клиент Тогда СостояниеЛкс(НовоеСостояние,, Истина); #КонецЕсли КонецЕсли; КонецПроцедуры Процедура ОсвободитьВсеИндикаторыПроцессовЛкс() Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; //Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл // ОбработатьИндикаторЛкс(СтрокаИндикатора, , Истина); //КонецЦикла; ТаблицаИндикаторов.Очистить(); КонецПроцедуры // Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла. // // Параметры: // Индикатор – Структура – индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс; // Счетчик – Число, *Неопределено – внешний счетчик цикла. // Функция ОбработатьИндикаторЛкс(Индикатор, Счетчик = Неопределено) Экспорт #Если Клиент Тогда Попытка Если Индикатор.РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; Исключение // На клиенте бывает, что строка таблицы индикаторов уже была удалена из-за модальности и обработчиков ожидания Возврат Ложь; КонецПопытки; #КонецЕсли // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Если Счетчик = Неопределено Тогда Счетчик = Индикатор.Счетчик + 1; КонецЕсли; Индикатор.Счетчик = Счетчик; ОбновитьИндикатор = Истина; ОчиститьСостояние = Ложь; Если Ложь Или Счетчик < Индикатор.КоличествоПроходов Или Индикатор.КоличествоПроходов = 0 Тогда Если Индикатор.МинимальныйПериодОбновления > 0 Тогда ТекущаяДата = ТекущаяДата(); Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления; Иначе ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; Если ОбновитьИндикатор Тогда Если Индикатор.Шаг > 0 Тогда Если Счетчик < Индикатор.СледующийСчетчик Тогда ОбновитьИндикатор = Ложь; КонецЕсли; //Иначе // ОбновитьИндикатор = Ложь; // ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " "; // СостояниеЛкс(ТекстСостояния,, Истина); КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда ОчиститьСостояние = Истина; ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Если Счетчик = Неопределено Тогда   Счетчик = Индикатор.Счетчик + 1;   КонецЕсли;   Индикатор.Счетчик = Счетчик;   ОбновитьИндикатор = Истина;   ОчиститьСостояние = Ложь;   Если Ложь   Или Счетчик < Индикатор.КоличествоПроходов   Или Индикатор.КоличествоПроходов = 0   Тогда   ТекущаяДата = ТекущаяДата();   Если Индикатор.МинимальныйПериодОбновления > 0 Тогда   Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда   Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления;   Иначе   ОбновитьИндикатор = Ложь;   КонецЕсли;   КонецЕсли;   Если ОбновитьИндикатор Тогда   Если Индикатор.Шаг > 0 Тогда   Если Счетчик < Индикатор.СледующийСчетчик Тогда   ОбновитьИндикатор = Ложь;   КонецЕсли;           КонецЕсли;   КонецЕсли;   Иначе   Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда   ОчиститьСостояние = Истина;   ОбновитьИндикатор = Ложь;   КонецЕсли;   КонецЕсли;   #Если Клиент Тогда Если ОчиститьСостояние Тогда СостояниеЛкс("",, Истина); КонецЕсли; #КонецЕсли Если ОбновитьИндикатор Тогда Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг); Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда МассивИндикаторов = Индикатор.Владелец(); Иначе МассивИндикаторов = Новый Массив; МассивИндикаторов.Добавить(Индикатор); КонецЕсли; Если ирКэш.ЭтоФоновоеЗаданиеЛкс() Тогда СтруктураИндикатора = СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(Индикатор); ТекстСостояния = "#Индикатор-" + СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураИндикатора); СообщитьЛкс(ТекстСостояния); Иначе #Если Клиент Тогда ТекстСостояния = ""; Для Каждого лИндикатор Из МассивИндикаторов Цикл Если ТекстСостояния <> "" Тогда ТекстСостояния = ТекстСостояния + ".>> "; КонецЕсли; ТекстСостояния = ТекстСостояния + ПолучитьТекстСостоянияИндикатораЛкс(лИндикатор); КонецЦикла; лИндикатор.ТекстСостояния = ТекстСостояния; СостояниеЛкс(ТекстСостояния, Индикатор.РазрешитьПрерывание, Истина); #КонецЕсли КонецЕсли; КонецЕсли; Возврат ОбновитьИндикатор; КонецФункции Процедура СостояниеЛкс(Знач СтрокаСостояния = "", РазрешитьПрерывание = Ложь, ЭтоСостояниеИндикатора = Ложь) Экспорт Если Не ЭтоСостояниеИндикатора Тогда ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если ТаблицаИндикаторов.Количество() > 0 Тогда Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1]; СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния; КонецЕсли; КонецЕсли; Если РазрешитьПрерывание Тогда СтрокаСостояния = СтрокаСостояния + ". Прервать Ctrl+Break"; КонецЕсли; #Если Клиент Тогда ИспользуемПояснение = Ложь; #Если ТолстыйКлиентУправляемоеПриложение Тогда Если Не ЗначениеЗаполнено(СтрокаСостояния) Тогда Возврат; КонецЕсли; Если ирКэш.НомерВерсииПлатформыЛкс() >= 803017 Тогда // http://www.hostedredmine.com/issues/875446 ИспользуемПояснение = Истина; КонецЕсли; #КонецЕсли Если ИспользуемПояснение Тогда Состояние(,, СтрокаСостояния); Иначе Состояние(СтрокаСостояния); КонецЕсли; #КонецЕсли КонецПроцедуры // Функция сравнивает две таблицы значений на идентичность структуры и данных // // Параметры // ТаблицаЗначений1 - ТаблицаЗначений для сравнения // ТаблицаЗначений2 - ТаблицаЗначений для сравнения // // Возвращаемое значение: // Булево, идентичны или нет две таблицы // Функция ТаблицыЗначенийРавныЛкс(ТаблицаЗначений1, ТаблицаЗначений2) Экспорт Если ТипЗнч(ТаблицаЗначений1) <> Тип("ТаблицаЗначений") ИЛИ ТипЗнч(ТаблицаЗначений2) <> Тип("ТаблицаЗначений") Тогда Возврат Ложь; КонецЕсли; Если ТаблицаЗначений1.Количество() <> ТаблицаЗначений2.Количество() Тогда Возврат Ложь; КонецЕсли; Если ТаблицаЗначений1.Колонки.Количество() <> ТаблицаЗначений2.Колонки.Количество() Тогда Возврат Ложь; КонецЕсли; Для каждого Колонка Из ТаблицаЗначений1.Колонки Цикл Если ТаблицаЗначений2.Колонки.Найти(Колонка.Имя) = Неопределено Тогда Возврат Ложь; КонецЕсли; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)]; Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда Возврат Ложь; КонецЕсли; КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для каждого СтрокаТаблицы1 Из ТаблицаЗначений1 Цикл   СтрокаТаблицы2 = ТаблицаЗначений2[ТаблицаЗначений1.Индекс(СтрокаТаблицы1)];   Если СтрокаТаблицы1[Колонка.Имя] <> СтрокаТаблицы2[Колонка.Имя] Тогда   Возврат Ложь;   КонецЕсли;   КонецЦикла;   КонецЦикла; Возврат Истина; КонецФункции // СравнитьТаблицыЗначений() Процедура ФункциональныеОпцииОбъектаМДЛкс(ОбъектМД, выхЗначенияФункОпций, выхСписокФункОпций = Неопределено, выхФункциональныеОпцииВключены = Неопределено) Экспорт выхЗначенияФункОпций = Новый Структура; выхФункциональныеОпцииВключены = Неопределено; Для Каждого ФункциональнаяОпция Из Метаданные.ФункциональныеОпции Цикл Если ФункциональнаяОпция.Состав.Содержит(ОбъектМД) Тогда выхФункциональныеОпцииВключены = Ложь; ОпцияВключена = ПолучитьФункциональнуюОпцию(ФункциональнаяОпция.Имя); выхЗначенияФункОпций.Вставить(ФункциональнаяОпция.Имя, ОпцияВключена); Если ОпцияВключена Тогда выхФункциональныеОпцииВключены = Истина; КонецЕсли; КонецЕсли; КонецЦикла; Если выхФункциональныеОпцииВключены = Неопределено Тогда выхФункциональныеОпцииВключены = Истина; КонецЕсли; выхСписокФункОпций = Новый СписокЗначений; Для Каждого КлючИЗначение Из выхЗначенияФункОпций Цикл выхСписокФункОпций.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Ключ + " = " + ОпцияВключена); КонецЦикла; КонецПроцедуры #Если Клиент Тогда Функция ИмяФормыИзСтрокиИнструментаЛкс(Знач СтрокаИнструмента) Экспорт ИмяВыбраннойФормы = СтрокаИнструмента.ПолноеИмя; Если Найти(ИмяВыбраннойФормы, "ОбщаяФорма.") <> 1 И Найти(ИмяВыбраннойФормы, ".Форма.") = 0 Тогда Если Найти(ИмяВыбраннойФормы, "Справочник.") = 1 Тогда ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".ФормаСписка"; Иначе ИмяВыбраннойФормы = ИмяВыбраннойФормы + ".Форма"; КонецЕсли; КонецЕсли; Возврат ИмяВыбраннойФормы; КонецФункции Процедура ПодключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода, Интервал = 0.1, Однократно = Истина) Экспорт Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ирПортативный.ПолучитьФорму().ПодключитьОбработчикОжидания(ИмяМетода, Интервал, Истина); Иначе ПодключитьОбработчикОжидания(ИмяМетода, Интервал, Истина); КонецЕсли; КонецПроцедуры Процедура ОтключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода) Экспорт Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ирПортативный.ПолучитьФорму().ОтключитьОбработчикОжидания(ИмяМетода); Иначе ОтключитьОбработчикОжидания(ИмяМетода); КонецЕсли; КонецПроцедуры Процедура ПодключитьГлобальныйОбработчикОжиданияСПараметрамиЛкс(ИмяМетода, Параметры, Интервал = 0.1, Однократно = Истина) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); Параметры = Новый Структура; #КонецЕсли Если мПлатформа.ПараметрыОбработчикаОжидания <> Неопределено Тогда ВызватьИсключение "Обработчик ожидания занят"; КонецЕсли; Параметры.Вставить("ИмяМетода", ИмяМетода); мПлатформа.ПараметрыОбработчикаОжидания = Параметры; ПодключитьГлобальныйОбработчикОжиданияЛкс("ГлобальныйОбработчикОжиданияСПараметрамиЛкс", Интервал, Однократно); КонецПроцедуры Процедура ОтлючитьГлобальныйОбработчикОжиданияСПараметрамиЛкс() Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли мПлатформа.ПараметрыОбработчикаОжидания = Неопределено; ОтключитьГлобальныйОбработчикОжиданияЛкс("ГлобальныйОбработчикОжиданияСПараметрамиЛкс"); КонецПроцедуры Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ПараметрыОбработчикаОжидания = мПлатформа.ПараметрыОбработчикаОжидания; Если ПараметрыОбработчикаОжидания = Неопределено Тогда СообщитьЛкс("Не удалось выполнить страховочный обработчик ожидания, т.к. обработка ирПлатформа была удалена из кэша", СтатусСообщения.Внимание); Возврат; КонецЕсли; мПлатформа.ПараметрыОбработчикаОжидания = Неопределено; Выполнить(ПараметрыОбработчикаОжидания.ИмяМетода + "(ПараметрыОбработчикаОжидания)"); КонецПроцедуры //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ФОРМАМИ // РежимОткрытия - Булево - Истина - Открытие, иначе Сохранение Функция ВыбратьФайлЛкс(РежимОткрытия = Истина, Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "", Знач Заголовок = "") Экспорт ВыборФайла = ДиалогВыбораФайлаЛкс(РежимОткрытия, Расширение, ОписаниеФормата, ПолноеИмяФайла, Каталог, КраткоеИмя, Заголовок); Если Не ВыборФайла.Выбрать() Тогда Возврат Неопределено; КонецЕсли; Возврат ВыборФайла.ПолноеИмяФайла; КонецФункции Функция ДиалогВыбораФайлаЛкс(РежимОткрытия = Истина, Знач Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "", Знач Заголовок = "") Экспорт Если РежимОткрытия = Истина Тогда РежимДиалога = РежимДиалогаВыбораФайла.Открытие; Иначе РежимДиалога = РежимДиалогаВыбораФайла.Сохранение; КонецЕсли; ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалога); ВыборФайла.Заголовок = Заголовок; Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда Файл = Новый Файл(ПолноеИмяФайла); ВыборФайла.Каталог = Файл.Путь; ВыборФайла.ПолноеИмяФайла = Файл.Имя; Иначе ВыборФайла.Каталог = Каталог; ВыборФайла.ПолноеИмяФайла = КраткоеИмя; КонецЕсли; ВыборФайла.Расширение = Расширение; Если Не ЗначениеЗаполнено(Расширение) Тогда Расширение = "*"; КонецЕсли; ВыборФайла.Фильтр = ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата); Возврат ВыборФайла; КонецФункции Функция ВыбратьКаталогВФормеЛкс(выхКаталог, ФормаДляУстановкиМодифицированности = Неопределено, Заголовок = "") Экспорт ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); ВыборФайла.Каталог = выхКаталог; ВыборФайла.Заголовок = Заголовок; Если Не ВыборФайла.Выбрать() Тогда Возврат Неопределено; КонецЕсли; выхКаталог = ВыборФайла.Каталог; Если ФормаДляУстановкиМодифицированности <> Неопределено Тогда ФормаДляУстановкиМодифицированности.Модифицированность = Истина; КонецЕсли; Возврат выхКаталог; КонецФункции Процедура ПолучитьМассивЗначенийПеретаскиванияЛкс(Знач ПараметрыПеретаскивания, выхМассивЗначений, выхТипЗначенияПеретаскивания = Неопределено) Экспорт ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания); Если выхТипЗначенияПеретаскивания = Тип("Массив") Тогда выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания[0]); выхМассивЗначений = ЗначениеПеретаскивания; Иначе выхМассивЗначений = Новый Массив; выхМассивЗначений.Добавить(ЗначениеПеретаскивания); КонецЕсли; КонецПроцедуры // Параметры: // КлючеваяКолонка - Строка - используется при отборе // ПроверятьОформлениеСтроки - Булево - долго Процедура ИзменитьПометкиВыделенныхИлиОтобранныхСтрокЛкс(Знач ТабличноеПоле, ИмяКолонкиПометки = "Пометка", НовоеЗначениеПометки = Истина, КлючеваяКолонка = "НомерСтроки", СтруктураОтбора = Неопределено, ПроверятьОформлениеСтроки = Истина) Экспорт ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Если ВыделенныеСтроки.Количество() <= 1 Тогда ВыделенныеСтроки = ТабличноеПоле.Значение; Попытка ОтборСтрок = ТабличноеПоле.ОтборСтрок; Исключение КонецПопытки; Если ОтборСтрок <> Неопределено Или СтруктураОтбора <> Неопределено Тогда Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора); #Если Сервер И Не Сервер Тогда Построитель = Новый ПостроительЗапроса; #КонецЕсли Построитель.ВыбранныеПоля.Очистить(); Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка); НомераОтобранныхСтрок = Построитель.Результат.Выгрузить(); НомераОтобранныхСтрок.Индексы.Добавить(КлючеваяКолонка); КонецЕсли; КонецЕсли; Для каждого Строка из ВыделенныеСтроки Цикл Если Истина И НомераОтобранныхСтрок <> Неопределено И НомераОтобранныхСтрок.Найти(Строка[КлючеваяКолонка], КлючеваяКолонка) = Неопределено Тогда // Строка не отвечает отбору Продолжить; КонецЕсли; Если ПроверятьОформлениеСтроки Тогда ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(Строка); Если ОформлениеСтроки.Ячейки[ИмяКолонкиПометки].ТолькоПросмотр Тогда Продолжить; КонецЕсли; КонецЕсли; Строка[ИмяКолонкиПометки] = НовоеЗначениеПометки; КонецЦикла; ТабличноеПоле.ОбновитьСтроки(); КонецПроцедуры Функция ВыбратьСсылкуЛкс(ИмяТаблицыИлиМДИлиТип, НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт Результат = ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип,, ИспользоватьДинамическийСписокИР,, Истина,, НачальноеЗначениеВыбора, Истина); Возврат Результат; КонецФункции Процедура ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(ТаблицаИсточник, НачальноеПолноеИмяОбъекта = "") Экспорт ФормаВыбораОбъектаБД = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхЛкс(,, НачальноеПолноеИмяОбъекта,, Истина,, Истина, Истина,, Истина,,, Истина); РезультатВыбора = ФормаВыбораОбъектаБД.ОткрытьМодально(); Если РезультатВыбора = Неопределено Тогда Возврат; КонецЕсли; ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(РезультатВыбора.ПолноеИмяОбъекта); ЭтоНаборЗаписей = ирОбщий.ЛиРегистровыйОбъектМетаданных(ОбъектМД); Если ЭтоНаборЗаписей Тогда ПолноеИмяМДСписка = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмяМДСписка = ОбъектМД.Родитель().ПолноеИмя(); КонецЕсли; МакетныйОбъект = Неопределено; ТекущаяГруппаТипаМетаданных = Неопределено; ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМДСписка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); Если ЭтоНаборЗаписей Тогда СтруктураОбъекта = МакетныйОбъект; ТаблицаПриемник = СтруктураОбъекта; Иначе ВыбраннаяСтрока = ОткрытьФормуСпискаЛкс(ПолноеИмяМДСписка,,,, Истина,,, Истина); Если ВыбраннаяСтрока = Неопределено Тогда Возврат; КонецЕсли; СтруктураОбъекта = ирОбщий.ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(ВыбраннаяСтрока, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина); ТаблицаПриемник = СтруктураОбъекта.Данные[ОбъектМД.Имя]; КонецЕсли; Если ТаблицаПриемник.Количество() > 0 Тогда Если ЭтоНаборЗаписей Тогда ТекстВопроса = "Хотите очистить набор записей в памяти перед заполнением?"; Иначе ТекстВопроса = "Выбранная табличная часть объекта не пустая. Хотите очистить ее в памяти перед заполнением?"; КонецЕсли; Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да); Если Ответ = КодВозвратаДиалога.Да Тогда ТаблицаПриемник.Очистить(); КонецЕсли; КонецЕсли; ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник); ОбработкаРедактора = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД"); #Если Сервер И Не Сервер Тогда ОбработкаРедактора = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ФормаРедактора = ОбработкаРедактора.РедактироватьМодифицированныйОбъект(СтруктураОбъекта); ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(РезультатВыбора.ПолноеИмяОбъекта); КонецПроцедуры // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(Значение1, Значение2, Модально = Ложь, Знач Название1 = Неопределено, Знач Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт Если Истина И ТипЗнч(Значение1) = Тип("ТаблицаЗначений") И ТипЗнч(Значение2) = Тип("ТаблицаЗначений") Тогда Обработка = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирСравнениеТаблиц"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирСравнениеТаблиц.Создать(); #КонецЕсли ФормаСравнителя = Обработка.ПолучитьФорму(); ФормаСравнителя.ПараметрТаблица1 = Значение1; ФормаСравнителя.ПараметрТаблица2 = Значение2; ФормаСравнителя.Открыть(); Возврат ФормаСравнителя.СравнитьТаблицыВФорме(); КонецЕсли; Если Не ЗначениеЗаполнено(Название1) Тогда Название1 = "первое"; КонецЕсли; Если Не ЗначениеЗаполнено(Название2) Тогда Название2 = "второе"; КонецЕсли; Путь1 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение1, Название1, ПолучатьXMLПредставлениеДляНеизвестныхТипов); Путь2 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение2, Название2, ПолучатьXMLПредставлениеДляНеизвестныхТипов); // Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится. Если СравнениеФайлов = Неопределено Тогда СравнениеФайлов = Новый СравнениеФайлов; КонецЕсли; СравнениеФайлов.ПервыйФайл = Путь1; СравнениеФайлов.ВторойФайл = Путь2; СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь; Если Истина И ТипЗнч(Значение1) = Тип("ТабличныйДокумент") И ТипЗнч(Значение2) = Тип("ТабличныйДокумент") Тогда СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент; Иначе СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент; КонецЕсли; Если Модально Тогда СравнениеФайлов.ПоказатьРазличияМодально(); Иначе СравнениеФайлов.ПоказатьРазличия(); КонецЕсли; Возврат СравнениеФайлов.Сравнить(); КонецФункции // СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс() // Сравнивает табличный документ, полученный из элемента управления с предыдущим. // // Параметры: // СравнительТабличныхДокументов – Массив, *Неопределено – переменная для хранения предыдущего табличного документа. // ЭлементУправления – ТабличноеПоле, ПолеТабличногоДокумента – откуда получаем содержимое. // Процедура СравнитьСодержимоеЭлементаУправленияЛкс(ЭтаФорма, ЭлементУправления) Экспорт Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда СравниваемыйДокумент = Новый ТекстовыйДокумент; СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст()); ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда СравниваемыйДокумент = Новый ТекстовыйДокумент; СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение); ИначеЕсли Ложь Или ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Или ТипЗнч(ЭлементУправления) = Тип("ТаблицаФормы") Тогда СравниваемыйДокумент = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ЭлементУправления); Если СравниваемыйДокумент = Неопределено Тогда Возврат; КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(ЭлементУправления) = Тип("ПолеТабличногоДокумента") Или (Истина И ТипЗнч(ЭлементУправления) = Тип("ПолеФормы") И ЭлементУправления.Вид = ВидПоляФормы.ПолеТабличногоДокумента) Тогда ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ЭлементУправления); СравниваемыйДокумент = ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ТабличныйДокумент); Иначе СообщитьЛкс("Неподдерживаемый тип элемента управления для сравнения"); Возврат; КонецЕсли; МассивСравнения = ирКэш.БуферСравненияЛкс("" + ТипЗнч(СравниваемыйДокумент)); Если МассивСравнения.Количество() = 2 Тогда МассивСравнения.Удалить(0); КонецЕсли; МассивСравнения.Добавить(СравниваемыйДокумент); Если МассивСравнения.Количество() = 2 Тогда Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Нет Тогда Возврат; КонецЕсли; ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма); СравниваемыйДокумент1 = МассивСравнения[0]; СравниваемыйДокумент2 = МассивСравнения[1]; СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(СравниваемыйДокумент1, СравниваемыйДокумент2); Иначе СообщитьЛкс("Первое значение для сравнения запомнено. Теперь передайте второе значение."); КонецЕсли; КонецПроцедуры Функция ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ТабличныйДокумент) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если Не ЛиОбластьЯчеекТабличногоДокументаОбъединенаЛкс(ТабличныйДокумент) Тогда Ответ = Вопрос("Использовать только текущую область (Да) иначе будет использован весь документ (Нет)?", РежимДиалогаВопрос.ДаНет); Иначе Ответ = КодВозвратаДиалога.Нет; КонецЕсли; Если Ответ = КодВозвратаДиалога.Да Тогда Результат = ТабличныйДокумент.ПолучитьОбласть(ТабличныйДокумент.ТекущаяОбласть.Имя); ЗаполнитьЗначенияСвойств(Результат, ТабличныйДокумент,, "ВыделенныеОбласти, ТекущаяОбласть"); Иначе Результат = ТабличныйДокумент.ПолучитьОбласть(); ЗаполнитьЗначенияСвойств(Результат, ТабличныйДокумент); КонецЕсли; Возврат Результат; КонецФункции Функция ЛиОбластьЯчеекТабличногоДокументаОбъединенаЛкс(Знач ТабличныйДокумент, Знач ТекущаяОбласть = Неопределено) #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если ТекущаяОбласть = Неопределено Тогда ТекущаяОбласть = ТабличныйДокумент.ТекущаяОбласть; КонецЕсли; Область = ТабличныйДокумент.Область(ТекущаяОбласть.Верх, ТекущаяОбласть.Лево); Возврат ТекущаяОбласть.Низ = Область.Низ И ТекущаяОбласть.Право = Область.Право; КонецФункции Функция ВывестиСтрокиТабличногоПоляСНастройкойЛкс(Знач ТабличноеПоле, ВыводБезОформления = Истина, Знач НастройкиСписка = Неопределено, выхТекущаяСтрока = Неопределено) Экспорт ФормаНастройки = ирКэш.Получить().ПолучитьФорму("ПараметрыВыводаСтрокТаблицы"); ФормаНастройки.ТабличноеПоле = ТабличноеПоле; Если ВыводБезОформления <> Неопределено Тогда ФормаНастройки.БезОформления = ВыводБезОформления; КонецЕсли; РезультатФормы = ФормаНастройки.ОткрытьМодально(); Если РезультатФормы = Неопределено Тогда Возврат Неопределено; КонецЕсли; выхТекущаяСтрока = Неопределено; Результат = ВывестиСтрокиТабличногоПоляЛкс(ТабличноеПоле, ФормаНастройки,, выхТекущаяСтрока, НастройкиСписка); Возврат Результат; КонецФункции Функция ВывестиСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач ПараметрыВывода, Отладка = Ложь, выхТекущаяСтрока = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт КлючТекущейСтроки = Неопределено; ИндексТекущейСтроки = Неопределено; СтруктураТипа = Неопределено; ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле, , СтруктураТипа); ВыбранныеКолонки = ПараметрыВывода.КолонкиТабличногоПоля.Выгрузить(Новый Структура("Пометка", Истина)); МассивСтрок = Неопределено; ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле); Если ЗначениеТабличногоПоля = Неопределено Тогда КоллекцияСтрок = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле,,, Ложь); ИначеЕсли ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДанныеФормыДерево") Тогда ЗначениеТабличногоПоля = ДанныеФормыВЗначение(ЗначениеТабличногоПоля, Тип("ДеревоЗначений")); КонецЕсли; ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); Если ТипИсточника = "Список" И ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда КлючТекущейСтроки = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы); Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда ЗаполнитьЗначенияСвойств(КлючТекущейСтроки, ТабличноеПоле.ТекущаяСтрока); КонецЕсли; Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда КоллекцияСтрок = КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(ТабличноеПоле); КонецЕсли; Иначе Если ПараметрыВывода.ТолькоВыделенныеСтроки Тогда МассивСтрок = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; Если ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда Если МассивСтрок <> Неопределено Тогда КоллекцияСтрок = МассивСтрок; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда КоллекцияСтрок = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок,, Ложь); КонецЕсли; Иначе КоллекцияСтрок = ЗначениеТабличногоПоля.Строки; Если ТипЗнч(ТабличноеПоле.ТекущаяСтрока) = Тип("СтрокаДереваЗначений") Тогда ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТабличноеПоле.ТекущаяСтрока); КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипИсточника = "ТабличнаяЧасть" Или ТипИсточника = "НаборЗаписей" Или ТипИсточника = "ТаблицаЗначений" Тогда Если ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда //ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущаяСтрока); ИндексТекущейСтроки = ЗначениеТабличногоПоля.Индекс(ТабличноеПоле.ТекущиеДанные); КонецЕсли; Если ПараметрыВывода.БезОформления Тогда КоллекцияСтрок = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок, Истина); Иначе Если МассивСтрок <> Неопределено Тогда КоллекцияСтрок = МассивСтрок; ИначеЕсли ТипИсточника = "ТаблицаЗначений" Или Не ОтборУстановленЛкс(ТабличноеПоле.ОтборСтрок) Тогда КоллекцияСтрок = ТабличноеПоле.Значение; Иначе КоллекцияСтрок = Новый Массив; КопияСтрок = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок, Истина); Для Каждого КопияСтроки Из КопияСтрок Цикл КоллекцияСтрок.Добавить(ТабличноеПоле.Значение[КопияСтроки.НомерСтроки - 1]); КонецЦикла; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипИсточника = "Список" Тогда КоллекцияСтрок = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле, МассивСтрок, Истина); КонецЕсли; КонецЕсли; Если ПараметрыВывода.БезОформления Тогда ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Данные"); Если ТипИсточника = "Список" И ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда КоллекцияСтрок = ДанныеСтрокДинамическогоСпискаЛкс(ТабличноеПоле, КоллекцияСтрок, ВыбранныеКолонки, НастройкиСписка, ПараметрыВывода.КоличествоПервых); #Если Сервер И Не Сервер Тогда КоллекцияСтрок = Новый ТаблицаЗначений; #КонецЕсли ВыбранныеКолонки = Неопределено; ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки); Если ТекущаяСтрока.Количество() > 0 Тогда ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТекущаяСтрока[0]); КонецЕсли; Если ЛиКорневойТипСсылкиЛкс(ТипТаблицыБДЛкс(ПолноеИмяТаблицы)) И ПараметрыВывода.КолонкиИдентификаторов Тогда //ВыбранныеКолонки.Добавить("Ссылка"); КоллекцияСтрок.Колонки.Добавить("ИдентификаторСсылкиЛкс",, "Идентификатор ссылки"); //Если ВыбранныеКолонки.Найти("ИдентификаторСсылкиЛкс") = Неопределено Тогда // ВыбранныеКолонки.Добавить("ИдентификаторСсылкиЛкс"); //КонецЕсли; Для Каждого СтрокаКоллекции Из КоллекцияСтрок Цикл СтрокаКоллекции.ИдентификаторСсылкиЛкс = СтрокаКоллекции.Ссылка.УникальныйИдентификатор(); КонецЦикла; КонецЕсли; ИначеЕсли ТипЗнч(ЗначениеТабличногоПоля) = Тип("ДеревоЗначений") Тогда ТаблицаСтрокДерева = Новый ТаблицаЗначений; Для Каждого КолонкаДерева Из ЗначениеТабличногоПоля.Колонки Цикл ТаблицаСтрокДерева.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина); КонецЦикла; Если ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда КоллекцияСтрок = ВсеСтрокиДереваЗначенийЛкс(ЗначениеТабличногоПоля); КонецЕсли; Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтрокДерева.Добавить(), СтрокаДерева); КонецЦикла; КоллекцияСтрок = ТаблицаСтрокДерева; КонецЕсли; ИмяТекущейКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Результат = ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(КоллекцияСтрок,,, ПараметрыВывода.ИтогиЧисловыхКолонок,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки, ПараметрыВывода.ОтображатьПустые, ПараметрыВывода.КолонкиИдентификаторов, ПараметрыВывода.КолонкиТипов, ПараметрыВывода.КолонкиЗначений, ВыбранныеКолонки, ИмяТекущейКолонки, ПараметрыВывода.ВыводВТаблицуЗначений, Отладка, ПараметрыВывода.КолонкиРазмеров, ПараметрыВывода.СузитьТипы); Иначе Если ТипИсточника = "Список" Тогда КоллекцияСтрок = ДанныеСтрокДинамическогоСпискаЛкс(ТабличноеПоле, КоллекцияСтрок,, НастройкиСписка, ПараметрыВывода.КоличествоПервых); #Если Сервер И Не Сервер Тогда КоллекцияСтрок = Новый ТаблицаЗначений; #КонецЕсли ТекущаяСтрока = КоллекцияСтрок.НайтиСтроки(КлючТекущейСтроки); Если ТекущаяСтрока.Количество() > 0 Тогда ИндексТекущейСтроки = КоллекцияСтрок.Индекс(ТекущаяСтрока[0]); КонецЕсли; Если ЛиКорневойТипСсылкиЛкс(ТипТаблицыБДЛкс(ПолноеИмяТаблицы)) Тогда КоллекцияСтрок = КоллекцияСтрок.ВыгрузитьКолонку("Ссылка"); КонецЕсли; КонецЕсли; ВыбранныеКолонки = ВыбранныеКолонки.ВыгрузитьКолонку("Имя"); Если ПараметрыВывода.ВыводВТаблицуЗначений Тогда Результат = Новый ТаблицаЗначений; Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл Колонка = ТабличноеПоле.Колонки[ВыбраннаяКолонка]; Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда Продолжить; КонецЕсли; Если Колонка.Видимость Тогда КолонкаПриемник = Результат.Колонки.Добавить(Колонка.Имя, Новый ОписаниеТипов("Строка"), Колонка.ТекстШапки); КонецЕсли; КонецЦикла; ВывестиСтрокиТабличногоПоляСОформлениемЛкс(КоллекцияСтрок,, Результат, ТабличноеПоле,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки); Иначе Результат = Новый ТабличныйДокумент; НомерКолонки = 1; НомерСтроки = 1; ОбластьТаблицы = Результат.Область(); ОбластьТаблицы.ЦветРамки = ЦветаСтиля.ЦветРамки; ОбластьЗаголовков = Результат.Область(НомерСтроки, 0, НомерСтроки, 0); ОбластьЗаголовков.ЦветФона = ТабличноеПоле.ЦветФонаШапки; ОбластьЗаголовков.ЦветТекста = ТабличноеПоле.ЦветТекстаШапки; Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл Колонка = ТабличноеПоле.Колонки[ВыбраннаяКолонка]; Если Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда Продолжить; КонецЕсли; Если Колонка.Видимость Тогда ОбластьЗаголовка = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки); ОбластьЗаголовка.Текст = Колонка.ТекстШапки; ОбластьЗаголовка.ЦветФона = Колонка.ЦветФонаШапки; ОбластьЗаголовка.ЦветТекста = Колонка.ЦветТекстаШапки; //ШиринаКолонки = Колонка.Ширина; //Если ШиринаКолонки <= 0 Тогда // Если ЗначениеЗаполнено(Колонка.Данные) Тогда // ШиринаКолонки = ЗначениеТабличногоПоля.Колонки[Колонка.Данные].Ширина; // Если ШиринаКолонки = 0 Тогда // ШиринаКолонки = 30; // КонецЕсли; // Иначе // ШиринаКолонки = 30; // КонецЕсли; //КонецЕсли; //ШиринаКолонки = Мин(ШиринаКолонки, 50); //ШиринаКолонки = Макс(ШиринаКолонки, 10); //ОбластьЗаголовка.ШиринаКолонки = ШиринаКолонки; ОбластьЗаголовка.ЦветФона = ЦветаСтиля.ЦветФонаШапкиТаблицы; ОбластьЗаголовка.ЦветТекста = ЦветаСтиля.ЦветТекстаШапкиТаблицы; УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЗаголовка, ТабличноеПоле); НомерКолонки = НомерКолонки + 1; КонецЕсли; КонецЦикла; ВывестиСтрокиТабличногоПоляСОформлениемЛкс(КоллекцияСтрок, НомерСтроки, Результат, ТабличноеПоле,, ПараметрыВывода.ВстроитьЗначенияВРасшифровки); УстановитьАвтоширинуКолонокТабличногоДокументаЛкс(Результат); Если ТабличноеПоле.ТекущаяКолонка <> Неопределено Тогда ИндексКолонки = ВыбранныеКолонки.Найти(ТабличноеПоле.ТекущаяКолонка.Имя); Если ИндексКолонки <> Неопределено Тогда Результат.ТекущаяОбласть = Результат.Область(2, ИндексКолонки + 1); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если Результат <> Неопределено Тогда Если ПараметрыВывода.ТолькоВыделенныеСтроки Или ИндексТекущейСтроки = Неопределено Тогда ИндексТекущейСтроки = 0; КонецЕсли; Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда НомерСтроки = ИндексТекущейСтроки + 2; Результат.ТекущаяОбласть = Результат.Область(НомерСтроки, Результат.ТекущаяОбласть.Лево); ИначеЕсли Результат.Количество() > ИндексТекущейСтроки И ИндексТекущейСтроки >= 0 Тогда выхТекущаяСтрока = Результат[ИндексТекущейСтроки]; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ДанныеСтрокДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач КлючиСтрок = Неопределено, Знач ВыбранныеКолонки = Неопределено, НастройкиСписка = Неопределено, Знач КоличествоПервых = 100000) Экспорт ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы); ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле); СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы,,,,,,, КоличествоПервых); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; Если НастройкиСписка = Неопределено Тогда НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок); КонецЕсли; ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор); Если Не ЛиКорневойТипПеречисленияЛкс(ПервыйФрагментЛкс(ПолноеИмяТаблицы)) Тогда ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок); КонецЕсли; Если КлючиСтрок <> Неопределено Тогда ГруппаИли = НастройкаКомпоновки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных")); ГруппаИли.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИли; ГруппаИли.Использование = Истина; Для Каждого КлючСтроки Из КлючиСтрок Цикл ГруппаИ = ГруппаИли.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных")); ГруппаИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИ; ГруппаИ.Использование = Истина; Для Каждого КлючИЗначение Из СтруктураКлюча Цикл Если ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(КлючСтроки)) Тогда ЗначениеПоляКлюча = КлючСтроки; Иначе ЗначениеПоляКлюча = КлючСтроки[КлючИЗначение.Ключ]; КонецЕсли; НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ГруппаИ, КлючИЗначение.Ключ, ЗначениеПоляКлюча); КонецЦикла; КонецЦикла; КонецЕсли; Для Каждого КлючИЗначение Из СтруктураКлюча Цикл НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, КлючИЗначение.Ключ); КонецЦикла; Если ВыбранныеКолонки <> Неопределено Тогда Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда Продолжить; КонецЕсли; НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка); КонецЦикла; КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки)); КомпоновщикНастроек.ЗагрузитьНастройки(НастройкаКомпоновки); КомпоновщикНастроек.Восстановить(); НастройкаКомпоновки = КомпоновщикНастроек.Настройки; КонецЕсли; Результат = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки,,,,,,,,,, "_"); Возврат Результат; КонецФункции Функция ВыделенныеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач НуженВидимыйПорядок = Истина) Экспорт ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Если Не НуженВидимыйПорядок Тогда Возврат ВыделенныеСтроки; КонецЕсли; // https://partners.v8.1c.ru/forum/t/1928636/m/1928636 // http://www.hostedredmine.com/issues/881648 МассивСтрок = Новый Массив; ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле); ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); Если ТипИсточника = "Список" И ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда КоллекцияСтрок = ДанныеСтрокДинамическогоСпискаЛкс(ТабличноеПоле, ВыделенныеСтроки); СтруктураКлюча = Неопределено; ОбъектМД = Неопределено; Для Каждого ДанныеСтроки Из КоллекцияСтрок Цикл МассивСтрок.Добавить(ирОбщий.КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ДанныеСтроки,,,, СтруктураКлюча, ОбъектМД)); КонецЦикла; Иначе Если Истина И ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") И ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение); #Если Сервер И Не Сервер Тогда ВсеСтроки = Новый Массив; #КонецЕсли Иначе ВсеСтроки = ДанныеЭлементаФормыЛкс(ТабличноеПоле); КонецЕсли; Если ЭтоКоллекцияЛкс(ВсеСтроки) Тогда Для Каждого ЭлементКоллекции Из ВсеСтроки Цикл Если ТипЗнч(ЭлементКоллекции) = Тип("ДанныеФормыЭлементКоллекции") Тогда ВыделеннаяСтрока = ЭлементКоллекции.ПолучитьИдентификатор(); СтрокаВыделена = ВыделенныеСтроки.Найти(ВыделеннаяСтрока) <> Неопределено; Иначе ВыделеннаяСтрока = ЭлементКоллекции; СтрокаВыделена = ВыделенныеСтроки.Содержит(ВыделеннаяСтрока); КонецЕсли; Если СтрокаВыделена Тогда МассивСтрок.Добавить(ВыделеннаяСтрока); КонецЕсли; КонецЦикла; Иначе // Грязно ПредПозиция = Неопределено; ПорядокНарушен = Ложь; ТаблицаСтрок = Новый ТаблицаЗначений; ТаблицаСтрок.Колонки.Добавить("Строка"); ТаблицаСтрок.Колонки.Добавить("Позиция"); Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда ПозицияСтроки = ВыделеннаяСтрока; Если Истина И ПредПозиция <> Неопределено И ПозицияСтроки < ПредПозиция И ТаблицаСтрок.Количество() > 2 Тогда ПорядокНарушен = Истина; КонецЕсли; ПредПозиция = ПозицияСтроки; ИначеЕсли Истина И ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") И ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ПозицияСтроки = ВсеСтроки.Найти(ВыделеннаяСтрока); Иначе ПозицияСтроки = Неопределено; КонецЕсли; СтрокаТаблицы = ТаблицаСтрок.Добавить(); СтрокаТаблицы.Строка = ВыделеннаяСтрока; СтрокаТаблицы.Позиция = ПозицияСтроки; КонецЦикла; Если Не ПорядокНарушен Или ТипЗнч(ТабличноеПоле) <> Тип("ТаблицаФормы") Тогда ТаблицаСтрок.Сортировать("Позиция"); КонецЕсли; МассивСтрок = ТаблицаСтрок.ВыгрузитьКолонку("Строка"); КонецЕсли; КонецЕсли; Возврат МассивСтрок; КонецФункции Функция ВыделенныеИлиВсеСтрокиТабличногоПоляЛкс(Знач ТабличноеПоле) Экспорт Если ТабличноеПоле.ВыделенныеСтроки.Количество() > 1 Тогда ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Иначе ВыделенныеСтроки = ТабличноеПоле.Значение; КонецЕсли; Возврат ВыделенныеСтроки; КонецФункции Процедура ВывестиСтрокиТабличногоПоляСОформлениемЛкс(Знач КоллекцияСтрок, НомерСтроки = Неопределено, Знач Результат, Знач ТабличноеПоле, Смещение = "", ВстроитьЗначенияВРасшифровки = Истина) Индикатор = ПолучитьИндикаторПроцессаЛкс(КоллекцияСтрок.Количество()); Для Каждого СтрокаИсточника Из КоллекцияСтрок Цикл ОбработатьИндикаторЛкс(Индикатор); ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(СтрокаИсточника); Если ОформлениеСтроки = Неопределено Тогда Прервать; КонецЕсли; Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда #Если Сервер И Не Сервер Тогда Результат = Новый ТабличныйДокумент; #КонецЕсли НомерСтроки = НомерСтроки + 1; ОбластьСтроки = Результат.Область(НомерСтроки, 0, НомерСтроки, 0); //ЗаполнитьЗначенияСвойств(ОбластьСтроки, ОформлениеСтроки, "Шрифт, ЦветТекста, ЦветФона"); ИначеЕсли ТипЗнч(Результат) = Тип("ТаблицаЗначений") Тогда #Если Сервер И Не Сервер Тогда Результат = Новый ТаблицаЗначений; #КонецЕсли ОбластьСтроки = Результат.Добавить(); КонецЕсли; НомерКолонки = 1; Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл Если Не Колонка.Видимость Или Колонка.Имя = ирКэш.ИмяКолонкиНомерСтрокиЛкс() Тогда Продолжить; КонецЕсли; ОформлениеЯчейки = ОформлениеСтроки.Ячейки[Колонка.Имя]; Если ТипЗнч(Результат) = Тип("ТабличныйДокумент") Тогда ОбластьЯчейки = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки); ЗаполнитьЗначенияСвойств(ОбластьЯчейки, ОформлениеЯчейки, "Шрифт, ЦветТекста, ЦветФона"); Если ОформлениеЯчейки.ОтображатьТекст Тогда ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.Текст; ИначеЕсли ОформлениеЯчейки.ОтображатьФлажок Тогда ОбластьЯчейки.Текст = Смещение + ОформлениеЯчейки.ЗначениеФлажка; КонецЕсли; Если Истина И ВстроитьЗначенияВРасшифровки //И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ОформлениеЯчейки.Значение, Ложь) Тогда ОбластьЯчейки.Расшифровка = ОформлениеЯчейки.Значение; КонецЕсли; УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЯчейки, ТабличноеПоле); НомерКолонки = НомерКолонки + 1; ИначеЕсли ТипЗнч(Результат) = Тип("ТаблицаЗначений") Тогда ОбластьСтроки[Колонка.Имя] = ОформлениеЯчейки.Текст; КонецЕсли; КонецЦикла; Если Истина И ТипЗнч(Результат) = Тип("ТабличныйДокумент") И ТипЗнч(СтрокаИсточника) = Тип("СтрокаДереваЗначений") И ТабличноеПоле.Развернут(СтрокаИсточника) Тогда Результат.НачатьГруппуСтрок(); ВывестиСтрокиТабличногоПоляСОформлениемЛкс(СтрокаИсточника.Строки, НомерСтроки, Результат, ТабличноеПоле, Смещение + " "); Результат.ЗакончитьГруппуСтрок(); КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); КонецПроцедуры Процедура ВывестиСтрокиТабличногоПоляИПоказатьЛкс(Знач ТабличноеПоле, Знач ВыводБезОформления = Неопределено, Знач НастройкиСписка = Неопределено) Экспорт ТекущаяСтрока = Неопределено; Результат = ВывестиСтрокиТабличногоПоляСНастройкойЛкс(ТабличноеПоле, ВыводБезОформления, НастройкиСписка, ТекущаяСтрока); Если Результат <> Неопределено Тогда ОткрытьЗначениеЛкс(Результат,,,, Ложь,, ТабличноеПоле); КонецЕсли; КонецПроцедуры Процедура УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(Знач ОбластьЯчейки, Знач ЭлементУправления) Экспорт ЛинияСплошная = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная); Если ЭлементУправления.ГоризонтальныеЛинии Тогда ОбластьЯчейки.ГраницаСверху = ЛинияСплошная; ОбластьЯчейки.ГраницаСнизу = ЛинияСплошная; КонецЕсли; Если ЭлементУправления.ВертикальныеЛинии Тогда ОбластьЯчейки.ГраницаСлева = ЛинияСплошная; ОбластьЯчейки.ГраницаСправа = ЛинияСплошная; КонецЕсли; КонецПроцедуры // ЛксСравнитьСодержимоеПоля() Процедура РасширитьКолонкиТабличногоПоляЛкс(ТабличноеПоле, УважатьЗапретИзмененияРазмера = Истина) Экспорт //ВведенноеЗначениеШирины = 10; //Если ВвестиЧисло(ВведенноеЗначениеШирины, "Введите новую ширину колонки для всех колонок", 5, 0) Тогда // УстановитьСвойствоВКоллекцииЛкс(ТабличноеПоле.Колонки, , "-Ширина", ВведенноеЗначениеШирины); //КонецЕсли; Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл Ширина = Колонка.Ширина; Если Ширина = 0 Тогда // Антибаг платформы. Ширина = 10; КонецЕсли; Если Ложь Или Не УважатьЗапретИзмененияРазмера Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять Тогда НоваяШирина = Ширина + 3; Колонка.Ширина = НоваяШирина; КонецЕсли; КонецЦикла; КонецПроцедуры // РасширитьКолонкиТабличногоПоляЛкс() // Пропорционально сжимает ширины колонок табличного поля. // // Параметры: // ТабличноеПоле – ТабличноеПоле; // Сжатие – Число, *2 – коэффициент сжатия; // УважатьЗапретИзмененияРазмера – Булево, *Истина – не сжимать колонки с запретом изменения размера; // Процедура СжатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, Сжатие = 2, УважатьЗапретИзмененияРазмера = Истина) Экспорт Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл Ширина = Колонка.Ширина; Если Ширина = 0 Тогда // Антибаг платформы. Ширина = 10; КонецЕсли; Если Ложь Или Не УважатьЗапретИзмененияРазмера Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять Тогда НоваяШирина = Ширина / Сжатие; НоваяШирина = Макс(НоваяШирина, 1); Колонка.Ширина = НоваяШирина; КонецЕсли; КонецЦикла; КонецПроцедуры // СжатьКолонкиТабличногоПоляЛкс() // Интерактивно записывает значение в элемент управления. Интерактивность заключается в срабатывании // события ПриИзменении у элемента управления. // // Параметры: // ЭлементУправления – ЭлементУправления – которому присваиваем значение; // Значение – Произвольный – присваиваемое значение; // *ФормаИнициатор - Форма, УправляемаяФорма, *Неопределено - которая будет использована в качестве инициатора события; // если не указана, то будет создана временная форма-пустышка. // // Результат - Булево - успешно ли значение установлено Функция ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Знач Значение, Знач ФормаИнициатор = Неопределено) Экспорт Если ФормаИнициатор = Неопределено Тогда ФормаИнициатор = ирКэш.Получить().ПолучитьФорму("Пустышка", ЭлементУправления); Иначе СтарыйВладелец = ФормаИнициатор.ВладелецФормы; СтарыйЗакрыватьПриВыборе = ФормаИнициатор.ЗакрыватьПриВыборе; ФормаИнициатор.ВладелецФормы = ЭлементУправления; ФормаИнициатор.ЗакрыватьПриВыборе = Ложь; КонецЕсли; НовоеЗначение = ЭлементУправления.ОграничениеТипа.ПривестиЗначение(Значение); Если Ложь Или НовоеЗначение <> Значение Или ЭлементУправления.ТолькоПросмотр Тогда Возврат Ложь; КонецЕсли; ФормаИнициатор.ОповеститьОВыборе(Значение); Если СтарыйЗакрыватьПриВыборе <> Неопределено Тогда ФормаИнициатор.ВладелецФормы = СтарыйВладелец; ФормаИнициатор.ЗакрыватьПриВыборе = СтарыйЗакрыватьПриВыборе; КонецЕсли; ЗначениеПоля = ДанныеЭлементаФормыЛкс(ЭлементУправления); //Попытка Результат = ЗначениеПоля = Значение; //Исключение // // Это поле управляемой формы // Результат = Истина; //КонецПопытки; Возврат Результат; КонецФункции // Интерактивно записывает значение в элемент управления (только поле ввода/формы) колонки табличного поля или таблицы формы. // Интерактивность заключается в срабатывании события ПриИзменении у элемента управления. // Строка табличного поля или таблицы формы должна находиться в режиме редактирования, // иначе никаких изменений данных не произойдет. // // Параметры: // ТабличноеПоле - ТабличноеПоле, ТаблицаФормы - внутри него строка редактируется; // Колонка – КолонкаТабличногоПоля, ПолеФормы – в ее ячейку будем помещать значение; // Значение – Произвольный – присваиваемое значение; // *ФормаИнициатор - Форма, УправляемаяФормы, *Неопределено - которая будет использована в качестве инициатора события; // если не указана, то будет создана временная форма-пустышка; // *ВосстанавитьТекущуюКолонку – Булево, *Истина; // *ВключитьРежимРедактирования – Булево, *Истина. // Процедура ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Знач Колонка, Знач Значение, Знач ФормаИнициатор = Неопределено, Знач ВосстанавитьТекущуюКолонку = Истина, Знач ВключитьРежимРедактирования = Истина, Знач КонтролироватьТекущиеДанные = Истина, Знач ВыключитьРежимРедактирования = Ложь) Экспорт Если ТипЗнч(Колонка) = Тип("КолонкаТабличногоПоля") Тогда ЭлементУправления = Колонка.ЭлементУправления; Если ТипЗнч(ЭлементУправления) <> Тип("ПолеВвода") Тогда ЭлементУправления = Неопределено; КонецЕсли; Иначе ЭлементУправления = Колонка; Если ТипЗнч(ЭлементУправления) <> Тип("ПолеФормы") Тогда ЭлементУправления = Неопределено; КонецЕсли; КонецЕсли; Если ЭлементУправления <> Неопределено Тогда Если ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда ДанныеПоля = ДанныеЭлементаФормыЛкс(ЭлементУправления); ХмлТип = XMLТипЗнч(ДанныеПоля); Если Истина И ХмлТип <> Неопределено И Найти(ХмлТип.ИмяТипа, "CatalogRef.") > 0 Тогда Если Ложь Или (Истина И ЗначениеЗаполнено(ЭлементУправления.ВыборПоВладельцу) И Значение.Владелец <> ЭлементУправления.ВыборПоВладельцу) Или (Истина И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы И Значение.ЭтоГруппа) Или (Истина И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Группы И Не Значение.ЭтоГруппа) Тогда Возврат; КонецЕсли; КонецЕсли; КонецЕсли; Если ВосстанавитьТекущуюКолонку Тогда СтараяТекущаяКолонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле); КонецЕсли; ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТабличноеПоле, Колонка); Если ВключитьРежимРедактирования Тогда ТабличноеПоле.ИзменитьСтроку(); КонецЕсли; ИнтерактивноЗаписатьВЭлементУправленияЛкс(ЭлементУправления, Значение, ФормаИнициатор); Если ВосстанавитьТекущуюКолонку Тогда ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТабличноеПоле, СтараяТекущаяКолонка); КонецЕсли; Если ВыключитьРежимРедактирования Тогда ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь); КонецЕсли; КонецЕсли; Если КонтролироватьТекущиеДанные Тогда // На 8.3.8 значение в свойство строки почему то не попадает ПутьКДаннымКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если ПутьКДаннымКолонки <> "" Тогда ТекущиеДанные = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле); Попытка ЗначениеЯчейки = ТекущиеДанные[ПутьКДаннымКолонки]; ИмяДанныхПравильное = Истина; Исключение // В табличных полях компоновки ИмяДанныхПравильное = Ложь; КонецПопытки; Если ИмяДанныхПравильное Тогда Если Значение <> ЗначениеЯчейки Тогда // Такое случается в некоторых состояниях формы (пока Открыта() = Ложь) // Также это срабатывает для неподдерживаемых типов в поле ввода ТекущиеДанные[ПутьКДаннымКолонки] = Значение; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(Знач ТабличноеПоле, НоваяТекущаяКолонка) #Если Сервер И Не Сервер Тогда ТабличноеПоле = Новый ТабличноеПоле; #КонецЕсли Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущаяКолонка, НоваяТекущаяКолонка); Иначе ПрисвоитьЕслиНеРавноЛкс(ТабличноеПоле.ТекущийЭлемент, НоваяТекущаяКолонка); КонецЕсли; КонецПроцедуры Процедура ТабличноеПолеОбновитьТекстыПодваловЛкс(Знач ТабличноеПолеРезультата) Экспорт #Если Сервер И Не Сервер Тогда ТабличноеПолеРезультата = Новый ТабличноеПоле; #КонецЕсли Если Не ТабличноеПолеРезультата.Подвал Тогда Возврат; КонецЕсли; КоличествоВыделенных = ТабличноеПолеРезультата.ВыделенныеСтроки.Количество(); Если КоличествоВыделенных > 1 Тогда ВыделенныеСтроки = ирОбщий.ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПолеРезультата); Иначе ВыделенныеСтроки = Неопределено; КонецЕсли; КопияТаблицы = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПолеРезультата, ВыделенныеСтроки); #Если Сервер И Не Сервер Тогда КопияТаблицы = Новый ТаблицаЗначений; #КонецЕсли КоличествоУжеВыведено = Ложь; КоллекцияСтрок = ТабличноеПолеРезультата.Значение; Если ТипЗнч(КоллекцияСтрок) = Тип("ДеревоЗначений") Тогда КоллекцияСтрок = КоллекцияСтрок.Строки; КонецЕсли; Для Каждого Колонка Из ТабличноеПолеРезультата.Колонки Цикл Если Не Колонка.Видимость Тогда Продолжить; КонецЕсли; ДанныеКолонки = Колонка.Данные; СуммаКолонки = Неопределено; Если Истина И ЗначениеЗаполнено(ДанныеКолонки) И КоллекцияСтрок.Количество() > 0 И КопияТаблицы.Колонки.Найти(ДанныеКолонки).ТипЗначения.СодержитТип(Тип("Число")) Тогда СуммаКолонки = КопияТаблицы.Итог(ДанныеКолонки); КонецЕсли; Если СуммаКолонки = Неопределено Тогда ТекстПодвала = ""; Если Не КоличествоУжеВыведено Тогда ТекстПодвала = "N" + КопияТаблицы.Количество(); КоличествоУжеВыведено = Истина; КонецЕсли; Колонка.ТекстПодвала = ТекстПодвала; Продолжить; КонецЕсли; Если КоличествоВыделенных > 1 Тогда ТекстПодвала = "!Σ"; Иначе ТекстПодвала = "Σ"; КонецЕсли; ТекстПодвала = ТекстПодвала + СуммаКолонки; Колонка.ТекстПодвала = ТекстПодвала; Колонка.ГоризонтальноеПоложениеВПодвале = ГоризонтальноеПоложение.Право; КонецЦикла; КонецПроцедуры Процедура ТабличноеПолеКнопкаОтображенияИтоговНажатиеЛкс(Знач ТабличноеПолеРезультата, Знач Кнопка) Экспорт #Если Сервер И Не Сервер Тогда ТабличноеПолеРезультата = Новый ТабличноеПоле; #КонецЕсли Кнопка.Пометка = Не Кнопка.Пометка; ТабличноеПолеРезультата.Подвал = Кнопка.Пометка; ТабличноеПолеОбновитьТекстыПодваловЛкс(ТабличноеПолеРезультата); КонецПроцедуры // Проверяет колонку табличного поля на интерактивную доступность для редактирования. // // Параметры: // пКолонка – КолонкаТабличногоПоля. // // Возвращаемое значение: // Истина - колонка интерактивно доступна; // Ложь - иначе. // Функция ЛиИнтерактивноДоступнаяКолонкаЛкс(КолонкаТабличногоПоля) Экспорт Если Истина И КолонкаТабличногоПоля <> Неопределено И КолонкаТабличногоПоля.Доступность И КолонкаТабличногоПоля.Видимость И Не КолонкаТабличногоПоля.ТолькоПросмотр И (Ложь Или ТипЗнч(КолонкаТабличногоПоля) = Тип("ПолеФормы") Или КолонкаТабличногоПоля.ДанныеФлажка <> "" Или (Истина И КолонкаТабличногоПоля.ЭлементУправления <> Неопределено И КолонкаТабличногоПоля.ЭлементУправления.Доступность)) Тогда Попытка Если КолонкаТабличногоПоля.ЭлементУправления.ТолькоПросмотр Тогда Возврат Ложь; КонецЕсли; Исключение КонецПопытки; Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛиИнтерактивноДоступнаяКолонкаЛкс() // Копирует привязки между элементами форм. // // Параметры: // пФорма – Форма – в которую копируем; // ЭлементПриемник – ЭлементУправления; // ЭлементИсточник – ЭлементУправления. // Процедура СкопироватьПривязкиЛкс(пФорма, ЭлементПриемник, ЭлементИсточник) Экспорт Перем ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента; Границы = Новый Массив; Границы.Добавить(ГраницаЭлементаУправления.Верх); Границы.Добавить(ГраницаЭлементаУправления.Низ); Границы.Добавить(ГраницаЭлементаУправления.Лево); Границы.Добавить(ГраницаЭлементаУправления.Право); Для Каждого Граница Из Границы Цикл ЭлементИсточник.ПолучитьПривязку( Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента); Если ПервыйЭлемент <> Неопределено Тогда ПервыйЭлемент = пФорма.ЭлементыФормы.Найти(ПервыйЭлемент.Имя); Если ПервыйЭлемент = Неопределено Тогда ПервыйЭлемент = пФорма.Панель; КонецЕсли; КонецЕсли; Если ВторойЭлемент <> Неопределено Тогда ВторойЭлемент = пФорма.ЭлементыФормы.Найти(ВторойЭлемент.Имя); Если ВторойЭлемент = Неопределено Тогда ВторойЭлемент = пФорма.Панель; КонецЕсли; КонецЕсли; ЭлементПриемник.УстановитьПривязку(Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента); КонецЦикла; КонецПроцедуры // СкопироватьПривязкиЛкс() // Заполняет форму по ее макету. Используется для динамического добавления элементов // в типовые формы, чтобы облегчить их обновление. Макет формы, если явно не указан, // ищется среди форм объекта метаданных формы по имени "Лкс"+<ИмяФормы>+"Макет". // Для измененных элементов в макете к имени следует добавлять через "_" суффиксы // в соответствии с изменениями: "Привязка", "Размер", "Позиция", "Внутри" (для коллекций). // Следует вызывать в обработчике ПередОткрытием формы. // Ограничения. // 1. Без явного указания макета работает только для основной формы объекта. // 2. Нельзя добавлять элементы в панели и поля табличного документа, т.к. у элемента нельзя // определить родителя. // 3. Нельзя, чтобы форма и макет имели разные размеры. Обрабатываеся. // 4. Нельзя добавлять и изменять элементы, привязанные косвенно к низу формы. // 5. Иногда элементы, привязанные косвенно к правой границе формы неверно располагаются. // 6. Нельзя, чтобы оригинальные имена измененных элементов включали "_". Обрабатывается. // // Параметры: // пФорма – Форма – которую настраиваем; // *пМакет – Форма - макет, по которому настраиваем. // Процедура НастроитьФормуПоМакетуЛкс(пФорма, пМакетФормы) Экспорт МакетФормы = пМакетФормы; СоответствиеПривязки = Новый Соответствие; Если Ложь Или пФорма.Высота <> МакетФормы.Высота Или пФорма.Ширина <> МакетФормы.Ширина Тогда СообщитьЛкс("Не соответствие размеров формы при заполнении по макету", СтатусСообщения.Важное); КонецЕсли; //ЗаполнитьЗначенияСвойств(пФорма, МакетФормы, , "ДокументОбъект, Данные, ЭтотОбъект, Панель, ЭлементыФормы"); //ЗаполнитьЗначенияСвойств(пФорма.Панель, МакетФормы.Панель, , "Данные"); ЭлементыФормы = пФорма.ЭлементыФормы; Для Каждого ЭлементМакета Из МакетФормы.ЭлементыФормы Цикл ИмяЭлемента = ЭлементМакета.Имя; ЭлементФормы = ЭлементыФормы.Добавить(ТипЗнч(ЭлементМакета), ИмяЭлемента, Ложь, пФорма.Панель); Если ТипЗнч(ЭлементМакета) = Тип("КоманднаяПанель") Тогда ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, Кнопки, ИсточникДействий"); Если ЭлементМакета.ИсточникДействий = пМакетФормы Тогда ЭлементФормы.ИсточникДействий = пФорма; КонецЕсли; ИначеЕсли ТипЗнч(ЭлементМакета) = Тип("ТабличноеПоле") Тогда ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, ТекущаяСтрока"); Иначе ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные"); КонецЕсли; СоответствиеПривязки.Вставить(ЭлементФормы, ЭлементМакета); КонецЦикла; // Установи новые привязки Для Каждого Привязка Из СоответствиеПривязки Цикл ЭлементФормы = Привязка.Ключ; ЭлементМакета = Привязка.Значение; СкопироватьПривязкиЛкс(пФорма, ЭлементФормы, ЭлементМакета); КонецЦикла; КонецПроцедуры // НастроитьФормуПоМакетуЛкс() // Изменяет свернутость всех строк табличного поля дерева значений. // // Параметры: // ДЗ – ТабличноеПоле – связанное с деревом значений и включенным режимом Дерево; // Свернуть – Булево, *Истина - новое значение свернутости. // Процедура ДеревоЗначенийСвернутьЛкс(ДЗ, Свернуть = Ложь, Строки = Неопределено) Экспорт Если Свернуть Тогда ПредставлениеПроцесса = "Сворачиваем строки дерева"; Иначе ПредставлениеПроцесса = "Разворачиваем строки дерева"; КонецЕсли; Если Строки = Неопределено Тогда Строки = ДЗ.Значение.Строки; КонецЕсли; Индикатор = ПолучитьИндикаторПроцессаЛкс(Строки.Количество(), ПредставлениеПроцесса); Для Каждого СтрокаДерева Из Строки Цикл ОбработатьИндикаторЛкс(Индикатор); Если Истина И Свернуть И ДЗ.Развернут(СтрокаДерева) Тогда ДЗ.Свернуть(СтрокаДерева); ИначеЕсли Истина И Не Свернуть И Не ДЗ.Развернут(СтрокаДерева) Тогда ДЗ.Развернуть(СтрокаДерева, Истина); КонецЕсли; //ДеревоЗначенийСвернутьЛкс(ДЗ, Свернуть, СтрокаДерева.Строки, Индикатор); КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(Индикатор); КонецПроцедуры Процедура ДеревоКонсолиПроверкаПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки) Экспорт Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; Если ЗначениеПеретаскивания.Свойство("Тип") Тогда Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда ТекущийРодитель = Строка; Пока ТекущийРодитель <> Неопределено Цикл Если ТекущийРодитель = ЗначениеПеретаскивания.Значение Тогда ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.НеОбрабатывать; Возврат; КонецЕсли; ТекущийРодитель = ТекущийРодитель.Родитель; КонецЦикла; СтандартнаяОбработка = Ложь; ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.Копирование; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ДеревоКонсолиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, СтрокаПриемник, Колонка, ИмяТипаСроки, ИмяПоляНаименования = "Наименование") Экспорт Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; Если ЗначениеПеретаскивания.Свойство("Тип") Тогда Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда СтандартнаяОбработка = Ложь; Если СтрокаПриемник <> Неопределено Тогда РодительскаяСтрока = СтрокаПриемник; Иначе РодительскаяСтрока = Элемент.Значение; КонецЕсли; НоваяСтрокаДерева = РодительскаяСтрока.Строки.Добавить(); СкопироватьСтрокиДереваЛкс(ЗначениеПеретаскивания.Значение, НоваяСтрокаДерева); Если Истина И ЗначениеПеретаскивания.Значение.Родитель = НоваяСтрокаДерева.Родитель И ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда // Иначе ДеревоКонсолиПриОкончанииРедактированияЛкс(НоваяСтрокаДерева, ИмяПоляНаименования); КонецЕсли; Элемент.ТекущаяСтрока = НоваяСтрокаДерева; Если ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда РодительСтроки = ЗначениеПеретаскивания.Значение.Родитель; Если РодительСтроки = Неопределено Тогда РодительСтроки = Элемент.Значение; Если ЗначениеПеретаскивания.Значение.Владелец() <> РодительСтроки Тогда // Строка другой формы. Не будем ее удалять РодительСтроки = Неопределено; КонецЕсли; КонецЕсли; Если РодительСтроки <> Неопределено Тогда РодительСтроки.Строки.Удалить(ЗначениеПеретаскивания.Значение); КонецЕсли; КонецЕсли; Если Элемент.ИзменяетДанные Тогда ЭтаФорма.Модифицированность = Истина; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ДеревоКонсолиПриОкончанииРедактированияЛкс(Знач СтрокаДерева, Знач ИмяПоляНаименования = "Наименование") Экспорт РодительСтроки = ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева); СтрокаДерева[ИмяПоляНаименования] = АвтоУникальноеИмяВКоллекцииЛкс(РодительСтроки.Строки, СтрокаДерева, ИмяПоляНаименования, Ложь); КонецПроцедуры Процедура ДеревоКонсолиНачалоПеретаскиванияЛкс(Элемент, ПараметрыПеретаскивания, Выполнение, ИмяТипаСроки) Экспорт Элемент.ТекущаяСтрока = Элемент.ТекущаяСтрока; // Для сохранения изменений в строке ЗначениеПеретаскивания = Новый Структура("Тип, Значение", ИмяТипаСроки, Элемент.ТекущаяСтрока); ПараметрыПеретаскивания.Значение = ЗначениеПеретаскивания; КонецПроцедуры Процедура СкопироватьСтрокиДереваЛкс(СтрокаИсточник, СтрокаПриемник, СтопСтрока = Неопределено, Рекурсивно = Истина) Экспорт Если СтопСтрока = Неопределено Тогда Если СтрокаПриемник.Родитель <> Неопределено Тогда СтопСтрока = СтрокаПриемник.Родитель; КонецЕсли; КонецЕсли; Дерево = СтрокаПриемник.Владелец(); Для Каждого Колонка Из Дерево.Колонки Цикл СтрокаПриемник[Колонка.Имя] = КопияОбъектаЛкс(СтрокаИсточник[Колонка.Имя]); КонецЦикла; Если Рекурсивно Тогда Для Каждого Строка Из СтрокаИсточник.Строки Цикл Если Строка = СтопСтрока Тогда Продолжить; КонецЕсли; НоваяСтрока = СтрокаПриемник.Строки.Добавить(); СкопироватьСтрокиДереваЛкс(Строка, НоваяСтрока, СтопСтрока, Рекурсивно); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ИзменитьСвернутостьЛкс(ЭтаФорма, Видимость, ГлавныйЭлемент, Разделитель, Панель, Направление, ПодчиненныйЭлемент = Неопределено, ПропорциональныйРазмер = Истина) Экспорт Если Не ЭтаФорма.Открыта() Тогда // Антибаг платформы. Иначе после закрытия и затем открытия привязки могут сломаеться Возврат; КонецЕсли; Если Разделитель = Неопределено Тогда Разделитель = ГлавныйЭлемент; КонецЕсли; Если ТипЗнч(Разделитель) = Тип("Разделитель") Тогда Если Разделитель.Ориентация = Ориентация.Авто Тогда // возможно это касается только свертки вправо СообщитьЛкс("Корректная работа свертки с разделителем """ + Разделитель.Имя + """ с ориентацией Авто невозможна из-за ошибки платформы", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; //ПервыйЭлемент = 0; //ГраницаПервогоЭлемента = 0; //ВторойЭлемент = 0; //ГраницаВторогоЭлемента = 0; Если СтрокиРавныЛкс(Направление, "лево") Тогда Если Видимость Тогда // откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель, ГраницаЭлементаУправления.Право); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право); КонецЕсли; ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево); КонецЕсли; //Разделитель.Ширина = ШиринаРазделителя; Иначе // скроем Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Лево; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Лево; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право); КонецЕсли; КонецЕсли; ИначеЕсли СтрокиРавныЛкс(Направление, "право") Тогда Если Видимость Тогда // откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель, ГраницаЭлементаУправления.Право); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право); КонецЕсли; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); //Разделитель.Ширина = ШиринаРазделителя; КонецЕсли; Иначе // Скроем Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Право; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Право; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево); КонецЕсли; КонецЕсли; ИначеЕсли СтрокиРавныЛкс(Направление, "низ") Тогда Если Видимость Тогда // Откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель, ГраницаЭлементаУправления.Низ); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ); КонецЕсли; ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); КонецЕсли; //Разделитель.Высота = ШиринаРазделителя; Иначе // Скроем Если Разделитель <> ГлавныйЭлемент Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх); ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Низ; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Низ; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх); КонецЕсли; КонецЕсли; ИначеЕсли СтрокиРавныЛкс(Направление, "верх") Тогда Если Видимость Тогда // Откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель, ГраницаЭлементаУправления.Низ); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ); КонецЕсли; ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх); //Разделитель.Высота = ШиринаРазделителя; КонецЕсли; Иначе // Скроем Если Разделитель <> ГлавныйЭлемент Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ); ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Верх; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Верх; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура УстановитьТекстСОткатомЛкс(ПолеТекста, Текст) Экспорт СтарыйТекст = ПолеТекста.ПолучитьТекст(); ПолеТекста.УстановитьГраницыВыделения(1, СтрДлина(СтарыйТекст) + 1); ПолеТекста.ВыделенныйТекст = Текст; КонецПроцедуры // УстановитьТекстСОткатомЛкс() // <Описание процедуры> // // Параметры: // Ссылка – Ссылка, КлючЗаписи, КонстантаМенеджер; // ПолноеИмя - Строка - полное имя метаданных для константы. // Процедура ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс(Ссылка, ПолноеИмя = "") Экспорт Если ЛиКлючЗаписиРегистраЛкс(Ссылка) Тогда ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)); ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); ФормаСписка = ПолучитьФормуСпискаЛкс(ОбъектМетаданных.ПолноеИмя(),,,,,, Ссылка); ФормаСписка.Открыть(); ИначеЕсли ЛиКорневойТипКонстантыЛкс(ПервыйФрагментЛкс(ПолноеИмя)) Тогда ОткрытьКонстантуВСпискеЛкс(ПоследнийФрагментЛкс(ПолноеИмя)); Иначе ОткрытьЗначение(Ссылка); КонецЕсли; КонецПроцедуры // ОткрытьСсылкуИзРезультатаПоискаСсылокЛкс() Процедура ОткрытьКонстантуВСпискеЛкс(ИмяКонстанты) Экспорт ФормаСписка = ПолучитьФормуЛкс("Обработка.ирРедакторКонстант.Форма",,, ИмяКонстанты); ФормаСписка.НачальноеЗначениеВыбора = ИмяКонстанты; ФормаСписка.Открыть(); КонецПроцедуры Функция ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(Знач Элемент, Текст, ВыделитьТекстДоКонца = Ложь) Экспорт НачалоКолонки = 0; НачалоСтроки = 0; КонецКолонки = 0; КонецСтроки = 0; Элемент.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки); Элемент.Значение = Текст; //ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, Текст); // Так делать нельзя, т.к. будет засоряться история последних введенных строк Если Не ЗначениеЗаполнено(Текст) Тогда Возврат Неопределено; КонецЕсли; //Элемент.УстановитьГраницыВыделения(1, 1, КонецСтроки, КонецКолонки); Элемент.УстановитьГраницыВыделения(1, СтрДлина(Текст) + 1); Элемент.ВыделенныйТекст = Элемент.ВыделенныйТекст; Если ВыделитьТекстДоКонца Тогда Элемент.УстановитьГраницыВыделения(НачалоСтроки, СтрДлина(Текст) + 1, КонецСтроки, СтрДлина(Текст) + 1); Иначе Элемент.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки); КонецЕсли; КонецФункции Функция ПрочитатьЗначениеИзФайлаСКонтролемПотерьЛкс(ПолноеИмяФайла) Экспорт ФайлЗначения = Новый Файл(ПолноеИмяФайла); ПолученноеЗначение = Неопределено; Если ФайлЗначения.Существует() Тогда Попытка ПолученноеЗначение = ЗначениеИзФайла(ПолноеИмяФайла); Исключение СообщитьЛкс("Ошибка чтения из файла: " + ОписаниеОшибки()); КонецПопытки; КонецЕсли; Если ПолученноеЗначение = Неопределено Тогда Возврат ПолученноеЗначение; КонецЕсли; СравнениеФайлов = Новый СравнениеФайлов; ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); Если Не ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(ПолученноеЗначение) Тогда //СообщитьЛкс("Не удалось сериализовать считанные из файла данные: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат ПолученноеЗначение; КонецЕсли; Попытка ЗначениеВФайл(ИмяВременногоФайла, ПолученноеЗначение); Исключение Возврат ПолученноеЗначение; КонецПопытки; СравнениеФайлов.ПервыйФайл = ПолноеИмяФайла; СравнениеФайлов.ВторойФайл = ИмяВременногоФайла; СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное; Если Не СравнениеФайлов.Сравнить() Тогда СообщитьЛкс("При чтении из файла вероятно была потеряна часть информации", СтатусСообщения.Внимание); КонецЕсли; УдалитьФайлы(ИмяВременногоФайла); Возврат ПолученноеЗначение; КонецФункции Функция ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(Знач ПолученноеЗначение) Экспорт Если ирКэш.НомерВерсииПлатформыЛкс() >= 803012 Тогда СериализацияXMLУспешна = Истина; Иначе СериализацияXMLУспешна = Ложь; Попытка // Антибаг платформы https://bugboard.v8.1c.ru/error/000035977.html // ЗначениеВФайл на некоторых ошибках вызывает безусловное завершение работы http://devtool1c.ucoz.ru/forum/2-746-1 // http://devtool1c.ucoz.ru/forum/2-752-1 // Выполняется сильно дольше чем ЗначениеВФайл! ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(ПолученноеЗначение); СериализацияXMLУспешна = Истина; Исключение // Может быть ошибка - Отсутствует отображение для типа 'ОбходРезультатаЗапроса'. http://devtool1c.ucoz.ru/forum/2-756-1 КонецПопытки; КонецЕсли; Возврат СериализацияXMLУспешна; КонецФункции Функция НомерВерсииБСПЛкс() Экспорт Если Метаданные.РегистрыСведений.Найти("ВерсииПодсистем") <> Неопределено Тогда Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ВерсииПодсистем.Версия КАК Версия |ИЗ | РегистрСведений.ВерсииПодсистем КАК ВерсииПодсистем |ГДЕ | ВерсииПодсистем.ИмяПодсистемы = &ИмяПодсистемы |"; Запрос.УстановитьПараметр("ИмяПодсистемы", "СтандартныеПодсистемы"); Таблица = Запрос.Выполнить().Выгрузить(); Если Таблица.Количество() > 0 Тогда ВерсияБСП = Таблица[0].Версия; КонецЕсли; КонецЕсли; Возврат ВерсияБСП; КонецФункции Процедура УстановитьАвтоматическоеРаскрытиеУзловДереваЛкс(Знач ТабличноеПолеДерева, Порог = 30) Экспорт Дерево = ТабличноеПолеДерева.Значение; #Если Сервер И Не Сервер Тогда Дерево = Новый ДеревоЗначений; #КонецЕсли ДеревоЗначенийСвернутьЛкс(ТабличноеПолеДерева, ирОбщий.ВсеСтрокиДереваЗначенийЛкс(Дерево).Количество() > Порог); Если Дерево.Строки.Количество() = 1 Тогда ТабличноеПолеДерева.Развернуть(Дерево.Строки[0]); КонецЕсли; КонецПроцедуры #КонецЕсли Функция ПраваСОграничениямиДоступаКДаннымЛкс() Экспорт ДоступныеПрава = Новый СписокЗначений; ДоступныеПрава.Добавить("Чтение", "Read"); ДоступныеПрава.Добавить("Добавление", "Insert"); ДоступныеПрава.Добавить("Изменение", "Update"); ДоступныеПрава.Добавить("Удаление", "Delete"); Возврат ДоступныеПрава; КонецФункции Процедура ЗаменитьИВыделитьВыделенныйТекстПоляЛкс(ЭтаФорма, ПолеТекстаВыражения, Знач НовыйВыделенныйТекст = "") Экспорт Перем Граница1, Граница2, Граница3, Граница4; Граница1 = 0; Граница2 = 0; Граница3 = 0; Граница4 = 0; ПолеТекстаВыражения.ПолучитьГраницыВыделения(Граница1, Граница2, Граница3, Граница4); Если Не ЗначениеЗаполнено(НовыйВыделенныйТекст) Тогда Если ТипЗнч(ПолеТекстаВыражения) = Тип("ПолеВвода") Тогда НовыйВыделенныйТекст = ПолеТекстаВыражения.Значение; Иначе НовыйВыделенныйТекст = ПолеТекстаВыражения.ПолучитьТекст(); КонецЕсли; Граница2 = 1; Иначе ПолеТекстаВыражения.ВыделенныйТекст = НовыйВыделенныйТекст; КонецЕсли; ПолеТекстаВыражения.УстановитьГраницыВыделения(Граница1, Граница2, Граница1, Граница2 + СтрДлина(НовыйВыделенныйТекст)); ЭтаФорма.ТекущийЭлемент = ПолеТекстаВыражения; КонецПроцедуры // Основным элементом страницы считается одноименный с ней элемент формы. // Процедура ОбновитьЗаголовкиСтраницПанелейЛкс(ЭтаФорма) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда ЭлементыФормы = ЭтаФорма.Элементы; Иначе ЭлементыФормы = ЭтаФорма.ЭлементыФормы; КонецЕсли; Для Каждого ЭлементФормы Из ЭлементыФормы Цикл Если Истина #Если Клиент Тогда И ТипЗнч(ЭлементФормы) <> Тип("Панель") #КонецЕсли И Не (Истина И ТипЗнч(ЭлементФормы) = Тип("ГруппаФормы") И ЭлементФормы.Вид = ВидГруппыФормы.Страницы) Тогда Продолжить; КонецЕсли; ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭлементФормы); КонецЦикла; КонецПроцедуры // ОбновитьЗаголовкиСтраницПанелейЛкс() Процедура ОбновитьЗаголовокФормыСОткрытымФайломЛкс(Знач ЭтаФорма, Знач ИмяОткрытогоФайла = Неопределено, Знач АвтосохранениеТекущегоФайла = Ложь) Экспорт Если ИмяОткрытогоФайла <> "" Тогда НоваяСтрока = ""; Если АвтосохранениеТекущегоФайла Тогда НоваяСтрока = " <Автосохранение> "; КонецЕсли; НоваяСтрока = НоваяСтрока + ИмяОткрытогоФайла; Иначе НоваяСтрока = "<Новый файл>"; КонецЕсли; ОбновитьТекстПослеМаркераВСтрокеЛкс(ЭтаФорма.Заголовок, , НоваяСтрока, ": "); КонецПроцедуры // мУстановитьЗаголовокФормы() Функция ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, Панель) Экспорт ТабличноеПолеСтраниц = ЭлементыФормы.Найти("Страницы" + Панель.Имя); Если ТабличноеПолеСтраниц <> Неопределено Тогда ТаблицаСтраниц = ДанныеЭлементаФормыЛкс(ТабличноеПолеСтраниц); КонецЕсли; ОбщееКоличество = 0; НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы; #Если Сервер И Не Сервер Тогда НеготовыеСтраницы = Новый СписокЗначений; #КонецЕсли Если ТипЗнч(Панель) = Тип("ГруппаФормы") Тогда Страницы = Панель.ПодчиненныеЭлементы; Иначе Страницы = Панель.Страницы; КонецЕсли; Для Каждого Страница Из Страницы Цикл ИмяСтраницы = Страница.Имя; Если ИмяСтраницы = "" Тогда // Служебная страница. Появляется после очистки страниц. Продолжить; КонецЕсли; Если Найти("." + ИмяСтраницы, ".Страница") = 1 Тогда ИмяСтраницы = СтрЗаменить("." + ИмяСтраницы, ".Страница", ""); КонецЕсли; ЭУ = ЭлементыФормы.Найти(ИмяСтраницы); Если ЭУ = Неопределено Тогда Продолжить; КонецЕсли; ЗначениеСтраницы = Неопределено; #Если Клиент Тогда Если ТипЗнч(Страница) = Тип("СтраницаПанели") Тогда ЗначениеСтраницы = Страница.Значение; КонецЕсли; #КонецЕсли Если Ложь Или НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя) <> Неопределено Или (Истина И ТипЗнч(ЗначениеСтраницы) = Тип("Структура") И ЗначениеСтраницы.Свойство("Рассчитано") И Не ЗначениеСтраницы.Рассчитано) Тогда Количество = "-"; Иначе Суффикс = ""; Количество = Неопределено; Если Ложь #Если Клиент Тогда Или ТипЗнч(ЭУ) = Тип("ТабличноеПоле") #КонецЕсли Или ТипЗнч(ЭУ) = Тип("ТаблицаФормы") Тогда ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ЭУ); Если ТипЗнч(ЗначениеЭУ) = Тип("ДеревоЗначений") Тогда Количество = ЗначениеЭУ.Строки.Количество(); Суффикс = "*"; ИначеЕсли ТипЗнч(ЗначениеЭУ) = Тип("ДанныеФормыДерево") Тогда Количество = ЗначениеЭУ.ПолучитьЭлементы().Количество(); Суффикс = "*"; Иначе Попытка Количество = ЗначениеЭУ.Количество(); Исключение КонецПопытки; Если Количество = Неопределено Тогда // Компоновка Попытка Количество = ЗначениеЭУ.Элементы.Количество(); //Суффикс = "*"; Исключение КонецПопытки; КонецЕсли; КонецЕсли; //Если Количество = 0 Тогда // Попытка // КоличествоКолонок = ЗначениеЭУ.Колонки.Количество(); // Исключение // КоличествоКолонок = 1; // КонецПопытки; // Если КоличествоКолонок = 0 Тогда // Количество = "-"; // КонецЕсли; //КонецЕсли; #Если Клиент Тогда ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокумента") Или ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокументаФормы") Тогда //Количество = ?(ЭУ.ВысотаТаблицы > 0, 1, 0); Количество = ЭУ.ВысотаТаблицы; ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокумента") Или ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокументаФормы") Тогда //Количество = ?(ЭУ.КоличествоСтрок() > 0, 1, 0); Количество = ЭУ.КоличествоСтрок(); ИначеЕсли Ложь Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемы") Или ТипЗнч(ЭУ) = Тип("ПолеГрафическойСхемыФормы") Тогда Количество = ЭУ.ЭлементыГрафическойСхемы.Количество(); #КонецЕсли ИначеЕсли Ложь #Если Клиент Тогда Или ТипЗнч(ЭУ) = Тип("Панель") #КонецЕсли Или (Истина И ТипЗнч(ЭУ) = Тип("ГруппаФормы") И ЭУ.Вид = ВидГруппыФормы.Страницы) Тогда //Количество = ЭУ.Страницы.Количество(); //Если Количество = 1 Тогда // Если ЭУ.Страницы[0].Имя = "" Тогда // Количество = 0; // КонецЕсли; //КонецЕсли; Количество = ОбновитьЗаголовкиСтраницПанелиЛкс(ЭтаФорма, ЭлементыФормы, ЭУ); КонецЕсли; Если ТипЗнч(Количество) = Тип("Число") Тогда ОбщееКоличество = ОбщееКоличество + Количество; КонецЕсли; КонецЕсли; Если ТаблицаСтраниц <> Неопределено Тогда СтрокаСтраницы = ТаблицаСтраниц.НайтиСтроки(Новый Структура("ИмяСтраницы", ИмяСтраницы)); Если СтрокаСтраницы.Количество() > 0 Тогда СтрокаСтраницы = СтрокаСтраницы[0]; СтрокаСтраницы.Количество = Количество; СтрокаСтраницы.Непустая = СтрокаСтраницы.Количество > 0; КонецЕсли; КонецЕсли; ОбновитьТекстПослеМаркераВСтрокеЛкс(Страница.Заголовок, , "" + Количество + Суффикс + ")", "("); КонецЦикла; Возврат ОбщееКоличество; КонецФункции //Для Объект = Неопределено возвращает Ложь, работает только для русского и английского языков платформы // Параметры: // КоличествоПараметров - нужно задать заведомо большее значение, чем может быть у метода Функция МетодРеализованЛкс(Объект, ИмяМетода) Экспорт Если Объект = Неопределено Тогда Возврат Ложь; КонецЕсли; Выражение = "Объект." + ИмяМетода + "(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)"; Попытка Выполнить(Выражение); Исключение Инфо = ИнформацияОбОшибке(); Описание = Инфо.Описание; КонецПопытки; Результат = Найти(НРег(Описание), "(" + НРег(ИмяМетода) + ")") = 0; Возврат Результат; КонецФункции // Параметры: // КоличествоПроходов - Число(Н8,0) // КлючЗамера - Строка // ВыдатьСообщение - Булево // Функция НачатьЗамерЛкс(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт ирПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда ирПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров; Если Не ЗначениеЗаполнено(КлючЗамера) Тогда КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя; КонецЕсли; ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1); СтрокаЗамера = ТаблицаЗамеров.Добавить(); СтрокаЗамера.Ключ = КлючЗамера; #Если Клиент Тогда СтрокаЗамера.Отладчик = ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено; #КонецЕсли СтрокаЗамера.КоличествоПроходов = КоличествоПроходов; Если Ложь Или ВыдатьСообщение //Или СтрокаЗамера.Отладчик Тогда Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов; Если СтрокаЗамера.Отладчик Тогда Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!"; КонецЕсли; СообщитьЛкс(Сообщение); КонецЕсли; СтрокаЗамера.ДатаНачала = ТекущееВремяВМиллисекундахЛкс(); Результат = КоличествоПроходов; Возврат Результат; КонецФункции // Параметры: // КлючЗамера - Строка - По умолчанию последний замер // Функция КончитьЗамерЛкс(Знач КлючЗамера = "") Экспорт ТекущееВремя = ТекущееВремяВМиллисекундахЛкс(); ирПлатформа = ирКэш.Получить(); ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров; Если Не ЗначениеЗаполнено(КлючЗамера) Тогда Если ТаблицаЗамеров.Количество() > 0 Тогда СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1]; КонецЕсли; Иначе СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ"); КонецЕсли; Если СтрокаЗамера = Неопределено Тогда Возврат Неопределено; КонецЕсли; Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала; Длительность = Длительность / 1000; Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с"; Если СтрокаЗамера.КоличествоПроходов > 1 Тогда Среднее = Длительность / СтрокаЗамера.КоличествоПроходов; Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с"; КонецЕсли; Если Ложь Или СтрокаЗамера.Отладчик Или ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено Тогда Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!"; КонецЕсли; СообщитьЛкс(Сообщение); ТаблицаЗамеров.Удалить(СтрокаЗамера); Результат = Длительность; Возврат Результат; КонецФункции Функция ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора = Неопределено) Экспорт ВременныйПостроительЗапроса = Новый ПостроительЗапроса; ВременныйПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличноеПоле.Значение); Попытка ОтборСтрок = ТабличноеПоле.ОтборСтрок; Исключение КонецПопытки; Если ОтборСтрок <> Неопределено Тогда СкопироватьОтборПостроителяЛкс(ВременныйПостроительЗапроса.Отбор, ОтборСтрок); КонецЕсли; Если СтруктураОтбора <> Неопределено Тогда Для Каждого КлючИЗначение Из СтруктураОтбора Цикл ВременныйПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ).Установить(КлючИЗначение.Значение); КонецЦикла; КонецЕсли; Возврат ВременныйПостроительЗапроса; КонецФункции Функция ПолучитьСтруктуруВыделенияТекстаЛкс() Экспорт Структура = Новый Структура(); Структура.Вставить("НачальнаяСтрока"); Структура.Вставить("НачальнаяКолонка"); Структура.Вставить("КонечнаяСтрока"); Структура.Вставить("КонечнаяКолонка"); Возврат Структура; КонецФункции Функция ПолеТекста_ПолучитьДиапазонВыделенияЛкс(ПолеТекста) Экспорт СтруктуруВыделения = ПолучитьСтруктуруВыделенияТекстаЛкс(); ПолеТекста.ПолучитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка, СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка); Возврат СтруктуруВыделения; КонецФункции Функция ПолеТекста_УстановитьДиапазонВыделенияЛкс(Знач ПолеТекста, Знач СтруктуруВыделения) Экспорт ПолеТекста.УстановитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка, СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка); Возврат Неопределено; КонецФункции Процедура ПолеТекстовогоДокументаУстановитьВставитьТекстИПереносСтрокиЛкс(Знач ПолеТекстовогоДокумента, Знач НовыйТекст) Экспорт #Если Сервер И Не Сервер Тогда ПолеТекстовогоДокумента = Новый ТекстовыйДокумент; #КонецЕсли НачальнаяПозиция = 0; КонечнаяПозиция = 0; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция, НачальнаяПозиция, КонечнаяПозиция); ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст; // Антибаг 8.3.12 https://partners.v8.1c.ru/forum/t/1719342/m/1719342, http://www.hostedredmine.com/issues/882423 ПолеТекстовогоДокумента.ВыделенныйТекст = Символы.ПС; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяПозиция, КонечнаяПозиция, НачальнаяПозиция, КонечнаяПозиция); КонецПроцедуры // Копирует таблицу значений из исходной таблицы значений с удалением типа Null из описаний типов колонок. // Параметры: // ЗагружатьДанныеВНовуюТаблицу - Булево - после создания новой таблицы загрузить в нее данные из исходной // ОбработатьТолькоКолонки - Строка - имена колонок разделенные запятыми // НеОбрабатыватьКолонки - Строка - имена колонок разделенные запятыми // // Возвращаемое значение: // ТаблицаЗначений // Функция ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Знач Таблица, ЗагружатьДанныеВНовуюТаблицу = Истина, ОбрабатыватьТолькоКолонки = "", НеОбрабатыватьКолонки = "") Экспорт Результат = Новый ТаблицаЗначений; НовыеКолонки = Результат.Колонки; ИсходныеКолонки = Таблица.Колонки; ИменаОбрабатываемыхКолонок = Новый Массив(); Если ОбрабатыватьТолькоКолонки <> "" Тогда ИменаОбрабатываемыхКолонок = СтрРазделитьЛкс(ОбрабатыватьТолькоКолонки, ",", Истина); КонецЕсли; ИменаНеобрабатываемыхКолонок = Новый Массив(); Если НеОбрабатыватьКолонки <> "" Тогда ИменаНеобрабатываемыхКолонок = СтрРазделитьЛкс(НеОбрабатыватьКолонки, ",", Истина); КонецЕсли; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для Каждого Колонка Из ИсходныеКолонки Цикл Если Ложь Или (Истина И ОбрабатыватьТолькоКолонки <> "" И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено) Или (Истина И НеОбрабатыватьКолонки <> "" И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено) Тогда ОписаниеТипов = Колонка.ТипЗначения; Иначе ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL"); КонецЕсли; НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина); КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для Каждого Колонка Из ИсходныеКолонки Цикл   Если Ложь   Или (Истина   И ОбрабатыватьТолькоКолонки <> ""   И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено)   Или (Истина   И НеОбрабатыватьКолонки <> ""   И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено)   Тогда   ОписаниеТипов = Колонка.ТипЗначения;   Иначе   ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL");   КонецЕсли;   НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина);   КонецЦикла;   Если ЗагружатьДанныеВНовуюТаблицу Тогда ЗагрузитьВТаблицуЗначенийЛкс(Таблица, Результат); КонецЕсли; Возврат Результат; КонецФункции Функция ЛиСсылочныйОбъектМетаданных(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Истина) Экспорт Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда ПолноеИмя = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмя = ОбъектМД; КонецЕсли; МассивФрагментов = СтрРазделитьЛкс(ПолноеИмя); Если Истина И Не ДляТабличнойЧастиПроверятьРодителя И МассивФрагментов.Количество() > 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С https://www.forum.mista.ru/topic.php?id=826103#58 КонецЕсли; КонецЕсли; Возврат Ссылка; КонецФункции Функция ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(Знач Текст) Экспорт //Если СНовойСтроки Тогда // Текст = Символы.ПС + Текст; //КонецЕсли; Текст = СтрЗаменить(Текст, Символы.ПС, Символы.ПС + "|"); Текст = """" + СтрЗаменить(Текст, """", """""") + """"; Возврат Текст; КонецФункции // ПолучитьСтроковыйЛитералИзМногострочногоТекста() Функция ВсеСтрокиДереваЗначенийЛкс(СтрокаИлиДеревоЗначений, ВВидеТаблицыЗначений = Ложь) Экспорт Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда ДеревоЗначений = СтрокаИлиДеревоЗначений.Владелец(); Иначе ДеревоЗначений = СтрокаИлиДеревоЗначений; КонецЕсли; Идентификатор = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); ДеревоЗначений.Колонки.Добавить(Идентификатор); ВсеСтроки = СтрокаИлиДеревоЗначений.Строки.НайтиСтроки(Новый Структура(Идентификатор,), Истина); ДеревоЗначений.Колонки.Удалить(Идентификатор); Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда ВсеСтроки.Добавить(СтрокаИлиДеревоЗначений); КонецЕсли; Если ВВидеТаблицыЗначений Тогда ТаблицаСтрокДерева = Новый ТаблицаЗначений; Для Каждого КолонкаДерева Из ДеревоЗначений.Колонки Цикл ТаблицаСтрокДерева.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина); КонецЦикла; Для Каждого СтрокаДерева Из ВсеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтрокДерева.Добавить(), СтрокаДерева); КонецЦикла; ВсеСтроки = ТаблицаСтрокДерева; КонецЕсли; Возврат ВсеСтроки; КонецФункции // ПолучитьВсеСтрокиДереваЗначений() Функция СериализацииРавныЛкс(Таблица1, Таблица2) Экспорт Хмл1 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица1); Хмл2 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица2); Возврат (Хмл1 = Хмл2); КонецФункции // ВариантОбрезания - 1 // ВариантОбрезания - 2 Функция ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке = Неопределено, ВариантОбрезания = 2) Экспорт Если ИнформацияОбОшибке = Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); КонецЕсли; Если ВариантОбрезания = 1 Тогда ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; ИначеЕсли Истина И ВариантОбрезания = 2 И ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ИнформацияОбОшибке.Описание + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); Иначе ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; Возврат ОписаниеОшибки; КонецФункции // МаксимальнаяГлубинаПричины - на сколько уровней вниз надо опуститься, пока есть вложенная причина Функция ПредставлениеИнформацииОбОшибкеЛкс(Знач ИнформацияОбОшибке, Знач МаксимальнаяГлубинаПричины = 0, УбратьСтрокуКодаСПервогоУровня = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); #КонецЕсли ОписаниеОшибки = ""; Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда Для Счетчик = 1 По МаксимальнаяГлубинаПричины Цикл Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; #Если Сервер И Не Сервер Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); #КонецЕсли Иначе Прервать; КонецЕсли; КонецЦикла; Если УбратьСтрокуКодаСПервогоУровня Тогда ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); Иначе // Такое может случаться в свойстве ИнформацияОбОшибке объекта ФоновоеЗадание из-за ошибки платформы ОписаниеОшибки = "Описание ошибки отсутствует"; КонецЕсли; КонецЕсли; Возврат ОписаниеОшибки; КонецФункции // Первая строка табличного документа содержит заголовки Функция ТаблицаЗначенийИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок = Истина, _ДлинаСтрокиТипаКолонки = 0, ВычислятьНетипизированныеЗначения = Ложь, ЛиВтораяСтрокаСодержитТипыЗначений = Ложь, ТолькоВыделеннаяОбласть = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент #КонецЕсли Если ТолькоВыделеннаяОбласть Тогда ТабличныйДокумент = ТабличныйДокумент.ПолучитьОбласть(ТабличныйДокумент.ТекущаяОбласть.Имя); КонецЕсли; ТаблицаПриемник = Новый ТаблицаЗначений; НачальнаяСтрока = 1; Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда НачальнаяСтрока = НачальнаяСтрока + 1; КонецЕсли; Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда НачальнаяСтрока = НачальнаяСтрока + 1; КонецЕсли; ТипизированныеКолонки = Новый Соответствие; Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда ИмяКолонки = ТабличныйДокумент.Область(1, Счетчик).Текст; Если Найти(ИмяКолонки, ".") > 0 Тогда Если Найти(ИмяКолонки, "_") > 0 Тогда ВызватьИсключение "В именах колонок макета не допускается использование одновременно ""_"" и ""."""; КонецЕсли; ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_"); КонецЕсли; ИмяКолонки = АвтоУникальноеИмяВКоллекцииЛкс(ТаблицаПриемник.Колонки, ИмяКолонки,,, "Колонка1"); Иначе ИмяКолонки = "Колонка" + Счетчик; КонецЕсли; Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда ИменаТипов = ТабличныйДокумент.Область(2, Счетчик).Текст; Иначе ИменаТипов = ""; КонецЕсли; Если ЗначениеЗаполнено(ИменаТипов) Тогда ТипизированныеКолонки[Счетчик] = 1; КонецЕсли; ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов)); КонецЦикла; // Цикл перебора строк табличного документа ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы; //Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ВысотаТаблицы); Для НомерСтроки = НачальнаяСтрока По ВысотаТаблицы Цикл // Добавление строки результирующей таблицы НоваяСтрокаТЗ = ТаблицаПриемник.Добавить(); Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); ТекстЯчейки = Область.Текст; Если Не ЗначениеЗаполнено(ТекстЯчейки) Тогда Поддокумент = ТабличныйДокумент.ПолучитьОбласть(НомерСтроки, НомерКолонки); Если Поддокумент.Рисунки.Количество() > 0 Тогда ТекстЯчейки = Поддокумент.Рисунки[0].Картинка; КонецЕсли; КонецЕсли; ЗначениеЯчейки = Неопределено; Если ТипизированныеКолонки[НомерКолонки] <> Неопределено Тогда ОписаниеТиповКолонки = ТаблицаПриемник.Колонки[НомерКолонки - 1].ТипЗначения; Если ОписаниеТиповКолонки.СодержитТип(Тип("ОписаниеТипов")) Тогда Попытка ЗначениеЯчейки = Новый ОписаниеТипов(ТекстЯчейки); Исключение КонецПопытки; ИначеЕсли ОписаниеТиповКолонки.СодержитТип(Тип("Тип")) Тогда Попытка ЗначениеЯчейки = Тип(ТекстЯчейки); Исключение КонецПопытки; КонецЕсли; КонецЕсли; Если Ложь Или ВычислятьНетипизированныеЗначения Или (Истина И ТипизированныеКолонки[НомерКолонки] <> Неопределено И ЗначениеЯчейки = Неопределено) Тогда Попытка ЗначениеЯчейки = Вычислить(ТекстЯчейки); Исключение КонецПопытки; КонецЕсли; Если ЗначениеЯчейки = Неопределено Тогда ЗначениеЯчейки = ТекстЯчейки; КонецЕсли; НоваяСтрокаТЗ[НомерКолонки - 1] = ЗначениеЯчейки; КонецЦикла; КонецЦикла; Возврат ТаблицаПриемник; КонецФункции Процедура УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки) Экспорт #Если Сервер И Не Сервер Тогда ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных; ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы; Для НомерСтроки = 1 По ВысотаТаблицы Цикл Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ТипЗнч(Область.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда Для каждого ЗначениеПоля Из ДанныеРасшифровки.Элементы[Область.Расшифровка].ПолучитьПоля() Цикл Если Не ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда Продолжить; КонецЕсли; Область.Расшифровка = ЗначениеПоля.Значение; Прервать; КонецЦикла; КонецЕсли; КонецЦикла; КонецЦикла; КонецПроцедуры Функция ПолучитьИдентификаторТипаЛкс(Тип) Экспорт Результат = СтрокаМеждуМаркерамиЛкс("" + ЗначениеВСтрокуВнутр(Тип), ",", "}", Ложь); Возврат Результат; КонецФункции Функция ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(Знач ТекстПрограммы = "") Экспорт Если ПустаяСтрока(ТекстПрограммы) Тогда #Если Клиент Тогда ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс(); #Иначе ВызватьИсключение "Получение текста из буфера обмена возможно только на клиенте"; #КонецЕсли КонецЕсли; Параметры = Новый Структура(); ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой"); #Если Сервер И Не Сервер Тогда ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать(); #КонецЕсли ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно(); ПолеВстроенногоЯзыка.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина, ТекстПрограммы); СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический")); //СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова", "Свойство")); Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл Параметры.Вставить(СтрокаПеременной.Слово); КонецЦикла; Возврат Параметры; КонецФункции // КолонкиНабора - КоллекцияКолонокДереваЗначений, КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокРезультатаЗапроса Функция СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(Знач СхемаИлиМакетКомпоновкиДанных, Знач КолонкиНабора, Знач ИмяНабора = "Основной", Знач СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь) Экспорт #Если Сервер И Не Сервер Тогда СхемаИлиМакетКомпоновкиДанных = Новый СхемаКомпоновкиДанных; #КонецЕсли Результат = СхемаИлиМакетКомпоновкиДанных.НаборыДанных.Найти(ИмяНабора); Если Результат = Неопределено Тогда Результат = СхемаИлиМакетКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных")); КонецЕсли; Результат.Имя = ИмяНабора; Результат.ИсточникДанных = СхемаИлиМакетКомпоновкиДанных.ИсточникиДанных[0].Имя; Результат.ИмяОбъекта = ИмяНабора; Для Каждого ЭлементМетаданных Из КолонкиНабора Цикл Если Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаДереваЗначений") Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаТаблицыЗначений") Тогда ИмяПоля = ЭлементМетаданных.Имя; ЗаголовокПоля = ЭлементМетаданных.Заголовок; ИначеЕсли Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаРезультатаЗапроса") Тогда ИмяПоля = ЭлементМетаданных.Имя; ЗаголовокПоля = ИмяПоля; ИначеЕсли Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("ПолеНастройки") Тогда ИмяПоля = ЭлементМетаданных.Имя; ЗаголовокПоля = ЭлементМетаданных.Представление; ИначеЕсли Ложь Или ТипЗнч(ЭлементМетаданных) = Тип("ДоступноеПолеОтбораКомпоновкиДанных") Тогда ИмяПоля = "" + ЭлементМетаданных.Поле; ЗаголовокПоля = ЭлементМетаданных.Заголовок; Иначе Продолжить; КонецЕсли; Поле = Результат.Поля.Найти(ИмяПоля); Если Поле = Неопределено Тогда Если ТипЗнч(Результат) = Тип("НаборДанныхОбъектМакетаКомпоновкиДанных") Тогда Поле = Результат.Поля.Добавить(); Поле.Имя = ИмяПоля; Иначе Поле = Результат.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); Поле.Поле = ИмяПоля; КонецЕсли; КонецЕсли; ПутьКДанным = ИмяПоля; Если СоздаватьПапкиПолей Тогда ПутьКДанным = Результат.Имя + "." + ПутьКДанным; КонецЕсли; Поле.ПутьКДанным = ПутьКДанным; Если ТипЗнч(Результат) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда Поле.Заголовок = ЗаголовокПоля; Поле.ТипЗначения = ЭлементМетаданных.ТипЗначения; Если Не ирКэш.ЛиПортативныйРежимЛкс() И ЭлементМетаданных.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Поле.ВыражениеПредставления = "ирОбщий.РасширенноеПредставлениеЗначенияЛкс(" + ИмяПоля + ")"; КонецЕсли; Если Истина И СоздаватьРесурсыЧисловыхПолей И Поле.ТипЗначения.СодержитТип(Тип("Число")) Тогда Ресурс = СхемаИлиМакетКомпоновкиДанных.ПоляИтога.Добавить(); Ресурс.Выражение = "Сумма(" + ИмяПоля + ")"; Ресурс.ПутьКДанным = ИмяПоля; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Процедура ЗаполнитьПараметрыСхемыПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос) Экспорт #Если Сервер И Не Сервер Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; #КонецЕсли ОписанияПараметров = Запрос.НайтиПараметры(); // Здесь могут быть ложные ошибки синтаксического контроля Для Каждого ОписаниеПараметра Из ОписанияПараметров Цикл Если Не Запрос.Параметры.Свойство(ОписаниеПараметра.Имя) Тогда Запрос.Параметры.Вставить(ОписаниеПараметра.Имя); КонецЕсли; КонецЦикла; Для Каждого КлючИЗначение Из Запрос.Параметры Цикл ЗначениеПараметра = КлючИЗначение.Значение; Если ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда Список = Новый СписокЗначений; Список.ЗагрузитьЗначения(ЗначениеПараметра); ЗначениеПараметра = Список; КонецЕсли; ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти(КлючИЗначение.Ключ); Если ПараметрСхемы = Неопределено Тогда ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Добавить(); КонецЕсли; ПараметрСхемы.Имя = КлючИЗначение.Ключ; ПараметрСхемы.ДоступенСписокЗначений = ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений"); //Тип надо задавать, чтобы значение корректно записалось. Иначе ссылки будут преобразованы к строке. МассивТипов = Новый Массив; МассивТипов.Добавить(ТипЗнч(КлючИЗначение.Значение)); Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда ПараметрСхемы.ТипЗначения = Новый ОписаниеТипов(МассивТипов); КонецЕсли; ПараметрСхемы.Значение = ЗначениеПараметра; КонецЦикла; КонецПроцедуры Функция СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос, Знач ИмяНабора = "Основной", Представления = Неопределено, АвтоЗаполнениеДоступныхПолей = Истина) Экспорт НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновкиДанных.НаборыДанных, СхемаКомпоновкиДанных.ИсточникиДанных[0]); НаборДанных.АвтоЗаполнениеДоступныхПолей = АвтоЗаполнениеДоступныхПолей; НаборДанных.Запрос = Запрос.Текст; Если Представления <> Неопределено Тогда Для Каждого КлючИЗначение Из Представления Цикл ПолеНабора = НаборДанных.Поля.Найти(КлючИЗначение.Ключ); Если ПолеНабора = Неопределено Тогда ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); КонецЕсли; ПолеНабора.Поле = КлючИЗначение.Ключ; ПолеНабора.ПутьКДанным = КлючИЗначение.Ключ; ПолеНабора.Заголовок = КлючИЗначение.Значение; КонецЦикла; КонецЕсли; ЗаполнитьПараметрыСхемыПоЗапросуЛкс(СхемаКомпоновкиДанных, Запрос); Возврат НаборДанных; КонецФункции // Представления - Структура Функция СоздатьСхемуКомпоновкиПоЗапросу(Знач ЗапросИлиТекст, ИмяНабораДанных = "Основной", Представления = Неопределено, АвтоЗаполнениеДоступныхПолей = Истина) Экспорт СхемаКомпоновки = СоздатьСхемуКомпоновкиЛкс(); #Если Сервер И Не Сервер Тогда СхемаКомпоновки = Новый СхемаКомпоновкиДанных; #КонецЕсли Если ТипЗнч(ЗапросИлиТекст) = Тип("Строка") Тогда Запрос = Новый Запрос; Запрос.Текст = ЗапросИлиТекст; Иначе Запрос = ЗапросИлиТекст; КонецЕсли; СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(СхемаКомпоновки, Запрос, ИмяНабораДанных, Представления, АвтоЗаполнениеДоступныхПолей); Возврат СхемаКомпоновки; КонецФункции Функция КомпоновщикПоСхемеКомпоновкиЛкс(Знач Схема) Экспорт #Если Сервер И Не Сервер Тогда Схема = Новый СхемаКомпоновкиДанных; #КонецЕсли ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема); КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек); Возврат КомпоновщикНастроек; КонецФункции Функция ВыбратьВсеДоступныеПоляКомпоновки(Знач СхемаКомпоновки, Знач НастройкаКомпоновки = Неопределено) Экспорт Если НастройкаКомпоновки = Неопределено Тогда НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; КонецЕсли; КомпоновщикНастройки = Новый КомпоновщикНастроекКомпоновкиДанных; КомпоновщикНастройки.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки)); КомпоновщикНастройки.ЗагрузитьНастройки(НастройкаКомпоновки); Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); Иначе ЭлементСтруктуры = НастройкаКомпоновки.Структура[0]; КонецЕсли; ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); Для Каждого ДоступноеПоле Из КомпоновщикНастройки.Настройки.ДоступныеПоляВыбора.Элементы Цикл // Чтобы пропустить системные папки Если Не ДоступноеПоле.Папка Тогда НовоеВыбранноеПоле = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле; НовоеВыбранноеПоле.Использование = Истина; КонецЕсли; КонецЦикла; Возврат НастройкаКомпоновки; КонецФункции Функция ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(Знач ПолноеИмяИлиОбъектМД, ИмяНабораДанных = "Основной", ДобавитьАвтополеКоличествоСтрок = Истина, ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда ПолноеИмяМД = ПолноеИмяИлиОбъектМД; Иначе ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя(); КонецЕсли; ПолноеИмяТаблицыБД = ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД); Схема = ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность, ДобавитьАвтополеКоличествоСтрок, ИндексПараметраПериодичность, ПсевдонимТаблицы, ИменаВместоПредставлений); Возврат Схема; КонецФункции Функция ПоляТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, _ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Запрос = Новый Запрос; Запрос.Текст = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность) + " ГДЕ ЛОЖЬ"; Попытка ТаблицаРезультата = Запрос.Выполнить().Выгрузить(); Исключение // Долгий способ пробуем только если быстрый не удался ПостроительЗапроса = Новый ПостроительЗапроса; Попытка ПостроительЗапроса.Текст = Запрос.Текст; ПостроительЗапроса.ЗаполнитьНастройки(); Исключение //Если ВызыватьИсключениеПриОтсутствииПрав Тогда // ВызватьИсключение; //КонецЕсли; СообщитьЛкс(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке().Причина)); Возврат Неопределено; КонецПопытки; ТаблицаРезультата = Новый ТаблицаЗначений; Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл ТаблицаРезультата.Колонки.Добавить(ДоступноеПоле.ПутьКДанным, ДоступноеПоле.ТипЗначения); КонецЦикла; КонецПопытки; Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя"); Результат.Колонки.Добавить("ТипЗначения"); Результат.Колонки.Добавить("Метаданные"); Результат.Колонки.Добавить("Заголовок"); ПоляТаблицы = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаРезультата).Колонки; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл СтрокаПоля = Результат.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы); КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл   СтрокаПоля = Результат.Добавить();   ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы);   КонецЦикла;   ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД); Если Истина И ТипТаблицы <> "ДвиженияССубконто" //И ТипТаблицы <> "ВиртуальнаяТаблица" Тогда ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина); Если ОбъектМД <> Неопределено Тогда Если ТипТаблицы = "Внешняя" Тогда Для Каждого ПолеТаблицы Из ОбъектМД.Поля Цикл СтрокаПоля = Результат.Найти(ПолеТаблицы.Имя, "Имя"); Если СтрокаПоля <> Неопределено Тогда СтрокаПоля.Метаданные = ПолеТаблицы; Заголовок = ПолеТаблицы.Представление(); Если ЗначениеЗаполнено(Заголовок) Тогда СтрокаПоля.Заголовок = Заголовок; КонецЕсли; КонецЕсли; КонецЦикла; Иначе ПрефиксРеквизита = ОбъектМД.ПолноеИмя() + ".Реквизит."; РодительМД = ОбъектМД.Родитель(); Если Истина И ТипТаблицы <> "Перерасчет" И ТипТаблицы <> "Внешняя" И ТипЗнч(РодительМД) <> Тип("ОбъектМетаданныхКонфигурация") Тогда ОбъектМДФильтра = РодительМД; Иначе ОбъектМДФильтра = ОбъектМД; КонецЕсли; ФильтрМетаданных = Новый Массив; ФильтрМетаданных.Добавить(ОбъектМДФильтра); //Если ТипТаблицы = "ДвиженияССубконто" Тогда // ПолноеИмяТаблицыБД = Лев(ПолноеИмяТаблицыБД, СтрДлина(ПолноеИмяТаблицыБД) - СТрДлина(".ДвиженияССубконто")); //КонецЕсли; НуженПеревод = Неопределено; СтруктураХраненияТаблиц = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных); ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(СтруктураХраненияТаблиц, НуженПеревод); СтрокиСтруктурыТаблицы = СтруктураХраненияТаблиц.НайтиСтроки(Новый Структура("ИмяТаблицы", ПолноеИмяТаблицыБД)); Если Истина И СтрокиСтруктурыТаблицы.Количество() = 0 И ТипТаблицы = "ВиртуальнаяТаблица" Тогда СтрокиСтруктурыТаблицы = СтруктураХраненияТаблиц.НайтиСтроки(Новый Структура("Назначение", "Основная")); КонецЕсли; Если СтрокиСтруктурыТаблицы.Количество() = 0 Тогда Если Истина И ТипТаблицы <> "Изменения" И ТипТаблицы <> "Константа" //И ТипТаблицы <> "Границы" //И ТипТаблицы <> "ЗадачиПоИсполнителю" Тогда СообщитьЛкс("Не удалось найти в структуре хранения БД описание таблицы " + ПолноеИмяТаблицыБД); Иначе // Для отладки // Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы. // Сюда попадаем для границ последовательностей, у которых ошибочно пустое имя таблицы. Пустышка = 1; КонецЕсли; Иначе Если СтрокиСтруктурыТаблицы.Количество() > 1 Тогда Пустышка = 1; // Для отладки. Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы КонецЕсли; ТаблицаПолей = СтрокиСтруктурыТаблицы[0].Поля; Если НуженПеревод Тогда ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(ТаблицаПолей, НуженПеревод); КонецЕсли; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для Каждого ПолеТаблицы Из ТаблицаПолей Цикл Если Истина И ЗначениеЗаполнено(ПолеТаблицы.Метаданные) И (Ложь Или ПолеТаблицы.ИмяПоля <> "НомерСтроки" Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0) Тогда СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя"); Если СтрокаПоля <> Неопределено Тогда Если Найти(ПолеТаблицы.Метаданные, ПрефиксРеквизита) = 1 Тогда // Для ускорения СтрокаПоля.Метаданные = ОбъектМД.Реквизиты[ПоследнийФрагментЛкс(ПолеТаблицы.Метаданные)]; Иначе СтрокаПоля.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолеТаблицы.Метаданные); КонецЕсли; Заголовок = СтрокаПоля.Метаданные.Представление(); Если ЗначениеЗаполнено(Заголовок) Тогда СтрокаПоля.Заголовок = Заголовок; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для Каждого ПолеТаблицы Из ТаблицаПолей Цикл   Если Истина   И ЗначениеЗаполнено(ПолеТаблицы.Метаданные)   И (Ложь   Или ПолеТаблицы.ИмяПоля <> "НомерСтроки"   Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 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].Синоним); // КонецЕсли //КонецЕсли; ЭлементПорядка = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных")); ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); КонецПроцедуры Функция ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность = Неопределено, ДобавитьАвтополеКоличествоСтрок = Истина, Знач ИндексПараметраПериодичность = Неопределено, Знач ПсевдонимТаблицы = "Т", ИменаВместоПредставлений = Ложь, РасширенноеЗаполнение = Ложь, КоличествоПервых = 0) Экспорт СхемаКомпоновки = СоздатьСхемуКомпоновкиЛкс(); #Если Сервер И Не Сервер Тогда СхемаКомпоновки = Новый СхемаКомпоновкиДанных; #КонецЕсли НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновки.НаборыДанных, СхемаКомпоновки.ИсточникиДанных[0]); #Если Сервер И Не Сервер Тогда НаборДанных = СхемаКомпоновки.НаборыДанных.Добавить(); #КонецЕсли НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина; НаборДанных.Запрос = ПолучитьТекстЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ПсевдонимТаблицы, Ложь, КоличествоПервых); Если ДобавитьАвтополеКоличествоСтрок Тогда ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновки); КонецЕсли; Если Ложь Или ИменаВместоПредставлений Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 // Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей Тогда Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос); Построитель.ЗаполнитьНастройки(); Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным; //ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным; Если ИменаВместоПредставлений Тогда ПолеНабора.Заголовок = ДоступноеПоле.Имя; Иначе ПолеНабора.Заголовок = ДоступноеПоле.Представление; КонецЕсли; КонецЦикла; КонецЕсли; Если РасширенноеЗаполнение Тогда ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновки); ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновки.НастройкиПоУмолчанию); ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновки.НастройкиПоУмолчанию); //БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода( // Отчет.КомпоновщикНастроек, "Title", Метаданные[Отчет.ТипДанных][Отчет.ИмяОбъекта].Синоним); //БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода( // Отчет.КомпоновщикНастроек, "TitleOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить); //БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода( // Отчет.КомпоновщикНастроек, "FilterOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить); //БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода( // Отчет.КомпоновщикНастроек, "DataParametersOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить); КонецЕсли; Возврат СхемаКомпоновки; КонецФункции Функция ПолучитьТекстЗапросаПолейТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = Неопределено, ПсевдонимТаблицы = "Т", Знач БлокироватьПолучениеДанных = Истина, КоличествоПервых = 0) Экспорт ТипТаблицы = ПервыйФрагментЛкс(ПолноеИмяТаблицыБД); // Оптимизация. Первые 2 ветки предотвращают вызов тяжелой функции ОписаниеТаблицыБДЛкс, но не являются логически необходимыми Если СтрЧислоВхождений(ПолноеИмяТаблицыБД, ".") = 1 Тогда Если ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяТаблицыБД) <> Неопределено Тогда ОписаниеТаблицы = Новый Структура("ИндексПараметраОтбора"); КонецЕсли; ИначеЕсли СтрокиРавныЛкс(ПолноеИмяТаблицыБД, "Константы") Тогда ОписаниеТаблицы = Новый Структура("ИндексПараметраОтбора"); Иначе ОписаниеТаблицы = ОписаниеТаблицыБДЛкс(ПолноеИмяТаблицыБД); КонецЕсли; Если ОписаниеТаблицы = Неопределено Тогда ВызватьИсключение "Таблица БД с именем " + ПолноеИмяТаблицыБД + " не найдена"; КонецЕсли; ПараметрыВиртуальнойТаблицы = ""; Если БлокироватьПолучениеДанных И ОписаниеТаблицы <> Неопределено Тогда ИндексПараметраОтбора = ОписаниеТаблицы.ИндексПараметраОтбора; Иначе ИндексПараметраОтбора = Неопределено; КонецЕсли; МаксимальныйИндекс = ИндексПараметраОтбора; Если ИндексПараметраПериодичность <> Неопределено Тогда Если МаксимальныйИндекс <> Неопределено Тогда МаксимальныйИндекс = Макс(МаксимальныйИндекс, ИндексПараметраПериодичность); Иначе МаксимальныйИндекс = ИндексПараметраПериодичность; КонецЕсли; КонецЕсли; Если МаксимальныйИндекс <> Неопределено Тогда МассивВыраженийПараметров = Новый Массив; Для Счетчик = 0 По МаксимальныйИндекс Цикл МассивВыраженийПараметров.Добавить(""); КонецЦикла; Если ИндексПараметраОтбора <> Неопределено Тогда МассивВыраженийПараметров[ИндексПараметраОтбора] = "ЛОЖЬ"; КонецЕсли; Если ИндексПараметраПериодичность <> Неопределено Тогда МассивВыраженийПараметров[ИндексПараметраПериодичность] = ВыражениеПараметраПериодичность; КонецЕсли; ПараметрыВиртуальнойТаблицы = ирОбщий.СтрСоединитьЛкс(МассивВыраженийПараметров); КонецЕсли; Если ЗначениеЗаполнено(ПараметрыВиртуальнойТаблицы) Тогда ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(" + ПараметрыВиртуальнойТаблицы + ")"; КонецЕсли; Если Не ЗначениеЗаполнено(ПсевдонимТаблицы) Тогда ПсевдонимТаблицы = "Т"; КонецЕсли; ТекстЗапроса = "ВЫБРАТЬ "; Если ЗначениеЗаполнено(КоличествоПервых) Тогда ТекстЗапроса = ТекстЗапроса + "ПЕРВЫЕ " + XMLСтрока(КоличествоПервых) + " "; КонецЕсли; ТекстЗапроса = ТекстЗапроса + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы; Возврат ТекстЗапроса; КонецФункции Функция ДобавитьДоступнуюТаблицуБДЛкс(ДоступныеТаблицыБД, ПолноеИмя, ПолноеИмяМД = "", ТипТаблицы = "", Имя = "", Представление = "", СхемаТаблицы = "", ПроверятьУникальность = Ложь, ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено) Экспорт Если Не ЗначениеЗаполнено(ПолноеИмя) Тогда ПолноеИмя = ПолноеИмяМД; КонецЕсли; Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмя); Если Фрагменты.Количество() > 1 Тогда //Если Не ЗначениеЗаполнено(СхемаТаблицы) Тогда // СхемаТаблицы = Фрагменты[0]; //КонецЕсли; Фрагменты.Удалить(0); КонецЕсли; Если ПроверятьУникальность Тогда СтрокаТаблицы = ДоступныеТаблицыБД.Найти(НРег(ПолноеИмя), "НПолноеИмя"); Иначе СтрокаТаблицы = Неопределено; КонецЕсли; Если СтрокаТаблицы = Неопределено Тогда СтрокаТаблицы = ДоступныеТаблицыБД.Добавить(); СтрокаТаблицы.Схема = СхемаТаблицы; СтрокаТаблицы.ПолноеИмяМД = ПолноеИмяМД; СтрокаТаблицы.ПолноеИмя = ПолноеИмя; СтрокаТаблицы.НПолноеИмя = НРег(СтрокаТаблицы.ПолноеИмя); СтрокаТаблицы.ИндексПараметраОтбора = ИндексПараметраОтбора; Если Не ЗначениеЗаполнено(Имя) Тогда СтрокаТаблицы.Имя = ирОбщий.СтрСоединитьЛкс(Фрагменты, "."); Иначе СтрокаТаблицы.Имя = Имя; КонецЕсли; СтрокаТаблицы.Представление = Представление; Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмя); КонецЕсли; СтрокаТаблицы.Тип = ТипТаблицы; Если ТипТаблицы = "Перерасчет" Тогда МетаРегистрРасчета = ОбъектМД.Родитель(); СтрокаТаблицы.Имя = МетаРегистрРасчета.Имя + "." + СтрокаТаблицы.Имя; СтрокаТаблицы.Представление = МетаРегистрРасчета.Представление() + "." + СтрокаТаблицы.Представление; КонецЕсли; //СтрокаТаблицы.Описание = МетаИсточник.Представление(); КонецЕсли; Возврат СтрокаТаблицы; КонецФункции Функция ПолучитьИндексКартинкиТипаТаблицыБДЛкс(Знач ТипТаблицы) Экспорт ТипТаблицы = ПеревестиВРусский(ТипТаблицы); ИндексКартинки = 14; Если ТипТаблицы = "Константы" Тогда ИндексКартинки = 2; ИначеЕсли ТипТаблицы = "Константа" Тогда ИндексКартинки = 2; //ИначеЕсли ТипТаблицы = "ТабличнаяЧасть" Тогда ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда ИндексКартинки = 20; ИначеЕсли ТипТаблицы = "Изменения" Тогда ИндексКартинки = 27; ИначеЕсли ТипТаблицы = "ВиртуальнаяТаблица" Тогда ИндексКартинки = 28; ИначеЕсли ТипТаблицы = "ВнешнийИсточникДанных" Тогда ИндексКартинки = 29; ИначеЕсли ТипТаблицы = "Справочник" Тогда ИндексКартинки = 3; ИначеЕсли ТипТаблицы = "Перечисление" Тогда ИндексКартинки = 4; ИначеЕсли ТипТаблицы = "Документ" Тогда ИндексКартинки = 5; ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда ИндексКартинки = 6; ИначеЕсли ТипТаблицы = "Последовательность" Тогда ИндексКартинки = 7; ИначеЕсли ТипТаблицы = "РегистрНакопления" Тогда ИндексКартинки = 8; ИначеЕсли ТипТаблицы = "РегистрСведений" Тогда ИндексКартинки = 9; ИначеЕсли ТипТаблицы = "РегистрБухгалтерии" Тогда ИндексКартинки = 10; ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда ИндексКартинки = 11; ИначеЕсли ТипТаблицы = "ПланОбмена" Тогда ИндексКартинки = 19; ИначеЕсли ТипТаблицы = "Задача" Тогда ИндексКартинки = 17; ИначеЕсли ТипТаблицы = "БизнесПроцесс" Тогда ИндексКартинки = 18; ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда ИндексКартинки = 26; ИначеЕсли ТипТаблицы = "ПланВидовРасчета" Тогда ИндексКартинки = 25; ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда ИндексКартинки = 22; ИначеЕсли ТипТаблицы = "Перечисление" Тогда ИндексКартинки = 23; ИначеЕсли ТипТаблицы = "ПланСчетов" Тогда ИндексКартинки = 24; ИначеЕсли ТипТаблицы = "Перерасчет" Тогда ИндексКартинки = 30; ИначеЕсли СтрокиРавныЛкс(ТипТаблицы, "Table") Тогда ИндексКартинки = 3; КонецЕсли; Возврат ИндексКартинки; КонецФункции Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПредставлениюЛкс(Знач ЭлементыНастройки, Знач Представление = "", Знач ПроверятьУникальность = Истина, Знач ИспользованиеДляНового = Истина) Экспорт Попытка ЭлементыНастройки = ЭлементыНастройки.Элементы; Исключение КонецПопытки; Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных"); ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда ТипЭлемента = Неопределено; КонецЕсли; Если ПроверятьУникальность Тогда ЭлементНастроек = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыНастройки, "Представление", Представление, ТипЭлемента); КонецЕсли; Если ЭлементНастроек = Неопределено Тогда Если ТипЭлемента <> Неопределено Тогда ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента); Иначе ЭлементНастроек = ЭлементыНастройки.Добавить(); КонецЕсли; ЭлементНастроек.Представление = Представление; ЭлементНастроек.Использование = ИспользованиеДляНового; КонецЕсли; Возврат ЭлементНастроек; КонецФункции // Параметры: // ЭлементыНастройки - ТабличноеПоле, ЭлементыНастроек Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = "", Знач ПроверятьУникальность = Истина, Знач ИспользованиеДляНового = Истина, выхСтандартнаяОбработка = Истина) Экспорт ТабличноеПоле = Неопределено; #Если Клиент Тогда Если ТипЗнч(ЭлементыНастройки) = Тип("ТабличноеПоле") Тогда ТабличноеПоле = ЭлементыНастройки; ЭлементыНастройки = ТабличноеПоле.Значение; КонецЕсли; #КонецЕсли Если ТипЗнч(Поле) = Тип("Строка") Тогда Поле = Новый ПолеКомпоновкиДанных(Поле); КонецЕсли; Попытка ЭлементыНастройки = ЭлементыНастройки.Элементы; Исключение КонецПопытки; ТипЭлемента = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки); Если ПроверятьУникальность Тогда ЭлементНастроек = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементыНастройки, Поле,, ТипЭлемента); КонецЕсли; Если ЭлементНастроек = Неопределено Тогда Если ТипЭлемента <> Неопределено Тогда ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента); Иначе ЭлементНастроек = ЭлементыНастройки.Добавить(); КонецЕсли; ЭлементНастроек.Поле = Поле; ЭлементНастроек.Использование = ИспользованиеДляНового; КонецЕсли; Если ТабличноеПоле <> Неопределено Тогда ТабличноеПоле.ТекущаяСтрока = ЭлементНастроек; выхСтандартнаяОбработка = Ложь; КонецЕсли; Возврат ЭлементНастроек; КонецФункции Функция ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки) Экспорт Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовПорядкаКомпоновкиДанных") Тогда ТипЭлемента = Тип("ЭлементПорядкаКомпоновкиДанных"); ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияВыбранныхПолейКомпоновкиДанных") Тогда ТипЭлемента = Тип("ВыбранноеПолеКомпоновкиДанных"); ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияПолейГруппировкиКомпоновкиДанных") Тогда ТипЭлемента = Тип("ПолеГруппировкиКомпоновкиДанных"); ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда ТипЭлемента = Неопределено; ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных"); ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("ОформляемыеПоляКомпоновкиДанных") Тогда ТипЭлемента = Тип("ОформляемоеПолеКомпоновкиДанных"); КонецЕсли; Возврат ТипЭлемента; КонецФункции // Параметры: // Поле - ПолеКомпоновкиДанных, Строка - если не заполнено, то подходит любое имя поля // ВсеНайденныеПоля - Массив - если Массив, то находим все поля Функция НайтиЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = Неопределено, Знач ТолькоВключенный = Ложь, ТипЭлементаРекурсия = Неопределено, ВсеНайденныеПоля = Неопределено) Экспорт Если ТипЗнч(Поле) = Тип("Строка") Тогда Поле = Новый ПолеКомпоновкиДанных(Поле); КонецЕсли; Если ТипЭлементаРекурсия = Неопределено Тогда ТипЭлементаРекурсия = ТипЭлементаИзТипаКоллекцииКомпоновкиЛкс(ЭлементыНастройки); КонецЕсли; //ИскомоеПолеЗаполнено = ЗначениеЗаполнено(Поле); // Не поддерживается в 8.2 http://www.hostedredmine.com/issues/878299 ИскомоеПолеЗаполнено = ЗначениеЗаполнено("" + Поле); Для Каждого ЭлементНастроек Из ЭлементыНастройки Цикл Если Истина И ТипЭлементаРекурсия <> Неопределено И ТипЗнч(ЭлементНастроек) <> ТипЭлементаРекурсия Тогда Попытка ДочерниеЭлементыНастройки = ЭлементНастроек.Элементы; Исключение ДочерниеЭлементыНастройки = Неопределено; КонецПопытки; Если ДочерниеЭлементыНастройки <> Неопределено Тогда НайденныйЭлемент = НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ДочерниеЭлементыНастройки, Поле, ТолькоВключенный, ТипЭлементаРекурсия, ВсеНайденныеПоля); Если НайденныйЭлемент <> Неопределено Тогда Если ВсеНайденныеПоля <> Неопределено Тогда ВсеНайденныеПоля.Добавить(НайденныйЭлемент); Иначе Прервать; КонецЕсли; КонецЕсли; КонецЕсли; Иначе Если ТипЭлементаРекурсия = Тип("ЭлементОтбораКомпоновкиДанных") Тогда ПолеЭлемента = ЭлементНастроек.ЛевоеЗначение; Иначе ПолеЭлемента = ЭлементНастроек.Поле; КонецЕсли; Если Истина И (Ложь Или ПолеЭлемента = Поле Или Не ИскомоеПолеЗаполнено) И (Ложь Или Не ТолькоВключенный Или ЭлементНастроек.Использование) Тогда НайденныйЭлемент = ЭлементНастроек; Если ВсеНайденныеПоля <> Неопределено Тогда ВсеНайденныеПоля.Добавить(НайденныйЭлемент); Иначе Прервать; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Если ВсеНайденныеПоля <> Неопределено И ВсеНайденныеПоля.Количество() > 0 Тогда НайденныйЭлемент = ВсеНайденныеПоля[0]; КонецЕсли; Возврат НайденныйЭлемент; КонецФункции Функция НайтиЭлементУсловногоОформленияПоПолюЛкс(Знач УсловноеОформление, Знач Поле, Знач ТолькоВключенный = Ложь, выхЭлементПоля = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда УсловноеОформление = Новый НастройкиКомпоновкиДанных; УсловноеОформление = УсловноеОформление.УсловноеОформление; #КонецЕсли Для Каждого ЭлементОформления Из УсловноеОформление.Элементы Цикл ЭлементПоля = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементОформления.Поля.Элементы, Поле, ТолькоВключенный); Если ЭлементПоля <> Неопределено Тогда выхЭлементПоля = ЭлементПоля; Возврат ЭлементОформления; КонецЕсли; ЭлементОтбора = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементОформления.Отбор.Элементы, Поле, ТолькоВключенный); Если ЭлементОтбора <> Неопределено Тогда выхЭлементПоля = ЭлементОтбора; Возврат ЭлементОформления; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции Функция НайтиЭлементНастроекКомпоновкиПоПолюПоВсейСтруктуреЛкс(Знач КорневойЭлементСтруктуры, Знач Поле, Знач ТолькоВключенный = Ложь, Знач ТипНастроек = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда КорневойЭлементСтруктуры = Новый НастройкиКомпоновкиДанных; #КонецЕсли ВсеГруппировки = ВсеГруппировкиКомпоновкиЛкс(КорневойЭлементСтруктуры.Структура); ВсеГруппировки.Добавить(КорневойЭлементСтруктуры); Результат = Новый Структура("ЭлементСтруктуры, ЭлементНастройки, ЭлементНастройки2"); Для Каждого ЭлементСтруктуры Из ВсеГруппировки Цикл ПолеНайдено = Ложь; Если Истина И Не ПолеНайдено И ТипЗнч(ЭлементСтруктуры) <> Тип("НастройкиКомпоновкиДанных") И (Ложь Или ТипНастроек = Неопределено Или ТипНастроек = Тип("ПолеГруппировкиКомпоновкиДанных")) Тогда ПолеГруппировки = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.ПоляГруппировки.Элементы, Поле, ТолькоВключенный); Если ПолеГруппировки <> Неопределено Тогда Результат.ЭлементСтруктуры = ЭлементСтруктуры; Результат.ЭлементНастройки = ПолеГруппировки; Возврат Результат; КонецЕсли; КонецЕсли; Если Истина И Не ПолеНайдено И (Ложь Или ТипНастроек = Неопределено Или ТипНастроек = Тип("ВыбранныеПоляКомпоновкиДанных")) Тогда ВыбранноеПоле = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.Выбор.Элементы, Поле, ТолькоВключенный); Если ВыбранноеПоле <> Неопределено Тогда Результат.ЭлементСтруктуры = ЭлементСтруктуры; Результат.ЭлементНастройки = ВыбранноеПоле; Возврат Результат; КонецЕсли; КонецЕсли; Если Истина И Не ПолеНайдено И (Ложь Или ТипНастроек = Неопределено Или ТипНастроек = Тип("ПорядокКомпоновкиДанных")) Тогда ЭлементПорядка = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.Порядок.Элементы, Поле, ТолькоВключенный); Если ЭлементПорядка <> Неопределено Тогда Результат.ЭлементСтруктуры = ЭлементСтруктуры; Результат.ЭлементНастройки = ЭлементПорядка; Возврат Результат; КонецЕсли; КонецЕсли; Если Истина И Не ПолеНайдено И (Ложь Или ТипНастроек = Неопределено Или ТипНастроек = Тип("ОтборКомпоновкиДанных")) Тогда ЭлементОтбора = ирОбщий.НайтиЭлементНастроекКомпоновкиПоПолюЛкс(ЭлементСтруктуры.Отбор.Элементы, Поле, ТолькоВключенный); Если ЭлементОтбора <> Неопределено Тогда Результат.ЭлементСтруктуры = ЭлементСтруктуры; Результат.ЭлементНастройки = ЭлементОтбора; Возврат Результат; КонецЕсли; КонецЕсли; Если Истина И Не ПолеНайдено И (Ложь Или ТипНастроек = Неопределено Или ТипНастроек = Тип("УсловноеОформлениеКомпоновкиДанных")) Тогда ЭлементПоля = Неопределено; ЭлементОФормления = ирОбщий.НайтиЭлементУсловногоОформленияПоПолюЛкс(ЭлементСтруктуры.УсловноеОформление, Поле, ТолькоВключенный, ЭлементПоля); Если ЭлементОФормления <> Неопределено Тогда Результат.ЭлементСтруктуры = ЭлементСтруктуры; Результат.ЭлементНастройки = ЭлементОФормления; Результат.ЭлементНастройки2 = ЭлементПоля; Возврат Результат; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции Функция ВсеГруппировкиКомпоновкиЛкс(Группировки, Знач ТолькоВключенный = Ложь, МассивЭлементов = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Группировки = Новый НастройкиКомпоновкиДанных; Группировки = Группировки.Структура; #КонецЕсли Если МассивЭлементов = Неопределено Тогда МассивЭлементов = Новый Массив; КонецЕсли; Для Каждого Группировка Из Группировки Цикл ТипЭлемента = Тип(Группировка); Если Ложь Или ТипЭлемента = Тип("ГруппировкаДиаграммыКомпоновкиДанных") Или ТипЭлемента = Тип("ГруппировкаКомпоновкиДанных") Или ТипЭлемента = Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда ВсеГруппировкиКомпоновкиЛкс(Группировка.Структура, ТолькоВключенный, МассивЭлементов); Если Ложь Или ТолькоВключенный Или Группировка.Использование Тогда МассивЭлементов.Добавить(Группировка); КонецЕсли; ИначеЕсли ТипЭлемента = Тип("ТаблицаКомпоновкиДанных") Тогда ВсеГруппировкиКомпоновкиЛкс(Группировка.Строки, ТолькоВключенный, МассивЭлементов); ВсеГруппировкиКомпоновкиЛкс(Группировка.Колонки, ТолькоВключенный, МассивЭлементов); Иначе Продолжить; КонецЕсли; КонецЦикла; Возврат МассивЭлементов; КонецФункции // Параметры: // ВыбранныеПоля - - // ТолькоВключенные - - // МассивРезультата - - // ВернутьТолькоПоля - Булево - вместо выбранных полей вернуть поля // // Возвращаемое значение: // - // Функция ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(Знач ВыбранныеПоля, Знач ТолькоВключенные = Ложь, МассивРезультата = Неопределено, ВернутьТолькоПоля = Ложь) Экспорт Если МассивРезультата <> Неопределено Тогда Результат = МассивРезультата; Иначе Результат = Новый Массив(); КонецЕсли; Для Каждого ВыбранноеПоле Из ВыбранныеПоля.Элементы Цикл Если ТипЗнч(ВыбранноеПоле) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда РезультатВложенный = ВсеВыбранныеПоляГруппировкиКомпоновкиЛкс(ВыбранноеПоле, ТолькоВключенные, Результат, ВернутьТолькоПоля); ИначеЕсли ТипЗнч(ВыбранноеПоле) = Тип("АвтоВыбранноеПолеКомпоновкиДанных") Тогда Пустышка = 0; Иначе Если Ложь Или Не ТолькоВключенные Или ВыбранноеПоле.Использование Тогда Если ВернутьТолькоПоля Тогда Результат.Добавить(ВыбранноеПоле.Поле); Иначе Результат.Добавить(ВыбранноеПоле); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ПолеИзОписанияОшибкиЛкс(ОписаниеОшибки) Экспорт // {Обработка.ирКонсольКомпоновокДанных.Форма.Форма.Форма(503)}: Ошибка при вызове метода контекста (Выполнить): Ошибка компоновки макета: Поле не найдено "НомерВерсииПлатформы" Результат = СтрокаМеждуМаркерамиЛкс(ОписаниеОшибки, "Поле не найдено """, """", Ложь); Возврат Результат; КонецФункции Функция НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(Знач Группировки, Знач Поле = "", Добавлять = Истина, НовоеИспользование = Истина) Экспорт Если ТипЗнч(Поле) = Тип("Строка") Тогда Поле = Новый ПолеКомпоновкиДанных(Поле); КонецЕсли; Группировка = НайтиГруппировкуКомпоновкиПоПолюЛкс(Группировки, Поле); Если Истина И Добавлять И Группировка = Неопределено Тогда Если ТипЗнч(Группировки) = Тип("КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных") Тогда Группировка = Группировки.Добавить(Тип("ГруппировкаКомпоновкиДанных")); Иначе Группировка = Группировки.Добавить(); КонецЕсли; Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных")); Если "" + Поле <> "" Тогда ПолеГруппировки = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных")); ПолеГруппировки.Поле = Поле; КонецЕсли; ЭлементСуществует = Истина; КонецЕсли; Если ЭлементСуществует Тогда Если НовоеИспользование <> Неопределено Тогда Группировка.Использование = НовоеИспользование; КонецЕсли; Результат = Группировка; Иначе Результат = Неопределено; КонецЕсли; Возврат Результат; КонецФункции Функция НайтиГруппировкуКомпоновкиПоПолюЛкс(Знач Группировки, Знач Поле) Экспорт ГруппировкаПоИскомомуПолю = Неопределено; Для Каждого Группировка Из Группировки Цикл Поля = Группировка.ПоляГруппировки.Элементы; Если Ложь Или (Истина И "" + Поле = "" И Поля.Количество() = 0) Или (Истина И Поля.Количество() = 1 И ТипЗнч(Поля[0]) = Тип("ПолеГруппировкиКомпоновкиДанных") И Поля[0].Поле = Поле) Тогда ГруппировкаПоИскомомуПолю = Группировка; Прервать; КонецЕсли; КонецЦикла; Возврат ГруппировкаПоИскомомуПолю; КонецФункции // Функция - Найти элемент отбора компоновки лкс // // Параметры: // Отбор - - // ИменаПолей - - // НайденныеЭлементы - Соответствие* - // ТолькоВключенныеНаРавенствоЗначению - - // ВключатьПодчиненные - - // // Возвращаемое значение: // - // Функция НайтиЭлементОтбораКомпоновкиЛкс(Знач Отбор, Знач ИменаПолей = Неопределено, Знач НайденныеЭлементы = Неопределено, Знач ТолькоВключенныеНаРавенствоЗначению = Ложь, Знач ВключатьПодчиненные = Ложь, Знач МассивПолейРекурсия = Неопределено) Экспорт Если ТипЗнч(Отбор) = Тип("ОтборКомпоновкиДанных") Тогда ЭлементыОтбора = Отбор.Элементы; Иначе ЭлементыОтбора = Отбор; КонецЕсли; Если МассивПолейРекурсия = Неопределено Тогда Если ТипЗнч(ИменаПолей) = Тип("Строка") Тогда МассивИменПолей = СтрРазделитьЛкс(ИменаПолей, ",", Истина); Иначе МассивИменПолей = ИменаПолей; КонецЕсли; МассивПолейРекурсия = Новый Массив; Если МассивИменПолей <> Неопределено Тогда Для Каждого ИмяПоля Из МассивИменПолей Цикл МассивПолейРекурсия.Добавить(Новый ПолеКомпоновкиДанных(ИмяПоля)); КонецЦикла; КонецЕсли; КонецЕсли; МассивПолейПуст = МассивПолейРекурсия.Количество() = 0; Если НайденныеЭлементы = Неопределено Тогда НайденныеЭлементы = Новый Соответствие; КонецЕсли; Для Каждого ЭлементОтбора ИЗ ЭлементыОтбора Цикл Если Истина И ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") И (Ложь Или Не ТолькоВключенныеНаРавенствоЗначению Или (Истина И ЭлементОтбора.Использование И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно И ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") И ТипЗнч(ЭлементОтбора.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных"))) Тогда Если Ложь Или МассивПолейПуст Или МассивПолейРекурсия.Найти(ЭлементОтбора.ЛевоеЗначение) <> Неопределено Тогда НайденныеЭлементы.Вставить("" + ЭлементОтбора.ЛевоеЗначение, ЭлементОтбора); КонецЕсли; ИначеЕсли Истина И ВключатьПодчиненные И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда НайтиЭлементОтбораКомпоновкиЛкс(ЭлементОтбора.Элементы,, НайденныеЭлементы, ТолькоВключенныеНаРавенствоЗначению, МассивПолейРекурсия); КонецЕсли; КонецЦикла; Если МассивИменПолей <> Неопределено И МассивИменПолей.Количество() = 1 Тогда Результат = НайденныеЭлементы[МассивИменПолей[0]]; Иначе Результат = НайденныеЭлементы; КонецЕсли; Возврат Результат; КонецФункции // При ИспользованиеДляНового=Ложь для существующего элемента отбора не меняется правое значение Функция НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Знач ЭлементыОтбора, Знач Поле = "", Знач Значение = Неопределено, Знач Сравнение = "", Знач ДоступныеПоляОтбора = Неопределено, Знач ПроверятьУникальность = Истина, ИспользованиеДляНового = Истина, СообщитьОДобавлении = Ложь) Экспорт Если ТипЗнч(ЭлементыОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда ЭлементыОтбора = ЭлементыОтбора.Отбор; КонецЕсли; Если ТипЗнч(ЭлементыОтбора) = Тип("ОтборКомпоновкиДанных") Тогда ДоступныеПоляОтбора = ЭлементыОтбора.ДоступныеПоляОтбора; ЭлементыОтбора = ЭлементыОтбора.Элементы; ИначеЕсли ТипЗнч(ЭлементыОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда ЭлементыОтбора = ЭлементыОтбора.Элементы; Иначе ЭлементыОтбора = ЭлементыОтбора; КонецЕсли; Если ТипЗнч(Поле) = Тип("Строка") Тогда Поле = Новый ПолеКомпоновкиДанных(Поле); КонецЕсли; Если ПроверятьУникальность Тогда ЭлементОтбора = НайтиЭлементОтбораКомпоновкиЛкс(ЭлементыОтбора, "" + Поле); КонецЕсли; Если ЭлементОтбора = Неопределено Тогда ЭлементОтбора = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементОтбора.Использование = ИспользованиеДляНового; ЭлементОтбора.ЛевоеЗначение = Поле; ИначеЕсли Не ИспользованиеДляНового Тогда // Опасно Возврат ЭлементОтбора; КонецЕсли; Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда Значение = Новый Массив(Значение); КонецЕсли; Если ТипЗнч(Значение) = Тип("Массив") Тогда СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(Значение); Значение = СписокЗначений; КонецЕсли; // Вид сравнения Если ТипЗнч(Сравнение) = Тип("ВидСравненияКомпоновкиДанных") Тогда Иначе Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда Сравнение = ВидСравненияКомпоновкиДанных.ВСписке; Иначе Сравнение = ВидСравненияКомпоновкиДанных.Равно; КонецЕсли; КонецЕсли; Если Истина И Сравнение = ВидСравненияКомпоновкиДанных.Равно И Значение = Неопределено И ДоступныеПоляОтбора <> Неопределено Тогда ДоступноеПолеОтбора = ДоступныеПоляОтбора.НайтиПоле(Поле); Если ДоступноеПолеОтбора <> Неопределено Тогда Значение = ДоступноеПолеОтбора.Тип.ПривестиЗначение(Значение); Если Истина И Значение = "" И ДоступноеПолеОтбора.Тип.КвалификаторыСтроки.Длина = 0 Тогда Сравнение = ВидСравненияКомпоновкиДанных.Содержит; КонецЕсли; КонецЕсли; КонецЕсли; ЭлементОтбора.ВидСравнения = Сравнение; ЭлементОтбора.ПравоеЗначение = Значение; Если СообщитьОДобавлении Тогда СообщитьЛкс("В отбор добавлен элемент """ + ЭлементОтбора.ЛевоеЗначение + " " + ЭлементОтбора.ВидСравнения + " " + ЭлементОтбора.ПравоеЗначение + """"); КонецЕсли; Возврат ЭлементОтбора; КонецФункции Функция НайтиДоступноеПолеКомпоновкиПоИмениКолонкиЛкс(Знач ДоступныеПоля, Знач ДанныеКолонки) Экспорт #Если Сервер И Не Сервер Тогда ДоступныеПоля = Новый НастройкиКомпоновкиДанных; ДоступныеПоля = ДоступныеПоля.ДоступныеПоляОтбора; #КонецЕсли ДоступноеПоле = ДоступныеПоля.НайтиПоле(Новый ПолеКомпоновкиДанных(ДанныеКолонки)); Если ДоступноеПоле = Неопределено Тогда ДоступноеПоле = ДоступныеПоля.НайтиПоле(Новый ПолеКомпоновкиДанных(СтрЗаменить(ДанныеКолонки, "_", "."))); КонецЕсли; Возврат ДоступноеПоле; КонецФункции // Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей Функция НеуникальныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено) Экспорт Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда КопияТаблицы = Таблица.Скопировать(ОтборСтрок, ИмяКолонки); Иначе КопияТаблицы = Таблица.Выгрузить(ОтборСтрок, ИмяКолонки); КонецЕсли; Типы = КопияТаблицы.Колонки[ИмяКолонки].ТипЗначения.Типы(); Если Истина И Типы.Количество() = 1 И Типы[0] = Тип("Строка") И ИгнорироватьРегистрДляПростогоСтрокогоТипа Тогда ИмяКолонкиНрег = ИмяКолонки + "_Нрег777233464645"; КопияТаблицы.Колонки.Добавить(ИмяКолонкиНрег); Для Каждого СтрокаКопииТаблицы Из КопияТаблицы Цикл СтрокаКопииТаблицы[ИмяКолонкиНрег] = НРег(СтрокаКопииТаблицы[ИмяКолонки]); КонецЦикла; Иначе ИмяКолонкиНрег = ИмяКолонки; КонецЕсли; КолонкаКоличества = ИмяКолонки + "7773534765"; //гарантировано уникальное имя колонки КопияТаблицы.Колонки.Добавить(КолонкаКоличества); КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества); КопияТаблицы.Свернуть(ИмяКолонкиНрег, КолонкаКоличества); КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв"); МассивНеуникальных = Новый Массив; Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл СтрокаКопии = КопияТаблицы[Индекс]; Если СтрокаКопии[КолонкаКоличества] > 1 Тогда МассивНеуникальных.Добавить(СтрокаКопии[ИмяКолонкиНрег]); КонецЕсли; КонецЦикла; Возврат МассивНеуникальных; КонецФункции // ПолучитьНеуникальныеЗначенияКолонки() // Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей // ИменаКолонок - Строка - имена колонок через запятую Функция НеуникальныеКлючиТаблицыЛкс(Таблица, Знач ИменаКолонок = "") Экспорт #Если Сервер И Не Сервер Тогда Таблица = Новый ТаблицаЗначений; #КонецЕсли Если Не ЗначениеЗаполнено(ИменаКолонок) Тогда ИменаКолонок = ""; Для Каждого КолонкаТаблицы Из Таблица.Колонки Цикл Если Ложь Или КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Или КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) Тогда Продолжить; КонецЕсли; Если ИменаКолонок <> "" Тогда ИменаКолонок = ИменаКолонок + ","; КонецЕсли; ИменаКолонок = ИменаКолонок + КолонкаТаблицы.Имя; КонецЦикла; КонецЕсли; Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда КопияТаблицы = Таблица.Скопировать(, ИменаКолонок); Иначе КопияТаблицы = Таблица.Выгрузить(, ИменаКолонок); КонецЕсли; КолонкаКоличества = "Количество7773534765"; //гарантировано уникальное имя колонки КопияТаблицы.Колонки.Добавить(КолонкаКоличества); КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества); КопияТаблицы.Свернуть(ИменаКолонок, КолонкаКоличества); КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв"); МассивНеуникальных = Новый Массив; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл СтрокаКопии = КопияТаблицы[Индекс]; Если СтрокаКопии[КолонкаКоличества] > 1 Тогда НеуникальныйКлюч = Новый Структура(ИменаКолонок); ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии); МассивНеуникальных.Добавить(НеуникальныйКлюч); КонецЕсли; КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл   СтрокаКопии = КопияТаблицы[Индекс];   Если СтрокаКопии[КолонкаКоличества] > 1 Тогда   НеуникальныйКлюч = Новый Структура(ИменаКолонок);   ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии);   МассивНеуникальных.Добавить(НеуникальныйКлюч);   КонецЕсли;   КонецЦикла;   Возврат МассивНеуникальных; КонецФункции // ПолучитьНеуникальныеЗначенияКолонки() Функция ПредставлениеОтбораЛкс(Знач Отбор) Экспорт ПредставлениеОтбора = "" + Отбор; Если Не ЗначениеЗаполнено(ПредставлениеОтбора) Тогда ПредставлениеОтбора = "Без отбора"; КонецЕсли; Возврат ПредставлениеОтбора; КонецФункции Функция ЛитеральноеПредставлениеЗначенияВЯзыкеЗапросовЛкс(ЗначениеПараметра, ВыводитьСообщения = Ложь) Экспорт ТекстЗамены = ""; ТипЗначенияПараметра = ТипЗнч(ЗначениеПараметра); ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначенияПараметра); Если ОбъектМД <> Неопределено Тогда КорневойТип = ирОбщий.ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя()); Если ирОбщий.ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда Если ирОбщий.ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗначенияПараметра) Тогда ТекстЗамены = "ТочкаМаршрута." + ЗначениеПараметра.Имя; ИначеЕсли ЗначениеПараметра.Пустая() Тогда ТекстЗамены = "ПустаяСсылка"; ИначеЕсли ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Тогда ТекстЗамены = XMLСтрока(ЗначениеПараметра); ИначеЕсли ирОбщий.ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда Если ЗначениеПараметра.Предопределенный Тогда ТекстЗамены = ирОбщий.ПолучитьМенеджерЛкс(ОбъектМД).ПолучитьИмяПредопределенного(ЗначениеПараметра); КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияБухгалтерии") Тогда ТекстЗамены = "ВидДвиженияБухгалтерии." + ЗначениеПараметра; ИначеЕсли ТипЗначенияПараметра = Тип("ВидДвиженияНакопления") Тогда ТекстЗамены = "ВидДвиженияНакопления." + ЗначениеПараметра; КонецЕсли; Если ТекстЗамены = "" Тогда Если ВыводитьСообщения Тогда СообщитьЛкс("Представление значения """ + ирОбщий.РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра) + """ в языке запросов через ЗНАЧЕНИЕ() невозможно") КонецЕсли; Иначе Если ОбъектМД <> Неопределено Тогда ТекстЗамены = ОбъектМД.ПолноеИмя() + "." + ТекстЗамены; КонецЕсли; ТекстЗамены = "ЗНАЧЕНИЕ(" + ТекстЗамены + ")"; КонецЕсли; Возврат ТекстЗамены; КонецФункции Функция ЛитеральноеПредставлениеЗначенияВоВстроенномЯзыкеЛкс(Значение) Экспорт Если ТипЗнч(Значение) = Тип("Неопределено") Тогда Результат = ПеревестиСтроку("Неопределено"); ИначеЕсли ТипЗнч(Значение) = Тип("Null") Тогда Результат = "Null"; Иначе Если ТипЗнч(Значение) = Тип("Дата") Тогда Результат = ПеревестиСтроку("Дата") + "(" + XMLСтрока(Год(Значение)) + ", " + XMLСтрока(Месяц(Значение)) + ", " + XMLСтрока(День(Значение)); Если НачалоДня(Значение) <> Значение Тогда Результат = Результат + ", " + XMLСтрока(Час(Значение)) + ", " + XMLСтрока(Минута(Значение)) + ", " + XMLСтрока(Секунда(Значение)); КонецЕсли; Результат = Результат + ")"; ИначеЕсли ТипЗнч(Значение) = Тип("Число") Тогда Результат = XMLСтрока(Значение); ИначеЕсли ТипЗнч(Значение) = Тип("Булево") Тогда Если Значение Тогда Результат = ПеревестиСтроку("Истина"); Иначе Результат = ПеревестиСтроку("Ложь"); КонецЕсли; ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда Результат = """" + СтрЗаменить(Значение, """", """""") + """"; Иначе ВызватьИсключение "Для типа значения """ + ТипЗнч(Значение) + """ не определено литеральное представление во встроенном языке"; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция РазличныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ОтборСтрок = Неопределено) Экспорт Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда #Если Сервер И Не Сервер Тогда Таблица = Новый ТаблицаЗначений; #КонецЕсли КопияТаблицы = Таблица.Скопировать(ОтборСтрок, ИмяКолонки); Иначе КопияТаблицы = Таблица.Выгрузить(ОтборСтрок, ИмяКолонки); КонецЕсли; #Если Сервер И Не Сервер Тогда КопияТаблицы = Новый ТаблицаЗначений; #КонецЕсли КопияТаблицы.Свернуть(ИмяКолонки); РазличныеЗначения = КопияТаблицы.ВыгрузитьКолонку(ИмяКолонки); Возврат РазличныеЗначения; КонецФункции // ПолучитьНеуникальныеЗначенияКолонки() Функция СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ОбъектыНаСервере = Неопределено) Экспорт СтруктураНабораЗаписей = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицыБД,,, Ложь, ОбъектыНаСервере); Возврат СтруктураНабораЗаписей; КонецФункции // Переводит системный идентификатор на язык варианта встроенного языка Функция ПеревестиСтроку(Русский) Экспорт // Для ускорения //Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда Если "" + Метаданные.ВариантВстроенногоЯзыка = "Русский" Тогда Возврат Русский; Иначе мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Локальный = мПлатформа.ПеревестиСтроку("" + Русский, Истина); Возврат Локальный; КонецЕсли; КонецФункции // Переводит системный идентификатор на русский язык Функция ПеревестиВРусский(Локальный) Экспорт //Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда Если КодСимвола(Локальный, 1) >= 128 Тогда Возврат Локальный; Иначе мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Русский = мПлатформа.ПеревестиВРусский("" + Локальный, Истина); Возврат Русский; КонецЕсли; КонецФункции // Переводит системный идентификатор на английский язык Функция ПеревестиИзРусскогоВАнглийскийЛкс(Локальный) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Русский = мПлатформа.ПеревестиСтроку("" + Локальный, Истина); Возврат Русский; КонецФункции Функция ПеревестиПолноеИмяМДВАнглийскийЛкс(ПолноеИмяМД) Экспорт Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД); Результат = ""; Для Счетчик = 1 По Фрагменты.Количество() / 2 Цикл Если Результат <> "" Тогда Результат = Результат + "."; КонецЕсли; Английский = ПеревестиИзРусскогоВАнглийскийЛкс(Фрагменты[(Счетчик-1)*2]); Результат = Результат + Английский + "." + Фрагменты[(Счетчик-1)*2+1]; КонецЦикла; Возврат Результат; КонецФункции Функция ТипКлючаЗаписиТаблицыЛкс(ПолноеИмяТаблицы) Экспорт ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы); Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда Результат = Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяТаблицы)); ИначеЕсли Истина И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) И ТипТаблицы <> "Перерасчет" И ТипТаблицы <> "Последовательность" Тогда Результат = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "КлючЗаписи.")); Иначе Результат = Тип("Неопределено"); КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ВернутьСтруктуру - Булево - возвращать структуру иначе список значений // ДляНабораЗаписейРегистраСведений - Булево - для регистров сведений подчиненных регистратору вернуть ключ записываемого объекта // Функция СтруктураКлючаТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВключатьНомерСтроки = Истина, ВернутьСтруктуру = Истина, ДляПодчиненногоРегистраСведенийНомерСтроки = Истина) Экспорт ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД); МассивФрагментов = СтрРазделитьЛкс(ПолноеИмяТаблицыБД); СписокПолей = Новый СписокЗначений; Если Ложь Или ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), ПеревестиСтроку("Ссылка")); ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД); НаборЗаписей = ирКэш.ЭталонныйНаборЗаписейЛкс(ПолноеИмяТаблицыБД); #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей(); #КонецЕсли Если Истина И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору И Не ДляПодчиненногоРегистраСведенийНомерСтроки Тогда Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), ПеревестиСтроку("Период")); КонецЕсли; Если ОбъектМД.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда СписокПолей.Добавить(НаборЗаписей.Отбор.Регистратор.ТипЗначения, ПеревестиСтроку("Регистратор")); КонецЕсли; Для Каждого Измерение Из ОбъектМД.Измерения Цикл СписокПолей.Добавить(Измерение.Тип, Измерение.Имя); КонецЦикла; КонецЕсли; Если СписокПолей.Количество() = 0 Тогда Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл Если Ложь Или ЭлементОтбора.Использование Или ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя); КонецЕсли; КонецЦикла; КонецЕсли; Если ВключатьНомерСтроки Тогда Если ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда Для Каждого Измерение Из ОбъектМД.Измерения Цикл СписокПолей.Добавить(Измерение.Тип, Измерение.Имя); КонецЦикла; ИначеЕсли Истина И ТипТаблицы <> "Перерасчет" И (Ложь Или Не ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) Или (ДляПодчиненногоРегистраСведенийНомерСтроки И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору)) Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Число"), ПеревестиСтроку("НомерСтроки")); КонецЕсли; КонецЕсли; ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), ПеревестиСтроку("Ссылка")); Если ВключатьНомерСтроки Тогда СписокПолей.Добавить(Новый ОписаниеТипов("Число"), ПеревестиСтроку("НомерСтроки")); КонецЕсли; ИначеЕсли ТипТаблицы = "Изменения" Тогда // Такой способ может быть долгим при частых вызовах ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.Текст = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицыБД + " КАК _Таблица_"; ПостроительЗапроса.ЗаполнитьНастройки(); Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл Если Ложь Или СтрокиРавныЛкс(ДоступноеПоле.ПутьКДанным, ПеревестиСтроку("НомерСообщения")) Тогда Продолжить; КонецЕсли; СписокПолей.Добавить(ДоступноеПоле.ТипЗначения, ДоступноеПоле.ПутьКДанным); КонецЦикла; ИначеЕсли ТипТаблицы = "Внешняя" Тогда ТаблицаМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяТаблицыБД); Если ТаблицаМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные Тогда СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), ПеревестиСтроку("Ссылка")); Иначе НаборЗаписей = ирКэш.ЭталонныйНаборЗаписейЛкс(ПолноеИмяТаблицыБД); Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя); КонецЦикла; КонецЕсли; ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда Поля = ПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД); Поле = Поля.Найти(ПеревестиСтроку("Ссылка"), "Имя"); СписокПолей.Добавить(Поле.ТипЗначения, Поле.Имя); Иначе ВызватьИсключение "Получение структуры ключа таблицы БД типа """ + ТипТаблицы + """ не поддерживается"; КонецЕсли; Если ВернутьСтруктуру Тогда Результат = Новый Структура(); Для Каждого ЭлементСписка Из СписокПолей Цикл Результат.Вставить(ЭлементСписка.Представление, ЭлементСписка.Значение); КонецЦикла; Иначе Результат = СписокПолей; КонецЕсли; Возврат Результат; КонецФункции Функция ДанныеСтрокиРегистраИзКлючаЗаписиЛкс(Знач КлючЗаписи, Знач ИмяТаблицыРегистра = "") Экспорт Если Не ЗначениеЗаполнено(ИмяТаблицыРегистра) Тогда ИмяТаблицыРегистра = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи))); КонецЕсли; СтруктураКлючаСтроки = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыРегистра,,, Ложь); ЗаполнитьЗначенияСвойств(СтруктураКлючаСтроки, КлючЗаписи); СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ИмяТаблицыРегистра); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, СтруктураКлючаСтроки); ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицыРегистра); Для Каждого СтрокаПоля Из ПоляТаблицыБД Цикл НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, СтрокаПоля.Имя); КонецЦикла; ДанныеСтроки = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки); Результат = Неопределено; Если ДанныеСтроки.Количество() > 0 Тогда Результат = ДанныеСтроки[0]; КонецЕсли; Возврат Результат; КонецФункции Функция УдалитьМутабельныеЗначенияВСтруктуреЛкс(Знач ДополнительныеСвойстваЛ) Экспорт // Убираем неудобные типы значений из дополнительных свойств объекта http://devtool1c.ucoz.ru/forum/2-832-1#3587 //УдаляемыеКлючи = Новый Массив; //Для Каждого КлючИЗначение Из ДополнительныеСвойстваЛ Цикл // Если ТипЗнч(КлючИЗначение.Значение) = Тип("МенеджерВременныхТаблиц") Тогда // УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ); // КонецЕсли; //КонецЦикла; //Для Каждого Ключ Из УдаляемыеКлючи Цикл // ДополнительныеСвойстваЛ.Удалить(Ключ); //КонецЦикла; Результат = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(ДополнительныеСвойстваЛ)); Возврат Результат; КонецФункции // Функция - Заполнить значения свойств обязательно. // // Параметры: // Объект - - // Структура - - // выхИменаСвойств - Строка - передается для ускорения, заполняется автоматически // // Возвращаемое значение: // - // Функция ЗаполнитьЗначенияСвойствОбязательноЛкс(Объект, Структура, выхИменаСвойств = "") Экспорт #Если Сервер И Не Сервер Тогда Структура = Новый Структура; #КонецЕсли Если Не ЗначениеЗаполнено(выхИменаСвойств) Тогда выхИменаСвойств = ИменаСвойствСтруктурыЛкс(Структура); КонецЕсли; ЗаполнитьЗначенияСвойств(Объект, Структура, выхИменаСвойств); КонецФункции Функция ИменаСвойствСтруктурыЛкс(Знач СтруктураИлиСтрокаТаблицы) Экспорт ИменаСвойств = ""; Если ТипЗнч(СтруктураИлиСтрокаТаблицы) <> Тип("Структура") Тогда СтруктураИлиСтрокаТаблицы = СтруктураИлиСтрокаТаблицы.Владелец().Колонки; КонецЕсли; Для Каждого КлючИЗначение Из СтруктураИлиСтрокаТаблицы Цикл Если ТипЗнч(КлючИЗначение) = Тип("КлючИЗначение") Тогда ИмяСвойства = КлючИЗначение.Ключ; Иначе ИмяСвойства = КлючИЗначение.Имя; КонецЕсли; ИменаСвойств = ИменаСвойств + "," + ИмяСвойства; КонецЦикла; ИменаСвойств = Сред(ИменаСвойств, 2); Возврат ИменаСвойств КонецФункции Функция ЦветТекстаНеактивностиЛкс() Экспорт Возврат Новый Цвет(100, 100, 100); КонецФункции Функция ЦветТекстаТекущегоЭлементаЛкс() Экспорт Возврат Новый Цвет(20, 40, 140); КонецФункции Функция ЦветТекстаИзмененныхДанныхЛкс() Экспорт Возврат WebЦвета.КожаноКоричневый; КонецФункции Функция ЦветФонаАкцентаЛкс() Экспорт Возврат Новый Цвет(250, 245, 230); КонецФункции // Для подчиненного регистра сведений выполняет чтение из БД // Параметры: // Результат - Структура Функция СтруктураИзКлючаЗаписиЛкс(КлючЗаписи, ПолноеИмяМДЭлемента = "", ДляПодчиненногоРегистраСведенийНомерСтроки = Ложь) Экспорт Если Не ЗначениеЗаполнено(ПолноеИмяМДЭлемента) Тогда ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючЗаписи)); ПолноеИмяМДЭлемента = ОбъектМД.ПолноеИмя(); Иначе ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяМДЭлемента); КонецЕсли; СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента, Истина,, Ложь); ЗаполнитьЗначенияСвойств(СтруктураКлюча, КлючЗаписи); Если ДляПодчиненногоРегистраСведенийНомерСтроки Тогда ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяМДЭлемента); Если Истина И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы) И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда ДанныеСтроки = СтрокаТаблицыБДПоКлючуЛкс(ПолноеИмяМДЭлемента, СтруктураКлюча); СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМДЭлемента); ЗаполнитьЗначенияСвойств(СтруктураКлюча, ДанныеСтроки); КонецЕсли; КонецЕсли; Возврат СтруктураКлюча; КонецФункции Функция XMLКлючОбъектаБДЛкс(Знач ОбъектДанных, Знач ИспользоватьСсылкуДляСсылочных = Ложь) Экспорт Если ОбъектДанных = Неопределено Тогда Результат = "Неопределено"; Возврат Результат; КонецЕсли; ПредставлениеОбъекта = ""; Если ТипЗнч(ОбъектДанных) = Тип("УдалениеОбъекта") Тогда Класс = "Удаление"; Иначе Попытка ЭтоНовый = ОбъектДанных.ЭтоНовый(); Класс = "Ссылочный"; ПредставлениеОбъекта = "" + ОбъектДанных + ","; Исключение Попытка УникальныйИдентификатор = ОбъектДанных.УникальныйИдентификатор(); Класс = "Ссылочный"; Исключение Попытка Пустышка = ОбъектДанных.Количество(); Класс = "НаборЗаписей"; Исключение Попытка Пустышка = ОбъектДанных.Значение; Класс = "Константы"; Исключение Класс = "Примитив"; КонецПопытки; КонецПопытки; КонецПопытки; КонецПопытки; Если Истина И Класс = "Ссылочный" И ИспользоватьСсылкуДляСсылочных Тогда Результат = ОбъектДанных; Возврат Результат; КонецЕсли; КонецЕсли; Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если ТипЗнч(ОбъектДанных) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей") Тогда Класс = "НаборЗаписей"; ИначеЕсли ТипЗнч(ОбъектДанных) = Тип("ОбработкаОбъект.ирИмитаторКонстантаМенеджер") Тогда Класс = "Константы"; КонецЕсли; КонецЕсли; // Антибаг 8.3.11 На перерасчетах ЗаписьXML ошибку выдает. https://partners.v8.1c.ru/forum/t/1674609/m/1674609 //XMLКлюч = "" + XMLТип(ТипОбъектаБДЛкс(ОбъектДанных)).ИмяТипа + "("; XMLКлюч = "" + СериализаторXDTO.XMLТип(ТипОбъектаБДЛкс(ОбъектДанных)).ИмяТипа + "("; Если Класс = "Ссылочный" Тогда Если ЭтоНовый = Истина Тогда УникальныйИдентификатор = "!" + ОбъектДанных.ПолучитьСсылкуНового().УникальныйИдентификатор(); КонецЕсли; Если УникальныйИдентификатор = Неопределено Тогда УникальныйИдентификатор = ОбъектДанных.Ссылка.УникальныйИдентификатор(); КонецЕсли; XMLКлюч = XMLКлюч + ПредставлениеОбъекта + УникальныйИдентификатор; ИначеЕсли Класс = "Удаление" Тогда XMLКлюч = XMLКлюч + XMLКлючОбъектаБДЛкс(ОбъектДанных.Ссылка); ИначеЕсли Класс = "НаборЗаписей" Тогда ПредставлениеОтбора = ""; Разделитель = ", "; Для Каждого ЭлементОтбора Из ОбъектДанных.Отбор Цикл Если ЭлементОтбора.Использование Тогда ПредставлениеОтбора = ПредставлениеОтбора + Разделитель + ЭлементОтбора.Имя + ":" + XMLКлючОбъектаБДЛкс(ЭлементОтбора.Значение); КонецЕсли; КонецЦикла; XMLКлюч = XMLКлюч + Сред(ПредставлениеОтбора, СтрДлина(Разделитель) + 1); ИначеЕсли Класс = "Константы" Тогда // Иначе // Примитивный тип XMLКлюч = XMLКлюч + ОбъектДанных; КонецЕсли; XMLКлюч = XMLКлюч + ")"; Результат = XMLКлюч; Возврат Результат; КонецФункции // Параметры: // Объект - ОбъектБД, ОбъектМД Функция ТабличныеЧастиОбъектаЛкс(Объект) Экспорт СтруктураТЧ = Новый Структура(); Если Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда ОбъектМД = Метаданные.НайтиПоТипу(Объект._Тип); ОбъектБД = Объект.Данные; ИначеЕсли ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда ОбъектМД = Объект; ОбъектБД = Неопределено; Иначе Если ЛиТипСсылкиТочкиМаршрутаЛкс(ТипЗнч(Объект)) Тогда Возврат СтруктураТЧ; КонецЕсли; ОбъектМД = Объект.Метаданные(); ОбъектБД = Объект; КонецЕсли; ЭтоСправочник = Метаданные.Справочники.Индекс(ОбъектМД) >= 0; Если Не ЛиСсылочныйОбъектМетаданных(ОбъектМД, Ложь) Тогда Возврат СтруктураТЧ; КонецЕсли; Для Каждого МетаТЧ из ОбъектМД.ТабличныеЧасти Цикл // Для реквизитов справочников, принадлежащих только группе или только элементу нужно игнорировать те объекты, для которых эти реквизиты не используются Если Истина И ОбъектБД <> Неопределено И ирОбщий.ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМД) Тогда Если Ложь Или (Истина И ОбъектБД.ЭтоГруппа И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Или (Истина И Не ОбъектБД.ЭтоГруппа И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Тогда Продолжить; КонецЕсли; КонецЕсли; СтруктураТЧ.Вставить(МетаТЧ.Имя, МетаТЧ.Представление()); КонецЦикла; Если Метаданные.ПланыСчетов.Индекс(ОбъектМД) >= 0 Тогда Если ОбъектМД.ВидыСубконто <> Неопределено Тогда СтруктураТЧ.Вставить(ПеревестиСтроку("ВидыСубконто"), "Виды субконто"); КонецЕсли; КонецЕсли; Если Метаданные.ПланыВидовРасчета.Индекс(ОбъектМД) >= 0 Тогда Если ОбъектМД.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.НеИспользовать Тогда СтруктураТЧ.Вставить(ПеревестиСтроку("БазовыеВидыРасчета"), "Базовые виды расчета"); КонецЕсли; СтруктураТЧ.Вставить(ПеревестиСтроку("ВедущиеВидыРасчета"), "Ведущие виды расчета"); Если ОбъектМД.ИспользованиеПериодаДействия Тогда СтруктураТЧ.Вставить(ПеревестиСтроку("ВытесняющиеВидыРасчета"), "Вытесняющие виды расчета"); КонецЕсли; КонецЕсли; Возврат СтруктураТЧ; КонецФункции Функция ЛиСтрокаСодержитВсеПодстрокиЛкс(Знач Строка, Знач Подстроки) Экспорт Если ТипЗнч(Подстроки) = Тип("Строка") Тогда Подстроки = СтрРазделитьЛкс(НРег(Подстроки), " ", Истина); КонецЕсли; НСтрока = НРег(Строка); Для Каждого Фрагмент Из Подстроки Цикл Если Найти(НСтрока, Фрагмент) = 0 Тогда Возврат Ложь; КонецЕсли; КонецЦикла; Возврат Истина; КонецФункции Функция СтрокаТаблицыБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча) Экспорт Запрос = Новый Запрос; ТекстЗапроса = "ВЫБРАТЬ Т.* ИЗ " + ПолноеИмяТаблицы + " КАК Т ГДЕ ИСТИНА "; Для Каждого КлючИЗначение Из СтруктураКлюча Цикл ТекстЗапроса = ТекстЗапроса + " И Т." + КлючИЗначение.Ключ + " = &" + КлючИЗначение.Ключ; КонецЦикла; СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураКлюча, Запрос.Параметры); Запрос.Текст = ТекстЗапроса; Таблица = Запрос.Выполнить().Выгрузить(); Если Таблица.Количество() > 1 Тогда ВызватьИсключение "По переданному ключу (" + ПолучитьПредставлениеСтруктурыЛкс(СтруктураКлюча) + ") найдено несколько строк таблицы"; ИначеЕсли Таблица.Количество() > 0 Тогда СтрокаРезультата = Таблица[0]; Иначе СтрокаРезультата = Неопределено; КонецЕсли; Возврат СтрокаРезультата; КонецФункции // Присваивает ячейке по указателю значение. Если после этого ячейка получает другое значение, то ячейке присваивается ее старое значение. Функция БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(П1, П2) Экспорт СтароеП1 = П1; П1 = П2; Если П1 <> П2 Тогда П1 = СтароеП1; Возврат Ложь; КонецЕсли; Возврат Истина; КонецФункции // БезопасноПрисвоитьПроизвольнуюСсылку() // ЛиНаходитьОбразующий - Булево - находить ближайший объект метаданных, если точный найти не удается Функция ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ЛиНаходитьОбразующий = Ложь) Экспорт Результат = Неопределено; Если Истина И Не ПустаяСтрока(ПолноеИмяТаблицыБД) И ПолноеИмяТаблицыБД <> "Константы" Тогда Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД); Если Фрагменты.Количество() < 2 Тогда Возврат Неопределено; КонецЕсли; ОбразующийМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]); Если Ложь Или ОбразующийМД = Неопределено Или Фрагменты.Количество() = 2 Тогда Результат = ОбразующийМД; Иначе Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда ДочерняяКоллекция = ОбразующийМД.ТабличныеЧасти; ИначеЕсли Фрагменты[0] = ПеревестиСтроку("РегистрРасчета") Тогда ДочерняяКоллекция = ОбразующийМД.Перерасчеты; ИначеЕсли Фрагменты[0] = ПеревестиСтроку("ВнешнийИсточникДанных") Тогда ДочерняяКоллекция = ОбразующийМД.Таблицы; Если Фрагменты.Количество() = 4 Тогда Результат = ДочерняяКоллекция.Найти(Фрагменты[3]); КонецЕсли; //ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда ИначеЕсли Ложь Или ЛиКорневойТипРегистраБДЛкс(Фрагменты[0]) Или Фрагменты[0] = ПеревестиСтроку("Константа") Тогда Результат = ОбразующийМД; Иначе ВызватьИсключение "Неизвестный корневой тип метаданных(" + Фрагменты[0] + ") с дочерней таблицей"; КонецЕсли; Если Результат = Неопределено И Фрагменты.Количество() = 3 Тогда ДочернийОбъектМД = ДочерняяКоллекция.Найти(Фрагменты[2]); Если ДочернийОбъектМД <> Неопределено Тогда Результат = ДочернийОбъектМД; ИначеЕсли ЛиНаходитьОбразующий Тогда // ВидыСубконто, Изменения, Точки Результат = ОбразующийМД; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьМетаданныеЛкс() Функция ОписаниеТипов1ВходитВОписаниеТипов2Лкс(ОписаниеТипов1, ОписаниеТипов2, ИгнорироватьNULL = Истина) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов1 = Новый ОписаниеТипов; ОписаниеТипов2 = Новый ОписаниеТипов; #КонецЕсли Результат = Не (ОписаниеТипов2.Типы().Количество() > 0 И ОписаниеТипов1.Типы().Количество() = 0); Если Результат Тогда Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл Если Истина И ИгнорироватьNULL И Тип = Тип("Null") Тогда Продолжить; КонецЕсли; Если Не ОписаниеТипов2.СодержитТип(Тип) Тогда Результат = Ложь; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции Функция ОписаниеТаблицыБДЛкс(ИмяТаблицыБД) Экспорт Возврат ирКэш.ТаблицаВсехТаблицБДЛкс().Найти(НРег(ИмяТаблицыБД), "НПолноеИмя"); КонецФункции Функция ЛиТаблицаБДСуществуетЛкс(ИмяТаблицыБД) Экспорт Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ 1 ИЗ " + ИмяТаблицыБД + " ГДЕ ЛОЖЬ"; Попытка Запрос.Выполнить(); Результат = Истина; Исключение Результат = Ложь; КонецПопытки; Возврат Результат; КонецФункции Функция ПредставлениеТаблицыБДЛкс(ИмяТаблицыБД) Экспорт ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ИмяТаблицыБД); Если ОбъектМД <> Неопределено Тогда Результат = ОбъектМД.Представление(); Иначе Результат = ОписаниеТаблицыБДЛкс(ИмяТаблицыБД).Представление; КонецЕсли; Возврат Результат; КонецФункции // Возвращаемое значение - всегда русский вариант Функция ТипТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт //ОписаниеТаблицы = ирКэш.ТаблицаВсехТаблицБДЛкс().Найти(НРег(ПолноеИмяТаблицыБД), "НПолноеИмя"); //Если ОписаниеТаблицы <> Неопределено Тогда // Возврат ОписаниеТаблицы.Тип; //КонецЕсли; Фрагменты = СтрРазделитьЛкс(ПолноеИмяТаблицыБД); ТипТаблицы = Фрагменты[0]; Если Фрагменты.Количество() > 2 Тогда ПоследнийФрагмент = Фрагменты[Фрагменты.ВГраница()]; Если Ложь Или ПоследнийФрагмент = ПеревестиСтроку("Изменения") Или ПоследнийФрагмент = ПеревестиСтроку("ДвиженияССубконто") //Или ПоследнийФрагмент = "Границы" Тогда ТипТаблицы = ПеревестиВРусский(ПоследнийФрагмент); //// Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(МассивФрагментов[0]) Тогда //// //ТипТаблицы = "ТабличнаяЧасть"; //// ТипТаблицы = МассивФрагментов[2]; //// КонецЕсли; Иначе Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД); Если ОбъектМД = Неопределено Тогда ТипТаблицы = ПеревестиВРусский(Фрагменты[2]); Иначе ТипТаблицы = "ТабличнаяЧасть"; КонецЕсли; //ИначеЕсли СтрокиРавныЛкс(Фрагменты[2], "ДвиженияССубконто") Тогда // ТипТаблицы = Фрагменты[0]; ИначеЕсли Фрагменты[0] = ПеревестиСтроку("РегистрРасчета") Тогда ТипТаблицы = "Перерасчет"; ИначеЕсли Фрагменты[0] = ПеревестиСтроку("ВнешнийИсточникДанных") Тогда ТипТаблицы = "Внешняя"; Иначе ТипТаблицы = "ВиртуальнаяТаблица"; КонецЕсли; КонецЕсли; Иначе ТипТаблицы = ПеревестиВРусский(ТипТаблицы); КонецЕсли; Возврат ТипТаблицы; КонецФункции // ВариантИсточников - Число, *0 // 0 - Основные таблицы // 1 - Таблицы изменений // 2 - Внутреннее соединение основных таблиц с их таблицами изменений с отбором по узлу Функция ТекстЗапросаПоВыбраннымТаблицамЛкс(ИменаТаблиц, ВариантИсточников = 0, ПервыеNКаждойТаблицы = 0, ПодключатьПоляКоличестваДвижений = Ложь, ИмяПоляПолногоИмениТаблицы = Неопределено) Экспорт ЛитералЗаменыОтсутствующихПолей = "НЕОПРЕДЕЛЕНО"; // NULL нельзя использовать из-за ошибок платформы 8.2.14 Если Не ЗначениеЗаполнено(ИмяПоляПолногоИмениТаблицы) Тогда ИмяПоляПолногоИмениТаблицы = "_ПолноеИмяТаблицы"; КонецЕсли; // Сначала определим общие реквизиты ПроверяемыеПоля = Новый Массив; ТипыОбъектовМД = Новый Структура; Для Каждого ИмяОбъектаМД Из ИменаТаблиц Цикл ТипОбъектаМД = ТипТаблицыБДЛкс(ИмяОбъектаМД); ТипыОбъектовМД.Вставить(ТипОбъектаМД); КонецЦикла; Если ТипыОбъектовМД.Количество() > 1 Тогда ТипОбъектаМД = Неопределено; КонецЕсли; Если ЗначениеЗаполнено(ТипОбъектаМД) Тогда ирКэш.Получить().ИнициализацияОписанияМетодовИСвойств(); СтрокаКорневогоТипа = ирКэш.Получить().ПолучитьСтрокуТипаМетаОбъектов(ТипОбъектаМД); Если СтрокаКорневогоТипа <> Неопределено Тогда СтрокаВида = ирКэш.Получить().ТаблицаИменЭлементовКоллекций.Найти(СтрокаКорневогоТипа.Множественное, "ИмяКоллекции"); Если СтрокаВида <> Неопределено Тогда Если ирОбщий.СтрокиРавныЛкс(ТипОбъектаМД, "ТабличнаяЧасть") Тогда ТипОбъектаМД = "Справочник.<Имя справочника>"; КонецЕсли; ИмяОбщегоТипа = ТипОбъектаМД + "." + СтрокаВида.ИмяЭлементаКоллекции; Если ВариантИсточников = 1 Тогда ИмяОбщегоТипа = ИмяОбщегоТипа + ".Изменения"; КонецЕсли; СтрокиИменПолей = ирКэш.Получить().ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ЯзыкПрограммы", ИмяОбщегоТипа, 1)); Для Каждого СтрокаСлова Из СтрокиИменПолей Цикл Если Ложь Или СтрокаСлова.ТипСлова = "Таблица" Или СтрокаСлова.ТипЗначения = "РезультатЗапроса" Или ПроверяемыеПоля.Найти(СтрокаСлова.Слово) <> Неопределено // Для таблиц бухгалтерии могут быть дубли из-за вариантов с корреспонденцией и без Тогда Продолжить; КонецЕсли; ПроверяемыеПоля.Добавить(СтрокаСлова.Слово); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; // Находим максимум общих реквизитов ОбщиеМетаПоля = Новый Массив; ЭтоПервыйПроход = Истина; Для Каждого ИмяТаблицы Из ИменаТаблиц Цикл ОбъектМетаданных = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы); Если ВариантИсточников > 0 Тогда Если ОбъектМетаданных = Неопределено Тогда ВызватьИсключение "У таблицы " + ИмяТаблицы + " нет таблицы регистрации изменений"; КонецЕсли; ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных); Если ЕстьТаблицаИзменений Тогда Если ВариантИсточников = 1 Тогда ИмяТаблицы = ИмяТаблицы + ".Изменения"; КонецЕсли; КонецЕсли; КонецЕсли; КоллекцияПолей = Новый Массив(); ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы); #Если Сервер И Не Сервер Тогда ПоляТаблицыБД = НайтиПоСсылкам().Колонки; #КонецЕсли Для Каждого ПолеТаблицы Из ПоляТаблицыБД Цикл Если ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Продолжить; КонецЕсли; ИмяПоля = ПолеТаблицы.Имя; Если Ложь Или ПроверяемыеПоля.Найти(ИмяПоля) <> Неопределено Тогда Продолжить; КонецЕсли; КоллекцияПолей.Добавить(ИмяПоля); КонецЦикла; Если ЭтоПервыйПроход Тогда Для Каждого ИмяПоля Из КоллекцияПолей Цикл ОбщиеМетаПоля.Добавить(ИмяПоля); КонецЦикла; Иначе НачальноеКоличество = ОбщиеМетаПоля.Количество(); Для СчетчикОбщиеМетаПоля = 1 По НачальноеКоличество Цикл ИмяПоля = ОбщиеМетаПоля[НачальноеКоличество - СчетчикОбщиеМетаПоля]; Если КоллекцияПолей.Найти(ИмяПоля) = Неопределено Тогда ОбщиеМетаПоля.Удалить(НачальноеКоличество - СчетчикОбщиеМетаПоля); КонецЕсли; КонецЦикла; Если ОбщиеМетаПоля.Количество() = 0 Тогда Прервать; КонецЕсли; КонецЕсли; ЭтоПервыйПроход = Ложь; КонецЦикла; ТекстОбщихМетаПолей = ""; Для Каждого ИмяПоля Из ОбщиеМетаПоля Цикл ПутьКПолю = ИмяПоля; Если Истина И ЛиКорневойТипСсылкиЛкс(ИменаТаблиц[0]) И ВариантИсточников > 0 Тогда ПутьКПолю = "Ссылка." + ИмяПоля; КонецЕсли; ТекстОбщихМетаПолей = ТекстОбщихМетаПолей + ", Т." + ПутьКПолю + " КАК " + ИмяПоля; КонецЦикла; #Если Клиент Тогда Индикатор = ПолучитьИндикаторПроцессаЛкс(ИменаТаблиц.Количество(), "Генерация текста запроса"); #КонецЕсли ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(""); ЗаписьXMLПустая = Истина; Для Каждого ИмяТаблицы Из ИменаТаблиц Цикл #Если Клиент Тогда ОбработатьИндикаторЛкс(Индикатор); #КонецЕсли ОбъектМетаданных = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы); КорневойТипТаблицы = ирОбщий.ПервыйФрагментЛкс(ИмяТаблицы); ТекстУсловияСоединения = ""; Если ВариантИсточников > 0 Тогда ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных); Если ЕстьТаблицаИзменений Тогда Если ВариантИсточников = 1 Тогда ИмяТаблицы = ИмяТаблицы + ".Изменения"; Иначе ТекстУсловияСоединения = "_Изменения_.Узел = &Узел"; СтруктураКлючаИзменений = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ИмяТаблицы + ".Изменения"); Для Каждого КлючИЗначение Из СтруктураКлючаИзменений Цикл Если ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Ключ, "Узел") Тогда Продолжить; КонецЕсли; Если ТекстУсловияСоединения <> "" Тогда ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " И"; КонецЕсли; ТекстУсловияСоединения = ТекстУсловияСоединения + " _Изменения_." + КлючИЗначение.Ключ + " = Т." + КлючИЗначение.Ключ; КонецЦикла; ТекстУсловияСоединения = Символы.ПС + " ВНУТРЕННЕЕ СОЕДИНЕНИЕ " + ИмяТаблицы + ".Изменения КАК _Изменения_ | ПО " + ТекстУсловияСоединения; КонецЕсли; КонецЕсли; КонецЕсли; Если ПодключатьПоляКоличестваДвижений Тогда Если ирОбщий.ЛиКорневойТипДокументаЛкс(КорневойТипТаблицы) Тогда ТекстОбщееКоличествоДвижений = ""; Для Каждого МетаРегистр Из ОбъектМетаданных.Движения Цикл ПолноеИмяРегистра = МетаРегистр.ПолноеИмя(); КраткоеИмяРегистра = МетаРегистр.Имя + "_"; ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " { ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ _Регистр_.Регистратор, КОЛИЧЕСТВО(*) КАК КоличествоСтрок | ИЗ " + ПолноеИмяРегистра + " КАК _Регистр_ СГРУППИРОВАТЬ ПО _Регистр_.Регистратор) КАК " + КраткоеИмяРегистра + " | ПО " + КраткоеИмяРегистра + ".Регистратор = Т.Ссылка}"; ВыражениеКоличества = "ЕСТЬNULL(" + КраткоеИмяРегистра + ".КоличествоСтрок, 0)"; Если ТекстОбщееКоличествоДвижений <> "" Тогда ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + " + "; КонецЕсли; ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + ВыражениеКоличества; ТекстОбщееКоличествоДвижений = ВыражениеКоличества + " КАК КоличествоСтрок" + КраткоеИмяРегистра + ", " + ТекстОбщееКоличествоДвижений; КонецЦикла; Если ЗначениеЗаполнено(ТекстОбщееКоличествоДвижений) Тогда ТекстУсловияСоединения = ТекстУсловияСоединения + " |{ГДЕ " + ТекстОбщееКоличествоДвижений + " КАК КоличествоСтрокВсеРегистры}"; КонецЕсли; КонецЕсли; КонецЕсли; //Если ВариантИсточников <> 1 Тогда ТекстНеобязательныхПолей = ""; ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы); #Если Сервер И Не Сервер Тогда ПоляТаблицыБД = НайтиПоСсылкам().Колонки; #КонецЕсли Для Каждого ПроверяемоеПоле Из ПроверяемыеПоля Цикл Если ПоляТаблицыБД.Найти(ПроверяемоеПоле, "Имя") = Неопределено Тогда ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", " + ЛитералЗаменыОтсутствующихПолей + " КАК " + ПроверяемоеПоле; Иначе ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", Т." + ПроверяемоеПоле + " КАК " + ПроверяемоеПоле; КонецЕсли; КонецЦикла; //КонецЕсли; Если Не ЗаписьXMLПустая Тогда ЗаписьXML.ЗаписатьБезОбработки(" |ОБЪЕДИНИТЬ ВСЕ |"); КонецЕсли; ЗаписьXMLПустая = Ложь; ЗаписьXML.ЗаписатьБезОбработки("ВЫБРАТЬ "); Если ЗначениеЗаполнено(ПервыеNКаждойТаблицы) Тогда ЗаписьXML.ЗаписатьБезОбработки("ПЕРВЫЕ " + XMLСтрока(ПервыеNКаждойТаблицы) + " "); КонецЕсли; Если ЗначениеЗаполнено(ТекстНеобязательныхПолей) Тогда ЗаписьXML.ЗаписатьБезОбработки(Сред(ТекстНеобязательныхПолей, 2) + ", "); КонецЕсли; Если ЗначениеЗаполнено(ТекстОбщихМетаПолей) Тогда ЗаписьXML.ЗаписатьБезОбработки(Сред(ТекстОбщихМетаПолей, 2) + ", "); КонецЕсли; ЗаписьXML.ЗаписатьБезОбработки("""" + ИмяТаблицы + """ КАК " + ИмяПоляПолногоИмениТаблицы + " ИЗ " + ИмяТаблицы + " КАК Т" + ТекстУсловияСоединения); КонецЦикла; //Если ЗначениеЗаполнено(ПервыеNОбщие) Тогда // ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ПервыеNОбщие) + " * ИЗ (" + ТекстЗапроса + ") КАК Т"; //КонецЕсли; ТекстЗапроса = ЗаписьXML.Закрыть(); ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Возврат ТекстЗапроса; КонецФункции Функция ТекстЗапросаПоместитьИзПараметраЛкс(Знач ИмяТаблицы, Знач ИмяПараметра = "ТЗ", Знач ЯвноВыбратьКаждоеПоле = Ложь, Знач Колонки = Неопределено, ДобавитьЗапросВыборки = Ложь, ДекларироватьТипы = Ложь) Экспорт Если ЯвноВыбратьКаждоеПоле Тогда #Если Сервер И Не Сервер Тогда Колонки = Новый ТаблицаЗначений; Колонки = Колонки.Колонки; #КонецЕсли ВыраженияПолей = Новый Массив; Для Каждого Колонка Из Колонки Цикл ВыражениеПоля = "Т." + Колонка.Имя; Если ДекларироватьТипы Тогда ВыражениеПоля = "ВЫБОР | КОГДА ИСТИНА | ТОГДА " + ВыражениеПоля; Для Каждого ТипПоля Из Колонка.ТипЗначения.Типы() Цикл ВыражениеПоля = ВыражениеПоля + " | КОГДА ЛОЖЬ | ТОГДА " + ирОбщий.ПустоеЗначениеПоТипуНаЯзыкеЗапросовЛкс(ТипПоля, Колонка.ТипЗначения); КонецЦикла; ВыражениеПоля = ВыражениеПоля + " |КОНЕЦ КАК " + Колонка.Имя; КонецЕсли; ВыраженияПолей.Добавить(ВыражениеПоля); КонецЦикла; ВыраженияПолей = " | " + ирОбщий.СтрСоединитьЛкс(ВыраженияПолей, "," + Символы.ПС); Иначе ВыраженияПолей = "*"; КонецЕсли; ТекстЗапросаПоместить = "ВЫБРАТЬ " + ВыраженияПолей + " |ПОМЕСТИТЬ " + ИмяТаблицы + " ИЗ &" + ИмяПараметра + " КАК Т;"; Если ДобавитьЗапросВыборки Тогда ТекстЗапросаПоместить = ТекстЗапросаПоместить + " |ВЫБРАТЬ * ИЗ " + ИмяТаблицы + " КАК " + ИмяТаблицы; КонецЕсли; Возврат ТекстЗапросаПоместить; КонецФункции Функция ЕстьТаблицаИзмененийОбъектаМетаданных(ПолноеИмяИлиОбъектМетаданных) Экспорт ЕстьТаблицаИзменений = Ложь; Если ТипЗнч(ПолноеИмяИлиОбъектМетаданных) = Тип("Строка") Тогда ОбъектМетаданных = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяИлиОбъектМетаданных); Если ОбъектМетаданных = Неопределено Тогда ВызватьИсключение "Объект метаданных не найден """ + ПолноеИмяИлиОбъектМетаданных + """"; КонецЕсли; Иначе ОбъектМетаданных = ПолноеИмяИлиОбъектМетаданных; КонецЕсли; //// Способ 1 //Для Каждого МетаПланОбмена Из Метаданные.ПланыОбмена Цикл // Если МетаПланОбмена.Состав.Содержит(ОбъектМетаданных) Тогда // Долго на больших конфигурациях // ЕстьТаблицаИзменений = Истина; // Прервать; // КонецЕсли; //КонецЦикла; //// Способ 2 //Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ИмяТаблицыИзМетаданныхЛкс(ОбъектМетаданных, Истина) + " КАК Т"); //Попытка // Запрос.НайтиПараметры(); // Долго, но стабильно. Длительность не зависит от количества планов обмена // ЕстьТаблицаИзменений = Истина; //Исключение // //Описание = ОписаниеОшибки(); // Пустышка = 1; //КонецПопытки; //// Способ 3 //Массив = Новый Массив; //Массив.Добавить(ОбъектМетаданных); //СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных(Массив); // очень долго //ЕстьТаблицаИзменений = СтруктураХранения.Найти("РегистрацияИзменений", "Назначение") <> Неопределено; // Способ 4 Быстрый при небольшом количестве планов обмена, а при большом? ОбъектыМетаданныхСРегистрациейИзменений = ирКэш.ОбъектыМетаданныхСРегистрациейИзменений(); ЕстьТаблицаИзменений = ОбъектыМетаданныхСРегистрациейИзменений[ОбъектМетаданных.ПолноеИмя()] <> Неопределено; Возврат ЕстьТаблицаИзменений; КонецФункции Функция ПрочитатьНаборЗаписейВТаблицуЛкс(НаборЗаписей, НовыйРежимБлокировки = Неопределено) Экспорт Если НовыйРежимБлокировки <> Неопределено Тогда ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина, НовыйРежимБлокировки); КонецЕсли; ЭтоИмитатор = Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И (Ложь Или ТипЗнч(НаборЗаписей) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей")); Если ЭтоИмитатор Тогда #Если Сервер И Не Сервер Тогда НаборЗаписей = Обработки.ирИмитаторНаборЗаписей.Создать(); #КонецЕсли НаборЗаписей.Прочитать(, Ложь); Результат = НаборЗаписей.Выгрузить(); Иначе #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей(); #КонецЕсли Данные = НаборЗаписей; ПолноеИмяМД = НаборЗаписей.Метаданные().ПолноеИмя(); КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД); Если ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Тогда // Чтобы в таблице правильно расставились субконто https://partners.v8.1c.ru/forum/t/1168440/m/1711008 Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ Т.* |ИЗ " + ПолноеИмяМД + "." + ПеревестиСтроку("ДвиженияССубконто") + "(,, Регистратор = &Регистратор) КАК Т |"; Запрос.УстановитьПараметр("Регистратор", НаборЗаписей.Отбор.Регистратор.Значение); ирОбщий.ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, Истина, РежимБлокировкиДанных.Разделяемый); // Избавиться от NULL в колонках видов субконто надо, чтобы потом метод Загрузить не выдавал ошибку Результат = ирОбщий.ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Запрос.Выполнить().Выгрузить()); Иначе НаборЗаписей.Прочитать(); Результат = НаборЗаписей.Выгрузить(); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект, ВызыватьИсключение = Истина) Экспорт Структура = Новый Структура; СтруктураОбменаДанными = СтруктураОбменаДаннымиОбъектаЛкс(Объект); Если СтруктураОбменаДанными <> Неопределено Тогда Структура.Вставить("ОбменДанными", СтруктураОбменаДанными); КонецЕсли; Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда ДополнительныеСвойстваXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект.ДополнительныеСвойства,,, ВызыватьИсключение); Структура.Вставить("ДополнительныеСвойстваXML", ДополнительныеСвойстваXML); КонецЕсли; Возврат Структура; КонецФункции Функция СтруктураОбменаДаннымиОбъектаЛкс(Знач Объект = Неопределено) Экспорт Попытка ОбменДанными = Объект.ОбменДанными; Исключение // Элемент плана обмена в 8.3.4- ОбменДанными = Неопределено; КонецПопытки; Узлы = Новый Массив; Если ОбменДанными <> Неопределено Тогда Попытка Получатели = ОбменДанными.Получатели; Исключение // Элемент плана обмена в 8.3.5+ Получатели = Неопределено; КонецПопытки; Если Получатели <> Неопределено Тогда Для Каждого Получатель Из ОбменДанными.Получатели Цикл Узлы.Добавить(Получатель); КонецЦикла; Автозаполнение = ОбменДанными.Получатели.Автозаполнение; Отправитель = ОбменДанными.Отправитель; Загрузка = ОбменДанными.Загрузка; КонецЕсли; КонецЕсли; Получатели = Новый Структура; Получатели.Вставить("Автозаполнение", Автозаполнение = Ложь); Получатели.Вставить("Узлы", Узлы); Результат = Новый Структура; Результат.Вставить("Загрузка", Загрузка = Истина); Результат.Вставить("Отправитель", Отправитель); Результат.Вставить("Получатели", Получатели); Возврат Результат; КонецФункции // СериализоватьПараметрыОбменаДанными() Процедура ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств) Экспорт Если СтруктураДополнительныхСвойств.Свойство("ОбменДанными") Тогда ВосстановитьСтруктуруОбменаДаннымиОбъектаЛкс(Объект, СтруктураДополнительныхСвойств.ОбменДанными); КонецЕсли; Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда ДополнительныеСвойства = ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураДополнительныхСвойств.ДополнительныеСвойстваXML); Если ДополнительныеСвойства <> Неопределено Тогда СкопироватьУниверсальнуюКоллекциюЛкс(ДополнительныеСвойства, Объект.ДополнительныеСвойства); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ВосстановитьСтруктуруОбменаДаннымиОбъектаЛкс(Знач Объект, Знач СтруктураОбменаДанными) Экспорт Если СтруктураОбменаДанными = Неопределено Тогда Возврат; КонецЕсли; Попытка ОбменДанными = Объект.ОбменДанными; Исключение // Элемент плана обмена в 8.3.4- Возврат; КонецПопытки; ЗаполнитьЗначенияСвойств(ОбменДанными, СтруктураОбменаДанными, "Загрузка"); Попытка Получатели = Объект.Получатели; Исключение // Элемент плана обмена в 8.3.5+ Возврат; КонецПопытки; Если СтруктураОбменаДанными.Свойство("Получатели") Тогда ЗаполнитьЗначенияСвойств(ОбменДанными.Получатели, СтруктураОбменаДанными.Получатели); ОбменДанными.Получатели.Очистить(); Для Каждого Получатель Из СтруктураОбменаДанными.Получатели.Узлы Цикл ОбменДанными.Получатели.Добавить(Получатель); КонецЦикла; КонецЕсли; КонецПроцедуры // ВосстановитьПараметрыОбменаДаннымиЛкс() // Записывает объект с параметризованным контекстом (клиент/сервер). // Обеспечивает запись объекта с попытками. Позволяет обойти неинтенсивные дедлоки и превышения ожиданий блокировки. // Также обеспечивает обход оптимистичных объектных блокировок в случае, если в БД пишутся точно те же данные объекта, что и актуальные. // Эффективно для многопоточной записи объектов. Процедура ЗаписатьОбъектЛкс(Знач Объект, Знач НаСервере = Неопределено, Знач РежимЗаписи = Неопределено, Знач РежимПроведения = Неопределено, Знач ОтключатьКонтрольЗаписи = Неопределено, Знач БезАвторегистрацииИзменений = Неопределено, Знач ПривилегированныйРежим = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт //#Если Сервер И Не Клиент Тогда // НаСервере = Ложь; //#КонецЕсли Если НаСервере = Неопределено Тогда ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс(); Если НаСервере = Неопределено Тогда НаСервере = ПараметрыЗаписи.ОбъектыНаСервере; КонецЕсли; Если ОтключатьКонтрольЗаписи = Неопределено Тогда ОтключатьКонтрольЗаписи = ПараметрыЗаписи.ОтключатьКонтрольЗаписи; КонецЕсли; Если ОтключатьЗаписьВерсии = Неопределено Тогда ОтключатьЗаписьВерсии = ПараметрыЗаписи.ОтключатьЗаписьВерсии; КонецЕсли; Если БезАвторегистрацииИзменений = Неопределено Тогда БезАвторегистрацииИзменений = ПараметрыЗаписи.БезАвторегистрацииИзменений; КонецЕсли; Если ПривилегированныйРежим = Неопределено Тогда ПривилегированныйРежим = ПараметрыЗаписи.ПривилегированныйРежим; КонецЕсли; Для Каждого СтрокаДопСвойства Из ПараметрыЗаписи.ДополнительныеСвойства Цикл Объект.ДополнительныеСвойства.Вставить(СтрокаДопСвойства.Имя, СтрокаДопСвойства.РасширенноеЗначение); КонецЦикла; Иначе Если ОтключатьКонтрольЗаписи = Неопределено Тогда ОтключатьКонтрольЗаписи = Ложь; КонецЕсли; Если ОтключатьЗаписьВерсии = Неопределено Тогда ОтключатьЗаписьВерсии = Ложь; КонецЕсли; Если БезАвторегистрацииИзменений = Неопределено Тогда БезАвторегистрацииИзменений = Ложь; КонецЕсли; Если ПривилегированныйРежим = Неопределено Тогда ПривилегированныйРежим = Ложь; КонецЕсли; КонецЕсли; Если НаСервере Тогда ТипОбъекта = ТипЗнч(Объект); ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта); Если ЭтоИмитатор Тогда ОбъектXML = Объект.Снимок(, Ложь); Иначе ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект); ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); КонецЕсли; ирСервер.ЗаписатьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, РежимЗаписи, РежимПроведения, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ТипОбъекта, ПривилегированныйРежим, ОтключатьЗаписьВерсии); Если ЭтоИмитатор Тогда Объект.ЗагрузитьСнимок(ОбъектXML); Иначе Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML); ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства); КонецЕсли; //#Если Клиент Тогда // Попытка // СсылкаОбъекта = Объект.Ссылка; // Исключение // КонецПопытки; // Если СсылкаОбъекта <> Неопределено Тогда // // При групповых обработках видимо будут большие потери // ОповеститьОбИзменении(СсылкаОбъекта); // КонецЕсли; //#КонецЕсли Иначе Если ПривилегированныйРежим Тогда УстановитьПривилегированныйРежим(Истина); КонецЕсли; Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(Объект); КонецЕсли; ОтключатьКонтрольЗаписи = Истина И ОтключатьКонтрольЗаписи = Истина И (Ложь Или РежимЗаписи = Неопределено Или РежимЗаписи = РежимЗаписиДокумента.Запись); НачалоПопыток = ТекущаяДата(); // Для обхода дедлоков и оптимистичной объектной блокировки при высокой параллельности Если РежимЗаписи = Неопределено Тогда ПопытокЗаписиОбъекта = 5; Иначе ПопытокЗаписиОбъекта = 3; КонецЕсли; ПредельнаяДлительность = 20; Для СчетчикПопыток = 1 По ПопытокЗаписиОбъекта Цикл УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ОтключатьЗаписьВерсии); Попытка Если РежимЗаписи = Неопределено Тогда Объект.Записать(); ИначеЕсли РежимЗаписи = "ПометкаУдаления" Тогда Объект.Записать(); Объект.ОбменДанными.Загрузка = Ложь; Если Не ирКэш.ЛиПортативныйРежимЛкс() И ТипЗнч(Объект) = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект") Тогда ПометкаУдаления = Объект.Данные.ПометкаУдаления; Иначе ПометкаУдаления = Объект.ПометкаУдаления; КонецЕсли; Объект.УстановитьПометкуУдаления(Не ПометкаУдаления); ИначеЕсли Истина И ТипЗнч(РежимЗаписи) = Тип("РежимЗаписиДокумента") И РежимЗаписи <> РежимЗаписиДокумента.Запись Тогда Объект.ОбменДанными.Загрузка = Ложь; Объект.Записать(РежимЗаписи, РежимПроведения); Иначе Объект.Записать(РежимЗаписи); КонецЕсли; Прервать; Исключение НужноВызватьИсключение = Истина; ОписаниеОшибки = ОписаниеОшибки(); НовоеОписаниеОшибки = ""; Если ТранзакцияАктивна() Тогда //НовоеОписаниеОшибки = "Транзакция активна" + Символы.ПС + ОписаниеОшибки; Иначе НОписаниеОшибки = НРег(ОписаниеОшибки); Если Истина И РежимЗаписи = Неопределено И (Ложь Или Найти(НОписаниеОшибки, "несоответствия версии или отсутствия записи базы данных") > 0 Или Найти(НОписаниеОшибки, "version mismatch or lack of database record") > 0) Тогда НужноВызватьИсключение = Ложь; ТекущийXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект, Ложь); //Объект.Прочитать(); // Чтение с блокировкой нам не нужно ОбъектДляСравнения = ПеречитатьОбъектЗапросомЛкс(Объект); Если Объект <> Неопределено Тогда НовыйXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ОбъектДляСравнения, Ложь); Если ТекущийXML = НовыйXML Тогда Прервать; Иначе Попытка лРежимЗагрузка = Объект.ОбменДанными.Загрузка; Исключение лРежимЗагрузка = Неопределено; КонецПопытки; ПолноеИмяМД = Объект.Метаданные().ПолноеИмя(); Если лРежимЗагрузка = Истина И СчетчикПопыток = 2 Тогда СообщитьЛкс("Возможно в обработчиках ПередЗаписью объекта " + ПолноеИмяМД + " в режиме Загрузка выполняется его нестабильная модификация"); КонецЕсли; НужноВызватьИсключение = СчетчикПопыток = ПопытокЗаписиОбъекта; Если НужноВызватьИсключение Тогда НовоеОписаниеОшибки = "Обход оптимистичной блокировки объекта " + ПолноеИмяМД + " отменен из-за его нестабильной модификации в обработчиках ПередЗаписью (Загрузка=" + XMLСтрока(лРежимЗагрузка) + ")" + Символы.ПС + ОписаниеОшибки; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или Найти(ОписаниеОшибки, "взаимоблокировк") > 0 Или Найти(ОписаниеОшибки, "deadlock") > 0 Тогда НужноВызватьИсключение = Ложь; КонецЕсли; КонецЕсли; Если Не НужноВызватьИсключение Тогда Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда //НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда //НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда //НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки; НужноВызватьИсключение = Истина; КонецЕсли; КонецЕсли; #Если Клиент Тогда Если ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(НОписаниеОшибки, Ложь) Тогда ВызватьИсключение; КонецЕсли; #КонецЕсли Если НужноВызватьИсключение Тогда СостояниеОбъекта = ПредставлениеДопСвойствОбъектаЛкс(Объект); Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта; Иначе НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда ВызватьИсключение НовоеОписаниеОшибки; Иначе ВызватьИсключение; КонецЕсли; КонецЕсли; КонецПопытки; КонецЦикла; КонецЕсли; КонецПроцедуры Функция ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта) Экспорт ЭтоИмитатор = Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И (Ложь Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей") Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторКонстантаМенеджер") Или ТипОбъекта = Тип("ОбработкаОбъект.ирИмитаторСсылочныйОбъект")); Возврат ЭтоИмитатор; КонецФункции // Параметры: // НаборЗаписейКуда - НаборЗаписей, ирИмитаторНаборЗаписей // КоллекцияПолученаВыгрузкойНабора - Булево - используется при ЗаполнитьВидыСубконто = Истина Процедура ЗагрузитьКоллекциюВНаборЗаписейЛкс(КоллекцияСтрокДвижений, НаборЗаписейКуда, ЗаполнитьВидыСубконто = Ложь, КоллекцияПолученаВыгрузкойНабора = Ложь) Экспорт ТаблицаДляЗагрузки = НаборЗаписейКуда.ВыгрузитьКолонки(); Для Каждого СтрокаНовойТаблицы Из КоллекцияСтрокДвижений Цикл ЗаполнитьЗначенияСвойств(ТаблицаДляЗагрузки.Добавить(), СтрокаНовойТаблицы); КонецЦикла; Если ЗаполнитьВидыСубконто Тогда ОбъектМД = Метаданные.НайтиПоТипу(ТипОбъектаБДЛкс(НаборЗаписейКуда)); КорневойТип = ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя()); Если ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Тогда ЗаполнитьВидыСубконтоВТаблицеЛкс(ТаблицаДляЗагрузки, ОбъектМД, КоллекцияПолученаВыгрузкойНабора); КонецЕсли; КонецЕсли; НаборЗаписейКуда.Загрузить(ТаблицаДляЗагрузки); //ирОбщий.НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(НаборЗаписейКуда); //Теперь это делается в ирОбщий.ЗаписатьОбъектЛкс() КонецПроцедуры Процедура ЗаполнитьВидыСубконтоВТаблицеЛкс(ТаблицаДляЗагрузки, ОбъектМД, ТаблицаПолученаВыгрузкойНабора = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаДляЗагрузки = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей(); ОбъектМД = ТаблицаДляЗагрузки.Метаданные(); #КонецЕсли СписокСчетов = Новый Массив; Для Каждого Проводка Из ТаблицаДляЗагрузки Цикл СписокСчетов.Добавить(Проводка.СчетДт); СписокСчетов.Добавить(Проводка.СчетКт); КонецЦикла; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Т.НомерСтроки КАК НомерСтроки, | Т.ВидСубконто КАК ВидСубконто, | Т.Ссылка КАК Ссылка |ИЗ | " + ОбъектМД.ПланСчетов.ПолноеИмя() + ".ВидыСубконто КАК Т |ГДЕ | Т.Ссылка В(&Счет) |УПОРЯДОЧИТЬ ПО ВидСубконто |"; // Порядок видов субконто в Набор.Выгрузить() и "ВЫБРАТЬ * ИЗ Регистр" могут не совпадать https://partners.v8.1c.ru/forum/t/1168440/m/1711008 Запрос.УстановитьПараметр("Счет", СписокСчетов); ТаблицаВидовСубконто = Запрос.Выполнить().Выгрузить(); МассивСторон = Новый Массив; МассивСторон.Добавить("Дт"); МассивСторон.Добавить("Кт"); Для Каждого Проводка Из ТаблицаДляЗагрузки Цикл Для Каждого Сторона Из МассивСторон Цикл СтрокиВидовСубконто = ТаблицаВидовСубконто.НайтиСтроки(Новый Структура("Ссылка", Проводка["Счет" + Сторона])); Счетчик = 1; Для Каждого СтрокаВидаСубконто Из СтрокиВидовСубконто Цикл Если ТаблицаПолученаВыгрузкойНабора Тогда НомерСубконто = Счетчик; Иначе НомерСубконто = СтрокаВидаСубконто.НомерСтроки; КонецЕсли; Проводка["ВидСубконто" + Сторона + НомерСубконто] = СтрокаВидаСубконто.ВидСубконто; Счетчик = Счетчик + 1; КонецЦикла; КонецЦикла; КонецЦикла; КонецПроцедуры Процедура УстановитьПометкуУдаленияОбъектаЛкс(Объект, НаСервере = Неопределено, ЗначениеПометки = Истина, БезАвторегистрацииИзменений = Неопределено, ПривилегированныйРежим = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт Если НаСервере = Неопределено Тогда ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс(); Если НаСервере = Неопределено Тогда НаСервере = ПараметрыЗаписи.ОбъектыНаСервере; КонецЕсли; Если БезАвторегистрацииИзменений = Неопределено Тогда БезАвторегистрацииИзменений = ПараметрыЗаписи.БезАвторегистрацииИзменений; КонецЕсли; Если ПривилегированныйРежим = Неопределено Тогда ПривилегированныйРежим = ПараметрыЗаписи.ПривилегированныйРежим; КонецЕсли; Если ОтключатьЗаписьВерсии = Неопределено Тогда ОтключатьЗаписьВерсии = ПараметрыЗаписи.ОтключатьЗаписьВерсии; КонецЕсли; Для Каждого СтрокаДопСвойства Из ПараметрыЗаписи.ДополнительныеСвойства Цикл Объект.ДополнительныеСвойства.Вставить(СтрокаДопСвойства.Имя, СтрокаДопСвойства.РасширенноеЗначение); КонецЦикла; КонецЕсли; Если НаСервере Тогда ТипОбъекта = ТипЗнч(Объект); ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта); Если ЭтоИмитатор Тогда #Если Сервер И Не Сервер Тогда Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать(); #КонецЕсли ОбъектXML = Объект.Снимок(); Иначе ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект); ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); КонецЕсли; ирСервер.УстановитьПометкуУдаленияОбъектаЛкс(ОбъектXML, ДополнительныеСвойства, ЗначениеПометки, БезАвторегистрацииИзменений, ТипОбъекта, ПривилегированныйРежим, ОтключатьЗаписьВерсии); Если ЭтоИмитатор Тогда Объект.ЗагрузитьСнимок(ОбъектXML); Иначе Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML); ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства); КонецЕсли; #Если Клиент Тогда ОповеститьОбИзменении(Объект.Ссылка); #КонецЕсли Иначе Если ПривилегированныйРежим Тогда УстановитьПривилегированныйРежим(Истина); КонецЕсли; УстановитьПараметрыЗаписиОбъектаЛкс(Объект, , БезАвторегистрацииИзменений, ОтключатьЗаписьВерсии); //Если РежимЗаписи = Неопределено Тогда // Объект.УстановитьПометкуУдаления(ЗначениеПометки); //Иначе Объект.УстановитьПометкуУдаления(ЗначениеПометки); //КонецЕсли; КонецЕсли; КонецПроцедуры Процедура УдалитьОбъектЛкс(Знач Объект, Знач НаСервере = Неопределено, Знач ОтключатьКонтрольЗаписи = Неопределено, Знач БезАвторегистрацииИзменений = Неопределено, ПривилегированныйРежим = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт Если НаСервере = Неопределено Тогда ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс(); Если НаСервере = Неопределено Тогда НаСервере = ПараметрыЗаписи.ОбъектыНаСервере; КонецЕсли; Если ОтключатьКонтрольЗаписи = Неопределено Тогда ОтключатьКонтрольЗаписи = ПараметрыЗаписи.ОтключатьКонтрольЗаписи; КонецЕсли; Если ОтключатьЗаписьВерсии = Неопределено Тогда ОтключатьЗаписьВерсии = ПараметрыЗаписи.ОтключатьЗаписьВерсии; КонецЕсли; Если БезАвторегистрацииИзменений = Неопределено Тогда БезАвторегистрацииИзменений = ПараметрыЗаписи.БезАвторегистрацииИзменений; КонецЕсли; Если ПривилегированныйРежим = Неопределено Тогда ПривилегированныйРежим = ПараметрыЗаписи.ПривилегированныйРежим; КонецЕсли; Для Каждого СтрокаДопСвойства Из ПараметрыЗаписи.ДополнительныеСвойства Цикл Объект.ДополнительныеСвойства.Вставить(СтрокаДопСвойства.Имя, СтрокаДопСвойства.РасширенноеЗначение); КонецЦикла; КонецЕсли; УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ОтключатьЗаписьВерсии); Если НаСервере Тогда ТипОбъекта = ТипЗнч(Объект); ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта); Если ЭтоИмитатор Тогда #Если Сервер И Не Сервер Тогда Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать(); #КонецЕсли ОбъектXML = Объект.Снимок(, Ложь); Иначе ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект); ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); КонецЕсли; ирСервер.УдалитьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений, ТипОбъекта, ПривилегированныйРежим, ОтключатьЗаписьВерсии); // https://partners.v8.1c.ru/forum/t/1728509/m/1728509 Если ЭтоИмитатор Тогда // Объект.ЗагрузитьСнимок(ОбъектXML); Объект.СброситьМодифицированность(); //Иначе // Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML); // ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства); КонецЕсли; #Если Клиент Тогда ОповеститьОбИзменении(Объект.Ссылка); #КонецЕсли Иначе Если ПривилегированныйРежим Тогда УстановитьПривилегированныйРежим(Истина); КонецЕсли; Объект.Удалить(); КонецЕсли; КонецПроцедуры Процедура УстановитьПараметрыЗаписиОбъектаЛкс(Знач Объект, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено, ОтключатьЗаписьВерсии = Неопределено) Экспорт Попытка ОбменДанными = Объект.ОбменДанными; Исключение // Элемент плана обмена в 8.3.4- ОбменДанными = Неопределено; КонецПопытки; Если ОбменДанными <> Неопределено Тогда Если ОтключатьКонтрольЗаписи <> Неопределено Тогда ОбменДанными.Загрузка = ОтключатьКонтрольЗаписи; КонецЕсли; Если БезАвторегистрацииИзменений <> Неопределено Тогда Попытка Получатели = ОбменДанными.Получатели; Исключение // Элемент плана обмена в 8.3.5+ Получатели = Неопределено; КонецПопытки; Если Получатели <> Неопределено Тогда Получатели.Автозаполнение = Не БезАвторегистрацииИзменений; КонецЕсли; КонецЕсли; КонецЕсли; Попытка ЗаписьИсторииДанных = Объект.ЗаписьИсторииДанных; Исключение // 8.3.14- ЗаписьИсторииДанных = Неопределено; КонецПопытки; Если ЗаписьИсторииДанных <> Неопределено Тогда Если ОтключатьЗаписьВерсии <> Неопределено Тогда ЗаписьИсторииДанных.Отказ = ОтключатьЗаписьВерсии; КонецЕсли; КонецЕсли; КонецПроцедуры // Параметры: // КлючОбъекта - Произвольный, *Неопределено - для нового ссылочного объекта Истина=Папка, для регистров передается Структура // ЧитатьДанныеРегистраИлиКонстанты - Булево - применяется только если задан КлючОбъекта Функция ОбъектБДПоКлючуЛкс(Знач ИмяОсновнойТаблицы, Знач КлючОбъекта = Неопределено, Знач СохранятьИдентификаторСсылки = Ложь, Знач ЧитатьДанныеРегистраИлиКонстанты = Истина, Знач ОбъектыНаСервере = Неопределено, выхИдентификаторСсылки = Неопределено, РазрешитьВложенныйВызов = Истина, НомерВерсии = Неопределено) Экспорт Если ОбъектыНаСервере = Неопределено Тогда ПараметрыЗаписи = ирКэш.ПараметрыЗаписиОбъектовЛкс(); #Если Сервер И Не Клиент Тогда ОбъектыНаСервере = Ложь; #Иначе //ОбъектыНаСервере = ирОбщий.ПолучитьРежимОбъектыНаСервереПоУмолчаниюЛкс(); ОбъектыНаСервере = ПараметрыЗаписи.ОбъектыНаСервере; #КонецЕсли КонецЕсли; ТипОсновнойТаблицы = ирОбщий.ТипТаблицыБДЛкс(ИмяОсновнойТаблицы); ЭтоМетаСсылка = ирОбщий.ЛиТипТаблицыМетассылкиЛкс(ТипОсновнойТаблицы); РазрешитьИмитаторы = ОбъектыНаСервере <> Ложь И Не ирКэш.ЭтоФайловаяБазаЛкс() И Не ирКэш.ЛиПортативныйРежимЛкс() И Не ЭтоМетаСсылка И Не ирКэш.ПараметрыЗаписиОбъектовЛкс().НеИспользоватьИмитаторыОбъектовДанных; мМетаданныеОбъекта = ирОбщий.ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяОсновнойТаблицы, Истина); Если мМетаданныеОбъекта = Неопределено Тогда Если ЗначениеЗаполнено(ИмяОсновнойТаблицы) Тогда ИмяОсновнойТаблицы = Неопределено; КонецЕсли; Иначе мПолноеИмяМД = мМетаданныеОбъекта.ПолноеИмя(); КонецЕсли; ЭтоСсылочныйОбъект = Ложь Или ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипОсновнойТаблицы) Или (Истина И ТипОсновнойТаблицы = "Внешняя" И мМетаданныеОбъекта.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные); Если Истина И РазрешитьИмитаторы И РазрешитьВложенныйВызов И (Ложь Или ЭтоСсылочныйОбъект Или ОбъектыНаСервере = "Обязательно") Тогда СтруктураСнимка = ирСервер.ПолучитьСнимокОбъектаБДПоКлючуЛкс(ИмяОсновнойТаблицы, КлючОбъекта, СохранятьИдентификаторСсылки, ЧитатьДанныеРегистраИлиКонстанты, выхИдентификаторСсылки, НомерВерсии); Если СтруктураСнимка <> Неопределено Тогда Имитатор = Новый (СтруктураСнимка.ТипОбъекта); #Если Сервер И Не Сервер Тогда Имитатор = Обработки.ирИмитаторСсылочныйОбъект.Создать(); #КонецЕсли Имитатор.ЗагрузитьСнимок(СтруктураСнимка.Снимок); Результат = Новый Структура; Результат.Вставить("Методы", Имитатор); Результат.Вставить("Данные", Имитатор.Данные); КонецЕсли; Иначе ЭтоКонстанта = ирОбщий.ЛиКорневойТипКонстантыЛкс(ТипОсновнойТаблицы); ЭтоПланОбмена = ирОбщий.ЛиКорневойТипПланаОбменаЛкс(ТипОсновнойТаблицы); ЭтоДокумент = ирОбщий.ЛиКорневойТипДокументаЛкс(ТипОсновнойТаблицы); //ЭтоВнешнийОбъект = ТипОсновнойТаблицы = "Внешняя"; Если Ложь Или Не ЗначениеЗаполнено(ТипОсновнойТаблицы) Или (Истина И ЭтоСсылочныйОбъект И ТипЗнч(КлючОбъекта) = Тип("Строка")) Тогда Возврат Неопределено; КонецЕсли; Результат = Новый Структура; Если ЭтоСсылочныйОбъект Тогда Если ЭтоМетаСсылка Тогда Объект = КлючОбъекта; выхСтруктураОбъекта = КлючОбъекта; Данные = Объект; Методы = Объект; Иначе Если Истина //И ЧитатьДанные И ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта)) И ЗначениеЗаполнено(КлючОбъекта) Тогда Если ЗначениеЗаполнено(НомерВерсии) Тогда ИсторияДанныхМоя = Вычислить("ИсторияДанных"); #Если Сервер И Не Сервер Тогда ИсторияДанныхМоя = ИсторияДанных; #КонецЕсли Объект = ИсторияДанныхМоя.СформироватьПоВерсии(КлючОбъекта, НомерВерсии); Объект.ДополнительныеСвойства.Вставить("НомерЗагруженнойВерсии", НомерВерсии); Иначе Объект = КлючОбъекта.ПолучитьОбъект(); //Если Объект <> Неопределено Тогда // Объект.Прочитать(); // Получаем гарантировано свежие данные мимо объектного кэша, но объектный кэш не обновится https://partners.v8.1c.ru/forum/topic/1383852 //КонецЕсли; КонецЕсли; КонецЕсли; Если Объект = Неопределено Тогда Если ЛиТипСсылкиБДЛкс(ТипЗнч(КлючОбъекта)) Тогда выхИдентификаторСсылки = КлючОбъекта.УникальныйИдентификатор(); ИначеЕсли Не СохранятьИдентификаторСсылки Тогда выхИдентификаторСсылки = Неопределено; КонецЕсли; Если КлючОбъекта <> "" Тогда ЭтоГруппаДляНового = КлючОбъекта = Истина; Попытка Объект = ирОбщий.СоздатьСсылочныйОбъектПоМетаданнымЛкс(мПолноеИмяМД, ЭтоГруппаДляНового, выхИдентификаторСсылки); Исключение // Может не быть прав на создание объекта СообщитьЛкс("Ошибка создания объекта: " + ОписаниеОшибки()); Возврат Неопределено; КонецПопытки; КонецЕсли; КонецЕсли; Данные = Объект; Методы = Объект; //#Если Не Клиент И Сервер Тогда Если РазрешитьИмитаторы Тогда ИмитаторОбъекта = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторСсылочныйОбъект"); #Если Сервер И Не Сервер Тогда ИмитаторОбъекта = Обработки.ирИмитаторСсылочныйОбъект.Создать(); #КонецЕсли ИмитаторОбъекта.Конструктор(Объект); Данные = ИмитаторОбъекта.Данные; Методы = ИмитаторОбъекта; КонецЕсли; //#КонецЕсли КонецЕсли; Иначе Если РазрешитьИмитаторы Тогда Если ЭтоКонстанта Тогда ИмитаторОбъекта = Обработки.ирИмитаторКонстантаМенеджер.Создать(); ИмитаторОбъекта.КонструкторПоКлючу(ИмяОсновнойТаблицы); Иначе ИмитаторОбъекта = Обработки.ирИмитаторНаборЗаписей.Создать(); ИмитаторОбъекта.КонструкторПоКлючу(ИмяОсновнойТаблицы, КлючОбъекта); КонецЕсли; Данные = ИмитаторОбъекта.Данные; Методы = ИмитаторОбъекта; Иначе Если ЭтоКонстанта Тогда Объект = Новый (СтрЗаменить(ИмяОсновнойТаблицы, ".", "МенеджерЗначения.")); Иначе Объект = Новый (ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ИмяОсновнойТаблицы)); #Если Сервер И Не Сервер Тогда Объект = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей(); #КонецЕсли Если КлючОбъекта <> Неопределено Тогда ЗаполнитьОтборПоКлючуЛкс(Объект.Отбор, КлючОбъекта); КонецЕсли; КонецЕсли; Данные = Объект; Методы = Объект; КонецЕсли; Если КлючОбъекта <> Неопределено И ЧитатьДанныеРегистраИлиКонстанты Тогда Методы.Прочитать(); КонецЕсли; КонецЕсли; Результат.Вставить("Данные", Данные); Результат.Вставить("Методы", Методы); Возврат Результат; КонецЕсли; Возврат Результат; КонецФункции Процедура ЗаполнитьОтборПоКлючуЛкс(Знач Отбор, Знач КлючОбъекта) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый ПостроительЗапроса; Отбор = Пустышка.Отбор; #КонецЕсли Для Каждого ЭлементОтбора Из Отбор Цикл СтруктураЧтенияЗначения = Новый Структура(ЭлементОтбора.Имя, null); ЗаполнитьЗначенияСвойств(СтруктураЧтенияЗначения, КлючОбъекта); Если СтруктураЧтенияЗначения[ЭлементОтбора.Имя] <> Null Тогда Отбор[ЭлементОтбора.Имя].Установить(КлючОбъекта[ЭлементОтбора.Имя]); КонецЕсли; КонецЦикла; КонецПроцедуры Функция ТипОбъектаБДЛкс(ОбъектБД) Экспорт Результат = ТипЗнч(ОбъектБД); Если Результат = Тип("Структура") Тогда Имитатор = ОбъектБД.Методы; Иначе Имитатор = ОбъектБД; КонецЕсли; Результат = ТипЗнч(Имитатор); Если ЭтоТипИмитатораОбъектаЛкс(Результат) Тогда Результат = Имитатор._Тип; КонецЕсли; Возврат Результат; КонецФункции Функция КопияОбъектаБДЛкс(СтруктураОбъекта) Экспорт СтруктураОбъекта = СтруктураОбъекта.Методы.Скопировать(); Если ТипЗнч(СтруктураОбъекта) <> Тип("Структура") Тогда СтруктураОбъектаНовая = Новый Структура; СтруктураОбъектаНовая.Вставить("Методы", СтруктураОбъекта); СтруктураОбъектаНовая.Вставить("Данные", СтруктураОбъекта); СтруктураОбъекта = СтруктураОбъектаНовая; КонецЕсли; Возврат СтруктураОбъекта; КонецФункции Функция СкопироватьТаблицуЛкс(ТаблицаИлиТабличнаяЧасть, ПараметрыОтбора = Неопределено, Колонки = Неопределено) Экспорт Если ТипЗнч(ТаблицаИлиТабличнаяЧасть) = Тип("ТаблицаЗначений") Тогда Результат = ТаблицаИлиТабличнаяЧасть.Скопировать(ПараметрыОтбора, Колонки); Иначе Результат = ТаблицаИлиТабличнаяЧасть.Выгрузить(ПараметрыОтбора, Колонки); КонецЕсли; Возврат Результат; КонецФункции Функция ПредставлениеДопСвойствОбъектаЛкс(Объект) Попытка ДополнительныеСвойства = Объект.ДополнительныеСвойства; Исключение ДополнительныеСвойства = Новый Структура; КонецПопытки; СостояниеОбъекта = ""; Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл Если ЛиСсылкаНаОбъектБДЛкс(КлючИЗначение.Значение) И ТранзакцияАктивна() Тогда // На случай сломанной транзакции ПредставлениеЗначения = ирОбщий.ПолныйИдентификаторСсылкиЛкс(КлючИЗначение.Значение); Иначе ПредставлениеЗначения = "" + КлючИЗначение.Значение; КонецЕсли; СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + ПредставлениеЗначения; КонецЦикла; Возврат СостояниеОбъекта; КонецФункции Функция ПрочитатьДвиженияДокументаПакетноЛкс(Ссылка, ОбъектыНаСервере = Неопределено, ТолькоКоличествоСтрок = Ложь) Экспорт ОбъектМД = Ссылка.Метаданные(); ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, Истина, Истина); Результат = Новый Соответствие; Если ОбъектыМД.Количество() > 0 Тогда Текст = ""; Для Каждого МетаРегистр из ОбъектыМД Цикл Если Текст <> "" Тогда Текст = Текст + ";" + Символы.ПС; КонецЕсли; ПолноеИмяМДРегистра = МетаРегистр.ПолноеИмя(); ИмяТаблицыБДРегистра = ИмяТаблицыИзМетаданныхЛкс(МетаРегистр); Если ТолькоКоличествоСтрок Тогда Текст = Текст + "ВЫБРАТЬ Количество(*)"; Иначе Текст = Текст + "ВЫБРАТЬ Т.*"; КонецЕсли; Если ТипТаблицыБДЛкс(ИмяТаблицыБДРегистра) = "ДвиженияССубконто" Тогда Текст = Текст + " |ИЗ " + ИмяТаблицыБДРегистра + "(,, Регистратор = &Ссылка) КАК Т"; Иначе ИмяПоляОтбора = ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра); Текст = Текст + " |ИЗ " + ИмяТаблицыБДРегистра + " КАК Т |ГДЕ Т." + ИмяПоляОтбора + " = &Ссылка"; КонецЕсли; КонецЦикла; Запрос = Новый Запрос; Запрос.Текст = Текст; Запрос.УстановитьПараметр("Ссылка", Ссылка); РезультатПакета = Запрос.ВыполнитьПакет(); ИндексВПакете = 0; Для Каждого МетаРегистр из ОбъектыМД Цикл ПолноеИмяМДРегистра = МетаРегистр.ПолноеИмя(); ИмяТаблицыБДРегистра = ИмяТаблицыИзМетаданныхЛкс(МетаРегистр); Результат[ПолноеИмяМДРегистра] = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(РезультатПакета[ИндексВПакете].Выгрузить()); Если ТолькоКоличествоСтрок Тогда Результат[ПолноеИмяМДРегистра] = Результат[ПолноеИмяМДРегистра][0][0]; КонецЕсли; ИндексВПакете = ИндексВПакете + 1; КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции Функция ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(Знач ИмяТаблицыБДРегистра) Экспорт ТипТаблицы = ТипТаблицыБДЛкс(ИмяТаблицыБДРегистра); Если ТипТаблицы = "Перерасчет" Тогда ИмяПоля = "ОбъектПерерасчета"; Иначе ИмяПоля = "Регистратор"; КонецЕсли; ИмяПоля = ирОбщий.ПеревестиСтроку(ИмяПоля); Возврат ИмяПоля; КонецФункции // Позволяет перечитать объект грязным чтением, т.е. без учета блокировок. Не перечитывает свойство ВерсияДанных! // На выходе объект имеет модифицированноть. Для удаленного объекта возвращает Неопределено. Функция ПеречитатьОбъектЗапросомЛкс(Знач Объект) Экспорт ОбъектМД = Объект.Метаданные(); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ * ИЗ " + ОбъектМД.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка"; Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка); ТаблицаОбъекта = Запрос.Выполнить().Выгрузить(); Если ТаблицаОбъекта.Количество() > 0 Тогда СтрокаДанных = ТаблицаОбъекта[0]; Для Каждого КолонкаТаблицы Из ТаблицаОбъекта.Колонки Цикл ЗначениеРеквизита = СтрокаДанных[КолонкаТаблицы.Имя]; Если ЗначениеРеквизита = Null Тогда // Реквизит (но не табличная часть) недоступен по признаку ЭтоГруппа. Если к нему обратиться у объекта, то будет ошибка "Ошибка установки значения свойства '...': Реквизит недоступен для группы" Продолжить; КонецЕсли; Пустышка = Объект[КолонкаТаблицы.Имя]; // Проверяем корректность вычисления выражения перед его использованием в попытке Если КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Попытка Объект[КолонкаТаблицы.Имя].Загрузить(ЗначениеРеквизита); Исключение // Табличная часть недоступна по признаку ЭтоГруппа. Выдается ошибка "Ошибка при вызове метода контекста (Загрузить): Объект недоступен для изменения" КонецПопытки; Иначе Попытка Объект[КолонкаТаблицы.Имя] = ЗначениеРеквизита; Исключение // Реквизит предназначен только для чтения КонецПопытки; КонецЕсли; КонецЦикла; Иначе Объект = Неопределено; КонецЕсли; Возврат Объект; КонецФункции // Антибаг платформы https://partners.v8.1c.ru/forum/topic/1168440 Процедура НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(Знач НаборЗаписей) Экспорт ЭтоИмитатор = Истина И Не ирКэш.ЛиПортативныйРежимЛкс() И (Ложь Или ТипЗнч(НаборЗаписей) = Тип("ОбработкаОбъект.ирИмитаторНаборЗаписей")); Если ЭтоИмитатор Тогда Возврат; Иначе #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей(); #КонецЕсли Данные = НаборЗаписей; ОбъектМД = НаборЗаписей.Метаданные(); КонецЕсли; КорневойТип = ПервыйФрагментЛкс(ОбъектМД.ПолноеИмя()); Если ЛиКорневойТипРегистраБухгалтерииЛкс(КорневойТип) Тогда Для Каждого Проводка Из Данные Цикл ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Ресурсы, ОбъектМД); ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Измерения, ОбъектМД); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, КоллекцияПолей, ОбъектМД) Экспорт #Если Сервер И Не Сервер Тогда Проводка = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей().Добавить(); ОбъектМД = Метаданные.РегистрыБухгалтерии.Хозрасчетный; #КонецЕсли Для Каждого Поле Из КоллекцияПолей Цикл Если Истина И Не Поле.Балансовый И Поле.ПризнакУчета <> Неопределено Тогда ИмяПризнакаУчета = Поле.ПризнакУчета.Имя; Если ОбъектМД.Корреспонденция Тогда Если Не Проводка.СчетДт[ИмяПризнакаУчета] Тогда ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Дт"], Неопределено); КонецЕсли; Если Не Проводка.СчетКт[ИмяПризнакаУчета] Тогда ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Кт"], Неопределено); КонецЕсли; Иначе Если Не Проводка.Счет[ИмяПризнакаУчета] Тогда ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя], Неопределено); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // Источник - http://infostart.ru/public/125988/ Функция ВыбратьПоГруппировкамЛкс(Выборка, Группировки, СИерархией = Ложь) Экспорт МетаВыборка = Новый Соответствие; врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкам; Если СИерархией Тогда врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией; КонецЕсли; МетаВыборка.Вставить("ОбходРезультата", врОбходРезультата); МассивГруппировок = Новый Массив; врСтрГруппировки = Группировки; Пока Истина Цикл Поз = Найти( врСтрГруппировки, "," ); Если Поз = 0 Тогда МассивГруппировок.Добавить(СокрЛП(врСтрГруппировки)); Прервать; КонецЕсли; МассивГруппировок.Добавить( СокрЛП( Лев(врСтрГруппировки,Поз-1) ) ); врСтрГруппировки = Сред( врСтрГруппировки, Поз+1 ); КонецЦикла; МетаВыборка.Вставить("Группировки", МассивГруппировок); врВыборка = Выборка; Для пц=0 По МассивГруппировок.Количество()-2 Цикл врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]); МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня); Если не врВыборкаУровня.Следующий() Тогда Прервать; КонецЕсли; врВыборка = врВыборкаУровня; КонецЦикла; врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]); МетаВыборка.Вставить("Выборка", врВыборкаУровня); МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня); Возврат МетаВыборка; КонецФункции // ВыбратьПоГруппировкамЛкс // Источник - http://infostart.ru/public/125988/ Функция СледующийПоГруппировкамЛкс(МетаВыборка, Уровень = Неопределено) Экспорт Если Уровень = Неопределено Тогда Уровень = МетаВыборка["Группировки"].Количество()-1; КонецЕсли; Если Уровень < 0 Тогда Возврат Ложь; КонецЕсли; врВыборка = МетаВыборка["_Выборка"+Строка(Уровень)]; Если врВыборка.Следующий() Тогда Возврат Истина; КонецЕсли; Если СледующийПоГруппировкамЛкс(МетаВыборка, Уровень-1) Тогда МассивГруппировок = МетаВыборка["Группировки"]; врВыборкаРодитель = МетаВыборка["_Выборка"+Строка(Уровень-1)]; врВыборка = врВыборкаРодитель.Выбрать(МетаВыборка["ОбходРезультата"],МассивГруппировок[Уровень]); МетаВыборка["_Выборка"+Строка(Уровень)] = врВыборка; Если Уровень = МассивГруппировок.Количество()-1 Тогда МетаВыборка["Выборка"] = врВыборка; КонецЕсли; Возврат СледующийПоГруппировкамЛкс(МетаВыборка, Уровень); Иначе Возврат Ложь; КонецЕсли; КонецФункции // зфСледующийПоГруппировкам Функция ВариантыРасположенияКонфигурационногоФайлаЛкс(выхСписок = Неопределено) Экспорт выхСписок = Новый СписокЗначений; выхСписок.Добавить("АктивныйФайл", "Активный файл"); выхСписок.Добавить("ДляТекущегоПользователя", "Для текущего пользователя ОС"); выхСписок.Добавить("ДляТекущейВерсии", "Для текущей версии платформы"); выхСписок.Добавить("ПеренаправлениеТекущейВерсии", "Перенаправление текущей версии"); Результат = Новый Структура; Для Каждого ЭлементСписка Из выхСписок Цикл Результат.Вставить(ЭлементСписка.Значение, ЭлементСписка.Значение); КонецЦикла; Возврат Результат; КонецФункции // ВариантРасположенияФайлаНастроек - // ДляТекущейВерсии // ПеренаправлениеТекущейВерсии - использовать значение ключа ConfLocation из файла conf.cfg // ДляТекущегоПользователя Функция КаталогНастроекПриложения1СЛкс(ВариантРасположенияФайлаНастроек = "ПеренаправлениеТекущейВерсии", СоздатьЕслиОтсутствует = Ложь, НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.ПолучитьКаталогНастроекПриложения1СЛкс(ВариантРасположенияФайлаНастроек, СоздатьЕслиОтсутствует); Иначе ВариантыРасположения = ВариантыРасположенияКонфигурационногоФайлаЛкс(); Если Ложь Или ВариантРасположенияФайлаНастроек = ВариантыРасположения.АктивныйФайл Или ВариантРасположенияФайлаНастроек = ВариантыРасположения.ДляТекущегоПользователя Тогда КаталогКонфигурацииПриложения = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс() + "\conf"; Иначе КаталогКонфигурацииПриложения = КаталогПрограммы() + "conf"; Если ВариантРасположенияФайлаНастроек = ВариантыРасположения.ПеренаправлениеТекущейВерсии Тогда ФайлУказатель = Новый Файл(КаталогКонфигурацииПриложения + "\conf.cfg"); Если ФайлУказатель.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя); Текст = ТекстовыйДокумент.ПолучитьТекст(); НовыйКаталогКонфигурацииПриложения = СтрокаМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС); НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения); Если НовыйКаталог.Существует() Тогда КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если СоздатьЕслиОтсутствует Тогда Файл = Новый Файл(КаталогКонфигурацииПриложения); Если Не Файл.Существует() Тогда СоздатьКаталог(КаталогКонфигурацииПриложения); КонецЕсли; КонецЕсли; Результат = КаталогКонфигурацииПриложения; КонецЕсли; Возврат Результат; КонецФункции // выхВариантРасположенияФайлаНастроек - // ДляТекущейВерсии // ПеренаправлениеТекущейВерсии - использовать значение ключа ConfLocation из файла conf.cfg // ДляТекущегоПользователя Функция ПолноеИмяФайлаНастройкиПриложения1СЛкс(КраткоеИмяФайла, НаСервере = Ложь, выхВариантРасположенияФайлаНастроек = Неопределено, выхДатаИзменения = Неопределено) Экспорт Если НаСервере Тогда Результат = ирСервер.ПолучитьПолноеИмяФайлаНастройкиПриложения1СЛкс(КраткоеИмяФайла,, выхВариантРасположенияФайлаНастроек, выхДатаИзменения); Иначе ВариантыРасположения = ВариантыРасположенияКонфигурационногоФайлаЛкс(); выхВариантРасположенияФайлаНастроек = ВариантыРасположения.ДляТекущегоПользователя; КаталогКонфигурацииПриложения = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс() + "\conf"; Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла; Файл = Новый Файл(Результат); ФайлСуществует = Файл.Существует(); Если Не ФайлСуществует Тогда выхВариантРасположенияФайлаНастроек = ВариантыРасположения.ДляТекущейВерсии; КаталогКонфигурацииПриложения = КаталогПрограммы() + "conf"; Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла; Файл = Новый Файл(Результат); ФайлСуществует = Файл.Существует(); Если Не ФайлСуществует Тогда выхВариантРасположенияФайлаНастроек = ВариантыРасположения.ПеренаправлениеТекущейВерсии; ФайлУказатель = Новый Файл(КаталогКонфигурацииПриложения + "\conf.cfg"); Если ФайлУказатель.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя); Текст = ТекстовыйДокумент.ПолучитьТекст(); НовыйКаталогКонфигурацииПриложения = СтрокаМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС); НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения); Если НовыйКаталог.Существует() Тогда КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения; Результат = КаталогКонфигурацииПриложения + "\" + КраткоеИмяФайла; Файл = Новый Файл(Результат); ФайлСуществует = Файл.Существует(); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ФайлСуществует Тогда Результат = Неопределено; выхВариантРасположенияФайлаНастроек = Неопределено; Иначе выхДатаИзменения = Файл.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс(); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ТекстКонфигурационногоФайлаВнешнихСоединенийЛкс(АдресОтладчика = "") Экспорт ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(" | //| | |" ); Возврат ТекстовыйДокумент; КонецФункции Функция ИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере = Ложь) Экспорт Результат = ПолноеИмяФайлаНастройкиПриложения1СЛкс("logcfg.xml", НаСервере); Возврат Результат; КонецФункции Функция КаталогТехножурналаЛкс(НаСервере = Ложь) Экспорт ИмяФайлаНастроекЖурнала = ИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере); Если ЗначениеЗаполнено(ИмяФайлаНастроекЖурнала) Тогда ТекстХМЛ = ПрочитатьТекстИзФайлаЛкс(ИмяФайлаНастроекЖурнала, , НаСервере); ЧтениеХМЛ = Новый ЧтениеXML; ЧтениеХМЛ.УстановитьСтроку(ТекстХМЛ); ПостроительДом = Новый ПостроительDOM(); Попытка ДокументДОМ = ПостроительДом.Прочитать(ЧтениеХМЛ); Исключение СообщитьЛкс("Ошибка чтения настройки техножурнала: " + ОписаниеОшибки(), СтатусСообщения.Внимание); КонецПопытки; Если ДокументДОМ <> Неопределено Тогда Узлы = ДокументДом.ПолучитьЭлементыПоИмени("log"); Если Узлы.Количество() > 0 Тогда Атрибут = Узлы.Элемент(0).Атрибуты.ПолучитьИменованныйЭлемент("location"); Если Атрибут <> Неопределено Тогда Результат = Атрибут.ТекстовоеСодержимое; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиТехножурналВключенЛкс(НаСервере = Ложь, ВыводитьСообщения = Ложь, РазрешитьИспользоватьПутьСКлиентаНаСервер = Ложь) Экспорт КаталогЖурнала = ""; КаталогЖурналаВзятИзНастроекЧтения = Ложь; Если НаСервере И РазрешитьИспользоватьПутьСКлиентаНаСервер Тогда #Если Клиент Тогда КаталогЖурнала = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогЖурналаСервера"); КаталогЖурналаВзятИзНастроекЧтения = Истина; #КонецЕсли КонецЕсли; Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда КаталогЖурнала = КаталогТехножурналаЛкс(НаСервере); КаталогЖурналаВзятИзНастроекЧтения = Ложь; КонецЕсли; Если ЗначениеЗаполнено(КаталогЖурнала) Тогда Если Не ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере, ВыводитьСообщения) Тогда Возврат Истина; Иначе Если ВыводитьСообщения Тогда Если КаталогЖурналаВзятИзНастроекЧтения Тогда СообщитьЛкс("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в настройках чтения анализа техножурнала", СтатусСообщения.Внимание); Иначе СообщитьЛкс("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в текущей настройке техножурнала", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; КонецЕсли; Иначе Если ВыводитьСообщения Тогда Если НаСервере Тогда СообщитьЛкс("Каталог техножурнала сервера не удалось прочитать из текущей настройки техножурнала и не задан в настройках чтения инструмента ""Анализ техножурнала"""); Иначе СообщитьЛкс("Каталог техножурнала клиента не удалось прочитать из текущей настройки техножурнала"); КонецЕсли; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьСообщения = Истина) Экспорт Если НаСервере Тогда Результат = ирСервер.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала); Иначе Результат = Ложь; ФайлКаталог = Новый Файл(КаталогЖурнала); Если Не ФайлКаталог.Существует() Тогда Результат = Истина; Иначе БлокирующиеФайлы = НайтиФайлы(КаталогЖурнала, "*.*"); Счетчик = 0; Для Каждого БлокирующийФайл Из БлокирующиеФайлы Цикл Счетчик = Счетчик + 1; Если Счетчик > 100 Тогда // Ускорена проверка доступности каталога техножурнала при очень большом числе подкаталогов в нем http://www.hostedredmine.com/issues/850582 Прервать; КонецЕсли; Если Не БлокирующийФайл.ЭтоКаталог() Тогда Если ВыводитьСообщения Тогда ТекстСообщения = "В корне каталога """ + КаталогЖурнала + """ техножурнала "; Если НаСервере Тогда ТекстСообщения = ТекстСообщения + "сервера"; Иначе ТекстСообщения = ТекстСообщения + "клиента"; КонецЕсли; СообщитьЛкс(ТекстСообщения + " обнаружены блокирующие файлы. Для работы журнала их необходимо удалить.", СтатусСообщения.Внимание); КонецЕсли; Результат = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиКлиентЗапущенНаКомпьютереСервераЛкс() Экспорт Результат = НРег(ирСервер.ПолучитьИмяКомпьютераЛкс()) = НРег(ИмяКомпьютера()); Возврат Результат; КонецФункции Функция ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка = Неопределено, НаСервере = Ложь) Экспорт Если НаСервере Тогда ирСервер.ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка); Иначе ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(Текст); ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); ТекстовыйДокумент.Записать(ИмяВременногоФайла, Кодировка); мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли мПлатформа.ПереместитьФайлКакАдминистратор(ИмяВременногоФайла, ПолноеИмяФайла); КонецЕсли; КонецФункции Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено, НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка); Иначе ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ПолноеИмяФайла, Кодировка); Результат = ТекстовыйДокумент.ПолучитьТекст(); КонецЕсли; Возврат Результат; КонецФункции Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина, НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах); Иначе Файлы = НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах); Результат = Новый Массив; Для Каждого Файл Из Файлы Цикл Результат.Добавить(Файл.ПолноеИмя); КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ИзданиеПлатформы - Строка(0,П) // Функция КаталогПустойИнфобазыЛкс(Знач ИзданиеПлатформы = "") Экспорт Если Не ЗначениеЗаполнено(ИзданиеПлатформы) Тогда ИзданиеПлатформы = ирКэш.НомерИзданияПлатформыЛкс(); КонецЕсли; КаталогПустойИнфобазы = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(, ИзданиеПлатформы) + "\EmptyDB"; Возврат КаталогПустойИнфобазы; КонецФункции // Параметры: // СоздаватьБазуВСлучаеОтсутствия - Булево // Функция СтрокаСоединенияПустойИнфобазыЛкс(ИзданиеПлатформы = "", Знач СоздаватьБазуВСлучаеОтсутствия = Истина) Экспорт КаталогПустойИнфобазы = КаталогПустойИнфобазыЛкс(ИзданиеПлатформы); Если СоздаватьБазуВСлучаеОтсутствия Тогда ФайлПустойИнфобазы = Новый Файл(КаталогПустойИнфобазы + "\1CV8.1CD"); Если Не ФайлПустойИнфобазы.Существует() Тогда СтрокаПараметров = "CREATEINFOBASE File=" + КаталогПустойИнфобазы + ";"; //СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу"; ИмяФайлаЛога = ПолучитьИмяВременногоФайла(); СтрокаПараметров = СтрокаПараметров + " /out" + ИмяФайлаЛога; СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + СтрокаПараметров; ирКэш.Получить().ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска); //ВыполнитьСкрытуюКомандуОС КонецЕсли; КонецЕсли; СтрокаСоединения = "File=""" + КаталогПустойИнфобазы + """;"; Результат = СтрокаСоединения; Возврат Результат; КонецФункции Функция СоздатьФайловуюБазу1СЛкс(Знач КаталогИнфобазы = "", ИмяФайлаКонфигурации = "", УдалитьСуществующую = Ложь, Знач ПолноеИмяИсполняемогоФайла = "") Экспорт ФайлПустойИнфобазы = Новый Файл(КаталогИнфобазы + "\1CV8.1CD"); Если ФайлПустойИнфобазы.Существует() И УдалитьСуществующую Тогда УдалитьФайлы(КаталогИнфобазы); КонецЕсли; Если Не ФайлПустойИнфобазы.Существует() Тогда СтрокаПараметров = "CREATEINFOBASE File=""" + КаталогИнфобазы + """;"; // Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=1076785#1076785 СтрокаПараметров = СтрокаПараметров + "Q=Q"; Если ЗначениеЗаполнено(ИмяФайлаКонфигурации) Тогда СтрокаПараметров = СтрокаПараметров + " /UseTemplate """ + ИмяФайлаКонфигурации + """"; КонецЕсли; //СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу"; Если Не ЗначениеЗаполнено(ПолноеИмяИсполняемогоФайла) Тогда ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс(); КонецЕсли; ЗапуститьПриложение("""" + ПолноеИмяИсполняемогоФайла + """ " + СтрокаПараметров,, Истина); КонецЕсли; Возврат ""; КонецФункции Функция ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс() Экспорт ПолноеИмяИсполняемогоФайла = "" + КаталогПрограммы() + "1cv8.exe"; Возврат ПолноеИмяИсполняемогоФайла; КонецФункции Функция ПолучитьСтрокуСКавычкамиДляКоманднойСтрокиЛкс(Строка) Экспорт Результат = """" + СтрЗаменить(Строка, """", """""") + """"; Возврат Результат; КонецФункции // Параметры: // СтрокаСоединенияБазы - Строка - пустая строка трактуется как строка соединения пустой инфобазы Функция ВыполнитьКомандуКонфигуратораЛкс(Знач КомандаКонфигуратора, Знач СтрокаСоединенияБазы = "", выхТекстЛога = "", ПодавлятьДиалоги = Истина, Состояние = "", УдалитьСуществующуюПустуюИнфобазу = Ложь, Знач ПолноеИмяИсполняемогоФайла = "", ДождатьсяЗавершения = Истина, ИмяПользователя = "", ПарольПользователя = "", СообщитьСтрокуПараметров = Истина, КодЯзыка = "") Экспорт #Если Клиент Тогда Если ЗначениеЗаполнено(Состояние) Тогда СостояниеЛкс(Состояние); КонецЕсли; #КонецЕсли Если Не ЗначениеЗаполнено(СтрокаСоединенияБазы) Тогда КаталогПустойИнфобазы = КаталогПустойИнфобазыЛкс(); СоздатьФайловуюБазу1СЛкс(КаталогПустойИнфобазы,, УдалитьСуществующуюПустуюИнфобазу, ПолноеИмяИсполняемогоФайла); СтрокаСоединенияБазы = "File=""" + КаталогПустойИнфобазы + """;"; КонецЕсли; КодВозврата = Неопределено; ИмяФайлаЛога = ПолучитьИмяВременногоФайла("txt"); Если Не ЗначениеЗаполнено(ПолноеИмяИсполняемогоФайла) Тогда ПолноеИмяИсполняемогоФайла = ПолноеИмяИсполняемогоФайлаКонфигуратораЛкс(); КонецЕсли; ДополнительныеПараметры = "/Out""" + ИмяФайлаЛога + """ " + КомандаКонфигуратора; ПараметрыПакетногоЗапуска = ПараметрыЗапускаПриложения1СЛкс(ИмяПользователя, ПарольПользователя,, Истина,,,, ДополнительныеПараметры, СообщитьСтрокуПараметров, СтрокаСоединенияБазы,,,, ЗначениеЗаполнено(ИмяПользователя), КодЯзыка); Если ПодавлятьДиалоги Тогда ПараметрыПакетногоЗапуска = ПараметрыПакетногоЗапуска + " /DisableStartupDialogs /DisableStartupMessages"; КонецЕсли; #Если Клиент Тогда Если СтрокиРавныЛкс(СтрокаСоединенияБазы, СтрокаСоединенияИнформационнойБазы()) И Не ЗначениеЗаполнено(ИмяПользователя) Тогда Если ирКэш.НомерВерсииПлатформыЛкс() > 802014 Тогда Выполнить("ЗапуститьСистему(ПараметрыПакетногоЗапуска, ДождатьсяЗавершения, КодВозврата)"); Иначе ЗапуститьСистему(ПараметрыПакетногоЗапуска, ДождатьсяЗавершения); КодВозврата = 0; КонецЕсли; Иначе #КонецЕсли СтрокаКоманды = """" + ПолноеИмяИсполняемогоФайла + """ " + ПараметрыПакетногоЗапуска; Если ирКэш.НомерВерсииПлатформыЛкс() > 802014 Тогда Выполнить("ЗапуститьПриложение(СтрокаКоманды,, ДождатьсяЗавершения, КодВозврата)"); Иначе ЗапуститьПриложение(СтрокаКоманды,, ДождатьсяЗавершения); КодВозврата = 0; КонецЕсли; #Если Клиент Тогда КонецЕсли; #КонецЕсли ФайлЛога = Новый Файл(ИмяФайлаЛога); Если ФайлЛога.Существует() Тогда ТекстовыйДокументЛога = Новый ТекстовыйДокумент; ТекстовыйДокументЛога.Прочитать(ФайлЛога.ПолноеИмя); выхТекстЛога = ТекстовыйДокументЛога.ПолучитьТекст(); КонецЕсли; Возврат КодВозврата = 0; КонецФункции Процедура ЗаполнитьСписокАдминистраторовБазыЛкс(Знач СписокАдминистраторов) Экспорт #Если Сервер И Не Сервер Тогда СписокАдминистраторов = Новый СписокЗначений; #КонецЕсли СписокАдминистраторов.Очистить(); Для Каждого Пользователь Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл #Если Сервер И Не Сервер Тогда Пользователь = ПользователиИнформационнойБазы.СоздатьПользователя(); #КонецЕсли Если ПравоДоступа("Администрирование", Метаданные, Пользователь) Тогда СписокАдминистраторов.Добавить(Пользователь.Имя); КонецЕсли; КонецЦикла; СписокАдминистраторов.СортироватьПоПредставлению(); КонецПроцедуры // р5яф67оыйи Функция ПараметрыЗапускаСеансаДляПодключенияКТекущемуОтладчикуЛкс(Знач ИдентификаторПроцессаОС = Неопределено) Экспорт Если Не ЗначениеЗаполнено(ИдентификаторПроцессаОС) Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС(); КонецЕсли; ПараметрыЗапускаДляОтладки = ""; ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'"); КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine; ВычислительРегулярныхВыражений = Новый COMОбъект("VBScript.RegExp"); ВычислительРегулярныхВыражений.IgnoreCase = Истина; ВычислительРегулярныхВыражений.Global = Истина; ВычислительРегулярныхВыражений.Pattern = "(/DebuggerUrl\s*.+?)( /|$)"; Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса); Если Вхождения.Count > 0 Тогда ПараметрыЗапускаДляОтладки = Вхождения.Item(Вхождения.Count - 1).SubMatches(0); КонецЕсли; ВычислительРегулярныхВыражений.Pattern = "(/Debug\s+.+?)( /|$)"; Вхождения = ВычислительРегулярныхВыражений.Execute(КоманднаяСтрокаПроцесса); Если Вхождения.Count > 0 Тогда СтрокаОтладчика = Вхождения.Item(Вхождения.Count - 1).SubMatches(0); Иначе СтрокаОтладчика = "/Debug"; КонецЕсли; ПараметрыЗапускаДляОтладки = ПараметрыЗапускаДляОтладки + " " + СтрокаОтладчика; Возврат ПараметрыЗапускаДляОтладки; КонецФункции // Создает 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 = Видимость; Прервать; Исключение // Тонкий клиент еще не готов ОписаниеОшибки = ОписаниеОшибки(); КонецПопытки; ПаузаЛкс(1); КонецЦикла; СостояниеЛкс(""); Результат = Соединение; #КонецЕсли ИначеЕсли Найти(ТипCOMОбъекта, "ComConnector") > 0 Тогда Результат = РезультатСоединения; КонецЕсли; Возврат Результат; КонецФункции // Выпонляет ожидание появляения сеанса и только потом возвращает Функция ЗапуститьСеансПодПользователемЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта = "", РежимЗапуска = "Авто", КодРазрешения = "", СообщитьКоманднуюСтроку = Ложь, ОткрытьПортативныеИнструменты = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Истина, РазрешитьОтладку = Истина, ДополнительныеПараметры = "", РежимИнтерфейсаТакси = Ложь, Элевация = Ложь, РазделениеДанных = "", ОтключитьАутентификациюОС = Ложь, КодЯзыка = "") Экспорт Если ЗначениеЗаполнено(ТипCOMОбъекта) Тогда Соединение = СоздатьСеансИнфобазы1С8Лкс(, ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта, Истина,,,, КодРазрешения); Иначе #Если Клиент Тогда //Если ирКэш.НомерВерсииПлатформыЛкс() = 802015 Тогда // Предупреждение("В релиза 8.2.15 функция недоступна", 20); // Антибаг платформы 8.2.15 // Возврат; //КонецЕсли; Если РежимЗапуска = "Авто" Тогда // Антибаг платформы. При передачи этого режима в явном виде в некоторых случаях пароль в командной строке игнорируется ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяИнфобазы); Если ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий"; ИначеЕсли ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Тогда КонечныйРежимЗапуска = "ОбычноеПриложение"; Иначе //Авто Если Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий"; Иначе КонечныйРежимЗапуска = "ОбычноеПриложение"; КонецЕсли; КонецЕсли; Иначе КонечныйРежимЗапуска = РежимЗапуска; КонецЕсли; ПараметрыЗапуска = ПараметрыЗапускаПриложения1СЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, КодРазрешения, Ложь, КонечныйРежимЗапуска, РазрешитьОтладку, ОчисткаКэшаКлиентСерверныхВызовов, ДополнительныеПараметры, СообщитьКоманднуюСтроку, , ОткрытьПортативныеИнструменты, РежимИнтерфейсаТакси, РазделениеДанных, ОтключитьАутентификациюОС, КодЯзыка); ТекущаяДата = ирСервер.ПолучитьТекущуюДатуЛкс(); Если КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий" Тогда СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8c.exe"" " + ПараметрыЗапуска; ЗапуститьПриложение(СтрокаЗапуска); Иначе Если Элевация Тогда Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + ПараметрыЗапуска; Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска,,,, Ложь, Истина); Иначе ЗапуститьСистему(ПараметрыЗапуска); КонецЕсли; КонецЕсли; СостояниеЛкс("Ожидание запуска сеанса..."); Успех = Ложь; ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс(); Пока Не Успех Цикл ОбработкаПрерыванияПользователя(); Если ирСервер.ПолучитьТекущуюДатуЛкс() - ДатаПоследнегоВопроса >= 5 Тогда Ответ = Вопрос("Продолжить ожидание сеанса (5 сек)?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Нет Тогда Прервать; КонецЕсли; ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс(); КонецЕсли; Сеансы = ПолучитьСеансыИнформационнойБазы(); Успех = Ложь; Для Каждого Сеанс Из Сеансы Цикл Если Истина И Сеанс.НачалоСеанса >= ТекущаяДата И НРег(Сеанс.ИмяКомпьютера) = НРег(ИмяКомпьютера()) И Сеанс.Пользователь <> Неопределено И НРег(Сеанс.Пользователь.Имя) = НРег(ИмяПользователяИнфобазы) Тогда Успех = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЦикла; СостояниеЛкс(""); #Иначе ВызватьИсключение "Запуск приложения допускается только на клиенте"; #КонецЕсли КонецЕсли; Возврат Соединение; КонецФункции // Параметры: // XML - // Тип - // ИспользоватьXDTO - // СообщатьОбОшибках - // Функция ВосстановитьОбъектИзСтрокиXMLЛкс(Знач ФайлИлиXML = "", Знач Тип = "", Знач ИспользоватьXDTO = Истина, Знач СообщатьОбОшибках = Истина) Экспорт Если Ложь Или ТипЗнч(ФайлИлиXML) = Тип("Файл") Или ЗначениеЗаполнено(ФайлИлиXML) Тогда ЧтениеXML = Новый ЧтениеXML; Если ТипЗнч(ФайлИлиXML) = Тип("Файл") Тогда ЧтениеXML.ОткрытьФайл(ФайлИлиXML.ПолноеИмя); Иначе ЧтениеXML.УстановитьСтроку(ФайлИлиXML); КонецЕсли; Попытка Если ИспользоватьXDTO Тогда Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Иначе Результат = ПрочитатьXML(ЧтениеXML); КонецЕсли; Исключение Если СообщатьОбОшибках Тогда СообщитьЛкс(ОписаниеОшибки(), СтатусСообщения.Важное); КонецЕсли; ЧтениеXML.Закрыть(); КонецПопытки; // Антибаг платформы 8.2-8.3.6 СериализаторXDTO некорректно восстанавливает пустую табличную часть поверх непустой https://partners.v8.1c.ru/forum/t/1329468/m/1329468 Попытка Пустышка = Результат.Модифицированность(); МетаТЧи = Результат.Метаданные().ТабличныеЧасти; Исключение МетаТЧи = Новый Массив; КонецПопытки; Для Каждого МетаТЧ Из МетаТЧи Цикл ТЧ = Результат[МетаТЧ.Имя]; Если ТЧ.Количество() = 0 Тогда Попытка ТЧ.Вставить(0); Исключение // Недоступна по разделению группа/элемент с неадекватной ошибкой https://partners.v8.1c.ru/forum/t/1374212/m/1374212 Продолжить; КонецПопытки; ТЧ.Удалить(0); КонецЕсли; КонецЦикла; КонецЕсли; Если Результат = Неопределено Тогда Если ЗначениеЗаполнено(Тип) Тогда Результат = Новый (Тип); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ВосстановитьНастройкуКомпоновкиИзСтрокиXMLЛкс(Знач XML = "", Знач СообщатьОбОшибках = Истина) Экспорт Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(XML, Тип("НастройкиКомпоновкиДанных"), , СообщатьОбОшибках); Возврат Результат; КонецФункции // Параметры: // Объект - // ИспользоватьXDTO - // Функция СохранитьОбъектВВидеСтрокиXMLЛкс(Знач Объект, Знач ИспользоватьXDTO = Истина, ИмяФайла = "", ВызыватьИсключение = Истина, Поток = Неопределено, Знач Сериализатор = Неопределено) Экспорт Если Сериализатор = Неопределено Тогда Сериализатор = СериализаторXDTO; КонецЕсли; ЭтоВременныйПоток = Поток = Неопределено; Если ЭтоВременныйПоток Тогда Поток = Новый ЗаписьXML; Если ЗначениеЗаполнено(ИмяФайла) Тогда Попытка Поток.ОткрытьФайл(ИмяФайла); Исключение ВызватьИсключение ОписаниеОшибки(); // Чтобы в диалоге "Вычислить выражение" полное описание показывалось КонецПопытки; Иначе Поток.УстановитьСтроку(); КонецЕсли; КонецЕсли; Результат = Неопределено; ТипОбъекта = ТипЗнч(Объект); ЭтоИмитатор = ЭтоТипИмитатораОбъектаЛкс(ТипОбъекта); Если ЭтоИмитатор Тогда #Если Сервер И Не Сервер Тогда Объект = Обработки.ирИмитаторСсылочныйОбъект.Создать(); #КонецЕсли Результат = Объект.ДанныеВСтрокуXMLЧерезXDTO(ИспользоватьXDTO, ВызыватьИсключение, Сериализатор); Поток.ЗаписатьБезОбработки(Результат); // Криво Иначе Попытка Если ИспользоватьXDTO Тогда Если Истина И ТипЗнч(Объект) <> Тип("ОбъектXDTO") И ТипЗнч(Объект) <> Тип("ЗначениеXDTO") Тогда Сериализатор.ЗаписатьXML(Поток, Объект); Иначе ФабрикаXDTO.ЗаписатьXML(Поток, Объект); КонецЕсли; Иначе ЗаписатьXML(Поток, Объект); КонецЕсли; Исключение Если ЭтоВременныйПоток Тогда Поток.Закрыть(); КонецЕсли; Если ВызыватьИсключение Тогда ВызватьИсключение; КонецЕсли; Поток = Неопределено; КонецПопытки; Если Поток <> Неопределено Тогда Если ЭтоВременныйПоток Тогда Результат = Поток.Закрыть(); КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ВосстановитьОбъектИзСтрокиJsonЛкс(СтрокаJSON) Экспорт Результат = Неопределено; ЧтениеJSON = МойЧтениеJSON(); #Если Сервер И Не Сервер Тогда ЧтениеJSON = Новый ЧтениеJSON; #КонецЕсли ЧтениеJSON.УстановитьСтроку(СтрокаJSON); // Метод ПрочитатьJSON появился в 8.3 Выполнить("Результат = ПрочитатьJSON(ЧтениеJSON)"); Возврат Результат; КонецФункции Функция СохранитьОбъектВСтрокуJsonЛкс(Объект) Экспорт ЗаписьJSON = МойЗаписьJSON(); #Если Сервер И Не Сервер Тогда ЗаписьJSON = Новый ЗаписьJSON; #КонецЕсли ЗаписьJSON.УстановитьСтроку(); // Метод ЗаписатьJSON появился в 8.3 Выполнить("ЗаписатьJSON(ЗаписьJSON, Объект)"); Результат = ЗаписьJSON.Закрыть(); Возврат Результат; КонецФункции Функция ФорматироватьТекстJsonЛкс(СтрокаJSON) Экспорт Если Не ЗначениеЗаполнено(СтрокаJSON) Тогда Возврат СтрокаJSON; КонецЕсли; СтруктураИзСтроки = ВосстановитьОбъектИзСтрокиJsonЛкс(СтрокаJSON); Результат = СохранитьОбъектВСтрокуJsonЛкс(СтруктураИзСтроки); Возврат Результат; КонецФункции Функция ПроверитьЦиклическиеСсылкиВстроенногоЯзыкаЛкс(Значение, Описание = "<Значение>", ВыводитьСообщение = Ложь) Экспорт Если ирКэш.НомерВерсииПлатформыЛкс() < 803010 Тогда Если ВыводитьСообщение Тогда СообщитьЛкс("Проверка циклических ссылок доступна только на платформе 8.3.10 и выше"); КонецЕсли; Возврат Новый ТаблицаЗначений; КонецЕсли; Попытка Результат = Вычислить("ПроверитьЦиклическиеСсылкиВстроенногоЯзыка(Значение, Описание)"); Исключение Результат = Новый ТаблицаЗначений; ОписаниеОшибки = ОписаниеОшибки(); КонецПопытки; Возврат Результат; КонецФункции Функция ЗаписатьОбъектДляОтладкиЛкс(Объект, АдресРезультата = Неопределено) Экспорт Если ТранзакцияАктивна() Тогда ирСервер.СтрокаСоединенияСервераЛкс(); // Проверка на автоостановку фоновых заданий отладчиком http://www.hostedredmine.com/issues/851201 лАдресРезультата = ПоместитьВоВременноеХранилище(Null, Новый УникальныйИдентификатор); СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект); Параметры = Новый Массив(); Параметры.Добавить(СтрокаХМЛ); Параметры.Добавить(лАдресРезультата); ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗаписатьОбъектДляОтладкиЛкс", Параметры,, "Запись объекта для отладки (ИР)"); ФоновоеЗадание.ОжидатьЗавершения(10); Результат = ПолучитьИзВременногоХранилища(лАдресРезультата); Иначе Если ТипЗнч(Объект) = Тип("Строка") Тогда Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(Объект); КонецЕсли; Если ТипЗнч(Объект) = Тип("Структура") Тогда Результат = ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс(); ирОбщий.СохранитьЗначениеЛкс(Результат, Объект); Иначе Объект.Записать(); Результат = Объект.Ссылка; КонецЕсли; Если АдресРезультата <> Неопределено Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс() Экспорт Возврат "Объект для отладки"; КонецФункции // Параметры: // КоллекцияСтрок - Структура, ТаблицаЗначений, КоллекцияСтрокДереваЗначений, ТабличнаяЧасть, НаборЗаписей Функция АвтоУникальноеИмяВКоллекцииЛкс(КоллекцияСтрок, БазовоеИмяИлиСтрока, ИмяКлючевойКолонки = "Имя", ИмяДолжноБытьИдентификатором = Истина, ЗаменаПустойСтроки = "_", Знач ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке = 50, КлючеваяКолонкаВНижнемРегистре = Ложь) Экспорт ТекущийИндекс = 0; Если ТипЗнч(БазовоеИмяИлиСтрока) = Тип("Строка") Или БазовоеИмяИлиСтрока = Неопределено Тогда БазовоеИмя = БазовоеИмяИлиСтрока; Иначе ИсключаемаяСтрока = БазовоеИмяИлиСтрока; БазовоеИмя = БазовоеИмяИлиСтрока[ИмяКлючевойКолонки]; //ТекущийИндекс = 1; ПоследнийСимвол = Прав(БазовоеИмя, 1); Если ЭтоЦифраЛкс(ПоследнийСимвол) Тогда БазовоеИмя = СтрокаБезКонцаЛкс(БазовоеИмя, 1); ТекущийИндекс = Число(ПоследнийСимвол); КонецЕсли; КонецЕсли; Колонки = Неопределено; Если ТипЗнч(КоллекцияСтрок) = Тип("ТаблицаЗначений") Тогда Колонки = КоллекцияСтрок.Колонки; ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияСтрокДереваЗначений") Тогда Если КоллекцияСтрок.Количество() > 0 Тогда Колонки = КоллекцияСтрок[0].Владелец().Колонки; КонецЕсли; ИначеЕсли Метаданные.НайтиПоТипу(ТипЗнч(КоллекцияСтрок)) <> Неопределено Тогда Колонки = КоллекцияСтрок.ВыгрузитьКолонки().Колонки; ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("Структура") Тогда // ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("СписокЗначений") Тогда // ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокТаблицыЗначений") Тогда // ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокДереваЗначений") Тогда // ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда // Иначе ВызватьИсключение "Неподдерживаемый тип (" + ТипЗнч(КоллекцияСтрок) + ") параметра КоллекцияСтрок"; КонецЕсли; Если ИмяДолжноБытьИдентификатором Тогда ДопустимаяДлинаИдентификатора = 0; Если Колонки <> Неопределено Тогда ДопустимаяДлинаИдентификатора = Колонки[ИмяКлючевойКолонки].ТипЗначения.КвалификаторыСтроки.Длина; КонецЕсли; Если Не ЗначениеЗаполнено(ДопустимаяДлинаИдентификатора) Тогда ДопустимаяДлинаИдентификатора = ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли БазовоеИмя = мПлатформа.ИдентификаторИзПредставленияЛкс(БазовоеИмя, ЗаменаПустойСтроки); Если ДопустимаяДлинаИдентификатора > 0 Тогда БазовоеИмя = Лев(БазовоеИмя, ДопустимаяДлинаИдентификатора); КонецЕсли; Иначе Если ПустаяСтрока(БазовоеИмя) Тогда БазовоеИмя = ЗаменаПустойСтроки; КонецЕсли; КонецЕсли; Пока Истина Цикл ТекущийПсевдоним = БазовоеИмя + Формат(ТекущийИндекс, "ЧГ="); Если ТипЗнч(КоллекцияСтрок) = Тип("Структура") Тогда СтрокиОдноименных = Новый Массив; Если КоллекцияСтрок.Свойство(ТекущийПсевдоним) Тогда СтрокиОдноименных.Добавить(КоллекцияСтрок[ТекущийПсевдоним]); КонецЕсли; ИначеЕсли ТипЗнч(КоллекцияСтрок) = Тип("СписокЗначений") Тогда СтрокиОдноименных = Новый Массив; Для Каждого ЭлементСписка Из КоллекцияСтрок Цикл Если ЭлементСписка.Представление = ТекущийПсевдоним Тогда СтрокиОдноименных.Добавить(ЭлементСписка); КонецЕсли; КонецЦикла; ИначеЕсли Ложь Или ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокТаблицыЗначений") Или ТипЗнч(КоллекцияСтрок) = Тип("КоллекцияКолонокДереваЗначений") Или ТипЗнч(КоллекцияСтрок) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда СтрокиОдноименных = Новый Массив; Для Каждого Колонка Из КоллекцияСтрок Цикл Если Колонка.Имя = ТекущийПсевдоним Тогда СтрокиОдноименных.Добавить(Колонка); КонецЕсли; КонецЦикла; Иначе ПроверочныйПсевдоним = ТекущийПсевдоним; Если КлючеваяКолонкаВНижнемРегистре Тогда ПроверочныйПсевдоним = НРег(ПроверочныйПсевдоним); КонецЕсли; СтрокиОдноименных = КоллекцияСтрок.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ПроверочныйПсевдоним)); КонецЕсли; Если Ложь Или СтрокиОдноименных.Количество() = 0 Или (Истина И СтрокиОдноименных.Количество() = 1 И ИсключаемаяСтрока <> Неопределено И СтрокиРавныЛкс(ТекущийПсевдоним, ИсключаемаяСтрока[ИмяКлючевойКолонки]) ) Тогда Прервать; КонецЕсли; ТекущийИндекс = ТекущийИндекс + 1; КонецЦикла; Возврат ТекущийПсевдоним; КонецФункции Функция ЭтоЦифраЛкс(Символ) Экспорт КодСимвола = КодСимвола(Символ); Результат = КодСимвола >= 48 И КодСимвола <= 57; Возврат Результат; КонецФункции // Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке // // Параметры: // ЭлементОтбора - <тип> - // Сравнение - <тип>, "" - // Значение - <тип> - // ЗначениеПо - <тип> - // Использование - <тип>, Истина - // ПриводитьТипДляНеопределено - <тип>, Истина - // // Возвращаемое значение: // Функция УстановитьЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Сравнение = "", Знач Значение, Знач ЗначениеПо = Неопределено, Знач Использование = Истина, Знач ПриводитьТипДляНеопределено = Истина) Экспорт Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда Значение = Новый Массив(Значение); КонецЕсли; Если ТипЗнч(Значение) = Тип("Массив") Тогда СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(Значение); Значение = СписокЗначений; ИначеЕсли Истина И ПриводитьТипДляНеопределено И Значение = Неопределено Тогда Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(Значение); КонецЕсли; // Вид сравнения Если СтрокиРавныЛкс(Сравнение, "Авто") Тогда Сравнение = ОпределитьВидСравненияПоЗначениюЛкс(Значение); ИначеЕсли ТипЗнч(Сравнение) = Тип("ВидСравнения") Тогда ИначеЕсли Истина И Сравнение <> Неопределено И Сравнение <> "" Тогда // Добавлено 25.03.2012 ВызватьИсключение "Неверный тип сравнения """ + ТипЗнч(Сравнение) + """"; Иначе Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда Сравнение = ВидСравнения.ВСписке; Иначе Сравнение = ВидСравнения.Равно; КонецЕсли; КонецЕсли; // Еще надо сделать автоопределение Сожержит, как у компоновки ЭлементОтбора.ВидСравнения = Сравнение; Попытка Если ЗначениеПо <> Неопределено Тогда ЭлементОтбора.ЗначениеС = Значение; ЭлементОтбора.ЗначениеПО = ЗначениеПо; Иначе ЭлементОтбора.Значение = Значение; КонецЕсли; Исключение ВызватьИсключение "Ошибка установки значения типа """ + ТипЗнч(Значение) + """ элементу отбора """ + ЭлементОтбора.Имя + """: " + ОписаниеОшибки(); КонецПопытки; Попытка ЭлементОтбора.Использование = Использование; Исключение // Сюда попадаем для элемента отбора набора записей с регистратором КонецПопытки; КонецФункции // Установить отбор по структуре // // Параметры: // Отбор - <тип> - // СтруктураОтбора - <тип> - // Сравнение - <тип>, "Авто" - // ДобавлятьСсылкуВПутьКДанным - <тип>, Ложь - // СброситьПередУстановкой - <тип>, Истина - // // Возвращаемое значение: // Функция УстановитьОтборПоСтруктуреЛкс(Знач Отбор, Знач СтруктураОтбора, Знач Сравнение = "Авто", Знач ДобавлятьСсылкуВПутьКДанным = Ложь, Знач СброситьПередУстановкой = Истина) Экспорт Если СброситьПередУстановкой Тогда Отбор.Сбросить(); КонецЕсли; Для Каждого КлючИЗначение Из СтруктураОтбора Цикл ПутьКДанным = КлючИЗначение.Ключ; Если ДобавлятьСсылкуВПутьКДанным Тогда ПутьКДанным = "Ссылка." + ПутьКДанным; КонецЕсли; НайтиДобавитьЭлементОтбораЛкс(Отбор, ПутьКДанным, Сравнение, КлючИЗначение.Значение, , , КлючИЗначение.Ключ); КонецЦикла; КонецФункции Процедура УстановитьОтборПоПодстрокеЛкс(ЭлементОтбора, Подстрока) Экспорт #Если Сервер И Не Сервер Тогда ЭлементОтбора = Новый ПостроительЗапроса; ЭлементОтбора = ЭлементОтбора.Отбор.Добавить(); #КонецЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит; ЭлементОтбора.Значение = Подстрока; ЭлементОтбора.Использование = ЗначениеЗаполнено(Подстрока); КонецПроцедуры Процедура ЗаполнитьНаборЗаписейПоОтборуЛкс(НаборЗаписей) Экспорт #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей(); #КонецЕсли СтруктураЗначенийОтбора = Новый Структура; Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл Если ЭлементОтбора.Использование Тогда СтруктураЗначенийОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение); КонецЕсли; КонецЦикла; Для Каждого СтрокаНабора Из НаборЗаписей Цикл ЗаполнитьЗначенияСвойств(СтрокаНабора, СтруктураЗначенийОтбора); КонецЦикла; КонецПроцедуры // Параметры: // Объект - Ссылочный объект или запись регистра // Отбор - Отбор, ОтборКомпоновкиДанных // Функция УстановитьЗначенияРеквизитовПоОтборуЛкс(Объект, Отбор) Экспорт Если ТипЗнч(Отбор) = Тип("Отбор") Тогда #Если Сервер И Не Сервер Тогда Отбор = Новый ПостроительЗапроса; Отбор = Отбор.Отбор; #КонецЕсли Для Каждого ЭлементОтбора Из Отбор Цикл Если Ложь Или Не ЭлементОтбора.Использование Или ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно Тогда Продолжить; КонецЕсли; ИмяРеквизита = ЭлементОтбора.Имя; ЗначениеОтбора = ЭлементОтбора.Значение; Попытка Объект[ИмяРеквизита] = ЗначениеОтбора; Исключение // Сюда попадаем например для ЭтоГруппа КонецПопытки; КонецЦикла; Иначе #Если Сервер И Не Сервер Тогда Отбор = Новый НастройкиКомпоновкиДанных; Отбор = Отбор.Отбор; #КонецЕсли Для Каждого ЭлементОтбора Из Отбор.Элементы Цикл Если Ложь Или Не ЭлементОтбора.Использование Или ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Равно Тогда Продолжить; КонецЕсли; ИмяРеквизита = "" + ЭлементОтбора.ЛевоеЗначение; Если Найти(ИмяРеквизита, ".") > 0 Тогда Продолжить; КонецЕсли; ЗначениеОтбора = ЭлементОтбора.ПравоеЗначение; Попытка Объект[ИмяРеквизита] = ЗначениеОтбора; Исключение // Сюда попадаем например для ЭтоГруппа КонецПопытки; КонецЦикла; КонецЕсли; КонецФункции // Определить вид сравнения по значению // // Параметры: // Значение - <тип> - // РежимКомпоновки - <тип>, Ложь - // ДоступныеВидыСравнения - <тип>, Неопределено - // // Возвращаемое значение: // Функция ОпределитьВидСравненияПоЗначениюЛкс(Знач Значение, Знач РежимКомпоновки = Ложь, Знач ДоступныеВидыСравнения = Неопределено) Экспорт ТипЗначения = ТипЗнч(Значение); Если РежимКомпоновки Тогда КоллекцияВидовСравнения = ВидСравненияКомпоновкиДанных; Иначе КоллекцияВидовСравнения = ВидСравнения; КонецЕсли; Если ТипЗначения = Тип("СписокЗначений") Тогда Результат = КоллекцияВидовСравнения.ВСписке; ИначеЕсли Истина И ТипЗначения = Тип("Строка") И ДоступныеВидыСравнения <> Неопределено И ДоступныеВидыСравнения.НайтиПоЗначению(КоллекцияВидовСравнения.Содержит) <> Неопределено Тогда Результат = КоллекцияВидовСравнения.Содержит; Иначе Результат = КоллекцияВидовСравнения.Равно; ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения); Если ОбъектМД <> Неопределено Тогда ТипТаблицы = ТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя()); Если ТипТаблицы = "Справочник" Тогда Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда Если Значение.ЭтоГруппа Тогда Результат = КоллекцияВидовСравнения.ВИерархии; КонецЕсли; Иначе // иерархия элементов Результат = КоллекцияВидовСравнения.ВИерархии; КонецЕсли; ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда Если Значение.ЭтоГруппа Тогда Результат = КоллекцияВидовСравнения.ВИерархии; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке // // Параметры: // ОтборИлиОбъект - <тип> - // ПутьКДанным - <тип>, "" - // Сравнение - <тип>, "" - // Значение - <тип>, Неопределено - // ЗначениеПо - <тип>, Неопределено - // Использование - <тип>, Истина - // Имя - <тип>, "" - // Представление - <тип>, "" - // // Возвращаемое значение: // Функция НайтиДобавитьЭлементОтбораЛкс(Знач ОтборИлиОбъект, Знач ПутьКДанным = "", Знач Сравнение = "", Знач Значение = Неопределено, Знач ЗначениеПо = Неопределено, Знач Использование = Истина, Знач Имя = "", Знач Представление = "") Экспорт Если ТипЗнч(ОтборИлиОбъект) = Тип("Отбор") Тогда Отбор = ОтборИлиОбъект; Иначе Отбор = ОтборИлиОбъект.Отбор; КонецЕсли; // Ищем или добавляем новый элемент отбора ЭлементОтбора = Неопределено; //Если Имя <> Неопределено Тогда // ЭлементОтбора= Отбор.Найти(Имя); //КонецЕсли; Если Имя <> Неопределено Тогда Для Каждого ЭлОтбора Из Отбор Цикл Если Ложь Или ЭлОтбора.Имя = Имя Или ЭлОтбора.Представление = Имя Тогда ЭлементОтбора = ЭлОтбора; КонецЕсли; КонецЦикла; КонецЕсли; Если ЭлементОтбора = Неопределено Тогда Попытка ЭлементОтбора = Отбор.Добавить(ПутьКДанным, Имя, Представление); Исключение ВызватьИсключение "Ошибка добавления элемента отбора """ + ПутьКДанным + """ построителя запроса: " + ОписаниеОшибки(); КонецПопытки; КонецЕсли; УстановитьЭлементОтбораЛкс(ЭлементОтбора, Сравнение, Значение, ЗначениеПо, Использование); Результат = ЭлементОтбора; Возврат Результат; КонецФункции Процедура ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, Префикс = "Т") Экспорт #Если Сервер И Не Сервер Тогда Запрос = Новый Запрос; #КонецЕсли ТекстЗапроса = Запрос.Текст; Параметры = Новый Структура; СкопироватьУниверсальнуюКоллекциюЛкс(Запрос.Параметры, Параметры); Для Каждого КлючИЗначение Из Параметры Цикл Если Найти(КлючИЗначение.Ключ, Префикс) = 1 Тогда ВызватьИсключение "Начало имени параметра " + КлючИЗначение.Ключ + " совпадает с префиксом " + Префикс; КонецЕсли; НовоеИмя = Префикс + КлючИЗначение.Ключ; ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&" + КлючИЗначение.Ключ, "&" + НовоеИмя); Запрос.УстановитьПараметр(НовоеИмя, КлючИЗначение.Значение); КонецЦикла; Запрос.Текст = ТекстЗапроса; КонецПроцедуры // ТаблицаПараметров - ТаблицаЗначений, ТабличнаяЧасть Функция НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ЗначениеПараметра, ИмяПараметра = Неопределено, ОбновитьКопиюСвойстваВНижнемРегистре = Ложь) Экспорт Если ТипЗнч(ТаблицаПараметров) = Тип("ТаблицаЗначений") Тогда МакетТаблицы = ТаблицаПараметров; Иначе МакетТаблицы = ТаблицаПараметров.ВыгрузитьКолонки(); КонецЕсли; Строки = ТаблицаПараметров.НайтиСтроки(Новый Структура(ИмяКолонкиЗначения, ЗначениеПараметра)); Если Строки.Количество() > 0 Тогда Результат = Строки[0]; Иначе Если ТипЗнч(ЗначениеПараметра) = Тип("Строка") Тогда ИмяПараметра = АвтоУникальноеИмяВКоллекцииЛкс(ТаблицаПараметров, "П", ИмяКолонкиИмени); Иначе ИмяТипа = ИмяТипаИзПолногоИмениМДЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеПараметра))); //Префикс = НРег(Лев(ОбъектМД.Имя, 1)); Префикс = ""; Если ИмяПараметра = Неопределено Тогда ИмяПараметра = "" + РасширенноеПредставлениеЗначенияЛкс(ЗначениеПараметра); КонецЕсли; Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда ИмяПараметра = СтрЗаменить(ИмяТипа, ".", "") + "Пустая"; КонецЕсли; ИмяПараметра = Префикс + ирКэш.Получить().ИдентификаторИзПредставленияЛкс(ИмяПараметра); ДопустимаяДлинаСтроки = МакетТаблицы.Колонки[ИмяКолонкиИмени].ТипЗначения.КвалификаторыСтроки.Длина; Если ДопустимаяДлинаСтроки > 0 Тогда ИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки); КонецЕсли; КонецЕсли; СтруктураСвойствПараметра = Новый Структура; СтруктураСвойствПараметра.Вставить(ИмяКолонкиИмени, ИмяПараметра); Счетчик = 0; Пока ТаблицаПараметров.НайтиСтроки(СтруктураСвойствПараметра).Количество() > 0 Цикл Счетчик = Счетчик + 1; СтрокаНомера = "" + Счетчик; Если ДопустимаяДлинаСтроки > 0 Тогда лИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки - СтрДлина(СтрокаНомера)); Иначе лИмяПараметра = ИмяПараметра; КонецЕсли; СтруктураСвойствПараметра[ИмяКолонкиИмени] = лИмяПараметра + СтрокаНомера; КонецЦикла; СтруктураСвойствПараметра.Вставить("ЭтоВыражение", Ложь); СтруктураСвойствПараметра.Вставить(ИмяКолонкиЗначения, ЗначениеПараметра); СтрокаНовогоПараметра = ТаблицаПараметров.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаНовогоПараметра, СтруктураСвойствПараметра); Если ОбновитьКопиюСвойстваВНижнемРегистре Тогда ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаНовогоПараметра, ИмяКолонкиИмени); КонецЕсли; Результат = СтрокаНовогоПараметра; КонецЕсли; Возврат Результат; КонецФункции // ДобавитьПараметрЗначение() Функция _ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицыИлиНаборЗаписей, Знач КлючНабора, ДобавитьИЗаполнитьСтрокуНабора = Ложь) Экспорт Если ТипЗнч(ПолноеИмяТаблицыИлиНаборЗаписей) = Тип("Строка") Тогда СтруктураНабораЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыИлиНаборЗаписей); НаборЗаписей = СтруктураНабораЗаписей.Методы; Иначе НаборЗаписей = ПолноеИмяТаблицыИлиНаборЗаписей; КонецЕсли; #Если Сервер И Не Сервер Тогда НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей(); #КонецЕсли //СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ИмяТаблицыИзМетаданныхЛкс(НаборЗаписей.Метаданные()), Ложь); //Для Каждого ПолеКлюча Из СтруктураКлюча Цикл // ИмяПоля = ПолеКлюча.Ключ; // Попытка // ЗначениеКлюча = КлючНабора[ИмяПоля]; // Исключение // // Имеет смысл для регистров сведений // Продолжить; // КонецПопытки; // ЭлементОтбора = НаборЗаписей.Отбор[ИмяПоля]; // ЭлементОтбора.Значение = ЗначениеКлюча; // ЭлементОтбора.Использование = Истина; //КонецЦикла; Если ЛиКлючЗаписиРегистраЛкс(КлючНабора) Тогда // Возможно эта строка лишена смысла КлючНабора = СтруктураИзКлючаЗаписиЛкс(КлючНабора, ПолноеИмяТаблицыИлиНаборЗаписей); КонецЕсли; Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл ИмяПоля = ЭлементОтбора.Имя; Попытка ЗначениеКлюча = КлючНабора[ИмяПоля]; Исключение // Имеет смысл для регистров сведений Продолжить; КонецПопытки; ЭлементОтбора.Значение = ЗначениеКлюча; ЭлементОтбора.Использование = Истина; КонецЦикла; Если ДобавитьИЗаполнитьСтрокуНабора Тогда ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючНабора); КонецЕсли; Возврат НаборЗаписей; КонецФункции // Получает копию таблицы значений с минимальными типами колонок для содержания всех данных. // Параметры: // ТаблицаДанных - ТаблицаЗначений // СужатьТолькоПроизвольныеКолонки - Булево - обрабатывать только колонки с пустым (произвольным) типом // ИмяКолонки - Строка - нужна только эта колонка // Функция ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Знач ТаблицаДанных, СужатьТолькоПроизвольныеКолонки = Ложь, ИмяКолонки = "") Экспорт #Если Сервер И Не Сервер Тогда ТаблицаДанных = Новый ТаблицаЗначений; #КонецЕсли ОставляемыеКолонки = ""; СужаемыеКолонки = Новый Массив(); Для Каждого КолонкаДанных Из ТаблицаДанных.Колонки Цикл Если ЗначениеЗаполнено(ИмяКолонки) И Не СтрокиРавныЛкс(ИмяКолонки, КолонкаДанных.Имя) Тогда Продолжить; КонецЕсли; Если Истина И СужатьТолькоПроизвольныеКолонки И КолонкаДанных.ТипЗначения.Типы().Количество() > 0 Тогда ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя; Иначе СужаемыеКолонки.Добавить(КолонкаДанных); КонецЕсли; КонецЦикла; //СостояниеЛкс("Оптимизация типов колонок"); НовыеКолонки = Новый Структура; МетаданныеТаблицыИзменены = Ложь; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СужаемыеКолонки.Количество(), "Анализ колонок"); Для Каждого КолонкаДанных Из СужаемыеКолонки Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); Типы = Новый Массив; ТаблицаКолонки = ТаблицаДанных.Скопировать(, КолонкаДанных.Имя); ТаблицаКолонки.Свернуть(КолонкаДанных.Имя); СтароеОписаниеТипов = КолонкаДанных.ТипЗначения; Для Каждого СтрокаДанных Из ТаблицаКолонки Цикл ТипЗначения = ТипЗнч(СтрокаДанных[КолонкаДанных.Имя]); Если Истина И ТипЗначения <> Тип("Неопределено") И Типы.Найти(ТипЗначения) = Неопределено Тогда Типы.Добавить(ТипЗначения); КонецЕсли; КонецЦикла; Если Типы.Количество() = 0 Тогда Типы = КолонкаДанных.ТипЗначения.Типы(); Если Типы.Количество() = 0 Тогда Типы.ДОбавить(Тип("Булево")); Типы.ДОбавить(Тип("Число")); КонецЕсли; // Чтобы от супертипов через точку не было много соединений, оставляем только 2 типа Пока Типы.Количество() > 2 Цикл Типы.Удалить(0); КонецЦикла; КонецЕсли; Если Типы.Количество() <> СтароеОписаниеТипов.Типы().Количество() Тогда МетаданныеТаблицыИзменены = Истина; КонецЕсли; НовоеОписаниеТипов = Новый ОписаниеТипов(Типы, , , СтароеОписаниеТипов.КвалификаторыЧисла, СтароеОписаниеТипов.КвалификаторыСтроки, СтароеОписаниеТипов.КвалификаторыДаты); НовыеКолонки.Вставить(КолонкаДанных.Имя, НовоеОписаниеТипов); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если МетаданныеТаблицыИзменены Тогда Если ОставляемыеКолонки <> "" Тогда ТипизированнаяТаблица = ТаблицаДанных.Скопировать(, ОставляемыеКолонки); Иначе ТипизированнаяТаблица = Новый ТаблицаЗначений; КонецЕсли; Для Каждого КлючИЗначение Из НовыеКолонки Цикл ОригинальнаяКолонка = ТаблицаДанных.Колонки[КлючИЗначение.Ключ]; ТипизированнаяТаблица.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение, ОригинальнаяКолонка.Заголовок, ОригинальнаяКолонка.Ширина); КонецЦикла; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаДанных.Количество() / 100, "Оптимизация таблицы"); // TODO оптимизировать через ИзменитьТипКолонкиТаблицыЗначенийЛкс Для Индекс = 0 По ТаблицаДанных.Количество() - 1 Цикл Если Индекс % 100 = 0 Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонецЕсли; Если ОставляемыеКолонки <> "" Тогда СтрокаТипизированнойТаблицы = ТипизированнаяТаблица[Индекс]; Иначе СтрокаТипизированнойТаблицы = ТипизированнаяТаблица.Добавить(); КонецЕсли; ЗаполнитьЗначенияСвойств(СтрокаТипизированнойТаблицы, ТаблицаДанных[Индекс]); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Иначе ТипизированнаяТаблица = ТаблицаДанных; КонецЕсли; Результат = ТипизированнаяТаблица; Возврат Результат; КонецФункции Процедура ИзменитьТипКолонкиТаблицыЗначенийЛкс(ТаблицаЗначений, ИмяКолонки, НовыйТипКолонки) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ИмяВременнойКолонки = ИмяКолонки + "_Вр31415926"; МассивДанныхКолонки = ТаблицаЗначений.ВыгрузитьКолонку(ИмяКолонки); ТаблицаЗначений.Колонки.Добавить(ИмяВременнойКолонки, НовыйТипКолонки); ТаблицаЗначений.ЗагрузитьКолонку(МассивДанныхКолонки, ИмяВременнойКолонки); ТаблицаЗначений.Колонки.Удалить(ИмяКолонки); ТаблицаЗначений.Колонки[ИмяВременнойКолонки].Имя = ИмяКолонки; КонецПроцедуры // ************************ // WMI Функция ПолучитьСтруктуруИзЗначенияWMIЛкс(ЗначениеWMI) Экспорт Результат = Новый Структура; Для каждого СвойствоWMI из ЗначениеWMI Цикл Если ТипЗнч(СвойствоWMI.Value) = Тип("COMSafeArray") Тогда ЗначениеСвойства = СвойствоWMI.Value.Выгрузить();// возможно массив надо будет переделать Иначе ЗначениеСвойства = СвойствоWMI.Value; //ИмяТипа = ПолучитьИмяТипаИзКвалификаторовWMIЛкс(СвойствоWMI); //Если СтрокиРавныЛкс(ИмяТипа, "Дата") Тогда Если СвойствоWMI.CIMTYPE = 101 Тогда //datetime ЗначениеСвойства = СтрокаДатыWMIВДатуЛкс(ЗначениеСвойства); КонецЕсли; КонецЕсли; Результат.Вставить(СвойствоWMI.Name, ЗначениеСвойства); КонецЦикла; Возврат Результат; КонецФункции Функция ПолучитьИмяТипаИзКвалификаторовWMIЛкс(Свойство) Экспорт ИмяТипа = ""; Попытка Квалификаторы = Свойство.Qualifiers_; Исключение // Нет у системных свойств Квалификаторы = Новый Массив(); КонецПопытки; Для Каждого Квалификатор Из Квалификаторы Цикл Если СтрокиРавныЛкс("CIMTYPE", Квалификатор.Name) Тогда ИмяТипа = Нрег(Квалификатор.Value); Прервать; КонецЕсли; КонецЦикла; Если Ложь Или Найти(ИмяТипа, "int") > 0 Тогда ИмяТипа = "Число"; ИначеЕсли Ложь Или Найти(ИмяТипа, "date") > 0 Или Найти(ИмяТипа, "time") > 0 Тогда ИмяТипа = "Дата"; ИначеЕсли Ложь Или Найти(ИмяТипа, "string") > 0 Или Найти(ИмяТипа, "char") > 0 Тогда ИмяТипа = "Строка"; ИначеЕсли ТипЗнч(ИмяТипа) = Тип("COMОбъект") Тогда ИмяТипа = "COMОбъект.{WbemScripting.SwbemLocator}." + ИмяТипа; КонецЕсли; Возврат ИмяТипа; КонецФункции Функция ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции, ИмяСвойства = "Description") Экспорт ОписаниеЭлемента = ""; Квалификаторы = ЭлементКоллекции.qualifiers_; Попытка КвалификаторОписание = Квалификаторы.item(ИмяСвойства); Исключение КвалификаторОписание = Неопределено; КонецПопытки; Если КвалификаторОписание <> Неопределено Тогда ОписаниеЭлемента = КвалификаторОписание.Value; КонецЕсли; Возврат ОписаниеЭлемента; КонецФункции Функция ПолучитьДокументациюСвойстваWMIЛкс(ИмяКласса, ИмяСвойства, СлужбаWMI = Неопределено) Экспорт Если СлужбаWMI = Неопределено Тогда СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(); КонецЕсли; wbemFlagUseAmendedQualifiers = 131072; //&H20000 ОписанияСвойств = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Properties_; Попытка ОписаниеСвойства = ОписанияСвойств.item(ИмяСвойства); Исключение Возврат ""; КонецПопытки; ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства); ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "CIMTYPE"); Если ТипЗначений <> Неопределено Тогда ТекстОписания = ТекстОписания + " |Type: " + ТипЗначений; КонецЕсли; ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "Units"); Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда ТекстОписания = ТекстОписания + " |Unit: " + ЕдиницаИзмерения; КонецЕсли; Возврат ТекстОписания; КонецФункции Функция ПолучитьДокументациюМетодаWMIЛкс(ИмяКласса, ИмяМетода, СлужбаWMI = Неопределено) Экспорт Если СлужбаWMI = Неопределено Тогда СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс(); КонецЕсли; wbemFlagUseAmendedQualifiers = 131072; //&H20000 ОписанияМетодов = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Methods_; Попытка ОписаниеМетода = ОписанияМетодов.item(ИмяМетода); Исключение Возврат ""; КонецПопытки; ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода); ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "CIMTYPE"); Если ТипЗначений <> Неопределено Тогда ТекстОписания = ТекстОписания + " |Type: " + ТипЗначений; КонецЕсли; ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "Units"); Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда ТекстОписания = ТекстОписания + " |Unit: " + ЕдиницаИзмерения; КонецЕсли; Возврат ТекстОписания; КонецФункции // Параметры: // СтрокаДаты - Строка(0,П) // Функция СтрокаДатыWMIВДатуЛкс(Знач СтрокаДаты = "") Экспорт Если Не ЗначениеЗаполнено(СтрокаДаты) Тогда Возврат Дата(1,1,1); Иначе Строка = Лев(СтрокаДаты, 4) + Сред(СтрокаДаты, 5, 2) + Сред(СтрокаДаты, 7, 2) + Сред (СтрокаДаты, 9, 2) + Сред(СтрокаДаты, 11, 2) + Сред(СтрокаДаты, 13, 2); Попытка Результат = Дата(Строка); Исключение СообщитьЛкс("Ошибка преобразования даты WMI из строки """ + СтрокаДаты + """: " + ОписаниеОшибки()); Возврат Дата(1,1,1); КонецПопытки; Результат = Результат + Вычислить("0." + Сред(СтрокаДаты, 16, 6)); КонецЕсли; Возврат Результат; КонецФункции // WMI // ************************* // ************************ // ADO Функция ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С = Неопределено) Экспорт Если РезультатТаблица = Неопределено Тогда РезультатТаблица = Новый ТаблицаЗначений; КонецЕсли; мПлатформа = ирКэш.Получить(); FieldКолонка = Новый Соответствие; Для каждого Field Из РезультатRecordset.Fields Цикл Если ПустаяСтрока(Field.Name) Тогда ИмяКолонки = ":?"; Для о=1 По СтрДлина(Field.Name)-1 Цикл ИмяКолонки = ИмяКолонки + "?"; КонецЦикла; Иначе ИмяКолонки = Field.Name; КонецЕсли; Если Не ЛиИмяПеременнойЛкс(ИмяКолонки) Тогда ИмяКолонки = мПлатформа.ИдентификаторИзПредставленияЛкс(ИмяКолонки); КонецЕсли; // контроль полей - двойников по именам НомерДвойника=0; Пока РезультатТаблица.Колонки.Найти(ИмяКолонки + Формат(НомерДвойника,"ЧГ=0")) <> Неопределено Цикл НомерДвойника = НомерДвойника + 1; КонецЦикла; ИмяКолонки = ИмяКолонки + Формат(НомерДвойника, "ЧГ=0"); Если Типизировать1С = Истина Тогда Тип1С = FieldADO_ПолучитьТип1CЛкс(Field); Иначе Тип1С = Неопределено; КонецЕсли; //Если Тип1С=Неопределено Тогда // Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,,"["+Name+"]"); //Иначе Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,Тип1С); //КонецЕсли; FieldКолонка.Вставить(Field, Колонка); КонецЦикла; Возврат FieldКолонка; КонецФункции // Выгружает результат запроса ADO (объект 'ADODB.Recordset') в таблицу значений с выводом прогресса состояния выгрузки Функция ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С = Ложь, БинарныеВСтроку = Ложь, RecordsAffected = 0, ИгнорироватьНеподдерживаемыеТипы = Ложь, ЗагружатьЭлементов = Неопределено, СмещениеГода = 0) Экспорт РезультатТаблица = Новый ТаблицаЗначений; Если РезультатRecordset = Неопределено Тогда Возврат РезультатТаблица; КонецЕсли; Если ЗначениеЗаполнено(ЗагружатьЭлементов) Тогда КоличествоЭлементов = Мин(ЗагружатьЭлементов, РезультатRecordset.RecordCount); Иначе КоличествоЭлементов = РезультатRecordset.RecordCount; КонецЕсли; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Загрузка результата"); Если РезультатRecordset.State = 0 Тогда // Выполнена команда РезультатТаблица.Колонки.Добавить("ExecutionInfo",, "Информация о выполнении:"); Стр = РезультатТаблица.Добавить(); Стр.ExecutionInfo = "Число записей, обработанных запросом: " + RecordsAffected; Иначе FieldКолонка = ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С); // Открыта выборка ТипCOMSafeArray = Тип("COMSafeArray"); adBinaryType = ирОбщий.intTypeADOЛкс("adBinary"); adVarBinaryType = ирОбщий.intTypeADOЛкс("adVarBinary"); adLongVarBinaryType = ирОбщий.intTypeADOЛкс("adLongVarBinary"); ПервыйРаз = Истина; Счетчик = 0; Если РезультатRecordset.EOF() = 0 И РезультатRecordset.BOF() = 0 Тогда РезультатRecordset.MoveFirst(); КонецЕсли; Пока РезультатRecordset.EOF() = 0 Цикл Если Индикатор.Счетчик = КоличествоЭлементов Тогда Прервать; КонецЕсли; ирОбщий.ОбработатьИндикаторЛкс(Индикатор); Счетчик = Счетчик + 1; СтрНов = РезультатТаблица.Добавить(); Для каждого Field Из РезультатRecordset.Fields Цикл Попытка ЗначениеПоля = Field.Value; Исключение Если Не ИгнорироватьНеподдерживаемыеТипы Тогда ВызватьИсключение "ADO. Невозможно прочитать значение типа " + XMLСтрока(Field.Type) + " из колонки результата """ + Field.Name + """"; КонецЕсли; ЗначениеПоля = Неопределено; КонецПопытки; Индекс = РезультатТаблица.Колонки.Индекс(FieldКолонка.Получить(Field)); Если Истина И ТипЗнч(ЗначениеПоля) = ТипCOMSafeArray И БинарныеВСтроку = Истина И (Ложь Или Field.Type = adBinaryType Или Field.Type = adVarBinaryType //ИЛИ (Field.Type=adLongVarBinaryType) ) Тогда // преобразование COMSafeArray в строку HEX СтрНов[Индекс] = BinaryCOMSafeArrayToHEXЛкс(ЗначениеПоля); ИначеЕсли СмещениеГода <> 0 И ТипЗнч(ЗначениеПоля) = Тип("Дата") Тогда СтрНов[Индекс] = ДобавитьМесяц(ЗначениеПоля, - СмещениеГода * 12); Иначе // преобразование типа неявное СтрНов[Индекс] = ЗначениеПоля; КонецЕсли; КонецЦикла; РезультатRecordset.MoveNext(); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; Возврат РезультатТаблица; КонецФункции Функция РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(РезультатRecordset, Типизировать1С = Истина, БинарныеВСтроку = Ложь, ЗагружатьЭлементов = 0, СмещениеГода = 2000, ИспользованиеGWF = Истина, Знач ADOUtils = Неопределено, МодальныйРежим = Ложь) Экспорт ТаблицаИзADO = Неопределено; Если ИспользованиеGWF Тогда Если ADOUtils = Неопределено Тогда мПлатформа = ирКэш.Получить(); ADOUtils = мПлатформа.ПолучитьADOUtils(, СмещениеГода, Истина); КонецЕсли; Если ADOUtils <> Неопределено Тогда ТаблицаИзADO = ADOUtils.ADORecordsetToValueTable(РезультатRecordset); Иначе //ОписаниеОшибки = "Не удалось подключить ВК GameWithFire.dll! Выгрузка из ADO будет выполняться программой на встроенном языке."; //СообщитьСУчетомМодальностиЛкс(ОписаниеОшибки, МодальныйРежим, СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; Если ТаблицаИзADO = Неопределено Тогда ТаблицаИзADO = ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С, БинарныеВСтроку,,, ЗагружатьЭлементов, СмещениеГода); КонецЕсли; Возврат ТаблицаИзADO; КонецФункции // *** УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO *** // подбирает описание типа 1С, соответствующее типу ADO Функция ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision0,NumericScale0, Справочно = Ложь) Экспорт Тип1С = Неопределено; Если Precision0 > 0 И NumericScale0 >= 0 Тогда Если Precision0 < NumericScale0 Тогда // кривой вариант настроек типа ADO (может иногда возвращаться провайдерами данных) Precision = Precision0 + NumericScale0; Иначе Precision = Precision0; КонецЕсли; UseМаксЧисло = (Precision > 32); Иначе // совсем кривой вариант UseМаксЧисло = Истина; КонецЕсли; NumericScale = ?(NumericScale0 < 0, 0, NumericScale0); NumericScaleM = ?(NumericScale > 10, 10, NumericScale); Если Type = intTypeADOЛкс("adEmpty") Тогда ИначеЕсли Type = intTypeADOЛкс("adSmallInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adInteger") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adSingle") Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adDouble") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision+NumericScale, NumericScale, ДопустимыйЗнак.Любой)); Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adCurrency")Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adDate") Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата)); ИначеЕсли Type = intTypeADOЛкс("adBSTR") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adIDispatch")Тогда ИначеЕсли Type = intTypeADOЛкс("adError") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adBoolean") Тогда Тип1С = Новый ОписаниеТипов("Булево"); ИначеЕсли Type = intTypeADOЛкс("adVariant") Тогда ИначеЕсли Type = intTypeADOЛкс("adIUnknown")Тогда ИначеЕсли Type = intTypeADOЛкс("adDecimal") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adTinyInt") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedTinyInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedSmallInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adBigInt") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Любой)); ИначеЕсли Type = intTypeADOЛкс("adUnsignedBigInt")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adFileTime")Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adGUID") Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("УникальныйИдентификатор"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adBinary") Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("Двоичныеданные"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adChar") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adWChar") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adNumeric") Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adUserDefined")Тогда ИначеЕсли Type = intTypeADOЛкс("adDBDate") Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата)); ИначеЕсли Type = intTypeADOЛкс("adDBTime") Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Время)); ИначеЕсли Type = intTypeADOЛкс("adDBTimeStamp")Тогда Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)); ИначеЕсли Type = intTypeADOЛкс("adChapter") Тогда Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный)); ИначеЕсли Type = intTypeADOЛкс("adPropVariant")Тогда ИначеЕсли Type = intTypeADOЛкс("adVarNumeric")Тогда Если UseМаксЧисло Тогда // взвешанно-максимальный числовой тип Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой)); Иначе Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой)); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adVarChar") Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adLongVarChar")Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adVarWChar")Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adLongVarWChar")Тогда Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная)); ИначеЕсли Type = intTypeADOЛкс("adVarBinary")Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("Двоичныеданные"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("adLongVarBinary")Тогда Если Справочно Тогда Тип1С = Новый ОписаниеТипов("Двоичныеданные"); КонецЕсли; ИначеЕсли Type = intTypeADOЛкс("AdArray") Тогда Иначе // Тип1С = Неопределено; КонецЕсли; Возврат Тип1С; КонецФункции // ПреобразоватьТипADO_Тип1СЛкс() // возвращает описание типа 1С, соответствующее типу объекта ADODB.Field // значение Неопределено соответствует значению произвольного типа 1С Функция FieldADO_ПолучитьТип1CЛкс(FieldADOЛкс, Справочно = Ложь) Экспорт Попытка Type = FieldADOЛкс.Type; DefinedSize = FieldADOЛкс.DefinedSize; Precision = FieldADOЛкс.Precision; NumericScale = FieldADOЛкс.NumericScale; Исключение Возврат Неопределено; КонецПопытки; Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,DefinedSize,Precision,NumericScale, Справочно); КонецФункции // возвращает описание типа 1С, соответствующее типу объекта ADODB.Parameter // значение Неопределено соответствует значению произвольного типа 1С Функция ParameterADO_ПолучитьТип1CЛкс(ParameterADOЛкс) Экспорт Попытка Type = ParameterADOЛкс.Type; Size = ParameterADOЛкс.Size; Precision = ParameterADOЛкс.Precision; NumericScale = ParameterADOЛкс.NumericScale; Исключение Возврат Неопределено; КонецПопытки; Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision,NumericScale); КонецФункции // возвращает структуру с полями объекта ADODB.Field Функция FieldADOЛкс(стрName,стрType,чисDefinedSize,чисPrecision,чисNumericScale,Value=Неопределено) Экспорт ПолеADO = Новый Структура("Name,Type,DefinedSize,Precision,NumericScale,Value"); ТипЧисло = Тип("Число"); Если стрName <> Неопределено Тогда ПолеADO.Вставить("Name",СокрЛП(стрName)); КонецЕсли; Если стрType <> Неопределено Тогда Если ТипЗнч(стрType) = ТипЧисло Тогда // дополнительный контроль числа на допустимое значение ПолеADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType))); Иначе ПолеADO.Вставить("Type",intTypeADOЛкс(стрType)); КонецЕсли; КонецЕсли; Если чисDefinedSize <> Неопределено Тогда Если ТипЗнч(чисDefinedSize)=ТипЧисло Тогда ПолеADO.Вставить("DefinedSize",Цел(чисDefinedSize)); Иначе ПолеADO.Вставить("DefinedSize",0); КонецЕсли; КонецЕсли; Если чисPrecision <> Неопределено Тогда Если ТипЗнч(чисPrecision)=ТипЧисло Тогда ПолеADO.Вставить("Precision",Цел(чисPrecision)); Иначе ПолеADO.Вставить("Precision",0); КонецЕсли; КонецЕсли; Если чисNumericScale <> Неопределено Тогда Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда ПолеADO.Вставить("NumericScale",Цел(чисNumericScale)); Иначе ПолеADO.Вставить("NumericScale",0); КонецЕсли; КонецЕсли; Если Value <> Неопределено Тогда ПолеADO.Вставить("Value",Value); КонецЕсли; Возврат ПолеADO; КонецФункции // возвращает структуру с полями объекта ADODB.Parameter Функция ParameterADOЛкс(стрName,стрDirection,стрType,чисSize,чисNumericScale,чисPrecision,чисAttributes=0,Value=Неопределено) Экспорт ПараметрADO = Новый Структура("Name,Direction,Type,Size,NumericScale,Precision,Attributes,Value"); ТипЧисло = Тип("Число"); Если стрName <> Неопределено Тогда ПараметрADO.Вставить("Name",СокрЛП(стрName)); КонецЕсли; Если чисAttributes <> Неопределено Тогда Если ТипЗнч(чисAttributes)=ТипЧисло И чисAttributes > 0 Тогда ПараметрADO.Вставить("Attributes",Цел(чисAttributes)); КонецЕсли; КонецЕсли; Если стрDirection <> Неопределено Тогда Если ТипЗнч(стрDirection) = ТипЧисло Тогда // дополнительный контроль числа на допустимое значение ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(strDirectionParADOЛкс(стрDirection))); Иначе ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(стрDirection)); КонецЕсли; КонецЕсли; Если стрType <> Неопределено Тогда Если ТипЗнч(стрType) = ТипЧисло Тогда // дополнительный контроль числа на допустимое значение ПараметрADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType))); Иначе ПараметрADO.Вставить("Type",intTypeADOЛкс(стрType)); КонецЕсли; КонецЕсли; Если чисSize <> Неопределено Тогда Если ТипЗнч(чисSize)=ТипЧисло Тогда ПараметрADO.Вставить("Size",Цел(чисSize)); Иначе ПараметрADO.Вставить("Size",0); КонецЕсли; КонецЕсли; Если чисNumericScale <> Неопределено Тогда Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда ПараметрADO.Вставить("NumericScale",Цел(чисNumericScale)); Иначе ПараметрADO.Вставить("NumericScale",0); КонецЕсли; КонецЕсли; Если чисPrecision <> Неопределено Тогда Если ТипЗнч(чисPrecision)=ТипЧисло Тогда ПараметрADO.Вставить("Precision",Цел(чисPrecision)); Иначе ПараметрADO.Вставить("Precision",0); КонецЕсли; КонецЕсли; Если Value <> Неопределено Тогда ПараметрADO.Вставить("Value",Value); КонецЕсли; Возврат ПараметрADO; КонецФункции Функция DigitDECtoHEXЛкс(ЦыфраD) Если ЦыфраD=0 Тогда Возврат "0"; ИначеЕсли ЦыфраD>=1 И ЦыфраD<=9 Тогда Возврат ""+ЦыфраD; ИначеЕсли ЦыфраD=10 Тогда Возврат "A"; ИначеЕсли ЦыфраD=11 Тогда Возврат "B"; ИначеЕсли ЦыфраD=12 Тогда Возврат "C"; ИначеЕсли ЦыфраD=13 Тогда Возврат "D"; ИначеЕсли ЦыфраD=14 Тогда Возврат "E"; ИначеЕсли ЦыфраD=15 Тогда Возврат "F"; Иначе Возврат "?"; КонецЕсли; КонецФункции Функция DigitHEXtoDECЛкс(ЦыфраH) Если ЦыфраH="0" ИЛИ ЦыфраH="1" ИЛИ ЦыфраH="2" ИЛИ ЦыфраH="3" ИЛИ ЦыфраH="4" ИЛИ ЦыфраH="5" ИЛИ ЦыфраH="6" ИЛИ ЦыфраH="7" ИЛИ ЦыфраH="8" ИЛИ ЦыфраH="9" Тогда Возврат Цел(ЦыфраH); ИначеЕсли ЦыфраH="a" ИЛИ ЦыфраH="A" Тогда Возврат 10; ИначеЕсли ЦыфраH="b" ИЛИ ЦыфраH="B" Тогда Возврат 11; ИначеЕсли ЦыфраH="c" ИЛИ ЦыфраH="C" Тогда Возврат 12; ИначеЕсли ЦыфраH="d" ИЛИ ЦыфраH="D" Тогда Возврат 13; ИначеЕсли ЦыфраH="e" ИЛИ ЦыфраH="E" Тогда Возврат 14; ИначеЕсли ЦыфраH="f" ИЛИ ЦыфраH="F" Тогда Возврат 15; Иначе Возврат -1; КонецЕсли; КонецФункции Функция СтрокаHEXtoINTЛкс(Знач СтрокаH) Экспорт ПрефиксH = Лев(СтрокаH,2); Если ПрефиксH="0x" ИЛИ ПрефиксH="0X" ИЛИ ПрефиксH="0х" ИЛИ ПрефиксH="0Х" Тогда СтрокаH=Сред(СтрокаH,3); КонецЕсли; Если ПустаяСтрока(СтрокаH) Тогда Возврат 0; КонецЕсли; ДлинаH=СтрДлина(СтрокаH); ЧислоD=0; Для о = 1 По ДлинаH Цикл ЦыфраH = Сред(СтрокаH,о,1); ЦифраD = DigitHEXtoDECЛкс(ЦыфраH); Если ЦифраD<0 Тогда Возврат -1; // нарушение формата 16-тиричного числа КонецЕсли; ЧислоD = 16*ЧислоD + ЦифраD; КонецЦикла; Возврат ЧислоD; КонецФункции // преобразует 16-тиричную строку в COMSafeArray Функция СтрокаHEXtoCOMSafeArrayЛкс(Знач СтрокаH) Экспорт ПрефиксH = Лев(СтрокаH,2); Если Ложь Или ПрефиксH="0x" ИЛИ ПрефиксH="0X" ИЛИ ПрефиксH="0х" ИЛИ ПрефиксH="0Х" Тогда СтрокаH=Сред(СтрокаH,3); КонецЕсли; Байты =СтрДлина(СтрокаH); Байты = 2*Окр(Байты/2,0,1); ArrayДанные = Новый Массив; Поза=1; Для о=1 По Байты Цикл ДваБайт = Сред(СтрокаH,Поза,2); ЗначInt = СтрокаHEXtoINTЛкс(ДваБайт); Если ЗначInt<0 Тогда Возврат Неопределено; КонецЕсли; ArrayДанные.Добавить(ЗначInt); Поза=Поза+2; КонецЦикла; Array = Новый COMSafeArray(ArrayДанные,"VT_UI1",Байты/2); Возврат Array; КонецФункции // преобразует объект УникальныйИдентификатор в COMSafeArray Функция GUIDToCOMSafeArrayЛкс(GUID) Экспорт ГУИД = СтрЗаменить(GUID,"-",Символы.ПС); Если СтрЧислоСтрок(ГУИД)<>5 Тогда // нарушена каноническая структура строки ГУИД: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12) Возврат Неопределено; КонецЕсли; // Соответсвие байтов в поле BINARY(16) с частями ГУИД: 4,5,3,2,1 - проверено для 1с-8.1.14 СтрокаH = СтрПолучитьСтроку(ГУИД,4) + СтрПолучитьСтроку(ГУИД,5)+ СтрПолучитьСтроку(ГУИД,3)+ СтрПолучитьСтроку(ГУИД,2)+ СтрПолучитьСтроку(ГУИД,1); Возврат СтрокаHEXtoCOMSafeArrayЛкс(СтрокаH); КонецФункции // преобразует значение уникального идентификатора ссылки в COMSafeArray Функция СсылкаToCOMSafeArrayЛкс(Ссылка) Экспорт Попытка ГУИД = СокрЛП(Ссылка.УникальныйИдентификатор()); Исключение // переданное значение не ссылка Возврат Неопределено; КонецПопытки; Возврат GUIDToCOMSafeArrayЛкс(ГУИД); КонецФункции // преобразоваение значения COMSafeArray, содержащие 2-байтовые целые в шестнадцатиричную строку Функция BinaryCOMSafeArrayToHEXЛкс(Array) Экспорт СтрHEX=""; Если ТипЗнч(Array)<>Тип("COMSafeArray") Тогда Возврат "?COMSafeArray?"; КонецЕсли; Массив=Array.Выгрузить(); Для каждого Слово Из Массив Цикл Если ТипЗнч(Слово)=Тип("Число") Тогда Слово=Цел(Слово); Если (Слово<0)ИЛИ(Слово>255) Тогда СтрHEX=СтрHEX+"??"; Иначе Байт1=Слово%16; Байт2=Цел(Слово/16); СтрHEX=СтрHEX+DigitDECtoHEXЛкс(Байт2)+DigitDECtoHEXЛкс(Байт1); КонецЕсли; Иначе СтрHEX=СтрHEX+"??"; КонецЕсли; КонецЦикла; Возврат "0x"+СтрHEX; КонецФункции // возвращает свойства параметра ADO из переданной структуры // с автоматическим подбором значений свойств по значению 1С (если свойство неопределено) Процедура ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils=Неопределено) Перем ТипЗначения1С; Если ТипЗнч(стТипADO)=Тип("Структура") Тогда стТипADO.Свойство("Direction",Direction); стТипADO.Свойство("Type",Type); стТипADO.Свойство("Precision",Precision); стТипADO.Свойство("NumericScale",NumericScale); стТипADO.Свойство("Size",Size); стТипADO.Свойство("Attributes",Attributes); стТипADO.Свойство("ТипЗначения1С",ТипЗначения1С); КонецЕсли; Если Истина И ТипЗнч(ТипЗначения1С) = Тип("ОписаниеТипов") И ТипЗначения1С.Типы().Количество() > 0 И НЕ ТипЗначения1С.СодержитТип(ТипЗнч(Значение1С)) Тогда // приведем значение 1С к указанному типу (актуально для значений Null, возвращаемых запросами 1С) Значение1С = ТипЗначения1С.ПривестиЗначение(Значение1С); КонецЕсли; Если Direction=Неопределено Тогда Direction=1; // 1 - входящий(Default) ... или 0 - неизвестно ??? КонецЕсли; Тип1С=ТипЗнч(Значение1С); Попытка Ссылка = Значение1С.Ссылка; Исключение Ссылка = Неопределено; Попытка // перечисления стоят особняком среди "ссылочных" типов МетаДата = Значение1С.Метаданные(); Если Метаданные.Перечисления.Содержит(МетаДата) Тогда Ссылка = Значение1С; КонецЕсли; Исключение КонецПопытки; КонецПопытки; Если Type=Неопределено Тогда // попытаемся подобрать по типу 1С Если Тип1С=Тип("Число") Тогда //Type = 4; // adSingle //Type = 5; // adDouble //Type = 14; // adDecimal //Type = 131; // adNumeric //Type = 139; // adVarNumeric Если Цел(Значение1С)=Значение1С Тогда Если ?(Значение1С<0,-1,1)*Значение1С <= 2147483647 Тогда // 2^32-1 Type = intTypeADOЛкс("adInteger"); // 3 Иначе Type = intTypeADOЛкс("adBigInt"); // 20 КонецЕсли; Иначе Type = 14; // adDecimal КонецЕсли; ИначеЕсли Тип1С=Тип("Строка") Тогда //Type = 129; // adChar //Type = 130; // adWChar //Type = 200; // adVarChar //Type = 201; // adLongVarChar //Type = 202; // adVarWChar //Type = 203; // adLongVarWChar Если СтрДлина(Значение1С)<=4000 Тогда Type = intTypeADOЛкс("adVarChar"); // 200 Иначе Type = intTypeADOЛкс("adLongVarChar"); // 201 КонецЕсли; ИначеЕсли Тип1С=Тип("Дата") Тогда //Type = 134; // adDBTime Если НачалоДня(Значение1С)=Значение1С Тогда Type = intTypeADOЛкс("adDBDate"); // 133 Иначе Type = intTypeADOЛкс("adDBTimeStamp"); // 135 КонецЕсли; ИначеЕсли Тип1С=Тип("Булево") Тогда Type = intTypeADOЛкс("adBoolean"); // 11 ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда Type = intTypeADOЛкс("adBinary"); // 128 Size = 16; Иначе Если Ссылка <> Неопределено Тогда // ссылочный тип - преобразуем в COMSafeArray Type = intTypeADOЛкс("adBinary"); // 128 Size = 16; Иначе Type = intTypeADOЛкс("adEmpty"); // 0? (Default) КонецЕсли; КонецЕсли; КонецЕсли; // ADOUtils.V8DateToDBDate( Дата ) // с учетом YearOffset // ADOUtils.BooleanParameter( Значение ) // COMSafeArray(1) // ADOUtils.TypeParameter( Значение ) // COMSafeArray(1) *_TYPE // ADOUtils.TableNumberParameter( Значение ) // COMSafeArray(4) *_RTRef // ADOUtils.DataVersionParameter( Значение ) // COMSafeArray(8) _Version // ADOUtils.RRefParameter( Значение ) // COMSafeArray(16) *IDRRef Если Ложь Или Type = intTypeADOЛкс("adBinary") // 128 Или Type = intTypeADOЛкс("adVarBinary") Тогда // 204 //Если ADOUtils = Неопределено Тогда // ADOUtils = ПолучитьADOUtils(); // Если ADOUtils = Неопределено Тогда // ADOUtils = Null; // для избежания повторных инициализаций // КонецЕсли; //КонецЕсли; Если Ссылка <> Неопределено Тогда // ссылочный тип - преобразуем в COMSafeArray(16) ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка); //Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда // ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка); //Иначе // ЗначениеADO = ADOUtils.RRefParameter(Ссылка); //КонецЕсли; ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда // ГУИД - преобразуем в COMSafeArray(16) ЗначениеADO = GUIDToCOMSafeArrayЛкс(Значение1С); ИначеЕсли Тип1С=Тип("Булево") Тогда // Булево - преобразуем в COMSafeArray(1) ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00")); //Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда // ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00")); //Иначе // ЗначениеADO = ADOUtils.BooleanParameter(Значение1С); //КонецЕсли; Иначе КонецЕсли; КонецЕсли; Если Precision=Неопределено Тогда Если Ложь Или Type = intTypeADOЛкс("adDecimal") // 14 ИЛИ Type = intTypeADOЛкс("adNumeric") // 131 ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139 Тогда Precision = СтрДлина(СтрЗаменить(Строка(Значение1С)," ","")); КонецЕсли; КонецЕсли; Если NumericScale=Неопределено Тогда Если Ложь Или Type = intTypeADOЛкс("adDecimal") // 14 ИЛИ Type = intTypeADOЛкс("adNumeric") // 131 ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139 Тогда NumericScale = СтрДлина(Строка(Значение1С-Цел(Значение1С))); КонецЕсли; КонецЕсли; Если Size=Неопределено Тогда Если Ложь Или Type = intTypeADOЛкс("adChar") // 129 ИЛИ Type = intTypeADOЛкс("adWChar") // 130 ИЛИ Type = intTypeADOЛкс("adVarChar") // 200 //ИЛИ Type = intTypeADOЛкс("adLongVarChar") // 201 ИЛИ Type = intTypeADOЛкс("adVarWChar") // 202 //ИЛИ Type = intTypeADOЛкс("adLongVarWChar") // 203 Тогда Size = СтрДлина(Значение1С); КонецЕсли; КонецЕсли; КонецПроцедуры // создает массив объектов ADODB.Parameter по списку параметров ADO и по списку типов ADO Функция ParametersArrayПолучитьЛкс(стПараметры,стПарТипADO, ADOUtils = Неопределено) Экспорт ParametersArray = Новый Массив; ТипаМассив = Тип("Массив"); ТипаСоответствие = Тип("Соответствие"); cтПараметрыТип = ТипЗнч(стПараметры); cтПарТипADOТип = ТипЗнч(стПарТипADO); Если стПараметры = Неопределено Тогда Возврат ParametersArray; ИначеЕсли cтПараметрыТип = ТипаМассив ИЛИ cтПараметрыТип = ТипаСоответствие Тогда Если стПарТипADO <> Неопределено И cтПарТипADOТип <> cтПараметрыТип Тогда ВызватьИсключение( "Тип значения списка типов параметров ADO ('"+cтПарТипADOТип+"') не равен |типу значения списка параметров запроса ('"+cтПараметрыТип+"') !"); КонецЕсли; Иначе ВызватьИсключение( "Не предусмотренный тип значения списка параметров запроса ('"+cтПараметрыТип+"') !"); КонецЕсли; ОбъектЗапрос = Новый COMОбъект("ADODB.Command"); Индекс = 0; Для каждого Параметр Из стПараметры Цикл Если cтПараметрыТип = ТипаМассив Тогда ПараметрИмя = Неопределено; Значение1С = Параметр; ИначеЕсли cтПараметрыТип = ТипаСоответствие Тогда ПараметрИмя = СокрЛП(Параметр.Ключ); Значение1С = Параметр.Значение; Иначе Продолжить; КонецЕсли; Индекс = Индекс + 1; стТипADO=Неопределено; Если cтПарТипADOТип=ТипаМассив Тогда Если Индекс<=стПарТипADO.Количество()-1 Тогда стТипADO = стПарТипADO.Получить(Индекс); КонецЕсли; ИначеЕсли cтПарТипADOТип = ТипаСоответствие Тогда стТипADO = стПарТипADO.Получить(Параметр.Ключ); КонецЕсли; ЗначениеADO = Неопределено; Attributes = Неопределено; Direction = Неопределено; Type = Неопределено; Precision = Неопределено; NumericScale = Неопределено; Size = Неопределено; // прочитаем свойства параметра ADO по полученной структуре типа и значению 1С ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils); // создадим параметр ADO и заполним его свойства Parameter = ОбъектЗапрос.CreateParameter(); Если НЕ ПустаяСтрока(Type) Тогда Parameter.Type=Type; КонецЕсли; Если НЕ ПустаяСтрока(Direction) Тогда Parameter.Direction=Direction; КонецЕсли; Если НЕ ПустаяСтрока(Size) Тогда Parameter.Size=Size; КонецЕсли; Если НЕ ПустаяСтрока(Attributes) Тогда Parameter.Attributes=Attributes; КонецЕсли; Если НЕ ПустаяСтрока(ПараметрИмя) Тогда Parameter.Name = ПараметрИмя; КонецЕсли; Если ЗначениеADO = Неопределено Тогда Parameter.Value=Значение1С; // преобразование не явное Иначе Parameter.Value=ЗначениеADO; КонецЕсли; // добавим в массив ParametersArray.Добавить(Parameter); КонецЦикла; Возврат ParametersArray; КонецФункции // ParametersArrayПолучитьЛкс() // формирует массив или соответствие со значениями параметров запроса из строки таблицы значений Функция стПараметры_Получить_ТЗЛкс(тзПараметры,СтрокаПараметров,NamedParameters,Знач ParametersPrefix) Экспорт Если NamedParameters=Истина Тогда ParametersPrefix=СокрЛП(ParametersPrefix); стПараметры=Новый Соответствие; Для каждого Колонка Из тзПараметры.Колонки Цикл стПараметры.Вставить(ParametersPrefix+Колонка.Имя,СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка))); КонецЦикла; Иначе стПараметры=Новый Массив; Для каждого Колонка Из тзПараметры.Колонки Цикл стПараметры.Добавить(СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка))); КонецЦикла; КонецЕсли; Возврат стПараметры; КонецФункции // стПараметры_Получить_ТЗЛкс() // добавляет и устанавливает объект ADODB.Parameter в коллекцию параметров // если не заданы свойства параметра ADO, делается попытка их подбора по типу значения 1С Функция ADODBCommand_УстановитьПараметрПо1СЛкс(ОбъектЗапрос,Инициализация,Индекс,Name,стТипADO,Значение1С,ADOUtils,ЕррорИнфо) Экспорт ЗначениеADO=Неопределено; Attributes=Неопределено; Direction=Неопределено; Type=Неопределено; Precision=Неопределено; NumericScale=Неопределено; Size=Неопределено; // прочитаем свойства параметра ADO из переданной структуры по значению 1С ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils); ЕррорИнфо=""; Попытка Если ОбъектЗапрос.Prepared = Ложь ИЛИ Инициализация <> Ложь Тогда // инициализация параметров запроса Добавить = Ложь; Если Name = Неопределено Тогда // по переданному индексу параметра Parameter = ОбъектЗапрос.CreateParameter(); Добавить = Истина; // создаем без имени Иначе // по переданному имени параметра Попытка // если уже есть параметр с именем - используем его Parameter = ОбъектЗапрос.Parameters.Item(Name); Исключение Parameter = Неопределено; КонецПопытки; Если Parameter = Неопределено Тогда // если нет - создаем с указанным именем Parameter = ОбъектЗапрос.CreateParameter(); Parameter.Name = Name; Добавить = Истина; КонецЕсли; КонецЕсли; Если НЕ ПустаяСтрока(Type) Тогда Parameter.Type=Type; КонецЕсли; Если НЕ ПустаяСтрока(Direction) Тогда Parameter.Direction=Direction; КонецЕсли; Если НЕ ПустаяСтрока(Size) Тогда Parameter.Size=Size; КонецЕсли; Если НЕ ПустаяСтрока(Attributes) И Attributes <> 0 Тогда Parameter.Attributes=Attributes; КонецЕсли; Если Добавить = Истина Тогда ОбъектЗапрос.Parameters.Append(Parameter); КонецЕсли; Иначе // установка параметра предварительно подготовленного параметризованного запроса Если Name = Неопределено Тогда // по переданному индексу параметра Parameter = ОбъектЗапрос.Parameters.Item(Индекс); Иначе // по переданному имени параметра Parameter = ОбъектЗапрос.Parameters.Item(Name); КонецЕсли; КонецЕсли; Если ЗначениеADO = Неопределено Тогда Parameter.Value=Значение1С; // преобразование не явное Иначе Parameter.Value=ЗначениеADO; КонецЕсли; Исключение ЕррорИнфо=ОписаниеОшибки(); Возврат Ложь; КонецПопытки; Возврат Истина; КонецФункции // ^^^ УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ^^^ // *** ПЕРЕЧИСЛЕНИЯ ADO *** // возвращает строковое представление типа параметра ADO(свойства Direction) по его числовому значению Функция strDirectionParADOЛкс(intTypeADOЛкс) Экспорт intType = Цел(intTypeADOЛкс); Если intType = 0 Тогда Возврат "adParamUnknown"; // Direction unknown ИначеЕсли intType = 1 Тогда Возврат "adParamInput"; // Input parameter (Default) ИначеЕсли intType = 2 Тогда Возврат "adParamOutput"; // Output parameter ИначеЕсли intType = 3 Тогда Возврат "adParamInputOutput"; // Input and output parameter ИначеЕсли intType = 4 Тогда Возврат "adParamReturnValue"; // Return value Иначе Возврат "adParamInput"; // как 1 КонецЕсли; КонецФункции // возвращает числовое значения типа параметра ADO(свойства Direction) по его числовому представлению Функция intDirectionParADOЛкс(strTypeADOЛкс) Экспорт strType = НРег(strTypeADOЛкс); Если strType = Нрег("adParamUnknown") Тогда Возврат 0; // Direction unknown ИначеЕсли strType = Нрег("adParamInput") Тогда Возврат 1; // Input parameter (Default) ИначеЕсли strType = Нрег("adParamOutput") Тогда Возврат 2; // Output parameter ИначеЕсли strType = Нрег("adParamInputOutput") Тогда Возврат 3; // Input and output parameter ИначеЕсли strType = Нрег("adParamReturnValue") Тогда Возврат 4; // Return value Иначе Возврат 1; // adParamInput КонецЕсли; КонецФункции // возвращает строковое представление типа значения ADO по его числовому значению Функция strTypeADOЛкс(intTypeADOЛкс) Экспорт intType = Цел(intTypeADOЛкс); Если intType = 0 Тогда Возврат "adEmpty"; // no value ИначеЕсли intType = 2 Тогда Возврат "adSmallInt"; // 2-byte signed integer ИначеЕсли intType = 3 Тогда Возврат "adInteger"; // 4-byte signed integer ИначеЕсли intType = 4 Тогда Возврат "adSingle"; // single-precision floating-point value ИначеЕсли intType = 5 Тогда Возврат "adDouble"; // double-precision floating-point value ИначеЕсли intType = 6 Тогда Возврат "adCurrency"; // currency value ИначеЕсли intType = 7 Тогда Возврат "adDate"; // number of days since December 30, 1899 + the fraction of a day ИначеЕсли intType = 8 Тогда Возврат "adBSTR"; // null-terminated character string ИначеЕсли intType = 9 Тогда Возврат "adIDispatch"; // pointer to an IDispatch interface on a COM object(currently not supported by ADO) ИначеЕсли intType = 10 Тогда Возврат "adError"; // 32-bit error code ИначеЕсли intType = 11 Тогда Возврат "adBoolean"; // boolean value ИначеЕсли intType = 12 Тогда Возврат "adVariant"; // automation Variant(currently not supported by ADO) ИначеЕсли intType = 13 Тогда Возврат "adIUnknown"; // pointer to an IUnknown interface on a COM object(currently not supported by ADO) ИначеЕсли intType = 14 Тогда Возврат "adDecimal"; // exact numeric value with a fixed precision and scale ИначеЕсли intType = 16 Тогда Возврат "adTinyInt"; // 1-byte signed integer ИначеЕсли intType = 17 Тогда Возврат "adUnsignedTinyInt"; // 1-byte unsigned integer ИначеЕсли intType = 18 Тогда Возврат "adUnsignedSmallInt"; // 2-byte unsigned integer ИначеЕсли intType = 19 Тогда Возврат "adUnsignedInt"; // 4-byte unsigned integer ИначеЕсли intType = 20 Тогда Возврат "adBigInt"; // 8-byte signed integer ИначеЕсли intType = 21 Тогда Возврат "adUnsignedBigInt"; // 8-byte unsigned integer ИначеЕсли intType = 64 Тогда Возврат "adFileTime"; // number of 100-nanosecond intervals since January 1,1601 ИначеЕсли intType = 72 Тогда Возврат "adGUID"; // globally unique identifier (GUID) ИначеЕсли intType = 128 Тогда Возврат "adBinary"; // binary value ИначеЕсли intType = 129 Тогда Возврат "adChar"; // string value ИначеЕсли intType = 130 Тогда Возврат "adWChar"; // null-terminated Unicode character string ИначеЕсли intType = 131 Тогда Возврат "adNumeric"; // exact numeric value with a fixed precision and scale ИначеЕсли intType = 132 Тогда Возврат "adUserDefined"; // user-defined variable ИначеЕсли intType = 133 Тогда Возврат "adDBDate"; // date value (yyyymmdd) ИначеЕсли intType = 134 Тогда Возврат "adDBTime"; // time value (hhmmss) ИначеЕсли intType = 135 Тогда Возврат "adDBTimeStamp"; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths) ИначеЕсли intType = 136 Тогда Возврат "adChapter"; // 4-byte chapter value that identifies rows in a child rowset ИначеЕсли intType = 138 Тогда Возврат "adPropVariant"; // automation PROPVARIANT ИначеЕсли intType = 139 Тогда Возврат "adVarNumeric"; // numeric value(Parameter object only) ИначеЕсли intType = 200 Тогда Возврат "adVarChar"; // string value (Parameter object only) ИначеЕсли intType = 201 Тогда Возврат "adLongVarChar"; // long string value ИначеЕсли intType = 202 Тогда Возврат "adVarWChar"; // null-terminated Unicode character string ИначеЕсли intType = 203 Тогда Возврат "adLongVarWChar"; // long null-terminated Unicode string value ИначеЕсли intType = 204 Тогда Возврат "adVarBinary"; // binary value (Parameter object only) ИначеЕсли intType = 205 Тогда Возврат "adLongVarBinary"; // long binary value ИначеЕсли intType = 8192 Тогда Возврат "AdArray"; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type Иначе Возврат "adEmpty"; // как 0 КонецЕсли; КонецФункции // возвращает числовое значение типа значения ADO по его строковому представлению Функция intTypeADOЛкс(strTypeADOЛкс) Экспорт strType = НРег(strTypeADOЛкс); Если strType = НРег("adEmpty") Тогда Возврат 0; // no value ИначеЕсли strType = НРег("adSmallInt") Тогда Возврат 2; // 2-byte signed integer ИначеЕсли strType = НРег("adInteger") Тогда Возврат 3; // 4-byte signed integer ИначеЕсли strType = НРег("adSingle") Тогда Возврат 4; // single-precision floating-point value ИначеЕсли strType = НРег("adDouble") Тогда Возврат 5; // double-precision floating-point value ИначеЕсли strType = НРег("adCurrency") Тогда Возврат 6; // currency value ИначеЕсли strType = НРег("adDate") Тогда Возврат 7; // number of days since December 30, 1899 + the fraction of a day ИначеЕсли strType = НРег("adBSTR") Тогда Возврат 8; // null-terminated character string ИначеЕсли strType = НРег("adIDispatch") Тогда Возврат 9; // pointer to an IDispatch interface on a COM object(currently not supported by ADO) ИначеЕсли strType = НРег("adError") Тогда Возврат 10; // 32-bit error code ИначеЕсли strType = НРег("adBoolean") Тогда Возврат 11; // boolean value ИначеЕсли strType = НРег("adVariant") Тогда Возврат 12; // automation Variant(currently not supported by ADO) ИначеЕсли strType = НРег("adIUnknown") Тогда Возврат 13; // pointer to an IUnknown interface on a COM object(currently not supported by ADO) ИначеЕсли strType = НРег("adDecimal") Тогда Возврат 14; // exact numeric value with a fixed precision and scale ИначеЕсли strType = НРег("adTinyInt") Тогда Возврат 16; // 1-byte signed integer ИначеЕсли strType = НРег("adUnsignedTinyInt") Тогда Возврат 17; // 1-byte unsigned integer ИначеЕсли strType = НРег("adUnsignedSmallInt") Тогда Возврат 18;// 2-byte unsigned integer ИначеЕсли strType = НРег("adUnsignedInt") Тогда Возврат 19; // 4-byte unsigned integer ИначеЕсли strType = НРег("adBigInt") Тогда Возврат 20; // 8-byte signed integer ИначеЕсли strType = НРег("adUnsignedBigInt") Тогда Возврат 21; // 8-byte unsigned integer ИначеЕсли strType = НРег("adFileTime") Тогда Возврат 64; // number of 100-nanosecond intervals since January 1,1601 ИначеЕсли strType = НРег("adGUID") Тогда Возврат 72; // globally unique identifier (GUID) ИначеЕсли strType = НРег("adBinary") Тогда Возврат 128; // binary value ИначеЕсли strType = НРег("adChar") Тогда Возврат 129; // string value ИначеЕсли strType = НРег("adWChar") Тогда Возврат 130; // null-terminated Unicode character string ИначеЕсли strType = НРег("adNumeric") Тогда Возврат 131; // exact numeric value with a fixed precision and scale ИначеЕсли strType = НРег("adUserDefined") Тогда Возврат 132; // user-defined variable ИначеЕсли strType = НРег("adDBDate") Тогда Возврат 133; // date value (yyyymmdd) ИначеЕсли strType = НРег("adDBTime") Тогда Возврат 134; // time value (hhmmss) ИначеЕсли strType = НРег("adDBTimeStamp") Тогда Возврат 135; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths) ИначеЕсли strType = НРег("adChapter") Тогда Возврат 136; // 4-byte chapter value that identifies rows in a child rowset ИначеЕсли strType = НРег("adPropVariant") Тогда Возврат 138; // automation PROPVARIANT ИначеЕсли strType = НРег("adVarNumeric") Тогда Возврат 139; // numeric value(Parameter object only) ИначеЕсли strType = НРег("adVarChar") Тогда Возврат 200; // string value (Parameter object only) ИначеЕсли strType = НРег("adLongVarChar") Тогда Возврат 201; // long string value ИначеЕсли strType = НРег("adVarWChar") Тогда Возврат 202; // null-terminated Unicode character string ИначеЕсли strType = НРег("adLongVarWChar") Тогда Возврат 203; // long null-terminated Unicode string value ИначеЕсли strType = НРег("adVarBinary") Тогда Возврат 204; // binary value (Parameter object only) ИначеЕсли strType = НРег("adLongVarBinary") Тогда Возврат 205; // long binary value ИначеЕсли strType = НРег("AdArray") Тогда Возврат 8192; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type Иначе Возврат 0; // adEmpty КонецЕсли; КонецФункции // возвращает числовое значение типа курсора по его строковому представлению Функция strCursorTypeЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = -1 Тогда Возврат "adOpenUnspecified"; // Does not specify the type of cursor ИначеЕсли intV = 0 Тогда Возврат "adOpenForwardOnly"; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default) ИначеЕсли intV = 1 Тогда Возврат "adOpenKeyset"; // Uses a keyset cursor. Like a dynamic cursor, except... ИначеЕсли intV = 2 Тогда Возврат "adOpenDynamic"; // Uses a dynamic cursor ИначеЕсли intV = 3 Тогда Возврат "adOpenStatic"; // Uses a static cursor Иначе Возврат "adOpenForwardOnly"; // как 0 КонецЕсли; КонецФункции // возвращает строковое представление типа курсора по его числовому значению Функция intCursorTypeЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adOpenUnspecified") Тогда Возврат -1; // Does not specify the type of cursor ИначеЕсли strV = Нрег("adOpenForwardOnly") Тогда Возврат 0; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default ИначеЕсли strV = Нрег("adOpenKeyset") Тогда Возврат 1; // Uses a keyset cursor. Like a dynamic cursor, except... ИначеЕсли strV = Нрег("adOpenDynamic") Тогда Возврат 2; // Uses a dynamic cursor ИначеЕсли strV = Нрег("adOpenStatic") Тогда Возврат 3; // Uses a static cursor Иначе Возврат 0; // adOpenForwardOnly КонецЕсли; КонецФункции // возвращает числовое значение местоположения курсора по его строковому представлению Функция strCursorLocationЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = 1 Тогда Возврат "adUseNone"; // Does not use cursor services ИначеЕсли intV = 2 Тогда Возврат "adUseServer"; // Uses a server-side cursor (Default) ИначеЕсли intV = 3 Тогда Возврат "adParamOutput"; // Uses a client-side cursor supplied by a local cursor library Иначе Возврат "adUseServer"; // как 2 КонецЕсли; КонецФункции // возвращает строковое представление местоположения курсора по его числовому значению Функция intCursorLocationЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adUseNone") Тогда Возврат 1; // Does not use cursor services ИначеЕсли strV = Нрег("adUseServer") Тогда Возврат 2; // Uses a server-side cursor (Default) ИначеЕсли strV = Нрег("adParamOutput") Тогда Возврат 3; // Uses a client-side cursor supplied by a local cursor library Иначе Возврат 2; // adUseServer КонецЕсли; КонецФункции // возвращает числовое значение типа блокировки данных по его строковому представлению Функция strLockTypeЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = -1 Тогда Возврат "adLockUnspecified"; // Unspecified type of lock. Clones inherits lock type from the original Recordset ИначеЕсли intV = 1 Тогда Возврат "adLockReadOnly"; // Read-only records ИначеЕсли intV = 2 Тогда Возврат "adLockPessimistic"; // Pessimistic locking, record by record. The provider lock records immediately after editing ИначеЕсли intV = 3 Тогда Возврат "adLockOptimistic"; // Optimistic locking, record by record. The provider lock records only when calling update ИначеЕсли intV = 4 Тогда Возврат "adLockBatchOptimistic"; // Optimistic batch updates. Required for batch update mode Иначе Возврат "adLockUnspecified"; // как -1 КонецЕсли; КонецФункции // возвращает строковое представление типа блокировки данных по его числовому значению Функция intLockTypeЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adLockUnspecified") Тогда Возврат -1; // Unspecified type of lock ИначеЕсли strV = Нрег("adLockReadOnly") Тогда Возврат 1; // Read-only records ИначеЕсли strV = Нрег("adLockPessimistic") Тогда Возврат 2; // Pessimistic locking, record by record. The provider lock records immediately after editing ИначеЕсли strV = Нрег("adLockOptimistic") Тогда Возврат 3; // Optimistic locking, record by record. The provider lock records only when calling update ИначеЕсли strV = Нрег("adLockBatchOptimistic") Тогда Возврат 4; // Optimistic batch updates. Required for batch update mode Иначе Возврат -1; // adLockUnspecified КонецЕсли; КонецФункции // возвращает числовое значение опции MarshalOptions по его строковому представлению Функция strMarshalOptionsЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = 0 Тогда Возврат "adMarshalAll"; // Returns all rows (Default) ИначеЕсли intV = 1 Тогда Возврат "adMarshalModifiedOnly"; // Returns only modified rows Иначе Возврат "adMarshalAll"; // как 0 КонецЕсли; КонецФункции // возвращает строковое представление опции MarshalOptions по его числовому значению Функция intMarshalOptionsЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adMarshalAll") Тогда Возврат 0; // Returns all rows (Default) ИначеЕсли strV = Нрег("adMarshalModifiedOnly") Тогда Возврат 1; // Returns only modified rows Иначе Возврат 0; // adMarshalAll КонецЕсли; КонецФункции // возвращает строковое представление типа команды ADO по его числовому значению Функция strCommandTypeADOЛкс(intTypeADOЛкс) Экспорт Если ТипЗнч(intTypeADOЛкс) = Тип("Число") Тогда intType = Цел(intTypeADOЛкс); Иначе intType = 0; КонецЕсли; Если intType = -1 Тогда Возврат "adCmdUnspecified"; // Unspecified type of command ИначеЕсли intType = 1 Тогда Возврат "adCmdText"; // строка оператора T-SQL ИначеЕсли intType = 2 Тогда Возврат "adCmdTable"; // имя таблицы для выборки строк ИначеЕсли intType = 4 Тогда Возврат "adCmdStoredProc"; // имя хранимой процедуры ИначеЕсли intType = 8 Тогда Возврат "adCmdUnknown"; // неизвестно, проверять провайдером (Default) ИначеЕсли intType = 256 Тогда Возврат "adCmdFile"; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only) ИначеЕсли intType = 512 Тогда Возврат "adCmdTableDirect"; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only) Иначе Возврат "adCmdUnknown"; // как 8 КонецЕсли; КонецФункции // возвращает числовое значение типа команды ADO по его строковому представлению Функция intCommandTypeADOЛкс(strTypeADOЛкс) Экспорт strType = Нрег(strTypeADOЛкс); Если strType = Нрег("adCmdUnspecified") Тогда Возврат -1; // Unspecified type of command ИначеЕсли strType = Нрег("adCmdText") Тогда Возврат 1; // строка оператора T-SQL ИначеЕсли strType = Нрег("adCmdTable") Тогда Возврат 2; // имя таблицы для выборки строк ИначеЕсли strType = Нрег("adCmdStoredProc") Тогда Возврат 4; // имя хранимой процедуры ИначеЕсли strType = Нрег("adCmdUnknown") Тогда Возврат 8; // неизвестно, проверять провайдером (Default) ИначеЕсли strType = Нрег("adCmdFile") Тогда Возврат 256; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only) ИначеЕсли strType = Нрег("adCmdTableDirect") Тогда Возврат 512; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only) Иначе Возврат 8; // adCmdUnknown КонецЕсли; КонецФункции // возвращает строковое представление типа команды ADO по его числовому значению Функция strExecuteOptionЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = -1 Тогда Возврат "adOptionUnspecified"; // Unspecified command ИначеЕсли intV = 16 Тогда Возврат "adAsyncExecute"; // The command should execute asynchronously ИначеЕсли intV = 32 Тогда Возврат "adAsyncFetch"; // The remaining rows after specified in the CacheSize should be retrieved asynchronously ИначеЕсли intV = 64 Тогда Возврат "adAsyncFetchNonBlocking"; // The main thread never blocks while retrieving. ИначеЕсли intV = 128 Тогда Возврат "adExecuteNoRecords"; // Discard, not return retrieved rows (with Command or Connection.Execute only) ИначеЕсли intV = 256 Тогда Возврат "adExecuteStream"; // The results of a command execution is a stream (with Connection.Execute only) ИначеЕсли intV = 512 Тогда Возврат "adExecuteRecord"; // Return a single row as a Record object Иначе Возврат "adOptionUnspecified"; // как -1 КонецЕсли; КонецФункции // возвращает числовое значение типа команды ADO по его строковому представлению Функция intExecuteOptionЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adOptionUnspecified") Тогда Возврат -1; // Unspecified command ИначеЕсли strV = Нрег("adAsyncExecute") Тогда Возврат 16; // The command should execute asynchronously ИначеЕсли strV = Нрег("adAsyncFetch") Тогда Возврат 32; // The remaining rows after specified in the CacheSize should be retrieved asynchronously ИначеЕсли strV = Нрег("adAsyncFetchNonBlocking") Тогда Возврат 64; // The main thread never blocks while retrieving ИначеЕсли strV = Нрег("adExecuteNoRecords") Тогда Возврат 128; // Discard, not return retrieved rows (with Command or Connection.Execute only) ИначеЕсли strV = Нрег("adExecuteStream") Тогда Возврат 256; // The results of a command execution is a stream (with Connection.Execute only) ИначеЕсли strV = Нрег("adExecuteRecord") Тогда Возврат 512; // Return a single row as a Record object Иначе Возврат -1; // adOptionUnspecified КонецЕсли; КонецФункции // возвращает строковое представление опции аттрибутов параметра ADO по числовому значению опции Функция strParameterADOAttributesЛкс(intValue) Экспорт Если ТипЗнч(intValue) = Тип("Число") Тогда intV = Цел(intValue); Иначе intV = 0; КонецЕсли; Если intV = 16 Тогда Возврат "adParamSigned"; // The parameter will accept signed values. ИначеЕсли intV = 64 Тогда Возврат "adParamNullAble"; // The parameter will accept null values. ИначеЕсли intV = 128 Тогда Возврат "adParamLong"; // The parameter will accept long binary data. Иначе Возврат "adParamSigned"; // как 16 КонецЕсли; КонецФункции // возвращает числовое значение оцции аттрибутов параметра ADO по строковому представлению опции Функция intParameterADOAttributesЛкс(strValue) Экспорт strV = Нрег(strValue); Если strV = Нрег("adParamSigned") Тогда Возврат 16; // The parameter will accept signed values. ИначеЕсли strV = Нрег("adParamNullAble") Тогда Возврат 64; // The parameter will accept null values. ИначеЕсли strV = Нрег("adParamLong") Тогда Возврат 128; // The parameter will accept long binary data. Иначе Возврат 16; // adParamSigned КонецЕсли; КонецФункции // ^^^ ПЕРЕЧИСЛЕНИЯ ADO ^^^ // ADO // ************************ // В платформе все корневые элементы древовидных структур содержат в свойстве Родитель Неопределено. // Поэтому возникает неудобство при работе с этим свойством, заключающееся в необходимости часто проверять его значение на Неопределено. // Параметры: // СтрокаДерева - СтрокаДереваЗначений, <Элемент любого иерархического объекта, имеющий родителя> // Дерево - <Иерархический объект, которому принадлежит элемент> - для дерева значений не нужно передавать // Функция ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево = Неопределено) Экспорт Попытка Родитель = СтрокаДерева.Родитель; Исключение Родитель = СтрокаДерева.ПолучитьРодителя(); КонецПопытки; Если Родитель = Неопределено Тогда Если Дерево = Неопределено Тогда Родитель = СтрокаДерева.Владелец(); Иначе Родитель = Дерево; КонецЕсли; КонецЕсли; Возврат Родитель; КонецФункции // Результат - Неопределено, "*", Число Функция ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение) Экспорт Если Не ЭтоКоллекцияЛкс(Значение) Тогда КоличествоЭлементов = Неопределено; Иначе КоличествоЭлементов = "*"; Если ТипЗнч(Значение) = Тип("COMSafeArray") Тогда КоличествоЭлементов = Значение.GetLength(); ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда Попытка КоличествоЭлементов = Значение.Count; Исключение КонецПопытки; КонецЕсли; Если КоличествоЭлементов = "*" Тогда Попытка КоличествоЭлементов = Значение.Количество(); Исключение КонецПопытки; КонецЕсли; КонецЕсли; Возврат КоличествоЭлементов; КонецФункции Функция ЭтоКоллекцияЛкс(Значение) Экспорт // Антибаг платформы 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1017316#1017316 Если Значение = ПараметрыСеанса Тогда Возврат Истина; КонецЕсли; // Для ускорения Если Значение = Неопределено Или Значение = Null Тогда Возврат Ложь; КонецЕсли; ХмлТип = XMLТипЗнч(Значение); Если ХмлТип <> Неопределено Тогда ИмяТипа = ХмлТип.ИмяТипа; Если Ложь Или Найти(ИмяТипа, "Ref.") > 0 Или ИмяТипа = "decimal" Или ИмяТипа = "boolean" Или ИмяТипа = "dateTime" Или ИмяТипа = "string" Тогда Возврат Ложь; КонецЕсли; КонецЕсли; Попытка Для Каждого _Элемент Из Значение Цикл // Это тяжелая операция и выполняется почему то минимум 2 раза судя по замеру Прервать; КонецЦикла; ЭтоКоллекция = Истина; Исключение ЭтоКоллекция = Ложь; КонецПопытки; Возврат ЭтоКоллекция; КонецФункции Функция ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД) Экспорт Фрагменты = СтрРазделитьЛкс(ПолноеИмяМД); ТипМетаданных = Фрагменты[0]; ИмяОбъекта = Фрагменты[1]; Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда ТипОбъекта = Тип(ТипМетаданных + "Объект." + ИмяОбъекта); Иначе КэшТиповВнешнихМетаданных = ирПортативный.мКэшТиповВнешнихМетаданных; ВнешнийОбъект = КэшТиповВнешнихМетаданных[ПолноеИмяМД]; Если ВнешнийОбъект <> Неопределено Тогда ТипОбъекта = ТипЗнч(ВнешнийОбъект); КонецЕсли; КонецЕсли; Если ТипОбъекта <> Неопределено Тогда Результат = Новый (ТипОбъекта); Иначе Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных); ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(ИмяОбъекта, ТипМетаданных); Попытка Результат = Менеджер.Создать(ПолноеИмяФайла, Ложь); //// Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1442085/m/1442085 //Если ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Тогда // Пустышка = Результат.ПолучитьФорму(); //КонецЕсли; Исключение // Это очень помогает при ошибках функций режима отладки ВызватьИсключение ОписаниеОшибки(); КонецПопытки; Если Истина И КэшТиповВнешнихМетаданных <> Неопределено // Такой прием ко всем нельзя применять, т.к. при получении формы у разных экземпляров будет возвращаться всегда форма первого экземпляра, если она открыта И (Ложь Или ИмяОбъекта = "ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой" Или ИмяОбъекта = "ирПлатформа") Тогда КэшТиповВнешнихМетаданных[ПолноеИмяМД] = Результат; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьПолноеИмяМДТипаЛкс(Тип) Экспорт ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип); Если ОбъектМетаданных <> Неопределено Тогда Результат = ОбъектМетаданных.ПолноеИмя(); Если ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Тогда Результат = Результат + "." + ПеревестиСтроку("Точки"); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ОптимальныйПотоковыйПисательЛкс() Экспорт Если ирКэш.НомерВерсииПлатформыЛкс() >= 803006 Тогда ПотоковыйПисатель = МойЗаписьJSON(); Иначе ПотоковыйПисатель = Новый ЗаписьXML; КонецЕсли; Возврат ПотоковыйПисатель; КонецФункции Функция МойЗаписьJSON() Экспорт Возврат Новый ("ЗаписьJSON"); КонецФункции Функция ОптимальныйПотоковыйЧитательЛкс() Экспорт Если ирКэш.НомерВерсииПлатформыЛкс() >= 803006 Тогда ПотоковыйЧитатель = МойЧтениеJSON(); Иначе ПотоковыйЧитатель = Новый ЧтениеXML; КонецЕсли; Возврат ПотоковыйЧитатель; КонецФункции Функция МойЧтениеJSON() Экспорт Возврат Новый ("ЧтениеJSON"); КонецФункции Функция ДеревоЗначенийИзМассиваСтруктурЛкс(МассивСтруктур, Дерево = Неопределено) Экспорт Если Дерево = Неопределено Тогда Дерево = Новый ДеревоЗначений; Дерево.Колонки.Добавить("Свойство"); Дерево.Колонки.Добавить("Значение"); КонецЕсли; Если ТипЗнч(МассивСтруктур) = Тип("Структура") Тогда ЭлементСтруктурыВДеревоЗначений(Дерево, МассивСтруктур); ИначеЕсли ТипЗнч(МассивСтруктур) = Тип("Массив") Тогда МассивВДеревоЗначений(Дерево, МассивСтруктур, ""); КонецЕсли; Возврат Дерево; КонецФункции Процедура ЭлементСтруктурыВДеревоЗначений(Дерево, Структура) #Если Сервер И Не Сервер Тогда Дерево = Новый ДеревоЗначений; #КонецЕсли Для Каждого ЭлСтруктуры Из Структура Цикл СтрокаДерева = Дерево.Строки.Добавить(); СтрокаДерева.Свойство = ЭлСтруктуры.Ключ; Если ТипЗнч(ЭлСтруктуры.Значение) = Тип("Структура") Тогда ЭлементСтруктурыВДеревоЗначений(СтрокаДерева, ЭлСтруктуры.Значение); ИначеЕсли ТипЗнч(ЭлСтруктуры.Значение) = Тип("Массив") Тогда СтрокаДерева.Значение = "[Массив-" + XMLСтрока(ЭлСтруктуры.Значение.Количество()) + "]"; МассивВДеревоЗначений(СтрокаДерева, ЭлСтруктуры.Значение, ЭлСтруктуры.Ключ); Иначе СтрокаДерева.Значение = ЭлСтруктуры.Значение; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура МассивВДеревоЗначений(Дерево, Массив, ИмяСвойства) #Если Сервер И Не Сервер Тогда Дерево = Новый ДеревоЗначений; #КонецЕсли Для Каждого СтрМассива Из Массив Цикл СтрокаДерева = Дерево.Строки.Добавить(); СтрокаДерева.Свойство = "[Элемент " + ИмяСвойства + "]"; Если ТипЗнч(СтрМассива) = Тип("Структура") Тогда ЭлементСтруктурыВДеревоЗначений(СтрокаДерева, СтрМассива); ИначеЕсли ТипЗнч(СтрМассива) = Тип("Массив") Тогда СтрокаДерева.Значение = "[Массив-" + XMLСтрока(СтрМассива.Количество()) + "]"; МассивВДеревоЗначений(СтрокаДерева, СтрМассива, ИмяСвойства); Иначе СтрокаДерева.Значение = СтрМассива; КонецЕсли; КонецЦикла; КонецПроцедуры Функция ОбработатьСобытиеЛкс(ТаблицаСобытий, ИмяСобытия, выхОписаниеОшибки, П0 = null, П1 = null, П2 = null, П3 = null, П4 = null, П5 = null, П6 = null, П7 = null) Экспорт СтрокаСобытия = ТаблицаСобытий.Найти(ИмяСобытия, "ИмяСобытия"); СтрокаXMLАлгоритма = СтрокаСобытия.Алгоритм; Если Не ЗначениеЗаполнено(СтрокаXMLАлгоритма) Тогда Возврат Истина; КонецЕсли; Если ТаблицаСобытий.Колонки.Найти("АлгоритмОбъект") = Неопределено Тогда ТаблицаСобытий.Колонки.Добавить("АлгоритмОбъект"); КонецЕсли; АлгоритмОбъект = СтрокаСобытия.АлгоритмОбъект; Если АлгоритмОбъект = Неопределено Тогда Попытка АлгоритмОбъект = ДесериализоватьАлгоритмОбъектЛкс(СтрокаXMLАлгоритма); Исключение ВызватьИсключение "Ошибка десериализации алгоритма для события " + ИмяСобытия + ": " + ОписаниеОшибки(); КонецПопытки; АлгоритмОбъект.Наименование = ИмяСобытия; ВнутренниеПараметры = АлгоритмОбъект.Параметры.Выгрузить(); АлгоритмОбъект.Параметры.Загрузить(СтрокаСобытия.Параметры); ЗагрузитьВТаблицуЗначенийЛкс(ВнутренниеПараметры, АлгоритмОбъект.Параметры); СтрокаСобытия.АлгоритмОбъект = АлгоритмОбъект; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Попытка Результат = мПлатформа.ВыполнитьМетодАлгоритма(АлгоритмОбъект, 0, П0, П1, П2, П3, П4, П5, П6, П7); Исключение //выхОписаниеОшибки = ПолучитьПричинуОшибки(ОписаниеОшибки()); выхОписаниеОшибки = ОписаниеОшибки(); Возврат Ложь; КонецПопытки; Возврат Истина; КонецФункции Функция ДесериализоватьАлгоритмОбъектЛкс(Знач СтрокаXMLАлгоритма) Экспорт СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма); АлгоритмОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИмитаторАлгоритмОбъект"); #Если Сервер И Не Сервер Тогда АлгоритмОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать(); #КонецЕсли АлгоритмОбъект.ТекстАлгоритма = СтруктураАлгоритма.ТекстАлгоритма; ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, АлгоритмОбъект.Параметры, Новый Структура("Вход", Истина)); Возврат АлгоритмОбъект; КонецФункции // мВнешниеНаборыДанных - Структура, Неопределено - не очищается Функция ДополнитьСтруктуруВнешнихНаборовДанныхПустышкамиЛкс(СхемаКомпоновкиДанных, ВнешниеНаборыДанных = Неопределено) Экспорт Если ВнешниеНаборыДанных = Неопределено Тогда ВнешниеНаборыДанных = Новый Структура(); КонецЕсли; // Создадим пустышки внешних наборов данных, если они не переданы ОбъектТаблица = 0; Для Каждого НаборДанных Из СхемаКомпоновкиДанных.НаборыДанных Цикл Если ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда Если НаборДанных.ИмяОбъекта = "" Тогда Продолжить; КонецЕсли; Если Не ВнешниеНаборыДанных.Свойство(НаборДанных.ИмяОбъекта, ОбъектТаблица) Тогда ОбъектТаблица = Новый ТаблицаЗначений; КонецЕсли; Попытка КолонкиОбъектаТаблицы = ОбъектТаблица.Колонки; Исключение // Тогда это табличная часть, но возможно и тут будет исключение КолонкиОбъектаТаблицы = ОбъектТаблица.ВыгрузитьКолонки().Колонки; КонецПопытки; Если КолонкиОбъектаТаблицы.Количество() > 0 Тогда Продолжить; КонецЕсли; Для Каждого Поле Из НаборДанных.Поля Цикл Если ТипЗнч(Поле) = Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда Если КолонкиОбъектаТаблицы.Найти(Поле.Поле) = Неопределено Тогда КолонкиОбъектаТаблицы.Добавить(Поле.Поле, Поле.ТипЗначения); КонецЕсли; КонецЕсли; КонецЦикла; ВнешниеНаборыДанных.Вставить(НаборДанных.ИмяОбъекта, ОбъектТаблица); ИначеЕсли ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных") Тогда ДополнитьСтруктуруВнешнихНаборовДанныхПустышкамиЛкс(Новый Структура("НаборыДанных", НаборДанных.Элементы), ВнешниеНаборыДанных); КонецЕсли; КонецЦикла; Возврат ВнешниеНаборыДанных; КонецФункции Процедура ПроверитьСхемуКомпоновкиЛкс(Знач ПроверочнаяСхема, Знач НастройкаКомпоновки, Знач ПроверятьДоступностьПолей = Истина, Знач ВнешниеФункцииРазрешены = Истина, НаСервере = Ложь) Экспорт Если НаСервере Тогда ирСервер.ПроверитьСхемуКомпоновкиЛкс(СохранитьОбъектВВидеСтрокиXMLЛкс(ПроверочнаяСхема), СохранитьОбъектВВидеСтрокиXMLЛкс(НастройкаКомпоновки), ПроверятьДоступностьПолей, ВнешниеФункцииРазрешены); Иначе КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; // От(ПроверочнаяСхема, НастройкаКомпоновки); ВнешниеНаборыДанных = ДополнитьСтруктуруВнешнихНаборовДанныхПустышкамиЛкс(ПроверочнаяСхема); МакетКомпоновки = КомпоновщикМакета.Выполнить(ПроверочнаяСхема, НастройкаКомпоновки,,,, ПроверятьДоступностьПолей); // Здесь будет возникать ошибка ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных,, ВнешниеФункцииРазрешены); КонецЕсли; КонецПроцедуры // Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений. // Параметры: // СхемаКомпоновки - СхемаКомпоновкиДанных // НастройкаКомпоновки - НастройкиКомпоновкиДанных // КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений // ВнешниеНаборыДанных - Структура // ТолькоСоздатьКолонки - Булево // СхемаКолонок - Структура - Если Неопределено, то не возвращается // МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено. // ОтключитьОбщиеИтоги - Булево // РежимОтладки - Булево // Функция СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(Знач СхемаКомпоновки, Знач НастройкаКомпоновки, КоллекцияЗначений = Неопределено, Знач ВнешниеНаборыДанных = Неопределено, Знач ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено, Знач МаксимальноеЧислоСтрокРезультата = 0, Знач ОтключитьОбщиеИтоги = Истина, Знач РежимОтладки = Ложь, Знач ПроверятьДоступностьПолей = Ложь, Знач СузитьТипы = Ложь, ЗаменаТочкиВИменахКолонок = "", ВыбратьВсеДоступныеПоля = Ложь) Экспорт Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда //ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); //ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура); КонецЕсли; Если ВыбратьВсеДоступныеПоля Тогда ВыбратьВсеДоступныеПоляКомпоновки(СхемаКомпоновки, НастройкаКомпоновки); КонецЕсли; Если ОтключитьОбщиеИтоги Тогда НастройкаКомпоновки.ПараметрыВывода.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВертикальноеРасположениеОбщихИтогов"), РасположениеИтоговКомпоновкиДанных.Нет); КонецЕсли; Если Ложь Или КоллекцияЗначений = Неопределено Или ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений") Или ТипЗнч(КоллекцияЗначений) = Тип("Массив") Тогда КоллекцияРезультата = Новый ТаблицаЗначений; Иначе КоллекцияРезультата = КоллекцияЗначений; КонецЕсли; Если РежимОтладки = Истина Тогда ОтладитьЛкс(СхемаКомпоновки, Ложь, НастройкаКомпоновки, ВнешниеНаборыДанных); //Возврат Неопределено; КонецЕсли; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; Попытка МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей); Исключение //ИнформацияОбОшибке = ИнформацияОбОшибке(); //Если глКэш.ЭтоВидимоеПриложение Тогда // ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); //Иначе // ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); //КонецЕсли; ВызватьИсключение; Возврат Неопределено; КонецПопытки; //ИсследоватьЛкс(МакетКомпоновки, Ложь); //ОтладитьЛкс(МакетКомпоновки, Ложь); //Возврат Неопределено; Если МаксимальноеЧислоСтрокРезультата > 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], СтрокаКлюча); ТекстСообщения = ТекстСообщения + ". Выделены строки первого ключа"; //ЭтаФорма.ТекущийЭлемент = ТабличноеПоле; КонецЕсли; СообщитьЛкс(ТекстСообщения); КонецПроцедуры Процедура УстановитьТекстПоляСохраняяПозициюЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт НачальнаяКолонка = 0; НачальнаяСтрока = 0; КонечнаяКолонка = 0; КонечнаяСтрока = 0; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекст); ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); КонецПроцедуры Функция ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL, АдресЧужойСхемыБД = "") Экспорт Фрагменты = СтрРазделитьЛкс(ЗначениеSDBL, ":"); Если Фрагменты.Количество() < 2 Тогда Возврат Неопределено; КонецЕсли; СтрокаНомераТаблицы = Фрагменты[0]; ИдентификаторОбъекта = Фрагменты[1]; ПолноеИмяМД = ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомераТаблицы, АдресЧужойСхемыБД); ОбъектМетаданныхНайден = Истина; Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда ПолноеИмяМД = "НеизвестныйСсылочныйТип" + СтрокаНомераТаблицы; ОбъектМетаданныхНайден = Ложь; КонецЕсли; Результат = ПолноеИмяМД + "._" + ИдентификаторОбъекта; Если ОбъектМетаданныхНайден И Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда //СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(Ложь); // Этот способ не работал для перечислений //УникальныйИдентификатор = Новый УникальныйИдентификатор(ПолучитьГУИДПрямойИзИнверсногоЛкс(Фрагменты[1])); //Массив = Новый Массив(); //Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда // Массив.Добавить(УникальныйИдентификатор); //КонецЕсли; //Значение = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)), Массив); // ПустаяСсылка = Новый (Тип(ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД))); ПустаяСсылкаВнутр = ЗначениеВСтрокуВнутр(ПустаяСсылка); ФрагментыПустойСсылки = СтрРазделитьЛкс(ПустаяСсылкаВнутр, ":"); СсылкаВнутр = ФрагментыПустойСсылки[0] + ":" + ИдентификаторОбъекта + "}"; Попытка Результат = ЗначениеИзСтрокиВнутр(СсылкаВнутр); Исключение // Например, если Фрагменты[1] содержит неверное число символов КонецПопытки; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомерТаблицы, АдресЧужойСхемыБД = "") Экспорт СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(,, АдресЧужойСхемыБД); #Если Сервер И Не Сервер Тогда СтруктураБД = Новый ТаблицаЗначений; #КонецЕсли СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданныхЛкс(, АдресЧужойСхемыБД); Для Каждого СтрокаШаблона Из СловарьШаблоновМетаданных.НайтиСтроки(Новый Структура("КоличествоПараметров", 1)) Цикл ИмяКандидат = СтрЗаменить(СтрокаШаблона.ПозиционныйШаблон, "1", СтрокаНомерТаблицы); СтрокаСтруктуры = СтруктураБД.Найти(ИмяКандидат, "КраткоеИмяТаблицыХранения"); Если СтрокаСтруктуры <> Неопределено Тогда Возврат СтрокаСтруктуры.Метаданные; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции Процедура ОтладитьОтложенныйОбъектЛкс(Знач СсылкаИлиИмяФайла = Неопределено, УдалитьОбъектПослеУспешногоОткрытия = Ложь) Экспорт СтруктураПараметров = Неопределено; ирПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Ссылка = Справочники.ирОбъектыДляОтладки.ПустаяСсылка(); ирПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если СсылкаИлиИмяФайла = Неопределено Тогда ВычислительРегулярныхВыражений = ирПлатформа.RegExp; ВычислительРегулярныхВыражений.Pattern = "Объект ""([^""]+)""|Файл ""([^""]+)""|Пользователь ""([^""]+)"""; СсылкаИлиИмяФайла = ПолучитьТекстИзБуфераОбменаОСЛкс(); Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла); ЕстьСправочник = Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено; //Если Не ВвестиСтроку(СсылкаИлиИмяФайла, "Введите результат сохранения объекта") Тогда ФормаВвода = ирПлатформа.ПолучитьФорму("ОткрытьОбъектДляОтладки"); Если Результат.Count > 0 Тогда ФормаВвода.Текст = СсылкаИлиИмяФайла; КонецЕсли; СсылкаИлиИмяФайла = ФормаВвода.ОткрытьМодально(); Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда Если ЕстьСправочник Тогда СсылкаИлиИмяФайла = ВыбратьСсылкуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки,, Ложь); Иначе ПутьДляФайловОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Расширение = ПолучитьРасширениеФайловДляОтладкиЛкс(); лПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, "Файлы объектов для отладки",, ПутьДляФайловОбъектовДляОтладки); Если лПолноеИмяФайла <> Неопределено Тогда СсылкаИлиИмяФайла = "Файл """ + лПолноеИмяФайла + """"; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда Возврат; КонецЕсли; Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла); Если Результат.Count = 0 Тогда СообщитьЛкс("Введен некорректный результат сохранения объекта для отладки"); Возврат; КонецЕсли; Если Результат.Item(0).SubMatches(0) <> Неопределено Тогда Если ЕстьСправочник Тогда ВычислительРегулярныхВыражений.Pattern = "\b(" + ирПлатформа.шGUID + ")\b"; Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла); Если Результат.Count > 0 Тогда СсылкаИлиИмяФайла = Результат.Item(0).Value; Иначе СсылкаИлиИмяФайла = Неопределено; КонецЕсли; Иначе СсылкаИлиИмяФайла = Неопределено; КонецЕсли; Если СсылкаИлиИмяФайла = Неопределено Тогда СообщитьЛкс("Введен некорректный результат сохранения объекта для отладки"); Возврат; КонецЕсли; СсылкаИлиИмяФайла = Справочники.ирОбъектыДляОтладки.ПолучитьСсылку(Новый УникальныйИдентификатор(СсылкаИлиИмяФайла)); Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда СообщитьЛкс("Объект для отладки не найден в справочнике"); Возврат; КонецЕсли; ИначеЕсли Результат.Item(0).SubMatches(1) <> Неопределено Тогда СсылкаИлиИмяФайла = Результат.Item(0).SubMatches(1); Если ЕстьСправочник Тогда // Перекладываем из файла в новый элемент справочника ФайлОбъектаДляОтладки = Новый Файл(СсылкаИлиИмяФайла); ОбъектДляОтладки = ВосстановитьОбъектИзСтрокиXMLЛкс(ФайлОбъектаДляОтладки); РезультатОтложения = ОтложитьУпакованныйОбъектДляОтладкиЛкс(ОбъектДляОтладки, СсылкаИлиИмяФайла); СообщитьЛкс(РезультатОтложения); УдалитьФайлы(ФайлОбъектаДляОтладки.ПолноеИмя); КонецЕсли; ИначеЕсли Результат.Item(0).SubMatches(2) <> Неопределено Тогда ИмяПользователя = Результат.Item(0).SubMatches(2); СтруктураПараметров = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс(),, ИмяПользователя); Если СтруктураПараметров = Неопределено Тогда СообщитьЛкс("Объект для отладки не найден в общих настройках пользователя """ + ИмяПользователя + """"); Возврат; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если СтруктураПараметров = Неопределено Тогда //Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда // СтрокаРезультата = ПолучитьИзВременногоХранилища(СсылкаИлиИмяФайла); // Если СтрокаРезультата = Неопределено Тогда // СообщитьЛкс("Временное хранилище пусто. Вероятно отлаживаемый сеанс завершился."); // Возврат; // КонецЕсли; ЧтениеXML = Новый ЧтениеXML; Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда ЧтениеXML.ОткрытьФайл(СсылкаИлиИмяФайла); ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(СсылкаИлиИмяФайла) Тогда Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | ирОбъектыДляОтладки.XML |ИЗ | Справочник.ирОбъектыДляОтладки КАК ирОбъектыДляОтладки |ГДЕ | ирОбъектыДляОтладки.Ссылка = &Ссылка |"; Запрос.УстановитьПараметр("Ссылка", СсылкаИлиИмяФайла); ТаблицаРезультата = Запрос.Выполнить().Выгрузить(); Если ТаблицаРезультата.Количество() = 0 Тогда СообщитьЛкс("Объект для отладки не найден в справочнике. Вероятно он был удален."); Возврат; КонецЕсли; СтрокаРезультата = ТаблицаРезультата[0]; СтрокаРезультата = СтрокаРезультата.XML; ЧтениеXML.УстановитьСтроку(СтрокаРезультата); КонецЕсли; Попытка СтруктураПараметров = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Исключение ОписаниеОшибки = ОписаниеОшибки(); СообщитьЛкс("Некорректный объект для отладки: " + ОписаниеОшибки, СтатусСообщения.Внимание); Возврат; КонецПопытки; КонецЕсли; ОтладитьОбъектПоСтруктуреЛкс(СтруктураПараметров); Если УдалитьОбъектПослеУспешногоОткрытия Тогда Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда УдалитьФайлы(СсылкаИлиИмяФайла); Иначе УдалениеОбъекта = Новый УдалениеОбъекта(СсылкаИлиИмяФайла); УдалениеОбъекта.ОбменДанными.Загрузка = Истина; УдалениеОбъекта.Записать(); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ОтладитьОбъектПоСтруктуреЛкс(Знач СтруктураПараметров) Экспорт #Если Сервер И Не Сервер Тогда СтруктураПараметров = Новый Структура; #КонецЕсли Объект = СтруктураПараметров.Объект; Если СтруктураПараметров.Свойство("ИмяПользователя") Тогда ИмяПользователя = СтруктураПараметров.ИмяПользователя; Если ИмяПользователя <> ИмяПользователя() Тогда СообщитьЛкс("Загружаемый снимок объекта для отладки был сделан под другим пользователем (" + ИмяПользователя + ")"); КонецЕсли; КонецЕсли; ТипОперации = СтруктураПараметров.ТипОперации; Если ТипОперации = "Отладить" Тогда НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = СтруктураПараметров.НастройкаКомпоновки; Если СтруктураПараметров.Свойство("ТипОбъекта") И СтруктураПараметров.ТипОбъекта = "HttpСоединение" Тогда // Параметр ИспользоватьАутентификациюОС появился в 8.3.7 Если Объект.Защищенное Тогда ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL; Иначе ЗащищенноеСоединение = Неопределено; КонецЕсли; Объект = Вычислить("Новый HTTPСоединение(Объект.Сервер, Объект.Порт, Объект.Пользователь, Объект.Пароль,, Объект.Таймаут, ЗащищенноеСоединение, Объект.ИспользоватьАутентификациюОС)"); ЗаполнитьЗначенияСвойств(Объект, СтруктураПараметров.Объект); НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Новый ("HTTPЗапрос"); ЗаполнитьЗначенияСвойств(НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, СтруктураПараметров.НастройкаКомпоновки); ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда СтруктураЗапроса = Объект; Объект = Новый Запрос; Если Истина И СтруктураЗапроса.Свойство("ВременныеТаблицы") И СтруктураЗапроса.ВременныеТаблицы <> Неопределено Тогда Объект.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = ""; #Если Клиент Тогда СостояниеЛкс("Подготовка временных таблиц"); #КонецЕсли ТекстЗапросаПодготовки = ""; НеподдерживаемыеКолонки = ""; Для Каждого КлючИЗначение Из СтруктураЗапроса.ВременныеТаблицы Цикл Если ТекстЗапросаПодготовки <> "" Тогда ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + ";"; НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + ","; КонецЕсли; НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + КлючИЗначение.Ключ; ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КлючИЗначение.Значение, Истина); #Если Сервер И Не Сервер Тогда ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ТекстВыбораПолей = ""; СуффиксВыборПодколонки = "_ВыборПодколонки_7в989"; СуффиксПодколонкиБезТипов = "_Значение_7в989"; СуффиксПодколонкиЗначениеДляТипов = "_ЗначениеДляТипа_7в989"; ЕстьКолонкиСТипомТип = Ложь; Для ИндексКолонки = 0 По ТаблицаЗначений.Колонки.Количество() - 1 Цикл Колонка = ТаблицаЗначений.Колонки[ИндексКолонки]; // Состав коллекции расширяется, но нам нужно обойти только начальный состав Если Ложь Или Колонка.ТипЗначения.СодержитТип(Тип("МоментВремени")) Или (ирКэш.НомерРежимаСовместимостиЛкс() < 803012 И Колонка.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))) //Или Колонка.ТипЗначения.СодержитТип(Тип("Тип")) Тогда Если НеподдерживаемыеКолонки <> "" Тогда НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + ", "; КонецЕсли; НеподдерживаемыеКолонки = НеподдерживаемыеКолонки + КлючИЗначение.Ключ + "." + Колонка.Имя; ИначеЕсли Колонка.ТипЗначения.СодержитТип(Тип("Тип")) Тогда ЕстьКолонкиСТипомТип = Истина; ИмяКолонкиВыбораПодколонки = Колонка.Имя + СуффиксВыборПодколонки; ИмяКолонкиЗначениеДляТипов = Колонка.Имя + СуффиксПодколонкиЗначениеДляТипов; ИмяКолонкиБезТипов = Колонка.Имя + СуффиксПодколонкиБезТипов; ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиВыбораПодколонки, Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(10))); ОписаниеТиповКолонкиБезТипов = Новый ОписаниеТипов(Колонка.ТипЗначения,, "Тип, Null"); Если ОписаниеТиповКолонкиБезТипов.Типы().Количество() > 0 Тогда ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиБезТипов, ОписаниеТиповКолонкиБезТипов); ВыражениеПоляБезТипов = "Т." + ИмяКолонкиБезТипов; Иначе ВыражениеПоляБезТипов = "НЕОПРЕДЕЛЕНО"; КонецЕсли; ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиЗначениеДляТипов); ТекстВыбораПолей = ТекстВыбораПолей + " | , ВЫБОР КОГДА Т." + ИмяКолонкиВыбораПодколонки + " = ""Тип"" | ТОГДА ТипЗначения(Т." + ИмяКолонкиЗначениеДляТипов + ") | КОГДА Т." + ИмяКолонкиВыбораПодколонки + " = ""Null"" | ТОГДА NULL | ИНАЧЕ " + ВыражениеПоляБезТипов + " | КОНЕЦ КАК " + Колонка.Имя + " |"; Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл ЗначениеКолонки = СтрокаТаблицы[Колонка.Имя]; Если ТипЗнч(ЗначениеКолонки) = Тип("Тип") Тогда СтрокаТаблицы[ИмяКолонкиВыбораПодколонки] = "Тип"; Типы = Новый Массив; Типы.Добавить(ЗначениеКолонки); ОписаниеТипов = Новый ОписаниеТипов(Типы); СтрокаТаблицы[ИмяКолонкиЗначениеДляТипов] = ОписаниеТипов.ПривестиЗначение(); ИначеЕсли ЗначениеКолонки = Null Тогда // Моноколонку с типом NULL тоже невозможно поместить во временную таблицу из таблицы-параметра СтрокаТаблицы[ИмяКолонкиВыбораПодколонки] = "Null"; Иначе СтрокаТаблицы[ИмяКолонкиБезТипов] = ЗначениеКолонки; КонецЕсли; КонецЦикла; ТаблицаЗначений.Колонки.Удалить(Колонка.Имя); Иначе ТекстВыбораПолей = ТекстВыбораПолей + ", Т." + Колонка.Имя + " КАК " + Колонка.Имя + " |"; КонецЕсли; КонецЦикла; Если ЕстьКолонкиСТипомТип Тогда ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(ТаблицаЗначений, Истина); ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + " |ВЫБРАТЬ Т.* ПОМЕСТИТЬ _Т ИЗ &" + КлючИЗначение.Ключ + " КАК Т; |ВЫБРАТЬ " + Сред(ТекстВыбораПолей, 2) + " ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ _Т КАК Т; |УНИЧТОЖИТЬ _Т"; Иначе ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + " |ВЫБРАТЬ Т.* ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ &" + КлючИЗначение.Ключ + " КАК Т"; КонецЕсли; Объект.Параметры.Вставить(КлючИЗначение.Ключ, ТаблицаЗначений); КонецЦикла; Если НеподдерживаемыеКолонки <> "" Тогда // https://partners.v8.1c.ru/forum/t/1570237/m/1570237 ВызватьИсключение "Невозможно восстановить временные таблицы из-за недопустимых типов (МоментВремени, УникальныйИдентификатор, Тип) в колонках: " + НеподдерживаемыеКолонки; КонецЕсли; Если ЗначениеЗаполнено(ТекстЗапросаПодготовки) Тогда Объект.Текст = ТекстЗапросаПодготовки; Попытка Объект.Выполнить(); Исключение СообщитьЛкс("Ошибка восстановления временных таблиц: " + ОписаниеОшибки()); КонецПопытки; КонецЕсли; КонецЕсли; Объект.Параметры.Очистить(); Объект.Текст = СтруктураЗапроса.Текст; // Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525 //СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураЗапроса.Параметры, Объект.Параметры); Для Каждого КлючИЗначение Из СтруктураЗапроса.Параметры Цикл Объект.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеИзСтрокиВнутр(КлючИЗначение.Значение)); КонецЦикла; КонецЕсли; ОтладитьЛкс(Объект, , НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, СтруктураПараметров.ВнешниеНаборыДанных); ИначеЕсли ТипОперации = "Исследовать" Тогда Если СтруктураПараметров.Свойство("СериализацияФабрикой") И СтруктураПараметров.СериализацияФабрикой Тогда Чтение = Новый ЧтениеXML; Чтение.УстановитьСтроку(Объект); XMLТип = СериализаторXDTO.ПолучитьXMLТип(Чтение); Объект = ФабрикаXDTO.ПрочитатьXML(Чтение, ФабрикаXDTO.Тип(XMLТип.URIПространстваИмен, XMLТип.ИмяТипа)); КонецЕсли; ИсследоватьЛкс(Объект, , СтруктураПараметров.КакКоллекцию); КонецЕсли; КонецПроцедуры // ОформляемыеКолонки - имена колонок, разделенные запятыми Процедура ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля(ОформлениеСтроки, Знач ОформляемыеКолонки = "") Экспорт ирПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда ирПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ОформляемыеКолонки = Новый Структура(ОформляемыеКолонки); НеФильтровтатьКолонки = (ОформляемыеКолонки.Количество() = 0); Для Каждого Ячейка Из ОформлениеСтроки.Ячейки Цикл Если Ложь Или НеФильтровтатьКолонки Или ОформляемыеКолонки.Свойство(Ячейка.Имя) Тогда ЗначениеЯчейки = Ячейка.Значение; Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда Ячейка.УстановитьТекст(ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки)); Ячейка.ЦветФона = WebЦвета.Роса; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля() Процедура ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, РасширенноеЗначение = Null, ЛиТипСтрокаСлужебный = Ложь) Экспорт Менеджер = Неопределено; ТекущеееЗначение = ДанныеЭлементаФормыЛкс(Элемент); Если ТипЗнч(ТекущеееЗначение) = Тип("Строка") Тогда Попытка ТипЗначенияПоля = ПолучитьТипЗначенияЭлементаФормыЛкс(Элемент); Исключение Если ТипЗнч(Элемент) = Тип("ПолеВвода") Тогда ВызватьИсключение; Иначе // Для поля формы игнорируем Возврат; КонецЕсли; КонецПопытки; Типы = ТипЗначенияПоля.Типы(); Если Типы.Количество() > 1 Тогда ЗначениеСсылки = НавигационнаяСсылкаВЗначениеЛкс(ТекущеееЗначение); Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда ПредставлениеЗначения = СтрокаМеждуМаркерамиЛкс(ТекущеееЗначение, "(", ")"); ЗначениеСсылки = ПреобразоватьЗначениеИзSDBLЛкс(ПредставлениеЗначения); КонецЕсли; Если Истина И ЗначениеСсылки <> Неопределено И ТипЗнч(ЗначениеСсылки) <> Тип("Строка") И Элемент.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСсылки)) Тогда Ответ = КодВозвратаДиалога.Да; Если Не ЛиТипСтрокаСлужебный Тогда Ответ = Вопрос("Хотите вставить строку как ссылку?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет); КонецЕсли; Если Ответ = КодВозвратаДиалога.Да Тогда Значение = ЗначениеСсылки; СтандартнаяОбработка = Ложь; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда Фрагменты = СтрРазделитьЛкс(ТекущеееЗначение); Если Фрагменты.Количество() > 1 Тогда ИмяТипа = Фрагменты[0] + "." + Фрагменты[1]; Попытка ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа); Исключение ОписаниеТипов = Неопределено; КонецПопытки; Если ОписаниеТипов <> Неопределено Тогда Значение = ОписаниеТипов.ПривестиЗначение(); Менеджер = ПолучитьМенеджерЛкс(Значение); СтандартнаяОбработка = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ЛиТипСтрокаСлужебный И СтандартнаяОбработка И ЗначениеЗаполнено(ТекущеееЗначение) Тогда Значение = ""; СтандартнаяОбработка = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Если ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущеееЗначение)) Тогда Менеджер = ПолучитьМенеджерЛкс(ТекущеееЗначение); КонецЕсли; Если Менеджер <> Неопределено Тогда Значение = ПреобразоватьПредставлениеВСсылкуЛкс(Менеджер, Текст); Если Значение <> Неопределено Тогда СтандартнаяОбработка = Ложь; КонецЕсли; Иначе Если Ложь Или (Истина И РасширенноеЗначение <> Null И ТипЗнч(РасширенноеЗначение) <> ТипЗнч(ТекущеееЗначение)) Или Элемент.ОграничениеТипа.ПривестиЗначение(ТекущеееЗначение) <> ТекущеееЗначение Тогда // Откат СтандартнаяОбработка = Ложь; Значение = Новый СписокЗначений; КонецЕсли; КонецЕсли; КонецПроцедуры Функция НавигационнаяСсылкаВЗначениеЛкс(Знач ТекущеееЗначение) Экспорт //e1cib/data/Справочник.ирОбъектыДляОтладки?ref=aa3a0009dd50223411e1c2907cccb6b7 Маркер = "e1cib/data/"; ТекстСсылки = ПоследнийФрагментЛкс(ТекущеееЗначение, Маркер, Ложь); Если ЗначениеЗаполнено(ТекстСсылки) Тогда Разделитель = "?ref="; Идентификатор = ПоследнийФрагментЛкс(ТекстСсылки, Разделитель); Идентификатор = ПолучитьГУИДПрямойИзИнверсногоЛкс(Идентификатор); ПолноеИмяМД = ПервыйФрагментЛкс(ТекстСсылки, Разделитель); лМенеджер = Новый (СтрЗаменить(ПолноеИмяМД, ".", "Менеджер.")); ЗначениеСсылки = лМенеджер.ПолучитьСсылку(Новый УникальныйИдентификатор(Идентификатор)); КонецЕсли; Возврат ЗначениеСсылки; КонецФункции Функция ПреобразоватьПредставлениеВСсылкуЛкс(Знач МенеджерИлиОбъектМД, Знач Текст, КэшПоиска = Неопределено) Экспорт Если ТипЗнч(МенеджерИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда Менеджер = ПолучитьМенеджерЛкс(МенеджерИлиОбъектМД); Иначе Менеджер = МенеджерИлиОбъектМД; КонецЕсли; Текст = СокрЛП(Текст); УникальныйИдентификатор = ирКэш.Получить().ПолучитьУникальныйИдентификаторИзСтроки(Текст); Если УникальныйИдентификатор <> Неопределено Тогда Значение = Менеджер.ПолучитьСсылку(УникальныйИдентификатор); Иначе ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(Менеджер)); RegExp = ирКэш.Получить().RegExp; RegExp.Pattern = "([^ ]+)\ от\ (\d+\.\d+\.\d+\ \d+\:\d+\:\d+)$"; Результаты = RegExp.Execute(Текст); Если Результаты.Count > 0 Тогда Номер = Результаты.Item(0).Submatches(0); Дата = Результаты.Item(0).Submatches(1); Попытка Дата = Дата(Дата); Исключение Дата = Неопределено; КонецПопытки; Если Дата <> Неопределено Тогда Если КэшПоиска <> Неопределено Тогда Значение = КэшПоиска[Текст]; КонецЕсли; Если Значение = Неопределено Тогда Запрос = Новый Запрос; Запрос.Текст = " |ВЫБРАТЬ | _Т.Ссылка |ИЗ | " + ОбъектМД.ПолноеИмя() + " КАК _Т |ГДЕ | _Т.Номер = &Номер | И _Т.Дата = &Дата |"; Запрос.УстановитьПараметр("Номер", Номер); Запрос.УстановитьПараметр("Дата", Дата); Значение = Новый СписокЗначений; Значение.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0)); Если Значение.Количество() > 0 Тогда Для Каждого ЭлементСписка Из Значение Цикл ЭлементСписка.Представление = "" + ЭлементСписка.Значение + " (" + ЭлементСписка.Значение.УникальныйИдентификатор() + ")"; КонецЦикла; КонецЕсли; Если КэшПоиска <> Неопределено Тогда КэшПоиска[Текст] = Значение; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Значение; КонецФункции // Параметры: // РедактированиеРазрешено - Булево - для открытия ссылки надо установить Ложь // ЭлементУправления - Неопределено - значение этого элемента управления открываем, при открытии значения из ячейки табличного поля должно быть Неопределено // ЭлементУправленияРодитель - ТабличноеПоле - чью ячейку открываем // Результат - Булево - Истина если значение было изменено Функция ОткрытьЗначениеЛкс(РасширенноеЗначение, РедактированиеРазрешено = Истина, СтандартнаяОбработка = Истина, ЗаголовокФормы = "", РедактироватьМодально = Истина, ПринудительноВОтдельнойФорме = Истина, ЭлементУправления = Неопределено, ЭлементУправленияРодитель = Неопределено) Экспорт Результат = Ложь; ТипРасширенногоЗначения = ТипЗнч(РасширенноеЗначение); ХмлТип = XMLТипЗнч(РасширенноеЗначение); Если Ложь Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений") Или ТипРасширенногоЗначения = Тип("ДеревоЗначений") Или ТипРасширенногоЗначения = Тип("МоментВремени") Или ТипРасширенногоЗначения = Тип("ТабличныйДокумент") Или ТипРасширенногоЗначения = Тип("Массив") Или ТипРасширенногоЗначения = Тип("Граница") Или ТипРасширенногоЗначения = Тип("УникальныйИдентификатор") Или ТипРасширенногоЗначения = Тип("Тип") Или ТипРасширенногоЗначения = Тип("ОписаниеТипов") Или ТипРасширенногоЗначения = Тип("СписокЗначений") Или ТипРасширенногоЗначения = Тип("ДвоичныеДанные") Или ТипРасширенногоЗначения = Тип("ХранилищеЗначения") Или ТипРасширенногоЗначения = Тип("Картинка") Или (Истина И ТипРасширенногоЗначения = Тип("Строка") И (Ложь Или ПринудительноВОтдельнойФорме Или СтрДлина(РасширенноеЗначение) > 150 Или Не РедактированиеРазрешено)) Тогда СтандартнаяОбработка = Ложь; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если Ложь Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений") Или ТипРасширенногоЗначения = Тип("ДеревоЗначений") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , РасширенноеЗначение); ФормаРедактирования.ТабличноеПоле = ЭлементУправления; ИначеЕсли ТипРасширенногоЗначения = Тип("МоментВремени") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("МоментВремени", , РасширенноеЗначение); ИначеЕсли ТипРасширенногоЗначения = Тип("ТабличныйДокумент") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("ТабличныйДокумент", , РасширенноеЗначение); Если ЭлементУправления <> Неопределено Тогда ФормаРедактирования.ПолеТабличногоДокумента = ЭлементУправления; Иначе ФормаРедактирования.ПолеТабличногоДокумента = РасширенноеЗначение; КонецЕсли; ИначеЕсли ТипРасширенногоЗначения = Тип("Граница") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("Граница", , РасширенноеЗначение); ИначеЕсли ТипРасширенногоЗначения = Тип("Массив") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("Массив", , РасширенноеЗначение); ИначеЕсли ТипРасширенногоЗначения = Тип("УникальныйИдентификатор") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("УникальныйИдентификатор", , РасширенноеЗначение); ИначеЕсли ТипРасширенногоЗначения = Тип("СписокЗначений") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("СписокЗначений", , РасширенноеЗначение); ИначеЕсли ТипРасширенногоЗначения = Тип("Строка") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("Текст", , Новый УникальныйИдентификатор()); ИначеЕсли ТипРасширенногоЗначения = Тип("Тип") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , ТипРасширенногоЗначения); ФормаРедактирования.РежимВыбора = Истина; ФормаРедактирования.МножественныйВыбор = Ложь; ИначеЕсли ТипРасширенногоЗначения = Тип("ОписаниеТипов") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("ВыборРедактируемыхТипов", , РасширенноеЗначение); ФормаРедактирования.РежимВыбора = Истина; ФормаРедактирования.МножественныйВыбор = Истина; ИначеЕсли ТипРасширенногоЗначения = Тип("ХранилищеЗначения") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("ХранилищеЗначения", , Новый УникальныйИдентификатор()); ИначеЕсли ТипРасширенногоЗначения = Тип("ДвоичныеДанные") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("ДвоичныеДанные", , Новый УникальныйИдентификатор()); ИначеЕсли ТипРасширенногоЗначения = Тип("Картинка") Тогда ФормаРедактирования = мПлатформа.ПолучитьФорму("Картинка", , Новый УникальныйИдентификатор()); КонецЕсли; Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда ФормаРедактирования.Заголовок = ЗаголовокФормы; КонецЕсли; Если ФормаРедактирования.Открыта() Тогда ФормаРедактирования.Активизировать(); Возврат Результат; КонецЕсли; ФормаРедактирования.ТолькоПросмотр = Не РедактированиеРазрешено; Если РедактированиеРазрешено Тогда ФормаРедактирования.НачальноеЗначениеВыбора = КопияОбъектаЛкс(РасширенноеЗначение, ); // Опасно Иначе ФормаРедактирования.НачальноеЗначениеВыбора = РасширенноеЗначение; КонецЕсли; Если РедактированиеРазрешено И РедактироватьМодально Тогда РезультатВыбора = ФормаРедактирования.ОткрытьМодально(); Если РезультатВыбора <> Неопределено Тогда РасширенноеЗначение = РезультатВыбора; Результат = Истина; КонецЕсли; Иначе ФормаРедактирования.Открыть(); КонецЕсли; ИначеЕсли Ложь Или ТипРасширенногоЗначения = Тип("Число") Или ТипРасширенногоЗначения = Тип("Строка") Или ТипРасширенногоЗначения = Тип("Дата") Или ТипРасширенногоЗначения = Тип("Булево") Или ТипРасширенногоЗначения = Тип("Неопределено") Или ТипРасширенногоЗначения = Тип("Null") Или ТипРасширенногоЗначения = Тип("ПолеКомпоновкиДанных") Или ТипРасширенногоЗначения = Тип("СтандартнаяДатаНачала") Или ТипРасширенногоЗначения = Тип("СтандартныйПериод") Или ТипРасширенногоЗначения = Тип("ВидДвиженияНакопления") Или ТипРасширенногоЗначения = Тип("ВидДвиженияБухгалтерии") Или ТипРасширенногоЗначения = Тип("ВидСчета") Или (Истина И ХмлТип <> Неопределено И Найти(ХмлТип.ИмяТипа, "Ref.") > 0) Тогда Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда Если ЗначениеЗаполнено(РасширенноеЗначение) Тогда ОбъектСуществует = ЛиСуществуетОбъектПоСсылкеЛкс(РасширенноеЗначение); Если Не ОбъектСуществует И Не ПринудительноВОтдельнойФорме Тогда //ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле); ОткрытьСсылкуВРедактореОбъектаБДЛкс(РасширенноеЗначение); СтандартнаяОбработка = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Если Ложь Или Не СтандартнаяОбработка Или Не РедактированиеРазрешено Или ЭлементУправленияРодитель = Неопределено Тогда Если ЛиТипСсылкиБДЛкс(ТипРасширенногоЗначения, Ложь) Тогда Если Истина И ЗначениеЗаполнено(РасширенноеЗначение) И ОбъектСуществует Тогда ОткрытьЗначение(РасширенноеЗначение); КонецЕсли; СтандартнаяОбработка = Ложь; КонецЕсли; Если СтандартнаяОбработка Тогда ОткрытьЗначение(РасширенноеЗначение); СтандартнаяОбработка = Ложь; КонецЕсли; КонецЕсли; Иначе //Если Истина // И ТипЗначения1 <> Неопределено // И ТипЗначения1.ПривестиЗначение(РасширенноеЗначение) <> РасширенноеЗначение //Тогда ИсследоватьЛкс(РасширенноеЗначение); СтандартнаяОбработка = Ложь; //КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ВыбратьСтрокуТаблицыЗначенийЛкс(Знач ТаблицаЗначений, Знач ТекущаяСтрока = Неопределено, Модально = Истина, Заголовок = "") Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ИмитаторТабличногоПоля = Новый Структура; ИмитаторТабличногоПоля.Вставить("ТекущаяКолонка"); ИмитаторТабличногоПоля.Вставить("ТекущаяСтрока", ТекущаяСтрока); ИмитаторТабличногоПоля.Вставить("Значение", ТаблицаЗначений); ИмитаторТабличногоПоля.Вставить("ВыделенныеСтроки", Новый Массив); ФормаРедактирования = мПлатформа.ПолучитьФорму("ТаблицаЗначений", , ТаблицаЗначений); ФормаРедактирования.ТабличноеПоле = ИмитаторТабличногоПоля; ФормаРедактирования.НачальноеЗначениеВыбора = ТаблицаЗначений; ФормаРедактирования.ТолькоПросмотр = Истина; Если ЗначениеЗаполнено(Заголовок) Тогда ФормаРедактирования.Заголовок = Заголовок; КонецЕсли; ФормаРедактирования.РежимВыбора = Истина; Если Модально Тогда Результат = ФормаРедактирования.ОткрытьМодально(); Иначе ФормаРедактирования.Открыть(); КонецЕсли; Возврат Результат; КонецФункции Функция ВыбратьЭлементСпискаЗначенийЛкс(Знач СписокЗначений, Знач ТекущийЭлемент = Неопределено, Модально = Истина, Заголовок = "") Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаРедактирования = мПлатформа.ПолучитьФорму("СписокЗначений", , СписокЗначений); ФормаРедактирования.НачальноеЗначениеВыбора = СписокЗначений; ФормаРедактирования.НачальныйЭлементСписка = ТекущийЭлемент; ФормаРедактирования.ТолькоПросмотр = Истина; Если ЗначениеЗаполнено(Заголовок) Тогда ФормаРедактирования.Заголовок = Заголовок; КонецЕсли; ФормаРедактирования.РежимВыбора = Истина; Если Модально Тогда Результат = ФормаРедактирования.ОткрытьМодально(); Иначе ФормаРедактирования.Открыть(); КонецЕсли; Возврат Результат; КонецФункции Функция ЛиСуществуетОбъектПоСсылкеЛкс(Знач РасширенноеЗначение) Экспорт Запрос = Новый Запрос("ВЫБРАТЬ 1 ИЗ " + ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)) + " ГДЕ Ссылка = &Ссылка"); Запрос.УстановитьПараметр("Ссылка", РасширенноеЗначение); ОбъектСуществует = Не Запрос.Выполнить().Пустой(); Возврат ОбъектСуществует; КонецФункции Функция ОткрытьРедакторИзПоляТабличногоДокументаЛкс(ПолеТабличногоДокумента) Экспорт Копия = Новый ТабличныйДокумент; Копия.Вывести(ПолеТабличногоДокумента); ЗаполнитьЗначенияСвойств(Копия, ПолеТабличногоДокумента); Результат = ирОбщий.ОткрытьЗначениеЛкс(Копия,,,, Ложь); Возврат Результат; КонецФункции Функция ОткрытьРедакторСтрокиТаблицыЛкс(ЭтаФорма, ТабличноеПоле, ИмяТаблицыБДТабличногоПоля = Неопределено, СвязиИПараметрыВыбора = Истина) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Форма = мПлатформа.ПолучитьФорму("СтрокаТаблицы", ЭтаФорма, ТабличноеПоле); Форма.ИмяТаблицыБД = ИмяТаблицыБДТабличногоПоля; Форма.СвязиИПараметрыВыбора = СвязиИПараметрыВыбора; Форма.Открыть(); Возврат Форма; КонецФункции Процедура ОткрытьФайлВПроводникеЛкс(Знач ИмяФайла) Экспорт ЗапуститьПриложение("explorer /select, """ + ИмяФайла + """"); КонецПроцедуры // Результат - Булево - Истина если значение было изменено Функция ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка = Ложь, РасширенноеЗначение = Null, РедактированиеРазрешено = Истина, ПринудительноВОтдельнойФорме = Ложь, Данные = "") Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда Колонка = ТабличноеПоле.ТекущаяКолонка; ЭлементУправления = Колонка.ЭлементУправления; Иначе Колонка = ТабличноеПоле.ТекущийЭлемент; ЭлементУправления = Колонка; КонецЕсли; Если Не ЗначениеЗаполнено(Данные) Тогда Данные = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; Если РасширенноеЗначение = Null Тогда Если Не ЗначениеЗаполнено(Данные) Тогда Возврат Ложь; КонецЕсли; РасширенноеЗначение = ТабличноеПоле.ТекущиеДанные[Данные]; КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") И ТабличноеПоле.ТекущаяСтрока <> Неопределено Тогда ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ТабличноеПоле.ТекущаяСтрока); Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя]; РедактированиеРазрешено = РедактированиеРазрешено И Не Ячейка.ТолькоПросмотр; КонецЕсли; РедактированиеРазрешено = Истина И РедактированиеРазрешено И Не ТабличноеПоле.ТолькоПросмотр И Не Колонка.ТолькоПросмотр И (Ложь Или ЭлементУправления = Неопределено Или ТипЗнч(ЭлементУправления) = Тип("Флажок") Или Не ЭлементУправления.ТолькоПросмотр); Если РедактированиеРазрешено Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзЗначения(РасширенноеЗначение); Попытка СвойствоГлобальногоКонтекста = Вычислить(СтруктураТипа.ИмяОбщегоТипа); Исключение СвойствоГлобальногоКонтекста = Неопределено; КонецПопытки; Если СвойствоГлобальногоКонтекста <> Неопределено Тогда мПлатформа.ИнициализацияОписанияМетодовИСвойств(); СписокВыбора = Новый СписокЗначений; #Если Сервер И Не Сервер Тогда СписокВыбора = Новый СписокЗначений; #КонецЕсли НачальныйВыбор = Неопределено; СтрокиЗначений = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "Перечисление" + СтруктураТипа.ИмяОбщегоТипа)); Для Каждого СтрокаЗначения Из СтрокиЗначений Цикл ЗначениеПеречисления = Вычислить(СтруктураТипа.ИмяОбщегоТипа + "." + СтрокаЗначения.Слово); ЭлементСписка = СписокВыбора.Добавить(ЗначениеПеречисления); Если РасширенноеЗначение = ЗначениеПеречисления Тогда НачальныйВыбор = ЭлементСписка; КонецЕсли; КонецЦикла; РезультатВыбора = ЭтаФорма.ВыбратьИзСписка(СписокВыбора, ЭлементУправления, НачальныйВыбор); Результат = РезультатВыбора <> Неопределено; Если Результат Тогда РасширенноеЗначение = РезультатВыбора.Значение; КонецЕсли; КонецЕсли; КонецЕсли; Если Результат = Неопределено Тогда Результат = ОткрытьЗначениеЛкс(РасширенноеЗначение, РедактированиеРазрешено, СтандартнаяОбработка,,, ПринудительноВОтдельнойФорме,, ТабличноеПоле); КонецЕсли; Если Результат Тогда НовоеЗначение = РасширенноеЗначение; // Сохраняем значение, т.к. оно может испортиться следующей строкой ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени, УникальныйИдентификатор) РасширенноеЗначение = НовоеЗначение; КонецЕсли; Возврат Результат; КонецФункции // ОткрытьЗначениеЯчейки() // Результат - Булево - Истина если значение было изменено Функция ПолеВводаРасширенногоЗначения_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, РасширенноеЗначение = Null) Экспорт Если РасширенноеЗначение = Null Тогда РасширенноеЗначение = Элемент.Значение; КонецЕсли; ЗначениеИзменено = Ложь; Если РасширенноеЗначение = Неопределено Тогда СтандартнаяОбработка = Ложь; ОграничениеТипа = Элемент.ОграничениеТипа; НовыйТипИлиЗначение = ирОбщий.ВыбратьРедактируемыйТипЛкс(ОграничениеТипа); Если НовыйТипИлиЗначение <> Неопределено Тогда Если ТипЗнч(НовыйТипИлиЗначение) = Тип("Тип") Тогда МассивТипов = ирОбщий.БыстрыйМассивЛкс(НовыйТипИлиЗначение); НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов); НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено); Иначе НовоеЗначение = НовыйТипИлиЗначение; КонецЕсли; РасширенноеЗначение = НовоеЗначение; Элемент.Значение = РасширенноеЗначение; // ЗначениеИзменено = Истина; КонецЕсли; Иначе Если Истина И ТипЗнч(Элемент.Значение) = Тип("СписокЗначений") И ТипЗнч(РасширенноеЗначение) = Тип("СписокЗначений") Тогда РасширенноеЗначение.ТипЗначения = Элемент.ТипЗначенияСписка; КонецЕсли; Результат = ирОбщий.ОткрытьЗначениеЛкс(РасширенноеЗначение, Истина, СтандартнаяОбработка); Если Результат Тогда Элемент.Значение = РасширенноеЗначение; КонецЕсли; Если Не СтандартнаяОбработка Тогда Элемент.Значение = РасширенноеЗначение; КонецЕсли; КонецЕсли; Возврат ЗначениеИзменено; КонецФункции // Результат - Булево - Истина если значение было изменено Функция ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение = Null, ИспользоватьОграничениеТипа = Ложь, СтруктураОтбора = Неопределено, Данные = "") Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда Колонка = ТабличноеПоле.ТекущаяКолонка; ЭлементУправления = Колонка.ЭлементУправления; Иначе Колонка = ТабличноеПоле.ТекущийЭлемент; ЭлементУправления = Колонка; КонецЕсли; Если Не ЗначениеЗаполнено(Данные) Тогда Данные = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); РазрешитьВыборТипа = Истина; Иначе РазрешитьВыборТипа = Ложь; КонецЕсли; Если РасширенноеЗначение = Null Тогда РасширенноеЗначение = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле)[Данные]; КонецЕсли; ЗначениеИзменено = Ложь; Если РасширенноеЗначение = Неопределено Тогда Если Не РазрешитьВыборТипа Тогда Возврат ЗначениеИзменено; КонецЕсли; СтандартнаяОбработка = Ложь; ОграничениеТипа = Неопределено; Если ИспользоватьОграничениеТипа Тогда ОграничениеТипа = ЭлементУправления.ОграничениеТипа; Если Истина И ОграничениеТипа.Типы().Количество() = 0 И ТипЗнч(ЭлементУправления) = Тип("ПолеФормы") И ЗначениеЗаполнено(ЭлементУправления.СвязьПоТипу.ПутьКДанным) Тогда ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ЭлементУправления); Попытка ОграничениеТипа = Вычислить("ЭтаФорма." + ЭлементУправления.СвязьПоТипу.ПутьКДанным); Исключение ВызватьИсключение "Ошибка вычисления влияющего типа поля: " + ОписаниеОшибки(); КонецПопытки; КонецЕсли; Если ОграничениеТипа.Типы().Количество() = 0 Тогда ОграничениеТипа = ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементУправления); КонецЕсли; КонецЕсли; НовыйТипИлиЗначение = ВыбратьРедактируемыйТипЛкс(ОграничениеТипа); Если НовыйТипИлиЗначение <> Неопределено Тогда Если ТипЗнч(НовыйТипИлиЗначение) = Тип("Тип") Тогда МассивТипов = БыстрыйМассивЛкс(НовыйТипИлиЗначение); НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов); НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено); Иначе НовоеЗначение = НовыйТипИлиЗначение; КонецЕсли; ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение); // Почему то запрещенные для поля ввода значения здесь превращаются в строку (например МоментВремени) РасширенноеЗначение = НовоеЗначение; ЗначениеИзменено = Истина; //// http://www.hostedredmine.com/issues/884276 //Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда // ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, ЭлементУправления, Истина,, РасширенноеЗначение); //КонецЕсли; КонецЕсли; КонецЕсли; Если РасширенноеЗначение <> Неопределено Тогда Если Не ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда ЗначениеИзменено = ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение, Истина, Истина, Данные) Или ЗначениеИзменено; КонецЕсли; //Если ЗначениеИзменено Тогда Если Не СтандартнаяОбработка Тогда ТабличноеПоле.ТекущиеДанные[Данные] = РасширенноеЗначение;// КонецЕсли; Если СтандартнаяОбработка Тогда Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РасширенноеЗначение)), СтруктураОтбора,, ЭлементУправления, Истина,, РасширенноеЗначение); СтандартнаяОбработка = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ЗначениеИзменено; КонецФункции // Нужно вызывать после установки признака ТолькоПросмотр ячеек. // ИменаКолонокСПиктограммамиТипов - Массив, Строка Процедура ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки, КнопкаРежимаОтображения = Неопределено, Знач ИменаКолонокСПиктограммамиТипов = "", РасширенныеКолонки = Неопределено, РасширенноеПредставлениеХранилищЗначений = Ложь, Знач РасширенныеДанныеСтроки = Неопределено) Экспорт Если ДанныеСтроки = Неопределено Тогда Возврат; КонецЕсли; КолонкиТаблицы = Элемент.Колонки; Если КнопкаРежимаОтображения <> Неопределено Тогда ВариантОтображенияИдентификаторов = КнопкаРежимаОтображения.Текст; КонецЕсли; Ячейки = ОформлениеСтроки.Ячейки; Если РасширенныеДанныеСтроки = Неопределено Тогда РасширенныеДанныеСтроки = ДанныеСтроки; КонецЕсли; СостоянияКнопки = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс(); ЛиОтбражатьПустые = Ложь Или ВариантОтображенияИдентификаторов = СостоянияКнопки[1] Или ВариантОтображенияИдентификаторов = СостоянияКнопки[2]; ОтображатьИдентификаторы = Ложь Или ВариантОтображенияИдентификаторов = СостоянияКнопки[2]; ирПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда ирПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если ТипЗнч(ИменаКолонокСПиктограммамиТипов) = Тип("Строка") Тогда ИменаКолонокСПиктограммамиТипов = СтрРазделитьЛкс(ИменаКолонокСПиктограммамиТипов, ",", Истина); КонецЕсли; Для Каждого Колонка Из КолонкиТаблицы Цикл Если Не Колонка.Видимость Тогда Продолжить; КонецЕсли; Ячейка = Ячейки[Колонка.Имя]; КартинкаЯчейки = Неопределено; КолонкаДанных = Неопределено; Если РасширенныеКолонки <> Неопределено Тогда РасширенныеКолонки.Свойство(Колонка.Имя, КолонкаДанных); КонецЕсли; КолонкаОтображаетДанныеФлажка = Ложь; Если КолонкаДанных <> Неопределено Тогда ЗначениеЯчейки = РасширенныеДанныеСтроки[КолонкаДанных]; Иначе Если Истина И Не ЗначениеЗаполнено(Колонка.Данные) И ЗначениеЗаполнено(Колонка.ДанныеФлажка) Тогда ЗначениеЯчейки = Ячейка.ЗначениеФлажка; КолонкаОтображаетДанныеФлажка = Истина; Иначе ЗначениеЯчейки = Ячейка.Значение; КонецЕсли; КонецЕсли; Если Истина И Не КолонкаОтображаетДанныеФлажка И ТипЗнч(ЗначениеЯчейки) = Тип("Булево") И ТипЗнч(Колонка.ЭлементУправления) <> Тип("ПолеВыбора") // Колонка "Вид" таблицы "Параметры" в консоли запросов Тогда Если Истина И Не ЛиОтбражатьПустые И Не ОтображатьИдентификаторы И ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) = Неопределено Тогда Ячейка.УстановитьТекст(""); Иначе Ячейка.УстановитьТекст("" + ЗначениеЯчейки); КонецЕсли; Если Не Ячейка.ТолькоПросмотр И Колонка.ЭлементУправления <> Неопределено Тогда Ячейка.УстановитьФлажок(ЗначениеЯчейки); ИначеЕсли ЗначениеЯчейки = Истина И Ячейка.Текст = "" Тогда КартинкаЯчейки = ирКэш.КартинкаПоИмениЛкс("ирФлажокТолькоПросмотр"); КонецЕсли; КонецЕсли; ПредставлениеЗначения = ""; Если Истина И Не КолонкаОтображаетДанныеФлажка И ТипЗнч(ЗначениеЯчейки) <> Тип("Строка") И ЗначениеЯчейки <> Неопределено И (Ложь Или РасширенноеПредставлениеХранилищЗначений Или ТипЗнч(ЗначениеЯчейки) = Тип("ОписаниеТипов") Или XMLТипЗнч(ЗначениеЯчейки) = Неопределено) Тогда ПредставлениеЗначения = РасширенноеПредставлениеЗначенияЛкс(ЗначениеЯчейки, Колонка,, РасширенноеПредставлениеХранилищЗначений, Ложь); КонецЕсли; Если ЛиОтбражатьПустые Тогда Если ТипЗнч(ЗначениеЯчейки) = Тип("Строка") Тогда ПредставлениеЗначения = """" + ЗначениеЯчейки + """"; Ячейка.ЦветФона = ЦветФонаЯчеекПустыхЗначенийЛкс(); ИначеЕсли Не ЭтоКоллекцияЛкс(ЗначениеЯчейки) Тогда Попытка ЗначениеНепустое = ЗначениеЗаполнено(ЗначениеЯчейки) И ЗначениеЯчейки <> Ложь; Исключение ЗначениеНепустое = Истина; КонецПопытки; Если Не ЗначениеНепустое Тогда ПредставлениеЗначения = ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки); Ячейка.ЦветФона = ЦветФонаЯчеекПустыхЗначенийЛкс(); КонецЕсли; КонецЕсли; КонецЕсли; Если ПредставлениеЗначения <> "" Тогда Если Ложь Или КолонкаОтображаетДанныеФлажка Или Формат(ЗначениеЯчейки, Колонка.Формат) = Ячейка.Текст // Здесь могут быть обращения к БД Тогда Ячейка.УстановитьТекст(ПредставлениеЗначения); КонецЕсли; КонецЕсли; Если ОтображатьИдентификаторы Тогда ИдентификаторСсылки = ПолучитьИдентификаторСсылкиЛкс(ЗначениеЯчейки, Истина); Если ИдентификаторСсылки <> Неопределено Тогда Ячейка.УстановитьТекст(ИдентификаторСсылки); КонецЕсли; КонецЕсли; Если КартинкаЯчейки = Неопределено И ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) <> Неопределено Тогда Если ТипЗнч(ЗначениеЯчейки) <> Тип("ПолеКомпоновкиДанных") Тогда ТипЗначения = ТипЗнч(ЗначениеЯчейки); Если Не ( Истина И ТипЗначения = Тип("Булево") И Ячейка.ОтображатьФлажок) Тогда КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения); Если КартинкаТипа <> Неопределено Тогда КартинкаЯчейки = КартинкаТипа; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если КартинкаЯчейки <> Неопределено Тогда Ячейка.УстановитьКартинку(КартинкаЯчейки); КонецЕсли; КонецЦикла; ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс(); Если Ячейки.Найти(ИмяКолонкиНомерСтроки) <> Неопределено Тогда Если ТипЗнч(ДанныеСтроки) = Тип("СтрокаДереваЗначений") Тогда ИндексСтроки = ПолучитьРодителяСтрокиДереваЛкс(ДанныеСтроки, ДанныеСтроки.Владелец()).Строки.Индекс(ДанныеСтроки); Иначе ИндексСтроки = ДанныеСтроки.Владелец().Индекс(ДанныеСтроки); КонецЕсли; Ячейки[ИмяКолонкиНомерСтроки].УстановитьТекст(XMLСтрока(ИндексСтроки + 1)); Ячейки[ИмяКолонкиНомерСтроки].ЦветТекста = Новый Цвет(128, 128, 128); КонецЕсли; Если ТипЗнч(ДанныеСтроки) = Тип("ТекущиеДанныеСписка") Тогда ЭтоВыводТекущейСтроки = Ложь; Если Элемент.ТекущиеДанные <> Неопределено Тогда ЭтоВыводТекущейСтроки = Истина; ИмяТаблицыБД = ИмяТаблицыБДДинамическогоСпискаЛкс(Элемент); КлючСтроки = СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыБД); #Если Сервер И Не Сервер Тогда КлючСтроки = Новый Структура; #КонецЕсли Для Каждого КлючИЗначение Из КлючСтроки Цикл Если ДанныеСтроки[КлючИЗначение.Ключ] <> Элемент.ТекущиеДанные[КлючИЗначение.Ключ] Тогда ЭтоВыводТекущейСтроки = Ложь; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; ИначеЕсли ТипЗнч(ДанныеСтроки) = Тип("ТекущиеДанныеСтруктурыНастроекКомпоновкиДанных") Тогда ЭтоВыводТекущейСтроки = Элемент.ТекущаяСтрока = ДанныеСтроки.Строка; Иначе ЭтоВыводТекущейСтроки = Элемент.ТекущаяСтрока = ДанныеСтроки; КонецЕсли; Если ЭтоВыводТекущейСтроки Тогда СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); #Если Сервер И Не Сервер Тогда СлужебныеДанныеФормы = Новый Структура; #КонецЕсли Если СлужебныеДанныеФормы.Свойство("ТекущиеСтроки") Тогда ТекущиеСтрокиФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма).ТекущиеСтроки; #Если Сервер И Не Сервер Тогда ТекущиеСтрокиФормы = Новый Структура; #КонецЕсли Если ТекущиеСтрокиФормы.Свойство(Элемент.Имя) Тогда ТекущийЦветФона = ОформлениеСтроки.ЦветФона; Если ТекущийЦветФона.Вид = ВидЦвета.АвтоЦвет Тогда ТекущийЦветФона = Элемент.ЦветФонаПоля; КонецЕсли; ОформлениеСтроки.ЦветФона = СмещенныйЦветЛкс(ТекущийЦветФона); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Функция СмещенныйЦветЛкс(Знач ТекущийЦветФона, СмещениеКрасный = -20, СмещениеЗеленый = 0, СмещениеСиний = -20) Экспорт Если ТекущийЦветФона.Вид = ВидЦвета.АвтоЦвет Тогда ТекущийЦветФона = ЦветаСтиля.ЦветФонаПоля; КонецЕсли; АбсолютныйЦвет = ирКэш.АбсолютныйЦветЛкс(ЗначениеВСтрокуВнутр(ТекущийЦветФона)); #Если Сервер И Не Сервер Тогда АбсолютныйЦвет = Новый Цвет; #КонецЕсли СмещенныйЦвет = Новый Цвет(Макс(0, АбсолютныйЦвет.Красный + СмещениеКрасный), Макс(0, АбсолютныйЦвет.Зеленый + СмещениеЗеленый), Макс(АбсолютныйЦвет.Синий + СмещениеСиний)); Возврат СмещенныйЦвет; КонецФункции Процедура ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент) Экспорт Если Элемент = Неопределено Тогда Возврат; КонецЕсли; СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); #Если Сервер И Не Сервер Тогда СлужебныеДанныеФормы = Новый Структура; #КонецЕсли Если Не СлужебныеДанныеФормы.Свойство("ТекущиеСтроки") Тогда СлужебныеДанныеФормы.Вставить("ТекущиеСтроки", Новый Структура); КонецЕсли; ТекущиеСтрокиФормы = СлужебныеДанныеФормы.ТекущиеСтроки; #Если Сервер И Не Сервер Тогда ТекущиеСтрокиФормы = Новый Структура; #КонецЕсли Если ТекущиеСтрокиФормы.Свойство(Элемент.Имя) Тогда СтараяТекущаяСтрока = ТекущиеСтрокиФормы[Элемент.Имя]; Если СтараяТекущаяСтрока <> Неопределено Тогда Элемент.ОбновитьСтроки(СтараяТекущаяСтрока); КонецЕсли; КонецЕсли; Если Элемент.ТекущаяСтрока <> Неопределено Тогда Элемент.РежимВыделенияСтроки = РежимВыделенияСтрокиТабличногоПоля.Ячейка; ТекущиеСтрокиФормы.Вставить(Элемент.Имя, Неопределено); Элемент.ОбновитьСтроки(Элемент.ТекущаяСтрока); КонецЕсли; ТекущиеСтрокиФормы.Вставить(Элемент.Имя, Элемент.ТекущаяСтрока); ИндексКолонки = 0; Пока Элемент.ТекущаяКолонка = Неопределено И Элемент.Колонки.Количество() > ИндексКолонки Цикл // Антибаг платформы 8.3.17 https://partners.v8.1c.ru/forum/t/1919341/m/1919341 http://www.hostedredmine.com/issues/877079 КолонкаТП = Элемент.Колонки[ИндексКолонки]; Если КолонкаТП.Доступность И КолонкаТП.Видимость Тогда Элемент.ТекущаяКолонка = КолонкаТП; КонецЕсли; ИндексКолонки = ИндексКолонки + 1; КонецЦикла; // Переключаем цветовую схему на старый вариант (без градиентов и с подсветкой текущей колонки) https://partners.v8.1c.ru/forum/t/898034/m/898082 Если Элемент.Колонки.Количество() > 0 И Элемент.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда Элемент.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки; КонецЕсли; ТабличноеПолеОбновитьТекстыПодваловЛкс(Элемент); КонецПроцедуры Процедура ИнтерактивноЗаписатьВКолонкуФлажкаЛкс(Знач Элемент, Знач Колонка, Знач НовоеЗначение) Экспорт ирОбщий.ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, НовоеЗначение,, Ложь,,, Истина); КонецПроцедуры Процедура УстановитьФокусВводаФормеЛкс(ФормаВладелец) Экспорт // Для обхода ошибок платформы. Форма при закрытии может вернуть фокус ввода главному окну вместо отображаемому на переднем плане дочернему окну. ФормаВладелец.Открыть(); мПлатформа = ирКэш.Получить(); ФормаПустышка = мПлатформа.ПолучитьФорму("Пустышка"); ФормаПустышка.Открыть(); ФормаПустышка.Закрыть(); КонецПроцедуры Процедура ТабличноеПолеОтбораКомпоновкиПеретаскиваниеЛкс(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка) Экспорт Если Истина И ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Массив") И ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда ТипЭлемента = ТипЗнч(ПараметрыПеретаскивания.Значение[0]); Если Ложь Или ТипЭлемента = Тип("ДоступноеПолеКомпоновкиДанных") Или ТипЭлемента = Тип("ДоступноеПолеОтбораКомпоновкиДанных") Тогда Если Истина И Строка <> Неопределено И Колонка <> Неопределено И Найти(Колонка.Данные, "ПравоеЗначение") = 1 Тогда СтандартнаяОбработка = Ложь; Строка.ПравоеЗначение = ПараметрыПеретаскивания.Значение[0].Поле; //ИначеЕсли Найти(Колонка.Данные, "ЛевоеЗначение") = 1 Тогда // Удобнее штатным способом добавлять новый элемент сразу в нужную позицию // СтандартнаяОбработка = Ложь; // Строка.ЛевоеЗначение = ПараметрыПеретаскивания.Значение[0].Поле; Иначе //Если ТипЗнч(Строка) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда // Родитель = ПолучитьРодителяСтрокиДереваЛкс(Строка, Элемент.Значение); //ИначеЕсли ТипЗнч(Строка) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда // Родитель = Строка; //Иначе // Родитель = Элемент.Значение; //КонецЕсли; //Для Каждого ДоступноеПоле Из ПараметрыПеретаскивания.Значение Цикл // #Если Сервер И Не Сервер Тогда // ДоступноеПоле = Новый НастройкиКомпоновкиДанных; // ДоступноеПоле = ДоступноеПоле.Выбор.ДоступныеПоляВыбора.НайтиПоле(); // #КонецЕсли // НовыйЭлемент = Родитель.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); // НовыйЭлемент.Использование = Истина; // НовыйЭлемент.ЛевоеЗначение = ДоступноеПоле.Поле; // Элемент.ТекущаяСтрока = НовыйЭлемент; //КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Функция ПолныйИдентификаторСсылкиЛкс(Знач ЗначениеЯчейки) Экспорт ИдентификаторСсылки = ПолучитьИдентификаторСсылкиЛкс(ЗначениеЯчейки); Возврат ИдентификаторСсылки; КонецФункции Функция ПолучитьИдентификаторЗначенияЛкс(Значение) Экспорт ИдентификаторЗначения = ПолучитьИдентификаторСсылкиЛкс(Значение); Если ИдентификаторЗначения = Неопределено Тогда ИдентификаторЗначения = Формат(Значение, "ЧН=; ДП=; БЛ="); КонецЕсли; Возврат ИдентификаторЗначения; КонецФункции Функция РазмерЗначенияЛкс(Значение) Экспорт Результат = СтрДлина(ЗначениеВСтрокуВнутр(Новый ХранилищеЗначения(Значение))); Возврат Результат; КонецФункции Процедура ТабличноеПолеВставитьКолонкуНомерСтрокиЛкс(Знач ТабличноеПоле) Экспорт ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс(); Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиНомерСтроки) = Неопределено Тогда КолонкаТП = ТабличноеПоле.Колонки.Вставить(0); КолонкаТП.Имя = ИмяКолонкиНомерСтроки; КолонкаТП.ТекстШапки = "№"; КолонкаТП.ПодсказкаВШапке = "Номер элемента в пределах родителя (служебная)"; КолонкаТП.ТолькоПросмотр = Истина; КолонкаТП.Ширина = 3; КонецЕсли; КонецПроцедуры // ОбновитьТаблицуКолонок() Процедура _РасширенныйВыборПравогоЗначенияОтбораКомпоновкиЛкс(ТабличноеПолеОтбора) Экспорт ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока; Если Ложь Или ТекущаяСтрока = Неопределено Или ТипЗнч(ТекущаяСтрока) = Тип("ОтборКомпоновкиДанных") Или ТипЗнч(ТекущаяСтрока) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда Возврат; КонецЕсли; ЗначениеОтбора = ТекущаяСтрока.ПравоеЗначение; КолонкаТП = ТабличноеПолеОтбора.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента; ТабличноеПолеОтбора.ТекущаяКолонка = КолонкаТП; Если ТипЗнч(ЗначениеОтбора) <> Тип("СписокЗначений") Тогда Если ЛиСсылкаНаОбъектБДЛкс(ЗначениеОтбора, Ложь) Тогда ТабличноеПолеОтбора.ИзменитьСтроку(); ирОбщий.ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеОтбора)),,, КолонкаТП.ЭлементУправления, Истина,, ЗначениеОтбора); КонецЕсли; Иначе Результат = ирОбщий.ОткрытьЗначениеЛкс(ЗначениеОтбора, Истина); Если Результат Тогда ТекущаяСтрока.ПравоеЗначение = ЗначениеОтбора; ТекущаяСтрока.Использование = Истина; КонецЕсли; КонецЕсли; КонецПроцедуры Функция ПоказатьДоступноеПолеЭлементаНастроекКомпоновкиЛкс(ЭтаФорма, Знач ТабличноеПолеДоступныхПолей, Знач ТабличноеПолеНастроек) Экспорт ТекущаяСтрока = ТабличноеПолеНастроек.ТекущаяСтрока; Если ТипЗнч(ТекущаяСтрока) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда ИскомоеПоле = ТекущаяСтрока.ЛевоеЗначение; Если ТабличноеПолеНастроек.ТекущаяКолонка = ТабличноеПолеНастроек.Колонки.ПравоеЗначениеДляКраткогоОтображенияЭлемента Тогда ИскомоеПоле = ТекущаяСтрока.ПравоеЗначение; КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(ТекущаяСтрока) = Тип("ЭлементПорядкаКомпоновкиДанных") Или ТипЗнч(ТекущаяСтрока) = Тип("ВыбранноеПолеКомпоновкиДанных") Или ТипЗнч(ТекущаяСтрока) = Тип("ПолеГруппировкиКомпоновкиДанных") Тогда ИскомоеПоле = ТекущаяСтрока.Поле; Иначе Возврат Неопределено; КонецЕсли; ДоступноеПоле = ТабличноеПолеДоступныхПолей.Значение.НайтиПоле(Новый ПолеКомпоновкиДанных(ИскомоеПоле)); Если ДоступноеПоле <> Неопределено Тогда ТабличноеПолеДоступныхПолей.ТекущаяСтрока = ДоступноеПоле; ЭтаФорма.ТекущийЭлемент = ТабличноеПолеДоступныхПолей; КонецЕсли; Возврат ДоступноеПоле; КонецФункции Процедура КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка) Экспорт МассивСостояний = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс(); Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда ТекстКнопки = Кнопка.Текст; Иначе ТекстКнопки = Кнопка.Заголовок; КонецЕсли; Если ТекстКнопки = МассивСостояний[2] Тогда Кнопка.Пометка = Ложь; НовыйТекстКнопки = МассивСостояний[0]; Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирПусто"); ИначеЕсли ТекстКнопки = МассивСостояний[1] Тогда Кнопка.Пометка = Истина; НовыйТекстКнопки = МассивСостояний[2]; Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирИдентификатор"); Иначе//Если ТекстКнопки = МассивСостояний[0] Тогда Кнопка.Пометка = Истина; НовыйТекстКнопки = МассивСостояний[1]; Кнопка.Картинка = ирКэш.КартинкаПоИмениЛкс("ирПусто"); КонецЕсли; Если ТипЗнч(Кнопка) = Тип("КнопкаКоманднойПанели") Тогда Кнопка.Текст = НовыйТекстКнопки; Иначе Кнопка.Заголовок = НовыйТекстКнопки; КонецЕсли; КонецПроцедуры Процедура ПрименитьИзмененияИЗакрытьФормуЛкс(ЭтаФорма, ЗначениеВыбора = Неопределено) Экспорт ЭтаФорма.Модифицированность = Ложь; Если Ложь Или ЭтаФорма.ВладелецФормы <> Неопределено Или Не ЭтаФорма.Открыта() Тогда ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора); КонецЕсли; Если ЭтаФорма.Открыта() Тогда ЭтаФорма.Закрыть(ЗначениеВыбора); КонецЕсли; //Если ЭтаФорма.Открыта() Тогда // ЭтаФорма.Закрыть(ЗначениеВыбора); //Иначе//Если ЭтаФорма.МодальныйРежим Тогда // ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора); //КонецЕсли; КонецПроцедуры // ПрименитьИзмененияИЗакрытьФорму() // // Параметры: // ЯзыкПрограммы - Число - 0 - встроенный язык, 1 - язык запросов, 2 - язык выражений СКД Функция НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Знач Слово, ЯзыкПрограммы = 0, ПоискСУчетомТипаСлова = Истина) Экспорт мПлатформа = ирКэш.Получить(); мПлатформа.ИнициализацияОписанияМетодовИСвойств(); МассивВозможныхТиповСлова = Новый Массив; МассивВозможныхТиповСлова.Добавить("Конструктор"); Слово = НРег(Слово); Если Ложь Или Не ПоискСУчетомТипаСлова Или Прав(Слово, 1) = "(" Тогда Если Прав(Слово, 1) = "(" Тогда Слово = СтрокаБезКонцаЛкс(Слово, 1); КонецЕсли; МассивВозможныхТиповСлова.Добавить("Метод"); КонецЕсли; Если Ложь Или Не ПоискСУчетомТипаСлова Или Прав(Слово, 1) <> "(" Тогда МассивВозможныхТиповСлова.Добавить("Свойство"); МассивВозможныхТиповСлова.Добавить("Конструкция"); МассивВозможныхТиповСлова.Добавить("Событие"); МассивВозможныхТиповСлова.Добавить("Таблица"); КонецЕсли; ТаблицаСтруктурВозможныхТиповКонтекста = мПлатформа.НоваяТаблицаСтруктурТипа(); Для Каждого ВозможныйТипСлова Из МассивВозможныхТиповСлова Цикл Если ВозможныйТипСлова = "Конструктор" Тогда КлючПоиска = Новый Структура("ТипКонтекста, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, ""); Иначе КлючПоиска = Новый Структура("НСлово, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, ""); КонецЕсли; НайденныеСтроки = мПлатформа.ТаблицаКонтекстов.НайтиСтроки(КлючПоиска); Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока)); КонецЦикла; НайденныеСтроки = мПлатформа.ТаблицаШаблоновКонтекстов.НайтиСтроки(КлючПоиска); Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока)); КонецЦикла; КонецЦикла; КлючПоиска = Новый Структура("НСлово, ЯзыкПрограммы", Слово, ЯзыкПрограммы); НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока)); КонецЦикла; Возврат ТаблицаСтруктурВозможныхТиповКонтекста; КонецФункции // НайтиВозможныеСтрокиОписанияСлова() // Открывает форму синтакс-помощника и загружает в нее нужную страницу, подсвечивая заданную строку. // // Параметры: // ВнутреннийПутьКОписанию – Строка – внутренний путь к странице синтакс-помощника; // СтрокаДляПодсветки – Строка – которую нужно подсветить в тексте страницы. // // Возвращаемое значение: // Форма. // Функция ОткрытьСтраницуСинтаксПомощникаЛкс(ВнутреннийПутьКОписанию, СтрокаДляПодсветки = "", ВладелецФормы = Неопределено, КлючУникальности = Неопределено) Экспорт Если ВнутреннийПутьКОписанию = "" Тогда Возврат Неопределено; КонецЕсли; ФормаСправка = ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , , КлючУникальности); ФормаСправка.ВладелецФормы = ВладелецФормы; ФормаСправка.ОткрытьАдрес(ВнутреннийПутьКОписанию, СтрокаДляПодсветки); ФормаСправка.ВладелецФормы = Неопределено; Возврат ФормаСправка; КонецФункции // Обходит строки табличного поля и имитирует редактирование и выбор пользователем заданного значения. // // Параметры: // ТабличноеПоле - ТабличноеПоле; // ЗначениеОбработки - Произвольные - значение, которое будем записывать в ячейки; // *ФормаИнициатор - Форма, *Неопределено - форма, от имени которой будет записывать; // *ТипИсточника – Строка, *Неопределено – "ТаблицаЗначений", "ТабличнаяЧасть"; // *Колонка – КолонкаТабличногоПоля, *Неопределено – колонка в которой обходим ячейки, по умолчанию текущая; // *ТолькоВыделенныеСтроки - Булево, *Истина - обходить только выделенные строки. // Процедура УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, ЗначениеОбработки, ФормаИнициатор = Неопределено, Знач ТипИсточника = Неопределено, Знач Колонка = Неопределено, Знач ТолькоВыделенныеСтроки = Истина, Знач ИнтерактивноеУстановка = Истина, Знач НаСервере = Ложь) Экспорт Если Колонка = Неопределено Тогда Колонка = ТабличноеПоле.ТекущаяКолонка; Иначе Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ТабличноеПоле.ТекущаяКолонка = Колонка; Иначе ТабличноеПоле.ТекущийЭлемент = Колонка; КонецЕсли; КонецЕсли; ЗначениеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле); Если ТипИсточника = "" Тогда ТипИсточника = ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; ЕстьОтборСтрок = Ложь Или ТипИсточника = "ТабличнаяЧасть" Или ТипИсточника = "НаборЗаписей"; Если ТолькоВыделенныеСтроки Тогда Если Истина И ТабличноеПоле.ВыделенныеСтроки.Количество() = 1 И ТипИсточника <> "ДеревоЗначений" Тогда ТекстОтбора = ""; Если ЕстьОтборСтрок Тогда ТекстОтбора = " удовлетворяющие отбору"; КонецЕсли; Ответ = Вопрос("Выделена только одна строка. Хотите обработать все" + ТекстОтбора + " строки?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Да Тогда ТолькоВыделенныеСтроки = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; КлючиСтрокДляОбработки = Новый Массив; КДанныетрокДляОбработки = Новый Массив; Если ТолькоВыделенныеСтроки Тогда Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл КлючиСтрокДляОбработки.Добавить(ВыделеннаяСтрока); КонецЦикла; Иначе Если ЕстьОтборСтрок Тогда Построитель = Новый ПостроительЗапроса; Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЗначениеТабличногоПоля); Построитель.ВыбранныеПоля.Очистить(); Построитель.ВыбранныеПоля.Добавить("НомерСтроки"); СкопироватьОтборПостроителяЛкс(Построитель.Отбор, ТабличноеПоле.ОтборСтрок); ТаблицаРезультата = Построитель.Результат.Выгрузить(); Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл КлючиСтрокДляОбработки.Добавить(СтрокаРезультата.НомерСтроки - 1); КонецЦикла; ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда Для Каждого СтрокаТаблицы Из ЗначениеТабличногоПоля Цикл Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда КлючСтроки = СтрокаТаблицы.ПолучитьИдентификатор(); Иначе КлючСтроки = СтрокаТаблицы; КонецЕсли; КлючиСтрокДляОбработки.Добавить(КлючСтроки); КонецЦикла; КонецЕсли; КонецЕсли; Индикатор = ПолучитьИндикаторПроцессаЛкс(КлючиСтрокДляОбработки.Количество(), "Групповая установка значения"); // Нужно встать на редактируемую колонку, чтобы сработал режим редактирования Для Каждого КлючСтроки Из КлючиСтрокДляОбработки Цикл ОбработатьИндикаторЛкс(Индикатор); Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда ДанныеСтроки = ТабличноеПоле.ДанныеСтроки(КлючСтроки); ТекущаяСтрока = КлючСтроки; Иначе Если ТипЗнч(КлючСтроки) = Тип("Число") Тогда ТекущаяСтрока = ЗначениеТабличногоПоля[КлючСтроки]; Иначе ТекущаяСтрока = КлючСтроки; КонецЕсли; ДанныеСтроки = ТекущаяСтрока; КонецЕсли; Если ТипЗнч(ЗначениеОбработки) = Тип("Структура") Тогда ЗаполнитьЗначенияСвойств(ЗначениеОбработки.Параметры, ДанныеСтроки); НовоеЗначение = ВычислитьВыражение(ЗначениеОбработки.Формула, ЗначениеОбработки.Параметры, НаСервере); Иначе НовоеЗначение = ЗначениеОбработки; КонецЕсли; Если ИнтерактивноеУстановка Тогда ТабличноеПоле.ТекущаяСтрока = ТекущаяСтрока; //ТабличноеПоле.ИзменитьСтроку(); ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение, ФормаИнициатор,,, Ложь); ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь); Иначе ТекущаяСтрока[Колонка.Имя] = НовоеЗначение; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(Индикатор); Если ТолькоВыделенныеСтроки Тогда Для Каждого ВыделеннаяСтрока Из КлючиСтрокДляОбработки Цикл ТабличноеПоле.ВыделенныеСтроки.Добавить(ВыделеннаяСтрока); КонецЦикла; КонецЕсли; КонецПроцедуры Функция ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(Знач ИсточникДействий, МассивСтрок = Неопределено, СУчетомОтбора = Ложь, ПреобразоватьДеревоВТаблицу = Истина) Экспорт ИмяТипаЗначения = ОбщийТипДанныхТабличногоПоляЛкс(ИсточникДействий); ИмяОсновнойТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ИсточникДействий); Если ИмяТипаЗначения = "Список" И ЗначениеЗаполнено(ИмяОсновнойТаблицы) Тогда Возврат Неопределено; КонецЕсли; Если Ложь #Если Клиент Тогда Или ТипЗнч(ИсточникДействий) = Тип("ТабличноеПоле") #КонецЕсли Тогда #Если Сервер И Не Сервер Тогда ИсточникДействий = Новый ТабличноеПоле; #КонецЕсли ВыгрузкаРезультата = ирОбщий.ДанныеЭлементаФормыЛкс(ИсточникДействий); Если ТипЗнч(ВыгрузкаРезультата) = Тип("ТаблицаЗначений") Тогда ВыгрузкаРезультата = ВыгрузкаРезультата.Скопировать(МассивСтрок); ИначеЕсли ТипЗнч(ВыгрузкаРезультата) = Тип("ДеревоЗначений") Тогда Если ПреобразоватьДеревоВТаблицу Тогда Если МассивСтрок = Неопределено Тогда ВыгрузкаРезультата = ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ВыгрузкаРезультата, Истина); Иначе ВыгрузкаРезультата = СкопироватьКолонкиКоллекцииЛкс(ВыгрузкаРезультата, Новый ТаблицаЗначений); Для Каждого СтрокаДерева Из МассивСтрок Цикл ЗаполнитьЗначенияСвойств(ВыгрузкаРезультата.Добавить(), СтрокаДерева); КонецЦикла; КонецЕсли; КонецЕсли; Иначе Если МассивСтрок <> Неопределено Или Не СУчетомОтбора Тогда ВыгрузкаРезультата = ВыгрузкаРезультата.Выгрузить(МассивСтрок); Иначе Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ИсточникДействий); #Если Сервер И Не Сервер Тогда Построитель = Новый ПостроительЗапроса; #КонецЕсли ВыгрузкаРезультата = Построитель.Результат.Выгрузить(); КонецЕсли; КонецЕсли; Счетчик = 0; Для Каждого КолонкаТП Из ИсточникДействий.Колонки Цикл ПутьКДанным = ПутьКДаннымКолонкиТабличногоПоляЛкс(ИсточникДействий, КолонкаТП); Если ЗначениеЗаполнено(ПутьКДанным) Тогда КолонкаТЗ = ВыгрузкаРезультата.Колонки[ПутьКДанным]; ВыгрузкаРезультата.Колонки.Сдвинуть(КолонкаТЗ, Счетчик - ВыгрузкаРезультата.Колонки.Индекс(КолонкаТЗ)); Счетчик = Счетчик + 1; КонецЕсли; КонецЦикла; Иначе // ТипЗнч(ИсточникДействий) = Тип("ТаблицаФормы") ВыгрузкаРезультата = ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(ИсточникДействий, МассивСтрок); Если ПреобразоватьДеревоВТаблицу И ТипЗнч(ВыгрузкаРезультата) = Тип("ДеревоЗначений") Тогда ВыгрузкаРезультата = ирОбщий.ВсеСтрокиДереваЗначенийЛкс(ВыгрузкаРезультата, Истина); КонецЕсли; КонецЕсли; Возврат ВыгрузкаРезультата; КонецФункции Процедура ПоследниеВыбранныеНажатиеЛкс(Знач ЭтаФорма, ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач Кнопка) Экспорт КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле); ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения); Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда Возврат; КонецЕсли; ИндексЭлементаСписка = Число(Сред(Кнопка.Имя, СтрДлина(НачалоИмениКнопкиПодменюПоследнихВыбранных()) + 1)); Если ПоследниеВыбранные.Количество() <= ИндексЭлементаСписка Тогда Возврат; КонецЕсли; КлючСтроки = ПоследниеВыбранные[ИндексЭлементаСписка].Значение; СтрокаНайдена = ирОбщий.УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(ЭтаФорма, ТабличноеПоле, КлючевоеПоле, КлючСтроки,, Истина); Если СтрокаНайдена И ЭтаФорма.РежимВыбора Тогда Ответ = Вопрос("Выбрать установленную строку?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда //ЭтаФорма.ОповеститьОВыборе(КлючСтроки); //Если Этаформа.ВводДоступен() Тогда ирПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда ирПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ирПлатформа.WshShell.SendKeys("~"); // При этом почему то NumLock перенажимается //КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ПоследниеВыбранныеДобавитьЛкс(ЭтаФорма, Знач ВыбранноеЗначение, Знач ПредставлениеЗначения = "", Знач ТабличноеПоле = Неопределено) Экспорт ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс(); Если Истина И ЗапоминатьПоследниеВыбранные <> Неопределено И ЗапоминатьПоследниеВыбранные > 0 Тогда КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле); ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения); Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда ПоследниеВыбранные = Новый СписокЗначений; КонецЕсли; Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда Если ВыбранноеЗначение.Количество() = 0 Тогда Возврат; КонецЕсли; ВыбранноеЗначение = ВыбранноеЗначение[0]; КонецЕсли; Индекс = ПоследниеВыбранные.НайтиПоЗначению(ВыбранноеЗначение); Если Индекс <> Неопределено Тогда ПоследниеВыбранные.Удалить(Индекс); КонецЕсли; КлючСтроки = ВыбранноеЗначение; Если Не ЗначениеЗаполнено(ПредставлениеЗначения) Тогда ПредставлениеЗначения = ПредставлениеКлючаСтрокиБДЛкс(ВыбранноеЗначение); КонецЕсли; ПоследниеВыбранные.Вставить(0, КлючСтроки, ПредставлениеЗначения); ирОбщий.СохранитьЗначениеЛкс(КлючЗначения, ПоследниеВыбранные); КонецЕсли; КонецПроцедуры Процедура НайденныеСтандартноСсылкиПриВыводеСтрокиЛкс(Знач ОформлениеСтроки) Экспорт ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки; Ячейки = ОформлениеСтроки.Ячейки; Если ирОбщий.ЛиКорневойТипРегистраСведенийЛкс(ирОбщий.ПервыйФрагментЛкс(ДанныеСтроки.Метаданные)) Тогда Попытка КлючЗаписи = ЗначениеИзСтрокиВнутр(Ячейки.Данные.Текст); Исключение // Некоторые большие ключи регистров в сериализованном виде не умещаются в 1024 символа КлючЗаписи = "<Ключ записи регистра обрезан и не может быть восстановлен>"; КонецПопытки; Ячейки.Данные.Текст = ирОбщий.ПредставлениеКлючаСтрокиБДЛкс(КлючЗаписи, Ложь); КонецЕсли; КонецПроцедуры Процедура ОформитьФонТекущейСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт Если Элемент.ТекущаяСтрока = ДанныеСтроки Тогда ОформлениеСтроки.ЦветФона = WebЦвета.СветлоНебесноГолубой; КонецЕсли; КонецПроцедуры Функция ПроверитьЗапуститьОтладчик(Знач ВремяОжиданияЗапуска = 5) Экспорт ИдентификаторПроцессаОтладчика = Неопределено; Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ПортОтладки = Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика); Если ИдентификаторПроцессаОтладчика = Неопределено Тогда //Если Не УФ(сПроверитьДоступностьКонфигуратора) Тогда // СообщитьЛкс("Конфигуратор уже открыт, но отладка не подключена. Выполните подключение отладчика вручную"); // Перейти ~Конец; //КонецЕсли; // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164 Если ирКэш.НомерВерсииПлатформыЛкс() = 802015 Тогда СообщитьЛкс("Из-за ошибки платформы 8.2.15 запуск и подключение отладчика необходимо выполнять вручную"); Возврат Неопределено; КонецЕсли; Если ПортОтладки = Неопределено Тогда СообщитьЛкс("Если используется TCP отладка, включите разрешение отладки в главном меню ""Сервис/Параметры/Системные"" и повторите операцию снова"); Возврат Неопределено; КонецЕсли; ПараметрыЗапуска = "CONFIG /DEBUG /DEBUGTARGET""tcp://127.0.0.1:" + ПортОтладки + """"; ЗапуститьСистему(ПараметрыЗапуска); ПаузаЛкс(ВремяОжиданияЗапуска); Если ИдентификаторПроцессаОтладчика = Неопределено Тогда ИдентификаторПроцессаОтладчика = 0; КонецЕсли; Пока Истина Цикл Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика); Если ИдентификаторПроцессаОтладчика = Неопределено Тогда Ответ = Вопрос("Отладчик еще не подключился. Повторить снова?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда Продолжить; КонецЕсли; КонецЕсли; Прервать; КонецЦикла; Иначе Платформа.АктивизироватьОкноПроцесса1С8(Число(ИдентификаторПроцессаОтладчика)); КонецЕсли; Если ИдентификаторПроцессаОтладчика <> Неопределено Тогда Результат = Число(ИдентификаторПроцессаОтладчика); КонецЕсли; Возврат Результат; КонецФункции Процедура ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда Возврат; КонецЕсли; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ТекущаяКолонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле); Если ТекущаяКолонка = Неопределено Тогда Возврат; КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда ИмяКолонки = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущаяКолонка, Истина); Иначе ИмяКолонки = ТекущаяКолонка.Данные; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Возврат; КонецЕсли; ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ИмяКолонки]; XMLТип = XMLТипЗнч(ЗначениеЯчейки); Если XMLТип = Неопределено Тогда Возврат; КонецЕсли; Если Найти(XMLТип.ИмяТипа, "Ref.") = 0 Тогда Возврат; КонецЕсли; //Если Ложь // Или Найти(XMLТип.ИмяТипа, "EnumRef.") > 0 // Или Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 //Тогда // ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ЗначениеЯчейки)),, Истина,,,, ЗначениеЯчейки); //Иначе ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеЯчейки); //КонецЕсли; КонецПроцедуры // Параметры // КлючИлиОбъект - СтруктураОбъектаБД, Ссылка, ОбъектБД Функция ОткрытьСсылкуВРедактореОбъектаБДЛкс(КлючОбъекта, ИскомоеЗначение = Неопределено, ИмяТабличнойЧасти = "", ИмяПоля = "", КлючСтроки = Неопределено) Экспорт ФормаРедактора = ПолучитьФормуСсылки(КлючОбъекта, ИскомоеЗначение); ФормаРедактора.Открыть(); Если ЗначениеЗаполнено(ИмяПоля) Тогда Если ЗначениеЗаполнено(ИмяТабличнойЧасти) Тогда ИмяДочернейТаблицыБД = КлючОбъекта.Метаданные().ПолноеИмя(); ИмяДочернейТаблицыБД = ИмяДочернейТаблицыБД + "." + ИмяТабличнойЧасти; КонецЕсли; ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ИмяДочернейТаблицыБД, ИмяПоля, КлючСтроки); КонецЕсли; Возврат ФормаРедактора; КонецФункции Функция ОткрытьОбъектВРедактореОбъектаБДЛкс(ОбъектБД, ИскомоеЗначение = Неопределено, КлючУникальности = Неопределено) Экспорт Если КлючУникальности = Неопределено Тогда КлючУникальности = Новый УникальныйИдентификатор; КонецЕсли; ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", ОбъектБД); ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Ложь); ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", ИскомоеЗначение); Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючУникальности); #Если Сервер И Не Сервер Тогда Форма = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ЗаполнитьЗначенияСвойств(Форма.фОбъект, ПараметрыФормы, "ПараметрКлючИлиОбъект, ПараметрПрочитатьОбъект, ПараметрИскомоеЗначение"); Форма.Открыть(); Возврат Форма; КонецФункции // Параметры // КлючИлиОбъект - СтруктураОбъектаБД, Ссылка, ОбъектБД Функция ПолучитьФормуСсылки(КлючОбъекта, ИскомоеЗначение = Неопределено) ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", КлючОбъекта); ПараметрыФормы.Вставить("ПараметрПрочитатьОбъект", Истина); ПараметрыФормы.Вставить("ПараметрИскомоеЗначение", ИскомоеЗначение); Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы,, КлючОбъекта); #Если Сервер И Не Сервер Тогда Форма = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы); Возврат Форма; КонецФункции Процедура НайтиИПоказатьСсылкиНаОбъектБД(СсылкаНаКоторуюИщемСсылки) Экспорт ПараметрыФормы = Новый Структура; ПараметрыФормы.Вставить("ПараметрКлючИлиОбъект", СсылкаНаКоторуюИщемСсылки); Форма = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", ПараметрыФормы); #Если Сервер И Не Сервер Тогда Форма = Обработки.ирРедакторОбъектаБД.Создать(); #КонецЕсли ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы); Форма.Открыть(); Форма.НайтиИПоказатьСсылкиВФорме(); КонецПроцедуры // НайтиСсылки() // ВариантПросмотра - Строка - "Компактный", "ЯзыкЗапросов", "ВстроенныйЯзык", ... Функция ПолучитьФормуТекстаЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, Знач КлючУникальности = Неопределено, ВладелецФормы = Неопределено, ВыделитьВсе = Ложь) Экспорт Если КлючУникальности = Неопределено Тогда КлючУникальности = Новый УникальныйИдентификатор(); КонецЕсли; ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("Текст", ВладелецФормы, КлючУникальности); ФормаПросмотра.НачальноеЗначениеВыбора = Текст; ФормаПросмотра.РекомендуемыйВариант = ВариантПросмотра; ФормаПросмотра.ТолькоПросмотр = ТолькоПросмотр; ФормаПросмотра.ПараметрВыделитьВсе = ВыделитьВсе; Если Не ЗначениеЗаполнено(Заголовок) Тогда //Заголовок = ФормаПросмотра.Заголовок; Заголовок = "Текст"; // Чтобы при повторном открытии не оставался старый текст КонецЕсли; ФормаПросмотра.Заголовок = Заголовок; Возврат ФормаПросмотра; КонецФункции Функция ОткрытьТекстЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, Знач КлючУникальности = Неопределено, ВладелецФормы = Неопределено, ВыделитьВсе = Ложь) Экспорт ФормаПросмотра = ПолучитьФормуТекстаЛкс(Текст, Заголовок, ВариантПросмотра, ТолькоПросмотр, КлючУникальности, ВладелецФормы, ВыделитьВсе); ФормаПросмотра.Открыть(); Возврат ФормаПросмотра; КонецФункции Процедура ОткрытьПросмотрДереваJSONЛкс(Знач СтрокаJSON, Знач Заголовок = "", Знач КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт Если Не ЗначениеЗаполнено(СтрокаJSON) Тогда Возврат; КонецЕсли; Если КлючУникальности = Неопределено Тогда КлючУникальности = Новый УникальныйИдентификатор(); КонецЕсли; ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("ДеревоJSON", ВладелецФормы, КлючУникальности); ФормаПросмотра.ПараметрJSON = СтрокаJSON; ФормаПросмотра.Открыть(); Если ЗначениеЗаполнено(Заголовок) Тогда ирОбщий.ОбновитьТекстПослеМаркераВСтрокеЛкс(ФормаПросмотра.Заголовок,, Заголовок, " - "); КонецЕсли; КонецПроцедуры Функция ФормаПросмотраHTMLЛкс(Текст) Экспорт Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.HTML"); Форма.ЭлементыФормы.ПолеHtmlДокумента.УстановитьТекст(Текст); Возврат Форма; КонецФункции Процедура ПолеВводаТекста_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда СтандартнаяОбработка = Ложь; ФормаРедактора = ирКэш.Получить().ПолучитьФорму("Текст", Элемент, Новый УникальныйИдентификатор); ФормаРедактора.РежимВыбора = Истина; ФормаРедактора.НачальноеЗначениеВыбора = Элемент.Значение; ФормаРедактора.Открыть(); КонецЕсли; КонецПроцедуры // Для управляемой формы возвращает путь относительно родителя Функция ПутьКДаннымКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Колонка = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ТабличноеПоле = Новый ТабличноеПоле; #КонецЕсли Если Колонка = Неопределено Тогда Колонка = ТекущаяКолонкаТаблицыФормыЛкс(ТабличноеПоле); КонецЕсли; Если ТипЗнч(Колонка) = Тип("ПолеФормы") Тогда ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Колонка, Истина); Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда ПутьКДанным = Колонка.Имя; Если Найти(ПутьКДанным, ТабличноеПоле.Имя) = 1 Тогда ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле); ПутьКДанным = Сред(ПутьКДанным, СтрДлина(ТабличноеПоле.Имя) + 1); КонецЕсли; СтрокаИлиКоллекция = Неопределено; Если ТабличноеПоле.ТекущиеДанные = Неопределено Тогда Если ЛиДанныеФормыСВозможностьюПоискаЛкс(ДанныеТаблицы) Тогда СтрокаИлиКоллекция = ДанныеТаблицы; КонецЕсли; Иначе СтрокаИлиКоллекция = ТабличноеПоле.ТекущиеДанные; КонецЕсли; Если СтрокаИлиКоллекция <> Неопределено Тогда ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ПутьКДанным); КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(Колонка) = Тип("ГруппаФормы") Тогда ПутьКДанным = ""; ИначеЕсли Колонка <> Неопределено Тогда // Обычная форма ПутьКДанным = Колонка.Данные; Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда ПутьКДанным = Колонка.ДанныеФлажка; Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда Если Ложь Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ПутьКДанным = Колонка.ДанныеКартинки; КонецЕсли; КонецЕсли; КонецЕсли; Если ТипЗнч(ТабличноеПоле.Значение) = Тип("НастройкиКомпоновкиДанных") Тогда // Здесь ПутьКДанным = "СтруктураОтчета" - виртуальное имя ПутьКДанным = ""; ИначеЕсли Ложь Или ПутьКДанным = "ПравоеЗначениеДляКраткогоОтображенияЭлемента" Тогда ПутьКДанным = "ПравоеЗначение"; ИначеЕсли Ложь Или ПутьКДанным = "ВидыСравненияДляКраткогоОтображенияЭлемента" Тогда ПутьКДанным = "ВидСравнения"; ИначеЕсли Ложь Или ПутьКДанным = "ЛевоеЗначениеДляКраткогоОтображенияЭлемента" Тогда ПутьКДанным = "ЛевоеЗначение"; КонецЕсли; КонецЕсли; Возврат ПутьКДанным; КонецФункции Функция НайтиПутьКДаннымПоляТаблицыФормыЛкс(Знач СтрокаИлиКоллекция, Знач ИмяПоля, выхЗначениеПоля = Неопределено) Экспорт Если ТипЗнч(СтрокаИлиКоллекция) = Тип("ТаблицаФормы") Тогда СтрокаИлиКоллекция = ДанныеЭлементаФормыЛкс(СтрокаИлиКоллекция); КонецЕсли; ДлинаСтроки = СтрДлина(ИмяПоля); ПутьКДанным = ""; РежимКоллекции = ЛиДанныеФормыСВозможностьюПоискаЛкс(СтрокаИлиКоллекция); Пока ДлинаСтроки > 0 Цикл ПроверяемоеИмя = Прав(ИмяПоля, ДлинаСтроки); ДлинаСтроки = ДлинаСтроки - 1; Если РежимКоллекции Тогда Попытка СтрокаИлиКоллекция.НайтиСтроки(Новый Структура(ПроверяемоеИмя)); ПутьКДанным = ПроверяемоеИмя; Прервать; Исключение Продолжить; КонецПопытки; Иначе Попытка выхЗначениеПоля = СтрокаИлиКоллекция[ПроверяемоеИмя]; ПутьКДанным = ПроверяемоеИмя; Прервать; Исключение Продолжить; КонецПопытки; КонецЕсли; КонецЦикла; Если Не ЗначениеЗаполнено(ПутьКДанным) Тогда ДлинаИмениДочернегоРеквизита = 0; Пока Не ЗначениеЗаполнено(ПутьКДанным) И ДлинаИмениДочернегоРеквизита < СтрДлина(ИмяПоля) Цикл ДлинаИмениДочернегоРеквизита = ДлинаИмениДочернегоРеквизита + 1; Если "_" <> Сред(ИмяПоля, СтрДлина(ИмяПоля) - ДлинаИмениДочернегоРеквизита + 1, 1) Тогда Продолжить; КонецЕсли; ИмяРеквизита = Лев(ИмяПоля, СтрДлина(ИмяПоля) - ДлинаИмениДочернегоРеквизита); ИмяДочернегоРеквизита = Прав(ИмяПоля, ДлинаИмениДочернегоРеквизита - 1); ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ИмяРеквизита, выхЗначениеПоля); Если Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда ИмяДочернегоРеквизита = ПеревестиВРусский(ИмяДочернегоРеквизита); // http://www.hostedredmine.com/issues/880938 КонецЕсли; Если ЗначениеЗаполнено(ПутьКДанным) И выхЗначениеПоля <> Неопределено Тогда ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(выхЗначениеПоля.Метаданные().ПолноеИмя()); Если ПоляТаблицыБД.Найти(ИмяДочернегоРеквизита, "Имя") = Неопределено Тогда ПутьКДанным = Неопределено; Иначе ПутьКДанным = ПутьКДанным + "." + ИмяДочернегоРеквизита; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; Возврат ПутьКДанным; КонецФункции Процедура ТабличноеПолеОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(Знач ТабличноеПоле) Экспорт Если ТабличноеПоле.ТекущиеДанные = Неопределено Тогда Возврат; КонецЕсли; ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда Возврат; КонецЕсли; ДанныеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле); НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДанныеТабличногоПоля, "Пользовательские"); Попытка Отбор = НастройкиСписка.Отбор; Исключение Отбор = ТабличноеПоле.ОтборСтрок; КонецПопытки; //Отбор = Новый ("Отбор"); Если ТипЗнч(Отбор) = Тип("Отбор") Тогда ЭлементОтбора = Отбор[ДанныеКолонки]; ДоступноеПоле = ЭлементОтбора; ТекущееЗначениеОтбора = ЭлементОтбора.Значение; ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки]; Иначе ДоступноеПоле = ирОбщий.НайтиДоступноеПолеКомпоновкиПоИмениКолонкиЛкс(Отбор.ДоступныеПоляОтбора, ДанныеКолонки); #Если Сервер И Не Сервер Тогда ДоступноеПоле = НастройкиСписка.ДоступныеПоляВыбора.НайтиПоле(); #КонецЕсли ЭлементОтбора = ирОбщий.НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Отбор, ДоступноеПоле.Поле,,,,, Ложь); ТекущееЗначениеОтбора = ЭлементОтбора.ПравоеЗначение; ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные["" + ДоступноеПоле.Поле]; КонецЕсли; Если ЭлементОтбора.Использование Тогда Если Ложь Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно Тогда Если Ложь Или ТипЗнч(ЗначениеЯчейки) <> Тип("Булево") Или ДоступноеПоле.ТипЗначения.Типы().Количество() > 1 Тогда СписокЗначений = Новый СписокЗначений; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда НовыйВидСравения = ВидСравнения.НеВСписке; Иначе НовыйВидСравения = ВидСравненияКомпоновкиДанных.НеВСписке; КонецЕсли; СписокЗначений.Добавить(ТекущееЗначениеОтбора); СписокЗначений.Добавить(ЗначениеЯчейки); ЭлементОтбора.ВидСравнения = НовыйВидСравения; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.Значение = СписокЗначений; Иначе ЭлементОтбора.ПравоеЗначение = СписокЗначений; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеВСписке Тогда СписокЗначений = ТекущееЗначениеОтбора; Если СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки) = Неопределено Тогда СписокЗначений.Добавить(ЗначениеЯчейки); КонецЕсли; // Для обновления отбора ЭлементОтбора.Использование = Ложь; ЭлементОтбора.Использование = Истина; ИначеЕсли Ложь Или ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке Тогда СписокЗначений = ТекущееЗначениеОтбора; СписокЗначений.Удалить(СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки)); // Для обновления отбора ЭлементОтбора.Использование = Ложь; ЭлементОтбора.Использование = Истина; Иначе ЭлементОтбора.Использование = Ложь; КонецЕсли; КонецЕсли; Если Не ЭлементОтбора.Использование Тогда ЭлементОтбора.Использование = Истина; Если Истина И ДоступноеПоле.ТипЗначения.СодержитТип(Тип("Строка")) И ДоступноеПоле.ТипЗначения.КвалификаторыСтроки.Длина = 0 Тогда Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда // Особенность платформы Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит; Иначе ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Содержит; КонецЕсли; Иначе Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит; Иначе ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеСодержит; КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно; Иначе ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно; КонецЕсли; КонецЕсли; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбора") Тогда // Привести значение нужно например для NULL в динамическом списке регистра бухгалтерии ЭлементОтбора.Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(ЗначениеЯчейки); Иначе ЭлементОтбора.ПравоеЗначение = ЗначениеЯчейки; КонецЕсли; КонецЕсли; Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора); КонецЕсли; КонецПроцедуры Функция ЗагрузитьЗначениеИзФайлаИнтерактивноЛкс(Знач Расширение = "", Знач ОписаниеФормата = "", Знач Сжатие = Истина) Экспорт Если Не ЗначениеЗаполнено(Расширение) И Сжатие Тогда Расширение = "zip"; КонецЕсли; ПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, ОписаниеФормата); Если ПолноеИмяФайла = Неопределено Тогда Возврат Неопределено; КонецЕсли; Результат = ЗагрузитьЗначениеИзФайлаЛкс(ПолноеИмяФайла, Сжатие); Возврат Результат; КонецФункции Функция СохранитьЗначениеВФайлИнтерактивноЛкс(Знач Значение, Знач Расширение = "", Знач ОписаниеФормата = "", Знач Сжатие = Истина, Знач УровеньСжатия = Неопределено, Знач Заголовок = "") Экспорт Если Не ЗначениеЗаполнено(Расширение) И Сжатие Тогда Расширение = "zip"; КонецЕсли; ПолноеИмяФайла = ВыбратьФайлЛкс(Ложь, Расширение, ОписаниеФормата,,,, Заголовок); Если ПолноеИмяФайла = Неопределено Тогда Возврат Неопределено; КонецЕсли; Результат = СохранитьЗначениеВФайлЛкс(Значение, ПолноеИмяФайла, Сжатие, УровеньСжатия); Возврат Результат; КонецФункции Функция ВыбратьРедактируемыйТипЛкс(ОграничениеТипа = Неопределено, ТолькоПросмотр = Ложь, НачальноеЗначениеВыбора = Неопределено, ВладелецФормы = Неопределено, ЗакрыватьПриВыборе = Истина) Экспорт Если ОграничениеТипа = Неопределено Тогда ОграничениеТипа = Новый ОписаниеТипов; КонецЕсли; ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы); ФормаРедактора.ОграничениеТипа = ОграничениеТипа; ФормаРедактора.ЗакрыватьПриВыборе = ЗакрыватьПриВыборе; ФормаРедактора.НачальноеЗначениеВыбора = НачальноеЗначениеВыбора; ФормаРедактора.РежимВыбора = Истина; ФормаРедактора.МножественныйВыбор = Ложь; ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр; РезультатВыбора = ФормаРедактора.ОткрытьМодально(); Возврат РезультатВыбора; КонецФункции Функция РедактироватьОписаниеРедактируемыхТиповЛкс(ОграничениеТипаИлиПолеВвода, ТолькоПросмотр = Ложь) Экспорт Если ТипЗнч(ОграничениеТипаИлиПолеВвода) = Тип("ОписаниеТипов") Тогда ВладелецФормы = Неопределено; ОграничениеТипа = ОграничениеТипаИлиПолеВвода; Иначе ВладелецФормы = ОграничениеТипаИлиПолеВвода; ОграничениеТипа = ОграничениеТипаИлиПолеВвода.Значение; КонецЕсли; ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы); //ФормаРедактора.ОграничениеТипа = ОграничениеТипа; ФормаРедактора.НачальноеЗначениеВыбора = ОграничениеТипа; ФормаРедактора.РежимВыбора = Истина; ФормаРедактора.МножественныйВыбор = Истина; ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр; РезультатВыбора = ФормаРедактора.ОткрытьМодально(); Возврат РезультатВыбора; КонецФункции // ПолноеИмяНачальногоТипаВыбора - Строка - полное имя метаданного Функция ОткрытьПодборСВыборомТипаЛкс(ВладелецФормы, ОписаниеТипов = Неопределено, Знач НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Истина, ПриПустомОписанииТиповРазрешатьВсе = Ложь) Экспорт ЕстьТипТип = Ложь; Если ТипЗнч(ОписаниеТипов) = Тип("Строка") Тогда ДоступныеОбъекты = СтрРазделитьЛкс(ОписаниеТипов, ",", Истина); ИначеЕсли ОписаниеТипов <> Неопределено Тогда ДоступныеОбъекты = Новый Массив(); ЕстьТипТип = Ложь; Для Каждого Тип Из ОписаниеТипов.Типы() Цикл Если Тип = Тип("Тип") Тогда ЕстьТипТип = Истина; Иначе ПолноеИмяМД = ПолучитьПолноеИмяМДТипаЛкс(Тип); Если ЗначениеЗаполнено(ПолноеИмяМД) Тогда ДоступныеОбъекты.Добавить(ПолноеИмяМД); КонецЕсли; КонецЕсли; КонецЦикла; Если ДоступныеОбъекты.Количество() = 0 И ПриПустомОписанииТиповРазрешатьВсе Тогда ДоступныеОбъекты = Неопределено; КонецЕсли; КонецЕсли; Если Истина И ДоступныеОбъекты = Неопределено И (Ложь Или ЕстьТипТип Или (Истина И ОписаниеТипов = Неопределено И ТипЗнч(НачальноеЗначениеВыбора) = Тип("Тип"))) Тогда Возврат ВыбратьРедактируемыйТипЛкс(,, НачальноеЗначениеВыбора, ВладелецФормы, Ложь); КонецЕсли; Если НачальноеЗначениеВыбора <> Неопределено Тогда ТипНачальногоЗначенияВыбора = ТипОбъектаБДЛкс(НачальноеЗначениеВыбора); ПолноеИмяНачальногоТипаВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипНачальногоЗначенияВыбора); КонецЕсли; Если Ложь Или ДоступныеОбъекты = Неопределено Или ДоступныеОбъекты.Количество() = 0 Или ДоступныеОбъекты.Количество() > 1 Тогда Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы); лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты); лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ПолноеИмяНачальногоТипаВыбора); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; Результат = Форма.ОткрытьМодально(); Если Результат = Неопределено Тогда Возврат Неопределено; КонецЕсли; ПолноеИмяМД = Результат.ПолноеИмяОбъекта; Иначе ПолноеИмяМД = ДоступныеОбъекты[0]; КонецЕсли; Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда Возврат Неопределено; КонецЕсли; Если ПолноеИмяНачальногоТипаВыбора <> ПолноеИмяМД Тогда НачальноеЗначениеВыбора = Неопределено; КонецЕсли; ТекущаяСтрока = Неопределено; Отбор = Неопределено; Если НачальноеЗначениеВыбора <> Неопределено Тогда ИмяXMLТипа = СериализаторXDTO.XMLТип(ТипНачальногоЗначенияВыбора).ИмяТипа; Если Ложь Или Найти(ИмяXMLТипа, "Ref.") > 0 Или Найти(ИмяXMLТипа, "RecordKey.") > 0 Тогда ТекущаяСтрока = НачальноеЗначениеВыбора; Иначе Отбор = НачальноеЗначениеВыбора.Методы.Отбор; КонецЕсли; КонецЕсли; ФормаВыбора = ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, Истина, Истина, ТекущаяСтрока); Возврат ФормаВыбора; КонецФункции Функция ПолучитьФормуВыбораОбъектаМетаданныхЛкс(Знач ВладелецФормы, Знач КлючУникальности, Знач НачальноеЗначениеВыбора, МножественныйВыбор = Ложь, ОтображатьСсылочныеОбъекты = Ложь, ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь, ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь, ТолькоИспользованиеПолнотекстовогоПоиска = Ложь, ОтображатьПеречисления = Ложь, Знач Фильтр = "", ОтображатьОбработки = Ложь, ОтображатьОтчеты = Ложь, ОтображатьПерерасчеты = Ложь) Экспорт лСтруктураПараметров = ПараметрыВыбораОбъектаМетаданныхЛкс(ОтображатьСсылочныеОбъекты, ОтображатьВыборочныеТаблицы, ОтображатьРегистры, ОтображатьПоследовательности, ОтображатьКонстанты, ОтображатьТабличныеЧасти, ОтображатьТаблицыИзменений, ОтображатьВнешниеИсточникиДанных, ЗапретитьВыбиратьСсылочныеОбъекты, ТолькоИспользованиеПолнотекстовогоПоиска, ОтображатьПеречисления, ОтображатьОбработки, ОтображатьОтчеты, ОтображатьПерерасчеты, МножественныйВыбор); Форма = ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(ВладелецФормы, КлючУникальности, НачальноеЗначениеВыбора, лСтруктураПараметров, Фильтр); Возврат Форма; КонецФункции Функция ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(Знач ВладелецФормы, Знач КлючУникальности, Знач НачальноеЗначениеВыбора, Знач лСтруктураПараметров, Знач Фильтр = "") Экспорт Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы, КлючУникальности); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора); лСтруктураПараметров.Вставить("Фильтр", Фильтр); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; Возврат Форма; КонецФункции Функция ПараметрыВыбораОбъектаМетаданныхЛкс(ОтображатьСсылочныеОбъекты = Ложь, ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь, ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь, ТолькоИспользованиеПолнотекстовогоПоиска = Ложь, ОтображатьПеречисления = Ложь, ОтображатьОбработки = Ложь, ОтображатьОтчеты = Ложь, ОтображатьПерерасчеты = Ложь, МножественныйВыбор = Ложь) Экспорт лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ОтображатьКонстанты", ОтображатьКонстанты); лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", ОтображатьВыборочныеТаблицы); лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", ОтображатьТаблицыИзменений); лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", ОтображатьТабличныеЧасти); лСтруктураПараметров.Вставить("ОтображатьРегистры", ОтображатьРегистры); лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", ОтображатьПерерасчеты); лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ОтображатьПоследовательности); лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", ОтображатьСсылочныеОбъекты); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ОтображатьВнешниеИсточникиДанных); лСтруктураПараметров.Вставить("ОтображатьПеречисления", ОтображатьПеречисления); лСтруктураПараметров.Вставить("ОтображатьОбработки", ОтображатьОбработки); лСтруктураПараметров.Вставить("ОтображатьОтчеты", ОтображатьОтчеты); лСтруктураПараметров.Вставить("ТолькоИспользованиеПолнотекстовогоПоиска", ТолькоИспользованиеПолнотекстовогоПоиска); лСтруктураПараметров.Вставить("ЗапретитьВыбиратьСсылочныеОбъекты", ЗапретитьВыбиратьСсылочныеОбъекты); лСтруктураПараметров.Вставить("МножественныйВыбор", МножественныйВыбор); Возврат лСтруктураПараметров; КонецФункции Процедура ОбъектМетаданныхНачалоВыбораЛкс(Знач Элемент, Знач ПараметрыВыбораОбъектаМетаданных, СтандартнаяОбработка) Экспорт СтандартнаяОбработка = Ложь; ФормаВыбора = ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(,, ДанныеЭлементаФормыЛкс(Элемент), ПараметрыВыбораОбъектаМетаданных); РезультатВыбора = ФормаВыбора.ОткрытьМодально(); Если РезультатВыбора <> Неопределено Тогда ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, РезультатВыбора.ПолноеИмяОбъекта); КонецЕсли; КонецПроцедуры Процедура ОбъектМетаданныхОкончаниеВводаТекстаЛкс(Знач Элемент, Знач ПараметрыВыбораОбъектаМетаданных, Текст, Значение, СтандартнаяОбработка) Экспорт Если ЗначениеЗаполнено(Текст) Тогда СтандартнаяОбработка = Ложь; Значение = Новый СписокЗначений; Если ирОбщий.ЛиТаблицаБДСуществуетЛкс(Текст) Тогда Значение.Добавить(Текст); Иначе ФормаВыбора = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхСтруктуройЛкс(Элемент,, ДанныеЭлементаФормыЛкс(Элемент), ПараметрыВыбораОбъектаМетаданных, Текст); РезультатВыбора = ФормаВыбора.ОткрытьМодально(); Если РезультатВыбора <> Неопределено Тогда Значение.Добавить(РезультатВыбора.ПолноеИмяОбъекта); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Функция ПолучитьФормуВыбораТаблицыСтруктурыБДЛкс(ЛиИменаБД, ИмяТаблицыХранения = "") Экспорт Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСтруктураХраненияБД.Форма",,, Истина); Форма.РежимВыбора = Истина; Форма.ПараметрИмяТаблицыХранения = ИмяТаблицыХранения; Форма.ПараметрПоказыватьSDBL = Не ЛиИменаБД; Форма.ПараметрПоказыватьСУБД = ЛиИменаБД; Возврат Форма КонецФункции Функция РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаXMLАлгоритма, ВнешниеПараметры = Неопределено, НаСервере = Ложь) Экспорт СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXMLАлгоритма); Результат = РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры,, НаСервере); Если Результат Тогда СтрокаXMLАлгоритма = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураАлгоритма); КонецЕсли; Возврат Результат; КонецФункции // Открыть редактирование текста алгоритма с параметрами в консоли кода // Парамерты: // СтруктураАлгоритма - Структура - возвращаемый // "ТекстАлгоритма" - Строка - текст алгоритма, // "ВнутренниеПараметры" - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внутренними (значения определяются при редактировании) параметрами алгоритма; // ВнешниеПараметры* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаПараметровАлгоритмаЛкс с внешними (значения определяются при каждом выполнении) параметрами алгоритма; // Методы* - ТаблицаЗначений - таблица с конструктором НоваяТаблицаМетодовПодсказкиЛкс с дополнительными методами доступными в алгоритме; // Результат - Булево - принял ли изменения пользователь Функция РедактироватьАлгоритмЧерезСтруктуруЛкс(СтруктураАлгоритма, ВнешниеПараметры = Неопределено, Методы = Неопределено, НаСервере = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ВнешниеПараметры = Новый ТаблицаЗначений; #КонецЕсли мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ОбработкаКонсольКода = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольКода"); ФормаКонсоли = ОбработкаКонсольКода.ПолучитьФорму(); Если ВнешниеПараметры <> Неопределено Тогда КопияПараметров = ВнешниеПараметры.Скопировать(); Если КопияПараметров.Колонки.Найти("ТаблицаСтруктурТипов") = Неопределено Тогда КопияПараметров.Колонки.Добавить("ТаблицаСтруктурТипов"); КонецЕсли; Если КопияПараметров.Колонки.Найти("Значение") = Неопределено Тогда КопияПараметров.Колонки.Добавить("Значение"); КонецЕсли; Если КопияПараметров.Колонки.Найти("Фиксированный") = Неопределено Тогда КопияПараметров.Колонки.Добавить("Фиксированный"); КонецЕсли; Для Каждого СтрокаПараметра Из КопияПараметров Цикл Если Истина И ТипЗнч(СтрокаПараметра.ТипЗначения) = Тип("ОписаниеТипов") И СтрокаПараметра.ТаблицаСтруктурТипов = Неопределено Тогда СтрокаПараметра.ТаблицаСтруктурТипов = мПлатформа.ПолучитьТаблицуСтруктурТиповИзОписанияТипов(СтрокаПараметра.ТипЗначения); КонецЕсли; КонецЦикла; КопияПараметров.ЗаполнитьЗначения(Истина, "Фиксированный"); ФормаКонсоли.мСписокВнешнихПараметров = КопияПараметров; КонецЕсли; Если СтруктураАлгоритма <> Неопределено Тогда Если СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда ФормаКонсоли.ПараметрТекст = СтруктураАлгоритма.ТекстАлгоритма; КонецЕсли; Если СтруктураАлгоритма.Свойство("ВнутренниеПараметры") Тогда ЗагрузитьВТаблицуЗначенийЛкс(СтруктураАлгоритма.ВнутренниеПараметры, КопияПараметров, Новый Структура("Вход", Истина)); КонецЕсли; КонецЕсли; ФормаКонсоли.ПараметрНаСервере = НаСервере; ФормаКонсоли.мМетоды = Методы; ФормаКонсоли.мРежимРедактора = Истина; ФормаКонсоли.ОткрытьМодально(); РезультатФормы = ФормаКонсоли.РезультатФормы; Результат = РезультатФормы <> Неопределено; Если Результат Тогда ВнутренниеПараметры = РезультатФормы.Параметры.Скопировать(Новый Структура("Вход, Фиксированный", Истина, Ложь), "Имя, Значение"); СтруктураАлгоритма = Новый Структура("ТекстАлгоритма, ВнутренниеПараметры", РезультатФормы.Текст, ВнутренниеПараметры); КонецЕсли; Возврат Результат; КонецФункции // Конструктор таблицы параметров алгоритма // Результат - ТаблицаЗначений - колонки "Имя, Значение, Вход, Выход, ТипЗначения, Комментарий" Функция НоваяТаблицаПараметровАлгоритмаЛкс() Экспорт Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Значение"); Результат.Колонки.Добавить("Вход", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("Выход", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов")); Результат.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ТаблицаСтруктурТипов"); Возврат Результат; КонецФункции // Конструктор таблицы методов контекстной подсказки // Результат - ТаблицаЗначений - колонки "Имя, ТипЗначения" Функция НоваяТаблицаМетодовПодсказкиЛкс() Экспорт Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов")); Результат.Колонки.Добавить("ТаблицаСтруктурТипов"); Возврат Результат; КонецФункции Функция СтрокаСобытияАлгоритмНачалоВыбораЛкс(Знач СтрокаСобытия, НаСервере = Ложь) Экспорт АлгоритмИзменен = РедактироватьАлгоритмЧерезСтрокуXMLЛкс(СтрокаСобытия.Алгоритм, СтрокаСобытия.Параметры, НаСервере); Если СтрокаСобытия.Параметры.Колонки.Найти("Значение") <> Неопределено Тогда СтрокаСобытия.Параметры.ЗаполнитьЗначения(, "Значение"); КонецЕсли; Если СтрокаСобытия.Владелец().Колонки.Найти("АлгоритмОбъект") <> Неопределено Тогда СтрокаСобытия.АлгоритмОбъект = Неопределено; КонецЕсли; Если СтрокаСобытия.Владелец().Колонки.Найти("ТаблицаСтруктурТипов") <> Неопределено Тогда СтрокаСобытия.Параметры.ЗаполнитьЗначения(Неопределено, "ТаблицаСтруктурТипов"); КонецЕсли; Возврат АлгоритмИзменен; КонецФункции Процедура ОформитьЯчейкуАлгоритмаВТабличномПолеЛкс(Знач ОформлениеСтроки, ИмяКолонки = "Алгоритм") Экспорт Если ЗначениеЗаполнено(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки]) Тогда СтруктураАлгоритма = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(ОформлениеСтроки.ДанныеСтроки[ИмяКолонки],,, Ложь); Если СтруктураАлгоритма <> Неопределено И СтруктураАлгоритма.Свойство("ТекстАлгоритма") Тогда ОформлениеСтроки.Ячейки[ИмяКолонки].УстановитьТекст(СокрП(СтруктураАлгоритма.ТекстАлгоритма)); КонецЕсли; КонецЕсли; КонецПроцедуры // ИсторияФайлов - СписокЗначений // Кнопки - КнопкиКоманднойПанели Процедура ОбновитьПодменюИсторииФайловЛкс(ИсторияФайлов, Кнопки, ИмяДействия = "ОткрытьФайлИзИстории") Экспорт Кнопки.Очистить(); ДлинаПредставления = 100; ДействиеКнопки = Новый Действие(ИмяДействия); Для Каждого СтрокаФайла Из ИсторияФайлов Цикл Файл = Новый Файл(СтрокаФайла.Значение); ДлинаПути = ДлинаПредставления - СтрДлина(Файл.Имя); Представление = Лев(Файл.Имя, ДлинаПредставления); Если ДлинаПути > 0 Тогда Если ДлинаПути < СтрДлина(Файл.Путь) + 3 Тогда Представление = Лев(Файл.Путь, ДлинаПути) + "...\" + Представление; Иначе Представление = Файл.Путь + Представление; КонецЕсли; КонецЕсли; КнопкаФайла = Кнопки.Добавить("_" + Формат(ИсторияФайлов.Индекс(СтрокаФайла), "ЧГ=;ЧН="), ТипКнопкиКоманднойПанели.Действие, Представление, ДействиеКнопки); КонецЦикла; КонецПроцедуры Процедура ДобавитьВИсториюЭлементЛкс(СписокИстории, ЗначениеЭлемента, РазмерИстории = 20) Экспорт ЭлементИстории = СписокИстории.НайтиПоЗначению(ЗначениеЭлемента); Если ЭлементИстории <> Неопределено Тогда СписокИстории.Удалить(ЭлементИстории); КонецЕсли; СписокИстории.Вставить(0, ЗначениеЭлемента); Пока СписокИстории.Количество() > РазмерИстории Цикл СписокИстории.Удалить(РазмерИстории); КонецЦикла; КонецПроцедуры Процедура УстановитьДоступностьПодменюЛкс(Знач Подменю, НоваяДоступность = Ложь) Экспорт Для Каждого Кнопка Из Подменю.Кнопки Цикл Кнопка.Доступность = НоваяДоступность; КонецЦикла; КонецПроцедуры Процедура ПоместитьТекстВБуферОбменаОСЛкс(Текст, ВариантПросмотра = "ВстроенныйЯзык") Экспорт // http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241 Попытка //Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так выбрасывается исключение после нескольких вызовов и сразу на 8.3.14+ Документ = Новый COMОбъект("HTMLFILE"); Окно = Документ.parentWindow; Окно.ClipboardData.SetData("Text", Текст); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки КонецПопытки; Если ПолучитьТекстИзБуфераОбменаОСЛкс() <> Текст Тогда ОткрытьТекстЛкс(Текст,, ВариантПросмотра,,,, Истина); КонецЕсли; Конецпроцедуры Функция ПолучитьТекстИзБуфераОбменаОСЛкс() Экспорт // http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241 Попытка //Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так выбрасывается исключение после нескольких вызовов и сразу на 8.3.14+ Документ = Новый COMОбъект("HTMLFILE"); Окно = Документ.parentWindow; Результат = "" + Окно.ClipboardData.GetData("Text"); // Похоже здесь может вернуться не строка Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки Результат = ""; КонецПопытки; Возврат Результат; КонецФункции // Параметры: // Отбор - Структура, Отбор, *Неопределено Функция ОткрытьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь, МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, Модально = Ложь, ПользовательскийОтбор = Неопределено, ТекущаяКолонка = Неопределено) Экспорт ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор,, ТекущаяКолонка); Если ФормаСписка = Неопределено Тогда Возврат Неопределено; КонецЕсли; Если Модально Тогда Если ФормаСписка.Открыта() Тогда ФормаСписка = ПолучитьФормуСпискаЛкс(ИмяТаблицыИлиМДИлиТип, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, РежимВыбора, МножественныйВыбор, ТекущаяСтрока, ПользовательскийОтбор, Новый УникальныйИдентификатор, ТекущаяКолонка); КонецЕсли; Результат = ФормаСписка.ОткрытьМодально(); Возврат Результат; Иначе ФормаСписка.Открыть(); Возврат ФормаСписка; КонецЕсли; КонецФункции // Параметры: // Отбор - Структура, Отбор, *Неопределено Функция ПолучитьФормуСпискаЛкс(Знач ИмяТаблицыИлиМДИлиТип, Знач Отбор = Неопределено, Знач ИспользоватьДинамическийСписокИР = Неопределено, Знач ВладелецФормы = Неопределено, Знач РежимВыбора = Ложь, Знач МножественныйВыбор = Ложь, Знач ТекущаяСтрока = Неопределено, Знач ПользовательскийОтбор = Неопределено, Знач КлючУникальности = Неопределено, Знач ТекущаяКолонка = Неопределено) Экспорт мПлатформа = ирКэш.Получить(); Если ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("ОбъектМетаданных") Тогда ИмяТаблицы = ИмяТаблицыИлиМДИлиТип.ПолноеИмя(); ИначеЕсли ТипЗнч(ИмяТаблицыИлиМДИлиТип) = Тип("Тип") Тогда ИмяТаблицы = ПолучитьПолноеИмяМДТипаЛкс(ИмяТаблицыИлиМДИлиТип); Иначе ИмяТаблицы = ИмяТаблицыИлиМДИлиТип; КонецЕсли; ТипТаблицы = ТипТаблицыБДЛкс(ИмяТаблицы); //МассивФрагментов = СтрРазделитьЛкс(ПолноеИмяМД); Если Ложь Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Или ТипТаблицы = "Изменения" Или ТипТаблицы = "Перерасчет" //Или ТипТаблицы = "Внешняя" //Или МассивФрагментов.Количество() > 2 Тогда СообщитьЛкс("Для таблицы " + ИмяТаблицы + " форма списка не предусмотрена"); Возврат Неопределено; КонецЕсли; Если ИспользоватьДинамическийСписокИР = Неопределено Тогда ИспользоватьДинамическийСписокИР = ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ИмяТаблицы); КонецЕсли; Если Истина И РежимВыбора = Истина И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда ИспользоватьДинамическийСписокИР = Истина; // Потому что у форм списков регистров режим выбора можно включить только через основной элемент управления КонецЕсли; Если ТипТаблицы = "Точки" Тогда ИспользоватьДинамическийСписокИР = Истина; КонецЕсли; Если ИспользоватьДинамическийСписокИР = Неопределено Тогда Ответ = Вопрос("Хотите использовать Динамический список (ИР)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет); ИспользоватьДинамическийСписокИР = Ответ = КодВозвратаДиалога.Да; КонецЕсли; Если ПользовательскийОтбор <> Неопределено Тогда ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных; ПользовательскийОтборКомпоновки = ПользовательскиеНастройки.Элементы.Добавить(Тип("ОтборКомпоновкиДанных")); Если ТипЗнч(ПользовательскийОтбор) = Тип("Отбор") Тогда Для Каждого ЭлементОтбора Из ПользовательскийОтбор Цикл Если ЭлементОтбора.Использование Тогда СтрокаВидаСравнения = мПлатформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель"); Если СтрокаВидаСравнения = Неопределено Тогда // %%%% Здесь можно добавить интеллекта Продолжить; КонецЕсли; ЭлементОтбора = НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ПользовательскийОтборКомпоновки, ЭлементОтбора.Имя, ЭлементОтбора.Значение, СтрокаВидаСравнения.Компоновка); ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ЭлементОтбора); КонецЕсли; КонецЦикла; Иначе СкопироватьОтборЛюбойЛкс(ПользовательскийОтборКомпоновки, ПользовательскийОтбор); КонецЕсли; // Важно: установка идентификатора должна выполняться в конце настройки элемента, // иначе он будет скопирован в пользовательские настройки частично заполненным. // Идентификатор установлен экспериментально https://partners.v8.1c.ru/forum/t/1644571/m/1644571, также подтвержден тут http://forum.infostart.ru/forum9/topic163501/message2246750/#message2246750 ПроверитьВключитьЭлементНастроекКомпоновкиВПользовательскиеНастройки(ПользовательскийОтборКомпоновки, "dfcece9d-5077-440b-b6b3-45a5cb4538eb"); КонецЕсли; Если ТипЗнч(Отбор) = Тип("Отбор") Тогда СтруктураОтбора = Новый Структура; Для Каждого ЭлементОтбора Из Отбор Цикл Если ЭлементОтбора.Использование Тогда Если ЭлементОтбора.ВидСравнения = ВидСравнения.Равно Тогда СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение); КонецЕсли; КонецЕсли; КонецЦикла; Иначе СтруктураОтбора = Отбор; КонецЕсли; ПараметрыФормы = Новый Структура("РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока, Отбор, ПользовательскиеНастройки, ТекущаяКолонка", РежимВыбора, МножественныйВыбор, Не МножественныйВыбор, ТекущаяСтрока, СтруктураОтбора, ПользовательскиеНастройки, ТекущаяКолонка); МожноИспользоватьДинамическийСписокИР = Истина; #Если ТолстыйКлиентОбычноеПриложение Тогда МожноИспользоватьДинамическийСписокИР = ТипТаблицы <> "Внешняя"; #КонецЕсли Если Истина И ИспользоватьДинамическийСписокИР И МожноИспользоватьДинамическийСписокИР Тогда КлючУникальности = КлючУникальностиДинамическогоСпискаЛкс(ИмяТаблицы, КлючУникальности); ПараметрыФормы.Вставить("ИмяТаблицы", ИмяТаблицы); //Если Не РежимВыбора Тогда // КлючУникальности = Новый УникальныйИдентификатор; //КонецЕсли; ФормаСписка = ПолучитьФормуЛкс("Обработка.ирДинамическийСписок.Форма", ПараметрыФормы, ВладелецФормы, КлючУникальности); ФормаСписка.РежимВыбора = РежимВыбора; // Чтобы заголовок сразу правильный сформировался ФормаСписка.УстановитьОбъектМетаданных(ИмяТаблицы); ОтборДинамическогоСписка = ФормаСписка.Отбор(); ПользовательскийОтборДинамическогоСписка = ФормаСписка.ПользовательскийОтбор(); Иначе Если РежимВыбора Тогда Попытка ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаВыбора", ПараметрыФормы, ВладелецФормы, КлючУникальности); Исключение // Например у регистров нет форм выбора КонецПопытки; КонецЕсли; Если ФормаСписка = Неопределено Тогда ФормаСписка = ПолучитьФормуЛкс(ИмяТаблицы + ".ФормаСписка", ПараметрыФормы, ВладелецФормы, КлючУникальности); КонецЕсли; Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда Попытка ОтборДинамическогоСписка = ФормаСписка.Отбор; Исключение КонецПопытки; ПользовательскийОтборДинамическогоСписка = ОтборДинамическогоСписка; КонецЕсли; КонецЕсли; Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда ФормаСписка.РежимВыбора = РежимВыбора; ФормаСписка.ЗакрыватьПриВыборе = Не МножественныйВыбор; ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока; Попытка ФормаСписка.МножественныйВыбор = МножественныйВыбор; Исключение // Есть не у всех форм КонецПопытки; Попытка ФормаСписка.ПараметрТекущаяСтрока = ТекущаяСтрока; Исключение // Есть не у всех форм КонецПопытки; Попытка ФормаСписка.ПараметрТекущаяКолонка = ТекущаяКолонка; Исключение // Есть не у всех форм КонецПопытки; КонецЕсли; Если Истина И ОтборДинамическогоСписка <> Неопределено И Отбор <> Неопределено Тогда СкопироватьОтборЛюбойЛкс(ОтборДинамическогоСписка, Отбор); КонецЕсли; Если Истина И ПользовательскийОтборДинамическогоСписка <> Неопределено И ПользовательскийОтбор <> Неопределено Тогда СкопироватьОтборЛюбойЛкс(ПользовательскийОтборДинамическогоСписка, ПользовательскийОтбор); КонецЕсли; Возврат ФормаСписка; КонецФункции Функция КлючУникальностиДинамическогоСпискаЛкс(Знач ИмяТаблицы, Знач КлючУникальности = "") Экспорт КлючУникальности = ИмяТаблицы + ";" + КлючУникальности; Возврат КлючУникальности; КонецФункции Процедура ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт СтандартнаяОбработка = Ложь; ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); ВыборФайла.Каталог = Элемент.Значение; Если Не ВыборФайла.Выбрать() Тогда Возврат; КонецЕсли; ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, ВыборФайла.Каталог); КонецПроцедуры Функция ОткрытьСсылкуВСпискеЛкс(Ссылка) Экспорт ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)).ПолноеИмя(); СтруктураПараметры = Новый Структура; СтруктураПараметры.Вставить("ТекущаяСтрока", Ссылка); ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор); ФормаСписка.Открыть(); Возврат ФормаСписка; КонецФункции // ИменаКолонок - Строка - имена колонок через запятую Процедура ТабличноеПолеОтобразитьФлажкиЛкс(ОформлениеСтроки, Знач ИменаКолонок) Экспорт Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда ИменаКолонок = СтрРазделитьЛкс(ИменаКолонок, ",", Истина); КонецЕсли; Для Каждого ИмяКолонки Из ИменаКолонок Цикл Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки]; //Если Ячейка.ТолькоПросмотр Тогда // Продолжить; //КонецЕсли; Если ТипЗнч(Ячейка.Значение) = Тип("Булево") Тогда Ячейка.УстановитьФлажок(Ячейка.Значение); Ячейка.УстановитьТекст(""); КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ТабличноеПолеПриИзмененииФлажкаЛкс(ТабличноеПоле, Знач Колонка) Экспорт #Если Сервер И Не Сервер Тогда ТабличноеПоле = Новый ТабличноеПоле; #КонецЕсли Если ТипЗнч(Колонка.ЭлементУправления) = Тип("ПолеВвода") Тогда ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ТабличноеПоле.ТекущаяСтрока); Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя]; Если Не Ячейка.ТолькоПросмотр Тогда Если Истина И Колонка.Данные = "" И Колонка.ДанныеФлажка = "" Тогда Колонка.ЭлементУправления.Значение = Не Ячейка.Значение; //ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение); Иначе //МетаданныеТипа = глПолучитьМетаданныеТипа(ТипЗнч(Элемент.Значение), "ТипСписка", Истина); //РедактированиеВДиалоге = Ложь; //Если Истина // И МетаданныеТипа <> Неопределено // И МетаданныеТипа.КлассМетаданных.Предок = оСсылочный //Тогда // Попытка // ВыбранныйСпособРедактирования = Элемент.СпособРедактирования; // Исключение // КонецПопытки; // РедактированиеВДиалоге = ВыбранныйСпособРедактирования <> СпособРедактированияСписка.ВСписке; //КонецЕсли; //РазрешитьИзменение = Истина; //Если РедактированиеВДиалоге Тогда //Иначе //Элемент.ЗакончитьРедактированиеСтроки(Ложь); ТабличноеПоле.ИзменитьСтроку(); ЗначениеЯчейки = Колонка.ЭлементУправления.Значение; Если ТипЗнч(ЗначениеЯчейки) = Тип("Булево") Тогда //ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ЗначениеЯчейки, , , Ложь); // Так возникает рассогласование флажка и данных в колонке формы ИсследовательКоллекций ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, Не ЗначениеЯчейки, , , Ложь, Ложь); //Элемент.ТекущаяКолонка = Колонка; КонецЕсли; ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь); //КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Функция СоздатьМенеджерСохраненияНастроекФормыЛкс(ЭтаФорма, КлючНазначенияИспользования = "", ЗагружатьСохранятьНастройкуПоУмолчанию = Истина, ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено) Экспорт МенеджерСохраненияНастроек = Новый Структура("СохраненныеНастройки, ПоследняяНастройка, КлючНастроек, ЗагружатьСохранятьНастройкуПоУмолчанию"); МенеджерСохраненияНастроек.КлючНастроек = ирОбщий.ИмяФормыИзФормыЛкс(ЭтаФорма) + ".СохраненныеНастройки"; МенеджерСохраненияНастроек.ЗагружатьСохранятьНастройкуПоУмолчанию = ЗагружатьСохранятьНастройкуПоУмолчанию; Если ЗначениеЗаполнено(КлючНазначенияИспользования) Тогда МенеджерСохраненияНастроек.КлючНастроек = МенеджерСохраненияНастроек.КлючНастроек + "." + КлючНазначенияИспользования; КонецЕсли; СохраненныеНастройкиНовые = Новый ТаблицаЗначений; СохраненныеНастройкиНовые.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); СохраненныеНастройкиНовые.Колонки.Добавить("Значение"); СохраненныеНастройкиНовые.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево")); СохраненныеНастройкиНовые.Колонки.Добавить("ДатаИзменения", Новый ОписаниеТипов("Дата")); СохраненныеНастройкиСтарые = ирОбщий.ВосстановитьЗначениеЛкс(МенеджерСохраненияНастроек.КлючНастроек); Если ТипЗнч(СохраненныеНастройкиСтарые) = Тип("ТаблицаЗначений") Тогда Для Каждого СтрокаСтаройНастройки Из СохраненныеНастройкиСтарые Цикл Если СтрокаСтаройНастройки.Значение <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СохраненныеНастройкиНовые.Добавить(), СтрокаСтаройНастройки); КонецЕсли; КонецЦикла; КонецЕсли; МенеджерСохраненияНастроек.СохраненныеНастройки = СохраненныеНастройкиНовые; СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек = МенеджерСохраненияНастроек; ЗагрузитьНастройкуФормыПоУмолчаниюЛкс(ЭтаФорма, Не ЗагружатьСохранятьНастройкуПоУмолчанию, ПараметрыЗагрузкиНастройкиПоУмолчанию); КонецФункции Процедура ЗагрузитьНастройкуФормыПоУмолчаниюЛкс(Знач ЭтаФорма, Знач ЗагрузитьПустуюНастройку = Ложь, Знач ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено) Экспорт Если ЗагрузитьПустуюНастройку Тогда НастройкаФормы = Неопределено; Иначе МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек; НастройкаПоУмолчанию = ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(МенеджерСохраненияНастроек.СохраненныеНастройки); Если НастройкаПоУмолчанию.Значение = Неопределено Тогда СохранитьНастройкиФормыЛкс(ЭтаФорма); НастройкаПоУмолчанию = ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(МенеджерСохраненияНастроек.СохраненныеНастройки); КонецЕсли; НастройкаФормы = НастройкаПоУмолчанию.Значение; КонецЕсли; //ПоследняяНастройка = МенеджерСохраненияНастроек.СохраненныеНастройки.Индекс(НастройкаПоУмолчанию); ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(ЭтаФорма, НастройкаФормы, ПараметрыЗагрузкиНастройкиПоУмолчанию); КонецПроцедуры Процедура ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(Знач ЭтаФорма, Знач НастройкаФормы, Знач ПараметрыЗагрузкиНастройкиПоУмолчанию = Неопределено) Экспорт ЕстьОбработчикЗагрузкиНастройки = МетодРеализованЛкс(ЭтаФорма, "ЗагрузитьНастройкуВФорме"); Если ЕстьОбработчикЗагрузкиНастройки Тогда ЭтаФорма.ЗагрузитьНастройкуВФорме(НастройкаФормы, ПараметрыЗагрузкиНастройкиПоУмолчанию); Иначе ЗагрузитьНастройкуФормыЛкс(ЭтаФорма, НастройкаФормы); КонецЕсли; КонецПроцедуры Процедура ЗагрузитьНастройкуФормыЛкс(Знач ЭтаФорма, Знач НастройкаФормы) Экспорт Если НастройкаФормы = Неопределено Тогда Возврат; КонецЕсли; ЗаполнитьЗначенияСвойств(ЭтаФорма, НастройкаФормы); Для Каждого КлючИЗначение Из НастройкаФормы Цикл Если Не ЕстьСвойствоОбъектаЛкс(ЭтаФорма, КлючИЗначение.Ключ) Тогда Продолжить; КонецЕсли; ТипЗначения = ТипЗнч(ЭтаФорма[КлючИЗначение.Ключ]); Если ЛиТипЗначенияТабличнойЧастиЛкс(ТипЗначения) Тогда ЭтаФорма[КлючИЗначение.Ключ].Загрузить(КлючИЗначение.Значение); ИначеЕсли ТипЗначения = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда ЭтаФорма[КлючИЗначение.Ключ].ЗагрузитьНастройки(КлючИЗначение.Значение); КонецЕсли; КонецЦикла; КонецПроцедуры Процедура СохранитьНастройкиФормыЛкс(Знач ЭтаФорма) Экспорт МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек; Если МенеджерСохраненияНастроек <> Неопределено И МенеджерСохраненияНастроек.ЗагружатьСохранятьНастройкуПоУмолчанию Тогда НастройкаПоУмолчанию = ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(МенеджерСохраненияНастроек.СохраненныеНастройки); НастройкаПоУмолчанию.Значение = СохраняемаяНастройкаФормыЛкс(ЭтаФорма); СохранитьЗначениеЛкс(МенеджерСохраненияНастроек.КлючНастроек, МенеджерСохраненияНастроек.СохраненныеНастройки); КонецЕсли; КонецПроцедуры Функция ПолучитьНастройкуПоУмолчаниюИзСпискаСохраненныхНастроекЛкс(СписокСохраненныхНастроек) Экспорт ИмяОсновнойНастройки = "Основная"; СтрокаСписка = СписокСохраненныхНастроек.Найти(Истина, "Пометка"); Если СтрокаСписка = Неопределено Тогда СтрокаСписка = СписокСохраненныхНастроек.Найти(ИмяОсновнойНастройки, "Представление"); КонецЕсли; Если СтрокаСписка = Неопределено Тогда СтрокаСписка = СписокСохраненныхНастроек.Добавить(); СтрокаСписка.Представление = ИмяОсновнойНастройки; КонецЕсли; СтрокаСписка.Пометка = Истина; Возврат СтрокаСписка; КонецФункции Функция ВыбратьИСохранитьНастройкуФормыЛкс(ЭтаФорма) Экспорт МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек; НовоеНаименование = Неопределено; СохраняемаяНастройкаФормы = СохраняемаяНастройкаФормыЛкс(ЭтаФорма, НовоеНаименование); мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаСохраненияНастройки = мПлатформа.ПолучитьФорму("ВыборНастройкиДляСохранения"); ФормаСохраненияНастройки.НачальноеЗначениеВыбора = МенеджерСохраненияНастроек.ПоследняяНастройка; ФормаСохраненияНастройки.НовоеНаименование = НовоеНаименование; Если МенеджерСохраненияНастроек.СохраненныеНастройки <> Неопределено Тогда ФормаСохраненияНастройки.СписокНастроек = МенеджерСохраненияНастроек.СохраненныеНастройки; КонецЕсли; ТекущиеДанные = ФормаСохраненияНастройки.ОткрытьМодально(); МенеджерСохраненияНастроек.СохраненныеНастройки = ФормаСохраненияНастройки.СписокНастроек; МенеджерСохраненияНастроек.ПоследняяНастройка = ФормаСохраненияНастройки.НачальноеЗначениеВыбора; Если ТекущиеДанные <> Неопределено Тогда ТекущиеДанные.Значение = СохраняемаяНастройкаФормы; КонецЕсли; СохранитьНастройкиФормыЛкс(ЭтаФорма); КонецФункции Функция СохраняемаяНастройкаФормыЛкс(Знач ЭтаФорма, выхНовоеНаименование = "") Экспорт выхНовоеНаименование = ""; ИменаСвойств = ""; СохраняемаяНастройкаФормы = ЭтаФорма.СохраняемаяНастройкаФормы(выхНовоеНаименование, ИменаСвойств); Если ЗначениеЗаполнено(ИменаСвойств) Тогда ИменаСвойств = СтрЗаменить(ИменаСвойств, "Реквизит.", ""); ИменаСвойств = СтрЗаменить(ИменаСвойств, "Форма.", ""); ИменаСвойств = СтрЗаменить(ИменаСвойств, "Табличная часть.", ""); МассивИмен = СтрРазделитьЛкс(ИменаСвойств, ",", Истина, Ложь); ЗначенияСвойств = Новый Структура(ИменаСвойств); ЗаполнитьЗначенияСвойств(ЗначенияСвойств, ЭтаФорма, ИменаСвойств); Для Каждого ИмяСвойства Из МассивИмен Цикл ТипЗначения = ТипЗнч(ЗначенияСвойств[ИмяСвойства]); Если ЛиТипЗначенияТабличнойЧастиЛкс(ТипЗначения) Тогда ЗначенияСвойств[ИмяСвойства] = ЗначенияСвойств[ИмяСвойства].Выгрузить(); ИначеЕсли ТипЗначения = Тип("КомпоновщикНастроекКомпоновкиДанных") Тогда ЗначенияСвойств[ИмяСвойства] = ЗначенияСвойств[ИмяСвойства].ПолучитьНастройки(); КонецЕсли; КонецЦикла; Если СохраняемаяНастройкаФормы = Неопределено Тогда СохраняемаяНастройкаФормы = Новый Структура; КонецЕсли; СкопироватьУниверсальнуюКоллекциюЛкс(ЗначенияСвойств, СохраняемаяНастройкаФормы); КонецЕсли; Возврат СохраняемаяНастройкаФормы; КонецФункции Функция ЛиТипЗначенияТабличнойЧастиЛкс(Знач ТипЗначения) Экспорт Возврат Найти(НРег(ТипЗначения), ПеревестиСтроку("табличная часть")) > 0; КонецФункции Функция ВыбратьИЗагрузитьНастройкуФормыЛкс(ЭтаФорма) Экспорт МенеджерСохраненияНастроек = СлужебныеДанныеФормыЛкс(ЭтаФорма).МенеджерСохраненияНастроек; Если МенеджерСохраненияНастроек.СохраненныеНастройки = Неопределено Тогда Возврат Неопределено; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаСохраненияНастройки = мПлатформа.ПолучитьФорму("ВыборНастройкиДляЗагрузки"); ФормаСохраненияНастройки.НачальноеЗначениеВыбора = МенеджерСохраненияНастроек.ПоследняяНастройка; Если МенеджерСохраненияНастроек.СохраненныеНастройки <> Неопределено Тогда ФормаСохраненияНастройки.СписокНастроек = МенеджерСохраненияНастроек.СохраненныеНастройки; КонецЕсли; ТекущиеДанные = ФормаСохраненияНастройки.ОткрытьМодально(); МенеджерСохраненияНастроек.СохраненныеНастройки = ФормаСохраненияНастройки.СписокНастроек; МенеджерСохраненияНастроек.ПоследняяНастройка = ФормаСохраненияНастройки.НачальноеЗначениеВыбора; Если ТекущиеДанные <> Неопределено И ТекущиеДанные.Значение <> Неопределено Тогда ЗагрузитьНастройкуФормыЧерезОбработчикЛкс(ЭтаФорма, ТекущиеДанные.Значение); КонецЕсли; СохранитьНастройкиФормыЛкс(ЭтаФорма); КонецФункции Функция ПолучитьПиктограммуТипаЛкс(Тип) Экспорт ИмяОбщегоТипа = Неопределено; КлючПоиска = Новый Структура("ИД,ТипТипа", ПолучитьИдентификаторТипаЛкс(Тип), "Основной"); мПлатформа = ирКэш.Получить(); мПлатформа.ИнициализацияОписанияОбщихТипов(); НайденныеСтроки = мПлатформа.ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда ИмяОбщегоТипа = НайденныеСтроки[0].Слово; Иначе //СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип); //ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; ОбъектМД = Метаданные.НайтиПоТипу(Тип); Если ОбъектМД <> Неопределено Тогда ТекущееИмяТипа = ОбъектМД.ПолноеИмя(); ИмяОбщегоТипа = ПервыйФрагментЛкс(ТекущееИмяТипа); КонецЕсли; КонецЕсли; Картинка = Неопределено; Если ИмяОбщегоТипа <> Неопределено Тогда ИмяКартинки = "ир" + ПервыйФрагментЛкс(ИмяОбщегоТипа); Попытка Картинка = ирКэш.КартинкаПоИмениЛкс(ИмяКартинки); Исключение ИмяКартинки = ИмяОбщегоТипа; Попытка Картинка = БиблиотекаКартинок[ИмяКартинки]; Исключение КонецПопытки; КонецПопытки; КонецЕсли; Возврат Картинка; КонецФункции Функция ПрочитатьДополнительныеПоляСсылающихсяОбъектовЛкс(Знач ТабличноеПоле, Знач КомпоновщикДопПолей, Знач ТаблицаДанных = Неопределено, ИмяПоляСсылки = "Данные") Экспорт #Если Сервер И Не Сервер Тогда КомпоновщикДопПолей = Новый КомпоновщикНастроекКомпоновкиДанных; #КонецЕсли Если ТаблицаДанных = Неопределено Тогда ТаблицаДанных = ДанныеЭлементаФормыЛкс(ТабличноеПоле); КонецЕсли; КомпоновщикДопПолей.Восстановить(СпособВосстановленияНастроекКомпоновкиДанных.Полное); МассивДопПолей = Новый Структура(); ДопустимоеЧислоДопПолей = 5; Счетчик = 1; СтрокаПорядка = ""; СтрокаВыбора = ""; Для Каждого ПолеПорядка Из КомпоновщикДопПолей.Настройки.Порядок.Элементы Цикл Если ПолеПорядка.Использование Тогда ИмяПоля = "" + ПолеПорядка.Поле; ИмяКолонки = "Реквизит" + Счетчик; ДоступноеПоле = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(ПолеПорядка.Поле); Если Счетчик > ДопустимоеЧислоДопПолей Тогда СообщитьЛкс("Дополнительное поле """ + ДоступноеПоле.Заголовок + """ пропущено, т.к. допускается не более " + ДопустимоеЧислоДопПолей + " полей"); Продолжить; КонецЕсли; МассивДопПолей.Вставить(ИмяКолонки, ИмяПоля); КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки]; КолонкаТП.Видимость = Истина; КолонкаТП.ТекстШапки = ДоступноеПоле.Заголовок; Если СтрокаПорядка <> "" Тогда СтрокаПорядка = СтрокаПорядка + ","; КонецЕсли; СтрокаПорядка = СтрокаПорядка + ИмяКолонки + " "; Если ПолеПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда СтрокаПорядка = СтрокаПорядка + "Возр"; Иначе СтрокаПорядка = СтрокаПорядка + "Убыв"; КонецЕсли; СтрокаВыбора = СтрокаВыбора + ", | Т." + ИмяПоля + " КАК " + ИмяКолонки; Счетчик = Счетчик + 1; КонецЕсли; КонецЦикла; Если Не ЗначениеЗаполнено(СтрокаПорядка) Тогда СтрокаПорядка = "Дата"; КонецЕсли; Для Счетчик = Счетчик По ДопустимоеЧислоДопПолей Цикл ИмяКолонки = "Реквизит" + Счетчик; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда КолонкаТП = ТабличноеПоле.ПодчиненныеЭлементы[ТабличноеПоле.Имя + ИмяКолонки]; Иначе КолонкаТП = ТабличноеПоле.Колонки[ИмяКолонки]; КонецЕсли; КолонкаТП.Видимость = Ложь; КонецЦикла; СтандартныеРеквизиты = Новый Структура; СтандартныеРеквизиты.Вставить("ПометкаУдаления", "ЛОЖЬ"); СтандартныеРеквизиты.Вставить("Проведен", "ЛОЖЬ"); СтандартныеРеквизиты.Вставить("ЭтоГруппа", "ЛОЖЬ"); СтандартныеРеквизиты.Вставить("Дата", "ДАТАВРЕМЯ(1,1,1)"); Для Каждого КлючИЗначение Из СтандартныеРеквизиты Цикл ИмяРеквизита = КлючИЗначение.Ключ; Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект." + ИмяРеквизита)) = Неопределено Тогда Продолжить; КонецЕсли; СтрокаВыбора = СтрокаВыбора + ", | ЕСТЬNULL(Т.Объект." + ИмяРеквизита + ", " + КлючИЗначение.Значение + ") КАК " + ИмяРеквизита; КонецЦикла; Если ТипЗнч(ТаблицаДанных) <> Тип("ТаблицаЗначений") Тогда //КопияТаблицыДанных = ТаблицаДанных.Выгрузить(, ИмяПоляСсылки); КопияТаблицыДанных = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле); Иначе КопияТаблицыДанных = ТаблицаДанных; КонецЕсли; КопияТаблицыДанных = ирОбщий.ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(КопияТаблицыДанных,, ИмяПоляСсылки); ОписаниеТиповСсылки = КопияТаблицыДанных.Колонки[ИмяПоляСсылки].ТипЗначения; ПорцияОбъектов = Новый ТаблицаЗначений; ПорцияОбъектов.Колонки.Добавить("Объект", ОписаниеТиповСсылки); ПорцияОбъектов.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число")); РазмерПорции = 10000; КоличествоПорций = Цел(ТаблицаДанных.Количество() / РазмерПорции) + 1; Запрос = Новый Запрос; ТекстЗапроса = " |ВЫБРАТЬ Т.* ПОМЕСТИТЬ Т ИЗ &Т КАК Т; |ВЫБРАТЬ Т.Объект, Т.Индекс" + СтрокаВыбора + " |ИЗ Т КАК Т"; Запрос.Текст = ТекстЗапроса; ИндексСтроки = 0; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоПорций, "Чтение дополнительных полей"); ДоступноеПолеОбъект = КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.НайтиПоле(Новый ПолеКомпоновкиДанных("Объект")); Для СчетчикПорций = 1 По КоличествоПорций Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); ПорцияОбъектов.Очистить(); Для Счетчик = 1 По РазмерПорции Цикл Если ИндексСтроки = ТаблицаДанных.Количество() Тогда Прервать; КонецЕсли; СтрокаОбъекта = ТаблицаДанных[ИндексСтроки]; ИндексСтроки = ИндексСтроки + 1; Если Ложь Или ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки]) = Тип("Строка") Или СтрокаОбъекта[ИмяПоляСсылки] = Неопределено Или ДоступноеПолеОбъект = Неопределено Или Не ДоступноеПолеОбъект.ТипЗначения.СодержитТип(ТипЗнч(СтрокаОбъекта[ИмяПоляСсылки])) Тогда СтрокаОбъекта.ИндексКартинки = 12; // Регистр сведений Продолжить; КонецЕсли; СтрокаПорции = ПорцияОбъектов.Добавить(); СтрокаПорции.Объект = СтрокаОбъекта[ИмяПоляСсылки]; СтрокаПорции.Индекс = ИндексСтроки - 1; КонецЦикла; Запрос.УстановитьПараметр("Т", ПорцияОбъектов); РезультатЗапроса = Запрос.Выполнить(); РеквизитыПорции = РезультатЗапроса.Выгрузить(); Для Каждого СтрокаПорции Из РеквизитыПорции Цикл СтрокаОбъекта = ТаблицаДанных[СтрокаПорции.Индекс]; СтрокаОбъекта.ИндексКартинки = ирОбщий.ПолучитьИндексКартинкиСсылкиЛкс(СтрокаПорции.Объект, Истина, СтрокаПорции); ЗаполнитьЗначенияСвойств(СтрокаОбъекта, СтрокаПорции); КонецЦикла; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); СтрокаПорядка = "Метаданные," + СтрокаПорядка; Возврат СтрокаПорядка; КонецФункции Процедура ОбновитьДоступныеПоляДляДополнительныхПолейЛкс(Знач ТаблицаДанных, Знач КомпоновщикДопПолей, Знач ТабличноеПолеДоступныхПолей) Экспорт //Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() = 0 Тогда Если ТипЗнч(ТаблицаДанных) = Тип("ТаблицаЗначений") Тогда ПолныеИменаМД = ТаблицаДанных.Скопировать(, "Метаданные"); Иначе ПолныеИменаМД = ТаблицаДанных.Выгрузить(, "Метаданные"); КонецЕсли; ПолныеИменаМД.Свернуть("Метаданные"); ПолныеИменаМД = ПолныеИменаМД.ВыгрузитьКолонку(0); МассивТипов = Новый Массив(); Для Каждого ПолноеИмяМД Из ПолныеИменаМД Цикл Если ТипЗнч(ПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда ПолноеИмяМД = ПолноеИмяМД.ПолноеИмя(); КонецЕсли; Попытка Тип = Тип(ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ПолноеИмяМД)); Исключение Продолжить; КонецПопытки; МассивТипов.Добавить(Тип); КонецЦикла; Если МассивТипов.Количество() > 0 Тогда КоллекцияПолей = Новый Массив(); КоллекцияПолей.Добавить(Новый Структура("Имя, ТипЗначения", "Объект", Новый ОписаниеТипов(МассивТипов))); ТекстЗапроса = ирОбщий.ПолучитьЗапросИмитаторКоллекцииПолейЛкс(КоллекцияПолей); СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса); Иначе СхемаКомпоновки = Новый СхемаКомпоновкиДанных; КонецЕсли; Если ТипЗнч(ТабличноеПолеДоступныхПолей) = Тип("ТаблицаФормы") Тогда ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПолеДоступныхПолей); ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПоместитьВоВременноеХранилище(СхемаКомпоновки), ЭтаФорма.УникальныйИдентификатор); Иначе ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновки); КонецЕсли; КомпоновщикДопПолей.Инициализировать(ИсточникДоступныхНастроек); Если КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы.Количество() > 0 Тогда #Если Клиент И Не Сервер Тогда ТабличноеПолеДоступныхПолей.Развернуть(КомпоновщикДопПолей.Настройки.ДоступныеПоляПорядка.Элементы[0]); #КонецЕсли КонецЕсли; //КонецЕсли; КонецПроцедуры // ИменаКолонок - Строка - имена колонок через запятую Процедура ТабличноеПолеОтобразитьПиктограммыТиповЛкс(ОформлениеСтроки, ИменаКолонок) Экспорт Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда ИменаКолонок = СтрРазделитьЛкс(ИменаКолонок, ",", Истина); КонецЕсли; Для Каждого ИмяКолонки Из ИменаКолонок Цикл Ячейка = ОформлениеСтроки.Ячейки.Найти(ИмяКолонки); //:Ячейка=Новый("ОформлениеЯчейки") Если Ячейка <> Неопределено Тогда ДанныеКартинки = Ячейка.Значение; Если ТипЗнч(ДанныеКартинки) = Тип("ПолеКомпоновкиДанных") Тогда Продолжить; КонецЕсли; СсылкаКартинка = Неопределено; ТипЗначения = ТипЗнч(ДанныеКартинки); Если Истина И ТипЗначения = Тип("Булево") И Ячейка.ОтображатьФлажок Тогда Продолжить; КонецЕсли; КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения); Если КартинкаТипа <> Неопределено Тогда Ячейка.УстановитьКартинку(КартинкаТипа); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // Получает картинку для корневого типа конфигурации. // // Параметры: // пКорневойТип – Строка – корневой тип конфигурации. // // Возвращаемое значение: // – Картинка – корневого типа конфигурации. // Функция ПолучитьКартинкуКорневогоТипаЛкс(Знач пКорневойТип) Экспорт Если СтрокиРавныЛкс("Изменения", пКорневойТип) Тогда Картинка = ирКэш.КартинкаПоИмениЛкс("ирТаблицаИзменений"); КонецЕсли; Если Картинка = Неопределено Тогда Картинка = ирКэш.КартинкаПоИмениЛкс("ир" + пКорневойТип); КонецЕсли; Если Картинка = Неопределено Или Картинка.Вид = ВидКартинки.Пустая Тогда //Попытка // Так почему то медленно работает // Картинка = БиблиотекаКартинок[пКорневойТип]; //Исключение //КонецПопытки; Картинка = ирКэш.КартинкаПоИмениЛкс(пКорневойТип); КонецЕсли; Если Картинка = Неопределено Тогда Картинка = Новый Картинка(); КонецЕсли; Возврат Картинка; КонецФункции // ПолучитьКартинкуКорневогоТипа() Функция ОткрытьТекущуюСтрокуТабличногоПоляТаблицыБДВРедактореОбъектаБДЛкс(ТабличноеПоле, ПолноеИмяМД = Неопределено, ДоступныеПоляВыбора = Неопределено, Связанный = Ложь, ФормаРедактора = Неопределено, ОбъектыНаСервере = Неопределено, ДляПодчиненногоРегистраСведенийНомерСтроки = Истина, ПриОтсутствииСтрокиОткрытьНовыйОбъект = Ложь, ИмяКолонкиДанных = Неопределено) Экспорт ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока; Если Не ПриОтсутствииСтрокиОткрытьНовыйОбъект И ТекущаяСтрока = Неопределено Тогда Возврат Неопределено; КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда Если ПолноеИмяМД = Неопределено Тогда ПолноеИмяМД = ДанныеЭлементаФормыЛкс(ТабличноеПоле).ОсновнаяТаблица; КонецЕсли; Если ИмяКолонкиДанных = Неопределено Тогда ТекущаяКолонка = ТабличноеПоле.ТекущийЭлемент; Если ТекущаяКолонка <> Неопределено Тогда ИмяКолонкиДанных = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТекущаяКолонка, Истина); КонецЕсли; КонецЕсли; Иначе Если ПолноеИмяМД = Неопределено Тогда ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя(); КонецЕсли; Если ИмяКолонкиДанных = Неопределено Тогда ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка; Если ТекущаяКолонка <> Неопределено Тогда ИмяКолонкиДанных = ТекущаяКолонка.Данные; КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ИмяКолонкиДанных <> Неопределено И (Ложь Или ДоступныеПоляВыбора = Неопределено Или ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ИмяКолонкиДанных)) <> Неопределено) Тогда ИмяКолонки = ИмяКолонкиДанных; Иначе ИмяКолонки = ""; КонецЕсли; ПолноеИмяТаблицы = ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); Если ТабличноеПоле.ТекущиеДанные <> Неопределено Тогда КлючОбъекта = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТабличноеПоле.ТекущиеДанные, ДляПодчиненногоРегистраСведенийНомерСтроки,, ОбъектыНаСервере); КонецЕсли; КорневойТип = ПервыйФрагментЛкс(ПолноеИмяТаблицы); Если КлючОбъекта = Неопределено Тогда Если Ложь Или ЛиКорневойТипСсылкиЛкс(КорневойТип) Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Тогда Если ТекущаяСтрока <> Неопределено Тогда ТипКлюча = ТипЗнч(ТекущаяСтрока.Ссылка); Иначе ТипКлюча = Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ПолноеИмяМД)); КонецЕсли; КлючОбъекта = Новый (ТипКлюча); ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипКлюча).ПолноеИмя(); Иначе КлючОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы,,, Ложь, ОбъектыНаСервере); КонецЕсли; КонецЕсли; ОткрытьРедакторОбъектаБДЛкс(ПолноеИмяТаблицы, ИмяКолонки, Связанный, КлючОбъекта, ОбъектыНаСервере, ТабличноеПоле.ТекущиеДанные, ТабличноеПоле.ТекущаяСтрока, ФормаРедактора); Возврат ФормаРедактора; КонецФункции Функция ОткрытьРедакторОбъектаБДЛкс(ПолноеИмяТаблицы, ИмяРеквизита, Связанный = Ложь, Знач КлючОбъекта = Неопределено, Знач ОбъектыНаСервере = Неопределено, Знач ТекущиеДанныеТабличногоПоля = Неопределено, ТекущаяСтрокаТабличногоПоля = Неопределено, ФормаРедактора = Неопределено) Экспорт Если ФормаРедактора = Неопределено Тогда КлючУникальности = ТекущаяСтрокаТабличногоПоля; Если Связанный Тогда КлючУникальности = "Связанный"; КонецЕсли; ФормаРедактора = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", , , КлючУникальности); КонецЕсли; Если КлючОбъекта <> Неопределено Тогда Если Не ФормаРедактора.Открыта() Тогда ПараметрыФормы = Новый Структура("ПараметрКлючИлиОбъект, ПараметрПрочитатьОбъект", КлючОбъекта, Истина); ЗаполнитьЗначенияСвойств(ФормаРедактора.фОбъект, ПараметрыФормы); Иначе ФормаРедактора.ЗагрузитьОбъектПоКлючу(КлючОбъекта); КонецЕсли; Иначе ФормаРедактора.УстановитьТаблицуБД(ПолноеИмяТаблицы); КонецЕсли; ФормаРедактора.Открыть(); СтруктураЛокальногоКлючаСтроки = Неопределено; Если ТекущиеДанныеТабличногоПоля <> Неопределено Тогда КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТекущиеДанныеТабличногоПоля, Истина, СтруктураЛокальногоКлючаСтроки, ОбъектыНаСервере); КонецЕсли; ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ПолноеИмяТаблицы, ИмяРеквизита, СтруктураЛокальногоКлючаСтроки); Возврат ФормаРедактора; КонецФункции Функция _КонтрольРазмераВыборкиПользователемЛкс(ЗапросИлиПостроитель, МаксимальноеЧислоСтрок = 500000) Экспорт КоличествоСтрокРезультата = ирКэш.Получить().ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(ЗапросИлиПостроитель); Если Истина И ТипЗнч(КоличествоСтрокРезультата) = Тип("Число") И КоличествоСтрокРезультата > МаксимальноеЧислоСтрок Тогда Кнопки = Новый СписокЗначений; Кнопки.Добавить("Все", "Все"); Кнопки.Добавить("Часть", "Первые " + Формат(МаксимальноеЧислоСтрок, "ЧГ=")); Ответ = Вопрос("Загружаемая таблица содержит " + КоличествоСтрокРезультата + " строк. Сколько строк загружать?", Кнопки, , "Часть"); //Если Ответ <> КодВозвратаДиалога.ОК Тогда // Возврат; //КонецЕсли; Если Ответ = "Все" Тогда МаксимальноеЧислоСтрок = 0; КонецЕсли; Иначе МаксимальноеЧислоСтрок = 0; КонецЕсли; Возврат МаксимальноеЧислоСтрок; КонецФункции // Параметры: // ИмяКлючевойКолонки - Строка - содержит имя таблицы // Функция ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных = Неопределено, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь) Экспорт МассивКлючей = Новый Массив; Если ДеревоМетаданных <> Неопределено Тогда #Если Сервер И Не Сервер Тогда ДеревоМетаданных = Новый ДеревоЗначений #КонецЕсли Для Каждого СтрокаДерева1 Из ДеревоМетаданных.Строки Цикл Для Каждого СтрокаДерева2 Из СтрокаДерева1.Строки Цикл КорневойТип = ПервыйФрагментЛкс(СтрокаДерева2[ИмяКлючевойКолонки]); Если Ложь Или КорневойТип = "ВнешнийИсточникДанных" Или КорневойТип = "РегламентноеЗадание" Или КорневойТип = "ОбщаяФорма" Или КорневойТип = "Интерфейс" Или КорневойТип = "Отчет" Или КорневойТип = "Обработка" Тогда Продолжить; КонецЕсли; ИмяТаблицы = СтрокаДерева2[ИмяКлючевойКолонки]; Если ИмяТаблицы = Неопределено Тогда Продолжить; КонецЕсли; Если ОбъектМДПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы) = Неопределено Тогда Продолжить; КонецЕсли; МассивКлючей.Добавить(ИмяТаблицы); Для Каждого СтрокаДерева3 Из СтрокаДерева2.Строки Цикл МассивКлючей.Добавить(СтрокаДерева3[ИмяКлючевойКолонки]); КонецЦикла; КонецЦикла; КонецЦикла; КлючамиЗаданыИменаТаблиц = Ложь; Иначе ЛокальныеТаблицы = ирКэш.ТаблицаВсехТаблицБДЛкс().Скопировать(Новый Структура("Схема", ""), "ПолноеИмя, Тип"); НачальноеКоличество = ЛокальныеТаблицы.Количество(); Для СчетчикЛокальныеТаблицы = 1 По НачальноеКоличество Цикл ОписаниеТаблицы = ЛокальныеТаблицы[НачальноеКоличество - СчетчикЛокальныеТаблицы]; Если ОписаниеТаблицы.Тип = "ВиртуальнаяТаблица" Тогда ЛокальныеТаблицы.Удалить(ОписаниеТаблицы); КонецЕсли; КонецЦикла; МассивКлючей = ЛокальныеТаблицы.ВыгрузитьКолонку("ПолноеИмя"); КлючамиЗаданыИменаТаблиц = Истина; КонецЕсли; ТекстПакета = ""; ТекстЗапроса = ""; СчетчикТаблиц = 0; Для Каждого ПолноеИмяМД Из МассивКлючей Цикл ТекстЧастиОбъединения = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные, КлючамиЗаданыИменаТаблиц); Если ТекстЧастиОбъединения = Неопределено Тогда Продолжить; КонецЕсли; Если ТекстЗапроса <> "" Тогда ТекстЗапроса = ТекстЗапроса + " |ОБЪЕДИНИТЬ ВСЕ"; КонецЕсли; ТекстЗапроса = ТекстЗапроса + ТекстЧастиОбъединения; СчетчикТаблиц = СчетчикТаблиц + 1; Если СчетчикТаблиц = 255 Тогда СчетчикТаблиц = 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 Тогда ТабличноеПоле.Развернуть(ТабличноеПоле.ТекущаяСтрока); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ТабличноеПолеСортироватьЛкс(ЭтаФорма, ТабличноеПоле, ПоВозрастанию = Истина) Экспорт ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка; Если ТекущаяКолонка = Неопределено Тогда Возврат; КонецЕсли; ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда СообщитьЛкс("Сортировка по этой колонке невозможна"); Возврат; КонецЕсли; Продолжаем = ПредупреждениеПередСортировкойПоСсылочнымКолонкамЛкс(ИмяКолонки, ТабличноеПоле); Если Не Продолжаем Тогда Возврат; КонецЕсли; Если ПоВозрастанию Тогда СтрокаСортировки = ИмяКолонки + " Возр"; Иначе СтрокаСортировки = ИмяКолонки + " Убыв"; КонецЕсли; Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда Родитель = ПолучитьРодителяСтрокиДереваЛкс(ТабличноеПоле.ТекущаяСтрока); КоллекцияСтрок = Родитель.Строки; Иначе КоллекцияСтрок = ТабличноеПоле.Значение; КонецЕсли; КоллекцияСтрок.Сортировать(СтрокаСортировки); КонецПроцедуры // http://www.hostedredmine.com/issues/877327 https://partners.v8.1c.ru/forum/t/1919734/m/1919734 Функция ПредупреждениеПередСортировкойПоСсылочнымКолонкамЛкс(Знач ИменаКолонок, Знач ТабличноеПоле, ОпасноеКоличествоСсылок = 5000) Экспорт Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда Родитель = ПолучитьРодителяСтрокиДереваЛкс(ТабличноеПоле.ТекущаяСтрока); КоллекцияСтрок = Родитель.Строки; Иначе КоллекцияСтрок = ТабличноеПоле.Значение; КонецЕсли; #Если Сервер И Не Сервер Тогда КоллекцияСтрок = Новый ТаблицаЗначений; #КонецЕсли Продолжаем = Истина; МассивИмен = СтрРазделитьЛкс(ИменаКолонок, ",", Истина); Если КоллекцияСтрок.Количество() * МассивИмен.Количество() > ОпасноеКоличествоСсылок Тогда МетаТЧ = Метаданные.НайтиПоТипу(ТипЗнч(КоллекцияСтрок[0])); Если МетаТЧ <> Неопределено Тогда Колонки = ТабличноеПоле.Значение.ВыгрузитьКолонки().Колонки; Иначе Колонки = КоллекцияСтрок[0].Владелец().Колонки; КонецЕсли; КоличествоСсылочныхКолонок = 0; НепустыеЗначенияПростыхСсылочныхКолонок = Новый СписокЗначений; Для Каждого ИмяКолонки Из МассивИмен Цикл КоличествоСсылочныхТипов = 0; Для Каждого Тип Из Колонки[ИмяКолонки].ТипЗначения.Типы() Цикл Если ирОбщий.ЛиТипСсылкиБДЛкс(Тип) Тогда КоличествоСсылочныхТипов = КоличествоСсылочныхТипов + 1; Если КоличествоСсылочныхТипов > 1 Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Если КоличествоСсылочныхТипов = 1 Тогда НепустыеЗначенияПростыхСсылочныхКолонок.Добавить(, ИмяКолонки); КонецЕсли; Если КоличествоСсылочныхТипов > 0 Тогда КоличествоСсылочныхКолонок = КоличествоСсылочныхКолонок + 1; КонецЕсли; КонецЦикла; Если КоличествоСсылочныхКолонок * КоллекцияСтрок.Количество() > ОпасноеКоличествоСсылок Тогда Ответ = Вопрос("Сортировка в памяти большого числа ссылочных значений может длиться долго, если для них задано динамическое представление. Сортировать?", РежимДиалогаВопрос.ДаНет, 10, КодВозвратаДиалога.Да); Если Ответ = КодВозвратаДиалога.Нет Тогда Продолжаем = Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Продолжаем; КонецФункции Процедура ТабличноеПолеПорядкаКомпоновкиВыборЛкс(Знач Элемент, Знач ВыбраннаяСтрока, Знач Колонка, СтандартнаяОбработка) Экспорт Если Колонка = Элемент.Колонки.ТипУпорядочивания Тогда Если ВыбраннаяСтрока.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда ВыбраннаяСтрока.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв; Иначе ВыбраннаяСтрока.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр; КонецЕсли; СтандартнаяОбработка = Ложь; КонецЕсли; КонецПроцедуры Процедура ТабличноеПолеЭлементовКомпоновкиПеретаскиваниеЛкс(Знач Элемент, Знач ПараметрыПеретаскивания, СтандартнаяОбработка, Знач Строка, Знач Колонка) Экспорт ЭлементыКомпоновки = Элемент.Значение; #Если Сервер И Не Сервер Тогда Пустышка = Новый НастройкиКомпоновкиДанных; ЭлементыКомпоновки = Пустышка.Порядок; #КонецЕсли ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; Если ТипЗнч(ЗначениеПеретаскивания) = Тип("Массив") Тогда Если ТипЗнч(ЗначениеПеретаскивания[0]) = Тип("ДоступноеПолеКомпоновкиДанных") Тогда СтандартнаяОбработка = Ложь; Для Каждого ЭлементПеретаскивания Из ЗначениеПеретаскивания Цикл КоллекцияПриемник = ЭлементыКомпоновки.Элементы; Если Строка <> Неопределено Тогда Попытка КоллекцияПриемник = Строка.Элементы; Исключение КонецПопытки; КонецЕсли; НовыйЭлемент = НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(КоллекцияПриемник, ЭлементПеретаскивания.Поле, ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение); Если Строка <> Неопределено Тогда СдвинутьЭлементКоллекцииНаПозициюДругогоЭлементаЛкс(КоллекцияПриемник, НовыйЭлемент, Строка); КонецЕсли; КонецЦикла; Элемент.ТекущаяСтрока = НовыйЭлемент; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура СдвинутьЭлементКоллекцииНаПозициюДругогоЭлементаЛкс(Знач Коллекция, Знач СдвигаемыйЭлемент, Знач ЭлементСЦелевойПозицией) Экспорт #Если Сервер И Не Сервер Тогда Коллекция = Новый ТаблицаЗначений; #КонецЕсли Коллекция.Сдвинуть(СдвигаемыйЭлемент, Коллекция.Индекс(ЭлементСЦелевойПозицией) - Коллекция.Индекс(СдвигаемыйЭлемент)); КонецПроцедуры Процедура ПрименитьСтрокуПоискаКТабличномуПолюДереваЛкс(ТабличноеПолеДерева, СтрокаПоиска, ИменаКолонокДанныхДляПоиска, выхСтруктураПоиска, АктивизироватьПервуюСтроку = Истина) Экспорт СтруктураКолонок = Новый Структура(ИменаКолонокДанныхДляПоиска); НайденныеСтрокиДерева = Новый Массив(); Если ЗначениеЗаполнено(СтрокаПоиска) Тогда ВсеСтроки = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение); ИндексТекущейСтроки = ВсеСтроки.Найти(ТабличноеПолеДерева.ТекущаяСтрока); ИндексАктивизируемойСтроки = Неопределено; Для Каждого СтрокаДерева Из ВсеСтроки Цикл Для Каждого КлючИЗначение Из СтруктураКолонок Цикл ИнтереснаяКолонка = КлючИЗначение.Ключ; Значение = СтрокаДерева[ИнтереснаяКолонка]; Если ТипЗнч(Значение) = Тип("Строка") Тогда Значение = НРег(Значение); Если Найти(Значение, НРег(СтрокаПоиска)) > 0 Тогда НайденныеСтрокиДерева.Добавить(СтрокаДерева); Если ИндексТекущейСтроки <> Неопределено И ВсеСтроки.Найти(СтрокаДерева) >= ИндексТекущейСтроки И ИндексАктивизируемойСтроки = Неопределено Тогда ИндексАктивизируемойСтроки = НайденныеСтрокиДерева.Количество() - 1; КонецЕсли; Родитель = СтрокаДерева; Пока Родитель <> Неопределено Цикл Если Не ТабличноеПолеДерева.Развернут(Родитель) Тогда ТабличноеПолеДерева.Развернуть(Родитель); КонецЕсли; Родитель = Родитель.Родитель; КонецЦикла; Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; Если АктивизироватьПервуюСтроку И НайденныеСтрокиДерева.Количество() > 0 Тогда Если ИндексАктивизируемойСтроки = Неопределено Тогда ИндексАктивизируемойСтроки = 0; КонецЕсли; ТабличноеПолеДерева.ТекущаяСтрока = НайденныеСтрокиДерева[ИндексАктивизируемойСтроки]; КонецЕсли; КонецЕсли; ТекущийИндексНайденнойСтроки = 0; выхСтруктураПоиска = Новый Структура("ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева", ТекущийИндексНайденнойСтроки, НайденныеСтрокиДерева); КонецПроцедуры Процедура СледующееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт Если СтруктураПоиска = Неопределено Тогда Возврат; КонецЕсли; Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки + 1; Если СтруктураПоиска.ТекущийИндексНайденнойСтроки >= СтруктураПоиска.НайденныеСтрокиДерева.Количество() Тогда СтруктураПоиска.ТекущийИндексНайденнойСтроки = 0; КонецЕсли; ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки]; КонецЕсли; КонецПроцедуры Процедура ПредыдущееВхождениеСтрокиПоискаВТабличномПолеДереваЛкс(ТабличноеПолеДерева, СтруктураПоиска) Экспорт Если СтруктураПоиска = Неопределено Тогда Возврат; КонецЕсли; Если СтруктураПоиска.НайденныеСтрокиДерева.Количество() > 0 Тогда СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.ТекущийИндексНайденнойСтроки - 1; Если СтруктураПоиска.ТекущийИндексНайденнойСтроки < 0 Тогда СтруктураПоиска.ТекущийИндексНайденнойСтроки = СтруктураПоиска.НайденныеСтрокиДерева.Количество() - 1; КонецЕсли; ТабличноеПолеДерева.ТекущаяСтрока = СтруктураПоиска.НайденныеСтрокиДерева[СтруктураПоиска.ТекущийИндексНайденнойСтроки]; КонецЕсли; КонецПроцедуры Процедура ОформитьСтрокуВТабличномПолеДереваСПоискомЛкс(ТабличноеПолеДерева, ОформлениеСтроки, ДанныеСтроки, СтруктураПоиска) Экспорт Если СтруктураПоиска = Неопределено Тогда Возврат; КонецЕсли; Если СтруктураПоиска.НайденныеСтрокиДерева.Найти(ДанныеСтроки) <> Неопределено Тогда ОформлениеСтроки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения"); КонецЕсли; КонецПроцедуры Функция ДобавитьСсылкуВИзбранноеЛкс(Ссылка, ДобавлятьВИзбранноеРаботыПользователя = Истина, ДобавлятьВИзрабнноеИнтерфейснойПанели = Истина) Экспорт Если ДобавлятьВИзбранноеРаботыПользователя Тогда Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя"); Если Избранное = Неопределено Тогда Избранное = Новый ИзбранноеРаботыПользователя; КонецЕсли; ЭлементИзбранного = Новый ЭлементИзбранногоРаботыПользователя; ЭлементИзбранного.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка); Избранное.Добавить(ЭлементИзбранного); ХранилищеСистемныхНастроек.Сохранить("Общее/ИзбранноеРаботыПользователя", "", Избранное); ОбновитьИнтерфейс(); КонецЕсли; Если ДобавлятьВИзрабнноеИнтерфейснойПанели Тогда ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма"); СтруктураЭлемента = Новый Структура(); СтруктураЭлемента.Вставить("Вид", Ссылка.Метаданные().ПолноеИмя()); СтруктураЭлемента.Вставить("Имя", Ссылка); НоваяСтрока = ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, "Избранное"); Если ФормаИнтерфейснойПанели.Открыта() Тогда ФормаИнтерфейснойПанели.ЗаполнитьСтатическиеВеткиДереваИнтерфейса(ФормаИнтерфейснойПанели, НоваяСтрока); Иначе ФормаИнтерфейснойПанели.СохранитьНастройки(ФормаИнтерфейснойПанели); КонецЕсли; КонецЕсли; КонецФункции // Процедура ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, Знач ИмяКолонки = "", Знач ЭтаФорма = Неопределено, Знач ПолноеИмяТаблицыБД = "") Экспорт Если ЗначениеЗаполнено(ПолноеИмяТаблицыБД) Тогда Ответ = Вопрос("Использовать значения текущей колонки (да) или ключи строк (нет)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет); СобиратьКлючи = Ответ = КодВозвратаДиалога.Нет; Иначе СобиратьКлючи = Ложь; КонецЕсли; Если СобиратьКлючи Тогда МассивСсылок = Новый Массив(); Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл КлючОбъекта = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицыБД, ВыделеннаяСтрока); МассивСсылок.Добавить(КлючОбъекта); КонецЦикла; КлючТекущейСтроки = КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицыБД, ТабличноеПоле.ТекущаяСтрока); Иначе МассивСсылок = СсылкиИзВыделенныхЯчеекТабличногоПоляЛкс(ТабличноеПоле, ИмяКолонки); КонецЕсли; ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок,, ЭтаФорма,, КлючТекущейСтроки); КонецПроцедуры Функция СсылкиИзВыделенныхЯчеекТабличногоПоляЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт МассивСсылок = Новый Массив; ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле); Если ВыделенныеСтроки.Количество() = 0 Тогда Возврат МассивСсылок; КонецЕсли; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ИмяКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Возврат МассивСсылок; КонецЕсли; Для Каждого Строка Из ВыделенныеСтроки Цикл Строка = ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Строка); ЗначениеСтроки = Строка[ИмяКолонки]; ТипЗначения = ТипЗнч(ЗначениеСтроки); Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда Продолжить; КонецЕсли; МассивСсылок.Добавить(ЗначениеСтроки); КонецЦикла; Возврат МассивСсылок; КонецФункции Функция ТекущаяКолонкаТаблицыФормыЛкс(ТаблицаФормы) Экспорт Если ТипЗнч(ТаблицаФормы) = Тип("ТаблицаФормы") Тогда Результат = ТаблицаФормы.ТекущийЭлемент; ИначеЕсли ТипЗнч(ТаблицаФормы) = Тип("ТабличноеПоле") Тогда Результат = ТаблицаФормы.ТекущаяКолонка; Иначе ВызватьИсключение "Неверный тип (" + ТипЗнч(ТаблицаФормы) + ") параметра"; КонецЕсли; Возврат Результат; КонецФункции Функция ОткрытьПодборИОбработкуОбъектовИзТабличногоПоляДинамическогоСпискаЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено, ВыделенныеСтроки = Неопределено) Экспорт ДинамическийСписок = ДанныеЭлементаФормыЛкс(ТабличноеПоле); ПолноеИмяМД = ""; ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, ПолноеИмяМД); Если ЗначениеЗаполнено(ПолноеИмяМД) Тогда Ответ = Вопрос("Обработать только выделенные строки (Да) иначе будет использован текущий отбор (Нет)?", РежимДиалогаВопрос.ДаНет); Иначе Ответ = КодВозвратаДиалога.Да; КонецЕсли; ВыбранныеПоля = Новый Массив; МассивКолонок = Неопределено; КолонкиТаблицыФормыИлиТабличногоПоляЛкс(ТабличноеПоле, МассивКолонок); ТекущееПолеТаблицы = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Для Каждого КолонкаТП Из МассивКолонок Цикл Если Не КолонкаТП.Видимость Тогда Продолжить; КонецЕсли; ДанныеКолонки = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле, КолонкаТП); Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда Продолжить; КонецЕсли; ВыбранныеПоля.Добавить(ДанныеКолонки); КонецЦикла; Если Ответ = КодВозвратаДиалога.Да Тогда Если ВыделенныеСтроки = Неопределено Тогда ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле); КонецЕсли; ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока; Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда ВыделенныеСтроки = КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(ТабличноеПоле, ВыделенныеСтроки); ТекущиеСтроки = Новый Массив; ТекущиеСтроки.Добавить(ТекущаяСтрока); ТекущаяСтрока = КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(ТабличноеПоле, ТекущиеСтроки)[0]; КонецЕсли; Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ВыделенныеСтроки, ВыбранныеПоля,, ТекущееПолеТаблицы, ТекущаяСтрока); Иначе Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, ПолноеИмяМД); Форма.ПараметрВыбранныеПоля = ВыбранныеПоля; Форма.ПараметрТекущееПоле = ТекущееПолеТаблицы; Форма.ПараметрКлючТекущейСтроки = ТабличноеПоле.ТекущаяСтрока; Если НастройкиСписка = Неопределено Тогда НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок); КонецЕсли; Форма.ПараметрНастройкаКомпоновки = НастройкиСписка; Форма.Открыть(); КонецЕсли; Возврат Форма; КонецФункции Функция КолонкиТаблицыФормыИлиТабличногоПоляЛкс(Знач ТабличноеПолеИлиТаблицаФормы, выхМассивКолонок = Неопределено, выхТекущаяКолонка = Неопределено) Экспорт Колонки = Новый Массив; Если ТипЗнч(ТабличноеПолеИлиТаблицаФормы) = Тип("ТабличноеПоле") Тогда Колонки = ТабличноеПолеИлиТаблицаФормы.Колонки; выхМассивКолонок = Колонки; выхТекущаяКолонка = ТабличноеПолеИлиТаблицаФормы.ТекущаяКолонка; ИначеЕсли ТипЗнч(ТабличноеПолеИлиТаблицаФормы) = Тип("ТаблицаФормы") Тогда Колонки = ТабличноеПолеИлиТаблицаФормы.ПодчиненныеЭлементы; выхМассивКолонок = Новый Массив; Для Каждого Элемент Из Колонки Цикл выхМассивКолонок.Добавить(Элемент); КонецЦикла; выхТекущаяКолонка = ТабличноеПолеИлиТаблицаФормы.ТекущийЭлемент; Если выхМассивКолонок.Найти(выхТекущаяКолонка) = Неопределено Тогда // Пользовательская колонка выхМассивКолонок.Добавить(выхТекущаяКолонка); КонецЕсли; КонецЕсли; Возврат Колонки; КонецФункции // В обычной форме "Динамический список ИР" для перечислений сделан статический список через таблицу значений Функция КлючиВыделенныхСтрокИмитатораДинамическогоСпискаЛкс(Знач ТабличноеПоле, ВыделенныеСтроки = Неопределено) Если ВыделенныеСтроки = Неопределено Тогда ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; КонецЕсли; ПараметрКоманды = Новый Массив(); Для Каждого Строка Из ВыделенныеСтроки Цикл Если ТипЗнч(Строка) = Тип("СтрокаТаблицыЗначений") Тогда КлючСтроки = Строка.Ссылка; Иначе КлючСтроки = Строка; КонецЕсли; ПараметрКоманды.Добавить(КлючСтроки); КонецЦикла; Возврат ПараметрКоманды; КонецФункции // Параметры: // ВыбранныеПоля - Массив, *Неопределено Функция ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок, ВыбранныеПоля = Неопределено, ЭтаФорма = Неопределено, ТекущееПолеТаблицы = Неопределено, КлючТекущейСтроки = Неопределено) Экспорт Если МассивСсылок.Количество() = 0 Тогда Возврат Неопределено; КонецЕсли; Если ЭтаФорма <> Неопределено Тогда ирОбщий.ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма); КонецЕсли; Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, Новый УникальныйИдентификатор); Форма.ПараметрМассивСсылок = МассивСсылок; Форма.ПараметрВыбранныеПоля = ВыбранныеПоля; Форма.ПараметрТекущееПоле = ТекущееПолеТаблицы; Форма.ПараметрКлючТекущейСтроки = КлючТекущейСтроки; Форма.Открыть(); //Форма.ЗагрузитьОбъектыДляОбработки(ПолучитьУникальныеЗначенияМассиваЛкс(МассивСсылок),, ВыбранныеПоля); Возврат Форма; КонецФункции Функция ПолучитьУникальныеЗначенияМассиваЛкс(Массив) Экспорт НовыйМассив = Новый Массив; Соответствие = Новый Соответствие; Для Каждого Элемент Из Массив Цикл Если Соответствие[Элемент] = 1 Тогда Продолжить; КонецЕсли; Соответствие.Вставить(Элемент, 1); НовыйМассив.Добавить(Элемент); КонецЦикла; Возврат НовыйМассив; КонецФункции Функция ПолучитьСтруктуруВосстановленияКонсолиЛкс(ИмяИлиОбъектКонсоли) Экспорт Если ТипЗнч(ИмяИлиОбъектКонсоли) = Тип("Строка") Тогда ИмяКонсоли = ИмяИлиОбъектКонсоли; Иначе ИмяКонсоли = ИмяИлиОбъектКонсоли.Метаданные().Имя; КонецЕсли; Структура = Новый Структура(); Структура.Вставить("БлокировкаВосстановления", Неопределено); ПрефиксИмениФайлаВосстановления = ИмяКонсоли + "_" + ИмяПользователя() + "_"; Структура.Вставить("ПрефиксИмениФайлаВосстановления", ПрефиксИмениФайлаВосстановления); ИмяФайлаВосстановления = ирКэш.Получить().КаталогФайловогоКэша + "\" + ПрефиксИмениФайлаВосстановления + Новый УникальныйИдентификатор + ".tmp"; Структура.Вставить("ФайлВосстановления", Новый Файл(ИмяФайлаВосстановления)); Возврат Структура; КонецФункции Функция СохранитьФайлВКонсолиСВосстановлениемЛкс(ДиалогВыбораФайла, Знач ИмяСохраняемогоФайла, ИмяОткрытогоФайла = "", ДанныеДляФайла, СтруктураВосстановления, ЗапрашиватьИмяФайла = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ДиалогВыбораФайла = Новый ДиалогВыбораФайла(); #КонецЕсли ФайлВосстановления = СтруктураВосстановления.ФайлВосстановления; ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления; БлокировкаВосстановления = СтруктураВосстановления.БлокировкаВосстановления; СохранитьФайл = Истина; Если Не СтрокиРавныЛкс(ИмяСохраняемогоФайла, ФайлВосстановления.ПолноеИмя) Тогда // Здесь можно вставить проверочную сериализацию+десериализацию ФайлВыбран = Истина; лФайл = Новый Файл(ИмяОткрытогоФайла); ДиалогВыбораФайла.ПолноеИмяФайла = ИмяСохраняемогоФайла; Если Ложь Или ПустаяСтрока(ИмяСохраняемогоФайла) Или ЗапрашиватьИмяФайла Или Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда Пока Истина Цикл Если ДиалогВыбораФайла.Выбрать() Тогда лФайл = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла); Если Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда КодОтвета = Вопрос("Это имя файла зарезервировано. Хотите выбрать другое?", РежимДиалогаВопрос.ОКОтмена); Если КодОтвета = КодВозвратаДиалога.ОК Тогда Продолжить; Иначе ФайлВыбран = Ложь; Прервать; КонецЕсли; КонецЕсли; ИмяСохраняемогоФайла = ДиалогВыбораФайла.ПолноеИмяФайла; ФайлВыбран = Истина; Прервать; Иначе ФайлВыбран = Ложь; СохранитьФайл = Ложь; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Иначе ФайлВыбран = Ложь; КонецЕсли; Если СохранитьФайл Тогда МоментНачала = ТекущаяДата(); Если Истина И НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) И БлокировкаВосстановления <> Неопределено Тогда БлокировкаВосстановления = Неопределено; КонецЕсли; ПроверитьСериализациюXMLПередВызовомЗначениеВФайлЛкс(ДанныеДляФайла); Если Не ЗначениеВФайл(ИмяСохраняемогоФайла, ДанныеДляФайла) Тогда СообщитьЛкс("Ошибка записи файла """ + ИмяСохраняемогоФайла + """", СтатусСообщения.Внимание); ФайлВыбран = Ложь; КонецЕсли; выхДлительность = ТекущаяДата() - МоментНачала; Если выхДлительность > 1 Тогда СообщитьЛкс("Автосохранение файла восстановления выполнено за " + выхДлительность + " секунд"); КонецЕсли; Если НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) Тогда БлокировкаВосстановления = Новый ЗаписьТекста(ИмяСохраняемогоФайла,,,Истина); КонецЕсли; КонецЕсли; Возврат ФайлВыбран; КонецФункции Функция ПроверитьВыбратьФайлВосстановленияКонсолиЛкс(СтруктураВосстановления) Экспорт ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления; СписокВосстановления = Новый СписокЗначений; ФайлыВосстановления = НайтиФайлы(ирКэш.Получить().КаталогФайловогоКэша, ПрефиксИмениФайлаВосстановления + "*.tmp"); Для Каждого ФайлВосстановления Из ФайлыВосстановления Цикл #Если Сервер И Не Сервер Тогда ФайлВосстановления = Новый Файл(); #КонецЕсли Попытка ФайлВосстановления.УстановитьВремяИзменения(ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс()); //Пустышка = Новый ЗаписьТекста(ФайлВосстановления.ПолноеИмя, , , Истина); Исключение // Файла заблокирован и значит сессия продолжается. Продолжить; КонецПопытки; СписокВосстановления.Добавить(ФайлВосстановления.ПолноеИмя, "" + (ФайлВосстановления.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс()) + " - " + ФайлВосстановления.ИмяБезРасширения); КонецЦикла; ИмяФайлаВосстановления = ""; Если СписокВосстановления.Количество() > 0 Тогда СписокВосстановления.СортироватьПоПредставлению(НаправлениеСортировки.Убыв); СписокВосстановления.Добавить("<Удалить все файлы восстановления>"); ВыбранныйЭлемент = СписокВосстановления.ВыбратьЭлемент("Вы можете открыть файл восстановления прерванной сессии"); Если ВыбранныйЭлемент <> Неопределено Тогда Если ВыбранныйЭлемент.Значение = "<Удалить все файлы восстановления>" Тогда Для Каждого ЭлементСписка Из СписокВосстановления Цикл Если ВыбранныйЭлемент = ЭлементСписка Тогда Продолжить; КонецЕсли; УдалитьФайлы(ЭлементСписка.Значение); КонецЦикла; Иначе ИмяФайлаВосстановления = ВыбранныйЭлемент.Значение; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИмяФайлаВосстановления; КонецФункции Процедура УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(СтруктураВосстановления) Экспорт СтруктураВосстановления.БлокировкаВосстановления = Неопределено; Попытка УдалитьФайлы(СтруктураВосстановления.ФайлВосстановления.ПолноеИмя); Исключение КонецПопытки; КонецПроцедуры Процедура СчитатьПорциюВыборкиВТаблицуЛкс(Выборка, ТаблицаПриемник, Знач РазмерПорции = 9999, СчитыватьЧерезКопиюТаблицы = Истина, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый Запрос; Выборка = Пустышка.Выполнить(); #КонецЕсли Если СчитыватьЧерезКопиюТаблицы Тогда // Иначе добавление и заполнение строк при связи с табличным полем будет дольше выполняться КопияТаблицыПриемника = ТаблицаПриемник.Скопировать(); Если СсылкаНаБуфернуюТаблицу <> Неопределено Тогда СсылкаНаБуфернуюТаблицу.Вставить("Таблица", КопияТаблицыПриемника); КонецЕсли; Иначе КопияТаблицыПриемника = ТаблицаПриемник; КонецЕсли; КоличествоРезультата = Выборка.Количество(); Несчитано = КоличествоРезультата - КопияТаблицыПриемника.Количество(); Если Ложь Или РазмерПорции > Несчитано Или РазмерПорции = 0 Тогда РазмерПорции = Несчитано; КонецЕсли; Если Несчитано = РазмерПорции Тогда ПредставлениеПроцесса = "Загрузка выборки"; Иначе ПредставлениеПроцесса = "Загрузка порции выборки"; КонецЕсли; #Если Клиент Тогда Индикатор = ПолучитьИндикаторПроцессаЛкс(РазмерПорции, ПредставлениеПроцесса); #КонецЕсли КолонкиВложенныхТаблиц = Новый Массив(); Для Каждого Колонка Из Выборка.Владелец().Колонки Цикл Если Колонка.ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда КолонкиВложенныхТаблиц.Добавить(Колонка.Имя); КонецЕсли; КонецЦикла; ЕстьКолонкиВложенныхТаблиц = КолонкиВложенныхТаблиц.Количество() > 0; РазмерПорцииОсталось = РазмерПорции; Пока Выборка.Следующий() Цикл НоваяСтрока = КопияТаблицыПриемника.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка); Если ЕстьКолонкиВложенныхТаблиц Тогда Для Каждого КолонкаВложеннойТаблицы Из КолонкиВложенныхТаблиц Цикл НоваяСтрока[КолонкаВложеннойТаблицы] = Выборка[КолонкаВложеннойТаблицы].Выгрузить(); КонецЦикла; КонецЕсли; Если РазмерПорцииОсталось > 0 Тогда РазмерПорцииОсталось = РазмерПорцииОсталось - 1; Если РазмерПорцииОсталось = 0 Тогда Прервать; КонецЕсли; КонецЕсли; #Если Клиент Тогда ОбработатьИндикаторЛкс(Индикатор); #КонецЕсли КонецЦикла; Если РазмерПорции = Несчитано Тогда Выборка = Неопределено; КонецЕсли; #Если Клиент Тогда ОсвободитьИндикаторПроцессаЛкс(); #КонецЕсли ТаблицаПриемник = КопияТаблицыПриемника; КонецПроцедуры // ТабличноеПоле определяется как источник действий командной панели. // Параметру ВыборкаРезультата внутри присваивается значение! Процедура ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатЗапроса, ВыборкаРезультата, КоманднаяПанель, ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", БезопасныйПорогКоличестваСтрок = 100000, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда лЗапрос = Новый Запрос; РезультатЗапроса = лЗапрос.Выполнить(); #КонецЕсли //БезопасныйПорогКоличестваСтрок = 1; // Для отладки ВыборкаРезультата = РезультатЗапроса.Выбрать(); ТабличноеПоле = КоманднаяПанель.ИсточникДействий; НачалоЗагрузки = ТекущаяДата(); Если Ложь Или БезопасныйПорогКоличестваСтрок = 0 Или ВыборкаРезультата.Количество() < БезопасныйПорогКоличестваСтрок Тогда ВыборкаРезультата = Неопределено; КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Ложь; ТабличноеПоле.Значение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой); Попытка Выполнить("ЭтаФорма." + ИмяОбработчикаОбновления + "()"); Исключение ВызватьИсключение ОписаниеОшибки(); КонецПопытки; Иначе ТабличноеПоле.Значение = Новый ТаблицаЗначений; Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл ТипЗначения = Колонка.ТипЗначения; Если ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений"); КонецЕсли; ТабличноеПоле.Значение.Колонки.Добавить(Колонка.Имя, ТипЗначения, Колонка.Имя, Колонка.Ширина); КонецЦикла; ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина); СчитатьПорциюВыборкиВТаблицуЛкс(ВыборкаРезультата, ТабличноеПоле.Значение, БезопасныйПорогКоличестваСтрок, , СсылкаНаБуфернуюТаблицу); КонецЕсли; Длительность = ТекущаяДата() - НачалоЗагрузки; Если Длительность > 30 Тогда СообщитьЛкс("Загрузка выборки выполнена за " + XMLСтрока(Длительность) + " секунд"); КонецЕсли; КонецПроцедуры // ТабличноеПоле определяется как источник действий командной панели. Процедура ЗагрузитьВыборкуВТабличноеПолеПолностьюЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина); ТабличноеПоле = КоманднаяПанель.ИсточникДействий; СчитатьПорциюВыборкиВТаблицуЛкс(мВыборкаРезультата, ТабличноеПоле.Значение, 0, , СсылкаНаБуфернуюТаблицу); КонецПроцедуры // Параметру КоличествоРезультата внутри присваивается значение! Процедура ПослеЗагрузкиВыборкиВТабличноеПолеЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт ТабличноеПоле = КоманднаяПанель.ИсточникДействий; Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда КоличествоСтрокВТабличномПоле = ВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение).Количество(); Иначе КоличествоСтрокВТабличномПоле = ТабличноеПоле.Значение.Количество(); КонецЕсли; Если ТипЗнч(мВыборкаРезультата) = Тип("COMОбъект") Тогда КоличествоРезультата = 0; Попытка КоличествоРезультата = мВыборкаРезультата.Count; Исключение Если мВыборкаРезультата.State <> 0 Тогда КоличествоРезультата = мВыборкаРезультата.RecordCount; КонецЕсли; КонецПопытки; //ВсеСчитано = КоличествоРезультата = КоличествоСтрокВТабличномПоле; ИначеЕсли ТипЗнч(мВыборкаРезультата) = Тип("ВыборкаИзРезультатаЗапроса") Тогда КоличествоРезультата = мВыборкаРезультата.Количество(); Если СсылкаНаБуфернуюТаблицу <> Неопределено И СсылкаНаБуфернуюТаблицу.Свойство("Таблица") Тогда ТабличноеПоле.Значение = СсылкаНаБуфернуюТаблицу.Таблица; КоличествоСтрокВТабличномПоле = ТабличноеПоле.Значение.Количество(); КонецЕсли; //ВсеСчитано = Ложь; Иначе КоличествоРезультата = КоличествоСтрокВТабличномПоле; //ВсеСчитано = Истина; КонецЕсли; ВсеСчитано = КоличествоРезультата = КоличествоСтрокВТабличномПоле; ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоСтрокВТабличномПоле, КоличествоРезультата, ВсеСчитано); КонецПроцедуры Функция ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(ПолноеИмяТаблицы, ИмяКолонки, ЗначениеОтбора, МаксимальнаяПорция = 0) Экспорт ПоляТаблицыБД = ирКэш.ПоляТаблицыБДЛкс(ПолноеИмяТаблицы); #Если Сервер И Не Сервер Тогда ПоляТаблицыБД = НайтиПоСсылкам().Колонки; #КонецЕсли ТекстПоля = ""; ПсевдонимТаблицы = "Т"; Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл Если Ложь Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда Продолжить; КонецЕсли; Если ЗначениеЗаполнено(ТекстПоля) Тогда ТекстПоля = ТекстПоля + ", "; КонецЕсли; ТекстПоля = ТекстПоля + ПсевдонимТаблицы + "." + ПолеТаблицыБД.Имя; КонецЦикла; ТекстПервые = ""; Если МаксимальнаяПорция > 0 Тогда ТекстПервые = " ПЕРВЫЕ " + Формат(МаксимальнаяПорция, "ЧГ=") + " "; КонецЕсли; ТекстЗапроса = " |ВЫБРАТЬ " + ТекстПервые + " " + ТекстПоля + " |ИЗ " + ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяТаблицы) + " КАК " + ПсевдонимТаблицы + " |{ГДЕ " + ПсевдонимТаблицы + "." + ИмяКолонки + "}"; Построитель = Новый ПостроительЗапроса(ТекстЗапроса); Если ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда ЭлементОтбора = Построитель.Отбор.Добавить(ИмяКолонки); ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке; ЭлементОтбора.Значение = ЗначениеОтбора; ЭлементОтбора.Использование = Истина; Иначе Построитель.Отбор.Добавить(ИмяКолонки).Установить(ЗначениеОтбора); КонецЕсли; Возврат Построитель; КонецФункции Функция ЗагрузитьСвязанныеСтрокиТаблицыБДЛкс(ЭтаФорма, ТабличноеПолеСвязанныхКолонок, ТабличноеПолеСвязанныхСтрок, КоманднаяПанельСвязанныхСтрок, мВыборкаРезультатаСтрокиТаблицы, ЗначениеОтбора) Экспорт СтрокаСвязаннойКолонки = ТабличноеПолеСвязанныхКолонок.ТекущаяСтрока; Если СтрокаСвязаннойКолонки = Неопределено Тогда Возврат Неопределено; КонецЕсли; ЭтаФорма.СтрокиТаблицыБД = Новый ТаблицаЗначений; ТабличноеПолеСвязанныхСтрок.СоздатьКолонки(); //Если ЗначениеОтбора = Неопределено Тогда // ЗначениеОтбора = СтрокаСвязаннойКолонки.Ссылка; //КонецЕсли; Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора); //ЧислоСтрокДляЗагрузки = ирОбщий.КонтрольРазмераВыборкиПользователемЛкс(Построитель); //Если ЧислоСтрокДляЗагрузки > 0 Тогда // Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора, ЧислоСтрокДляЗагрузки); //КонецЕсли; //// http://partners.v8.1c.ru/forum/thread.jsp?id=1034151#1034151 ////МаксимальныйРазмер = 500000; ////Построитель = ПолучитьПостроительВыборкиСвязанныхСтрок(, МаксимальныйРазмер); // Антибаг 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1017264#1017264 Если ирКэш.НомерВерсииПлатформыЛкс() >= 802014 Тогда Если Истина И СтрокаСвязаннойКолонки.ТипТаблицы = "Изменения" И Найти(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, "РегистрСведений.") = 1 Тогда Если Метаданные.ОбщиеРеквизиты.Количество() > 0 Тогда Возврат Неопределено; КонецЕсли; //Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл // ВыбранноеПоле = Построитель.ВыбранныеПоля.Найти(ОбщийРеквизит.Имя); // Если Истина // И ВыбранноеПоле <> Неопределено // И ОбъектМетаданных.Измерения.Найти(ОбщийРеквизит.Имя) = Неопределено // Тогда // Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда // Построитель.ВыбранныеПоля.Удалить(ВыбранноеПоле); // КонецЕсли; // КонецЕсли; //КонецЦикла; КонецЕсли; КонецЕсли; Попытка РезультатСтрокиТаблицы = Построитель.Результат; Исключение // Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1031481#1031481 СообщитьЛкс(ОписаниеОшибки()); Возврат Неопределено; КонецПопытки; ирОбщий.ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатСтрокиТаблицы, мВыборкаРезультатаСтрокиТаблицы, КоманднаяПанельСвязанныхСтрок); //Если СтрокиТаблицыБД.Количество() = МаксимальныйРазмер Тогда // СообщитьЛкс("Были выбраны первые " + МаксимальныйРазмер + " строк таблицы"); //КонецЕсли; СтруктураОтбора = Новый Структура("ПолноеИмяТаблицы, ИмяКолонки", СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки); ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаСвязаннойКолонки); ТабличноеПолеСвязанныхСтрок.СоздатьКолонки(); ТабличноеПолеСвязанныхСтрок.ТекущаяКолонка = ТабличноеПолеСвязанныхСтрок.Колонки[СтрокаСвязаннойКолонки.ИмяКолонки]; Для Каждого КолонкаТП Из ТабличноеПолеСвязанныхСтрок.Колонки Цикл КолонкаТП.ТолькоПросмотр = Истина; КонецЦикла; Попытка ИскомаяСсылка = СтрокаСвязаннойКолонки.Ссылка Исключение ИскомаяСсылка = Неопределено; КонецПопытки; Если ИскомаяСсылка <> Неопределено Тогда ТекущаяСтрока = ТабличноеПолеСвязанныхСтрок.Значение.Найти(ИскомаяСсылка, СтрокаСвязаннойКолонки.ИмяКолонки); Если ТекущаяСтрока <> Неопределено Тогда ТабличноеПолеСвязанныхСтрок.ТекущаяСтрока = ТекущаяСтрока; КонецЕсли; КонецЕсли; Возврат СтрокаСвязаннойКолонки.ПолноеИмяТаблицы; КонецФункции Процедура ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоЗагружено, КоличествоРезультата, ВсеСчитано) Экспорт Если ВсеСчитано Тогда СтрокаКоличествоРезультата = "" + КоличествоЗагружено; ПолеСтрокиКоличестваРезультата.ЦветФона = Новый Цвет(); Иначе СтрокаКоличествоРезультата = "" + КоличествоЗагружено + "/" + КоличествоРезультата; ПолеСтрокиКоличестваРезультата.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаВычисляемогоЗначения"); КонецЕсли; ПолеСтрокиКоличестваРезультата.Значение = СтрокаКоличествоРезультата; КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Не ВсеСчитано; КонецПроцедуры Функция ПолучитьТекстОтбораЗапросаКомпоновкиЛкс(ЗапросСОтбором, ПсевдонимТаблицыПередГДЕ = "Т") Экспорт ТекстОтбораДублей = ПоследнийФрагментЛкс(ЗапросСОтбором.Текст, "КАК " + ПсевдонимТаблицыПередГДЕ + " |ГДЕ", Ложь); Если Не ЗначениеЗаполнено(ТекстОтбораДублей) Тогда ТекстОтбораДублей = " ИСТИНА "; КонецЕсли; Возврат ТекстОтбораДублей; КонецФункции Функция НайтиПоказатьСтрокуВПолеТекстовогоДокументаЛкс(Форма = Неопределено, ПолеТекстовогоДокумента, СтрокаПоиска, СловоЦеликом = Ложь) Экспорт Если СловоЦеликом Тогда ИскательСловаЦеликом = ирКэш.ВычислительРегулярныхВыраженийЛкс(); ИскательСловаЦеликом.Global = Ложь; ИскательСловаЦеликом.Multiline = Истина; ИскательСловаЦеликом.Pattern = ШаблонПоискаСловаЦеликомЛкс(СтрокаПоиска); Вхождение = ИскательСловаЦеликом.Execute(ПолеТекстовогоДокумента.ПолучитьТекст()); Если Вхождение.Count > 0 Тогда Позиция = Вхождение.Item(0).FirstIndex + 1; Позиция = Позиция + СтрДлина(Вхождение.Item(0).SubMatches(0)); Иначе Позиция = 0; КонецЕсли; Иначе Позиция = Найти(Нрег(ПолеТекстовогоДокумента.ПолучитьТекст()), Нрег(СтрокаПоиска)); КонецЕсли; Если Позиция > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Позиция, Позиция + СтрДлина(СтрокаПоиска)); Если Форма <> Неопределено Тогда Форма.ТекущийЭлемент = ПолеТекстовогоДокумента; КонецЕсли; Результат = Истина; Иначе Если СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1); КонецЕсли; Результат = Ложь; КонецЕсли; Возврат Результат; КонецФункции Функция ШаблонПоискаСловаЦеликомЛкс(Знач СтрокаПоиска) Экспорт Возврат "(^|[^_a-zа-яё0-9])(" + ПреобразоватьТекстДляРегулярныхВыраженийЛкс(СтрокаПоиска) + ")($|[^_a-zа-яё0-9])"; КонецФункции // Параметры: // Элемент - ПолеТабличногоДокумента // Функция ПолеТабличногоДокумента_ПолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт Сумма = 0; СчетчикЯчеекСуммы = 0; СчетчикЯчеекОбщий = 0; ВыделенныеОбласти = Элемент.ВыделенныеОбласти; ЕстьИгнорированныеОбласти = Ложь; НачальноеКоличество = ВыделенныеОбласти.Количество(); Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти]; Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда Продолжить; КонецЕсли; ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1); СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти; Если ПлощадьОбласти < 10000 Тогда Для НомерКолонки = Область.Лево по Область.Право Цикл Для НомерСтроки = Область.Верх по Область.Низ Цикл ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; Попытка Число = Число(ОбластьЯчейки.Текст); Исключение Продолжить; КонецПопытки; Сумма = Сумма + Число; СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1; КонецЦикла; КонецЦикла; Иначе ЕстьИгнорированныеОбласти = Истина; КонецЕсли; КонецЦикла; СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы; Сумма = "" + Сумма; Если ЕстьИгнорированныеОбласти Тогда СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?"; Сумма = Сумма + "+?"; КонецЕсли; Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + ""; Возврат Текст; КонецФункции // Параметры: // Таблица - ТаблицаЗначений - может быть модифицирована здесь, поэтому нужно передавать копию, если нужна неизменность Функция ВывестиТаблицуВТабличныйДокументИлиТаблицуЗначенийЛкс(ТаблицаЗначений, Знач Приемник = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхКолонок = Истина, АвтофиксацияШапки = Истина, ВстроитьЗначенияВРасшифровки = Истина, ОтображатьПустые = Ложь, ДобавлятьКолонкиИдентификаторов = Ложь, ДобавлятьКолонкиТипов = Ложь, ДобавлятьКолонкиПредставлений = Истина, Знач ВыбранныеКолонки = Неопределено, ИмяТекущейКолонки = "", ВыводВТаблицуЗначений = Ложь, Отладка = Ложь, ДобавлятьКолонкиРазмеров = Ложь, СузитьТипы = Ложь) Экспорт ТребоватьТипЛкс(ТаблицаЗначений,, Тип("ТаблицаЗначений")); ирПлатформа = ирКэш.Получить(); Если ДобавлятьКолонкиТипов Или ДобавлятьКолонкиИдентификаторов Тогда //ТаблицаЗначений = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаЗначений); ТаблицаЗначений = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(ТаблицаЗначений); КонецЕсли; #Если Сервер И Не Сервер Тогда ирПлатформа = Обработки.ирПлатформа.Создать(); ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ВнешниеНаборыДанных = Новый Структура("Основной", ТаблицаЗначений); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; КолонкиИдентификаторов = Новый Массив; КолонкиТипов = Новый Массив; КолонкиРазмеров = Новый Массив; Если ВыбранныеКолонки = Неопределено Тогда ВыбранныеКолонки = Новый Массив; Для Каждого Колонка Из КолонкиИсточникаДанныхЛкс(ТаблицаЗначений) Цикл ВыбранныеКолонки.Добавить(Колонка.Имя); КонецЦикла; КонецЕсли; //ПримитивныеТипы = Новый Массив; //ПримитивныеТипы.Добавить(Тип("Число")); //ПримитивныеТипы.Добавить(Тип("Строка")); //ПримитивныеТипы.Добавить(Тип("Дата")); //ПримитивныеТипы.Добавить(Тип("Булево")); //ПримитивныеТипы.Добавить(Тип("Неопределено")); //ПримитивныеТипы.Добавить(Тип("Null")); //ПримитивныеТипы.Добавить(Тип("УникальныйИдентификатор")); ИменаТипов = Новый Структура; ПозицииКолонок = Новый Структура; ИндексТекущейКолонки = 0; Для Каждого ВыбраннаяКолонка Из ВыбранныеКолонки Цикл Если Не ЗначениеЗаполнено(ВыбраннаяКолонка) Тогда Продолжить; КонецЕсли; ИмяКолонки = СтрЗаменить(ВыбраннаяКолонка, ".", "_"); Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки); Если Колонка = Неопределено Тогда // Например "ИдентификаторСсылкиЛкс" в таблице формы Продолжить; КонецЕсли; ТипыКолонки = Колонка.ТипЗначения.Типы(); ПозицииКолонок.Вставить(Колонка.Имя, НастройкаКомпоновки.Выбор.Элементы.Количество()); Если ДобавлятьКолонкиПредставлений Тогда НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ВыбраннаяКолонка); КонецЕсли; Если Ложь Или ОтображатьПустые Или (Истина И ДобавлятьКолонкиТипов И ТипыКолонки.Количество() > 1) Тогда КолонкиТипов.Добавить(Колонка.Имя); ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_ИмяТипаЗначения_", Новый ОписаниеТипов("Строка"), Колонка.Заголовок + " (тип)"); Если ДобавлятьКолонкиТипов Тогда НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_ИмяТипаЗначения_"); КонецЕсли; ИменаТиповКолонки = Новый Соответствие; Для Каждого Тип Из ТипыКолонки Цикл ИменаТиповКолонки.Вставить(Тип, ПредставлениеТипаЛкс(Тип, Колонка.ТипЗначения, Истина)); КонецЦикла; ИменаТипов.Вставить(Колонка.Имя, ИменаТиповКолонки); КонецЕсли; Если ДобавлятьКолонкиИдентификаторов Тогда ЕстьСсылочныйТип = ТипыКолонки.Количество() = 0; Если Не ЕстьСсылочныйТип Тогда Для Каждого Тип Из ТипыКолонки Цикл Если ЛиТипСсылкиБДЛкс(Тип, Ложь) Тогда ЕстьСсылочныйТип = Истина; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если ЕстьСсылочныйТип Тогда Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество(); КонецЕсли; КолонкиИдентификаторов.Добавить(Колонка.Имя); ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_ИдентификаторЗначения_", Новый ОписаниеТипов("Строка"), Колонка.Заголовок + " (идентификатор)"); НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_ИдентификаторЗначения_"); КонецЕсли; КонецЕсли; Если ДобавлятьКолонкиРазмеров Тогда Если Ложь Или Колонка.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения")) Или (Истина И Колонка.ТипЗначения.СодержитТип(Тип("Строка")) И Колонка.ТипЗначения.КвалификаторыСтроки.ДопустимаяДлина = 0) Тогда Если ИндексТекущейКолонки = 0 И ЗначениеЗаполнено(ИмяТекущейКолонки) И СтрокиРавныЛкс(ВыбраннаяКолонка, ИмяТекущейКолонки) Тогда ИндексТекущейКолонки = НастройкаКомпоновки.Выбор.Элементы.Количество(); КонецЕсли; КолонкиРазмеров.Добавить(Колонка.Имя); ТаблицаЗначений.Колонки.Вставить(ТаблицаЗначений.Колонки.Индекс(Колонка) + 1, ИмяКолонки + "_РазмерЗначения_", Новый ОписаниеТипов("Число"), Колонка.Заголовок + " (размер)"); НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяКолонки + "_РазмерЗначения_"); КонецЕсли; КонецЕсли; Если ОтображатьПустые Тогда ПустыеЗначения = Новый Массив; ПустыеЗначения.Добавить(Неопределено); ПустыеЗначения.Добавить(0); ПустыеЗначения.Добавить(Дата(1,1,1)); ПустыеЗначения.Добавить(Ложь); ПустыеЗначения.Добавить(""); Для Каждого ПустоеЗначение Из ПустыеЗначения Цикл Если Ложь Или Колонка.ТипЗначения.Типы().Количество() = 0 Или Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение)) Тогда ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить(); ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение)); //ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс()); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, , ВидСравненияКомпоновкиДанных.НеЗаполнено); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ВыбраннаяКолонка, ПустоеЗначение, ВидСравненияКомпоновкиДанных.Равно); ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить(); ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка); КонецЕсли; КонецЦикла; // Отдельно для особенного Null ПустоеЗначение = Null; Если Истина И Колонка.ТипЗначения.Типы().Количество() > 0 И Колонка.ТипЗначения.СодержитТип(ТипЗнч(ПустоеЗначение)) Тогда ЭлементУсловногоОформления = НастройкаКомпоновки.УсловноеОформление.Элементы.Добавить(); ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Текст", ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ПустоеЗначение)); //ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветФонаЯчеекПустыхЗначенийЛкс()); НайтиДобавитьЭлементОтбораКомпоновкиЛкс(ЭлементУсловногоОформления.Отбор, ИмяКолонки + "_ИмяТипаЗначения_", "Null", ВидСравненияКомпоновкиДанных.Равно); ПолеЭлементаОформления = ЭлементУсловногоОформления.Поля.Элементы.Добавить(); ПолеЭлементаОформления.Поле = Новый ПолеКомпоновкиДанных(ВыбраннаяКолонка); КонецЕсли; КонецЕсли; КонецЦикла; Если Ложь Или КолонкиТипов.Количество() > 0 Или КолонкиИдентификаторов.Количество() > 0 Или КолонкиРазмеров.Количество() > 0 Тогда Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЗначений.Количество(), "Заполнение доп. колонок"); Для Каждого СтрокаТаблицы Из ТаблицаЗначений Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); // добавляет значительную долю длительности цикла // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Для Каждого ИмяКолонки Из КолонкиТипов Цикл Если Ложь Или ДобавлятьКолонкиТипов Или СтрокаТаблицы[ИмяКолонки] = Null Тогда СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])]; КонецЕсли; КонецЦикла; Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = ПолучитьИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; Для Каждого ИмяКолонки Из КолонкиРазмеров Цикл СтрокаТаблицы[ИмяКолонки + "_РазмерЗначения_"] = РазмерЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]); КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для Каждого ИмяКолонки Из КолонкиТипов Цикл   Если Ложь   Или ДобавлятьКолонкиТипов   Или СтрокаТаблицы[ИмяКолонки] = Null   Тогда   СтрокаТаблицы[ИмяКолонки + "_ИмяТипаЗначения_"] = ИменаТипов[ИмяКолонки][ТипЗнч(СтрокаТаблицы[ИмяКолонки])];   КонецЕсли;   КонецЦикла;   Для Каждого ИмяКолонки Из КолонкиИдентификаторов Цикл   СтрокаТаблицы[ИмяКолонки + "_ИдентификаторЗначения_"] = ПолучитьИдентификаторЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);   КонецЦикла;   Для Каждого ИмяКолонки Из КолонкиРазмеров Цикл   СтрокаТаблицы[ИмяКолонки + "_РазмерЗначения_"] = РазмерЗначенияЛкс(СтрокаТаблицы[ИмяКолонки]);   КонецЦикла;   КонецЦикла; КонецЕсли; Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура); КонецЕсли; СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхКолонок); Если Отладка Тогда ОтладитьЛкс(СхемаКомпоновки, , НастройкаКомпоновки, ВнешниеНаборыДанных); Возврат Неопределено; КонецЕсли; Если ВыводВТаблицуЗначений Тогда Приемник = СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных,,,,,,, СузитьТипы); //Приемник = ТаблицаЗначений.Скопировать(, "..."); Иначе Приемник = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Приемник, ВнешниеНаборыДанных, ДанныеРасшифровки, АвтофиксацияШапки,, ВстроитьЗначенияВРасшифровки); #Если Сервер И Не Сервер Тогда Приемник = Новый ТабличныйДокумент; #КонецЕсли Если ЗначениеЗаполнено(ИмяТекущейКолонки) И ВыбранныеКолонки.Найти(ИмяТекущейКолонки) <> Неопределено Тогда Приемник.ТекущаяОбласть = Приемник.Область(2, ПозицииКолонок[ИмяТекущейКолонки] + 1); КонецЕсли; Для Счетчик = 1 По ВыбранныеКолонки.Количество() Цикл ИмяКолонки = ВыбранныеКолонки[Счетчик - 1]; Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда Продолжить; КонецЕсли; Колонка = ТаблицаЗначений.Колонки.Найти(ИмяКолонки); Если Колонка <> Неопределено Тогда Приемник.Область(1, ПозицииКолонок[ИмяКолонки] + 1).Примечание.Текст = "Типы значений: " + РасширенноеПредставлениеЗначенияЛкс(Колонка.ТипЗначения); КонецЕсли; КонецЦикла; КонецЕсли; Возврат Приемник; КонецФункции Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено, ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь) Экспорт #Если Сервер И Не Сервер Тогда НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; #КонецЕсли Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура); КонецЕсли; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; Если ДанныеРасшифровки = Неопределено Тогда ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных; КонецЕсли; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, ДанныеРасшифровки,,, ПроверятьДоступностьПолей); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина); Если ТабличныйДокумент = Неопределено Тогда ТабличныйДокумент = Новый ТабличныйДокумент; КонецЕсли; ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки); Если ВстроитьЗначенияПолейВРасшифровки Тогда Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); ИдентификаторРасшифровки = Ячейка.Расшифровка; Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля(); Если ЗначенияПолей.Количество() > 0 Тогда Ячейка.Расшифровка = ЗначенияПолей[0].Значение; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; Возврат ТабличныйДокумент; КонецФункции Функция ДополнительныеДействияРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровки, выхКоличествоСсылочныхПолей = 0) Экспорт #Если Сервер И Не Сервер Тогда ЭлементРасшифровки = Новый ЭлементРасшифровкиКомпоновкиДанныхПоля; #КонецЕсли ДополнительныеПунктыМеню = Новый СписокЗначений; выхКоличествоСсылочныхПолей = 0; Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл ЗначениеПоляЗначение = ЗначениеПоля.Значение; ПорогДлины = 100; ПредставлениеЗначения = ПредставлениеЗначенияСОграничениемДлиныЛкс(ЗначениеПоляЗначение, ПорогДлины); Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение) Тогда ДополнительныеПунктыМеню.Добавить(Новый Структура("Ссылка, ОткрытьВРедактореОбъектаБД", ЗначениеПоля.Значение), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """", , ирКэш.КартинкаПоИмениЛкс("ирРедактироватьОбъектБД")); выхКоличествоСсылочныхПолей = выхКоличествоСсылочныхПолей + 1; КонецЕсли; ДополнительныеПунктыМеню.Добавить(Новый Структура("Значение, Открыть", ЗначениеПоля.Значение), "Открыть """ + ЗначениеПоля.Поле + " = " + ПредставлениеЗначения + """", , ирОбщий.ПолучитьПиктограммуТипаЛкс(ТипЗнч(ЗначениеПоля.Значение))); КонецЦикла; Возврат ДополнительныеПунктыМеню; КонецФункции Процедура ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(Знач ВыбранноеДействие, СтандартнаяОбработка) Экспорт Если ТипЗнч(ВыбранноеДействие) = Тип("Структура") Тогда Если ВыбранноеДействие.Свойство("Открыть") Тогда ирОбщий.ОткрытьЗначениеЛкс(ВыбранноеДействие.Значение, Ложь, СтандартнаяОбработка); ИначеЕсли ВыбранноеДействие.Свойство("ОткрытьВРедактореОбъектаБД") Тогда ирОбщий.ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранноеДействие.Ссылка); КонецЕсли; КонецЕсли; КонецПроцедуры // Параметры: // ОтчетОбъект - Форма, ОтчетОбъект Процедура ОтчетКомпоновкиОбработкаРасшифровкиЛкс(Знач ОтчетОбъект, Знач Расшифровка, СтандартнаяОбработка, ДополнительныеПараметры, ПолеТабличногоДокумента, ДанныеРасшифровки, Авторасшифровка = Ложь) Экспорт #Если _ Тогда ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных; ЭлементРасшифровки = ДанныеРасшифровки.Элементы[0]; ТабличныйДокумент = Новый ТабличныйДокумент; ОтчетОбъект = Отчеты.ирАнализЗамераПроизводительности.Создать(); #КонецЕсли Если ТипЗнч(Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда //Возврат; КонецЕсли; ЭлементРасшифровки = ДанныеРасшифровки.Элементы[Расшифровка]; ДоступныеДействия = Новый Массив; РазрешитьАвтовыборДействия = Истина; ПараметрВыбранногоДействия = Неопределено; КоличествоСсылочныхПолей = 0; СписокДополнительныхДействий = ДополнительныеДействияРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки, КоличествоСсылочныхПолей); #Если Сервер И Не Сервер Тогда СписокДополнительныхДействий = Новый СписокЗначений; #КонецЕсли КоличествоОбщихДействий = СписокДополнительныхДействий.Количество(); ЗначенияВсехПолей = Новый Соответствие; ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровки,, ЗначенияВсехПолей); Для Каждого ЭлементОтбора Из ДанныеРасшифровки.Настройки.Отбор.Элементы Цикл Если Ложь Или Не ЭлементОтбора.Использование Или ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Или ЭлементОтбора.ВидСравнения <> ВидСравненияКомпоновкиДанных.Равно Или ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда Продолжить; КонецЕсли; ЗначенияВсехПолей["" + ЭлементОтбора.ЛевоеЗначение] = ЭлементОтбора.ПравоеЗначение; КонецЦикла; Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ОбработкаРасшифровки") Тогда ОтчетОбъект.ОбработкаРасшифровки(ДанныеРасшифровки, ЭлементРасшифровки, ПолеТабличногоДокумента, ДоступныеДействия, СписокДополнительныхДействий, РазрешитьАвтовыборДействия, ЗначенияВсехПолей); КонецЕсли; Если Истина И РазрешитьАвтовыборДействия И Авторасшифровка И (ЛОжь ИЛи СписокДополнительныхДействий.Количество() - КоличествоОбщихДействий = 1 Или СписокДополнительныхДействий.Количество() - КоличествоОбщихДействий = 0 И КоличествоСсылочныхПолей = 1) Тогда ВыбранноеДействие = СписокДополнительныхДействий[0].Значение; КонецЕсли; Если ВыбранноеДействие = Неопределено Тогда ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных); ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек); ОбработкаРасшифровки.ВыбратьДействие(Расшифровка, ВыбранноеДействие, ПараметрВыбранногоДействия, ДоступныеДействия, СписокДополнительныхДействий, Авторасшифровка); КонецЕсли; Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Нет Тогда СтандартнаяОбработка = Ложь; //Возврат; КонецЕсли; Если ПараметрВыбранногоДействия = Неопределено Тогда ПараметрВыбранногоДействия = ЗначенияВсехПолей; КонецЕсли; ОбработатьДополнительноеДействиеРасшифровкиКомпоновкиЛкс(ВыбранноеДействие, СтандартнаяОбработка); Если ирОбщий.МетодРеализованЛкс(ОтчетОбъект, "ДействиеРасшифровки") Тогда ОтчетОбъект.ДействиеРасшифровки(ВыбранноеДействие, ПараметрВыбранногоДействия, СтандартнаяОбработка); КонецЕсли; Если СтандартнаяОбработка Тогда Если ВыбранноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда ОткрытьЗначение(ПараметрВыбранногоДействия); ИначеЕсли ТипЗнч(ВыбранноеДействие) = Тип("ДействиеОбработкиРасшифровкиКомпоновкиДанных") Тогда ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(ОтчетОбъект.СхемаКомпоновкиДанных); ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, ИсточникДоступныхНастроек); НовыеНастройки = ОбработкаРасшифровки.ПрименитьНастройки(Расшифровка, ПараметрВыбранногоДействия); ОтчетОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(НовыеНастройки); ОтчетОбъект.СкомпоноватьРезультат(ПолеТабличногоДокумента); КонецЕсли; КонецЕсли; СтандартнаяОбработка = Ложь; КонецПроцедуры Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Ложь) Экспорт Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент); ТекущееЗначение = ДанныеЭлементаФормыЛкс(Элемент); Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение, Ложь) Тогда НачальноеЗначениеВыбора = ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(ТекущееЗначение)); КонецЕсли; лСтруктураПараметров = Новый Структура; лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина); лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина); лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина); лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора); Форма.НачальноеЗначениеВыбора = лСтруктураПараметров; ЗначениеВыбора = Форма.ОткрытьМодально(); Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда лПолноеИмяОбъекта = Неопределено; Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда ИмяТипаСсылки = ИмяТипаИзПолногоИмениМДЛкс(лПолноеИмяОбъекта, "Ссылка"); ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки); НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено); ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение); // // http://www.hostedredmine.com/issues/884276 //Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда // //Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда // ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,,, Элемент, Истина); // //КонецЕсли; //КонецЕсли; КонецЕсли; КонецЕсли; СтандартнаяОбработка = Ложь; Возврат НовоеЗначение; КонецФункции // Результат - значение выбранного типа, но не обязательно выбранное (выбор типа выполняется синхронно, а значения - асинхронно) Функция ПолеВвода_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, ИгнорироватьОписаниеТипов = Ложь) Экспорт РезультатВыбора = ДанныеЭлементаФормыЛкс(Элемент); Если Истина И ИгнорироватьОписаниеТипов И (Ложь Или ТипЗнч(РезультатВыбора) = Тип("Строка") Или РезультатВыбора = Неопределено) Тогда Типы = Элемент.ОграничениеТипа.Типы(); Если Типы.Количество() = 1 Тогда // Ссылка внешнего источника данных СтандартнаяОбработка = Ложь; ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(Типы[0]),,, Элемент, Истина,, РезультатВыбора); Иначе РезультатВыбора = ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка); КонецЕсли; ИначеЕсли ЛиСсылкаНаОбъектБДЛкс(РезультатВыбора, Ложь) Тогда СтандартнаяОбработка = Ложь; Отбор = Новый Структура; Если ТипЗнч(Элемент) = Тип("ПолеВвода") И Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(РезультатВыбора)) Тогда Если ЗначениеЗаполнено(Элемент.ВыборПоВладельцу) Тогда Отбор.Вставить("Владелец", Элемент.ВыборПоВладельцу); КонецЕсли; КонецЕсли; ОткрытьФормуСпискаЛкс(ПолучитьПолноеИмяМДТипаЛкс(ТипЗнч(РезультатВыбора)), Отбор,, Элемент, Истина,, РезультатВыбора); Иначе // Тут надо делать выбор из диалога плоского списка типов КонецЕсли; Возврат РезультатВыбора; КонецФункции Функция ДобавитьМногострочнуюСтрокуВТекстЛкс(ТекстПриемник, СтрокаДляВставки, Смещение, СНовойСтроки = Ложь, ОбрезатьЛевыеПустые = Ложь) Экспорт Если Не ЗначениеЗаполнено(ТекстПриемник) Тогда ТекстПриемник = ""; КонецЕсли; ЗаписьТекста = Новый ЗаписьXML; ЗаписьТекста.УстановитьСтроку(); Если СНовойСтроки Тогда ЗаписьТекста.ЗаписатьБезОбработки(Символы.ПС + Смещение); КонецЕсли; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(СтрокаДляВставки); ЗаписьТекста.ЗаписатьБезОбработки(ТекстовыйДокумент.ПолучитьСтроку(1)); Для Счетчик = 2 По ТекстовыйДокумент.КоличествоСтрок() Цикл ТекущаяСтрока = ТекстовыйДокумент.ПолучитьСтроку(Счетчик); Если ОбрезатьЛевыеПустые Тогда ТекущаяСтрока = СокрЛ(ТекущаяСтрока); КонецЕсли; ЗаписьТекста.ЗаписатьБезОбработки(Символы.ПС + Смещение + ТекущаяСтрока); КонецЦикла; ТекстПриемник = ТекстПриемник + ЗаписьТекста.Закрыть(); Возврат ТекстПриемник; КонецФункции Функция ПолучитьИндексКартинкиТипаЛкс(ОписаниеТипов) Экспорт Если ОписаниеТипов = Неопределено Тогда Возврат 14; КонецЕсли; Типы = ОписаниеТипов.Типы(); Если Типы.Количество() = 1 Тогда КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Типы[0]); Если Типы[0] = Тип("Число") Тогда ИндексКартинки = 0; ИначеЕсли Типы[0] = Тип("Строка") Тогда ИндексКартинки = 1; ИначеЕсли Типы[0] = Тип("Дата") Тогда ИндексКартинки = 2; ИначеЕсли Типы[0] = Тип("Булево") Тогда ИндексКартинки = 3; ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда ИндексКартинки = 19; ИначеЕсли Типы[0] = Тип("Тип") Тогда ИндексКартинки = 20; ИначеЕсли Типы[0] = Тип("УникальныйИдентификатор") Тогда ИндексКартинки = 21; ИначеЕсли КорневойТип = "Справочник" Тогда ИндексКартинки = 7; ИначеЕсли КорневойТип = "Документ" Тогда ИндексКартинки = 8; ИначеЕсли КорневойТип = "Перечисление" Тогда ИндексКартинки = 9; ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда ИндексКартинки = 10; ИначеЕсли КорневойТип = "ПланСчетов" Тогда ИндексКартинки = 11; ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда ИндексКартинки = 12; ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда ИндексКартинки = 13; ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда ИндексКартинки = 14; ИначеЕсли КорневойТип = "Задача" Тогда ИндексКартинки = 13; ИначеЕсли КорневойТип = "ПланОбмена" Тогда ИндексКартинки = 15; Иначе ИндексКартинки = 16; КонецЕсли; Иначе ИндексКартинки = 16; КонецЕсли; Возврат ИндексКартинки; КонецФункции Функция ПроверитьПодпискиЛкс() Экспорт Результат = Истина; // Проверка компиляции общих модулей с обработчиками событий СписокМодулей = Новый Структура; СписокМодулейВызоваСервера = Новый Структура; ОбщиеМодули = Метаданные.ОбщиеМодули; #Если ТолстыйКлиентУправляемоеПриложение Тогда ИмяКлиента = "Управляемое"; #Иначе ИмяКлиента = "Обычное"; #КонецЕсли ИмяСвойства = "Клиент" + ИмяКлиента + "Приложение"; Для Каждого Подписка Из Метаданные.ПодпискиНаСобытия Цикл #Если Сервер И Не Сервер Тогда Подписка = Метаданные.ПодпискиНаСобытия.ВерсионированиеОбъектов_ПриЗаписиОбъекта; #КонецЕсли МетаМодуль = ОбщиеМодули.Найти(ирОбщий.ПервыйФрагментЛкс(Подписка.Обработчик)); Если МетаМодуль = Неопределено Тогда // Некорректная подписка Продолжить; КонецЕсли; Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда // Проверяем только подписки менеджеров Если Не МетаМодуль[ИмяСвойства] И Не МетаМодуль.ВызовСервера Тогда ТипыИсточников = Подписка.Источник.Типы(); // Долго! Если ТипыИсточников.Количество() > 0 И Не ирОбщий.ЛиТипОбъектаБДЛкс(ТипыИсточников[0]) Тогда // Это подписка менеджера СписокМодулей.Вставить(МетаМодуль.Имя); КонецЕсли; КонецЕсли; Иначе // Проверяем все подписки в портативном режиме обычном приложении Если Не МетаМодуль[ИмяСвойства] Тогда СписокМодулей.Вставить(МетаМодуль.Имя); КонецЕсли; КонецЕсли; Если Подписка.Событие = "ОбработкаПолученияПредставления" И МетаМодуль.ВызовСервера Тогда СписокМодулейВызоваСервера.Вставить(МетаМодуль.Имя); КонецЕсли; КонецЦикла; Если СписокМодулей.Количество() > 0 Тогда Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ТипыОбъектовПодписок = ""; Иначе ТипыОбъектовПодписок = " менеджеров"; КонецЕсли; СообщитьЛкс("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на события" + ТипыОбъектовПодписок + ".", СтатусСообщения.Внимание); СообщитьЛкс("Поэтому в работе некоторых инструментов возможны ошибки ""При подписке * на событие * произошла ошибка. Обработчик события не найден."""); Если ИмяКлиента = "Обычное" Тогда СообщитьЛкс("Необходимо в конфигураторе установить ""Сервис""/""Параметры""/""Редактирование конфигурации для режимов запуска""=""Управляемое приложение и обычное приложение""."); КонецЕсли; Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда ТекстСообщения = "Рекомендуется установить флажок ""Вызова сервера"" или ""Клиент (" + ИмяКлиента + " приложение)"" и обеспечить компиляцию у этих общих модулей:"; Иначе ТекстСообщения = "Рекомендуется установить флажок ""Клиент (" + ИмяКлиента + " приложение)"" и обеспечить компиляцию у этих общих модулей:"; КонецЕсли; Для Каждого КлючИЗначение Из СписокМодулей Цикл ТекстСообщения = ТекстСообщения + " " + КлючИЗначение.Ключ + ","; КонецЦикла; СообщитьЛкс(ТекстСообщения); Результат = Ложь; КонецЕсли; Если СписокМодулейВызоваСервера.Количество() > 0 Тогда СообщитьЛкс("В конфигурации обнаружены недоступные на клиенте (" + ИмяКлиента + " приложение) общие модули с обработчиками подписок на событие ""ОбработкаПолученияПредставления"".", СтатусСообщения.Внимание); СообщитьЛкс("Это может приводить к сильному замеделению получения представлений таких ссылок. Поэтому перенесите эти обработчики в модуль, компилируемый на толстых клиентах"); Для Каждого КлючИЗначение Из СписокМодулей Цикл ТекстСообщения = ТекстСообщения + " " + КлючИЗначение.Ключ + ","; КонецЦикла; СообщитьЛкс(ТекстСообщения); Результат = Ложь; КонецЕсли; Возврат Результат; КонецФункции // Тяжелый метод. Попытка-Исключение в 5-10 раз быстрее. Функция ЕстьСвойствоОбъектаЛкс(Объект, Свойство) Экспорт УникальноеЗначение = "м86ыщшру5аа7шлв9823454"; Структура = Новый Структура(Свойство, УникальноеЗначение); ЗаполнитьЗначенияСвойств(Структура, Объект); Результат = Структура[Свойство] <> УникальноеЗначение; Возврат Результат; КонецФункции //////////////////////////////// // ФОРМЫ Процедура ИнициализироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы, РазрешитьОткрытиеДополнительныхФорм = Истина) Экспорт // Проверяем режим модальности мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ОткрыватьФормуПерезапуска = Ложь; // Проверка контроля модальности СпрашиватьОПерезапуске = Истина; Список = Новый СписокЗначений; Попытка Список.ВыбратьЭлемент(); Исключение СпрашиватьОПерезапуске = Ложь; КонецПопытки; Если Ложь Или ирКэш.НомерИзданияПлатформыЛкс() = "82" Или мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина Или Метаданные.РежимИспользованияМодальности = Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.Использовать Тогда Если Не СпрашиватьОПерезапуске Тогда ВызватьИсключение "При запуске приложения из конфигуратора автоматически включается контроль модальности. |Запустите приложение другим способом, чтобы разрешить модальность."; КонецЕсли; ИначеЕсли РазрешитьОткрытиеДополнительныхФорм Тогда ИдентификаторПроцессаОС = мПлатформа.ПолучитьИдентификаторПроцессаОС(); ТекущийПроцесс = ПолучитьCOMОбъект("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2:Win32_Process.Handle='" + XMLСтрока(ИдентификаторПроцессаОС) + "'"); КоманднаяСтрокаПроцесса = ТекущийПроцесс.CommandLine; мПлатформа.мВопросОтключенияПроверкиМодальностиЗадавался = Истина; Если Ложь Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckModal") > 0 //Или Найти(КоманднаяСтрокаПроцесса, "/EnableCheckExtensionsAndAddInsSyncCalls") > 0 Тогда СообщитьЛкс("При запуске сеанса из конфигуратора автоматически включается контроль модальности. Для его отключения рекомендуется перезапустить сеанс через открывшуюся форму.", СтатусСообщения.Внимание); ОткрыватьФормуПерезапуска = Истина; КонецЕсли; КонецЕсли; // Проверяем защиту от опасных действий // Здесь это делать мало полезно, т.к. она срабатывает раньше Если Истина И РазрешитьОткрытиеДополнительныхФорм И ирКэш.ЛиПортативныйРежимЛкс() И мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась <> Истина //И ирКэш.НомерВерсииПлатформыЛкс() < 803010 // Когда в платформе исправят проблему, тогда и отключим Тогда ТекущийПользовательБазы = ПользователиИнформационнойБазы.ТекущийПользователь(); Попытка ЗащитаОтОпасныхДействий = ТекущийПользовательБазы.ЗащитаОтОпасныхДействий; Исключение ЗащитаОтОпасныхДействий = Неопределено; КонецПопытки; Если Истина И ЗначениеЗаполнено(ТекущийПользовательБазы.Имя) И ЗащитаОтОпасныхДействий <> Неопределено И ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина Тогда СообщитьЛкс("У текущего пользователя базы включена защита от опасных действий. Для корректной работы инструментров ее рекомендуется отключить перезапуском сеанса через открывшуюся форму.", СтатусСообщения.Внимание); ОткрыватьФормуПерезапуска = Истина; КонецЕсли; мПлатформа.мПроверкаЗащитыОтОпасныхДействийВыполнялась = Истина; КонецЕсли; Если ОткрыватьФормуПерезапуска Тогда #Если ТолстыйКлиентОбычноеПриложение Тогда ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ПерезапускСеансаОбычная"); #Иначе ОткрытьФормуЛкс("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #КонецЕсли КонецЕсли; НастроитьЭлементыФормыЛкс(ЭтаФорма); //_Форма_ВставитьСкрытуюКоманднуюПанельГлобальныхКомандЛкс(ЭтаФорма); ПерехватКлавиатуры = мПлатформа.ПодключитьПерехватКлавиатуры(); СлужебныеДанныеФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); СлужебныеДанныеФормы.Вставить("ПерехватКлавиатуры", ПерехватКлавиатуры); мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); мСвойстваФормы.Вставить("МенеджерСохраненияНастроек"); мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы); мСвойстваФормы.Вставить("НеготовыеСтраницы", Новый СписокЗначений); Если ирКэш.ЛиПортативныйРежимЛкс() Тогда Контейнер = Новый Структура(); Оповестить("ирПолучитьБазовуюФорму", Контейнер); Если Не Контейнер.Свойство("ирПортативный") Тогда БазоваяФорма = ирПортативный.ПолучитьФорму(); БазоваяФорма.Открыть(); КонецЕсли; #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + мПлатформа.ИдентификаторИзПредставленияЛкс(ПолноеИмяФормы) + "(ЭтаФорма)"; Выполнить(СтрокаВызова); Иначе МетаФорма = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПолноеИмяФормы); Если МетаФорма = Неопределено Тогда СообщитьЛкс("Метаформа не найдена по полному имени """ + ПолноеИмяФормы + """", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; ФлажокОбъектыНаСервере = ЭтаФорма.ЭлементыФормы.Найти("ОбъектыНаСервере"); Если ФлажокОбъектыНаСервере <> Неопределено Тогда #Если Сервер И Не Сервер Тогда ирПортативный = Обработки.ирПортативный.Создать(); #КонецЕсли ФлажокОбъектыНаСервере.Доступность = Не ирКэш.ЛиПортативныйРежимЛкс() Или ирПортативный.ЛиСерверныйМодульДоступенЛкс(); Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ФлажокОбъектыНаСервере.Подсказка = "Запись и удаление объектов данных выполнять на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение."; Иначе ФлажокОбъектыНаСервере.Подсказка = "При выполнении кода на клиенте работать с объектами данных на сервере. Это снижает скорость, но повышает совместимость с конфигурациями под управляемое приложение. При выполнении кода на сервере этот параметр не используется."; КонецЕсли; КонецЕсли; Если мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась <> Истина Тогда Если Метаданные.ХранилищеОбщихНастроек <> Неопределено Тогда ИмяПроверочнойНастройки = "Тест"; СохранитьЗначениеЛкс(ИмяПроверочнойНастройки, 1); Если ВосстановитьЗначениеЛкс(ИмяПроверочнойНастройки) = Неопределено Тогда СообщитьЛкс("В конфигурации переопределено хранилище общих настроек и оно не восстанавливает сохраненные значения. Корректная работа подсистемы ""Инструменты разработчика"" невозможна", СтатусСообщения.Важное); КонецЕсли; КонецЕсли; мПлатформа.мПроверкаСовместимостиКонфигурацииВыполнялась = Истина; #Если Сервер И Не Сервер Тогда ВыполнитьПроверкуСовместимостиКонфигурацииЛкс(); #КонецЕсли ПодключитьГлобальныйОбработчикОжиданияЛкс("ВыполнитьПроверкуСовместимостиКонфигурацииЛкс", 1, Истина); КонецЕсли; ирКэш.СостояниеПодготовкиКэшаЛкс(); #Если ТолстыйКлиентУправляемоеПриложение Тогда ирКэш.ВременноеОкноСообщенийЛкс(); // Сразу помещаем форму в кэш, чтобы там включился детектор начала потока кода #КонецЕсли КонецПроцедуры Процедура НастроитьЭлементыФормыЛкс(ЭтаФорма) Экспорт мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); КнопкиВсехДействийКомандныхПанелей = Новый Соответствие; ИмяКнопки = "СтруктураКоманднойПанели"; ВозможныеИменаРеквизита = Новый Массив; ВозможныеИменаРеквизита.Добавить("ОбработкаОбъект"); ВозможныеИменаРеквизита.Добавить("ОсновнойОбъект"); ОсновнойРеквизит = Неопределено; Для Каждого ИмяОсновногоРеквизита Из ВозможныеИменаРеквизита Цикл Если ЕстьСвойствоОбъектаЛкс(ЭтаФорма, ИмяОсновногоРеквизита) Тогда ОсновнойРеквизит = ЭтаФорма[ИмяОсновногоРеквизита]; Прервать; КонецЕсли; КонецЦикла; Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл Если ОсновнойРеквизит <> Неопределено Тогда Попытка Данные = ЭлементФормы.Данные; Подсказка = ЭлементФормы.Подсказка; // У ActiveX этого свойства нет Исключение Данные = ""; КонецПопытки; Если Не ПустаяСтрока(Данные) И Найти(Данные, ".") = 0 Тогда Если Не ЗначениеЗаполнено(ЭлементФормы.Подсказка) Тогда РеквизитОбъекта = ОсновнойРеквизит.Метаданные().Реквизиты.Найти(Данные); Если РеквизитОбъекта <> Неопределено Тогда ЭлементФормы.Подсказка = РеквизитОбъекта.Подсказка; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Встраиваем кнопки структуры командной панели КоманднаяПанель = Неопределено; ВстроитьВНачало = Истина; Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда КоманднаяПанель = ЭлементФормы; Если Не КоманднаяПанель.Видимость Тогда Продолжить; КонецЕсли; ВстроитьВНачало = КоманднаяПанель.Ширина > 100; //ИначеЕсли ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда // КоманднаяПанель = ЭлементФормы.КонтекстноеМеню; Иначе Попытка // В контекстных меню функция маловостребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок КоманднаяПанель = ЭлементФормы.КонтекстноеМеню; ВстроитьВНачало = Ложь; Исключение КонецПопытки; КонецЕсли; Если Истина И КоманднаяПанель <> Неопределено И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено Тогда НужноВстроить = Ложь; КоличествоКнопок = 0; Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда КоличествоКнопок = КоличествоКнопок + 1; Если КоличествоКнопок > 4 Тогда НужноВстроить = Истина; Прервать; КонецЕсли; КонецЕсли; Если Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда НужноВстроить = Истина; Прервать; КонецЕсли; КонецЦикла; Если НужноВстроить Тогда Если ВстроитьВНачало Тогда КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0); Иначе КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Добавить(); КонецЕсли; КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки; КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; КнопкаСтруктураКоманднойПанели.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКоманднаяПанель"); КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто; КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели"; КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели"; Попытка КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие"); Исключение // В этой форме нет обработчика КоманднаяПанель.Кнопки.Удалить(КнопкаСтруктураКоманднойПанели); Возврат; КонецПопытки; КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель); КонецЕсли; КонецЕсли; Если ТипЗнч(ЭлементФормы) = Тип("ТабличноеПоле") Тогда НастроитьТабличноеПолеЛкс(ЭлементФормы); КонецЕсли; КонецЦикла; мСвойстваФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей); КонецПроцедуры Процедура НастроитьТабличноеПолеЛкс(Знач ЭлементФормы) Экспорт // Возвращаем старый стиль шапок колонок, при котором видна текущая колонка Если ЭлементФормы.Колонки.Количество() > 0 Тогда // Антифича платформы 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=898034 Если ЭлементФормы.Колонки[0].ЦветФонаШапки <> ЦветаСтиля.ЦветФонаКнопки Тогда ЭлементФормы.Колонки[0].ЦветФонаШапки = ЦветаСтиля.ЦветФонаКнопки; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда мСвойстваФормы = СлужебныеДанныеФормыЛкс(ЭтаФорма); КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка]; Если Кнопка <> Неопределено Тогда Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда // Для контекстных меню КоманднаяПанель = КоманднаяПанель.Кнопки[0]; КонецЕсли; КонецЕсли; Иначе КоманднаяПанель = РодительЭлементаУправляемойФормыЛкс(Кнопка, Тип("ГруппаФормы")); КонецЕсли; ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы"); ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель; ФормаСтруктуры.Форма = ЭтаФорма; ФормаСтруктуры.ОткрытьМодально(); КонецПроцедуры Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма, КлючУникальности = Неопределено) Экспорт ФормаСтруктуры = ирКэш.Получить().ПолучитьФорму("СтруктураФормы",, КлючУникальности); ФормаСтруктуры.Форма = ЭтаФорма; ФормаСтруктуры.ОткрытьМодально(); КонецПроцедуры Функция ОткрытьФормуСоединенияСУБДЛкс(Автоподключение = Ложь) Экспорт мПлатформа = ирКэш.Получить(); ПроверкаСоединенияADOЭтойБДВыполнялась = мПлатформа.мПроверкаСоединенияADOЭтойБДВыполнялась = Истина; ФормаПодключения = ирКэш.Получить().ПолучитьФорму("ПараметрыСоединенияСУБД"); ФормаПодключения.Автоподключение = Автоподключение И ПроверкаСоединенияADOЭтойБДВыполнялась; Если (Не ПроверкаСоединенияADOЭтойБДВыполнялась Или Не Автоподключение) И Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда Если ФормаПодключения.ОткрытьМодально() <> Истина Тогда Возврат Неопределено; КонецЕсли; КонецЕсли; Возврат ФормаПодключения; КонецФункции Функция ОткрытьОбщиеПараметрыЗаписиЛкс(ТолькоОбъектыНаСервере = Ложь) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Форма = мПлатформа.ПолучитьФорму("ПараметрыЗаписиОбъектов"); Форма.ПараметрТолькоОбъектыНаСервере = ТолькоОбъектыНаСервере; Форма.ОткрытьМодально(); КонецФункции Функция ОткрытьСсылкуИТСЛкс(СтрокаЗапуска) Экспорт Маркер = "v?doc"; Если Найти(СтрокаЗапуска, Маркер) > 0 Тогда ФрагментыМаркера = ирОбщий.СтрРазделитьЛкс(Маркер, "?"); СисИнфо = Новый СистемнаяИнформация; ФрагментыВерсии = ирОбщий.СтрРазделитьЛкс(СисИнфо.ВерсияПриложения); ТекущаяВерсия = ФрагментыВерсии[0] + "." + ФрагментыВерсии[1] + "." + ФрагментыВерсии[2]; ВыбраннаяВерсия = СтрЗаменить(ТекущаяВерсия, ".", ""); СтрокаЗапуска = ирОбщий.СтрЗаменитьЛкс(СтрокаЗапуска, Маркер, ФрагментыМаркера[0] + ВыбраннаяВерсия + ФрагментыМаркера[1]); КонецЕсли; ЗапуститьПриложение(СтрокаЗапуска); КонецФункции Процедура УстановитьДоступностьВыполненияНаСервереЛкс(ЭтаФорма) Экспорт ДоступностьРежима = Не ирКэш.ЛиПортативныйРежимЛкс(); Если ЭтаФорма.ЭлементыФормы.Найти("ВыполнятьНаСервере") <> Неопределено Тогда ЭтаФорма.ЭлементыФормы.ВыполнятьНаСервере.Доступность = ДоступностьРежима; КонецЕсли; Если Не ДоступностьРежима Тогда ЭтаФорма.ЭтотОбъект.ВыполнятьНаСервере = Ложь; КонецЕсли; КонецПроцедуры #КонецЕсли Функция ПреставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт Представление = ""; Если СочетаниеКлавиш.Alt Тогда Представление = Представление + "Alt+"; КонецЕсли; Если СочетаниеКлавиш.Ctrl Тогда Представление = Представление + "Ctrl+"; КонецЕсли; Если СочетаниеКлавиш.Shift Тогда Представление = Представление + "Shift+"; КонецЕсли; Представление = Представление + СочетаниеКлавиш.Клавиша; Возврат Представление; КонецФункции Функция ЦветФонаЯчеекПустыхЗначенийЛкс() Экспорт ЦветПустых = Новый Цвет(250, 255, 250); //WebЦвета.Роса; Возврат ЦветПустых; КонецФункции Функция ВосстановитьЗначениеЛкс(КлючНастроек, ДляВсехПользователей = Ложь) Экспорт #Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда Возврат ВосстановитьЗначениеЛкс(КлючНастроек); #Иначе Если Истина И ДляВсехПользователей И (Ложь Или ирКэш.НомерВерсииПлатформыЛкс() < 803001 Или ПравоДоступа("АдминистрированиеДанных", Метаданные)) Тогда ИмяПользователя = ирКэш.ИмяПродукта(); Иначе //ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ ИмяПользователя = ИмяПользователя(); КонецЕсли; Результат = ХранилищеОбщихНастроек.Загрузить(ирКэш.ИмяПродукта(), КлючНастроек,, ИмяПользователя); #Если Клиент Тогда Если Результат = Неопределено Тогда // Импорт из старого хранилища настроек Результат = ВосстановитьЗначение(КлючНастроек); Если Результат <> Неопределено Тогда СохранитьЗначениеЛкс(КлючНастроек, Результат); СохранитьЗначение(КлючНастроек, Неопределено); КонецЕсли; КонецЕсли; #КонецЕсли Возврат Результат; #КонецЕсли КонецФункции Функция СохранитьЗначениеЛкс(КлючНастроек, Значение, ДляВсехПользователей = Ложь) Экспорт #Если ТонкийКлиент Или ВебКлиент Или МобильныйКлиент Тогда ирСервер.СохранитьЗначениеЛкс(КлючНастроек, Значение); #Иначе Если ДляВсехПользователей И ПравоДоступа("АдминистрированиеДанных", Метаданные) Тогда ИмяПользователя = ирКэш.ИмяПродукта(); Иначе //ИмяПользователя = Неопределено; // Такое значение вызывает ошибки у нестандартных хранилищ ИмяПользователя = ИмяПользователя(); КонецЕсли; ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Значение,, ИмяПользователя); #КонецЕсли КонецФункции Процедура ДобавитьИндексВТаблицуЛкс(ТаблицаЗначений, Знач СтрокаИндекса) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ИндексНайден = Ложь; Для Каждого Индекс Из ТаблицаЗначений.Индексы Цикл Если "" + Индекс = СтрокаИндекса Тогда ИндексНайден = Истина; Прервать; КонецЕсли; КонецЦикла; Если Не ИндексНайден Тогда ТаблицаЗначений.Индексы.Добавить(СтрокаИндекса); КонецЕсли; КонецПроцедуры // вВыполнитьОбработку() // Можно ради скорости отказываться от использования этой функции Функция ЛиПустаяПодгруппаRegExpЛкс(Подгруппа) Экспорт Результат = Ложь Или Подгруппа = Неопределено // наш случай Или Подгруппа = ""; // RegExV8 Возврат Результат; КонецФункции Процедура ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Объект, ИмяСвойства = "Имя") Экспорт Объект["Н" + ИмяСвойства] = НРег(Объект[ИмяСвойства]); КонецПроцедуры Функция ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки) Экспорт #Если Сервер И Не Сервер Тогда МакетКомпоновки = Новый МакетКомпоновкиДанных; #КонецЕсли СхемаКолонок = Новый Структура; // Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных ОписанияМакетовОбластей = МакетКомпоновки.Макеты; Если ОписанияМакетовОбластей.Количество() > 0 Тогда ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки; Если ЯчейкиЗаголовка <> Неопределено Тогда КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество(); Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл // Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205 // http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023 ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс]; Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда Продолжить; КонецЕсли; ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение; Если ПараметрЯчейки = Неопределено Тогда Продолжить; КонецЕсли; Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение; ПозицияТочки = Найти(Выражение, "."); Если Ложь Или ПозицияТочки = 0 Или Найти(Выражение, " ") > 0 Или Найти(Выражение, "(") > 0 Тогда //ИмяПоля = ""; Продолжить; Иначе ИмяПоля = Сред(Выражение, ПозицияТочки + 1); КонецЕсли; СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля); Прервать; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; Возврат СхемаКолонок; КонецФункции Функция ПолучитьТекущуюДатуЛкс(НаСервере = Ложь) Экспорт Если НаСервере Тогда Результат = ирСервер.ПолучитьТекущуюДатуЛкс(); Иначе Результат = ТекущаяДата(); КонецЕсли; Возврат Результат; КонецФункции Функция СтрокиРавныЛкс(Знач Строка1, Знач Строка2, СУчетомРегистра = Ложь, БезПравыхНепечатныхСимволов = Ложь) Экспорт // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Если Не СУчетомРегистра Тогда Строка1 = НРег(Строка1); Строка2 = НРег(Строка2); КонецЕсли; Если БезПравыхНепечатныхСимволов Тогда Строка1 = СокрП(Строка1); Строка2 = СокрП(Строка2); КонецЕсли; Результат = Строка1 = Строка2; Возврат Результат; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Если Не СУчетомРегистра Тогда   Строка1 = НРег(Строка1);   Строка2 = НРег(Строка2);   КонецЕсли;   Если БезПравыхНепечатныхСимволов Тогда   Строка1 = СокрП(Строка1);   Строка2 = СокрП(Строка2);   КонецЕсли;   Результат = Строка1 = Строка2;   Возврат Результат;   КонецФункции // Вставляет параметры в строку, учитывая, что в параметрах могут использоваться подстановочные слова %1, %2 и т.д. Функция ПодставитьПараметрыСПроцентомЛкс(Знач СтрокаПодстановки, Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Результат = ""; Позиция = СтрНайтиЛкс(СтрокаПодстановки, "%"); Пока Позиция > 0 Цикл Результат = Результат + Лев(СтрокаПодстановки, Позиция - 1); СимволПослеПроцента = Сред(СтрокаПодстановки, Позиция + 1, 1); ПодставляемыйПараметр = Неопределено; Если СимволПослеПроцента = "1" Тогда ПодставляемыйПараметр = Параметр1; ИначеЕсли СимволПослеПроцента = "2" Тогда ПодставляемыйПараметр = Параметр2; ИначеЕсли СимволПослеПроцента = "3" Тогда ПодставляемыйПараметр = Параметр3; ИначеЕсли СимволПослеПроцента = "4" Тогда ПодставляемыйПараметр = Параметр4; ИначеЕсли СимволПослеПроцента = "5" Тогда ПодставляемыйПараметр = Параметр5; ИначеЕсли СимволПослеПроцента = "6" Тогда ПодставляемыйПараметр = Параметр6; ИначеЕсли СимволПослеПроцента = "7" Тогда ПодставляемыйПараметр = Параметр7 ИначеЕсли СимволПослеПроцента = "8" Тогда ПодставляемыйПараметр = Параметр8; ИначеЕсли СимволПослеПроцента = "9" Тогда ПодставляемыйПараметр = Параметр9; КонецЕсли; Если ПодставляемыйПараметр = Неопределено Тогда Результат = Результат + "%"; СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 1); Иначе Результат = Результат + ПодставляемыйПараметр; СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 2); КонецЕсли; Позиция = СтрНайтиЛкс(СтрокаПодстановки, "%"); КонецЦикла; Результат = Результат + СтрокаПодстановки; Возврат Результат; КонецФункции // Подставляет параметры в строку. Максимально возможное число параметров - 9. // Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы. // // Параметры: // ШаблонСтроки - Строка - шаблон строки с параметрами (вхождениями вида "%<номер параметра>", // например "%1 пошел в %2"); // Параметр - Строка - значение подставляемого параметра. // // Возвращаемое значение: // Строка - текстовая строка с подставленными параметрами. // // Пример: // СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел // в Зоопарк". // Функция СтрШаблонЛкс(Знач ШаблонСтроки, Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт ЕстьПараметрыСПроцентом = СтрНайтиЛкс(Параметр1, "%") Или СтрНайтиЛкс(Параметр2, "%") Или СтрНайтиЛкс(Параметр3, "%") Или СтрНайтиЛкс(Параметр4, "%") Или СтрНайтиЛкс(Параметр5, "%") Или СтрНайтиЛкс(Параметр6, "%") Или СтрНайтиЛкс(Параметр7, "%") Или СтрНайтиЛкс(Параметр8, "%") Или СтрНайтиЛкс(Параметр9, "%"); Если ЕстьПараметрыСПроцентом Тогда Возврат ПодставитьПараметрыСПроцентомЛкс(ШаблонСтроки, Параметр1, Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); КонецЕсли; ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%1", Параметр1); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%2", Параметр2); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%3", Параметр3); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%4", Параметр4); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%5", Параметр5); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%6", Параметр6); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%7", Параметр7); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%8", Параметр8); ШаблонСтроки = СтрЗаменить(ШаблонСтроки, "%9", Параметр9); Возврат ШаблонСтроки; КонецФункции // Функция собирает строку из элементов массива с разделителем. // // Параметры: // пМассив - Массив - из которого формируем строку; // *пРазделитель - Строка - символ-разделитель. // // Возвращаемое значение: // Строка. // Функция СтрСоединитьЛкс(пМассив, пРазделитель = ", ") Экспорт // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(); Пустая = Истина; Для Каждого Элемент Из пМассив Цикл Если Не Пустая Тогда ЗаписьXML.ЗаписатьБезОбработки(пРазделитель); Иначе Пустая = Ложь; КонецЕсли; ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент)); КонецЦикла; Результат = ЗаписьXML.Закрыть(); Возврат Результат; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) ЗаписьXML = Новый ЗаписьXML;   ЗаписьXML.УстановитьСтроку();   Пустая = Истина;   Для Каждого Элемент Из пМассив Цикл   Если Не Пустая Тогда   ЗаписьXML.ЗаписатьБезОбработки(пРазделитель);   Иначе   Пустая = Ложь;   КонецЕсли;   ЗаписьXML.ЗаписатьБезОбработки(Строка(Элемент));   КонецЦикла;   Результат = ЗаписьXML.Закрыть();   Возврат Результат;   КонецФункции Функция СтрокаИзВыраженияВстроенногоЯзыкаЛкс(Знач Текст) Экспорт Текст = СтрЗаменить(Текст, """""", """"); Если Лев(Текст, 1) = """" Тогда Текст = Сред(Текст, 2); КонецЕсли; Если Прав(Текст, 1) = """" Тогда Текст = Лев(Текст, СтрДлина(Текст) - 1); КонецЕсли; Возврат Текст; КонецФункции // Преобразует исходную строку в число без вызова исключений. // // Параметры: // Значение - Строка - строка, которую необходимо привести к числу. // Например, "10", "+10", "010", вернет 10; // "(10)", "-10",вернет -10; // "10,2", "10.2",вернет 10.2; // "000", " ", "",вернет 0; // "10текст", вернет Неопределено. // // Возвращаемое значение: // Число, Неопределено - полученное число, либо Неопределено, если строка не является числом. // Функция СтрокаВЧислоЛкс(Знач Значение) Экспорт Значение = СтрЗаменить(Значение, " ", ""); Если Лев(Значение, 1) = "(" Тогда Значение = СтрЗаменить(Значение, "(", "-"); Значение = СтрЗаменить(Значение, ")", ""); КонецЕсли; СтрокаБезНулей = СтрЗаменить(Значение, "0", ""); Если ПустаяСтрока(СтрокаБезНулей) Или СтрокаБезНулей = "-" Тогда Возврат 0; КонецЕсли; ТипЧисло = Новый ОписаниеТипов("Число"); Результат = ТипЧисло.ПривестиЗначение(Значение); Возврат ?(Результат <> 0 И Не ПустаяСтрока(СтрокаБезНулей), Результат, Неопределено); КонецФункции // Разделяет URL по составным частям: протокол, сервер, путь к ресурсу. // // Параметры: // URL - Строка - ссылка на ресурс в сети Интернет // // Возвращаемое значение: // Структура: // Протокол - Строка - протокол доступа к ресурсу // ИмяСервера - Строка - сервер, на котором располагается ресурс // ПутьКФайлуНаСервере - Строка - путь к ресурсу на сервере // Функция РазделитьURLЛкс(Знач URL) Экспорт СтруктураURL = СтруктураURIЛкс(URL); Результат = Новый Структура; Результат.Вставить("Протокол", ?(ПустаяСтрока(СтруктураURL.Схема), "http", СтруктураURL.Схема)); Результат.Вставить("ИмяСервера", СтруктураURL.ИмяСервера); Результат.Вставить("ПутьКФайлуНаСервере", СтруктураURL.ПутьНаСервере); Возврат Результат; КонецФункции // Разбирает строку URI на составные части и возвращает в виде структуры. // На основе RFC 3986. // // Параметры: // СтрокаURI - Строка - ссылка на ресурс в формате: <схема>://<логин>:<пароль>@<хост>:<порт>/<путь>?<параметры>#<якорь> // // Возвращаемое значение: // Структура - составные части URI согласно формату: // * Схема - Строка // * Логин - Строка // * Пароль - Строка // * ИмяСервера - Строка - часть <хост>:<порт> входного параметра // * Хост - Строка // * Порт - Строка // * ПутьНаСервере - Строка - часть <путь>?<параметры>#<якорь> входного параметра // Функция СтруктураURIЛкс(Знач СтрокаURI) Экспорт СтрокаURI = СокрЛП(СтрокаURI); // схема Схема = ""; Позиция = Найти(СтрокаURI, "://"); Если Позиция > 0 Тогда Схема = НРег(Лев(СтрокаURI, Позиция - 1)); СтрокаURI = Сред(СтрокаURI, Позиция + 3); КонецЕсли; // строка соединения и путь на сервере СтрокаСоединения = СтрокаURI; ПутьНаСервере = ""; Позиция = Найти(СтрокаСоединения, "/"); Если Позиция > 0 Тогда ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1); СтрокаСоединения = Лев(СтрокаСоединения, Позиция - 1); КонецЕсли; // информация пользователя и имя сервера СтрокаАвторизации = ""; ИмяСервера = СтрокаСоединения; Позиция = Найти(СтрокаСоединения, "@"); Если Позиция > 0 Тогда СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1); ИмяСервера = Сред(СтрокаСоединения, Позиция + 1); КонецЕсли; // логин и пароль Логин = СтрокаАвторизации; Пароль = ""; Позиция = Найти(СтрокаАвторизации, ":"); Если Позиция > 0 Тогда Логин = Лев(СтрокаАвторизации, Позиция - 1); Пароль = Сред(СтрокаАвторизации, Позиция + 1); КонецЕсли; // хост и порт Хост = ИмяСервера; Порт = ""; Позиция = Найти(ИмяСервера, ":"); Если Позиция > 0 Тогда Хост = Лев(ИмяСервера, Позиция - 1); Порт = Сред(ИмяСервера, Позиция + 1); КонецЕсли; Результат = Новый Структура; Результат.Вставить("Схема", Схема); Результат.Вставить("ИспользоватьHTTPS", ирОбщий.СтрокиРавныЛкс(Схема, "HTTPS")); Результат.Вставить("Логин", Логин); Результат.Вставить("Пароль", Пароль); Результат.Вставить("ИмяСервера", ИмяСервера); Результат.Вставить("Хост", Хост); Результат.Вставить("Порт", ?(ПустаяСтрока(Порт), Неопределено, Число(Порт))); Результат.Вставить("ПортHTTP", ?(ПустаяСтрока(Порт), ?(Результат.ИспользоватьHTTPS, 443, 80), Результат.Порт)); Результат.Вставить("ПутьНаСервере", ПутьНаСервере); Возврат Результат; КонецФункции // Поиск числа в строке // // Параметры: // ИсходнаяСтрока - Строка, строка в которой ищется число // ПозицияЧисла - Число, позиция начала числа // КоличествоСимволов - Число, количество символов числа // // Возвращаемое значение: // Булево - Истина, число найдено // Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, выхПозицияЧисла = 0, выхКоличествоСимволов = 0) Экспорт выхПозицияЧисла = 0; выхКоличествоСимволов = 0; ДлинаСтроки = СтрДлина(ИсходнаяСтрока); Для Сч = 1 По ДлинаСтроки Цикл ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1)); Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда Если выхПозицияЧисла = 0 Тогда выхПозицияЧисла = Сч; выхКоличествоСимволов = 1; Иначе выхКоличествоСимволов = выхКоличествоСимволов + 1; КонецЕсли; Иначе Если выхПозицияЧисла <> 0 Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Возврат выхПозицияЧисла > 0; КонецФункции Функция ЭтоКорректныйСимволИмениПеременнойЛкс(Символ, Вычислитель = Неопределено) Экспорт Если Вычислитель = Неопределено Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Вычислитель = ирКэш.ВычислительРегулярныхВыраженийЛкс(); Вычислитель.Pattern = "[" + мПлатформа.шБуква + "\d]"; КонецЕсли; Результат = Вычислитель.Test(Символ); //Код = КодСимвола(Символ, 1); //Результат = (Код <= 57 И Код >= 48) ИЛИ (Код <= 90 И Код >= 65) ИЛИ (Код <= 122 И Код >= 97) ИЛИ (Код <= 1103 И Код >= 1040) ИЛИ Код = 95; Возврат Результат; КонецФункции Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт #Если Клиент Тогда Если ВыводитьПредупрежденияИСообщения Тогда Ответ = КодВозвратаДиалога.ОК; Если НаСервере Тогда ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала); Иначе ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала); КонецЕсли; Если ОбщийРазмер > 0 Тогда Ответ = Вопрос("Действительно удалить рекурсивно все файлы (" + Формат(Цел(ОбщийРазмер/1000000), "ЧН=") + "МБ) в каталоге журнала?", РежимДиалогаВопрос.ОКОтмена); КонецЕсли; Если Ответ <> КодВозвратаДиалога.ОК Тогда Возврат; КонецЕсли; КонецЕсли; Если НаСервере Тогда ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения); Возврат; КонецЕсли; #КонецЕсли ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина); Если ФайлыЖурнала.Количество() > 0 Тогда СчетчикНеудаленных = 0; Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл Попытка УдалитьФайлы(ФайлЖурнала.ПолноеИмя); Исключение СчетчикНеудаленных = СчетчикНеудаленных + 1; КонецПопытки; КонецЦикла; Если ВыводитьПредупрежденияИСообщения Тогда Если СчетчикНеудаленных > 0 Тогда СообщитьЛкс("" + СчетчикНеудаленных + " файлов техножурнала удалить не удалось"); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс() Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги); ОбщийРазмер = 0; Для Каждого Файл Из Файлы Цикл Если Файл.ЭтоКаталог() Тогда Продолжить; КонецЕсли; ОбщийРазмер = ОбщийРазмер + Файл.Размер(); КонецЦикла; Возврат ОбщийРазмер; КонецФункции // Выполняет копирование файлов рекурсивно Процедура СкопироватьФайлыЛкс(КаталогИсточник, КаталогПриемник) Экспорт Файлы = НайтиФайлы(КаталогИсточник, "*.*"); Для Каждого Файл Из Файлы Цикл ФайлПриемник = Новый Файл(КаталогПриемник + "\" + Файл.Имя); Если Файл.ЭтоКаталог() Тогда СоздатьКаталог(ФайлПриемник.ПолноеИмя); СкопироватьФайлыЛкс(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя); Продолжить; КонецЕсли; КопироватьФайл(Файл.ПолноеИмя, ФайлПриемник.ПолноеИмя); КонецЦикла; КонецПроцедуры Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка", НезависимыйРодитель = Ложь) Экспорт Если Родитель = Неопределено Тогда Возврат; КонецЕсли; ТекСостояние = Родитель[ИмяДанныхФлажка]; НайденыВключенные = Ложь; НайденыВыключенные = Ложь; Для каждого Строка из Родитель.Строки Цикл ЗначениеФлажка = Строка[ИмяДанныхФлажка]; Если ЗначениеФлажка = 0 Тогда НайденыВыключенные = Истина; ИначеЕсли ЗначениеФлажка = 1 Тогда НайденыВключенные = Истина; ИначеЕсли ЗначениеФлажка = 2 Тогда НайденыВключенные = Истина; НайденыВыключенные = Истина; Прервать; КонецЕсли; Если НайденыВключенные И НайденыВыключенные Тогда Прервать; КонецЕсли; КонецЦикла; Если НезависимыйРодитель Тогда Если НайденыВключенные Тогда Включить = 2; КонецЕсли; Иначе Если НайденыВключенные И НайденыВыключенные Тогда Включить = 2; ИначеЕсли НайденыВключенные И Не НайденыВыключенные Тогда Включить = 1; ИначеЕсли Не НайденыВключенные И НайденыВыключенные Тогда Включить = 0; ИначеЕсли Не НайденыВключенные И Не НайденыВыключенные Тогда Включить = 2; КонецЕсли; КонецЕсли; Если Включить = ТекСостояние Тогда Возврат; Иначе Если Родитель[ИмяДанныхФлажка] <> 1 Или Не НезависимыйРодитель Тогда Родитель[ИмяДанныхФлажка] = Включить; УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт ТекСостояние = ТекСтрока[ИмяДанныхФлажка]; Подчиненные = ТекСтрока.Строки; Если ТекСостояние = 2 Тогда ТекСтрока[ИмяДанныхФлажка] = 0; КонецЕсли; Если Подчиненные.Количество() > 0 Тогда Для каждого Строка из Подчиненные Цикл Строка[ИмяДанныхФлажка] = ТекСостояние; УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка); КонецЦикла; КонецЕсли; КонецПроцедуры Функция ЛиСпискиПодсистемПересекаютсяЛкс(ФильтрПодсистем, СписокПодсистем) Экспорт Если ТипЗнч(ФильтрПодсистем) = Тип("Строка") Тогда СписокФильтра = Новый СписокЗначений; СписокФильтра.Добавить(ФильтрПодсистем); КонецЕсли; Если Ложь Или СписокФильтра.Количество() = 0 Или СписокФильтра[0] = "" Тогда Возврат Истина; КонецЕсли; Для Каждого Подсистема Из СписокПодсистем Цикл Если ТипЗнч(Подсистема) = Тип("ОбъектМетаданных") Тогда ИмяПодсистемы = Подсистема.ПолноеИмя(); Иначе ИмяПодсистемы = Подсистема.Значение; КонецЕсли; Если СписокФильтра.НайтиПоЗначению(ИмяПодсистемы) <> Неопределено Тогда Возврат Истина; КонецЕсли; КонецЦикла; Возврат Ложь; КонецФункции // Разбирает строку на две части: до подстроки разделителя и после // // Параметры: // Стр - разбираемая строка // Разделитель - подстрока-разделитель // Режим - 0 - разделитель в возвращаемые подстроки не включается // 1 - разделитель включается в левую подстроку // 2 - разделитель включается в правую подстроку // // Возвращаемое значение: // Правая часть строки - до символа-разделителя // Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт ПраваяЧасть = ""; ПозРазделителя = Найти(Стр, Разделитель); ДлинаРазделителя = СтрДлина(Разделитель); Если ПозРазделителя > 0 Тогда ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя)); Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1))); КонецЕсли; Возврат(ПраваяЧасть); КонецФункции // вОтделитьРазделителем() // Проверяет попадание даты внутрь интервала всключая границы Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт ЛиДатаВНеИнтервале = Ложь Или (Истина И ЗначениеЗаполнено(НачалоПериода) И ПроверяемаяДата < НачалоПериода) Или (Истина И ЗначениеЗаполнено(КонецПериода) И ПроверяемаяДата > КонецПериода); Возврат Не ЛиДатаВНеИнтервале; КонецФункции // Проверяет попадание даты внутрь интервала исключая границы Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт ПустаяДата = Дата("00010101"); ЛиДатаВНеИнтервале = Ложь Или (Истина И НачалоПериода <> ПустаяДата И ПроверяемаяДата <= НачалоПериода) Или (Истина И КонецПериода <> ПустаяДата И ПроверяемаяДата >= КонецПериода); Возврат Не ЛиДатаВНеИнтервале; КонецФункции Функция ЛиСобытиеОшибкиФоновогоЗаданияЛкс(ИмяСобытияЖурнала) Экспорт Результат = Ложь Или ИмяСобытияЖурнала = "_$Job$_.Fail" Или ИмяСобытияЖурнала = "_$Job$_.Error"; Возврат Результат; КонецФункции Функция ЛиСобытиеУспехаФоновогоЗаданияЛкс(ИмяСобытияЖурнала) Экспорт Результат = Ложь Или ИмяСобытияЖурнала = "_$Job$_.Finish" Или ИмяСобытияЖурнала = "_$Job$_.Succeed"; Возврат Результат; КонецФункции Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт ПроверочныйФайл = Новый Файл(Каталог); Попытка ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог(); Исключение Если ВыводитьСообщения Тогда СообщитьЛкс("Указанный путь """ + Каталог + """ не доступен: " + ОписаниеОшибки()); КонецЕсли; Возврат Ложь; КонецПопытки; Если Не ЭтоКаталог Тогда Если ВыводитьСообщения Тогда СообщитьЛкс("Указанный путь """ + Каталог + """ не является каталогом"); КонецЕсли; Возврат Ложь; КонецЕсли; Возврат Истина; КонецФункции // http://www.hostedredmine.com/issues/882395 Процедура СообщитьЛкс(ТекстСообщения, Статус = Неопределено, ТолькоВоВременноеОкно = Ложь) Экспорт Если Не ТолькоВоВременноеОкно Тогда Сообщить(ТекстСообщения, Статус); КонецЕсли; #Если ТолстыйКлиентУправляемоеПриложение Тогда Форма = ирКэш.ВременноеОкноСообщенийЛкс(); Форма.ВывестиСообщение(ТекстСообщения); #КонецЕсли КонецПроцедуры Функция ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(СтрокаРасширений, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт Расширения = СтрРазделитьЛкс(СтрокаРасширений, ",", Истина); Результат = ""; Для Каждого Расширение Из Расширения Цикл Если Результат <> "" Тогда Результат = Результат + "|"; КонецЕсли; ОписаниеРасширения = "(*." + Расширение + ")|*." + Расширение; Если ЗначениеЗаполнено(ОписаниеФормата) Тогда ОписаниеРасширения = ОписаниеФормата + " " + ОписаниеРасширения; КонецЕсли; Результат = Результат + ОписаниеРасширения; КонецЦикла; Если РазрешитьВсеФайлы Тогда Результат = Результат + "|Все файлы (*.*)|*.*"; КонецЕсли; Возврат Результат; КонецФункции // Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных // в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана. // Фиксированные коллекции превращаются в нефиксированные. // // Параметры: // КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция; // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник. // // Возвращаемое значение: // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник. // Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт Если КоллекцияИсточник <> Неопределено И КоллекцияИсточник = КоллекцияПриемник Тогда ВызватьИсключение "Нельзя загружать коллекцию в саму себя"; КонецЕсли; ТипКоллекции = ТипЗнч(КоллекцияИсточник); Если Ложь Или ТипКоллекции = Тип("Массив") Или ТипКоллекции = Тип("ФиксированныйМассив") #Если Не ТонкийКлиент И Не ВебКлиент Тогда Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных") #КонецЕсли Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Массив; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл КоллекцияПриемник.Добавить(Элемент); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Структура") Или ТипКоллекции = Тип("ФиксированнаяСтруктура") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Структура; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Соответствие") Или ТипКоллекции = Тип("ФиксированноеСоответствие") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Соответствие; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый СписокЗначений; КонецЕсли; Для Каждого Элемент Из КоллекцияИсточник Цикл ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент); КонецЦикла; Возврат КоллекцияПриемник; #Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки(); КонецЕсли; ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник); Возврат КоллекцияПриемник; #КонецЕсли Иначе СообщитьЛкс("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """"); Возврат Неопределено; КонецЕсли; КонецФункции Функция ОтборУстановленЛкс(Отбор) Экспорт Для Каждого ЭлементОтбора Из Отбор Цикл Если ЭлементОтбора.Использование Тогда Возврат Истина; КонецЕсли; КонецЦикла; Возврат Ложь; КонецФункции #Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент Тогда Процедура ВычислитьВыраженияПараметровЛкс(Знач ТаблицаВычисляемыхПараметров, СтруктураПараметров, Знач МодальныйРежим = Ложь, НаСервере = Ложь) Экспорт Если НаСервере Тогда СтруктураПараметровXML = ирОбщий.СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров); ирСервер.ВычислитьВыраженияПараметровЛкс(ТаблицаВычисляемыхПараметров, СтруктураПараметровXML); СтруктураПараметров = ирОбщий.ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураПараметровXML); Иначе Для каждого СтрокаПараметра Из ТаблицаВычисляемыхПараметров Цикл Значение = Неопределено; Если ЗначениеЗаполнено(СтрокаПараметра.Выражение) Тогда ТекстАлгоритма = " |Параметры = _П0; |лПараметры = _П0; // Устаревшее |Результат = " + СтрокаПараметра.Выражение; Попытка Значение = ВыполнитьАлгоритм(ТекстАлгоритма,,, СтруктураПараметров); Исключение СообщитьСУчетомМодальностиЛкс("Ошибка при вычислении параметра """ + СтрокаПараметра.ИмяПараметра + """" + Символы.ПС + ОписаниеОшибки(), МодальныйРежим, СтатусСообщения.Важное); КонецПопытки; КонецЕсли; СтруктураПараметров.Вставить(СтрокаПараметра.ИмяПараметра, Значение); КонецЦикла; КонецЕсли; КонецПроцедуры Функция ПолучитьГрубоКоличествоСтрокВРезультатеЗапросаЛкс(ЗапросИлиПостроитель, ЛиЗамерВремени = Ложь, МодальныйРежим = Ложь, ИмяЗапроса = "") Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если ТипЗнч(ЗапросИлиПостроитель) = Тип("ПостроительЗапроса") Тогда Запрос = ЗапросИлиПостроитель.ПолучитьЗапрос(); Иначе Запрос = ЗапросИлиПостроитель; КонецЕсли; ОригинальныйТекстЗапроса = Запрос.Текст; // Исключаем тяжелые типы из финальной выборки МассивИменВременныхТаблиц = Новый Массив(); ТекстПостроителя = мПлатформа.ЗамаскироватьВременныеТаблицы(Запрос, , МассивИменВременныхТаблиц); ПостроительЗапроса = Новый ПостроительЗапроса; Попытка ПостроительЗапроса.Текст = ТекстПостроителя; Исключение ОписаниеОшибки = ОписаниеОшибки(); Возврат ОписаниеОшибки; КонецПопытки; ПостроительЗапроса.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять; ПостроительЗапроса.ЗаполнитьНастройки(); УдаляемыеВыбранныеПоля = Новый Массив; Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Найти(ВыбранноеПоле.Имя); ТипЗначенияПоля = ДоступноеПоле.ТипЗначения; Если Ложь Или (Истина И ТипЗначенияПоля.СодержитТип(Тип("Строка")) И ТипЗначенияПоля.КвалификаторыСтроки.Длина = 0) Или ТипЗначенияПоля.СодержитТип(Тип("ХранилищеЗначения")) Тогда УдаляемыеВыбранныеПоля.Добавить(ВыбранноеПоле); КонецЕсли; КонецЦикла; Для Каждого ВыбранноеПоле Из УдаляемыеВыбранныеПоля Цикл ПостроительЗапроса.ВыбранныеПоля.Удалить(ВыбранноеПоле); КонецЦикла; ПромежуточныйТекстЗапроса = ПостроительЗапроса.ПолучитьЗапрос().Текст; ПромежуточныйТекстЗапроса = мПлатформа.РазмаскироватьВременныеТаблицы(ПромежуточныйТекстЗапроса, МассивИменВременныхТаблиц); МассивТекстовЗапросов = мПлатформа.РазбитьГрубоТекстПакетногоЗапросаНаТекстыЗапросов(ПромежуточныйТекстЗапроса); // разбивка производится второй раз. можно оптимизировать ТекстПоследнегоЗапроса = МассивТекстовЗапросов[МассивТекстовЗапросов.ВГраница()]; ТекстДоПоследнегоЗапроса = ""; Для Индекс = 0 По МассивТекстовЗапросов.ВГраница() - 1 Цикл ТекстДоПоследнегоЗапроса = ТекстДоПоследнегоЗапроса + МассивТекстовЗапросов[Индекс]; КонецЦикла; ТекстПоследнегоЗапроса = мПлатформа.ПреобразоватьЗапросВПодзапрос(ТекстПоследнегоЗапроса, "КОЛИЧЕСТВО(1) КАК КоличествоСтрок",, Истина); Запрос.Текст = ТекстДоПоследнегоЗапроса + ТекстПоследнегоЗапроса; #Если Клиент Тогда НачалоПредварительногоВыполнения = мПлатформа.ПолучитьТекущееВремяВМиллисекундах(); #КонецЕсли Попытка РезультатПредварительногоЗапроса = Запрос.Выполнить(); ПредварительныйЗапросБылиОшибки = Ложь; Исключение ПредварительныйЗапросБылиОшибки = Истина; КоличествоСтрок = ОписаниеОшибки(); КонецПопытки; #Если Клиент Тогда Если Истина И ЛиЗамерВремени И Не ПредварительныйЗапросБылиОшибки Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Время формирования предварительного результата """ + ИмяЗапроса + """ - " + Строка(мПлатформа.ПолучитьТекущееВремяВМиллисекундах() - НачалоПредварительногоВыполнения) + " мс", МодальныйРежим); КонецЕсли; #КонецЕсли Если Не ПредварительныйЗапросБылиОшибки Тогда КоличествоСтрок = РезультатПредварительногоЗапроса.Выгрузить()[0].КоличествоСтрок; КонецЕсли; Запрос.Текст = ОригинальныйТекстЗапроса; Возврат КоличествоСтрок; КонецФункции Функция ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновкиЛкс(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки = Ложь, ЛиЗамерВремени = Ложь, МодальныйРежим = Ложь) Экспорт КоличествоСтрокВсего = 0; Запрос = Новый Запрос; Для Каждого ЗначениеПараметра Из МакетКомпоновкиДанныхВКоллекциюЗначений.ЗначенияПараметров Цикл Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение); КонецЦикла; Для Каждого НаборДанных Из МакетКомпоновкиДанныхВКоллекциюЗначений.НаборыДанных Цикл Если ТипЗнч(НаборДанных) <> Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда Продолжить; КонецЕсли; Запрос.Текст = НаборДанных.Запрос; КоличествоСтрок = ПолучитьГрубоКоличествоСтрокВРезультатеЗапросаЛкс(Запрос, ЛиЗамерВремени, МодальныйРежим, НаборДанных.Имя); Если ТипЗнч(КоличествоСтрок) = Тип("Число") Тогда КоличествоСтрокВсего = КоличествоСтрокВсего + КоличествоСтрок; Иначе БылиОшибки = Истина; КонецЕсли; КонецЦикла; Возврат КоличествоСтрокВсего; КонецФункции // ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки() Функция СкомпоноватьОтчетВКонсолиЛкс(КоллекцияВывода, Знач МакетКомпоновкиДанных, ВнешниеНаборыДанных = Неопределено, Автофиксация = Истина, МодальныйРежим = Ложь, ЛиОтладка = Ложь, АдресДанныхРасшифровки = Неопределено, НаСервере = Ложь, МаркироватьНачалоИКонецВТехножурнале = Истина, выхЭлементыРезультата = Неопределено) Экспорт Если НаСервере Тогда АдресКоллекцииВывода = ПоместитьВоВременноеХранилище(КоллекцияВывода); АдресМакетаКомпоновки = ПоместитьВоВременноеХранилище(МакетКомпоновкиДанных); Результат = ирСервер.СкомпоноватьОтчетВКонсолиЛкс(АдресКоллекцииВывода, АдресМакетаКомпоновки, ВнешниеНаборыДанных, Автофиксация, МодальныйРежим, ЛиОтладка, АдресДанныхРасшифровки); КоллекцияВывода = ПолучитьИзВременногоХранилища(АдресКоллекцииВывода); Возврат Результат; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); МакетКомпоновкиДанных = Новый МакетКомпоновкиДанных; #КонецЕсли // Осторожная выборка ВыполнятьПредварительныйЗапрос = ВосстановитьЗначениеЛкс("ир_ВыполнятьПредварительныйЗапрос"); БезопасныйПорогКоличестваСтрок = ВосстановитьЗначениеЛкс("ир_БезопасныйПорогКоличестваСтрок"); Если ВыполнятьПредварительныйЗапрос = Истина Тогда //Если ТипЗнч(КоллекцияВывода) = Тип("ТабличныйДокумент") Тогда МакетКомпоновкиДанныхВКоллекциюЗначений = МакетКомпоновкиДанных; //Иначе // МакетКомпоновкиДанныхВКоллекциюЗначений = ПолучитьМакетКомпоновки("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"); //КонецЕсли; БылиОшибки = Ложь; КоличествоСтрокВсего = ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновкиЛкс(МакетКомпоновкиДанныхВКоллекциюЗначений, БылиОшибки, ЛиОтладка, МодальныйРежим); ТекстВопроса = "Оценка общего размера результатов запросов макета составляет " + КоличествоСтрокВсего + " строк."; Если БылиОшибки Тогда ТекстВопроса = ТекстВопроса + " |При расчете некоторые запросы не удалось проанализировать." КонецЕсли; Если Ложь Или БезопасныйПорогКоличестваСтрок * 1000 < КоличествоСтрокВсего Или БылиОшибки Тогда #Если Клиент Тогда Ответ = Вопрос(ТекстВопроса + " Продолжить?", РежимДиалогаВопрос.ОКОтмена); Отменить = Ответ <> КодВозвратаДиалога.ОК; #Иначе СообщитьЛкс(ТекстВопроса + " Отмена."); Отменить = Истина; #КонецЕсли Если Отменить Тогда Возврат Ложь; КонецЕсли; КонецЕсли; КонецЕсли; Если ЛиОтладка Тогда Запрос = Новый Запрос; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл ЗначениеПараметра = Параметр.Значение; Если ТипЗнч(ЗначениеПараметра) = Тип("ВыражениеКомпоновкиДанных") Тогда Попытка ЗначениеПараметра = Вычислить(ЗначениеПараметра); Исключение ЗначениеПараметра = Неопределено; ирОбщий.СообщитьСУчетомМодальностиЛкс("Ошибка вычисления значения параметра """ + Параметр.Имя + """: " + ОписаниеОшибки(), МодальныйРежим, СтатусСообщения.Внимание); КонецПопытки; КонецЕсли; Запрос.УстановитьПараметр(Параметр.Имя, ЗначениеПараметра); КонецЦикла; СтруктураНаборовДанныхЗапросовМакета = ВсеНаборыДанныхЗапросовКомпоновкиЛкс(МакетКомпоновкиДанных.НаборыДанных); Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных; Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда // Служебные наборы данных пропускаем Продолжить; КонецЕсли; Запрос.Текст = НаборДанных.Запрос; ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Запрос - " + НаборДанных.Имя) КонецЦикла; КонецЕсли; Если ЛиОтладка Тогда НачалоВывода = мПлатформа.ПолучитьТекущееВремяВМиллисекундах(); КонецЕсли; Если МаркироватьНачалоИКонецВТехножурнале Тогда мАнализТехножурнала = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирАнализТехножурнала"); #Если Сервер И Не Сервер Тогда мАнализТехножурнала = Обработки.ирАнализТехножурнала.Создать(); #КонецЕсли мАнализТехножурнала.НачатьТрассу("КонсольКомпоновки"); КонецЕсли; Если АдресДанныхРасшифровки <> Неопределено Тогда ДанныеРасшифровки = ПолучитьИзВременногоХранилища(АдресДанныхРасшифровки); КонецЕсли; ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина); Если Ложь Или ТипЗнч(КоллекцияВывода) = Тип("ТабличныйДокумент") #Если Клиент Тогда Или ТипЗнч(КоллекцияВывода) = Тип("ПолеТабличногоДокумента") #КонецЕсли Тогда выхЭлементыРезультата = Новый Массив; ЭлементыРасшифровки = Неопределено; Если ДанныеРасшифровки <> Неопределено Тогда ЭлементыРасшифровки = ДанныеРасшифровки.Элементы; КонецЕсли; ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(КоллекцияВывода, ПроцессорКомпоновкиДанных, ЭлементыРасшифровки, , , Автофиксация, выхЭлементыРезультата); Иначе ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; КоллекцияВывода.Колонки.Очистить(); ПроцессорВывода.УстановитьОбъект(КоллекцияВывода); ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина); КонецЕсли; Если АдресДанныхРасшифровки <> Неопределено Тогда АдресДанныхРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровки); КонецЕсли; Если МаркироватьНачалоИКонецВТехножурнале Тогда мАнализТехножурнала.КончитьТрассу(); КонецЕсли; Если ЛиОтладка Тогда СообщитьСУчетомМодальностиЛкс("Формирование результата - " + Строка(мПлатформа.ПолучитьТекущееВремяВМиллисекундах() - НачалоВывода) + " мс", МодальныйРежим); КонецЕсли; Возврат Истина; КонецФункции // Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом. // Содержит рекурсивный вызов. // // Параметры: // НаборыДанных – НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных; // *СтруктураНаборовДанных – Структура, *Неопрелено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных")) // // Возвращаемое значение: // Структура. // Функция ВсеНаборыДанныхЗапросовКомпоновкиЛкс(Знач НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт Если СтруктураНаборовДанных = Неопределено Тогда СтруктураНаборовДанных = Новый Структура; КонецЕсли; Для каждого НаборДанных Из НаборыДанных Цикл Если Ложь Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда // Платформа генерит такие наборы для служебных целей ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); Иначе ИмяНабора = НаборДанных.Имя; КонецЕсли; СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных)); ИначеЕсли Ложь Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных") Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных") Тогда ВсеНаборыДанныхЗапросовКомпоновкиЛкс(НаборДанных.Элементы, СтруктураНаборовДанных); КонецЕсли; КонецЦикла; Возврат СтруктураНаборовДанных; КонецФункции // Выводит результат СКД с установкой вертикальной автофиксации. // Параметры: // Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет; // ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных; // ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных; // МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей; // РазрешитьПрерывание - Булево, *Истина. // Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки = Неопределено, Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных; #КонецЕсли ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.ОтображатьПроцентВывода = Ложь; ПроцессорВывода.УстановитьДокумент(Таб); ПроцессорВывода.НачатьВывод(); ФиксацияВыполнена = Ложь; Если МассивИгнорируемыхПолей = Неопределено Тогда МассивИгнорируемыхПолей = Новый Массив; КонецЕсли; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(100, "Компоновка",,, Ложь); Пока Истина Цикл Если РазрешитьПрерывание Тогда #Если Клиент Тогда ОбработкаПрерыванияПользователя(); #КонецЕсли КонецЕсли; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий(); Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда Прервать; КонецЕсли; Если Индикатор.Счетчик <> ЭлементРезультатаКомпоновкиДанных.ПроцентВывода Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор, ЭлементРезультатаКомпоновкиДанных.ПроцентВывода); КонецЕсли; // Автофиксация Если Истина И Автофиксация И Не ФиксацияВыполнена И ЭлементыРасшировки <> Неопределено Тогда Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля(); Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда Таб.ФиксацияСверху = Таб.ВысотаТаблицы; ФиксацияВыполнена = Истина; Прервать; КонецЕсли; КонецЦикла; Если ФиксацияВыполнена Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных); Если Истина И выхЭлементыРезультата <> Неопределено И выхЭлементыРезультата.Количество() < 10000 Тогда выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных); КонецЕсли; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();   Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда   Прервать;   КонецЕсли;   Если Индикатор.Счетчик <> ЭлементРезультатаКомпоновкиДанных.ПроцентВывода Тогда   ирОбщий.ОбработатьИндикаторЛкс(Индикатор, ЭлементРезультатаКомпоновкиДанных.ПроцентВывода);   КонецЕсли;     Если Истина   И Автофиксация   И Не ФиксацияВыполнена   И ЭлементыРасшировки <> Неопределено   Тогда   Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл   Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда   ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();   Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл   Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда   Таб.ФиксацияСверху = Таб.ВысотаТаблицы;   ФиксацияВыполнена = Истина;   Прервать;   КонецЕсли;   КонецЦикла;   Если ФиксацияВыполнена Тогда   Прервать;   КонецЕсли;   КонецЕсли;   КонецЦикла;   КонецЕсли;   ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);   Если Истина   И выхЭлементыРезультата <> Неопределено   И выхЭлементыРезультата.Количество() < 10000   Тогда   выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);   КонецЕсли;   КонецЦикла; ПроцессорВывода.ЗакончитьВывод(); КонецПроцедуры // ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс Функция ТабличноеПолеИлиТаблицаФормы_СколькоСтрокЛкс(ТабличноеПоле, Знач НастройкиСписка = Неопределено) Экспорт ЗначениеЭУ = ДанныеЭлементаФормыЛкс(ТабличноеПоле); //ТипЗначенияТабличногоПоля = ТипЗнч(ИсточникДействий.Значение); //ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаИзКонкретногоТипа, ТипЗначенияТабличногоПоля); Попытка Количество = ЗначениеЭУ.Количество(); Попытка Отбор = ТабличноеПоле.ОтборСтрок; Исключение КонецПопытки; Если ТипЗнч(Отбор) = Тип("Отбор") И ОтборУстановленЛкс(Отбор) Тогда #Если Клиент Тогда Количество = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТабличноеПоле,, Истина).Количество(); #КонецЕсли КонецЕсли; Исключение Попытка //Коллекция компоновки Количество = ЗначениеЭУ.Элементы.Количество(); //Суффикс = "*"; Исключение Попытка //Или ИмяОбщегоТипа = "ДеревоЗначений" Количество = ЗначениеЭУ.Строки.Количество(); Суффикс = "*"; Исключение // ДинамическийСписок ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); ИмяСлужебногоПоля = "СлужебноеПоле123213м34"; ТекстЗапроса = "ВЫБРАТЬ Т.*, 0 КАК " + ИмяСлужебногоПоля + " ИЗ " + ПолноеИмяТаблицы + " КАК Т"; СхемаКомпоновки = ирОбщий.СоздатьСхемуКомпоновкиПоЗапросу(ТекстЗапроса); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; Если НастройкиСписка = Неопределено Тогда НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ЗначениеЭУ); КонецЕсли; ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор); //ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок); ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ИмяСлужебногоПоля); Запрос = ПолучитьЗапросИзКомпоновкиЛкс(СхемаКомпоновки, НастройкаКомпоновки,,,,, Ложь); #Если Сервер И Не Сервер Тогда Запрос = Новый Запрос; #КонецЕсли Запрос.Текст = СтрЗаменить(Запрос.Текст, "0 КАК " + ИмяСлужебногоПоля, "РАЗРЕШЕННЫЕ КОЛИЧЕСТВО(*) КАК КоличествоСтрок"); Количество = Запрос.Выполнить().Выгрузить()[0][0]; Отбор = НастройкиСписка.Отбор; КонецПопытки; КонецПопытки; КонецПопытки; Текст = "Количество строк "; Если Отбор <> Неопределено Тогда Текст = Текст + "отобрано "; КонецЕсли; Текст = Текст + "- " + Формат(Количество, "ЧН=; ЧГ=") + Суффикс; Если ТабличноеПоле.ВыделенныеСтроки.Количество() > 1 Тогда Текст = Текст + ", выделено - " + Формат(ТабличноеПоле.ВыделенныеСтроки.Количество(), "ЧН=; ЧГ="); КонецЕсли; Если Отбор <> Неопределено Тогда Текст = Текст + ". Отбор - """ + Отбор + """ "; КонецЕсли; СообщитьЛкс(Текст); // Тексты подвала Результат = Количество; МассивПодвалов = Новый Массив; Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл ТекстПодвала = ПоследнийФрагментЛкс(КолонкаТП.ТекстПодвала, "Σ"); Если ЗначениеЗаполнено(ТекстПодвала) Тогда МассивПодвалов.Добавить(КолонкаТП.ТекстШапки + " = " + ТекстПодвала); КонецЕсли; КонецЦикла; Если МассивПодвалов.Количество() > 0 Тогда СообщитьЛкс(СтрСоединитьЛкс(МассивПодвалов, "; ")); КонецЕсли; Возврат Результат; КонецФункции Функция ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле, выхПолноеИмяМД = "") Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда //выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле); ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма); СлужебныеДанные = СлужебныеДанныеФормыЛкс(ЭтаФорма); Если СлужебныеДанные <> Неопределено Тогда ДинамическийСписок = СлужебныеДанные.ДинамическиеСписки[ПутьКДаннымСписка]; ПолноеИмяТаблицы = ДинамическийСписок.ОсновнаяТаблица; Иначе ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока; Если Ложь Или ТекущаяСтрока = Неопределено Или ТипЗнч(ТекущаяСтрока) = Тип("Число") // Основная таблица не указана Тогда Возврат Неопределено; КонецЕсли; ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(ТекущаяСтрока)).ПолноеИмя(); КонецЕсли; Если Не ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда ПолноеИмяТаблицы = СокрЛП(ирОбщий.СтрокаМеждуМаркерамиЛкс(ДинамическийСписок.ТекстЗапроса, "ИЗ ", " КАК _Т", Ложь)); КонецЕсли; ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы); Иначе ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)); КонецЕсли; Если ОбъектМД <> Неопределено Тогда выхПолноеИмяМД = ОбъектМД.ПолноеИмя(); КонецЕсли; Если ЗначениеЗаполнено(выхПолноеИмяМД) Тогда ПолноеИмяТаблицы = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД); КонецЕсли; Возврат ПолноеИмяТаблицы; КонецФункции Функция ЗапросДинамическогоСпискаЛкс(ТабличноеПоле) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда //выхПолноеИмяМД = ДинамическийСписок.ОсновнаяТаблица; // На клиенте недоступно ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле); ПутьКДаннымСписка = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле,, ЭтаФорма); ДинамическийСписок = ЭтаФорма.мСлужебныеДанные.ДинамическиеСписки[ПутьКДаннымСписка]; ПолноеИмяТаблицы = ДинамическийСписок.ОсновнаяТаблица; Если ЗначениеЗаполнено(ПолноеИмяТаблицы) Тогда Запрос = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицы; Иначе Запрос = ДинамическийСписок.Запрос; КонецЕсли; Иначе выхПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя(); ПолноеИмяТаблицы = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(выхПолноеИмяМД); Запрос = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицы; КонецЕсли; Возврат Запрос; КонецФункции // Формирует макет компоновки и извлекает из него запрос // Параметры: // Схема - СхемаКомпоновкиДанных // НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных // ДобавлятьУпорядочивание - Булево // ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один // выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура, // где ключи - имена колонок, а значения - полные имена полей // // Результат - Запрос // Функция ПолучитьЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновкиДанных, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "", ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт НастройкаКомпоновкиДанных = КопияОбъектаЛкс(НастройкаКомпоновкиДанных); #Если Сервер И Не Сервер Тогда НастройкаКомпоновкиДанных = Новый НастройкиКомпоновкиДанных #КонецЕсли Если НастройкаКомпоновкиДанных.Структура.Количество() = 0 Тогда НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура); КонецЕсли; Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ДобавитьВыбранноеПоле); КонецЕсли; Если Не СПредставлениямиСсылок Тогда Для Каждого ВыбранноеПоле Из НастройкаКомпоновкиДанных.Выбор.Элементы Цикл Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда ВызватьИсключение "Неподдерживаемый тип выбранного поля - " + ТипЗнч(ВыбранноеПоле); КонецЕсли; Если ВыбранноеПоле.Использование Тогда НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации КонецЕсли; КонецЦикла; НастройкаКомпоновкиДанных.Выбор.Элементы.Очистить(); КонецЕсли; КопияПорядка = Новый Массив; Для Каждого ЭлементПорядка Из НастройкаКомпоновкиДанных.Порядок.Элементы Цикл Если ЭлементПорядка.Использование Тогда КопияПорядка.Добавить(ЭлементПорядка); НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ЭлементПорядка.Поле); КонецЕсли; КонецЦикла; НастройкаКомпоновкиДанных.Порядок.Элементы.Очистить(); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; // ирОбщий.ОтЛкс(Схема, НастройкаКомпоновкиДанных) МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновкиДанных, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей); СтрокаПорядка = ВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(КопияПорядка,,,, МакетКомпоновки.НаборыДанных[0].Поля); Запрос = Новый Запрос; Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда СообщитьЛкс("В макете компоновки обнаружено более одного запроса"); КонецЕсли; ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос; Если ДобавлятьУпорядочивание Тогда Если ЗначениеЗаполнено(СтрокаПорядка) Тогда ТекстЗапроса = ТекстЗапроса + " |//Секция_Упорядочить. Этот комментарий используется в коде |УПОРЯДОЧИТЬ ПО | " + СтрокаПорядка; КонецЕсли; Если Ложь Или Автоупорядочивание //Или ЗначениеЗаполнено(СтрокаПорядка) Тогда ТекстЗапроса = ТекстЗапроса + " |//Секция_Упорядочить. Этот комментарий используется в коде |АВТОУПОРЯДОЧИВАНИЕ"; КонецЕсли; КонецЕсли; Запрос.Текст = ТекстЗапроса; Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение); КонецЦикла; Если ПрефиксИменПараметров <> "" Тогда ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров); КонецЕсли; Если выхСхемаКолонок <> Неопределено Тогда //выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки); // НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0]; Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным); КонецЦикла; Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным); КонецЦикла; КонецЕсли; Возврат Запрос; КонецФункции // Получает строку для установки порядка компоновки. // // Параметры: // ПорядокКомпоновки – ПорядокКомпоновкиДанных, ЭлементыПорядкаКомпоновкиДанных // ИсключаемоеПоле - Строка // СимволЗаменыТочки - Строка // ДиалектSQL - Строка // ПутиКДаннымПолей - ПоляНабораДанныхЗапросаМакетаКомпоновкиДанных // // Возвращаемое значение: // Строка - для установки порядка. // Функция ВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(Знач ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1C", ПутиКДаннымПолей = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Пустышка = Новый НастройкиКомпоновкиДанных; ПорядокКомпоновки = Пустышка.Порядок; #КонецЕсли Если ТипЗнч(ПорядокКомпоновки) = Тип("ПорядокКомпоновкиДанных") Тогда ПорядокКомпоновки = ПорядокКомпоновки.Элементы; КонецЕсли; Строка = ""; Если СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда СтрокаВозр = "Возр"; СтрокаУбыв = "Убыв"; Иначе СтрокаВозр = "Asc"; СтрокаУбыв = "Desc"; КонецЕсли; Для Каждого ЭлементПорядка Из ПорядокКомпоновки Цикл Если Ложь Или Не ЭлементПорядка.Использование Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных") Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле Тогда Продолжить; КонецЕсли; ИмяПоля = "" + ЭлементПорядка.Поле; Если ПутиКДаннымПолей <> Неопределено Тогда ПутьКДаннымПоля = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ПутиКДаннымПолей, "ПутьКДанным", ИмяПоля); Если ПутьКДаннымПоля = Неопределено Тогда // Например реквизит ТЧ Продолжить; КонецЕсли; ИмяПоля = ПутьКДаннымПоля.Имя; КонецЕсли; Если СимволЗаменыТочки <> Неопределено Тогда ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки); КонецЕсли; Строка = Строка + ", " + ИмяПоля + " "; Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда Строка = Строка + СтрокаВозр; Иначе Строка = Строка + СтрокаУбыв; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 3); КонецФункции // ТипНастроек - Число Функция НастройкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, ТипНастроек = "Результирующие") Экспорт Если ТипЗнч(ДинамическийСписок) = Тип("ДинамическийСписок") Тогда Если ТипНастроек = "Результирующие" Тогда НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ПолучитьНастройки(); ИначеЕсли ТипНастроек = "Фиксированные" Тогда НастройкиСписка = ДинамическийСписок.КомпоновщикНастроек.ФиксированныеНастройки; ИначеЕсли ТипНастроек = "Пользовательские" Тогда ПользовательскиеНастройки = ДинамическийСписок.КомпоновщикНастроек.ПользовательскиеНастройки; #Если Сервер И Не Сервер Тогда ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных; #КонецЕсли НастройкиСписка = Новый Структура("Отбор, Порядок, УсловноеОформление"); Для Каждого ЭлементПользовательскихНастроек Из ПользовательскиеНастройки.Элементы Цикл Если ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ОтборКомпоновкиДанных") Тогда НастройкиСписка.Отбор = ЭлементПользовательскихНастроек; ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("ПорядокКомпоновкиДанных") Тогда НастройкиСписка.Порядок = ЭлементПользовательскихНастроек; ИначеЕсли ТипЗнч(ЭлементПользовательскихНастроек) = Тип("УсловноеОформлениеКомпоновкиДанных") Тогда НастройкиСписка.УсловноеОформление = ЭлементПользовательскихНастроек; КонецЕсли; КонецЦикла; Иначе НастройкиСписка = ДинамическийСписок; КонецЕсли; Иначе НастройкиСписка = ДинамическийСписок; КонецЕсли; Возврат НастройкиСписка; КонецФункции // Параметры: // СписокПодсистем - СписокЗначений // Результат - Соответствие - ключи - объекты метаданных входящие в заданные подсистемы Функция ОбъектыПодсистемЛкс(СписокПодсистем, СтрокаДереваПодсистем = Неопределено, ОбъектыВыбранныхПодсистем = Неопределено) Экспорт Если ОбъектыВыбранныхПодсистем = Неопределено Тогда ОбъектыВыбранныхПодсистем = Новый Соответствие; КонецЕсли; ПодсистемаПеревод = ПеревестиСтроку("Подсистема"); Для Каждого ЭлементСписка Из СписокПодсистем Цикл //ПодсистемаМД = ирКэш.ОбъектМДПоПолномуИмениЛкс("Подсистема." + СтрЗаменить(ЭлементСписка.Значение, ".", ".Подсистема.")); ПодсистемаМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(ПодсистемаПеревод + "." + СтрЗаменить(ЭлементСписка.Значение, ".", "." + ПодсистемаПеревод + ".")); Для Каждого ЭлементСостава Из ПодсистемаМД.Состав Цикл ОбъектыВыбранныхПодсистем.Вставить(ЭлементСостава, 1); КонецЦикла; КонецЦикла; Возврат ОбъектыВыбранныхПодсистем; КонецФункции Функция НоваяТаблицаНастроекСтандартногоХранилищаЛкс() Экспорт ТабОписаний = Новый ТаблицаЗначений; ТабОписаний.Колонки.Добавить("ИмяХранилища"); ТабОписаний.Колонки.Добавить("ИмяОбъекта"); ТабОписаний.Колонки.Добавить("КлючНастроек"); ТабОписаний.Колонки.Добавить("Настройка"); ТабОписаний.Колонки.Добавить("ИмяПользователя"); ТабОписаний.Колонки.Добавить("Описание"); Возврат ТабОписаний; КонецФункции Функция ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(мдОбъекта, ВключаяПоследовательности = Ложь, ВключаяПерерасчеты = Ложь) Экспорт ОбъектыМД = Новый Массив(); Для Каждого МетаРегистр из мдОбъекта.Движения Цикл ОбъектыМД.Добавить(МетаРегистр); Если ВключаяПерерасчеты Тогда Если ЛиКорневойТипРегистраРасчетаЛкс(ПервыйФрагментЛкс(МетаРегистр.ПолноеИмя())) Тогда Для Каждого ПерерасчетМД Из МетаРегистр.Перерасчеты Цикл ОбъектыМД.Добавить(ПерерасчетМД); КонецЦикла; КонецЕсли; КонецЕсли; КонецЦикла; Если ВключаяПоследовательности Тогда Для Каждого МетаПоследовательность Из Метаданные.Последовательности Цикл Если МетаПоследовательность.Документы.Содержит(мдОбъекта) Тогда ОбъектыМД.Добавить(МетаПоследовательность); КонецЕсли; КонецЦикла; КонецЕсли; Возврат ОбъектыМД; КонецФункции // Функция считывает в табличный документ данные из текстового файла // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные // ИмяФайла - имя текстового файла, из которого необходимо прочитать данные // // Возвращаемое значение: // Истина, если файл прочитан, Ложь - иначе // Функция ПрочитатьТабличныйДокументИзТекстаЛкс(ТабличныйДокумент, ИмяФайла, Разделитель = ",", ОбрезатьНепечатныеСимволы = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ВыбФайл = Новый Файл(ИмяФайла); Если НЕ ВыбФайл.Существует() Тогда СообщитьЛкс("Файл не существует!"); Возврат Ложь; КонецЕсли; ТекстовыйДокумент = Новый ТекстовыйДокумент; Попытка ТекстовыйДокумент.Прочитать(ИмяФайла); Исключение СообщитьЛкс("Ошибка открытия файла!"); Возврат Ложь; КонецПопытки; ТабличныйДокумент.Очистить(); Текст = ТекстовыйДокумент.ПолучитьТекст(); #Если Клиент Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаРазбивки = мПлатформа.ПолучитьФорму("РазбивкаТекста"); ФормаРазбивки.Приемник = ТабличныйДокумент; ФормаРазбивки.Текст = Текст; Если ФормаРазбивки.ОткрытьМодально() = Неопределено Тогда Возврат Ложь; КонецЕсли; #Иначе ирОбщий.ПолучитьТаблицуИзСтрокиСРазделителемЛкс(Текст, Разделитель, ОбрезатьНепечатныеСимволы, ТабличныйДокумент); #КонецЕсли Возврат Истина; КонецФункции // () // Функция считывает в табличный документ данные из файла в формате dBase III (*.dbf) // // Параметры: // ТабличныйДокумент - ТабличныйДокумент, в который необходимо прочитать данные // ИмяФайла - имя файла в формате TXT, из которого необходимо прочитать данные // // Возвращаемое значение: // Истина, если файл прочитан, Ложь - иначе // Функция ПрочитатьТабличныйДокументИзDBFЛкс(ТабличныйДокумент, ИмяФайла) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ВыбФайл = Новый Файл(ИмяФайла); Если НЕ ВыбФайл.Существует() Тогда СообщитьЛкс("Файл не существует!"); Возврат Ложь; КонецЕсли; XBase = Новый XBase; XBase.Кодировка = КодировкаXBase.OEM; Попытка XBase.ОткрытьФайл(ИмяФайла); Исключение СообщитьЛкс("Ошибка открытия файла!"); Возврат Ложь; КонецПопытки; ТабличныйДокумент.Очистить(); ТекущаяСтрока = 1; ТекущаяКолонка = 0; Для каждого Поле Из XBase.поля Цикл ТекущаяКолонка = ТекущаяКолонка + 1; ТабличныйДокумент.Область("R" + Формат(ТекущаяСтрока, "ЧГ=") +"C" + Формат(ТекущаяКолонка, "ЧГ=")).Текст = Поле.Имя; КонецЦикла; Рез = XBase.Первая(); Пока Не XBase.ВКонце() Цикл ТекущаяСтрока = ТекущаяСтрока + 1; ТекущаяКолонка = 0; Для каждого Поле Из XBase.поля Цикл ТекущаяКолонка = ТекущаяКолонка + 1; Если Поле.Тип = "M" Тогда Продолжить; КонецЕсли; ТабличныйДокумент.Область("R" + Формат(ТекущаяСтрока, "ЧГ=") +"C" + Формат(ТекущаяКолонка, "ЧГ=")).Текст = XBase.ПолучитьЗначениеПоля(ТекущаяКолонка - 1); КонецЦикла; XBase.Следующая(); КонецЦикла; Возврат Истина; КонецФункции // () // Параметры: // ТаблицаПриемник - ТабличныйДокумент, ТаблицаЗначений, *Неопределено // Функция ПолучитьТаблицуИзСтрокиСРазделителемЛкс(Знач Текст, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь, Знач ИменаКолонокИзПервойСтроки = Ложь, Знач ТаблицаПриемник = Неопределено) Экспорт Если ТаблицаПриемник = Неопределено Тогда ТаблицаПриемник = Новый ТаблицаЗначений; КонецЕсли; КоличествоКолонок = 0; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(Текст); КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок(); Индикатор = ПолучитьИндикаторПроцессаЛкс(КоличествоСтрок, "Разбивка текста"); Для СчетчикСтроки = 1 По КоличествоСтрок Цикл ОбработатьИндикаторЛкс(Индикатор); СтрокаТекста = ТекстовыйДокумент.ПолучитьСтроку(СчетчикСтроки); Массив = СтрРазделитьЛкс(СтрокаТекста, Разделитель, ОбрезатьНепечатныеСимволы, Истина); Если КоличествоКолонок < Массив.Количество() Тогда Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда Для ИндексКолонки = КоличествоКолонок По Массив.Количество() - 1 Цикл Если ИменаКолонокИзПервойСтроки И СчетчикСтроки = 1 Тогда ИмяКолонки = мПлатформа.ИдентификаторИзПредставленияЛкс(Массив[ИндексКолонки]); Иначе ИмяКолонки = "Колонка" + XMLСтрока(ИндексКолонки); КонецЕсли; ТаблицаПриемник.Колонки.Добавить(ИмяКолонки); КонецЦикла; КонецЕсли; КоличествоКолонок = Массив.Количество(); //ИначеЕсли КоличествоКолонок > Массив.Количество() Тогда // СообщитьЛкс("В строке текст №" + XMLСтрока(СчетчикСтроки) + " указаны значения не для всех колонок"); КонецЕсли; Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда СтрокаТаблицы = ТаблицаПриемник.Добавить(); Для ИндексКолонки = 0 По Массив.ВГраница() Цикл СтрокаТаблицы[ИндексКолонки] = Массив[ИндексКолонки]; КонецЦикла; Иначе //Если ТипЗнч(ТаблицаПриемник) = Тип("ТабличныйДокумент") Тогда #Если Сервер И Не Сервер Тогда ТаблицаПриемник = Новый ТабличныйДокумент; #КонецЕсли АдресЯчейки = "R" + Формат(СчетчикСтроки, "ЧГ=") + "C"; Для ИндексКолонки = 0 По Массив.ВГраница() Цикл ТаблицаПриемник.Область(АдресЯчейки + Формат(ИндексКолонки + 1, "ЧГ=")).Текст = Массив[ИндексКолонки]; КонецЦикла; КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); Возврат ТаблицаПриемник; КонецФункции // СтрРазделитьЛкс() Функция ОбщийТипДанныхТабличногоПоляЛкс(Знач ТабличноеПоле, ПреобразоватьТипДанныхФормы = Ложь, выхСтруктураТипа = Неопределено) Экспорт мПлатформа = ирКэш.Получить(); ЗначениеТабличногоПоля = ДанныеЭлементаФормыЛкс(ТабличноеПоле); Если ПреобразоватьТипДанныхФормы Тогда ТипЗначенияТабличногоПоля = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ТабличноеПоле).Типы()[0]; Иначе ТипЗначенияТабличногоПоля = ТипЗнч(ЗначениеТабличногоПоля); КонецЕсли; Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда ТипИсточника = "ТаблицаЗначений"; ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда ТипИсточника = "ДеревоЗначений"; ИначеЕсли ЛиДанныеФормыСВозможностьюПоискаЛкс(ТипЗначенияТабличногоПоля) Тогда ТипИсточника = "ТаблицаЗначений"; ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДанныеФормыДерево") Тогда ТипИсточника = "ДеревоЗначений"; Иначе мПлатформа.ИнициализацияОписанияМетодовИСвойств(); выхСтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля); Если Ложь Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВидыСубконто") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "БазовыеВидыРасчета") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВедущиеВидыРасчета") > 0 Или Найти(выхСтруктураТипа.ИмяОбщегоТипа, "ВытесняющиеВидыРасчета") > 0 Тогда ТипИсточника = "ТабличнаяЧасть"; ИначеЕсли Найти(выхСтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда ТипИсточника = "НаборЗаписей"; ИначеЕсли Найти(выхСтруктураТипа.ИмяОбщегоТипа, "Список.") > 0 Тогда ТипИсточника = "Список"; ИначеЕсли выхСтруктураТипа.ИмяОбщегоТипа = "ДинамическийСписок" Тогда //ТипИсточника = "ДинамическийСписок"; ТипИсточника = "Список"; КонецЕсли; КонецЕсли; Возврат ТипИсточника; КонецФункции // ИнтерактивноУстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗ() Функция ЛиДанныеФормыСВозможностьюПоискаЛкс(Знач ДанныеИлиТипТаблицы) Экспорт Если ТипЗнч(ДанныеИлиТипТаблицы) <> Тип("Тип") Тогда Тип = ТипЗнч(ДанныеИлиТипТаблицы); Иначе Тип = ДанныеИлиТипТаблицы; КонецЕсли; Возврат Ложь Или Тип = Тип("ДанныеФормыКоллекция") Или Тип = Тип("ДанныеФормыСтруктураСКоллекцией"); КонецФункции // Параметры: // ЭтаФорма - Форма // ТабличноеПоле - ТабличноеПоле // КлючевоеПоле - Строка // ЗначениеКлюча - // СообщатьОбУспехе - Булево // Функция УстановитьТекущуюСтрокуСКонтролемУспешностиЛкс(Знач ЭтаФорма, Знач ТабличноеПоле, Знач КлючевоеПоле = "Ссылка", Знач ЗначениеКлюча = Неопределено, Знач СообщатьОбУспехе = Ложь, АктивизироватьТабличноеПолеПриУспехе = Ложь) Экспорт ТипИсточника = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ТабличноеПоле); Если Ложь Или ТипИсточника = "ТаблицаЗначений" Или ТипИсточника = "ТабличнаяЧасть" Или ТипИсточника = "НаборЗаписей" Тогда ДанныеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле); #Если Сервер И Не Сервер Тогда ДанныеТабличногоПоля = Новый ТаблицаЗначений; #КонецЕсли Если КлючевоеПоле <> Неопределено Тогда НайденныеСтроки = ДанныеТабличногоПоля.НайтиСтроки(Новый Структура(КлючевоеПоле, ЗначениеКлюча)); Иначе НайденныеСтроки = ДанныеТабличногоПоля; КонецЕсли; Если НайденныеСтроки.Количество() > 0 Тогда НайденнаяСтрока = НайденныеСтроки[0]; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда НайденнаяСтрока = НайденнаяСтрока.ПолучитьИдентификатор(); КонецЕсли; КонецЕсли; ЭтоКлиентскийИсточникДанных = Истина; ИначеЕсли ТипИсточника = "ДеревоЗначений" Тогда НайденнаяСтрока = ТабличноеПоле.Значение.Строки.Найти(ЗначениеКлюча, КлючевоеПоле, Истина); ЭтоКлиентскийИсточникДанных = Истина; Иначе ДанныеТабличногоПоля = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле); НайденнаяСтрока = ЗначениеКлюча; Отбор = ДанныеТабличногоПоля.Отбор; ЭтоКлиентскийИсточникДанных = Ложь; МетаданныеИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ДанныеТабличногоПоля)); Если МетаданныеИсточника = Неопределено Тогда ИмяТаблицыБД = ЭтаФорма.фОбъект.ПолноеИмяТаблицы; // Для управляемых форма реализована поддержка только формы "Динамический список" Иначе ИмяТаблицыБД = МетаданныеИсточника.ПолноеИмя(); КонецЕсли; ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ " + ИмяТаблицыБД; ПостроительЗапроса.ЗаполнитьНастройки(); СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ИмяТаблицыБД,,, Ложь); ЗаполнитьЗначенияСвойств(СтруктураКлюча, ЗначениеКлюча); УстановитьОтборПоСтруктуреЛкс(ПостроительЗапроса.Отбор, СтруктураКлюча); СтрокаЕстьВИсточникеДанных = Не ПостроительЗапроса.Результат.Пустой(); КонецЕсли; Если ЭтоКлиентскийИсточникДанных Тогда СтрокаЕстьВИсточникеДанных = НайденнаяСтрока <> Неопределено; КонецЕсли; Если СтрокаЕстьВИсточникеДанных Тогда ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока; Иначе СообщитьЛкс("Строка не найдена в источнике данных"); КонецЕсли; Если ТабличноеПоле.ТекущаяСтрока = НайденнаяСтрока Тогда Если АктивизироватьТабличноеПолеПриУспехе Тогда ЭтаФорма.ТекущийЭлемент = ТабличноеПоле; КонецЕсли; Результат = Истина; Иначе Если СтрокаЕстьВИсточникеДанных Тогда ТекстСообщения = "Строка найдена в источнике данных, но не найдена в табличном поле"; Если Отбор <> Неопределено Тогда ТекстСообщения = ТекстСообщения + " с учетом отбора " + Отбор; КонецЕсли; СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание); КонецЕсли; Результат = Ложь; КонецЕсли; Возврат Результат; КонецФункции // Параметры // МетаданныеКолонок - КоллекцияОбъектовМетаданных, ТаблицаЗначений - для таблицы значений используются колонки Имя и Метаданные Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияТиповКолонок = Неопределено, МетаданныеКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено, ТолькоПросмотр = Ложь) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда Если ОписанияТиповКолонок = Неопределено Тогда ОписанияТиповКолонок = ирСервер.ПолучитьТаблицуДочернихРеквизитовЛкс(ТабличноеПоле); КонецЕсли; Иначе Если ОписанияТиповКолонок = Неопределено Тогда ОписанияТиповКолонок = ТабличноеПоле.Значение.Колонки; КонецЕсли; КонецЕсли; Для Каждого КолонкаТаблицы Из ОписанияТиповКолонок Цикл Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда КолонкаТабличногоПоля = ТабличноеПоле.ПодчиненныеЭлементы.Найти(ТабличноеПоле.Имя + КолонкаТаблицы.Имя); Иначе КолонкаТабличногоПоля = ТабличноеПоле.Колонки.Найти(КолонкаТаблицы.Имя); КонецЕсли; Если КолонкаТабличногоПоля = Неопределено Тогда Продолжить; КонецЕсли; Если КолонкаТабличногоПоля.Видимость Тогда Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда Если ТабличноеПоле.ТекущийЭлемент = Неопределено Тогда ТабличноеПоле.ТекущийЭлемент = КолонкаТабличногоПоля; КонецЕсли; Иначе Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда ТабличноеПоле.ТекущаяКолонка = КолонкаТабличногоПоля; КонецЕсли; КонецЕсли; КонецЕсли; Если ТолькоПросмотр Тогда КолонкаТабличногоПоля.ТолькоПросмотр = Истина; КонецЕсли; Если Ложь #Если Клиент Тогда Или ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") #КонецЕсли Тогда ТипыРеквизита = КолонкаТаблицы.ТипЗначения.Типы(); Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда //КолонкаТабличногоПоля.Данные = ""; //КолонкаТабличногоПоля.ДанныеФлажка = КолонкаТаблицы.Имя; //КолонкаТабличногоПоля.РежимРедактирования = РежимРедактированияКолонки.Непосредственно; КолонкаТабличногоПоля.Ширина = 3; Иначе Если КолонкаТаблицы.Ширина > 0 Тогда КолонкаТабличногоПоля.Ширина = Мин(КолонкаТаблицы.Ширина, 50); // Почему то в редакторе таблицы значений не работала автоширина (-1) КонецЕсли; Если КолонкаТабличногоПоля.Ширина = 0 Тогда КолонкаТабличногоПоля.Ширина = 3; // Для 8.2 необходимо, иначе колонки будут не видны КонецЕсли; КонецЕсли; Если МетаданныеКолонок <> Неопределено Тогда Если ТипЗнч(МетаданныеКолонок) = Тип("КоллекцияОбъектовМетаданных") Тогда Метареквизит = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя); Иначе СтрокаПоля = МетаданныеКолонок.Найти(КолонкаТаблицы.Имя, "Имя"); Если СтрокаПоля <> Неопределено Тогда Метареквизит = СтрокаПоля.Метаданные; Иначе Метареквизит = Неопределено; КонецЕсли; КонецЕсли; Если Метареквизит <> Неопределено Тогда Попытка Подсказка = Метареквизит.Подсказка; Исключение // У графы журнала нет подсказки Подсказка = Неопределено; КонецПопытки; Если Подсказка <> Неопределено Тогда КолонкаТабличногоПоля.ПодсказкаВШапке = Подсказка; Если Метареквизит.МногострочныйРежим Тогда КолонкаТабличногоПоля.ЭлементУправления.МногострочныйРежим = Метареквизит.МногострочныйРежим; КолонкаТабличногоПоля.ЭлементУправления.РасширенноеРедактирование = Метареквизит.РасширенноеРедактирование; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ДоступныеПоляВыбора <> Неопределено Тогда ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя)); Если ДоступноеПоле <> Неопределено Тогда ТекстШапки = ДоступноеПоле.Заголовок; Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда КолонкаТабличногоПоля.Заголовок = ТекстШапки; Иначе КолонкаТабличногоПоля.ТекстШапки = ТекстШапки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры Функция ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс() Экспорт МассивСостояний = Новый Массив; МассивСостояний.Добавить("Не отображать"); МассивСостояний.Добавить("Отображать пустые"); МассивСостояний.Добавить("Отображать пустые и идентификаторы"); Возврат МассивСостояний; КонецФункции Функция КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле = Неопределено) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда КлючУникальности = ЭтаФорма.мКлючУникальности; Иначе КлючУникальности = ЭтаФорма.КлючУникальности; КонецЕсли; Результат = ИмяФормыИзФормыЛкс(ЭтаФорма) + "."; Если Не ЭтаФорма.РежимВыбора Тогда Если ТабличноеПоле <> Неопределено Тогда Результат = Результат + ТабличноеПоле.Имя + "."; Иначе ирОбщий.СообщитьЛкс("При формировании ключа списка последних выбранных значений нужно указывать табличное поле"); КонецЕсли; КонецЕсли; Результат = Результат + Лев(КлючУникальности, 50) + ".ПоследниеВыбранные"; Возврат Результат; КонецФункции // Параметры: // ЭтаФорма - Форма // КнопкаПодменю - Кнопка - подменю, в которое будут добавлены кнопки // Процедура ПоследниеВыбранныеЗаполнитьПодменюЛкс(Знач ЭтаФорма, КнопкаПодменю, Знач ТабличноеПоле = Неопределено, Знач ОбработчикКнопки = Неопределено) Экспорт КлючЗначения = КлючСохраненияСпискаПоследнихВыбранныхЗначенийФормыЛкс(ЭтаФорма, ТабличноеПоле); ПоследниеВыбранные = ВосстановитьЗначениеЛкс(КлючЗначения); Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда ОчиститьПодчиненныеЭлементыФормыЛкс(КнопкаПодменю, 0); Иначе КнопкаПодменю.Кнопки.Очистить(); КонецЕсли; Если ТипЗнч(ПоследниеВыбранные) <> Тип("СписокЗначений") Тогда Возврат; КонецЕсли; ЗапоминатьПоследниеВыбранные = КоличествоЗапоминаемыхПоследнихВыбранныхЛкс(); Для Счетчик = ЗапоминатьПоследниеВыбранные По ПоследниеВыбранные.Количество() - 1 Цикл ПоследниеВыбранные.Удалить(ЗапоминатьПоследниеВыбранные); КонецЦикла; ПодсказкаКнопки = "Активировать выбранный элемент в списке"; Для каждого ЭлементСписка Из ПоследниеВыбранные Цикл ИмяКнопки = НачалоИмениКнопкиПодменюПоследнихВыбранных() + ПоследниеВыбранные.Индекс(ЭлементСписка); Если ТипЗнч(КнопкаПодменю) = Тип("ГруппаФормы") Тогда Кнопка = ЭтаФорма.Элементы.Добавить(КнопкаПодменю.Имя + ИмяКнопки, Тип("КнопкаФормы"), КнопкаПодменю); //Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто; Кнопка.Заголовок = ЭлементСписка.Представление; Попытка Кнопка.ИмяКоманды = ИмяКнопки; Исключение Прервать; КонецПопытки; Иначе #Если Клиент Тогда Кнопка = КнопкаПодменю.Кнопки.Добавить(); Кнопка.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; Кнопка.Имя = ИмяКнопки; //Кнопка.Отображение = ОтображениеКнопкиКоманднойПанели.Авто; Кнопка.Текст = ЭлементСписка.Представление; Кнопка.Подсказка = ПодсказкаКнопки; Кнопка.Пояснение = Кнопка.Подсказка; Если ОбработчикКнопки = Неопределено Тогда ОбработчикКнопки = Новый Действие("ПоследниеВыбранныеНажатие"); КонецЕсли; Попытка Кнопка.Действие = ОбработчикКнопки; Исключение Прервать; КонецПопытки; #КонецЕсли КонецЕсли; КонецЦикла; КонецПроцедуры Функция КоличествоЗапоминаемыхПоследнихВыбранныхЛкс() Возврат 10; КонецФункции Функция НачалоИмениКнопкиПодменюПоследнихВыбранных() Возврат "ПоследниеВыбранные"; КонецФункции Функция ПолучитьИспользованиеДинамическогоСпискаВместоОсновнойФормыЛкс(ПолноеИмяМД) Экспорт Возврат ирОбщий.ВосстановитьЗначениеЛкс("ирДинамическийСписок.ВместоОсновной." + ПолноеИмяМД) <> Ложь; КонецФункции // УстановитьОбъектМетаданных() Процедура ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(ПолеВвода, Знач КлючИстории, Знач ЗапоминатьПоследние = 20, Знач НеЗапоминатьПустыеТипизированные = Истина, ДополнительныйКлючИстории = "") Экспорт ЗначениеПоля = ДанныеЭлементаФормыЛкс(ПолеВвода); Если Ложь Или (Истина И Не НеЗапоминатьПустыеТипизированные И ЗначениеПоля <> ПолеВвода.ТипЗначения.ПривестиЗначение(Неопределено)) Или ЗначениеЗаполнено(ЗначениеПоля) Тогда НовоеЗначениеXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ЗначениеПоля); Если СтрДлина(НовоеЗначениеXML) > 1000 Тогда Возврат; КонецЕсли; Если ТипЗнч(КлючИстории) <> Тип("Строка") Тогда КлючИстории = ИмяФормыИзФормыЛкс(КлючИстории); КонецЕсли; КлючИстории = КлючИстории + ДополнительныйКлючИстории; КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения"; ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючНастройки); Если ТипЗнч(ПоследниеЗначения) <> Тип("Массив") Тогда ПоследниеЗначения = Новый Массив; КонецЕсли; ПоследниеЗначенияXML = Новый Массив; Для Каждого Значение Из ПоследниеЗначения Цикл ПоследниеЗначенияXML.Добавить(СохранитьОбъектВВидеСтрокиXMLЛкс(Значение)); КонецЦикла; Индекс = ПоследниеЗначенияXML.Найти(НовоеЗначениеXML); Если Индекс <> Неопределено Тогда ПоследниеЗначения.Удалить(Индекс); КонецЕсли; ПоследниеЗначения.Вставить(0, ЗначениеПоля); Для Счетчик = ЗапоминатьПоследние По ПоследниеЗначения.ВГраница() Цикл ПоследниеЗначения.Удалить(ЗапоминатьПоследние); КонецЦикла; СохранитьЗначениеЛкс(КлючНастройки, ПоследниеЗначения); ПолеВвода.СписокВыбора.Очистить(); Для Каждого Значение Из ПоследниеЗначения Цикл НовыйЭлемент = ПолеВвода.СписокВыбора.Добавить(Значение); КонецЦикла; КонецЕсли; КонецПроцедуры Процедура ПолеВводаСИсториейВыбора_НачалоВыбораИзСпискаЛкс(ПолеВвода, Знач КлючИстории, ДополнительныйКлючИстории = "") Экспорт // Запоминать последние Если ТипЗнч(КлючИстории) <> Тип("Строка") Тогда КлючИстории = ИмяФормыИзФормыЛкс(КлючИстории); КонецЕсли; КлючИстории = КлючИстории + ДополнительныйКлючИстории; КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения"; ПоследниеЗначения = ВосстановитьЗначениеЛкс(КлючНастройки); Если ТипЗнч(ПоследниеЗначения) = Тип("Массив") Тогда ПолеВвода.СписокВыбора.Очистить(); Для Каждого Значение Из ПоследниеЗначения Цикл ПолеВвода.СписокВыбора.Добавить(Значение); КонецЦикла; КонецЕсли; КонецПроцедуры Функция ПолучитьИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки) Экспорт Попытка ТипЗначения = ДанныеСтроки.ТипЗначения; Исключение ТипЗначения = Неопределено; КонецПопытки; ИндексКартинки = -1; Если Ложь Или ДанныеСтроки.ТипСлова = "Ключевое слово" Или ДанныеСтроки.ТипСлова = "Конструкция" Тогда ИндексКартинки = 13; ИначеЕсли ТипЗначения = "Имя типа" Тогда ИндексКартинки = 12; ИначеЕсли ДанныеСтроки.ТипСлова = "Метод" Тогда Попытка Пустышка = ДанныеСтроки.Успех; ЕстьУспех = Истина; Исключение ЕстьУспех = Ложь; КонецПопытки; Если Ложь Или (Истина И ЕстьУспех И (Ложь Или ДанныеСтроки.ТаблицаСтруктурТипов = Неопределено Или ДанныеСтроки.ТаблицаСтруктурТипов.Количество() = 0 Или ДанныеСтроки.ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = "")) Или (Истина И Не ЕстьУспех И ДанныеСтроки.ТипЗначения = "") Тогда Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 0; ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда ИндексКартинки = 6; //ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда // ИндексКартинки = 9; Иначе ИндексКартинки = 3; КонецЕсли; Иначе Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 1; ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда ИндексКартинки = 7; //ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда // ИндексКартинки = 10; Иначе ИндексКартинки = 4; КонецЕсли; КонецЕсли; ИначеЕсли ДанныеСтроки.ТипСлова = "Свойство" Тогда Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 2; ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда ИндексКартинки = 8; //ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда // ИндексКартинки = 11; Иначе ИндексКартинки = 5; КонецЕсли; ИначеЕсли ДанныеСтроки.ТипСлова = "Таблица" Тогда ИндексКартинки = 14; ИначеЕсли ДанныеСтроки.ТипСлова = "Поле" Тогда Если ДанныеСтроки.Определение = "Предопределенный" Тогда ИндексКартинки = 15; Иначе ИндексКартинки = 16; КонецЕсли; ИначеЕсли ДанныеСтроки.ТипСлова = "Группа" Тогда ИндексКартинки = 18; КонецЕсли; Возврат ИндексКартинки; КонецФункции Функция ПолучитьИдентификаторСсылкиЛкс(Ссылка, ВместеСТипом = Ложь) Экспорт ИдентификаторСсылки = Неопределено; XMLТип = XMLТипЗнч(Ссылка); Если XMLТип <> Неопределено Тогда Если Найти(XMLТип.ИмяТипа, "Ref.") > 0 Тогда Если Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Тогда ИдентификаторСсылки = "{" + ирОбщий.СтрокаМеждуМаркерамиЛкс(ЗначениеВСтрокуВнутр(Ссылка), "," + Символы.ПС + "{", "}" + Символы.ПС + "}") + "}"; ИдентификаторСсылки = СтрЗаменить(ИдентификаторСсылки, Символы.ПС, ""); Иначе ИдентификаторСсылки = XMLСтрока(Ссылка); КонецЕсли; ИначеЕсли XMLТип.ИмяТипа = "Type" Тогда XMLТипТипа = XMLТип(Ссылка); Если XMLТипТипа <> Неопределено Тогда ИдентификаторСсылки = XMLТипТипа.ИмяТипа; КонецЕсли; КонецЕсли; КонецЕсли; Если ВместеСТипом И ИдентификаторСсылки <> Неопределено Тогда ИдентификаторСсылки = ИдентификаторСсылки + "." + XMLТип.ИмяТипа; КонецЕсли; Возврат ИдентификаторСсылки; КонецФункции Функция ИменаИспользуемыхВЗапросеВременныхТаблицЛкс(Знач ЗапросИлиМенеджерВременныхТаблиц, Знач ОбязательныеДляПроверкиИмена = """") Экспорт Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли МассивИмен = СтрРазделитьЛкс(ОбязательныеДляПроверкиИмена, ",", Истина, Ложь); Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст); Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы); КонецЦикла; ИначеЕсли ирКэш.НомерВерсииПлатформыЛкс() >= 803008 Тогда #Если Сервер И Не Сервер Тогда Пустышка = Новый Запрос; ЗапросИлиМенеджерВременныхТаблиц = Пустышка.МенеджерВременныхТаблиц; #КонецЕсли Для Каждого ТаблицаМенеджера Из ЗапросИлиМенеджерВременныхТаблиц.Таблицы Цикл МассивИмен.Добавить(ТаблицаМенеджера.ПолноеИмя); КонецЦикла; ИначеЕсли Не ЗначениеЗаполнено(ОбязательныеДляПроверкиИмена) Тогда ВызватьИсключение "Необходимо указать имена временных таблиц"; КонецЕсли; Возврат МассивИмен; КонецФункции // ПолВТ() Процедура СкопироватьДеревоЛкс(ИсходноеДерево, НовоеДерево, ОчиститьПередЗагрузкой = Истина, ЗначенияПоУмолчанию = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ЗначенияПоУмолчанию = Новый Структура; #КонецЕсли Если ОчиститьПередЗагрузкой Тогда НовоеДерево.Строки.Очистить(); КонецЕсли; Если ИсходноеДерево.Строки.Количество() = 0 Тогда Возврат; КонецЕсли; Если ЗначенияПоУмолчанию <> Неопределено Тогда ИменаСвойствПоУмолчанию = ИменаСвойствСтруктурыЛкс(ЗначенияПоУмолчанию); КонецЕсли; Для каждого СтрокаДерева из ИсходноеДерево.Строки Цикл НоваяСтрока = НовоеДерево.Строки.Добавить(); Если ЗначенияПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(НоваяСтрока, ЗначенияПоУмолчанию, ИменаСвойствПоУмолчанию); КонецЕсли; ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаДерева); СкопироватьДеревоЛкс(СтрокаДерева, НоваяСтрока, ОчиститьПередЗагрузкой = Истина); КонецЦикла; КонецПроцедуры Функция СоздатьСамоудаляющийсяКомандныйФайлЛкс(Знач ТекстКомандногоФайла = "", Знач КраткоеИмяФайла = "") Экспорт Если ЗначениеЗаполнено(КраткоеИмяФайла) Тогда ПолноеИмяФайла = КаталогВременныхФайлов() + КраткоеИмяФайла + ".bat"; Иначе ПолноеИмяФайла = ПолучитьИмяВременногоФайла("bat"); КонецЕсли; ТекстКомандногоФайла = ТекстКомандногоФайла + " |del """ + ПолноеИмяФайла + """ |"; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстКомандногоФайла); ТекстовыйДокумент.Записать(ПолноеИмяФайла, КодировкаТекста.OEM); Результат = ПолноеИмяФайла; Возврат Результат; КонецФункции // Проверить уникальность строк ТЧ по колонке // // Параметры: // Объект - <тип> - // ИмяТаблицы - <тип> - // ИмяКолонки - <тип>, "" - // // Возвращаемое значение: // Функция ПроверитьУникальностьСтрокТЧПоКолонкеЛкс(Объект, ИмяТаблицы, ИмяКолонки = "", ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина, ОтборСтрок = Неопределено, МассивИсключений = Неопределено) Экспорт Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда ИмяКолонки = Объект.Метаданные().ТабличныеЧасти[ИмяТаблицы].Реквизиты[0].Имя; КонецЕсли; Если Истина И МассивИсключений <> Неопределено И ИгнорироватьРегистрДляПростогоСтрокогоТипа Тогда НовыйМассивИсключений = Новый Массив; Для Каждого ИсключаемоеЗначение Из МассивИсключений Цикл Если ТипЗнч(ИсключаемоеЗначение) = Тип("Строка") Тогда ИсключаемоеЗначение = НРег(ИсключаемоеЗначение); КонецЕсли; НовыйМассивИсключений.Добавить(ИсключаемоеЗначение); КонецЦикла; МассивИсключений = НовыйМассивИсключений; КонецЕсли; Успех = Истина; НеуникальныеЗначения = НеуникальныеЗначенияКолонкиТаблицыЛкс(Объект[ИмяТаблицы], ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа, ОтборСтрок); Для Каждого НеуникальноеЗначение Из НеуникальныеЗначения Цикл Если Истина И МассивИсключений <> Неопределено И МассивИсключений.Найти(НеуникальноеЗначение) <> Неопределено Тогда Продолжить; КонецЕсли; СообщитьЛкс("Значение """ + НеуникальноеЗначение + """ встречается более одного раза среди активных строк в колонке """ + ИмяКолонки + """ таблицы """ + ИмяТаблицы + """", СтатусСообщения.Внимание); Успех = Ложь; КонецЦикла; Возврат Успех; КонецФункции Функция ПолучитьПроцессОСЛкс(Знач ИдентификаторПроцесса = Неопределено, Знач НачалоПроцесса = Неопределено, Знач Компьютер = Неопределено, ВызватьИсключениеПриОшибкеПодключенияWMI = Истина, ДопустимоеОтклонениеВремени = 2, МаркерВКоманднойСтроке = Неопределено, ИмяИсполняемогоФайла = Неопределено) Экспорт Если СтрокиРавныЛкс(ИдентификаторПроцесса, "текущий") Тогда ИдентификаторПроцесса = ирКэш.Получить().ПолучитьИдентификаторПроцессаОС(); КонецЕсли; Попытка WMIЛокатор = ирКэш.ПолучитьCOMОбъектWMIЛкс(Компьютер); Исключение Если ВызватьИсключениеПриОшибкеПодключенияWMI Тогда ВызватьИсключение; КонецЕсли; ОписаниеОшибки = ОписаниеОшибки(); СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Внимание); WMIЛокатор = Неопределено; КонецПопытки; Если WMIЛокатор = Неопределено Тогда Возврат Неопределено; КонецЕсли; // ТекстОтбора = "1=1 AND"; Синтаксис WQL такого не допускает ТекстОтбора = ""; Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " ProcessID = " + XMLСтрока(ИдентификаторПроцесса); КонецЕсли; Если ЗначениеЗаполнено(МаркерВКоманднойСтроке) Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " CommandLine LIKE '%" + МаркерВКоманднойСтроке + "%'"; КонецЕсли; Если ЗначениеЗаполнено(ИмяИсполняемогоФайла) Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " Name = '" + ИмяИсполняемогоФайла + "'"; КонецЕсли; Если НачалоПроцесса <> Неопределено Тогда Если ТекстОтбора <> "" Тогда ТекстОтбора = ТекстОтбора + "AND "; КонецЕсли; ТекстОтбора = ТекстОтбора + " CreationDate >= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса - ДопустимоеОтклонениеВремени); ТекстОтбора = ТекстОтбора + " AND CreationDate <= " + ПолучитьЛитералДатыДляWQLЛкс(НачалоПроцесса + 1 + ДопустимоеОтклонениеВремени); КонецЕсли; Результат = "Процесс ОС с отбором (" + ТекстОтбора + ") не найден"; ТекстЗапросаWQL = "Select * from Win32_Process Where " + ТекстОтбора; ВыборкаПроцессовОС = WMIЛокатор.ExecQuery(ТекстЗапросаWQL); Для Каждого ПроцессОС Из ВыборкаПроцессовОС Цикл Результат = ПроцессОС; Прервать; КонецЦикла; Возврат Результат; КонецФункции Функция ПолучитьЛитералДатыДля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С" // русские буквы И ПубликаторПродукта <> "1C-Soft" // латинские буквы И ПубликаторПродукта <> "1С-Софт" // русские буквы Тогда Продолжить; КонецЕсли; //НаименованиеПродукта = Инсталлер.ProductInfo(Продукт, "ProductName"); КаталогВерсии = Инсталлер.ProductInfo(Продукт, "InstallLocation"); //СтрокаРелиза = Инсталлер.ProductInfo(Продукт, "VersionString"); Иначе КаталогВерсии = Продукт.InstallLocation; КонецЕсли; СтрокаТаблицыСборок = СборкиПлатформы.Добавить(); СтрокаТаблицыСборок.Каталог = КаталогВерсии; ФайлПолученияВерсии = Неопределено; Если ТипыComКлассов <> Неопределено Тогда Для Каждого ТипКласса Из ТипыComКлассов Цикл //Если Метаданные().ТабличныеЧасти.СборкиПлатформы.Реквизиты.Найти(ВыборкаКлассов.Имя) = Неопределено Тогда // Продолжить; //КонецЕсли; ФайлКомпоненты = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\" + ТипКласса.КлючевойФайл, Компьютер); СтрокаТаблицыСборок[ТипКласса.Имя] = ФайлКомпоненты <> Неопределено; Если СтрокаТаблицыСборок[ТипКласса.Имя] Тогда ФайлПолученияВерсии = ФайлКомпоненты; КонецЕсли; КонецЦикла; КонецЕсли; ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\ragent.exe", Компьютер); СтрокаТаблицыСборок.АгентСервера = ИсполняемыйФайл <> Неопределено; Если СтрокаТаблицыСборок.АгентСервера Тогда ФайлПолученияВерсии = ИсполняемыйФайл; КонецЕсли; ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\ras.exe", Компьютер); СтрокаТаблицыСборок.СерверАдминистрирования = ИсполняемыйФайл <> Неопределено; Если СтрокаТаблицыСборок.СерверАдминистрирования Тогда ФайлПолученияВерсии = ИсполняемыйФайл; КонецЕсли; ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\dbgs.exe", Компьютер); СтрокаТаблицыСборок.СерверОтладки = ИсполняемыйФайл <> Неопределено; Если СтрокаТаблицыСборок.СерверОтладки Тогда ФайлПолученияВерсии = ИсполняемыйФайл; КонецЕсли; ИсполняемыйФайл = ПолучитьФайлWMIЛкс(СтрокаТаблицыСборок.Каталог + "bin\crserver.exe", Компьютер); СтрокаТаблицыСборок.СерверХранилища = ИсполняемыйФайл <> Неопределено; Если СтрокаТаблицыСборок.СерверХранилища Тогда ФайлПолученияВерсии = ИсполняемыйФайл; КонецЕсли; Если ФайлПолученияВерсии <> Неопределено Тогда СтрокаТаблицыСборок.ФайлыСуществуют = Истина; СтрокаТаблицыСборок.x64 = ирКэш.Это64битнаяОСЛкс() И Найти(СтрокаТаблицыСборок.Каталог, "(x86)") = 0; СтрокаТаблицыСборок.СборкаПлатформы = ФайлПолученияВерсии.Version; СтрокаТаблицыСборок.КлючСборки = КлючСборкиПлатформыЛкс(СтрокаТаблицыСборок); СтрокаВерсии = ФайлПолученияВерсии.Version; Если ЗначениеЗаполнено(СтрокаВерсии) Тогда СтрокаТаблицыСборок.СборкаПлатформы = СтрокаВерсии; Фрагменты = СтрРазделитьЛкс(СтрокаВерсии); ИзданиеПлатформы = Фрагменты[0] + "." + Фрагменты[1]; СтрокаТаблицыСборок.ИзданиеПлатформы = ИзданиеПлатформы; СтрокаТаблицыСборок.Порядок = Фрагменты[0] * 10000000 + Фрагменты[1] * 1000000 + Фрагменты[2] * 10000 + Фрагменты[3]; КонецЕсли; КонецЕсли; СтрокаТаблицыСборок.НКаталог = НРег(СтрокаТаблицыСборок.Каталог); КонецЦикла; СборкиПлатформы.Сортировать("Порядок Убыв, ФайлыСуществуют Убыв, СборкаПлатформы Убыв, x64"); КонецПроцедуры Функция КлючСборкиПлатформыЛкс(Знач СтрокаТаблицыСборок) Экспорт Возврат СтрокаТаблицыСборок.СборкаПлатформы + " - " + ?(СтрокаТаблицыСборок.x64, "64", "32"); КонецФункции Функция ЗаменитьСлешиНаДвойныеЛкс(Строка) Экспорт Результат = СтрЗаменить(Строка, "\", "\\"); Возврат Результат; КонецФункции Функция ПолучитьТекстРезультатаКомандыОСЛкс(Знач СтрокаКоманды = "", ОжидатьЗавершения = Истина, Знач ИмяКомпьютера = "", Элевация = Ложь) Экспорт Платформа = ирКэш.Получить(); Если Ложь Тогда Платформа = Обработки.ирПлатформа.Создать(); КонецЕсли; ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла("txt")); Платформа.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаКоманды, ФайлРезультата.Путь,, ФайлРезультата.Имя, ОжидатьЗавершения, Элевация); Если ОжидатьЗавершения Тогда Если ФайлРезультата.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, КодировкаТекста.OEM); УдалитьФайлы(ФайлРезультата.ПолноеИмя); Результат = ТекстовыйДокумент.ПолучитьТекст(); Иначе Результат = Неопределено; КонецЕсли; Иначе Результат = ФайлРезультата.ПолноеИмя; КонецЕсли; Возврат Результат; КонецФункции Процедура ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, НичегоНеДелатьБезТранзакции = Ложь, НовыйРежимБлокировкиДанных = Неопределено) Экспорт Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(НаборЗаписей)); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); КорневойТип = ПервыйФрагментЛкс(ПространствоБлокировок); Если ирОбщий.ТипТаблицыБДЛкс(ПространствоБлокировок) = "Перерасчет" Тогда Возврат; //ПространствоБлокировок = ОбъектМД.Родитель().ПолноеИмя(); КонецЕсли; Если Ложь Или Не ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей"; КонецЕсли; ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл Если ЭлементОтбора.Использование Тогда ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, ЭлементОтбора.Значение); КонецЕсли; КонецЦикла; Если НовыйРежимБлокировкиДанных = Неопределено Тогда НовыйРежимБлокировкиДанных = РежимБлокировкиДанных.Исключительный; КонецЕсли; ЭлементБлокировки.Режим = НовыйРежимБлокировкиДанных; Блокировка.Заблокировать(); КонецПроцедуры Процедура ЗаблокироватьРегистрПоМенеджеруЗаписиЛкс(МенеджерЗаписи, НичегоНеДелатьБезТранзакции = Ложь, Знач РежимБлокировки = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи(); #КонецЕсли Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(МенеджерЗаписи)); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); КорневойТип = ПервыйФрагментЛкс(ПространствоБлокировок); Если ирОбщий.ТипТаблицыБДЛкс(ПространствоБлокировок) = "Перерасчет" Тогда Возврат; //ПространствоБлокировок = ОбъектМД.Родитель().ПолноеИмя(); КонецЕсли; Если ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей"; КонецЕсли; НаборЗаписей = Новый (СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "НаборЗаписей.")); ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, МенеджерЗаписи[ЭлементОтбора.Имя]); КонецЦикла; Если РежимБлокировки <> Неопределено Тогда ЭлементБлокировки.Режим = РежимБлокировки; КонецЕсли; Блокировка.Заблокировать(); КонецПроцедуры Процедура ЗаблокироватьСсылкуВТранзакцииЛкс(СсылочныйОбъект, НичегоНеДелатьБезТранзакции = Ложь) Экспорт Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = СсылочныйОбъект.Метаданные(); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылочныйОбъект.Ссылка); Блокировка.Заблокировать(); КонецПроцедуры Процедура ЗаблокироватьКонстантуЛкс(КонстантаМенеджерЗначения, НичегоНеДелатьБезТранзакции = Ложь, Знач РежимБлокировки = Неопределено) Экспорт Если Ложь Или Метаданные.РежимУправленияБлокировкойДанных = Метаданные.СвойстваОбъектов.РежимУправленияБлокировкойДанныхПоУмолчанию.Автоматический Или (Истина И НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна()) Тогда Возврат; КонецЕсли; Блокировка = Новый БлокировкаДанных; ОбъектМД = Метаданные.НайтиПоТипу(ирОбщий.ТипОбъектаБДЛкс(КонстантаМенеджерЗначения)); ПространствоБлокировок = ОбъектМД.ПолноеИмя(); ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок); Если РежимБлокировки <> Неопределено Тогда ЭлементБлокировки.Режим = РежимБлокировки; КонецЕсли; Блокировка.Заблокировать(); КонецПроцедуры Функция ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиИменаБД = Ложь, ЭтоТабличнаяЧасть = Ложь, ИспользоватьИмяПоляВместоПустогоПредставления = Ложь) Экспорт ПредставлениеПоля = СтрокаПоля.ИмяПоля; Если ПустаяСтрока(ПредставлениеПоля) Тогда Если ЛиИменаБД Тогда // Антибаг платформы. У некоторых полей почему то пустое имя, а должно быть непустое. https://partners.v8.1c.ru/forum/topic/1275356#m_1275356 Если ЭтоТабличнаяЧасть Тогда Если ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_KeyField") Тогда ПредставлениеПоля = "НомерСтроки"; ИначеЕсли Найти(СтрокаПоля.ИмяПоляХранения, "IDRRef") > 0 Тогда ПредставлениеПоля = "Ссылка"; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(ПредставлениеПоля) Тогда Если ЛиИменаБД Тогда НИмяПоляХранения = НРег(СтрокаПоля.ИмяПоляХранения); НМаркерПоляТипаЗначения = НРег("TYPE"); НМаркерПоляТипаСсылки = НРег("TRef"); //МаркерПоляЗначенияСсылки = НРег("RRef"); Если Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаСсылки)) = НМаркерПоляТипаСсылки Тогда ПредставлениеПоля = ПредставлениеПоля + "_ТипСсылки"; ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаЗначения)) = НМаркерПоляТипаЗначения Тогда ПредставлениеПоля = ПредставлениеПоля + "_ТипЗначения"; //ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляЗначенияСсылки)) = НМаркерПоляЗначенияСсылки Тогда // ПредставлениеПоля = ПредставлениеПоля + "_Ссылка"; КонецЕсли; КонецЕсли; ИначеЕсли ИспользоватьИмяПоляВместоПустогоПредставления Тогда ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения; КонецЕсли; Возврат ПредставлениеПоля; КонецФункции Функция ПолучитьПредставлениеСтруктурыЛкс(Структура) Экспорт #Если Сервер И Не Сервер Тогда Структура = Новый Структура; #КонецЕсли ПредставлениеСтруктуры = ""; Для Каждого КлючИЗначение Из Структура Цикл Если ПредставлениеСтруктуры <> "" Тогда ПредставлениеСтруктуры = ПредставлениеСтруктуры + ", "; КонецЕсли; ПредставлениеСтруктуры = ПредставлениеСтруктуры + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение; КонецЦикла; Возврат ПредставлениеСтруктуры; КонецФункции Функция ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаСтруктурыБД, ЛиСтруктураДанныхВИменахБД = Ложь, СтрокаТаблицыХранения, ЛиПредставлениеВИменахБД = Ложь) Экспорт ЭтоТабличнаяЧасть = СтрокаТаблицыХранения.Назначение = "ТабличнаяЧасть"; ПредставлениеИндекса = ""; Разделитель = ""; Для каждого СтрокаПоля Из СтрокаИндексаСтруктурыБД.Поля Цикл Если ЛиПредставлениеВИменахБД Тогда ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения; Иначе ПредставлениеПоля = ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиСтруктураДанныхВИменахБД, ЭтоТабличнаяЧасть, Истина); КонецЕсли; ПредставлениеИндекса = ПредставлениеИндекса + Разделитель + ПредставлениеПоля; Разделитель = ", "; КонецЦикла; Возврат ПредставлениеИндекса; КонецФункции Процедура ОбработатьВыборкуСтруктурыХраненияБДЛкс(Знач Результат, ЛиИменаБД = Ложь, ВычислитьИменаИндексов = Истина) Экспорт #Если Сервер И Не Сервер Тогда Результат = Новый ТаблицаЗначений; #КонецЕсли Если Результат.Колонки.Найти("КраткоеИмяТаблицыХранения") <> Неопределено Тогда // Например это схема чужой БД Возврат; КонецЕсли; //Результат.Колонки.ИмяТаблицыХранения.Имя = "ИмяТаблицыХраненияСРегистромБукв"; Результат.Колонки.Добавить("КраткоеИмяТаблицыХранения", Новый ОписаниеТипов("Строка")); //Результат.Колонки.Добавить("ИмяТаблицыХранения", Новый ОписаниеТипов("Строка")); НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский; ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(Результат, НуженПеревод); Для Каждого СтрокаТаблицыХранения Из Результат Цикл // Антибаг платформы 8.2.16 У ряда назначений таблиц ИмяТаблицы пустое http://partners.v8.1c.ru/forum/thread.jsp?id=1090307#1090307 Если ПустаяСтрока(СтрокаТаблицыХранения.ИмяТаблицы) Тогда МетаПолноеИмяТаблицы = ""; Если ЗначениеЗаполнено(СтрокаТаблицыХранения.Метаданные) Тогда МетаПолноеИмяТаблицы = СтрокаТаблицыХранения.Метаданные; КонецЕсли; Если СтрокаТаблицыХранения.Назначение = "РегистрацияИзменений" Тогда СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + ".Изменения"; ИначеЕсли СтрокаТаблицыХранения.Назначение = "Основная" Тогда СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы; Иначе СтрокаТаблицыХранения.ИмяТаблицы = МетаПолноеИмяТаблицы + "." + СтрокаТаблицыХранения.Назначение; КонецЕсли; КонецЕсли; //СтрокаТаблицыХранения.ИмяТаблицыХранения = НРег(ирОбщий.ПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХраненияСРегистромБукв)); // В режим ЛиИменаБД=Ложь Document209.VT2672->VT2672 СтрокаТаблицыХранения.КраткоеИмяТаблицыХранения = НРег(ирОбщий.ПоследнийФрагментЛкс(СтрокаТаблицыХранения.ИмяТаблицыХранения)); Если ВычислитьИменаИндексов Тогда Индексы = СтрокаТаблицыХранения.Индексы; Индексы.Колонки.Добавить("ИмяИндекса", Новый ОписаниеТипов("Строка")); ПеревестиКолонкиСтруктурыХраненияБДИндексыЛкс(Индексы, НуженПеревод); Для Каждого СтрокаИндексаХранения Из Индексы Цикл ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(СтрокаИндексаХранения.Поля, НуженПеревод); ПредставлениеИндекса = ирОбщий.ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаХранения, ЛиИменаБД, СтрокаТаблицыХранения); СтрокаИндексаХранения.ИмяИндекса = "Индекс(" + ПредставлениеИндекса + ")"; КонецЦикла; КонецЕсли; КонецЦикла; Результат.Индексы.Добавить("КраткоеИмяТаблицыХранения"); КонецПроцедуры Процедура ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(Знач Поля, НуженПеревод = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Поля = Новый ТаблицаЗначений; #КонецЕсли Если НуженПеревод = Неопределено Тогда НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский; КонецЕсли; Если НуженПеревод Тогда Попытка Поля.Колонки[ПеревестиСтроку("ИмяПоляХранения")].Имя = "ИмяПоляХранения"; Поля.Колонки[ПеревестиСтроку("ИмяПоля")].Имя = "ИмяПоля"; Поля.Колонки[ПеревестиСтроку("Метаданные")].Имя = "Метаданные"; Исключение // Повторный перевод КонецПопытки; КонецЕсли; КонецПроцедуры Процедура ПеревестиКолонкиСтруктурыХраненияБДИндексыЛкс(Знач Индексы, НуженПеревод = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Индексы = Новый ТаблицаЗначений; #КонецЕсли Если НуженПеревод = Неопределено Тогда НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский; КонецЕсли; Если НуженПеревод Тогда Попытка Индексы.Колонки[ПеревестиСтроку("ИмяИндексаХранения")].Имя = "ИмяИндексаХранения"; Индексы.Колонки[ПеревестиСтроку("Поля")].Имя = "Поля"; Исключение // Повторный перевод КонецПопытки; КонецЕсли; КонецПроцедуры Процедура ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(Знач Результат, НуженПеревод = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Результат = Новый ТаблицаЗначений; #КонецЕсли Если НуженПеревод = Неопределено Тогда НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский; КонецЕсли; Если НуженПеревод Тогда Результат.Колонки[ПеревестиСтроку("ИмяТаблицы")].Имя = "ИмяТаблицы"; Результат.Колонки[ПеревестиСтроку("ИмяТаблицыХранения")].Имя = "ИмяТаблицыХранения"; Результат.Колонки[ПеревестиСтроку("Индексы")].Имя = "Индексы"; Результат.Колонки[ПеревестиСтроку("Метаданные")].Имя = "Метаданные"; Результат.Колонки[ПеревестиСтроку("Назначение")].Имя = "Назначение"; Результат.Колонки[ПеревестиСтроку("Поля")].Имя = "Поля"; КонецЕсли; КонецПроцедуры Процедура ПеревестиКолонкиНайтиПоСсылкамЛкс(Знач Таблица, НуженПеревод = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Таблица = Новый ТаблицаЗначений; #КонецЕсли Если НуженПеревод = Неопределено Тогда НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский; КонецЕсли; Если НуженПеревод Тогда Попытка Таблица.Колонки[ПеревестиСтроку("Ссылка")].Имя = "Ссылка"; Таблица.Колонки[ПеревестиСтроку("Данные")].Имя = "Данные"; Таблица.Колонки[ПеревестиСтроку("Метаданные")].Имя = "Метаданные"; Исключение // Повторный перевод КонецПопытки; КонецЕсли; КонецПроцедуры Процедура ПеревестиКолонкиВыгрузитьЖурналРегистрацииЛкс(Знач Таблица, НуженПеревод = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда Таблица = Новый ТаблицаЗначений; #КонецЕсли Если НуженПеревод = Неопределено Тогда НуженПеревод = Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Английский; КонецЕсли; Если НуженПеревод Тогда Для Каждого Колонка Из Таблица.Колонки Цикл Таблица.Колонки[Колонка.Имя].Имя = ПеревестиВРусский(Колонка.Имя); КонецЦикла; КонецЕсли; КонецПроцедуры Функция ПолучитьСтруктуруХраненияБДЛкс(Знач ОтборПоМетаданным = Неопределено, ЛиИменаБД = Ложь, ВычислитьИменаИндексов = Истина, АдресЧужойСхемыБД = "") Экспорт Если ОтборПоМетаданным = Неопределено Тогда #Если Клиент Тогда СостояниеЛкс("Получение структуры БД..."); #КонецЕсли ИначеЕсли ТипЗнч(ОтборПоМетаданным) <> Тип("Массив") Тогда Массив = Новый Массив; Массив.Добавить(ОтборПоМетаданным); ОтборПоМетаданным = Массив; КонецЕсли; Если ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда СтруктураСхемы = ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД); Если ЛиИменаБД Тогда ГлавнаяТаблица = СтруктураСхемы.СУБД; Иначе ГлавнаяТаблица = СтруктураСхемы.SDBL; КонецЕсли; Если ОтборПоМетаданным <> Неопределено Тогда Результат = ГлавнаяТаблица.СкопироватьКолонки(); Если ГлавнаяТаблица.Индексы.Количество() = 0 Тогда ГлавнаяТаблица.Индексы.Добавить("Метаданные"); КонецЕсли; Для Каждого ИмяМД Из ОтборПоМетаданным Цикл Для Каждого СтрокаТаблицы Из ГлавнаяТаблица.НайтиСтроки("Метаданные", ИмяМД) Цикл ЗаполнитьЗначенияСвойств(Результат.Добавить(), СтрокаТаблицы); КонецЦикла; КонецЦикла; Иначе Результат = ГлавнаяТаблица; КонецЕсли; Иначе Результат = ПолучитьСтруктуруХраненияБазыДанных(ОтборПоМетаданным, ЛиИменаБД); КонецЕсли; ОбработатьВыборкуСтруктурыХраненияБДЛкс(Результат, ЛиИменаБД, ВычислитьИменаИндексов); Если ОтборПоМетаданным = Неопределено Тогда #Если Клиент Тогда СостояниеЛкс(""); #КонецЕсли КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьЧужуюСхемуБДЛкс(АдресЧужойСхемыБД) Экспорт Если Не ЗначениеЗаполнено(АдресЧужойСхемыБД) Тогда Возврат Неопределено; Иначе Результат = ПолучитьИзВременногоХранилища(АдресЧужойСхемыБД); КонецЕсли; Возврат Результат; КонецФункции Функция ДочернийОбъектМДПоИмениЛкс(Знач МетаОбъект, Знач ИмяПоля, Знач ТипТаблицы = "") Экспорт Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда ТипТаблицы = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект); КонецЕсли; Если Ложь Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Или ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда #Если Сервер И Не Сервер Тогда МетаОбъект = Метаданные.Справочники.Валюты; #КонецЕсли Результат = МетаОбъект.Реквизиты.Найти(ИмяПоля); ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда #Если Сервер И Не Сервер Тогда МетаОбъект = Метаданные.РегистрыСведений.КурсыВалют; #КонецЕсли Результат = МетаОбъект.Измерения.Найти(ИмяПоля); Если Не ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда Если Результат = Неопределено Тогда Результат = МетаОбъект.Ресурсы.Найти(ИмяПоля); КонецЕсли; Если Результат = Неопределено Тогда Результат = МетаОбъект.Реквизиты.Найти(ИмяПоля); КонецЕсли; КонецЕсли; КонецЕсли; Если Результат = Неопределено И ирКэш.НомерРежимаСовместимостиЛкс() >= 802014 Тогда ОбщийРеквизит = Метаданные.ОбщиеРеквизиты.Найти(ИмяПоля); Если ОбщийРеквизит <> Неопределено Тогда Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаОбъект) Тогда Результат = ОбщийРеквизит; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Процедура ОбновитьПовторноИспользуемыеЗначенияЛкс() Экспорт Если ирКэш.ЛиПортативныйРежимЛкс() Тогда ирПортативный.ОбновитьПовторноИспользуемыеЗначенияЛкс(); Иначе ОбновитьПовторноИспользуемыеЗначения(); КонецЕсли; КонецПроцедуры Функция ПолучитьСовместимоеЗначениеПараметраЗапросаЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт Результат = ЗначениеПараметра; ТипЗначенияПараметра = ТипЗнч(Результат); Если Истина И ТипЗначенияПараметра = Тип("Массив") И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда СписокЗначений = Новый СписокЗначений; ПреобразованиеУспешно = Истина; Для Каждого ЭлементМассива Из Результат Цикл Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда СписокЗначений.Добавить(ЭлементМассива); Иначе ПреобразованиеУспешно = Ложь; Прервать; КонецЕсли; КонецЦикла; Если ПреобразованиеУспешно Тогда Результат = СписокЗначений; КонецЕсли; Иначе // http://www.hostedredmine.com/issues/885230 //МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра); //Если МетаданныеТипаЗначения <> Неопределено Тогда // ТипТаблицы = ТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя()); // Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда // Результат = ЗначениеПараметра.Выгрузить(); // КонецЕсли; //КонецЕсли; Попытка Результат = Результат.Выгрузить(); Исключение КонецПопытки; Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда #Если Сервер И Не Сервер Тогда ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов; #КонецЕсли Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(Результат); КонецЕсли; КонецЕсли; Если Результат <> ЗначениеПараметра Тогда СообщитьЛкс("Значение параметра """ + ИмяПараметра + """ было преобразовано """ + ТипЗначенияПараметра + """->""" + ТипЗнч(Результат) + """", СтатусСообщения.Внимание); КонецЕсли; Возврат Результат; КонецФункции Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт ТекстЗапроса = ДинамическийСписок.ТекстЗапроса; Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица; КонецЕсли; Запрос = Новый Запрос(ТекстЗапроса); выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; ТекущаяГруппировка = выхНастройкаКомпоновки; Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл Если ПолеГруппировки.Использование Тогда ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле); КонецЕсли; КонецЦикла; НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура); Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл Если ДоступноеПоле.Папка Тогда Продолжить; КонецЕсли; НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле); КонецЦикла; НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(выхНастройкаКомпоновки); НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Отбор); НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Параметры); НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Порядок); НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.УсловноеОформление); выхНастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO); выхСхема = СоздатьСхемуКомпоновкиПоЗапросу(Запрос); КонецПроцедуры // Если передана НастройкаКомпоновкиПриемник, то в качестве результата вернется ее копия! Функция СкопироватьНастройкиКомпоновкиЛкс(НастройкаКомпоновкиИлиДинамическийСписокИсточник, Знач НастройкаКомпоновкиПриемник = Неопределено, КопироватьОтбор = Ложь, КопироватьПараметры = Ложь, КопироватьПорядок = Ложь, КопироватьУсловноеОформление = Ложь, КопироватьВыбор = Ложь) Экспорт #Если Сервер И Не Сервер Тогда НастройкаКомпоновкиИсточник = Новый НастройкиКомпоновкиДанных; НастройкаКомпоновкиИлиДинамическийСписокИсточник = Новый НастройкиКомпоновкиДанных; #КонецЕсли Если НастройкаКомпоновкиПриемник = Неопределено Тогда НастройкаКомпоновкиПриемник = Новый НастройкиКомпоновкиДанных; КонецЕсли; Если ТипЗнч(НастройкаКомпоновкиИлиДинамическийСписокИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор; Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыДанных; УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление; Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок; Выбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Выбор; Иначе // ДинамическийСписок Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор; Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Параметры; УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление; Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок; Выбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Выбор; КонецЕсли; НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновкиПриемник); Если КопироватьОтбор Тогда НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор); КонецЕсли; Если КопироватьПараметры Тогда НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(Параметры); КонецЕсли; Если КопироватьПорядок Тогда НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(Порядок); КонецЕсли; Если КопироватьУсловноеОформление Тогда НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление); КонецЕсли; Если КопироватьВыбор Тогда НастройкаXDTO.selection = СериализаторXDTO.ЗаписатьXDTO(Выбор); КонецЕсли; НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO); Возврат НастройкаКомпоновкиПриемник; КонецФункции // СкопироватьОтборКомпоновкиЛкс() Функция ПолучитьРасширениеФайловДляОтладкиЛкс() Экспорт Результат = "deb"; Возврат Результат; КонецФункции Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Знач Наименование = "") Если Не ЗначениеЗаполнено(Наименование) Тогда Наименование = "" + СтруктураПараметров.Объект; КонецЕсли; Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + Наименование; Успех = Ложь; ДоступноФоновоеЗадание = Не (Истина И ТранзакцияАктивна() И ирКэш.ЭтоФайловаяБазаЛкс() // В файловой базе даже 8.3 не получится, т.к. там не истинной параллельности //И (Ложь // Или РежимСовместимостиМеньше8_3_4Лкс() // Или ирКэш.ЭтоФоновоеЗаданиеЛкс()) ); Если Истина И Метаданные.Справочники.Найти("ирОбъектыДляОтладки") <> Неопределено И ДоступноФоновоеЗадание Тогда Попытка ХранимоеЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров); ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент(); ОбъектДляОтладки.Наименование = Наименование; ОбъектДляОтладки.XML = ХранимоеЗначение; выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки); Успех = Истина; Исключение Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки(); КонецПопытки; Если Успех Тогда Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в справочник ""Объекты для отладки""." + " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")"; КонецЕсли; Иначе //выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор); //Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Открыть объект для отладки""." //+ " Адрес """ + выхОбъектДляОтладки + """"; КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Успех = Ложь; Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда РасширениеФайловДляОтладки = ПолучитьРасширениеФайловДляОтладкиЛкс(); Платформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда Платформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Наименование = Платформа.ИдентификаторИзПредставленияЛкс(Наименование); ИмяФайла = КаталогОбъектовДляОтладки + "\" + Наименование + "." + РасширениеФайловДляОтладки; ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла); Попытка СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя); Успех = Истина; Исключение СообщитьЛкс("Ошибка сохранения файла для отладки: " + ОписаниеОшибки()); КонецПопытки; Если Успех Тогда выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя; Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в файл." + " Файл """ + выхОбъектДляОтладки + """"; КонецЕсли; Иначе ТекстРекомендации = "Рекомендуется в общих настройках инструментов задать каталог объектов для отладки."; СообщитьЛкс(ТекстРекомендации); КонецЕсли; Если Не Успех Тогда Если ТранзакцияАктивна() И Не ДоступноФоновоеЗадание Тогда Попытка ОтменитьТранзакцию(); Успех = Истина; Исключение // Системная транзакция записи объекта КонецПопытки; Если Не Успех Тогда Результат = "Невозможно отменить транзакцию записи объекта для сохранения объекта для отладки в общие настройки. " + ТекстРекомендации; Иначе СообщитьЛкс("Транзакция была отменена для сохранения объекта для отладки в общие настройки"); КонецЕсли; Иначе Успех = Истина; КонецЕсли; Если Успех Тогда Успех = Ложь; Попытка КлючНастройки = ЗаписатьОбъектДляОтладкиЛкс(СтруктураПараметров); Успех = Истина; Исключение Результат = "Ошибка записи объекта для отладки: " + ОписаниеОшибки(); КонецПопытки; КонецЕсли; Если Успех Тогда Результат = РезультатСохраненияОбъектаОтложеннойОтладкиВНастройкуЛкс(КлючНастройки); КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // КлючНастройки - Ссылка, Строка Функция РезультатСохраненияОбъектаОтложеннойОтладкиВНастройкуЛкс(Знач КлючНастройки = "") Экспорт Если Не ЗначениеЗаполнено(КлючНастройки) Тогда КлючНастройки = ИмяНастройкиХраненияОбъектаОтложеннойОтладкиЛкс(); КонецЕсли; Результат = "Скопируйте эту строку и используйте команду ""Открыть объект для отладки"". Данные помещены в настройку """ + КлючНастройки + """." + " Пользователь """ + ИмяПользователя() + """"; Возврат Результат; КонецФункции Функция СоздаваемыеВременныеТаблицыПакетаЛкс(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе = Ложь) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли МассивТаблиц = мПлатформа.ПолучитьМассивСоздаваемыхВременныхТаблицПакета(ТекстЗапроса, ТолькоТребующиеУничтоженияНаВходе); Возврат МассивТаблиц; КонецФункции // Подставляет параметры в строку. Максимально возможное число параметров - 9. // Параметры в строке задаются как %<номер параметра>. Нумерация параметров начинается с единицы. // // Параметры: // СтрокаПодстановки - Строка - шаблон строки с параметрами (вхождениями вида "%ИмяПараметра"); // Параметр - Строка - подставляемый параметр. // // Возвращаемое значение: // Строка - текстовая строка с подставленными параметрами. // // Пример: // ПодставитьПараметрыВСтроку(НСтр("ru='%1 пошел в %2'"), "Вася", "Зоопарк") = "Вася пошел в Зоопарк". // Функция ПодставитьПараметрыВСтрокуЛкс(Знач СтрокаПодстановки, Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт ИспользоватьАльтернативныйАлгоритм = Ложь Или Найти(Параметр1, "%") Или Найти(Параметр2, "%") Или Найти(Параметр3, "%") Или Найти(Параметр4, "%") Или Найти(Параметр5, "%") Или Найти(Параметр6, "%") Или Найти(Параметр7, "%") Или Найти(Параметр8, "%") Или Найти(Параметр9, "%"); Если ИспользоватьАльтернативныйАлгоритм Тогда СтрокаПодстановки = ПодставитьПараметрыВСтрокуАльтернативныйАлгоритм(СтрокаПодстановки, Параметр1, Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); Иначе СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%1", Параметр1); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%2", Параметр2); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%3", Параметр3); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%4", Параметр4); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%5", Параметр5); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%6", Параметр6); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%7", Параметр7); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%8", Параметр8); СтрокаПодстановки = СтрЗаменить(СтрокаПодстановки, "%9", Параметр9); КонецЕсли; Возврат СтрокаПодстановки; КонецФункции // Вставляет параметры в строку, учитывая, что в параметрах могут использоваться подстановочные слова %1, %2 и т.д. Функция ПодставитьПараметрыВСтрокуАльтернативныйАлгоритм(Знач СтрокаПодстановки, Знач Параметр1, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Результат = ""; Позиция = Найти(СтрокаПодстановки, "%"); Пока Позиция > 0 Цикл Результат = Результат + Лев(СтрокаПодстановки, Позиция - 1); СимволПослеПроцента = Сред(СтрокаПодстановки, Позиция + 1, 1); ПодставляемыйПараметр = ""; Если СимволПослеПроцента = "1" Тогда ПодставляемыйПараметр = Параметр1; ИначеЕсли СимволПослеПроцента = "2" Тогда ПодставляемыйПараметр = Параметр2; ИначеЕсли СимволПослеПроцента = "3" Тогда ПодставляемыйПараметр = Параметр3; ИначеЕсли СимволПослеПроцента = "4" Тогда ПодставляемыйПараметр = Параметр4; ИначеЕсли СимволПослеПроцента = "5" Тогда ПодставляемыйПараметр = Параметр5; ИначеЕсли СимволПослеПроцента = "6" Тогда ПодставляемыйПараметр = Параметр6; ИначеЕсли СимволПослеПроцента = "7" Тогда ПодставляемыйПараметр = Параметр7 ИначеЕсли СимволПослеПроцента = "8" Тогда ПодставляемыйПараметр = Параметр8; ИначеЕсли СимволПослеПроцента = "9" Тогда ПодставляемыйПараметр = Параметр9; КонецЕсли; Если ПодставляемыйПараметр = "" Тогда Результат = Результат + "%"; СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 1); Иначе Результат = Результат + ПодставляемыйПараметр; СтрокаПодстановки = Сред(СтрокаПодстановки, Позиция + 2); КонецЕсли; Позиция = Найти(СтрокаПодстановки, "%"); КонецЦикла; Результат = Результат + СтрокаПодстановки; Возврат Результат; КонецФункции Функция ПолучитьКаталогОбъектовДляОтладкиЛкс(ДляСервера = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ирПортативный = Обработки.ирПортативный.Создать(); #КонецЕсли Если ирКэш.ЛиПортативныйРежимЛкс() Тогда КаталогОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс(); Иначе //ИмяФайла = ПолучитьИмяВременногоФайла(РасширениеФайловДляОтладки); КаталогОбъектовДляОтладки = ВосстановитьЗначениеЛкс("КаталогОбъектовДляОтладки"); #Если Клиент Тогда Если Не ДляСервера И Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда КаталогОбъектовДляОтладки = ирКэш.Получить().КаталогФайловогоКэша; КонецЕсли; #КонецЕсли Если ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда ИмяКаталогаБазы = ирКэш.Получить().ИдентификаторИзПредставленияЛкс(СтрокаСоединенияИнформационнойБазы()); КаталогОбъектовДляОтладки = КаталогОбъектовДляОтладки + "\" + ИмяКаталогаБазы + "\"; Каталог = Новый Файл(КаталогОбъектовДляОтладки); Если Не Каталог.Существует() Тогда Попытка СоздатьКаталог(КаталогОбъектовДляОтладки); Исключение СообщитьЛкс("Ошибка создрания каталога объектов для отладки: " + ОписаниеОшибки()); КаталогОбъектовДляОтладки = Неопределено; КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; Возврат КаталогОбъектовДляОтладки; КонецФункции Функция ИмяПродуктаЛкс() Экспорт Возврат "ИнструментыРазработчикаTormozit"; КонецФункции Функция ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Параметры) Экспорт // Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525 //СтруктураЗапроса.Параметры = КопияОбъектаЛкс(Объект.Параметры); Структура = Новый Структура(); Для Каждого КлючИЗначение Из Параметры Цикл ЗначениеПараметра = ПолучитьСовместимоеЗначениеПараметраЗапросаЛкс(КлючИЗначение.Значение, КлючИЗначение.Ключ); Структура.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(ЗначениеПараметра)); КонецЦикла; Возврат Структура; КонецФункции Функция СкопироватьЗапросЛкс(ЗапросИсточник, ЗапросПриемник = Неопределено) Экспорт Если ЗапросПриемник = Неопределено Тогда ЗапросПриемник = Новый Запрос; КонецЕсли; ЗапросПриемник.Текст = ЗапросИсточник.Текст; ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ЗапросИсточник.Параметры, ЗапросПриемник.Параметры); Возврат ЗапросПриемник; КонецФункции // СкопироватьЗапросЛкс() Функция ПолучитьТекстЗапросаВсехТиповСсылокЛкс(ИмяВременнойТаблицы = "ВсеТипыСсылок", Знач ОписаниеТипов = Неопределено) Экспорт Если ОписаниеТипов = Неопределено Тогда ОписаниеТипов = ОписаниеТиповВсеСсылкиЛкс(); КонецЕсли; #Если Сервер И Не Сервер Тогда ОписаниеВсехТипов = Новый ОписаниеТипов; #КонецЕсли ТекстТаблицыТипов = ""; Для Каждого Тип Из ОписаниеТипов.Типы() Цикл ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя(); НоваяСтрока = "ВЫБРАТЬ ТИП(" + ПолноеИмя + ") КАК Тип, """ + ПолноеИмя + """ КАК Имя" + Символы.ПС; Если ТекстТаблицыТипов <> "" Тогда ТекстТаблицыТипов = ТекстТаблицыТипов + "ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС; Иначе Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда НоваяСтрока = НоваяСтрока + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС; КонецЕсли; КонецЕсли; ТекстТаблицыТипов = ТекстТаблицыТипов + НоваяСтрока; КонецЦикла; //ТекстТаблицыТипов = ТекстТаблицыТипов + " ИНДЕКСИРОВАТЬ ПО Тип"; // По такому типу поля нельзя индексировать Возврат ТекстТаблицыТипов; КонецФункции Функция ПолучитьТекстЗапросаДатВДиапазонеЛкс(ИмяВременнойТаблицы = "ДатыДиапазона") Экспорт Текст = "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d) КАК Период |"; Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда Текст = Текст + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС; КонецЕсли; Текст = Текст + "ИЗ | (ВЫБРАТЬ 0 КАК a | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК aa | ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК b | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК bb | ПО (ИСТИНА) | ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК c | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК cc | ПО (ИСТИНА) | ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ | 0 КАК d | ОБЪЕДИНИТЬ | ВЫБРАТЬ 1 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 2 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 3 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 4 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 5 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 6 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 7 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 8 | ОБЪЕДИНИТЬ | ВЫБРАТЬ 9) КАК dd | ПО (ИСТИНА) |ГДЕ | aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)"; Возврат Текст; КонецФункции Функция ПолучитьСобственноеВнешнееСоединениеЛкс(ИнициализироватьИнтерфейсИР = Ложь, выхИнтерфейсИР = Неопределено) Экспорт ИмяПользователяВнешнегоСоединения = ""; ПарольПользователяВнешнегоСоединения = ""; Если ПользователиИнформационнойБазы.ПолучитьПользователей().Количество() > 0 Тогда ИмяПользователяВнешнегоСоединения = ИмяПользователя() + "_ВнешнееСоединение"; Попытка ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяВнешнегоСоединения); Исключение СообщитьЛкс("Не удалось выполнить поиск служебного пользователя: " + ОписаниеОшибки()); // Разделенная база в неразделенном сеансе Возврат Неопределено; КонецПопытки; Если ПользовательИБ = Неопределено Тогда ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя(); ПользовательИБ.Имя = ИмяПользователяВнешнегоСоединения; ПользовательИБ.ПолноеИмя = ИмяПользователяВнешнегоСоединения; СообщитьЛкс("Создан служебный пользователь ИБ с именем """ + ИмяПользователяВнешнегоСоединения + """"); КонецЕсли; ТекущийПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь(); ЗаполнитьЗначенияСвойств(ПользовательИБ, ТекущийПользовательИБ,, "Имя, ПолноеИмя"); ПользовательИБ.Роли.Очистить(); Для Каждого Роль Из ТекущийПользовательИБ.Роли Цикл ПользовательИБ.Роли.Добавить(Роль); КонецЦикла; ПарольПользователяВнешнегоСоединения = "" + Новый УникальныйИдентификатор; ПользовательИБ.ПоказыватьВСпискеВыбора = Ложь; ПользовательИБ.АутентификацияОС = Ложь; ПользовательИБ.АутентификацияСтандартная = Истина; ПользовательИБ.Пароль = ПарольПользователяВнешнегоСоединения; ПользовательИБ.Записать(); КонецЕсли; Результат = ЗапуститьСеансПодПользователемЛкс(ИмяПользователяВнешнегоСоединения, ПарольПользователяВнешнегоСоединения, "ComConnector"); Если ирКэш.ЛиПортативныйРежимЛкс() Тогда выхИнтерфейсИР = Результат.ВнешниеОбработки.Создать(ирПортативный.ИспользуемоеИмяФайла, Ложь); Иначе выхИнтерфейсИР = Результат; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ТабличныйДокумент - ТабличныйДокумент // ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных // Поля - Строка(0,П), Массив - Если строка, то через запятую перечисленные имена полей. // Область - ВыделенныеОбластиТабличногоДокумента, Массив, ОбластьЯчеекТабличногоДокумента - Если не указано, используются выделенные области // Функция ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, Знач ДанныеРасшифровки = Неопределено, Знач Поля = "", Знач Область = Неопределено, Знач выхКлючТекущейСтроки = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли Если Истина И ТипЗнч(Поля) = Тип("Строка") И Не ПустаяСтрока(Поля) Тогда МассивИменПолей = ирОбщий.СтрРазделитьЛкс(Поля, ",", Истина); ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда МассивИменПолей = Поля; Иначе МассивИменПолей = Новый Массив; КонецЕсли; ТаблицаРезультата = Неопределено; МассивСсылок = Новый Массив; АвтоПоля = МассивИменПолей.Количество() = 0; Если ТипЗнч(Область) = Тип("Неопределено") Тогда КоллекцияОбластей = ТабличныйДокумент.ВыделенныеОбласти; ИначеЕсли ТипЗнч(Область) = Тип("Массив") Тогда КоллекцияОбластей = Область; ИначеЕсли ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда КоллекцияОбластей = Новый Массив; КоллекцияОбластей.Добавить(Область); КонецЕсли; Если ТипЗнч(ДанныеРасшифровки) = Тип("ДанныеРасшифровкиКомпоновкиДанных") Тогда ЭлементыРасшифровки = ДанныеРасшифровки.Элементы; КонецЕсли; НачальноеКоличество = КоллекцияОбластей.Количество(); Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл Область = КоллекцияОбластей[НачальноеКоличество - СчетчикВыделенныеОбласти]; Если Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Колонки Тогда Лево = Область.Лево; Право = Область.Право; Верх = 1; Низ = ТабличныйДокумент.ВысотаТаблицы; ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Строки Тогда Лево = 1; Право = ТабличныйДокумент.ШиринаТаблицы; Верх = Область.Верх; Низ = Область.Низ; ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда Лево = Область.Лево; Право = Область.Право; Верх = Область.Верх; Низ = Область.Низ; Иначе Продолжить; КонецЕсли; Для НомерСтроки = Верх по Низ Цикл КлючПолучен = Ложь; СтруктураПолей = Новый Структура; Для НомерКолонки = Лево по Право Цикл ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки); Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; Расшифровка = ОбластьЯчейки.Расшифровка; Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда Если ЭлементыРасшифровки = Неопределено Тогда ВызватьИсключение "В табличном документа найден идентификатор расшифровки компоновки, но не переданы данные расшифровки"; КонецЕсли; ЭлементРасшифровкиПоля = ЭлементыРасшифровки[Расшифровка]; Если НомерСтроки = Верх Тогда Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; Для Каждого ИмяПоля Из МассивИменПолей Цикл ТаблицаРезультата.Колонки.Добавить(ИмяПоля); КонецЦикла; КонецЕсли; Если АвтоПоля Тогда ИмяПоля = ЭлементРасшифровкиПоля.ПолучитьПоля()[0].Поле; МассивИменПолей.Добавить(ИмяПоля); ИмяКолонки = СтрЗаменить(ИмяПоля, ".", ""); Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда ТаблицаРезультата.Колонки.Добавить(ИмяКолонки); КонецЕсли; КонецЕсли; КонецЕсли; КлючПолучен = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровкиПоля, МассивИменПолей, СтруктураПолей); Если Истина И КлючПолучен И (Ложь Или НомерКолонки = Право Или Не АвтоПоля) Тогда Прервать; КонецЕсли; ИначеЕсли ирОбщий.ЛиСсылкаНаОбъектБДЛкс(Расшифровка, Ложь) Тогда ИмяКолонки = "Ссылка"; СтруктураПолей.Вставить(ИмяКолонки, Расшифровка); КлючПолучен = Истина; Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; КонецЕсли; Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда ТаблицаРезультата.Колонки.Добавить(ИмяКолонки); КонецЕсли; ИначеЕсли ТипЗнч(Расшифровка) = Тип("Структура") Тогда СкопироватьУниверсальнуюКоллекциюЛкс(Расшифровка, СтруктураПолей); КлючПолучен = Истина; Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; КонецЕсли; Для Каждого КлючИЗначение Из Расшифровка Цикл Если ТаблицаРезультата.Колонки.Найти(КлючИЗначение.Ключ) = Неопределено Тогда ТаблицаРезультата.Колонки.Добавить(КлючИЗначение.Ключ); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; Если КлючПолучен Тогда Если ТаблицаРезультата.НайтиСтроки(СтруктураПолей).Количество() = 0 Тогда СтрокаРезультата = ТаблицаРезультата.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтруктураПолей); Если ТабличныйДокумент.ТекущаяОбласть = Область Тогда выхКлючТекущейСтроки = СтрокаРезультата; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; Если ТаблицаРезультата = Неопределено Тогда ТаблицаРезультата = Новый ТаблицаЗначений; КонецЕсли; Результат = ТаблицаРезультата; Возврат Результат; КонецФункции // Извлекаемые значения помещаются в структуру // Параметры: // ЭлементРасшифровкиПоля - ЭлементРасшифровкиКомпоновкиДанныхГруппировка, ЭлементРасшифровкиКомпоновкиДанныхПоля // Поля - Строка(0,П), Массив // СтруктураПолей - Структура (если поля заданы), Соответствие // Функция ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровкиПоля, Знач Поля = "", Знач СтруктураПолей = Неопределено) Экспорт Если СтруктураПолей = Неопределено Тогда СтруктураПолей = Новый Структура; КонецЕсли; Если Истина И ТипЗнч(Поля) = Тип("Строка") И Не ПустаяСтрока(Поля) Тогда МассивИменПолей = ирОбщий.СтрРазделитьЛкс(Поля, ",", Истина); ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда МассивИменПолей = Поля; Иначе МассивИменПолей = Новый Массив; КонецЕсли; Если МассивИменПолей.Количество() > 0 И СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда Результат = Истина; Иначе Результат = Ложь; Если ТипЗнч(ЭлементРасшифровкиПоля) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда ЗначенияПолей = ЭлементРасшифровкиПоля.ПолучитьПоля(); Если ЗначенияПолей.Количество() > 0 Тогда Если МассивИменПолей.Количество() > 0 Тогда Для Каждого ИмяПоля Из МассивИменПолей Цикл ЗначениеПоля = ЗначенияПолей.Найти(ИмяПоля); ИмяСвойства = СтрЗаменить(ИмяПоля, ".", ""); Если Истина И ЗначениеПоля <> Неопределено И Не СтруктураПолей.Свойство(ИмяСвойства) Тогда СтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение); Если СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда Результат = Истина; Прервать КонецЕсли; КонецЕсли; КонецЦикла; Иначе Для Каждого ЗначениеПоля Из ЗначенияПолей Цикл СтруктураПолей.Вставить(ЗначениеПоля.Поле, ЗначениеПоля.Значение); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; Если Не Результат Тогда РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей(); Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, СтруктураПолей); Если Результат Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьСоединениеСУБД(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "") Экспорт Если Не ЗначениеЗаполнено(ИмяСервера) Тогда ПараметрыСоединения = ПараметрыСоединенияADOЭтойБДЛкс(); ИмяСервера = ПараметрыСоединения.ИмяСервера; ИмяБД = ПараметрыСоединения.ИмяБД; ИмяПользователя = ПараметрыСоединения.ИмяПользователя; Пароль = ПараметрыСоединения.Пароль; КонецЕсли; КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли ИсточникДанных = КонсольЗапросов.ПолучитьСтруктуруИсточникаДанныхADO(); ИсточникДанных.Платформа = 11; // ADO-SQLOLEDB ИсточникДанных.БазаСервер = ИмяСервера; ИсточникДанных.БазаИмя = ИмяБД; ИсточникДанных.АутентификацияОС = Не ЗначениеЗаполнено(ИмяПользователя); ИсточникДанных.Пользователь = ИмяПользователя; ИсточникДанных.Пароль = Пароль; СоединениеADO = Неопределено; ОшибкиПодключения = Неопределено; Если Не КонсольЗапросов.ConnectADO(ИсточникДанных, СоединениеADO,, ОшибкиПодключения) Тогда СообщениеОбОшибке = "Ошибки подключения к серверу MSSQL:"; Для каждого ОшибкаПодключения Из ОшибкиПодключения Цикл СообщениеОбОшибке = СообщениеОбОшибке + Символы.ПС + ОшибкаПодключения; КонецЦикла; СообщитьЛкс(СообщениеОбОшибке); СоединениеADO = Неопределено; Иначе КлючНастроек = "" + Новый УникальныйИдентификатор; ХранилищеОбщихНастроек.Сохранить(ирКэш.ИмяПродукта(), КлючНастроек, Неопределено); РезультатЗапроса = ирОбщий.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс("SELECT * FROM _CommonSettings WHERE _SettingsKey = '" + КлючНастроек + "'",,,,, Ложь, СоединениеADO); ХранилищеОбщихНастроек.Удалить(ирКэш.ИмяПродукта(), КлючНастроек, ИмяПользователя()); Если РезультатЗапроса.Количество() = 0 Тогда СообщитьЛкс("Указаны параметры подключения к БД, не связанной с текущей базой 1С", СтатусСообщения.Внимание); СоединениеADO = Неопределено; КонецЕсли; КонецЕсли; Возврат СоединениеADO; КонецФункции Функция ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ИмяЗапроса = "Запрос для отладки", Параметры = Неопределено, Автоподключение = Ложь) Экспорт КонсольЗапросов = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли КонсольЗапросов.ОткрытьЗапросБД(ТекстЗапроса, ИмяЗапроса, Параметры, Автоподключение); КонецФункции Функция HTTPСоединение(ИмяСервера, Таймаут = 0, Порт = Неопределено, ИспользоватьЗащищенноеСоединение = Ложь) Экспорт ЗащищенноеСоединение = Неопределено; Если ИспользоватьЗащищенноеСоединение Тогда ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL; КонецЕсли; Попытка Результат = Новый HTTPСоединение(ИмяСервера, Порт,,,, Таймаут, ЗащищенноеСоединение); Исключение // Антибаг платформы https://bugboard.v8.1c.ru/error/000013833.html Результат = Новый HTTPСоединение(ИмяСервера, Порт,,, Новый ИнтернетПрокси(Ложь), Таймаут, ЗащищенноеСоединение); КонецПопытки; Возврат Результат; КонецФункции Функция ИнтернетПрокси(ИспользоватьСобственныйПрокси = Ложь, ЗащищенноеСоединение = Ложь) Экспорт ИнтернетПрокси = Новый ИнтернетПрокси(Не ИспользоватьСобственныйПрокси); Если ИспользоватьСобственныйПрокси Тогда СобственныеПрокси = ирОбщий.ВосстановитьЗначениеЛкс("ИнтернетПрокси"); #Если Сервер И Не Сервер Тогда СобственныеПрокси = Новый Структура; #КонецЕсли Протокол = ?(ЗащищенноеСоединение, "https", "http"); Если СобственныеПрокси.Свойство(Протокол) Тогда НастройкиПрокси = СобственныеПрокси[Протокол]; Если ЗначениеЗаполнено(НастройкиПрокси.Сервер) Тогда ИнтернетПрокси.Установить(Протокол, НастройкиПрокси.Сервер, НастройкиПрокси.Порт, НастройкиПрокси.Пользователь, НастройкиПрокси.Пароль, НастройкиПрокси.АутентификацияОС); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИнтернетПрокси; КонецФункции Функция ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляВКонсолиНеМенялся, ДатаИзмененияВнешнейОбработки) Экспорт // Из-за негарантированной последовательности изменений одного файла в сетевом ресурсе, проводимых с разных компьютеров, серверное выполнение лишено смысла //Если НаСервере Тогда // Результат = ирСервер.ОбновитьМодульВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля, ТекстМодуляВКонсолиНеМенялся, ДатаИзмененияВнешнейОбработки); // Возврат Результат; //Иначе мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ИмяФайлаВнешнейОбработки = ФайлВнешнейОбработкиДляОтладкиЛкс(БазовоеИмяВнешнейОбработки); Если Не ЗначениеЗаполнено(ИмяФайлаВнешнейОбработки) Тогда Возврат Ложь; КонецЕсли; ФайловыйКэшАлгоритмовДопускаетРедактирование = Истина; ФайлВнешнейОбработки = Новый Файл(ИмяФайлаВнешнейОбработки); Если ДатаИзмененияВнешнейОбработки <> Неопределено Тогда Если Ложь Или (Истина И ФайлВнешнейОбработки.Существует() И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() > ДатаИзмененияВнешнейОбработки И ФайловыйКэшАлгоритмовДопускаетРедактирование) Или (Истина И ФайлВнешнейОбработки.Существует() И ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() = ДатаИзмененияВнешнейОбработки И ТекстМодуляВКонсолиНеМенялся) Тогда Возврат Ложь; КонецЕсли; КонецЕсли; мПлатформа.СформироватьВнешнююОбработку(ФайлВнешнейОбработки, ИмяВнешнейОбработки, ТекстМодуля); //// 19.01.2019 Для ВерсияАлгоритма в консоли кода ////ДатаИзмененияВнешнейОбработки = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс(); //Если ЗначениеЗаполнено(ДатаИзмененияВнешнейОбработки) Тогда // ФайлВнешнейОбработки.УстановитьВремяИзменения(ДатаИзмененияВнешнейОбработки); //КонецЕсли; Возврат Истина; //КонецЕсли; КонецФункции // Получает идентификатор из любой строки. // "3-я Дебиторка По контрагентам с интервалами СНГ (для Руководства)" => "_3_яДебиторкаПоКонтрагентамСИнтерваламиСНГ_дляРуководства_". // Обретка ирПлатформа.ИдентификаторИзПредставленияЛкс() // // Параметры: // Представление – Строка. // // Возвращаемое значение: // Строка. // Функция ИдентификаторИзПредставленияЛкс(Знач Представление = Неопределено, ЗаменаПустойСтроки = "_", ДопРазрешенныеСимволы = "") Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Если Представление = Неопределено Тогда Представление = Новый УникальныйИдентификатор; КонецЕсли; Результат = мПлатформа.ИдентификаторИзПредставленияЛкс(Представление, ЗаменаПустойСтроки, ДопРазрешенныеСимволы); Возврат Результат; КонецФункции Функция ФайлВнешнейОбработкиДляОтладкиЛкс(Знач ИмяВнешнейОбработки) Экспорт КаталогОбъектовДляОтладки = ПолучитьКаталогОбъектовДляОтладкиЛкс(); Если Не ЗначениеЗаполнено(КаталогОбъектовДляОтладки) Тогда СообщитьЛкс("В общих настройках инструментов не задан каталог объектов для отладки! Сохранение внешней обработки не выполнено.", СтатусСообщения.Внимание); Возврат ""; КонецЕсли; ИмяФайлаВнешнейОбработки = КаталогОбъектовДляОтладки + "\" + ИмяВнешнейОбработки + ".epf"; Возврат ИмяФайлаВнешнейОбработки; КонецФункции Процедура ЗаписатьДокументDOMВФайлЛкс(Знач ДокументДом, Знач ИмяФайла) Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.ОткрытьФайл(ИмяФайла); ЗаписьДом = Новый ЗаписьDOM; ЗаписьДом.Записать(ДокументДом, ЗаписьXML); ЗаписьXML.Закрыть(); КонецПроцедуры Функция ЗаписатьДокументDOMВСтрокуЛкс(Знач ДокументДом) Экспорт ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.УстановитьСтроку(""); ЗаписьДом = Новый ЗаписьDOM; ЗаписьДом.Записать(ДокументДом, ЗаписьXML); Результат = ЗаписьXML.Закрыть(); Возврат Результат; КонецФункции Функция ПрочитатьФайлВДокументDOMЛкс(Знач ИмяФайла, ИгнорироватьПробельныеСимволы = Ложь) Экспорт ЧтениеXML = Новый ЧтениеXML; ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы); ЧтениеXML.ОткрытьФайл(ИмяФайла, ПараметрыЧтения); ПостроительДом = Новый ПостроительDOM(); ДокументДОМ = ПостроительДом.Прочитать(ЧтениеXML); ЧтениеXML.Закрыть(); Возврат ДокументДОМ; КонецФункции Функция ПрочитатьТекстВДокументDOMЛкс(Знач Текст, ИгнорироватьПробельныеСимволы = Ложь) Экспорт ЧтениеXML = Новый ЧтениеXML; ПараметрыЧтения = Новый ПараметрыЧтенияXML(,,,,,,,, ИгнорироватьПробельныеСимволы); ЧтениеXML.УстановитьСтроку(Текст, ПараметрыЧтения); ПостроительDOM = Новый ПостроительDOM; ДокументДом = ПостроительDOM.Прочитать(ЧтениеXML); Возврат ДокументДом; КонецФункции Функция ПолучитьДокументDOMИзСтрокиВнутрЛкс(ТекстФайла, ИгнорироватьПробельныеСимволы = Истина) Экспорт XMLСтрока = СтрокаВнутрВХМЛТелоЛкс(ТекстФайла); ДокументDOM = ПрочитатьТекстВДокументDOMЛкс(XMLСтрока, ИгнорироватьПробельныеСимволы); Возврат ДокументDOM; КонецФункции Функция ЭтотРасширениеКонфигурацииЛкс() Экспорт Результат = Неопределено; Если Не ирОбщий.РежимСовместимостиМеньше8_3_4Лкс() Тогда Попытка ЭтиРасширения = Вычислить("РасширенияКонфигурации").Получить(); // Антибаг платформы https://partners.v8.1c.ru/forum/t/1607016/m/1607016 Исключение Возврат Результат; КонецПопытки; ОтборРасширений = Новый Структура("Имя", ирОбщий.ИмяПродуктаЛкс()); ЭтиРасширения = Вычислить("РасширенияКонфигурации").Получить(ОтборРасширений); Если ЭтиРасширения.Количество() > 0 Тогда Результат = ЭтиРасширения[0]; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция АдаптироватьРасширениеЛкс(ИмяПользователя = "", ПарольПользователя = "", ВключатьНомерСтроки = Истина) Экспорт #Если ТонкийКлиент Или ВебКлиент Тогда Результат = ирСервер.АдаптироватьРасширениеЛкс(); Возврат Результат; #КонецЕсли ПометкиКоманд = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПометкиКоманд",, ирОбщий.ИмяПродуктаЛкс()); ПодключитьОтладкуВнешнихОбработокБСП = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПодключитьОтладкуВнешнихОбработокБСП",, ирОбщий.ИмяПродуктаЛкс()); //ПодключитьОтладкуОтчетов = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.ПодключитьОтладкуОтчетов",, ирОбщий.ИмяПродуктаЛкс()); ПодключитьОтладкуОтчетов = Ложь; // Теперь это делается через глобальную команду //СгенерироватьРольВсеПрава = ХранилищеОбщихНастроек.Загрузить(, "ирАдаптацияРасширения.СгенерироватьРольВсеПрава",, ирОбщий.ИмяПродуктаЛкс()); СгенерироватьРольВсеПрава = Ложь; // Давать права на верхние объекты метаданных недостаточно. Поэтому отключил пока этот флажок НадоДобавитьВсеСсылочныеМетаданнные = СгенерироватьРольВсеПрава; Для Каждого КлючИЗначение Из ПометкиКоманд Цикл Если КлючИЗначение.Значение Тогда НадоДобавитьВсеСсылочныеМетаданнные = Истина; Прервать; КонецЕсли; КонецЦикла; ЭтотРасширение = ЭтотРасширениеКонфигурацииЛкс(); #Если Сервер И Не Сервер Тогда ЭтотРасширение = РасширенияКонфигурации.Создать(); #КонецЕсли ИмяРасширения = ЭтотРасширение.Имя; ТекстСпискаОбъектовКонфигурации = ""; Если НадоДобавитьВсеСсылочныеМетаданнные Тогда ТипыСсылок = ирОбщий.ОписаниеТиповВсеСсылкиЛкс(Ложь).Типы(); #Если Сервер И Не Сервер Тогда ТипыСсылок = Новый Массив; #КонецЕсли ТипыСсылокПлановОбмена = ПланыОбмена.ТипВсеСсылки().Типы(); // Сначала выгружаем из конфигурации все метаданные //ТекстСпискаОбъектовКонфигурации = Метаданные.ПолноеИмя(); ДобавляемыеТипы = СкопироватьУниверсальнуюКоллекциюЛкс(ТипыСсылок); #Если Сервер И Не Сервер Тогда ДобавляемыеТипы = Новый Массив; #КонецЕсли Если СгенерироватьРольВсеПрава Тогда ДобавляемыеТипыРегистров = Новый Массив; ДобавляемыеТипыРегистров.Добавить("РегистрыСведений"); ДобавляемыеТипыРегистров.Добавить("РегистрыНакопления"); ДобавляемыеТипыРегистров.Добавить("РегистрыРасчета"); ДобавляемыеТипыРегистров.Добавить("РегистрыБухгалтерии"); ДобавляемыеТипыРегистров.Добавить("Последовательности"); Для Каждого ИмяКоллекцииРегистров Из ДобавляемыеТипыРегистров Цикл Для Каждого ОбъектМД Из Метаданные[ИмяКоллекцииРегистров] Цикл ДобавляемыеТипы.Добавить(Тип(СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "НаборЗаписей."))); КонецЦикла; КонецЦикла; КонецЕсли; Для Каждого Тип Из ДобавляемыеТипы Цикл ОбъектМД = Метаданные.НайтиПоТипу(Тип); ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя(); КонецЦикла; Для Каждого ОбъектМД Из Метаданные.ВнешниеИсточникиДанных Цикл Если ОбъектМД.РасширениеКонфигурации() <> Неопределено Тогда Продолжить; КонецЕсли; ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + ОбъектМД.ПолноеИмя(); КонецЦикла; КонецЕсли; Если ПодключитьОтладкуВнешнихОбработокБСП И ирКэш.НомерВерсииБСПЛкс() >= 204 Тогда ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + Метаданные.ОбщиеМодули.ДополнительныеОтчетыИОбработки.ПолноеИмя(); КонецЕсли; ПодключитьОтладкуОтчетов = ПодключитьОтладкуОтчетов И Метаданные.ОсновнаяФормаОтчета <> Неопределено И Метаданные.ОсновнаяФормаОтчета.РасширениеКонфигурации() = Неопределено; Если ПодключитьОтладкуОтчетов Тогда ТекстСпискаОбъектовКонфигурации = ТекстСпискаОбъектовКонфигурации + Символы.ПС + Метаданные.ОсновнаяФормаОтчета.ПолноеИмя(); КонецЕсли; ТекстСпискаОбъектовКонфигурации = Сред(ТекстСпискаОбъектовКонфигурации, 2); // ! ИмяФайлаСпискаВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла("txt"); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовКонфигурации); ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиКонфигурации); КаталогВыгрузкиКонфигурации = ПолучитьИмяВременногоФайла(); СоздатьКаталог(КаталогВыгрузкиКонфигурации); ТекстЛога = ""; Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиКонфигурации + """ -listFile """ + ИмяФайлаСпискаВыгрузкиКонфигурации + """ -Format Plain", СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка конфигурации в файлы",,,, ИмяПользователя, ПарольПользователя); УдалитьФайлы(ИмяФайлаСпискаВыгрузкиКонфигурации); Если Не Успех Тогда УдалитьФайлы(КаталогВыгрузкиКонфигурации); СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; // Выгружаем объекты из расширения КаталогВыгрузкиРасширения = ПолучитьИмяВременногоФайла(); ИмяФайлаСпискаВыгрузкиРасширения = ПолучитьИмяВременногоФайла("txt"); ТекстЛога = ""; СоздатьКаталог(КаталогВыгрузкиРасширения); ТекстСпискаОбъектовРасширения = "Конфигурация." + ИмяРасширения; Для Каждого КлючИЗначение Из ПометкиКоманд Цикл ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "ОбщаяКоманда." + КлючИЗначение.Ключ; КонецЦикла; ТекстовыйДокумент.УстановитьТекст(ТекстСпискаОбъектовРасширения); ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения); // Пришлось отказаться от частичной загрузки из-за непонятной ошибки // Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации //Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain", // СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы"); Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpConfigToFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain", СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Выгрузка расширения в файлы",,,, ИмяПользователя, ПарольПользователя); Если Не Успех Тогда УдалитьФайлы(КаталогВыгрузкиРасширения); СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; // Добавим ссылочные объекты в расширение ИмяФайла = КаталогВыгрузкиРасширения + "\Configuration.xml"; ОписаниеРасширения = Новый ТекстовыйДокумент; ОписаниеРасширения.Прочитать(ИмяФайла); ОписаниеРасширения = ОписаниеРасширения.ПолучитьТекст(); ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла); Если НадоДобавитьВсеСсылочныеМетаданнные Тогда УзелТиповСпискаОбъектов = ДокументДом.ПолучитьЭлементыПоИмени("ChildObjects"); УзелТиповСпискаОбъектов = УзелТиповСпискаОбъектов[0]; Если СгенерироватьРольВсеПрава Тогда ТекстФайлаПрав = Новый ЗаписьXML; ТекстФайлаПрав.УстановитьСтроку(""); ТекстФайлаПрав.ЗаписатьБезОбработки(" | | true | true | false"); КонецЕсли; ДобавленныеВнешниеИсточникиДанных = Новый Соответствие; Для Каждого Тип Из ДобавляемыеТипы Цикл ПолноеИмяМДXML = XMLТип(Тип).ИмяТипа; Если Ложь Или Найти(ПолноеИмяМДXML, "RoutePointRef.") > 0 Тогда Продолжить; КонецЕсли; ЭтоТаблицаВИД = Найти(ПолноеИмяМДXML, "ExternalDataSourceTableRef.") > 0; Если ЭтоТаблицаВИД Тогда Фрагменты = СтрРазделитьЛкс(ПолноеИмяМДXML); Фрагменты[0] = "ExternalDataSource"; Фрагменты.Вставить(2, "Table"); МассивТаблицВИД = ДобавленныеВнешниеИсточникиДанных[Фрагменты[1]]; Если МассивТаблицВИД = Неопределено Тогда МассивТаблицВИД = Новый Массив; ДобавленныеВнешниеИсточникиДанных.Вставить(Фрагменты[1], МассивТаблицВИД); КонецЕсли; ПолноеИмяМДXML = СтрСоединитьЛкс(Фрагменты, "."); КонецЕсли; ПолноеИмяМДXML = СтрЗаменить(ПолноеИмяМДXML, "Ref.", "."); ПолноеИмяМДXML = СтрЗаменить(ПолноеИмяМДXML, "RecordSet.", "."); // Добавим в описание конфигурации (Configuration.xml) ОбъектМД = Метаданные.НайтиПоТипу(Тип); Если Не ЭтоТаблицаВИД Тогда ИмяКлассаМДXML = ПервыйФрагментЛкс(ПолноеИмяМДXML); ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя(); Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") > 0 Тогда Продолжить; КонецЕсли; УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML); УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя; УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта); Иначе МассивТаблицВИД.Добавить(ОбъектМД.Имя); ИмяКлассаМДXML = "Table"; КонецЕсли; // Укажем принадлежность объекта в его описании ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ПолноеИмяМДXML + ".xml"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя); //ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "", Ложь, Истина, Истина); НаЧтоЗаменять = " | " + ирОбщий.ПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + " | Adopted | | | "; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина); НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>"; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); Если СгенерироватьРольВсеПрава Тогда Если Истина И Найти(ПолноеИмяМДXML, "Enum.") = 0 Тогда // Даем права Просмотр и ПросмотрИстории ТекстФайлаПрав.ЗаписатьБезОбработки(" | | " + ПолноеИмяМДXML + " | | Read | true | | | View | true | | | ReadDataHistory | true | | | ViewDataHistory | true | | "); КонецЕсли; КонецЕсли; КонецЦикла; Для Каждого КлючИЗначение Из ДобавленныеВнешниеИсточникиДанных Цикл ПолноеИмяМДXML = "ExternalDataSource." + КлючИЗначение.Ключ; ИмяКлассаМДXML = ПервыйФрагментЛкс(ПолноеИмяМДXML); // Добавим в описание конфигурации (Configuration.xml) ОбъектМД = Метаданные.ВнешниеИсточникиДанных[КлючИЗначение.Ключ]; ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя(); Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") > 0 Тогда Продолжить; КонецЕсли; УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML); УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя; УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта); // Укажем принадлежность объекта в его описании ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ПолноеИмяМДXML + ".xml"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя); //ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "", Ложь, Истина, Истина); НаЧтоЗаменять = " | " + ирОбщий.ПоследнийФрагментЛкс(ФайлИсточник.ИмяБезРасширения) + " | Adopted | | | "; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина); НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>"; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ДокументДомВИД = ирОбщий.ПрочитатьТекстВДокументDOMЛкс(ТекстФайла); УзелТиповСпискаДочернихОбъектов = ДокументДомВИД.ПолучитьЭлементыПоИмени("ChildObjects"); УзелТиповСпискаДочернихОбъектов = УзелТиповСпискаДочернихОбъектов[0]; Для Каждого ИмяТаблицы Из КлючИЗначение.Значение Цикл УзелОбъекта = ДокументДомВИД.СоздатьЭлемент("Table"); УзелОбъекта.ТекстовоеСодержимое = ИмяТаблицы; УзелТиповСпискаДочернихОбъектов.ДобавитьДочерний(УзелОбъекта); КонецЦикла; ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДомВИД, ФайлПриемник.ПолноеИмя); КонецЦикла; Если СгенерироватьРольВсеПрава Тогда // Добавим в описание конфигурации (Configuration.xml) ИмяКлассаМДXML = "Role"; ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + "Роль.ирВсеПрава"; Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + "ирВсеПрава" + "<") = 0 Тогда УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML); УзелОбъекта.ТекстовоеСодержимое = "ирВсеПрава"; УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта); КонецЕсли; ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + ".ирВсеПрава.xml"); ТекстФайла = " | | | | ирВсеПрава | | | ru | Все права (ИР) | | | Сгенерирована инструментом ""Адаптация расширения"" для доступа на просмотр ко всем данным | | |"; ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + ".ирВсеПрава.Rights.xml"); ТекстФайлаПрав.ЗаписатьБезОбработки(" |"); ТекстовыйДокумент.УстановитьТекст(ТекстФайлаПрав.Закрыть()); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); КонецЕсли; КонецЕсли; Если ПодключитьОтладкуВнешнихОбработокБСП И ирКэш.НомерВерсииБСПЛкс() >= 204 Тогда ИмяОбъектаОригинала = "ДополнительныеОтчетыИОбработки"; ИмяОбъектаРасширения = "ирДополнительныеОтчетыИОбработкиБСП"; // Добавим в описание конфигурации (Configuration.xml) ИмяКлассаМДXML = "CommonModule"; ОбъектМД = Метаданные.ОбщиеМодули[ИмяОбъектаОригинала]; ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя(); Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") = 0 Тогда УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML); УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя; УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта); // Укажем принадлежность объекта в его описании ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".xml"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя); //ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "", Ложь, Истина, Истина); НаЧтоЗаменять = " | " + ИмяОбъектаОригинала + " | Adopted | | "; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина); НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>"; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); КонецЕсли; ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Module.txt"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Module.txt"); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); КонецЕсли; Если ПодключитьОтладкуОтчетов И Метаданные.ОсновнаяФормаОтчета <> Неопределено Тогда ИмяОбъектаОригинала = Метаданные.ОсновнаяФормаОтчета.Имя; ИмяОбъектаРасширения = Метаданные.ОбщиеФормы.ирФормаОтчетаРасширение.Имя; // Добавим в описание конфигурации (Configuration.xml) ИмяКлассаМДXML = "CommonForm"; ОбъектМД = Метаданные.ОбщиеФормы[ИмяОбъектаОригинала]; ТекстСпискаОбъектовРасширения = ТекстСпискаОбъектовРасширения + Символы.ПС + ОбъектМД.ПолноеИмя(); Если Найти(ОписаниеРасширения, "<" + ИмяКлассаМДXML + ">" + ОбъектМД.Имя + "<") = 0 Тогда УзелОбъекта = ДокументДом.СоздатьЭлемент(ИмяКлассаМДXML); УзелОбъекта.ТекстовоеСодержимое = ОбъектМД.Имя; УзелТиповСпискаОбъектов.ДобавитьДочерний(УзелОбъекта); // Укажем принадлежность объекта в его описании ФайлИсточник = Новый Файл(КаталогВыгрузкиКонфигурации + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".xml"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ФайлИсточник.Имя); //ПереместитьФайл(ФайлИсточник.ПолноеИмя, ФайлПриемник.ПолноеИмя); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "", "", Ложь, Истина, Истина); НаЧтоЗаменять = " | " + ИмяОбъектаОригинала + " | Adopted | Managed | | "; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ЧтоЗаменять = ирОбщий.СтрокаМеждуМаркерамиЛкс(ТекстФайла, "<" + ИмяКлассаМДXML + " uuid=", ">", Ложь, Истина, Истина); НаЧтоЗаменять = "<" + ИмяКлассаМДXML + " uuid=""" + Новый УникальныйИдентификатор + """>"; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); КонецЕсли; // Модуль ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Form.Module.txt"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Form.Module.txt"); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); // Диалог ФайлИсточник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ИмяОбъектаРасширения + ".Form.xml"); ФайлПриемник = Новый Файл(КаталогВыгрузкиРасширения + "\" + ИмяКлассаМДXML + "." + ОбъектМД.Имя + ".Form.xml"); ТекстовыйДокумент.Прочитать(ФайлИсточник.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ЧтоЗаменять = ""; НаЧтоЗаменять = ""; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять); ЧтоЗаменять = ""; НаЧтоЗаменять = ""; ТекстФайла = СтрЗаменитьЛкс(ТекстФайла, ЧтоЗаменять, НаЧтоЗаменять, Истина); ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ФайлПриемник.ПолноеИмя); КонецЕсли; ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла); // Добавим типы ссылочных объектов в общие команды #Если Сервер И Не Сервер Тогда ТипыСсылок = Новый ОписаниеТипов; #КонецЕсли Для Каждого КлючИЗначение Из ПометкиКоманд Цикл ИмяКоманды = КлючИЗначение.Ключ; ИмяФайла = КаталогВыгрузкиРасширения + "\CommonCommand." + ИмяКоманды + ".xml"; ДокументДОМ = ирОбщий.ПрочитатьФайлВДокументDOMЛкс(ИмяФайла); УзелТиповПараметра = ДокументДом.ПолучитьЭлементыПоИмени("CommandParameterType"); УзелТиповПараметра = УзелТиповПараметра[0]; Пока УзелТиповПараметра.ДочерниеУзлы.Количество() > 0 Цикл УзелТиповПараметра.УдалитьДочерний(УзелТиповПараметра.ПервыйДочерний); КонецЦикла; Если КлючИЗначение.Значение Тогда Если ИмяКоманды = Метаданные.ОбщиеКоманды.ирРедактироватьИзмененияНаУзле.Имя Тогда ТипыПараметра = ТипыСсылокПлановОбмена; Иначе ТипыПараметра = ТипыСсылок; КонецЕсли; Для Каждого Тип Из ТипыПараметра Цикл УзелТипа = ДокументДом.СоздатьЭлемент("v8:Type"); // http://v8.1c.ru/8.1/data/core УзелТипа.ТекстовоеСодержимое = "cfg:" + XMLТип(Тип).ИмяТипа; // http://v8.1c.ru/8.1/data/enterprise/current-config УзелТиповПараметра.ДобавитьДочерний(УзелТипа); КонецЦикла; КонецЕсли; ирОбщий.ЗаписатьДокументDOMВФайлЛкс(ДокументДом, ИмяФайла); КонецЦикла; ТекстЛога = ""; // Пришлось отказаться от частичной загрузки из-за непонятной ошибки // Файл - Configuration.xml: ошибка частичной загрузки - идентификатор 15dc941a-fd9f-4d00-bc7e-3ef077518def загружаемой конфигурации отличается от идентификатора b9c0a797-9739-4c3f-a665-796b3bf92d6a сохраненной конфигурации //ФайлыДляЗагрузки = НайтиФайлы(КаталогВыгрузкиРасширения, "*"); //ТекстовыйДокумент.Очистить(); //Для Каждого Файл Из ФайлыДляЗагрузки Цикл // ТекстовыйДокумент.ДобавитьСтроку(Файл.ПолноеИмя); //КонецЦикла; //ТекстовыйДокумент.Записать(ИмяФайлаСпискаВыгрузкиРасширения); //Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -listFile """ + ИмяФайлаСпискаВыгрузкиРасширения + """ -Format Plain", // СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,, "Загрузка расширения из файлов"); Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadConfigFromFiles """ + КаталогВыгрузкиРасширения + """ -Extension """ + ИмяРасширения + """ -Format Plain", СтрокаСоединенияИнформационнойБазы(), ТекстЛога, , "Загрузка расширения из файлов",,,, ИмяПользователя, ПарольПользователя); УдалитьФайлы(КаталогВыгрузкиРасширения); Если Не Успех Тогда СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; // Почему то без этого расширение не применялось (оставалась активной кнопка "Обновить конфигурацию БД" //ЭтотРасширение.Записать(); КонечныйФайл = ПолучитьИмяВременногоФайла(); Успех = ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpCfg """ + КонечныйФайл + """ -Extension """ + ИмяРасширения + """", СтрокаСоединенияИнформационнойБазы(), ТекстЛога,,,,,, ИмяПользователя, ПарольПользователя); Если Не Успех Тогда СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; ЭтотРасширение.Записать(Новый ДвоичныеДанные(КонечныйФайл)); Возврат Истина; КонецФункции Функция ПредставлениеКлючаСтрокиБДЛкс(Знач КлючСтроки, ПолучатьПредставленияСсылок = Истина) Экспорт Если ЛиКлючЗаписиРегистраЛкс(КлючСтроки) Тогда ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючСтроки)).ПолноеИмя(); СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяМД, , Ложь, Ложь); ПредставленияКлюча = ""; Для Каждого ЭлементСписка Из СтруктураКлюча Цикл Если ПредставленияКлюча <> "" Тогда ПредставленияКлюча = ПредставленияКлюча + ", "; КонецЕсли; ПредставлениеЗначения = КлючСтроки[ЭлементСписка.Представление]; Если Не ПолучатьПредставленияСсылок И ирОбщий.ЛиСсылкаНаОбъектБДЛкс(ПредставлениеЗначения) Тогда ПредставлениеЗначения = "" + ПредставлениеЗначения.УникальныйИдентификатор(); Иначе ПредставлениеЗначения = "" + ПредставлениеЗначения; КонецЕсли; ПредставленияКлюча = ПредставленияКлюча + ЭлементСписка.Представление + " = " + ПредставлениеЗначения; КонецЦикла; Иначе ПредставленияКлюча = "" + КлючСтроки; //СтруктураЧтения = Новый Структура("Владелец"); //Попытка // ЗаполнитьЗначенияСвойств(СтруктураЧтения, КлючСтроки); //Исключение // // Нет доступа //КонецПопытки; //Если ЗначениеЗаполнено(СтруктураЧтения.Владелец) Тогда // Если ПолучатьПредставленияСсылок Тогда // Владелец = Владелец.УникальныйИдентификатор(); // КонецЕсли; // ПредставленияКлюча = "[" + ПредставлениеКлючаСтрокиБДЛкс(Владелец) + "]" + ПредставленияКлюча; //КонецЕсли; КонецЕсли; Возврат ПредставленияКлюча; КонецФункции Функция ПеременныеОкруженияПроцессаЛкс() Shell = Новый COMОбъект("WScript.Shell"); ПеременныеОкружения = Shell.Environment("PROCESS"); Возврат ПеременныеОкружения; КонецФункции Процедура ПроверитьСоздатьКаталогПередСозданиемФайлаЛкс(Знач ИмяКонфигурационногоФайла) Экспорт Файл = Новый Файл(ИмяКонфигурационногоФайла); ФайлКаталога = Новый Файл(Файл.Путь); Если Не ФайлКаталога.Существует() Тогда СоздатьКаталог(ФайлКаталога.ПолноеИмя); КонецЕсли; КонецПроцедуры Функция КаталогПрограммныхФайловОСЛкс(x64 = Ложь) Экспорт ПеременныеОкружения = ПеременныеОкруженияПроцессаЛкс(); Если ирКэш.Это64битнаяОСЛкс() Тогда Если x64 Тогда ИмяПеременной = "ProgramW6432"; Иначе ИмяПеременной = "ProgramFiles(x86)"; КонецЕсли; Иначе ИмяПеременной = "ProgramFiles"; КонецЕсли; КаталогПрограммныхФайлов = ПеременныеОкружения.Item(ИмяПеременной); Возврат КаталогПрограммныхФайлов; КонецФункции Функция КаталогПеремещаемыхДанныхПриложенийЛкс() Экспорт ПеременныеОкружения = ПеременныеОкруженияПроцессаЛкс(); КаталогПеремещаемыхДанныхПриложений = ПеременныеОкружения.Item("Appdata"); Возврат КаталогПеремещаемыхДанныхПриложений; КонецФункции Функция ПараметрыСоединенияADOЭтойБДЛкс(выхСтрокаСвойств = "") Экспорт выхСтрокаСвойств = "ИмяСервера, ИмяБД, ИмяПользователя, Пароль, НаСервере"; Результат = Новый Структура(выхСтрокаСвойств); Результат.ИмяСервера = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяСервера"); Результат.ИмяБД = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяБД"); Результат.ИмяПользователя = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.ИмяПользователя"); НовыйПароль = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.Пароль"); Если НовыйПароль <> Неопределено Тогда Результат.Пароль = НовыйПароль.Получить(); КонецЕсли; Результат.НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере"); Возврат Результат; КонецФункции Функция ПроверитьСоединениеADOЭтойБДЛкс(Знач ИмяСервера = "", Знач ИмяБД = "", Знач ИмяПользователя = "", Знач Пароль = "", Знач НаСервере = Неопределено, ЗапрашиватьПараметрыПодключения = Истина) Экспорт Если ЗапрашиватьПараметрыПодключения Тогда #Если Клиент Тогда ФормаПодключения = ОткрытьФормуСоединенияСУБДЛкс(Истина); Если ФормаПодключения = Неопределено Тогда Возврат Ложь; КонецЕсли; Если НаСервере = Неопределено Тогда НаСервере = ФормаПодключения.НаСервере; КонецЕсли; #Иначе СообщитьЛкс("Необходимо с клиента выполнить проверку установки соединения с СУБД"); Возврат Ложь; #КонецЕсли КонецЕсли; Если НаСервере = Истина Тогда ЛиСоединениеУстановлено = ирСервер.ПроверитьСоединениеADOЭтойБДЛкс(ИмяСервера, ИмяБД, ИмяПользователя, Пароль); Иначе Соединение = ПолучитьСоединениеСУБД(ИмяСервера, ИмяБД, ИмяПользователя, Пароль); ЛиСоединениеУстановлено = Соединение <> Неопределено; КонецЕсли; Возврат ЛиСоединениеУстановлено; КонецФункции Функция ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(Знач ТекстЗапроса, Знач РежимОтладки = Ложь, Знач ПредставлениеЗапроса = "", Знач СмещениеГода = 2000, Знач ИспользованиеGWF = Истина, Знач НаСервере = Неопределено, СоединениеADO = Неопределено) Экспорт Если РежимОтладки Тогда ирОбщий.ОткрытьЗапросСУБДЛкс(ТекстЗапроса, ПредставлениеЗапроса); Возврат Неопределено; КонецЕсли; #Если Клиент Тогда Если НаСервере = Неопределено Тогда НаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ирПараметрыСоединенияСУБД.НаСервере"); КонецЕсли; #КонецЕсли Если НаСервере = Истина Тогда Таблица = ирСервер.ВыполнитьЗапросКЭтойБазеЧерезADOЛкс(ТекстЗапроса, СмещениеГода, ИспользованиеGWF); Иначе Если СоединениеADO = Неопределено Тогда СоединениеADO = ПолучитьСоединениеСУБД(); Если СоединениеADO = Неопределено Тогда Возврат Неопределено; КонецЕсли; КонецЕсли; //КомандаADO = Новый COMОбъект("ADODB.Command"); //КомандаADO.CommandTimeout = 30; // секунд //КомандаADO.CommandText = ТекстЗапроса; //КомандаADO.CommandType = 1; //КомандаADO.ActiveConnection = мСоединениеADO; //Если РежимОтладки = 1 Тогда // ирОбщий.ОтладитьЛкс(КомандаADO); // Возврат Неопределено; //КонецЕсли; //РезультатЗапроса = КомандаADO.Execute(); РезультатЗапроса = Новый COMОбъект("ADODB.Recordset"); adOpenStatic = 3; adLockOptimistic = 3; adCmdText = 1; РезультатЗапроса.Open(ТекстЗапроса, СоединениеADO, adOpenStatic, adLockOptimistic, adCmdText); Таблица = ирОбщий.РезультатЗапросаADOВТаблицуЗначенийОбщийЛкс(РезультатЗапроса, , , , СмещениеГода, ИспользованиеGWF); КонецЕсли; Возврат Таблица; КонецФункции //Функция получает на вход текст html, из которого создает COM объект HtmlFile //Параметры // ТекстHtml - Строка. Текст в формате HTML // ПереопределятьБазу - используется только при УстановитьБазу = Истина //Возвращаемое значение //COM объект с типом HtmlFile Функция ПолучитьHtmlFileИзТекстаHtmlЛкс(ТекстHtml = "", Результат = Неопределено) Экспорт Если Результат = Неопределено Тогда Результат = Новый COMОбъект("HtmlFile"); КонецЕсли; Результат.open("text/html"); Результат.write(ТекстHtml); Результат.close(); Возврат Результат; КонецФункции Функция ПолучитьHtmlТекстВыделенияЛкс(ДокументHtml) Экспорт Результат = ""; Если ДокументHtml.getSelection() <> Неопределено Тогда Выделение = ДокументHtml.getSelection(); Если Выделение.rangeCount > 0 Тогда ЭлементDiv = ДокументHtml.createElement("div"); Для Счетчик = 0 по Выделение.rangeCount - 1 Цикл ЭлементDiv.appendChild(Выделение.getRangeAt(Счетчик).cloneContents()); КонецЦикла; Результат = ЭлементDiv.innerHTML; КонецЕсли; ИначеЕсли ДокументHtml.selection <> Неопределено Тогда //Если ДокументHtml.selection.type = "Text" Тогда // Результат = ДокументHtml.selection.createRange().htmlText; //КонецЕсли; Результат = ДокументHtml.selection.CreateRange().htmlText; КонецЕсли; Возврат Результат; КонецФункции Функция ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим = Ложь, ПропускатьОшибки = Ложь, ТекстАлгоритма, ПараметраАлгоритмы = Неопределено, ПерейтиНаСервер = Ложь) Экспорт Если ПерейтиНаСервер Тогда ирСервер.ОбработатьПорциюСтрокТаблицыЛкс(АдресТаблицыЗначений, НачальныйНомерСтроки, РазмерПорции, МодальныйРежим, ПропускатьОшибки, ТекстАлгоритма, ПараметраАлгоритмы); Возврат Неопределено; КонецЕсли; #Если Сервер И Не Сервер Тогда ТаблицаЗначений = Новый ТаблицаЗначений; #КонецЕсли ТаблицаЗначений = ПолучитьИзВременногоХранилища(АдресТаблицыЗначений); КоличествоСтрокТаблицы = ТаблицаЗначений.Количество(); Для НомерСтроки = НачальныйНомерСтроки По Мин(НачальныйНомерСтроки + РазмерПорции - 1, ТаблицаЗначений.Количество()) Цикл СтрокаТаблицы = ТаблицаЗначений[НомерСтроки - 1]; Попытка ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритма,,, ПараметраАлгоритмы, СтрокаТаблицы, НомерСтроки = 1, НомерСтроки = КоличествоСтрокТаблицы); Исключение Если Не ПропускатьОшибки Тогда ВызватьИсключение КонецЕсли; ирОбщий.СообщитьСУчетомМодальностиЛкс("Строка результата №" + НомерСтроки + ": " + ОписаниеОшибки(), МодальныйРежим); КонецПопытки; КонецЦикла; КонецФункции Процедура ПаузаЛкс(ЧислоСекунд) Экспорт Попытка ВК = ирКэш.ВКОбщаяЛкс(); ВК.Sleep(ЧислоСекунд * 1000); Исключение // Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1820672/m/1930393 КонецПопытки; КонецПроцедуры Процедура ПаузаМиллисекундЛкс(Число) Экспорт Попытка ВК = ирКэш.ВКОбщаяЛкс(); ВК.Sleep(Число); Исключение // Антибаг платформы 8.3 https://partners.v8.1c.ru/forum/t/1820672/m/1930393 КонецПопытки; КонецПроцедуры Функция СеансКонфигуратора() Экспорт Сеансы = ПолучитьСеансыИнформационнойБазы(); Для Каждого Сеанс Из Сеансы Цикл Если СтрокиРавныЛкс(Сеанс.ИмяПриложения, "Designer") Тогда Возврат Сеанс; КонецЕсли; КонецЦикла; Возврат Неопределено; КонецФункции Функция ПростойРезультатЗапросаЛкс(ТекстЗапроса, АдресХранилища = Неопределено) Экспорт Если ЗначениеЗаполнено(ТекстЗапроса) Тогда ЗапросКоличестваСтрок = Новый Запрос(ТекстЗапроса); Результат = ЗапросКоличестваСтрок.Выполнить().Выгрузить()[0][0]; Иначе Результат = 0; КонецЕсли; Если ЗначениеЗаполнено(АдресХранилища) Тогда ПоместитьВоВременноеХранилище(Результат, АдресХранилища); КонецЕсли; КонецФункции Функция КоличествоСтрокВТаблицеБДЛкс(ОбъектМетаданных, АдресВременногоХранилища = "") Экспорт Если Не ЗначениеЗаполнено(ОбъектМетаданных) Тогда Возврат ""; КонецЕсли; ЗапросКоличестваСтрок = Новый Запрос("ВЫБРАТЬ КОЛИЧЕСТВО(*) ИЗ " + ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ОбъектМетаданных)); Попытка КоличествоСтрок = ЗапросКоличестваСтрок.Выполнить().Выгрузить()[0][0]; Исключение КоличествоСтрок = Неопределено; КонецПопытки; Если ЗначениеЗаполнено(АдресВременногоХранилища) Тогда ПоместитьВоВременноеХранилище(КоличествоСтрок, АдресВременногоХранилища); КонецЕсли; Возврат КоличествоСтрок; КонецФункции Процедура ВыделитьПервыеСтрокиДинамическогоСпискаЛкс(Знач ТабличноеПоле, Знач Количество, Знач НастройкиСписка = Неопределено) Экспорт ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ТабличноеПоле); ПолноеИмяТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле); СхемаКомпоновки = ирОбщий.ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицы,,,,,,, Количество); НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных; Если НастройкиСписка = Неопределено Тогда НастройкиСписка = НастройкиДинамическогоСпискаЛкс(ДинамическийСписок); КонецЕсли; ирОбщий.СкопироватьОтборЛюбойЛкс(НастройкаКомпоновки.Отбор, НастройкиСписка.Отбор); ирОбщий.СкопироватьПорядокЛюбойЛкс(НастройкаКомпоновки.Порядок, НастройкиСписка.Порядок); СтруктураКлюча = ирОбщий.СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,, Ложь); Для Каждого ЭлементСписка Из СтруктураКлюча Цикл ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, ЭлементСписка.Представление); КонецЦикла; КлючиСтрок = ирОбщий.СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(СхемаКомпоновки, НастройкаКомпоновки); ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КлючиСтрок.Количество(), "Выделение"); Для Каждого КлючСтроки Из КлючиСтрок Цикл ирОбщий.ОбработатьИндикаторЛкс(Индикатор); ВыделенныеСтроки.Добавить(ирОбщий.КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, КлючСтроки)); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если КлючиСтрок.Количество() <> Количество Тогда СообщитьЛкс("Выделены все отобранные элементы, но меньшим количеством " + XMLСтрока(КлючиСтрок.Количество())); КонецЕсли; Если ТипЗнч(ТабличноеПоле) = Тип("ТабличноеПоле") Тогда ТабличноеПоле.ОбновитьСтроки(); КонецЕсли; КонецПроцедуры // Если в текущей строке не достаточно полей для заполнения ключа записи регистра, то всегда возвращается набор записей, не смотря на параметр ДляРегистровСоздатьНаборЗаписей. // Параметры: // СтруктураКлюча - Структура - для ускорения в циклах; // ОбъектМД - ОбъектМетаданных - для ускорения в циклах; Функция КлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, Знач ТекущаяСтрока, ДляПодчиненногоРегистраСведенийНомерСтроки = Ложь, выхСтруктураЛокальногоКлючаСтроки = Неопределено, ОбъектыНаСервере = Неопределено, СтруктураКлюча = Неопределено, ОбъектМД = Неопределено) Экспорт ИмяПоляСсылка = ирОбщий.ПеревестиСтроку("Ссылка"); ИмяПоляНомерСтроки = ирОбщий.ПеревестиСтроку("НомерСтроки"); ИмяПоляПериод = ирОбщий.ПеревестиСтроку("Период"); ТипТаблицы = ТипТаблицыБДЛкс(ПолноеИмяТаблицы); Если СтруктураКлюча = Неопределено Тогда СтруктураКлюча = СтруктураКлючаТаблицыБДЛкс(ПолноеИмяТаблицы,,, ДляПодчиненногоРегистраСведенийНомерСтроки); КонецЕсли; #Если Сервер И Не Сервер Тогда СтруктураКлюча = Новый Структура; #КонецЕсли Если СтруктураКлюча.Свойство(ИмяПоляНомерСтроки) Тогда выхСтруктураЛокальногоКлючаСтроки = Новый Структура(ИмяПоляНомерСтроки); ИначеЕсли СтруктураКлюча.Свойство(ИмяПоляПериод) Тогда выхСтруктураЛокальногоКлючаСтроки = Новый Структура(ИмяПоляПериод); Иначе выхСтруктураЛокальногоКлючаСтроки = Неопределено; КонецЕсли; Если выхСтруктураЛокальногоКлючаСтроки <> Неопределено Тогда ЗаполнитьЗначенияСвойств(выхСтруктураЛокальногоКлючаСтроки, ТекущаяСтрока); КонецЕсли; Если Ложь Или ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Или ЛиКорневойТипЖурналаДокументовЛкс(ТипТаблицы) Тогда Если ирОбщий.ЛиТипСсылкиБДЛкс(ТипЗнч(ТекущаяСтрока), Ложь) Тогда КлючОбъекта = ТекущаяСтрока; Иначе КлючОбъекта = ТекущаяСтрока[ИмяПоляСсылка]; КонецЕсли; ПолноеИмяТаблицы = Метаданные.НайтиПоТипу(ТипЗнч(КлючОбъекта)).ПолноеИмя(); ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда КлючОбъекта = ТекущаяСтрока[ИмяПоляСсылка]; ИначеЕсли Ложь Или ЛиКорневойТипРегистраБДЛкс(ТипТаблицы, Ложь) //Или ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда Если Не ДляПодчиненногоРегистраСведенийНомерСтроки Тогда НайденыВсеПоляКлючаЗаписи = Истина; Для Каждого КлючИЗначение Из СтруктураКлюча Цикл Попытка Пустышка = ТекущаяСтрока[КлючИЗначение.Ключ]; Исключение НайденыВсеПоляКлючаЗаписи = Ложь; Прервать; КонецПопытки; КонецЦикла; КонецЕсли; ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока); Если Ложь Или ДляПодчиненногоРегистраСведенийНомерСтроки Или Не НайденыВсеПоляКлючаЗаписи Тогда //КлючОбъекта = ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицы, ТекущаяСтрока); УдаляемыеКлючи = Новый Массив; Для Каждого КлючИЗначение Из СтруктураКлюча Цикл Если ТипЗнч(КлючИЗначение.Значение) = Тип("ОписаниеТипов") Тогда УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ); КонецЕсли; КонецЦикла; Для Каждого УдаляемыйКлюч Из УдаляемыеКлючи Цикл СтруктураКлюча.Удалить(УдаляемыйКлюч); КонецЦикла; КлючОбъекта = ОбъектБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча,, Ложь, ОбъектыНаСервере); Иначе Если ОбъектМД = Неопределено Тогда ОбъектМД = ОбъектМДПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицы); КонецЕсли; МенеджерРегистра = Новый (ИмяТипаИзПолногоИмениМДЛкс(ОбъектМД.ПолноеИмя(), "Менеджер")); КлючОбъекта = МенеджерРегистра.СоздатьКлючЗаписи(СтруктураКлюча); КонецЕсли; ИначеЕсли ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока); КлючОбъекта = Новый Структура("ПолноеИмяТаблицы, Структура", ПолноеИмяТаблицы, СтруктураКлюча); Иначе КлючОбъекта = Неопределено; КонецЕсли; Возврат КлючОбъекта; КонецФункции Функция СообщенияПользователюОтФоновогоЗаданияЛкс(Знач ФоновоеЗадание, УдалятьПолученные = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ФоновоеЗадание = ФоновыеЗадания.Выполнить(); #КонецЕсли СообщенияПользователю = ФоновоеЗадание.ПолучитьСообщенияПользователю(УдалятьПолученные); // Антибаг платформы 8.2.14 Если СообщенияПользователю = Неопределено Тогда СообщенияПользователю = Новый Массив; КонецЕсли; Возврат СообщенияПользователю; КонецФункции Функция СоединитьСообщенияПользователюЛкс(Знач СообщенияОбъекта) Экспорт СообщенияОбработки = Новый ЗаписьXML; СообщенияОбработки.УстановитьСтроку(""); Для Каждого СообщениеОбъекта Из СообщенияОбъекта Цикл #Если Сервер И Не Сервер Тогда СообщениеОбъекта = Новый СообщениеПользователю; #КонецЕсли СообщенияОбработки.ЗаписатьБезОбработки(СообщениеОбъекта.Текст + Символы.ПС); КонецЦикла; ТекстСообщений = СообщенияОбработки.Закрыть(); Возврат ТекстСообщений; КонецФункции Функция ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(); #КонецЕсли ИдентификаторФоновогоЗадания = ФоновоеЗадание.УникальныйИдентификатор; #Если Клиент Тогда ПодключитьГлобальныйОбработчикОжиданияСПараметрамиЛкс("ОтменитьФоновоеЗаданиеОтложенноЛкс", Новый Структура("ИдентификаторФоновогоЗадания", ИдентификаторФоновогоЗадания)); СостояниеЛкс("Выполняем фоновое задание", Истина); #КонецЕсли Пока Истина Цикл #Если Клиент Тогда ОбработкаПрерыванияПользователя(); #КонецЕсли ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторФоновогоЗадания); ОбработатьСообщенияФоновогоЗаданияЛкс(ФоновоеЗадание); Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда Прервать; КонецЕсли; ПаузаМиллисекундЛкс(100); КонецЦикла; #Если Клиент Тогда ОтлючитьГлобальныйОбработчикОжиданияСПараметрамиЛкс(); #КонецЕсли Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда ИнформацияОбОшибке = ФоновоеЗадание.ИнформацияОбОшибке; ТекстСообщения = "Фоновое задание завершено аварийно! Описание ошибки получить не удалось"; #Если Клиент Тогда Если ИнформацияОбОшибке <> Неопределено Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Иначе СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание); КонецЕсли; #Иначе Если ИнформацияОбОшибке <> Неопределено Тогда ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); Иначе ВызватьИсключение ТекстСообщения; КонецЕсли; #КонецЕсли Результат = Ложь; Иначе Результат = Истина; КонецЕсли; Возврат Результат; КонецФункции Процедура ОбработатьСообщенияФоновогоЗаданияЛкс(Знач ФоновоеЗадание) Экспорт #Если Сервер И Не Сервер Тогда ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(); #КонецЕсли СообщенияПользователю = СообщенияПользователюОтФоновогоЗаданияЛкс(ФоновоеЗадание, Истина); Если СообщенияПользователю <> Неопределено Тогда ТекстСостояния = ""; ИндикаторПроцесса = ирОбщий.ПолучитьИндикаторПроцессаЛкс(); Для Каждого СообщениеПользователю Из СообщенияПользователю Цикл #Если Сервер И Не Сервер Тогда СообщениеПользователю = Новый СообщениеПользователю; #КонецЕсли СтруктураИндикатора = Неопределено; Если Найти(СообщениеПользователю.Текст, "#Индикатор-") = 1 Тогда СтруктураИндикатора = ВосстановитьОбъектИзСтрокиXMLЛкс(ирОбщий.СтрокаМеждуМаркерамиЛкс(СообщениеПользователю.Текст, "#Индикатор-")); КонецЕсли; Если СтруктураИндикатора = Неопределено Тогда СообщениеПользователю.Сообщить(); СообщитьЛкс(СообщениеПользователю.Текст,, Истина); Иначе ЗаполнитьЗначенияСвойств(ИндикаторПроцесса, СтруктураИндикатора); ТекстСостояния = ПолучитьТекстСостоянияИндикатораЛкс(ИндикаторПроцесса); КонецЕсли; КонецЦикла; ОсвободитьИндикаторПроцессаЛкс(); Если ЗначениеЗаполнено(ТекстСостояния) Тогда СостояниеЛкс(ТекстСостояния, Истина); КонецЕсли; КонецЕсли; КонецПроцедуры //////////////////////////////////////////////// // Многопоточность Функция НоваяСтруктураМногопоточнойОбработкиЛкс(Знач ИмяОбработчикаОбъекта, Знач МодульОбработчика, Знач ИмяОбработчикаРезультатаОбъекта, Знач КоличествоОбъектовВПорции, Знач ВыполнятьНаСервере, Знач КоличествоПотоков, Знач ОбщиеПараметрыОбработкиОдногоОбъекта = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда МодульОбработчика = Обработки.ирПодборИОбработкаОбъектов.Создать(); #КонецЕсли ПотокиОбработки = Новый ТаблицаЗначений; ПотокиОбработки.Колонки.Добавить("АдресРезультата"); ПотокиОбработки.Колонки.Добавить("СтрокиРезультатовОбъектов"); ПотокиОбработки.Колонки.Добавить("УникальныйИдентификатор"); ДоступностьМногопоточности = ВыполнятьНаСервере И Не ирКэш.ЭтоФайловаяБазаЛкс() И Не ирКэш.ЛиПортативныйРежимЛкс(); Для Счетчик = 1 По КоличествоПотоков Цикл Если Счетчик > 1 И Не ДоступностьМногопоточности Тогда Прервать; КонецЕсли; ПотокиОбработки.Добавить(); КонецЦикла; Если ОбщиеПараметрыОбработкиОдногоОбъекта = Неопределено Тогда ОбщиеПараметрыОбработкиОдногоОбъекта = Новый Структура(); Для Каждого МетаРеквизит Из МодульОбработчика.Метаданные().Реквизиты Цикл ЗначениеРеквизита = МодульОбработчика[МетаРеквизит.Имя]; Если Ложь Или ТипЗнч(ЗначениеРеквизита) = Тип("Строка") Или ТипЗнч(ЗначениеРеквизита) = Тип("Булево") Или ТипЗнч(ЗначениеРеквизита) = Тип("Дата") Или ТипЗнч(ЗначениеРеквизита) = Тип("Число") Тогда ОбщиеПараметрыОбработкиОдногоОбъекта.Вставить(МетаРеквизит.Имя, ЗначениеРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Статистика = Новый ТаблицаЗначений; Статистика.Колонки.Добавить("Длительность"); СтруктураПотоков = Новый Структура; СтруктураПотоков.Вставить("ПорцияОбъектов", Неопределено); СтруктураПотоков.Вставить("ПотокиОбработки", ПотокиОбработки); СтруктураПотоков.Вставить("Статистика", Статистика); СтруктураПотоков.Вставить("ФактическоеКоличествоПотоков", ПотокиОбработки.Количество()); СтруктураПотоков.Вставить("КоличествоОбъектовВПорции", КоличествоОбъектовВПорции); СтруктураПотоков.Вставить("МодульОбработчика", МодульОбработчика); СтруктураПотоков.Вставить("ОбщиеПараметрыОбработкиОдногоОбъекта", ОбщиеПараметрыОбработкиОдногоОбъекта); СтруктураПотоков.Вставить("ИмяОбработчикаРезультатаОбъекта", ИмяОбработчикаРезультатаОбъекта); СтруктураПотоков.Вставить("ИмяОбработчикаОбъекта", ИмяОбработчикаОбъекта); Возврат СтруктураПотоков; КонецФункции Процедура ДобавитьОбъектВОчередьМногопоточнойОбработкиЛкс(СтруктураПотоков, ПараметрыОбработкиОбъекта, СтрокиРезультатовОбъекта = Неопределено) Экспорт МодульОбработчика = СтруктураПотоков.МодульОбработчика; Если СтруктураПотоков.ФактическоеКоличествоПотоков = 1 Тогда РезультатОбработки = Вычислить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаОбъекта + "(ПараметрыОбработкиОбъекта)"); Выполнить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаРезультатаОбъекта + "(РезультатОбработки, СтрокиРезультатовОбъекта)"); Возврат; КонецЕсли; ПорцияОбъектов = СтруктураПотоков.ПорцияОбъектов; Если ПорцияОбъектов = Неопределено Тогда ПорцияОбъектов = Новый Структура("ПараметрыОбработкиОбъектов, СтрокиРезультатовОбъектов", Новый Массив, Новый Массив); СтруктураПотоков.ПорцияОбъектов = ПорцияОбъектов; КонецЕсли; ПорцияОбъектов.ПараметрыОбработкиОбъектов.Добавить(ПараметрыОбработкиОбъекта); ПорцияОбъектов.СтрокиРезультатовОбъектов.Добавить(СтрокиРезультатовОбъекта); Если ПорцияОбъектов.ПараметрыОбработкиОбъектов.Количество() < СтруктураПотоков.КоличествоОбъектовВПорции Тогда Возврат; КонецЕсли; ЗапуститьПотокОбработкиПорцииЛкс(СтруктураПотоков); КонецПроцедуры Процедура ОжидатьЗавершенияВсехПотоковОбработкиЛкс(СтруктураПотоков) Экспорт Если СтруктураПотоков.ПорцияОбъектов <> Неопределено Тогда ЗапуститьПотокОбработкиПорцииЛкс(СтруктураПотоков); КонецЕсли; Пока ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков, Ложь).Количество() < СтруктураПотоков.ПотокиОбработки.Количество() Цикл ПаузаМиллисекундЛкс(10); КонецЦикла; Если СтруктураПотоков.ПотокиОбработки.Количество() > 1 Тогда СообщитьСтатистикуПорцийСРекомендациями(СтруктураПотоков, Истина); КонецЕсли; КонецПроцедуры Процедура СообщитьСтатистикуПорцийСРекомендациями(Знач СтруктураПотоков, ВыводитьСтатистикуОбязательно = Ложь) Статистика = СтруктураПотоков.Статистика; СредняяДлительностьПорции = Окр(Статистика.Итог("Длительность") / Статистика.Количество(), 1); ТекстСообщения = "Обработано " + Статистика.Количество() + " порций. Средняя длительность порции - " + СредняяДлительностьПорции + " сек"; Если СредняяДлительностьПорции > 5 Тогда ТекстСообщения = ТекстСообщения + ". Рекомендуется уменьшить количество объектов в порции."; ИначеЕсли СредняяДлительностьПорции < 1 Тогда ТекстСообщения = ТекстСообщения + ". Рекомендуется увеличить количество объектов в порции."; ИначеЕсли Не ВыводитьСтатистикуОбязательно Тогда Возврат; КонецЕсли; ирОбщий.СообщитьЛкс(ТекстСообщения); КонецПроцедуры Процедура ЗапуститьПотокОбработкиПорцииЛкс(Знач СтруктураПотоков) //ФоновыеЗадания.ОжидатьЗавершенияВыполнения() // Не позволяет ждать одного из Пока Истина Цикл НомераСвободныхПотоков = ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков); Если НомераСвободныхПотоков.Количество() > 0 Тогда Прервать; КонецЕсли; ПаузаМиллисекундЛкс(5); КонецЦикла; ПорцияОбъектов = СтруктураПотоков.ПорцияОбъектов; НомерСвободногоПотока = НомераСвободныхПотоков[0]; ПотокиОбработки = СтруктураПотоков.ПотокиОбработки; ПотокиОбработки[НомерСвободногоПотока].СтрокиРезультатовОбъектов = ПорцияОбъектов.СтрокиРезультатовОбъектов; АдресРезультата = ПоместитьВоВременноеХранилище(Null); ПараметрыЗадания = Новый Массив(5); ПараметрыЗадания[0] = СтруктураПотоков.МодульОбработчика.Метаданные().ПолноеИмя(); ПараметрыЗадания[1] = СтруктураПотоков.ИмяОбработчикаОбъекта; ПараметрыЗадания[2] = СтруктураПотоков.ОбщиеПараметрыОбработкиОдногоОбъекта; ПараметрыЗадания[3] = ПорцияОбъектов.ПараметрыОбработкиОбъектов; ПараметрыЗадания[4] = АдресРезультата; #Если Сервер И Не Сервер Тогда ирОбщий.ОбработатьПорциюОбъектовЛкс(); #КонецЕсли ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ОбработатьПорциюОбъектовЛкс", ПараметрыЗадания, НомерСвободногоПотока, "Поток обработки объектов " + НомерСвободногоПотока); ПотокиОбработки[НомерСвободногоПотока].АдресРезультата = АдресРезультата; ПотокиОбработки[НомерСвободногоПотока].УникальныйИдентификатор = ФоновоеЗадание.УникальныйИдентификатор; СтруктураПотоков.ПорцияОбъектов = Неопределено; КонецПроцедуры Процедура ОбработатьПорциюОбъектовЛкс(ПолноеИмяМД, ИмяОбработчикаОбъекта, ОбщиеПараметрыОбработки, ПараметрыМетода, АдресРезультата) Экспорт Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирПодборИОбработкаОбъектов.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); РезультатПорции = Новый Массив; Для Каждого ПараметрыВызова Из ПараметрыМетода Цикл РезультатПорции.Добавить(Вычислить("Обработка." + ИмяОбработчикаОбъекта + "(ПараметрыВызова)")); КонецЦикла; ПоместитьВоВременноеХранилище(РезультатПорции, АдресРезультата); КонецПроцедуры Функция ОбновитьПотокиОбработкиОбъектовЛкс(СтруктураПотоков, ОбновлятьДоПервогоСвободного = Истина) ПотокиОбработки = СтруктураПотоков.ПотокиОбработки; Статистика = СтруктураПотоков.Статистика; НомераСвободныхПотоков = Новый Массив; МодульОбработчика = СтруктураПотоков.МодульОбработчика; Для Каждого ПотокОбработки Из СтруктураПотоков.ПотокиОбработки Цикл Если ЗначениеЗаполнено(ПотокОбработки.УникальныйИдентификатор) Тогда ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ПотокОбработки.УникальныйИдентификатор); СообщенияПользователю = СообщенияПользователюОтФоновогоЗаданияЛкс(ФоновоеЗадание, Истина); Для Каждого СообщениеПользователю Из СообщенияПользователю Цикл СообщениеПользователю.Сообщить(); КонецЦикла; Если ФоновоеЗадание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда РезультатПорции = ПолучитьИзВременногоХранилища(ПотокОбработки.АдресРезультата); Если Статистика <> Неопределено Тогда СтрокаСтатистики = Статистика.Добавить(); СтрокаСтатистики.Длительность = ФоновоеЗадание.Конец - ФоновоеЗадание.Начало; Если Статистика.Количество() = 4 Тогда СообщитьСтатистикуПорцийСРекомендациями(СтруктураПотоков); КонецЕсли; КонецЕсли; Иначе РезультатОбработки = "Фоновое задание отменено"; Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда РезультатОбработки = ПодробноеПредставлениеОшибки(ФоновоеЗадание.ИнформацияОбОшибке); КонецЕсли; ВызватьИсключение РезультатОбработки; //РезультатПорции = Новый Массив; //ТекстСообщений = ирОбщий.СоединитьСообщенияПользователюЛкс(СообщенияПользователю); //Для Счетчик = 1 По ПотокОбработки.СтрокиРезультатовОбъектов.Количество() Цикл // РезультатПорции.Добавить(Новый Структура("Результат, ТекстСообщений", РезультатОбработки, ТекстСообщений)); //КонецЦикла; КонецЕсли; Для ИндексОбъектаПорции = 0 По ПотокОбработки.СтрокиРезультатовОбъектов.ВГраница() Цикл РезультатОбработки = РезультатПорции[ИндексОбъектаПорции]; СтрокиРезультатов = ПотокОбработки.СтрокиРезультатовОбъектов[ИндексОбъектаПорции]; Выполнить("МодульОбработчика." + СтруктураПотоков.ИмяОбработчикаРезультатаОбъекта + "(РезультатОбработки, СтрокиРезультатов)"); ПотокОбработки.СтрокиРезультатовОбъектов[ИндексОбъектаПорции] = СтрокиРезультатов; КонецЦикла; ПотокОбработки.УникальныйИдентификатор = Неопределено; КонецЕсли; КонецЕсли; Если ПотокОбработки.УникальныйИдентификатор = Неопределено Тогда НомерСвободногоПотока = СтруктураПотоков.ПотокиОбработки.Индекс(ПотокОбработки); НомераСвободныхПотоков.Добавить(НомерСвободногоПотока); КонецЕсли; КонецЦикла; Возврат НомераСвободныхПотоков; КонецФункции //////////////////////////////////////////////// // Групповые обработки с возможностью фонового выполнения Процедура ОчиститьДвиженияДокументаЛкс(Знач Ссылка, Знач ВключаяПоследовательности = Ложь, Знач ВключаяПерерасчеты = Ложь) Экспорт ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(Ссылка.Метаданные(), ВключаяПоследовательности, ВключаяПерерасчеты); Для Каждого МетаРегистр из ОбъектыМД Цикл ПолноеИмяМД = МетаРегистр.ПолноеИмя(); ИмяТаблицыБДРегистра = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД); ИмяПоляОтбора = ирОбщий.ИмяПоляОтбораПодчиненногоНабораЗаписейЛкс(ИмяТаблицыБДРегистра); СтруктураНаборЗаписей = ирОбщий.ОбъектБДПоКлючуЛкс(ПолноеИмяМД, Новый Структура(ИмяПоляОтбора, Ссылка),, Ложь); ирОбщий.ЗаписатьОбъектЛкс(СтруктураНаборЗаписей.Методы); КонецЦикла; КонецПроцедуры Функция ПодборИОбработкаОбъектов_ВыполнитьОбработкуЛкс(Знач ИмяОбработки, ОбщиеПараметрыОбработки, Знач НастройкаОбработки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт #Если Клиент Тогда Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда ОбщиеПараметрыОбработки.Удалить("Компоновщик"); ФормаРезультата = ФормаРезультатаФоновогоЗаданияЛкс(); АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультата.УникальныйИдентификатор); ПараметрыЗадания = Новый Массив; ПараметрыЗадания.Добавить(ИмяОбработки); // ИмяОбработки ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); // ОбщиеПараметрыОбработки ПараметрыЗадания.Добавить(НастройкаОбработки); // НастройкаОбработки ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ПодборИОбработкаОбъектов_ВыполнитьОбработкуЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы(), Метаданные.Обработки.ирПодборИОбработкаОбъектов.Представление() + ". " + ИмяОбработки); Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда // Антибаг 8.3.16- В обычном приложении в клиент-серверном режиме из временного хранилища иногда возвращается Неопределено https://partners.v8.1c.ru/forum/t/1768363/m/1768363, http://www.hostedredmine.com/issues/884756 ФормаРезультата.ОбновитьВременноеХранилище(АдресРезультата); ОбщиеПараметрыОбработки = ПолучитьИзВременногоХранилища(АдресРезультата); Результат = ОбщиеПараметрыОбработки.Результат; КонецЕсли; Иначе #КонецЕсли Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирПодборИОбработкаОбъектов"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирПодборИОбработкаОбъектов.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); НастройкаОбработки.Вставить("ИмяОбработки", ИмяОбработки); Если ЗначениеЗаполнено(ОбщиеПараметрыОбработки.Запрос.Текст) Тогда Запрос = Новый Запрос; Запрос.Текст = ОбщиеПараметрыОбработки.Запрос.Текст; ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ОбщиеПараметрыОбработки.Запрос.Параметры, Запрос.Параметры); Обработка.мЗапрос = Запрос; КонецЕсли; Результат = Обработка.ВыполнитьГрупповуюОбработку(НастройкаОбработки); ЗаполнитьЗначенияСвойств(ОбщиеПараметрыОбработки, Обработка); Если ЗначениеЗаполнено(АдресРезультата) Тогда ОбщиеПараметрыОбработки.Вставить("Результат", Результат); ПоместитьВоВременноеХранилище(ОбщиеПараметрыОбработки, АдресРезультата); КонецЕсли; #Если Клиент Тогда КонецЕсли; Оповестить("ЗаписанОбъект", , ЭтаФорма); #КонецЕсли Возврат Результат; КонецФункции Функция ПоискДублейИЗаменаСсылок_ВыполнитьЗаменуЛкс(Знач ОбщиеПараметрыОбработки, Знач СоответствиеЗамен, Знач НайденныеСсылки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт #Если Клиент Тогда Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда ФормаРезультатФоновогоЗадания = ФормаРезультатаФоновогоЗаданияЛкс(); АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор); ПараметрыЗадания = Новый Массив; ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); ПараметрыЗадания.Добавить(СоответствиеЗамен); ПараметрыЗадания.Добавить(НайденныеСсылки); ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ПоискДублейИЗаменаСсылок_ВыполнитьЗаменуЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы(), Метаданные.Обработки.ирПоискДублейИЗаменаСсылок.Представление()); Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда // Антибаг 8.3 В обычной форме в клиент-серверном режиме из временного хранилища возвращается Неопределено https://partners.v8.1c.ru/forum/t/1768363/m/1768363 ФормаРезультатФоновогоЗадания.ОбновитьВременноеХранилище(АдресРезультата); Результат = ПолучитьИзВременногоХранилища(АдресРезультата); КонецЕсли; Иначе #КонецЕсли Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирПоискДублейИЗаменаСсылок"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирПоискДублейИЗаменаСсылок.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); Обработка.ВыполнитьЗаменуЭлементов(СоответствиеЗамен, НайденныеСсылки); Результат = Новый Структура; Результат.Вставить("ИзмененныеПроведенныеДокументы", Обработка.ИзмененныеПроведенныеДокументы.Выгрузить()); Результат.Вставить("СоответствиеЗамен", СоответствиеЗамен); Если ЗначениеЗаполнено(АдресРезультата) Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецЕсли; #Если Клиент Тогда КонецЕсли; Оповестить("ЗаписанОбъект", , ЭтаФорма); #КонецЕсли Возврат Результат; КонецФункции Функция УдалениеОбъектовСКонтролемСсылок_УдалитьОбъектыЛкс(Знач ОбщиеПараметрыОбработки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт #Если Клиент Тогда Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда ФормаРезультатФоновогоЗадания = ФормаРезультатаФоновогоЗаданияЛкс(); АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор); ПараметрыЗадания = Новый Массив; ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.УдалениеОбъектовСКонтролемСсылок_УдалитьОбъектыЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы(), Метаданные.Обработки.ирУдалениеОбъектовСКонтролемСсылок.Представление()); Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда // Антибаг 8.3 В обычной форме в клиент-серверном режиме из временного хранилища возвращается Неопределено https://partners.v8.1c.ru/forum/t/1768363/m/1768363 ФормаРезультатФоновогоЗадания.ОбновитьВременноеХранилище(АдресРезультата); Результат = ПолучитьИзВременногоХранилища(АдресРезультата); КонецЕсли; Иначе #КонецЕсли Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирУдалениеОбъектовСКонтролемСсылок"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирУдалениеОбъектовСКонтролемСсылок.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); Обработка.УдаляемыеОбъекты.Загрузить(ОбщиеПараметрыОбработки.УдаляемыеОбъекты); Обработка.УдалитьОбъектыЛкс(); Результат = Новый Структура; Результат.Вставить("УдаляемыеОбъекты", Обработка.УдаляемыеОбъекты.Выгрузить()); Если ЗначениеЗаполнено(АдресРезультата) Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецЕсли; #Если Клиент Тогда КонецЕсли; Оповестить("ЗаписанОбъект", , ЭтаФорма); #КонецЕсли Возврат Результат; КонецФункции Функция ЗагрузкаТабличныхДанных_ЗагрузитьЛкс(Знач ОбщиеПараметрыОбработки, Знач Записывать, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт #Если Клиент Тогда Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда ФормаРезультатФоновогоЗадания = ФормаРезультатаФоновогоЗаданияЛкс(); АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор); ПараметрыЗадания = Новый Массив; ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); ПараметрыЗадания.Добавить(Записывать); ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗагрузкаТабличныхДанных_ЗагрузитьЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы(), Метаданные.Обработки.ирЗагрузкаТабличныхДанных.Представление()); Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда // Антибаг 8.3 В обычной форме в клиент-серверном режиме из временного хранилища возвращается Неопределено https://partners.v8.1c.ru/forum/t/1768363/m/1768363 ФормаРезультатФоновогоЗадания.ОбновитьВременноеХранилище(АдресРезультата); Результат = ПолучитьИзВременногоХранилища(АдресРезультата); КонецЕсли; Иначе #КонецЕсли Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирЗагрузкаТабличныхДанных"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирЗагрузкаТабличныхДанных.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); Обработка.ЗагрузитьВТаблицуБДИзТаблицыЗначений(Записывать); Результат = Новый Структура; Результат.Вставить("ТаблицаБД", Обработка.ТаблицаБД); Результат.Вставить("КоличествоУспешно", Обработка.КоличествоУспешно); Результат.Вставить("КоличествоНеуспешно", Обработка.КоличествоНеуспешно); Если ЗначениеЗаполнено(АдресРезультата) Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецЕсли; #Если Клиент Тогда КонецЕсли; Оповестить("ЗаписанОбъект", , ЭтаФорма); #КонецЕсли Возврат Результат; КонецФункции Функция ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьВыгрузкуЛкс(Знач ОбщиеПараметрыОбработки, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт #Если Клиент Тогда Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда ФормаРезультатФоновогоЗадания = ФормаРезультатаФоновогоЗаданияЛкс(); АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор); ПараметрыЗадания = Новый Массив; ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьВыгрузкуЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы()); Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда // Антибаг 8.3 В обычной форме в клиент-серверном режиме из временного хранилища возвращается Неопределено https://partners.v8.1c.ru/forum/t/1768363/m/1768363 ФормаРезультатФоновогоЗадания.ОбновитьВременноеХранилище(АдресРезультата); Результат = ПолучитьИзВременногоХранилища(АдресРезультата); Результат.Записать(ОбщиеПараметрыОбработки.ИмяФайла); КонецЕсли; Иначе #КонецЕсли Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирВыгрузкаЗагрузкаДанныхЧерезФайл"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирВыгрузкаЗагрузкаДанныхЧерезФайл.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); Результат = Обработка.ВыполнитьВыгрузку(); #Если Сервер И Не Сервер Тогда Результат = Новый ДвоичныеДанные; #КонецЕсли Если ЗначениеЗаполнено(АдресРезультата) Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); Иначе Результат.Записать(Обработка.ИмяФайла); КонецЕсли; #Если Клиент Тогда КонецЕсли; #КонецЕсли Возврат Результат; КонецФункции Функция ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьЗагрузкуЛкс(Знач ОбщиеПараметрыОбработки, Знач ДвоичныеДанные = Неопределено, Знач АдресРезультата = Неопределено, Знач ЭтаФорма = Неопределено) Экспорт #Если Клиент Тогда Если ДвоичныеДанные = Неопределено Тогда ДвоичныеДанные = Новый ДвоичныеДанные(ОбщиеПараметрыОбработки.ИмяФайла); КонецЕсли; Если ОбщиеПараметрыОбработки.ВыполнятьНаСервере Тогда ФормаРезультатФоновогоЗадания = ФормаРезультатаФоновогоЗаданияЛкс(); //ОбщиеПараметрыОбработки.ИмяФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор); АдресРезультата = ПоместитьВоВременноеХранилище(Null, ФормаРезультатФоновогоЗадания.УникальныйИдентификатор); ПараметрыЗадания = Новый Массив; ПараметрыЗадания.Добавить(ОбщиеПараметрыОбработки); ПараметрыЗадания.Добавить(ДвоичныеДанные); ПараметрыЗадания.Добавить(АдресРезультата); // АдресРезультата ПараметрыЗадания.Добавить(Неопределено); // ЭтаФорма ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ВыгрузкаЗагрузкаДанныхЧерезФайл_ВыполнитьЗагрузкуЛкс", ПараметрыЗадания, НомерСеансаИнформационнойБазы()); Если ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание, ЭтаФорма) Тогда // Антибаг 8.3 В обычной форме в клиент-серверном режиме из временного хранилища возвращается Неопределено https://partners.v8.1c.ru/forum/t/1768363/m/1768363 ФормаРезультатФоновогоЗадания.ОбновитьВременноеХранилище(АдресРезультата); Результат = ПолучитьИзВременногоХранилища(АдресРезультата); КонецЕсли; Иначе #КонецЕсли Обработка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирВыгрузкаЗагрузкаДанныхЧерезФайл"); #Если Сервер И Не Сервер Тогда Обработка = Обработки.ирВыгрузкаЗагрузкаДанныхЧерезФайл.Создать() #КонецЕсли ЗаполнитьЗначенияСвойств(Обработка, ОбщиеПараметрыОбработки); Обработка.ИмяФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные); Результат = Обработка.ВыполнитьЗагрузку(); Если ЗначениеЗаполнено(АдресРезультата) Тогда ПоместитьВоВременноеХранилище(Результат, АдресРезультата); КонецЕсли; #Если Клиент Тогда КонецЕсли; Оповестить("ЗаписанОбъект", , ЭтаФорма); #КонецЕсли Возврат Результат; КонецФункции //////////////////////////////////////////////// #КонецЕсли #Если Не ТонкийКлиент И Не ВебКлиент И Не МобильныйКлиент И Клиент Тогда Функция ОткрытьСистемнуюФормуОтчетПоВерсииЛкс(Данные, НомерВерсии) Экспорт Попытка ОткрытьФорму("sysForm:DataHistoryVersionDataRuForm", Новый Структура("Данные, НомерВерсии", Данные, НомерВерсии)); Исключение ОписаниеОшибки = ОписаниеОшибки(); ИсследоватьВерсиюОбъектаДанныхЛкс(Данные, НомерВерсии); КонецПопытки; КонецФункции Процедура ИсследоватьВерсиюОбъектаДанныхЛкс(Знач Данные, Знач НомерВерсии) Экспорт #Если ВебКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #Иначе ИсторияДанныхМоя = Вычислить("ИсторияДанных"); #Если Сервер И Не Сервер Тогда ИсторияДанныхМоя = ИсторияДанных; #КонецЕсли Структура = ИсторияДанныхМоя.ПолучитьДанныеВерсии(Данные, НомерВерсии); ИсследоватьЛкс(Структура); #КонецЕсли КонецПроцедуры Функция ОткрытьСистемнуюФормуСписокВерсийЛкс(Данные, НомерВерсии) Экспорт ОткрытьФорму("sysForm:DataHistoryVersions", Новый Структура("Data, VersionNumber", Данные, НомерВерсии)); КонецФункции Функция ОткрытьСистемнуюФормуСравненияВерсийЛкс(Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения) Экспорт ОткрытьФорму("sysForm:DataHistoryVersionDifferenecesRuForm", Новый Структура("Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения", Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения)); КонецФункции Процедура ИсследоватьСравнениеВерсийЛкс(Знач Данные, Знач НомерВерсииПослеИзменения, Знач НомерВерсииДоИзменения) Экспорт #Если ВебКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #Иначе ИсторияДанныхМоя = Вычислить("ИсторияДанных"); #Если Сервер И Не Сервер Тогда ИсторияДанныхМоя = ИсторияДанных; #КонецЕсли Структура = ИсторияДанныхМоя.ПолучитьРазличияВерсий(Данные, НомерВерсииПослеИзменения, НомерВерсииДоИзменения); ИсследоватьЛкс(Структура); #КонецЕсли КонецПроцедуры Функция ФормаРезультатаФоновогоЗаданияЛкс() Экспорт // Управляемые формы так создавать нельзя! // http://www.hostedredmine.com/issues/874998 //мПлатформа = ирКэш.Получить(); //#Если Сервер И Не Сервер Тогда // мПлатформа = Обработки.ирПлатформа.Создать(); //#КонецЕсли //ФормаРезультатФоновогоЗадания = мПлатформа.ПолучитьФорму("РезультатФоновогоЗадания"); ФормаРезультатФоновогоЗадания = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.РезультатФоновогоЗадания"); Возврат ФормаРезультатФоновогоЗадания; КонецФункции Процедура ОтменитьФоновоеЗаданиеОтложенноЛкс(Параметры) Экспорт ОтменитьФоновоеЗаданиеЛкс(Параметры.ИдентификаторФоновогоЗадания); КонецПроцедуры Процедура ОтменитьФоновоеЗаданиеЛкс(Знач ИдентификаторФоновогоЗадания) Экспорт Если Не ЗначениеЗаполнено(ИдентификаторФоновогоЗадания) Тогда Возврат; КонецЕсли; ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторФоновогоЗадания); Если ФоновоеЗадание <> Неопределено И ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда ФоновоеЗадание.Отменить(); ПодключитьГлобальныйОбработчикОжиданияСПараметрамиЛкс("ПроверитьОтмененноеФоновоеЗаданиеОтложенноЛкс", Новый Структура("Идентификатор", ИдентификаторФоновогоЗадания), 2); КонецЕсли; КонецПроцедуры Процедура ПроверитьОтмененноеФоновоеЗаданиеОтложенноЛкс(Параметры) Экспорт ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(Параметры.Идентификатор); Если ФоновоеЗадание <> Неопределено И ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда СообщитьЛкс("Фоновое задание """ + ФоновоеЗадание.Наименование + """, которому была отправлена команда отмены, до сих пор выполняется", СтатусСообщения.Внимание); КонецЕсли; КонецПроцедуры Функция ЗагрузитьТабличныйДокументИнтерактивноЛкс(Знач ТабличныйДокумент = Неопределено, выхПолноеИмяФайла = "") Экспорт Если ТабличныйДокумент = Неопределено Тогда ТабличныйДокумент = Новый ТабличныйДокумент; КонецЕсли; ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла"; ДиалогВыбораФайла.Фильтр = "Табличный документ (*.mxl)|*.mxl|Лист Excel (*.xls)|*.xls|Лист Excel (*.xlsx)|*.xlsx|Open document (*.ods)|*.ods|Текстовый документ (*.txt)|*.txt|Текстовый документ (*.csv)|*.csv|dBase III (*.dbf)|*.dbf|"; Если ДиалогВыбораФайла.Выбрать() Тогда выхПолноеИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла; ФайлНаДиске = Новый Файл(выхПолноеИмяФайла); Если Ложь Или ирОбщий.СтрокиРавныЛкс(ФайлНаДиске.Расширение, ".txt") Или ирОбщий.СтрокиРавныЛкс(ФайлНаДиске.Расширение, ".csv") Тогда ПрочитатьТабличныйДокументИзТекстаЛкс(ТабличныйДокумент, выхПолноеИмяФайла); ИначеЕсли нРег(ФайлНаДиске.Расширение) = ".dbf" Тогда ПрочитатьТабличныйДокументИзDBFЛкс(ТабличныйДокумент, выхПолноеИмяФайла); Иначе ТабличныйДокумент.Прочитать(выхПолноеИмяФайла); КонецЕсли; Иначе ТабличныйДокумент = Неопределено; КонецЕсли; Возврат ТабличныйДокумент; КонецФункции Функция СохранитьТабличныйДокументИнтерактивноЛкс(Знач ТабличныйДокументИсточник, выхПолноеИмяФайла = "", Знач СразуОткрыть = Ложь, Знач УстанавливатьПризнакСодержитЗначение = Ложь) Экспорт Если Не ЗначениеЗаполнено(выхПолноеИмяФайла) Тогда ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение); ДиалогВыбораФайла.Заголовок = "Записать табличный документ в файл"; ДиалогВыбораФайла.Фильтр = "Табличный документ (*.mxl)|*.mxl|Лист Excel (*.xls)|*.xls|Лист Excel (*.xlsx)|*.xlsx|Open document (*.ods)|*.ods|Текстовый документ (*.txt)|*.txt"; Если Не ДиалогВыбораФайла.Выбрать() Тогда Возврат Ложь; КонецЕсли; выхПолноеИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла; КонецЕсли; ТабличныйДокумент = Новый ТабличныйДокумент; ТабличныйДокумент.ВставитьОбласть(ТабличныйДокументИсточник.Область(),,, Ложь); Файл = Новый файл(выхПолноеИмяФайла); ТипФайла = ТипФайлаТабличногоДокумента.MXL; Если ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".xls") Тогда ТипФайла = ТипФайлаТабличногоДокумента.XLS; Если УстанавливатьПризнакСодержитЗначение Тогда УстановитьПризнакСодержитЗначение(ТабличныйДокумент); КонецЕсли; ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".xlsx") Тогда ТипФайла = ТипФайлаТабличногоДокумента.XLSX; Если УстанавливатьПризнакСодержитЗначение Тогда УстановитьПризнакСодержитЗначение(ТабличныйДокумент); КонецЕсли; ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".ods") Тогда ТипФайла = ТипФайлаТабличногоДокумента.ODS; ИначеЕсли ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".txt") Тогда ТипФайла = ТипФайлаТабличногоДокумента.TXT; КонецЕсли; Попытка ТабличныйДокумент.Записать(выхПолноеИмяФайла, ТипФайла); Исключение СообщитьЛкс(ОписаниеОшибки()); Возврат Ложь; КонецПопытки; Если Не СразуОткрыть И Не ирОбщий.СтрокиРавныЛкс(Файл.Расширение, ".mxl") Тогда Ответ = Вопрос("Хотите сразу открыть сохраненный файл в сопоставленном приложении?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да); СразуОткрыть = Ответ = КодВозвратаДиалога.Да; КонецЕсли; Если СразуОткрыть Тогда ЗапуститьПриложение(выхПолноеИмяФайла); КонецЕсли; Возврат Истина; КонецФункции Процедура УстановитьПризнакСодержитЗначение(ТабличныйДокумент) #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли // Проставим свойство СодержитЗначение, чтобы при открытии в EXCEL в строках типа "000534235" не устанавливался формат "Почтовый" // и не пропадали лидирующие нули при входе в режим редактирования ячейки Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл Для ТекущаяСтрока = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка); ОбластьЯчейки.СодержитЗначение = Истина; КонецЦикла; КонецЦикла; КонецПроцедуры Функция ПодтверждениеОперацииСУБДЛкс() Экспорт ИмяБД = ПолучитьСоединениеСУБД().DefaultDatabase; Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы " + ИмяБД + " и нарушение лицензионного соглашения 1С?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да; КонецФункции // РежимИмяСиноним - Булево - Истина - Имя Процедура НастроитьАвтоТабличноеПолеДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним = Ложь, РазрешитьСортировку = Истина, ПредельноеКоличествоВидимыхКолонок = 30) Экспорт // Антибаг платформы 8.2-8.3 для регистра бухгалтерии https://partners.v8.1c.ru/forum/t/1372055/m/1372055 ДинамическийСписок = ирОбщий.ДанныеЭлементаФормыЛкс(ОсновнойЭУ); ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ДинамическийСписок)); ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ПолноеИмяТаблицы = ирОбщий.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД); ТипТаблицы = ирОбщий.ТипТаблицыБДЛкс(ПолноеИмяТаблицы); КорневойТип = ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМД); КорневойТип = ПеревестиВРусский(КорневойТип); //СтруктураХраненияПолей = ирКэш.ПолучитьСтруктуруХраненияБДЛкс().НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля; ФильтрМетаданных = Новый Массив; ФильтрМетаданных.Добавить(ПолноеИмяМД); НуженПеревод = Неопределено; СтруктураХраненияТаблиц = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных); ПеревестиКолонкиСтруктурыХраненияБДТаблицыЛкс(СтруктураХраненияТаблиц, НуженПеревод); СтруктураХраненияТаблицы = СтруктураХраненияТаблиц.НайтиСтроки(Новый Структура("Назначение, Метаданные", ПеревестиСтроку("Основная"), ПолноеИмяМД))[0]; СтруктураХраненияПолей = СтруктураХраненияТаблицы.Поля; ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(СтруктураХраненияПолей, НуженПеревод); ВерсияПлатформы = ирКэш.НомерВерсииПлатформыЛкс(); Если КорневойТип <> "РегистрБухгалтерии" Тогда ОсновнойЭУ.СоздатьКолонки(); КонецЕсли; Попытка КолонкиСписка = ОсновнойЭУ.Значение.Колонки; Исключение // Перечисление КонецПопытки; КолонкиТП = ОсновнойЭУ.Колонки; Колонка = КолонкиТП.Найти("Картинка"); Если Колонка = Неопределено Тогда КолонкаКартинки = КолонкиТП.Добавить("Картинка"); КолонкаКартинки.ОтображатьСтандартнуюКартинку = Истина; КолонкаКартинки.Ширина = 3; КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять; КолонкаКартинки.ТекстШапки = ""; КонецЕсли; Попытка НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка; Исключение НастройкаПорядка = Неопределено; КонецПопытки; КоличествоВидимыхКолонок = 0; Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл Колонка = КолонкиТП.Найти(ЭлементОтбора.Имя); Если Колонка = Неопределено Тогда // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1002521#1002521 Если Ложь Или Найти(ЭлементОтбора.Имя, "ВидСубконтоДт") = 1 Или Найти(ЭлементОтбора.Имя, "ВидСубконтоКт") = 1 Тогда Продолжить; КонецЕсли; Попытка КолонкиСписка.Добавить(ЭлементОтбора.Имя, ЭлементОтбора.Имя <> ПеревестиСтроку("Ссылка") И ЭлементОтбора.Имя <> ПеревестиСтроку("ЭтоГруппа")); Исключение // Сюда попадает например элемент отбора от критерия отбора Продолжить; КонецПопытки; Колонка = КолонкиТП.Добавить(); КонецЕсли; //Колонка.ТекстШапки = ЭлементОтбора.Представление; Если КорневойТип <> "Перечисление" Тогда ДанныеПодключены = Ложь; Если Истина И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Булево")) И ЭлементОтбора.ТипЗначения.Типы().Количество() = 1 Тогда Колонка.УстановитьЭлементУправления(Тип("Флажок")); Попытка Колонка.ДанныеФлажка = ЭлементОтбора.Имя; ДанныеПодключены = Истина; Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки КонецПопытки; Иначе Колонка.УстановитьЭлементУправления(Тип("ПолеВвода")); Попытка Колонка.Данные = ЭлементОтбора.Имя; ДанныеПодключены = Истина; Исключение // Например поле "Ссылка" почему то является недопустимым ОписаниеОшибки = ОписаниеОшибки(); // Для отладки КонецПопытки; КонецЕсли; Если Не ДанныеПодключены Тогда Колонка.Видимость = Ложь; КонецЕсли; КонецЕсли; Если КоличествоВидимыхКолонок > ПредельноеКоличествоВидимыхКолонок Тогда Колонка.Видимость = Ложь; Иначе КоличествоВидимыхКолонок = КоличествоВидимыхКолонок + 1; КонецЕсли; // Закомментировал 13.02.2011 //Если ЗначениеЗаполнено(Колонка.Данные) Тогда // Колонка.Имя = Колонка.Данные; //КонецЕсли; Колонка.Имя = ЭлементОтбора.Имя; СтрокаСтрукутрыПоля = СтруктураХраненияПолей.Найти(ЭлементОтбора.Имя, "ИмяПоля"); Если СтрокаСтрукутрыПоля <> Неопределено Тогда МетаданныеПоля = СтрокаСтрукутрыПоля.Метаданные; Если ЗначениеЗаполнено(МетаданныеПоля) Тогда МетаданныеПоля = ирКэш.ОбъектМДПоПолномуИмениЛкс(МетаданныеПоля); КонецЕсли; Попытка Колонка.ПодсказкаВШапке = МетаданныеПоля.Подсказка; Исключение // У графы журнала нет подсказки КонецПопытки; КонецЕсли; // Антибаг платформы 8.2-8.3.6 https://partners.v8.1c.ru/forum/t/1337995/m/1337995 Если Истина И ВерсияПлатформы < 803008 И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор")) Тогда СообщитьЛкс("Колонка """ + ЭлементОтбора.Имя + """ типа УникальныйИдентификатор не будет отображаться из-за ошибки платформы"); КолонкиТП.Удалить(Колонка); Продолжить; КонецЕсли; Если РазрешитьСортировку И НастройкаПорядка <> Неопределено Тогда ЭлементУправленияПорядком = НастройкаПорядка.Найти(ЭлементОтбора.Имя); Если ЭлементУправленияПорядком <> Неопределено Тогда ЭлементУправленияПорядком.Доступность = Истина; КонецЕсли; КонецЕсли; КонецЦикла; Если КолонкиСписка <> Неопределено Тогда Для Каждого ЭлементНастройкиОтбора Из ОсновнойЭУ.НастройкаОтбора Цикл ЭлементНастройкиОтбора.Доступность = Истина; КонецЦикла; НовыйПорядок = ирОбщий.ПолучитьСтрокуПорядкаЛкс(ДинамическийСписок.Порядок); Если Не ЗначениеЗаполнено(НовыйПорядок) Тогда НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка; ПредопределенныеПоля = Новый Массив(); Если ТипТаблицы = "ПланСчетов" Тогда ПредопределенныеПоля.Добавить("Код"); КонецЕсли; ПредопределенныеПоля.Добавить("Наименование"); ПредопределенныеПоля.Добавить("Дата"); ПредопределенныеПоля.Добавить("Период"); ПредопределенныеПоля.Добавить("ДатаИзменения"); ПредопределенныеПоля.Добавить("ДатаСоздания"); ПредопределенныеПоля.Добавить("Номер"); ПредопределенныеПоля.Добавить("Код"); ПеревестиКолонкиСтруктурыХраненияБДИндексыЛкс(СтруктураХраненияТаблицы.Индексы); Для Каждого ПредопределенноеПоле Из ПредопределенныеПоля Цикл ЭлементПорядка = НастройкаПорядка.Найти(ПредопределенноеПоле); Если ЭлементПорядка <> Неопределено Тогда Для Каждого ИндексТаблицыБД Из СтруктураХраненияТаблицы.Индексы Цикл ПеревестиКолонкиСтруктурыХраненияБДПоляЛкс(ИндексТаблицыБД.Поля); Если ИндексТаблицыБД.Поля[0].ИмяПоля = ПредопределенноеПоле Тогда ЭлементПорядка.Доступность = Истина; Прервать; КонецЕсли; КонецЦикла; Если ЭлементПорядка.Доступность Тогда НовыйПорядок = ПредопределенноеПоле; Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; Если ЗначениеЗаполнено(НовыйПорядок) Тогда // Обязательную установку делаем, чтобы в шапках появились индикаторы сортировки (антибаг платформы) ДинамическийСписок.Порядок.Установить(НовыйПорядок); КонецЕсли; //Компоновщик = ирКэш.КомпоновщикТаблицыМетаданныхЛкс(ОбъектМД.ПолноеИмя()); //#Если Сервер И Не Сервер Тогда // Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных; //#КонецЕсли //Для Каждого ПолеВыбора Из Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл // Если ПолеВыбора.Папка Тогда // Продолжить; // КонецЕсли; //КонецЦикла; КонецЕсли; Если ЛиКорневойТипСсылкиЛкс(КорневойТип) Тогда КолонкаИдентификатора = КолонкиТП.Добавить("ИдентификаторСсылкиЛкс"); КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки"; КонецЕсли; Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда КолонкаИдентификатора = КолонкиТП.Добавить("ИмяПредопределенныхДанных"); КолонкаИдентификатора.ТекстШапки = "Имя предопределенных данных"; КолонкаИдентификатора.Видимость = Ложь; КонецЕсли; НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(ОсновнойЭУ, РежимИмяСиноним); КонецПроцедуры Процедура НастроитьЗаголовкиАвтоТабличногоПоляДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач РежимИмяСиноним) Экспорт ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение)); ПоляТаблицы = ПолучитьПоляТаблицыМДЛкс(ОбъектМД.ПолноеИмя()); Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл Колонка = ОсновнойЭУ.Колонки.Найти(ПолеТаблицы.Имя); Если Колонка = Неопределено Тогда Продолжить; КонецЕсли; Если РежимИмяСиноним Тогда Колонка.ТекстШапки = ПолеТаблицы.Имя; Иначе Колонка.ТекстШапки = ПолеТаблицы.Заголовок; КонецЕсли; КонецЦикла; КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка() Процедура ФормаОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда Если ЭтаФорма.Открыта() Тогда ЭтаФорма.Закрыть(); Если ЭтаФорма.Открыта() Тогда Параметр.Отказ = Истина; КонецЕсли; КонецЕсли; ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда Если ЭтаФорма.Открыта() Тогда Параметр.Ответ = Истина; КонецЕсли; ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда ИмяФормы = ИмяФормыИзФормыЛкс(ЭтаФорма); Если Не ЗначениеЗаполнено(ИмяФормы) Тогда Попытка ИмяФормы = ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя(); Исключение КонецПопытки; КонецЕсли; Если Не ЗначениеЗаполнено(ИмяФормы) Тогда ИмяФормы = "Неизвестная форма"; КонецЕсли; СообщитьЛкс(ИмяФормы); КонецЕсли; КонецПроцедуры Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт СтандартнаяОбработка = Ложь; Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда ЗапуститьПриложение(ИмяФайла); КонецЕсли; КонецПроцедуры // Создает новый экземпляр обработки и открывает его форму. // // Параметры: // Объект - ОбработкаОбъект, ОтчетОбъект. // // Возвращаемое значение: // Форма. // Функция ОткрытьНовоеОкноОбработкиЛкс(ЭтотОбъект) Экспорт Если ТипЗнч(ЭтотОбъект) = Тип("УправляемаяФорма") Тогда Результат = ПолучитьФормуЛкс(ЭтотОбъект.ИмяФормы,,, Новый УникальныйИдентификатор); Иначе Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать(); Иначе ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя(); НовыйОбъект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяОбъекта); КонецЕсли; Результат = НовыйОбъект.ПолучитьФорму(); КонецЕсли; Результат.Открыть(); Возврат Результат; КонецФункции // ОткрытьНовоеОкноОбработкиЛкс() Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено, ТолькоВнешниеФормы = Ложь) Экспорт Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда //ирПортативный #Если Сервер И Не Сервер Тогда // Такой прием нужен для обхода ошибка компиляции в портативном режиме Фрагменты = СтрРазделитьЛкс(ПолноеИмяФормы); #Если Сервер И Не Сервер Тогда Фрагменты = Новый Массив; #КонецЕсли // http://www.hostedredmine.com/issues/883626 Если Истина И (Фрагменты[0] = "Обработка" Или Фрагменты[0] = "Отчет") И Фрагменты.Количество() > 2 И Найти(Фрагменты[1], "ир") = 1 И Фрагменты[1] <> Метаданные.Обработки.ирДинамическийСписок.Имя Тогда Если Не ТолькоВнешниеФормы Тогда ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]); КонецЕсли; Если ОбъектМД = Неопределено Тогда ВызватьИсключение "Не найден объект метаданных " + ПолноеИмяФормы; КонецЕсли; Если Истина И СтрокиРавныЛкс(Фрагменты[2], "Форма") И Фрагменты.Количество() = 4 Тогда ИмяФормы = Фрагменты[3]; Иначе ИмяФормы = Неопределено; КонецЕсли; Менеджер = Новый (ПеревестиСтроку(Фрагменты[0]) + ПеревестиСтроку("Менеджер") + "." + Фрагменты[1]); Результат = Менеджер.ПолучитьФорму(ИмяФормы, Владелец, Уникальность); Иначе Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно); КонецЕсли; Если Найти(ПолноеИмяФормы, "Обработка.ирПлатформа.") = 1 Тогда Попытка ЭтоЗапрещено = Результат.ЭтотОбъект.Метаданные().ПолноеИмя() = ПеревестиСтроку("Обработка") + ".ирПлатформа"; Исключение ЭтоЗапрещено = Ложь; КонецПопытки; Если ЭтоЗапрещено Тогда СообщитьЛкс("Создан лишний экземпляр обработки ирПлатформа"); КонецЕсли; КонецЕсли; //ирПортативный #КонецЕсли Иначе Фрагменты = СтрРазделитьЛкс(ПолноеИмяФормы); Если Не ТолькоВнешниеФормы Тогда ОбъектМД = ирКэш.ОбъектМДПоПолномуИмениЛкс(Фрагменты[0] + "." + Фрагменты[1]); КонецЕсли; Если ОбъектМД = Неопределено Тогда Если Истина И СтрокиРавныЛкс(Фрагменты[2], "Форма") И Фрагменты.Количество() = 4 Тогда ИмяФормы = Фрагменты[3]; Иначе ИмяФормы = Неопределено; КонецЕсли; Если Фрагменты[1] = "ирПортативный" Тогда Результат = ирПортативный.ПолучитьФорму(ИмяФормы, Владелец, Уникальность); Иначе ТипМетаданных = Фрагменты[0]; Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных); ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных); Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность); КонецЕсли; Иначе Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Процедура ЗаполнитьСписокВыбораПоляСортировкиТабличногоПоляЛкс(Знач СписокВыбора, Знач ТабличноеПоле) Экспорт #Если Сервер И Не Сервер Тогда СписокВыбора = Новый СписокЗначений; #КонецЕсли СписокВыбора.Очистить(); Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл Если Истина И ЗначениеЗаполнено(КолонкаТП.Данные) И (КолонкаТП.Видимость Или КолонкаТП.ИзменятьВидимость) //И Не (КолонкаТП.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор")) И КолонкаТП.ТипЗначения.Типы() = 1) Тогда СписокВыбора.Добавить(КолонкаТП.Данные + " Убыв", КолонкаТП.ТекстШапки + " Убыв"); СписокВыбора.Добавить(КолонкаТП.Данные + " Возр", КолонкаТП.ТекстШапки + " Возр"); КонецЕсли; КонецЦикла; СписокВыбора.СортироватьПоПредставлению(); КонецПроцедуры Функция СсылкаОсновногоОбъектаФормыЛкс(Знач ТекущаяФорма) Экспорт ИмяОсновногоРеквизита = "Объект"; Попытка Ссылка = ТекущаяФорма[ИмяОсновногоРеквизита].Ссылка; Исключение ИмяОсновногоРеквизита = ирОбщий.ПеревестиСтроку(ИмяОсновногоРеквизита); Ссылка = Неопределено; КонецПопытки; Если Ссылка = Неопределено Тогда Попытка Ссылка = ТекущаяФорма[ИмяОсновногоРеквизита].Ссылка; Исключение Ссылка = Неопределено; КонецПопытки; КонецЕсли; Возврат Ссылка; КонецФункции Функция ПолучитьЦветСтиляЛкс(ИмяЦвета) Экспорт //Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя); Если ИмяЦвета = "ирТекстИнформационнойНадписи" Тогда Возврат Новый Цвет(83, 106, 194); ИначеЕсли ИмяЦвета = "ирЦветФонаЧередованияСтрок" Тогда //Возврат WebЦвета.МятныйКрем; Возврат Новый Цвет(240, 255, 225); ИначеЕсли ИмяЦвета = "ирЦветФонаВычисляемогоЗначения" Тогда Возврат WebЦвета.ГолубойСКраснымОттенком; ИначеЕсли ИмяЦвета = "ирЦветФонаОшибки" Тогда Возврат Новый Цвет(255, 235, 235); ИначеЕсли ИмяЦвета = "ирЦветФонаРасширенногоПредставленияЗначения" Тогда Возврат Новый Цвет(255, 255, 180); Иначе Результат = ЦветаСтиля[ИмяЦвета]; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // Значение - // ОчиститьПередУстановкой - Булево // УстановитьТекст - Булево // УстановитьЗначение - Булево // Функция БуферОбмена_УстановитьЗначениеЛкс(Знач Значение = "", Знач ОчиститьПередУстановкой = Истина, Знач УстановитьТекст = Истина, Знач УстановитьЗначение = Истина) Экспорт WinAPI = ирКэш.Получить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 <> Неопределено Тогда КоличествоСимволов = СтрДлина(ВнутреннееЗначение); ПромежуточныйТекст = 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 <> Неопределено Тогда 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 Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения) Тогда Результат = ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, НовоеЗначение); КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ЭтаФорма - Форма - для управляемой формы можно не передавать, она определится автоматически // Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма = Неопределено) Экспорт Если ЭтаФорма = Неопределено Тогда ЭтаФорма = ирОбщий.АктивнаяУправляемаяФормаЛкс(); КонецЕсли; ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент; Текст = БуферОбмена_ПолучитьТекстЛкс(); Значение = БуферОбмена_ПолучитьЗначениеЛкс(); Если Значение = Неопределено Тогда Возврат Неопределено; КонецЕсли; ПродолжитьОбработку = Истина; ТипЗначения = ТипЗнч(Значение); ПутьКДанным = ""; Если Ложь Или ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Или ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеФормы") Тогда Если Не ЭтаФорма.ТолькоПросмотр Тогда Если ТипЗначения = Тип("Массив") Тогда Значение = Значение[0]; КонецЕсли; ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение, Текст); //Если ПродолжитьОбработку И ЗначениеЗаполнено(ТекущийЭлементФормы.Данные) Тогда // // Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора // Попытка // ЭтаФорма[ТекущийЭлементФормы.Данные] = Значение; // Исключение // КонецПопытки; //КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Или ТипЗнч(ТекущийЭлементФормы) = Тип("ТаблицаФормы") Тогда Попытка РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге; Исключение РедактированиеВДиалоге = Ложь; КонецПопытки; Если ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда Колонка = ТекущийЭлементФормы.ТекущаяКолонка; ЭлементУправления = Колонка.ЭлементУправления; Иначе Колонка = ТекущийЭлементФормы.ТекущийЭлемент; ЭлементУправления = Колонка; КонецЕсли; Если Истина И Не РедактированиеВДиалоге И Не ЭтаФорма.ТолькоПросмотр И Не ТекущийЭлементФормы.ТолькоПросмотр И Колонка <> Неопределено И (Ложь Или ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Или ТипЗнч(ЭлементУправления) = Тип("ПолеФормы")) И Не ЭлементУправления.ТолькоПросмотр Тогда ДобавитьСтроку = Истина И ТекущийЭлементФормы.ТекущиеДанные = Неопределено И ТекущийЭлементФормы.ИзменятьСоставСтрок; Если Истина И Значение <> Неопределено И ТекущийЭлементФормы.ИзменятьСоставСтрок И Не ДобавитьСтроку Тогда Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет); ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да; КонецЕсли; Если ДобавитьСтроку Тогда ТекущийЭлементФормы.ДобавитьСтроку(); ТабличноеПоле_УстановитьТекущуюКолонкуЛкс(ТекущийЭлементФормы, Колонка); КонецЕсли; Если ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строку при вызове команды и иногда установке текущей колонки КонецЕсли; Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда Если ТипЗначения = Тип("Массив") Тогда Значение = Значение[0]; КонецЕсли; ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ЭлементУправления, Значение, Текст); ИмяКолонкиДанных = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТекущийЭлементФормы); Если ПродолжитьОбработку И ЗначениеЗаполнено(ИмяКолонкиДанных) Тогда // Например ссылка таблицы внешнего источника в поле ввода не может быть установлена через оповещение выбора Если ТипЗнч(ТекущийЭлементФормы.ТекущиеДанные) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда ИмяКолонкиДанных = ПервыйФрагментЛкс(ИмяКолонкиДанных, "Для"); КонецЕсли; Попытка ТекущийЭлементФормы.ТекущиеДанные[ИмяКолонкиДанных] = Значение; Исключение КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецФункции // Параметры: // ЭтаФорма - Форма - для управляемой формы можно не передавать, она определится автоматически // Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма = Неопределено) Экспорт Если ЭтаФорма = Неопределено Тогда ЭтаФорма = ирОбщий.АктивнаяУправляемаяФормаЛкс(); КонецЕсли; Значение = Неопределено; ЕстьСсылкиВТекущемПоле = ирОбщий.СсылкиИзТекущейКолонкиВыделенныхСтрокТаблицыЛкс(ЭтаФорма, Значение, Ложь).Количество() > 0; Если Не ЕстьСсылкиВТекущемПоле Тогда ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент; Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда Значение = ДанныеЭлементаФормыЛкс(ТекущийЭлементФормы); //Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст; Если ТипЗнч(Значение) = Тип("Строка") Тогда Значение = Неопределено; КонецЕсли; ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда //:ТекущийЭлементФормы = Новый ("ТабличноеПоле") Если Истина И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено Тогда Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя]; Значение = Ячейка.Значение; Если ТипЗнч(Значение) = Тип("Строка") Тогда КлючеваяКолонкаДанных = Неопределено; ТипСтроки = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока); Если КлючеваяКолонкаДанных <> Неопределено Тогда Значение = Новый Массив; Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл Значение.Добавить(ВыделеннаяСтрока[КлючеваяКолонкаДанных]); КонецЦикла; ИначеЕсли Ложь Или ТипСтроки = Тип("ДоступноеПолеКомпоновкиДанных") Или ТипСтроки = Тип("ДоступноеПолеОтбораКомпоновкиДанных") Тогда //Значение = Новый Массив; //Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл // Значение.Добавить(ВыделеннаяСтрока); //КонецЦикла; Значение = ТекущийЭлементФормы.ТекущаяСтрока.Поле; Иначе //Значение = Неопределено; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда #Если Сервер И Не Сервер Тогда ТекущийЭлементФормы = Новый ТабличныйДокумент; #КонецЕсли Попытка ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки; Исключение ДанныеРасшифровки = Неопределено; КонецПопытки; Если Истина И ТипЗнч(ДанныеРасшифровки) = Тип("ДанныеРасшифровкиКомпоновкиДанных") И ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка]; Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение, Ложь) Тогда Продолжить; КонецЕсли; Значение = ЗначениеПоля.Значение; Прервать; КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; БуферОбмена_УстановитьЗначениеЛкс(Значение,, Ложь, Истина); КонецФункции Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено, Знач АдресСхемыКомпоновки = Неопределено) Экспорт Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле); Форма.НастройкиСписка = НастройкиСписка; Форма.АдресСхемыКомпоновки = АдресСхемыКомпоновки; Форма.ОткрытьМодально(); КонецФункции Функция ОткрытьГруппировкуТабличногоПоляЛкс(Знач ТабличноеПоле, Знач НастройкиСписка = Неопределено, ИменаКлючевыхКолонок = "") Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Форма = мПлатформа.ПолучитьФорму("ГруппировкаТаблицы", ТабличноеПоле); Форма.НастройкиСписка = НастройкиСписка; Форма.ПараметрИменаКлючевыхКолонок = ИменаКлючевыхКолонок; Форма.Открыть(); КонецФункции Процедура ПоказатьСсылкуНаМодульКонфигурацииЛкс(ПолноеИмяМодуля) Экспорт Ссылка = "{" + ПолноеИмяМодуля + "(1)}:"; Текст = //"" " |" + Ссылка + "
|Скопируйте эту ссылку и откройте через программу ClipAngel в конфигураторе |" //"" ; Форма = ФормаПросмотраHTMLЛкс(Текст); Форма.ОткрытьМодально(); КонецПроцедуры // ОткрытиеФормы() Процедура СкрытьПоказатьОднозначныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, Знач Скрыть = Истина, Знач ИгнорироватьКолонки = Неопределено) Экспорт ОставитьТолькоРазличающиесяКолонки = Ложь; Если Скрыть Тогда // Включаем видимость тех колонок реквизитов, в каких есть различия между элементами группы, а у остальных выключаем Если ТабличноеПоле.Значение.Количество() > 1 Тогда ОставитьТолькоРазличающиесяКолонки = Истина; КонецЕсли; КонецЕсли; Для Каждого КолонкаТП Из ТабличноеПоле.Колонки Цикл Если Ложь Или (Истина И ИгнорироватьКолонки <> Неопределено И ЗначениеЗаполнено(КолонкаТП.Данные) И ИгнорироватьКолонки.Свойство(КолонкаТП.Данные)) Или ТабличноеПоле.Значение.Колонки.Найти(КолонкаТП.Данные) = Неопределено Тогда Продолжить; КонецЕсли; Если ОставитьТолькоРазличающиесяКолонки Тогда ПервоеЗначение = ТабличноеПоле.Значение[0][КолонкаТП.Данные]; Для Индекс = 1 По ТабличноеПоле.Значение.Количество() - 1 Цикл ТекущееЗначение = ТабличноеПоле.Значение[Индекс][КолонкаТП.Данные]; Если ПервоеЗначение <> ТекущееЗначение Тогда Прервать; КонецЕсли; КонецЦикла; НоваяВидимость = ПервоеЗначение <> ТекущееЗначение; Иначе НоваяВидимость = Истина; КонецЕсли; КолонкаТП.Видимость = НоваяВидимость; КонецЦикла; КонецПроцедуры Процедура _Форма_ВставитьСкрытуюКоманднуюПанельГлобальныхКомандЛкс(ЭтаФорма) Экспорт ЭлементыФормы = ЭтаФорма.ЭлементыФормы; ИмяКоманднойПанели = "КП_ПолеВвода"; КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели); Если КонтекстноеМенюФормы = Неопределено Тогда КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели); КонтекстноеМенюФормы.Видимость = Ложь; КонецЕсли; //лПлатформа = ирКэш.Получить(); //МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды"); //КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода; //ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы); КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(КонтекстноеМенюФормы); Для Каждого ЭлементФормы Из ЭлементыФормы Цикл Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда Попытка КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню; Исключение // Поле ввода принадлежит не панели, поэтому у него нет свойства Продолжить; КонецПопытки; Если КонтекстноеМеню = Неопределено Тогда //ЭлементФормы.АвтоКонтекстноеМеню = Ложь; ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы; КонецЕсли; КонецЕсли; КонецЦикла; ДействияФормы = ЭлементыФормы.Найти("ДействияФормы"); Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда ПанельФормы = ЭтаФорма.Панель; Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь); ДействияФормы.ИсточникДействий = ЭтаФорма; ПанельФормы.КонтекстноеМеню = ДействияФормы; Иначе ДействияФормы = ПанельФормы.КонтекстноеМеню; КонецЕсли; КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(ДействияФормы); КонецЕсли; КонецПроцедуры Процедура Форма_ПриОткрытииЛкс(ЭтаФорма) Экспорт Если ЭтаФорма.МодальныйРежим Тогда мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли мПлатформа.СчетчикМодальныхФорм.Добавить(1); КонецЕсли; КонецПроцедуры Процедура Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные) Экспорт Если Источник = "KeyboardHook" Тогда Если Не ЭтаФорма.ВводДоступен() Тогда Возврат; КонецЕсли; ПолученноеЧисло = Лев(Данные,5); ПолученноеЧисло = Число(ПолученноеЧисло); ВиртуальнаяКлавиша = ПолученноеЧисло % 256; ПолученноеЧисло = ПолученноеЧисло - ВиртуальнаяКлавиша; РасширеннаяКлавиша = ПолученноеЧисло % 512; ПолученноеЧисло = ПолученноеЧисло - РасширеннаяКлавиша; ПравыйАльт = ПолученноеЧисло % 1024; ПолученноеЧисло = ПолученноеЧисло - ПравыйАльт; ЛевыйАльт = ПолученноеЧисло % 2048; ПолученноеЧисло = ПолученноеЧисло - ЛевыйАльт; ПравыйКонтрол = ПолученноеЧисло % 4096; ПолученноеЧисло = ПолученноеЧисло - ПравыйКонтрол; ЛевыйКонтрол = ПолученноеЧисло % 8192; ПолученноеЧисло = ПолученноеЧисло - ЛевыйКонтрол; ПравыйШифт = ПолученноеЧисло % 16384; ПолученноеЧисло = ПолученноеЧисло - ПравыйШифт; ЛевыйШифт = ПолученноеЧисло; Если СтрДлина(Данные)>5 Тогда Символ = Сред(Данные, 6); Иначе Символ = ""; КонецЕсли; КодыКлавиш = ирКэш.КодыКлавиш(); Если Найти(Данные, КодыКлавиш["CTRL+ALT+E"]) = 1 Тогда ирОбщий.ОткрытьГлобальноеМенюЛкс(ЭтаФорма); ИначеЕсли Ложь Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеВвода") Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле") Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ПолеФормы") Или ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТаблицаФормы") Тогда Если Найти(Данные, КодыКлавиш["CTRL+C"]) = 1 Тогда Попытка БуферОбмена_КопироватьЛкс(ЭтаФорма); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки Сообщить(ОписаниеОшибки); КонецПопытки; ИначеЕсли Ложь //Или Найти(Данные, КодыКлавиш["CTRL+V"]) = 1 // Много нежелательных действий Или Найти(Данные, КодыКлавиш["ALT+SHIFT+V"]) = 1 Тогда БуферОбмена_ВставитьЛкс(ЭтаФорма); ИначеЕсли Найти(Данные, КодыКлавиш["CTRL+A"]) = 1 Тогда Если ТипЗнч(ЭтаФорма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда ТабличноеПолеОбновитьТекстыПодваловЛкс(ЭтаФорма.ТекущийЭлемент); КонецЕсли; КонецЕсли; КонецЕсли; //Сообщить(Данные); КонецЕсли; КонецПроцедуры Процедура ВнешнееСобытиеЛкс(Источник, Событие, Данные) Экспорт #Если ТолстыйКлиентУправляемоеПриложение Тогда Если Источник = "KeyboardHook" Тогда ЭтаФорма = АктивнаяУправляемаяФормаЛкс(); Если ЭтаФорма <> Неопределено Тогда Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные); КонецЕсли; КонецЕсли; #КонецЕсли КонецПроцедуры Процедура Форма_ПриЗакрытииЛкс(ЭтаФорма, СохранитьНастройкуПоУмолчанию = Истина) Экспорт // У некоторых из-за большого объема данных в настройках пользователя это вызывает большие задержки //ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс"); СохранитьНастройкиФормыЛкс(ЭтаФорма); мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли СчетчикМодальныхФорм = мПлатформа.СчетчикМодальныхФорм; Если СчетчикМодальныхФорм.Количество() > 0 Тогда КоличествоФормВТекущемМодальномПространстве = СчетчикМодальныхФорм[СчетчикМодальныхФорм.ВГраница()]; КоличествоФормВТекущемМодальномПространстве = КоличествоФормВТекущемМодальномПространстве - 1; Если КоличествоФормВТекущемМодальномПространстве = 0 Тогда СчетчикМодальныхФорм.Удалить(СчетчикМодальныхФорм.ВГраница()); Иначе СчетчикМодальныхФорм[СчетчикМодальныхФорм.ВГраница()] = КоличествоФормВТекущемМодальномПространстве; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ПредложитьЗакрытьМодальнуюФормуЛкс(ЭтаФорма) Экспорт Если ЭтаФорма.МодальныйРежим Тогда Ответ = Вопрос("Хотите закрыть текущую форму, чтобы открыть новую форму немодально?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Да Тогда ЭтаФорма.Закрыть(); КонецЕсли; КонецЕсли; КонецПроцедуры Функция ЗапроситьСохранениеДанныхФормыЛкс(ЭтаФорма) Экспорт Если ЭтаФорма.Модифицированность Тогда ПередОтображениемДиалогаПередЗакрытиемФормыЛкс(ЭтаФорма); Ответ = Вопрос("Данные в форме были изменены. Сохранить изменения?", РежимДиалогаВопрос.ДаНетОтмена); КонецЕсли; Возврат Ответ; КонецФункции Функция ПериодОчисткиМенеджераВременныхТаблицЛкс() Экспорт Период = ирОбщий.ВосстановитьЗначениеЛкс("ПредлагатьОчиститьМенеджерВременныхТаблицЧерезМинут"); Если Период = Неопределено Тогда Период = 30; ИначеЕсли Период < 10 Тогда Период = 10; ИначеЕсли Период > 60 Тогда Период = 60; КонецЕсли; Возврат Период; КонецФункции Процедура ПередОтображениемДиалогаПередЗакрытиемФормыЛкс(Знач ЭтаФорма) Экспорт #Если ТолстыйКлиентУправляемоеПриложение Тогда ЭтаФорма.Открыть(); // http://www.hostedredmine.com/issues/881581 #КонецЕсли КонецПроцедуры Процедура КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(Знач КоманднаяПанельПолеВвода) КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить("МакетФормы"); КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; Попытка КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие"); Исключение КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать); Возврат; КонецПопытки; КнопкаКопировать.Имя = "БуферОбмена_Копировать"; КнопкаКопировать.Текст = "Копировать значение"; КнопкаКопировать.Подсказка = "Копировать значение в буфер обмена"; КнопкаКопировать.Пояснение = КнопкаКопировать.Подсказка; КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина); КнопкаКопировать.Картинка = ирКэш.КартинкаПоИмениЛкс("ирКопировать"); // Здесь в расширении будет неявное обращение к серверу https://partners.v8.1c.ru/forum/topic/1635523 КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить(); КнопкаВставить.Имя = "БуферОбмена_Вставить"; КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; КнопкаВставить.Текст = "Вставить значение"; КнопкаВставить.Подсказка = "Вставить значение из буфера обмена"; КнопкаВставить.Пояснение = КнопкаВставить.Подсказка; КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина); КнопкаВставить.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие"); КнопкаВставить.Картинка = ирКэш.КартинкаПоИмениЛкс("ирВставить"); // Здесь в расширении будет неявное обращение к серверу https://partners.v8.1c.ru/forum/topic/1635523 КнопкаВставить = КоманднаяПанельПолеВвода.Кнопки.Добавить(); КнопкаВставить.Имя = "ОткрытьГлобальноеМеню"; КнопкаВставить.ТипКнопки = ТипКнопкиКоманднойПанели.Действие; КнопкаВставить.Текст = "Глобальное меню"; КнопкаВставить.Подсказка = "Открыть глобальное меню"; КнопкаВставить.Пояснение = КнопкаВставить.Подсказка; КнопкаВставить.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.E, Истина, Истина); КнопкаВставить.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие"); КонецПроцедуры Процедура УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка) Экспорт Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда БуферОбмена_КопироватьЛкс(ЭтаФорма); ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда БуферОбмена_ВставитьЛкс(ЭтаФорма); ИначеЕсли Кнопка.Имя = "ОткрытьГлобальноеМеню" Тогда ОткрытьГлобальноеМенюЛкс(ЭтаФорма); КонецЕсли; КонецПроцедуры Процедура УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры) Экспорт Параметры.Кнопка.СочетаниеКлавиш = Параметры.СочетаниеКлавиш; КонецПроцедуры Процедура БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс(Параметры) Экспорт БуферОбмена_УстановитьЗначениеЛкс(Параметры.Значение, Параметры.ОчиститьПередУстановкой, Параметры.УстановитьТекст, Параметры.УстановитьЗначение); //УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры); КонецПроцедуры // Родственник ВернутьПостоянныйПарольПользователяЛкс // Пароль устанавливается временный и опционально роль ирРазработчик Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина, ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска = Истина) Экспорт #Если Сервер И Не Сервер Тогда ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя(); #КонецЕсли мПлатформа = ирКэш.Получить(); НужноВернутьАутентификациюОС = Ложь; НужноВернутьАутентификациюПаролем = Ложь; НужноВернутьПароль = Ложь; НужноВернутьЗащитуОтОпасныхДействий = Ложь; УдалитьРольРазработчикИР = Ложь; Если ПодменитьПарольНаВремяЗапуска Тогда Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда СообщитьЛкс("Назначение временного пароля собственному пользователю не допускается"); Возврат Неопределено; КонецЕсли; мhash = ПользовательИБ.СохраняемоеЗначениеПароля; Если ПользовательИБ.АутентификацияОС = Истина Тогда ПользовательИБ.АутентификацияОС = Ложь; НужноВернутьАутентификациюОС = Истина; КонецЕсли; Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда ПользовательИБ.АутентификацияСтандартная = Истина; НужноВернутьАутентификациюПаролем = Истина; КонецЕсли; Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ"; ПользовательИБ.Пароль = Пароль; НужноВернутьПароль = Истина; КонецЕсли; Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда УдалитьРольРазработчикИР = Истина; ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик); КонецЕсли; КонецЕсли; Если ОтключитьЗащитуОтОпасныхДействийНаВремяЗапуска Тогда Если ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() И ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь; НужноВернутьЗащитуОтОпасныхДействий = Истина; КонецЕсли; КонецЕсли; ПользовательИБ.Записать(); НаборПараметров = Новый Структура(); НаборПараметров.Вставить("mHash", мhash); НаборПараметров.Вставить("НужноВернутьАутентификациюПаролем", НужноВернутьАутентификациюПаролем); НаборПараметров.Вставить("НужноВернутьАутентификациюОС", НужноВернутьАутентификациюОС); НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ); НаборПараметров.Вставить("НужноВернутьПароль", НужноВернутьПароль); НаборПараметров.Вставить("НужноВернутьЗащитуОтОпасныхДействий", НужноВернутьЗащитуОтОпасныхДействий); НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР); НаборПараметров.Вставить("Имя", ПользовательИБ.Имя); НаборПараметров.Вставить("Пароль", Пароль); Возврат НаборПараметров; КонецФункции // Родственник УстановитьВременныеСвойстваПользователюИБЛкс Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт; //УстановитьПривилегированныйРежим(Истина); Если НаборПараметров <> Неопределено Тогда мhash = НаборПараметров.mhash; НужноВернутьАутентификациюПаролем = НаборПараметров.НужноВернутьАутентификациюПаролем; НужноВернутьАутентификациюОС = НаборПараметров.НужноВернутьАутентификациюОС; НужноВернутьПароль = НаборПараметров.НужноВернутьПароль; НужноВернутьЗащитуОтОпасныхДействий = НаборПараметров.НужноВернутьЗащитуОтОпасныхДействий; ПользовательИБ = НаборПараметров.ПользовательИБ; УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР; Иначе Возврат; КонецЕсли; Если НужноВернутьПароль Тогда ПользовательИБ.СохраняемоеЗначениеПароля = мHash; КонецЕсли; Если НужноВернутьАутентификациюПаролем Тогда ПользовательИБ.АутентификацияСтандартная = Ложь; КонецЕсли; Если НужноВернутьАутентификациюОС Тогда ПользовательИБ.АутентификацияОС = Истина; КонецЕсли; Если НужноВернутьЗащитуОтОпасныхДействий И ирКэш.ДоступнаЗащитаОтОпасныхДействийЛкс() Тогда ПользовательИБ.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Истина; КонецЕсли; Если УдалитьРольРазработчикИР Тогда ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик); КонецЕсли; ПользовательИБ.Записать(); КонецПроцедуры Процедура НастроитьПоляВводаПараметровПотоковЛкс(ЭтаФорма) Экспорт ЭлементыФормы = ЭтаФорма.ЭлементыФормы; СписокВыбора = ЭлементыФормы.КоличествоОбъектовВПорции.СписокВыбора; СписокВыбора.Добавить(1); СписокВыбора.Добавить(2); СписокВыбора.Добавить(5); СписокВыбора.Добавить(10); СписокВыбора.Добавить(20); СписокВыбора.Добавить(50); СписокВыбора.Добавить(100); СписокВыбора.Добавить(200); СписокВыбора = ЭлементыФормы.КоличествоПотоков.СписокВыбора; СписокВыбора.Добавить(1); СписокВыбора.Добавить(4); СписокВыбора.Добавить(8); СписокВыбора.Добавить(12); СписокВыбора.Добавить(16); КонецПроцедуры Функция ОткрытьМенеджерТабличногоПоляЛкс(ТабличноеПоле = Неопределено, ЭтаФорма, АктивизироватьСтраницу = "") Экспорт Если ТабличноеПоле = Неопределено Тогда ТабличноеПоле = ЭтаФорма.ТекущийЭлемент; КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаМенеджера = мПлатформа.ПолучитьФорму("МенеджерТабличногоПоля", ЭтаФорма); ФормаМенеджера.УстановитьСвязь(ТабличноеПоле, , АктивизироватьСтраницу); Возврат ФормаМенеджера; КонецФункции Процедура ОткрытьСвязанныйСеансТонкогоКлиентаЛкс() Экспорт Результат = ирКэш.ПолучитьСеансТонкогоКлиентаЛкс(); Результат.Visible = Истина; Окна = Результат.ПолучитьОкна(); СписокОткрытыхОбъектов = Новый СписокЗначений; Для Каждого Окно Из Окна Цикл Попытка Содержимое = Окно.Содержимое; Исключение // В 8.2 нет такого свойства Продолжить; КонецПопытки; Для Каждого Форма Из Содержимое Цикл Попытка СсылкаCOM = Форма.Parameters.Key; Исключение СсылкаCOM = Неопределено; КонецПопытки; Если СсылкаCOM <> Неопределено Тогда ФрагментыИмениТипа = ирОбщий.СтрРазделитьЛкс(Форма.FormName); МассивПараметров = Новый Массив; МассивПараметров.Добавить(Новый УникальныйИдентификатор(Результат.String(СсылкаCOM.УникальныйИдентификатор()))); Ссылка = Новый (Тип(ФрагментыИмениТипа[0] + "Ссылка." + ФрагментыИмениТипа[1]), МассивПараметров); СписокОткрытыхОбъектов.Добавить(Ссылка, ФрагментыИмениТипа[0] + "." + ФрагментыИмениТипа[1] + " - " + Ссылка); КонецЕсли; КонецЦикла; КонецЦикла; Если СписокОткрытыхОбъектов.Количество() > 0 Тогда СписокОткрытыхОбъектов.СортироватьПоПредставлению(); ВыбранныйЭлемент = СписокОткрытыхОбъектов.ВыбратьЭлемент("Выберите объект для открытия в редакторе объекта БД"); Если ВыбранныйЭлемент <> Неопределено Тогда ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбранныйЭлемент.Значение); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ОповеститьОЗаписиОбъектаЛкс(ТипОбъекта, Источник = Неопределено) Экспорт Оповестить("ЗаписанОбъект", ТипОбъекта, Источник); ОповеститьОбИзменении(ТипОбъекта); КонецПроцедуры // Для оповещения об изменениях объектов в памяти клиентского приложения Процедура ОповеститьОбИзмененииОбъектаЛкс(Объект, Источник = Неопределено) Экспорт Оповестить("ИзмененОбъект", Объект, Источник); КонецПроцедуры Функция ЭтоНеудобнаяСсылкаДляОбработкиВыбораЛкс(Знач ВыбранноеЗначение) Экспорт // Почему то для ссылок внешних источников данных оповещение о выборе устанавливает строкове значение XMLТип = XMLТипЗнч(ВыбранноеЗначение); Если Истина И XMLТип <> Неопределено И (Ложь Или Найти(XMLТип.ИмяТипа, "ExternalDataSourceTableRef.") > 0 Или (Истина И ВыбранноеЗначение <> Неопределено И Метаданные.НайтиПоТипу(ТипЗнч(ВыбранноеЗначение)) <> Неопределено И ВыбранноеЗначение.Метаданные().РасширениеКонфигурации() <> Неопределено)) Тогда ЭтоНеудобнаяСсылка = Истина; Иначе ЭтоНеудобнаяСсылка = Ложь; КонецЕсли; Возврат ЭтоНеудобнаяСсылка; КонецФункции Функция ОткрытьОбъектМетаданныхЛкс(ОбъектИлиПолноеИмяМД) Экспорт Если ТипЗнч(ОбъектИлиПолноеИмяМД) = Тип("ОбъектМетаданных") Тогда ОбъектМД = ОбъектИлиПолноеИмяМД; Иначе ОбъектМД = ПолучитьМетаданныеЛкс(ОбъектИлиПолноеИмяМД); КонецЕсли; #Если Сервер И Не Сервер Тогда ОбъектМД = Метаданные.НайтиПоТипу(); #КонецЕсли Если ОбъектМД = Неопределено Тогда Возврат Неопределено; КонецЕсли; ПолноеИмяМД = ОбъектМД.ПолноеИмя(); Фрагменты = ирОбщий.СтрРазделитьЛкс(ПолноеИмяМД); Если Фрагменты.Количество() = 2 Тогда Форма = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма"); Форма.ПараметрИмяОбъектаМетаданных = ПолноеИмяМД; Форма.ПрименитьПараметрыФормы(); КонецЕсли; Возврат Форма; КонецФункции Функция ОткрытьПользователяИБЛкс(Пользователь) Экспорт ФормаПользователя = ирОбщий.ПолучитьФормуЛкс("Обработка.ирРедакторПользователей.Форма.ПользовательИнфобазы",,, Пользователь); ФормаПользователя.ПользовательБД = ПользователиИнформационнойБазы.НайтиПоИмени(Пользователь); ФормаПользователя.Открыть(); Возврат ФормаПользователя; КонецФункции Функция ОбработкаОбъектИзФормыЛкс(ЭтаФорма) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда ОбработкаОбъект = ЭтаФорма; Иначе //ОбработкаОбъект = ЭтаФорма.РеквизитФормыВЗначение("фОбъект"); Фрагменты = СтрРазделитьЛкс(ЭтаФорма.ИмяФормы); ОбработкаОбъект = ДанныеФормыВЗначение(ЭтаФорма.фОбъект, Тип("ОбработкаОбъект." + Фрагменты[1])); КонецЕсли; Возврат ОбработкаОбъект; КонецФункции Процедура ПроверитьЗакрытьФормуПриОтказеЛкс(ЭтаФорма, Знач Отказ) Экспорт // Антибаг платформы 8.3.11-12 Не работает установка параметра Отказ перед открытием обычной формы в управляемом приложении // https://partners.v8.1c.ru/forum/t/1713475/m/1713475 #Если ТолстыйКлиентУправляемоеПриложение Тогда Если Отказ И Не ЭтаФорма.МодальныйРежим Тогда ЭтаФорма.Закрыть(); КонецЕсли; #КонецЕсли КонецПроцедуры Функция КлючиСтрокБДИзТаблицыФормыЛкс(Форма = Неопределено, выхКлючТекущейСтроки = Неопределено, выхТаблицаФормыДинамическогоСписка = Неопределено, Знач НуженВидимыйПорядок = Истина) Экспорт Результат = Новый Массив; Если Форма = Неопределено Тогда Форма = АктивнаяУправляемаяФормаЛкс(); КонецЕсли; Если Ложь Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы") Или ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда ТаблицаФормы = Форма.ТекущийЭлемент; Если ЛиКлючСсылкиИлиРегистраЛкс(ТаблицаФормы.ТекущаяСтрока) Тогда выхКлючТекущейСтроки = ТаблицаФормы.ТекущаяСтрока; КонецЕсли; Ссылка = ТаблицаФормы.ТекущаяСтрока; ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, НуженВидимыйПорядок); Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда выхТаблицаФормыДинамическогоСписка = ТаблицаФормы; Возврат ВыделенныеСтроки; КонецЕсли; Структура = Новый Структура("Ссылка, Data"); Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл ДанныеСтроки = ТаблицаФормы.ДанныеСтроки(ВыделеннаяСтрока); ЗаполнитьЗначенияСвойств(Структура, ДанныеСтроки); Ссылка = Структура["Ссылка"]; Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда Результат.Добавить(Ссылка); КонецЕсли; Ссылка = Структура["Data"]; Если ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда Результат.Добавить(Ссылка); Если ВыделеннаяСтрока = ТаблицаФормы.ТекущаяСтрока Тогда выхКлючТекущейСтроки = Ссылка; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; Возврат Результат; КонецФункции Функция КлючОсновногоОбъектаУправляемойФормыЛкс(Форма = Неопределено) Экспорт Результат = Новый Массив; Если Форма = Неопределено Тогда Форма = АктивнаяУправляемаяФормаЛкс(); КонецЕсли; Если ТипЗнч(Форма) = Тип("УправляемаяФорма") Тогда Ссылка = ирОбщий.СсылкаОсновногоОбъектаФормыЛкс(Форма); Если Не ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда Попытка Ссылка = Форма.Параметры.Ключ; Исключение КонецПопытки; КонецЕсли; Если Не ЛиКлючСсылкиИлиРегистраЛкс(Ссылка) Тогда Ссылка = Неопределено; КонецЕсли; КонецЕсли; Возврат Ссылка; КонецФункции Функция СсылкиИзТекущейКолонкиВыделенныхСтрокТаблицыЛкс(Форма = Неопределено, выхКлючТекущейСтроки = Неопределено, НуженВидимыйПорядок = Истина) Экспорт Результат = Новый Массив; Если Форма = Неопределено Тогда Форма = АктивнаяУправляемаяФормаЛкс(); КонецЕсли; Если ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТаблицаФормы") Тогда ТаблицаФормы = Форма.ТекущийЭлемент; ТекущееПоле = ТаблицаФормы.ТекущийЭлемент; ПолноеИмяПоля = ТекущееПоле.Имя; ПутьКДанным = Null; ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы, НуженВидимыйПорядок); Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл ДанныеСтроки = ТаблицаФормы.ДанныеСтроки(ВыделеннаяСтрока); Если ПутьКДанным = Null Тогда ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(ДанныеСтроки, ПолноеИмяПоля); КонецЕсли; ЗначениеПоля = Неопределено; Если ЗначениеЗаполнено(ПутьКДанным) Тогда ЗначениеПоля = ДанныеСтроки[ПервыйФрагментЛкс(ПутьКДанным)]; КонецЕсли; Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда Результат.Добавить(ЗначениеПоля); Если ВыделеннаяСтрока = ТаблицаФормы.ТекущаяСтрока Тогда выхКлючТекущейСтроки = ЗначениеПоля; КонецЕсли; КонецЕсли; КонецЦикла; Если Найти(ПутьКДанным, ".") > 0 И Результат.Количество() > 0 Тогда Результат = ПрочитатьРеквизитПоМассивуСсылокЛкс(Результат, ПоследнийФрагментЛкс(ПутьКДанным)); КонецЕсли; ИначеЕсли ТипЗнч(Форма.ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда ТабличноеПоле = Форма.ТекущийЭлемент; ПутьКДанным = ПутьКДаннымКолонкиТабличногоПоляЛкс(ТабличноеПоле); Если ЗначениеЗаполнено(ПутьКДанным) Тогда ВыделенныеСтроки = ВыделенныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, НуженВидимыйПорядок); Для Каждого ВыделеннаяСтрока Из ВыделенныеСтроки Цикл ДанныеСтроки = ТабличноеПоле.ДанныеСтроки(ВыделеннаяСтрока); ЗначениеПоля = Неопределено; Если ЗначениеЗаполнено(ПутьКДанным) Тогда ЗначениеПоля = ДанныеСтроки[ПоследнийФрагментЛкс(ПутьКДанным)]; КонецЕсли; Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда Результат.Добавить(ЗначениеПоля); Если ВыделеннаяСтрока = ТабличноеПоле.ТекущаяСтрока Тогда выхКлючТекущейСтроки = ЗначениеПоля; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ИначеЕсли ТипЗнч(Форма.ТекущийЭлемент) = Тип("ПолеФормы") Тогда ПолеФормы = Форма.ТекущийЭлемент; Если ПолеФормы.Вид = ВидПоляФормы.ПолеВвода Тогда ЗначениеПоля = ДанныеЭлементаФормыЛкс(Форма.ТекущийЭлемент); Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда Результат.Добавить(ЗначениеПоля); выхКлючТекущейСтроки = ЗначениеПоля; КонецЕсли; ИначеЕсли ПолеФормы.Вид = ВидПоляФормы.ПолеТабличногоДокумента Тогда ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма); ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ПолеФормы); #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли КлючТекущейСтроки = Неопределено; ТаблицаЗначений = ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(ТабличныйДокумент, ДанныеРасшифровки,,, КлючТекущейСтроки); Если ТаблицаЗначений.Колонки.Количество() > 0 Тогда Для Каждого ЗначениеПоля Из ТаблицаЗначений.ВыгрузитьКолонку(0) Цикл Если ЛиКлючСсылкиИлиРегистраЛкс(ЗначениеПоля) Тогда Результат.Добавить(ЗначениеПоля); КонецЕсли; КонецЦикла; Если КлючТекущейСтроки <> Неопределено И ЛиКлючСсылкиИлиРегистраЛкс(КлючТекущейСтроки[0]) Тогда выхКлючТекущейСтроки = КлючТекущейСтроки[0]; КонецЕсли; КонецЕсли; Если выхКлючТекущейСтроки = Неопределено И Результат.Количество() > 0 Тогда выхКлючТекущейСтроки = Результат[0]; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПрочитатьРеквизитПоМассивуСсылокЛкс(Знач Ссылки, Знач ИмяРеквизита) Экспорт #Если Сервер И Не Сервер Тогда Ссылки = Новый Массив; #КонецЕсли Результат = Новый Массив; Если Ссылки.Количество() > 0 Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ Т." + ИмяРеквизита + " ИЗ " + Ссылки[0].Метаданные().ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка В (&Ссылки)"; Запрос.УстановитьПараметр("Ссылки", Ссылки); Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0); КонецЕсли; Возврат Результат; КонецФункции Функция ЭтоУправляемаяФормаОтчетаЛкс(Знач АктивнаяФорма, РазрешитьВнешнийОтчет = Ложь) Экспорт Возврат Истина И ТипЗнч(АктивнаяФорма) <> Тип("Форма") И (Ложь Или Найти(АктивнаяФорма.ИмяФормы, ирОбщий.ПеревестиСтроку("Отчет") + ".") = 1 Или РазрешитьВнешнийОтчет И Найти(АктивнаяФорма.ИмяФормы, ирОбщий.ПеревестиСтроку("ВнешнийОтчет") + ".") = 1); КонецФункции Функция АктивнаяУправляемаяФормаЛкс() Экспорт ТекущееОкно = АктивноеОкно(); Если ТекущееОкно = Неопределено Тогда Окна = ПолучитьОкна(); Для Каждого ТекущееОкно Из Окна Цикл Если ТекущееОкно.НачальнаяСтраница Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если ТипЗнч(ТекущееОкно) = Тип("ОкноКлиентскогоПриложения") Тогда АктивнаяФорма = Неопределено; Для Каждого Форма Из ТекущееОкно.Содержимое Цикл Если Форма.ВводДоступен() Тогда АктивнаяФорма = Форма; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Возврат АктивнаяФорма; КонецФункции Функция ТекущийЭлементАктивнойФормыЛкс(АктивнаяФорма = Неопределено) Экспорт Если АктивнаяФорма = Неопределено Тогда АктивнаяФорма = АктивнаяУправляемаяФормаЛкс(); КонецЕсли; ТекущийЭлемент = АктивнаяФорма.ТекущийЭлемент; Если ТипЗнч(АктивнаяФорма) = Тип("УправляемаяФорма") Тогда Если ТипЗнч(ТекущийЭлемент) = Тип("ОсновнойЭлементФормы") Тогда // http://www.hostedredmine.com/issues/880476 ТекущийЭлемент = Неопределено; КонецЕсли; КонецЕсли; Возврат ТекущийЭлемент; КонецФункции Процедура СравнитьТаблицуИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма); Если Истина И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле") И ТипЗнч(ТекущийЭлемент) <> Тип("ПолеТабличногоДокумента") И Не (Истина И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы") И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента) Тогда Возврат; КонецЕсли; ирОбщий.СравнитьСодержимоеЭлементаУправленияЛкс(Форма, ТекущийЭлемент); КонецПроцедуры Процедура ОткрытьТаблицуЗначенийИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма); Если Ложь Или ТипЗнч(ТекущийЭлемент) = Тип("ТаблицаФормы") Или ТипЗнч(ТекущийЭлемент) = Тип("ТабличноеПоле") Тогда Результат = ТаблицаЗначенийИзТаблицыФормыСКоллекциейЛкс(ТекущийЭлемент,,, Ложь); ИначеЕсли Ложь Или ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента") Или (Истина И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы") И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента) Тогда ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма); ТабличныйДокумент = ДанныеЭлементаФормыЛкс(ТекущийЭлемент); Результат = ирОбщий.ПолучитьТаблицуКлючейИзТабличногоДокументаЛкс(ТабличныйДокумент, ДанныеРасшифровки); #Если Сервер И Не Сервер Тогда Результат = Новый ТаблицаЗначений; #КонецЕсли Если Результат.Колонки.Количество() = 0 Тогда Ответ = Вопрос("Ячейки не содержат расшифровки. Хотите назначить имена колонкам из первой строки выделенной области?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет); ЛиПерваяСтрокаСодержитИменаКолонок = Ответ = КодВозвратаДиалога.Да; Результат = ТаблицаЗначенийИзТабличногоДокументаЛкс(ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок,,,, Истина); КонецЕсли; Результат = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Результат); ТекущийЭлемент = Неопределено; Иначе Возврат; КонецЕсли; Если Результат <> Неопределено Тогда ОткрытьЗначениеЛкс(Результат,,,, Ложь,, ТекущийЭлемент); Иначе // ДинамическийСписок ирОбщий.ВывестиСтрокиТабличногоПоляИПоказатьЛкс(ТекущийЭлемент); КонецЕсли; КонецПроцедуры Процедура ОткрытьТабличныйДокументИзАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма); Если Ложь Или ТипЗнч(ТекущийЭлемент) = Тип("ПолеТабличногоДокумента") Или (Истина И ТипЗнч(ТекущийЭлемент) = Тип("ПолеФормы") И ТекущийЭлемент.Вид = ВидПоляФормы.ПолеТабличногоДокумента) Тогда Результат = ДанныеЭлементаФормыЛкс(ТекущийЭлемент); ДанныеРасшифровки = ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Форма); КонецЕсли; Если Результат <> Неопределено Тогда ОткрытьТабличныйДокументРезультатаКомпоновкиЛкс(Результат, ДанныеРасшифровки); КонецЕсли; КонецПроцедуры Процедура ОткрытьТабличныйДокументРезультатаКомпоновкиЛкс(Знач ПолеТабличногоДокумента, Знач ДанныеРасшифровки = Неопределено, Знач ИмяСохраненияПоложенияОкна = "") Экспорт //ТабличныйДокумент = Новый ТабличныйДокумент; //ТабличныйДокумент.Вывести(ПолеТабличногоДокумента); ТабличныйДокумент = ПолучитьОбластьТабличногоДокументаИнтерактивноЛкс(ПолеТабличногоДокумента); #Если Сервер И Не Сервер Тогда ТабличныйДокумент = Новый ТабличныйДокумент; #КонецЕсли ТабличныйДокумент.ИмяСохраненияПоложенияОкна = ИмяСохраненияПоложенияОкна; Если ДанныеРасшифровки <> Неопределено Тогда УпроститьРасшифровкиТабличногоДокументаКомпоновкиЛкс(ТабличныйДокумент, ДанныеРасшифровки); КонецЕсли; ОткрытьЗначениеЛкс(ТабличныйДокумент,,,, Ложь,, ПолеТабличногоДокумента); КонецПроцедуры Функция ДанныеРасшифровкиУправляемойФормыОтчетаЛкс(Знач Форма) Экспорт ВозможныеИменаРеквизитов = Новый Массив; ВозможныеИменаРеквизитов.Добавить("ДанныеРасшифровки"); ВозможныеИменаРеквизитов.Добавить("ОтчетДанныеРасшифровки"); Для Каждого ИмяРеквизита Из ВозможныеИменаРеквизитов Цикл Попытка АдресРасшифровки = Форма[ИмяРеквизита]; Прервать; Исключение АдресРасшифровки = Неопределено; КонецПопытки; КонецЦикла; Если ЗначениеЗаполнено(АдресРасшифровки) Тогда ДанныеРасшифровки = ПолучитьИзВременногоХранилища(АдресРасшифровки); КонецЕсли; Возврат ДанныеРасшифровки; КонецФункции Процедура ОткрытьРазличныеЗначенияКолонкиАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма); Если Истина И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле") Тогда Возврат; КонецЕсли; ирОбщий.ОткрытьРазличныеЗначенияКолонкиЛкс(ТекущийЭлемент); КонецПроцедуры Процедура ОтладитьКомпоновкуДанныхАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт Если Форма = Неопределено Тогда Форма = АктивнаяУправляемаяФормаЛкс(); КонецЕсли; Если ТипЗнч(Форма) <> Тип("УправляемаяФорма") Тогда Возврат; КонецЕсли; Попытка НастройкиОтчета = Форма.НастройкиОтчета; Исключение НастройкиОтчета = Неопределено; КонецПопытки; Если НастройкиОтчета <> Неопределено И НастройкиОтчета.СхемаМодифицирована Тогда // Стандартная форма отчета БСП СхемаКомпоновки = ПолучитьИзВременногоХранилища(НастройкиОтчета.АдресСхемы); Иначе Фрагменты = СтрРазделитьЛкс(Форма.ИмяФормы); Если Фрагменты[0] = ирОбщий.ПеревестиСтроку("Отчет") Тогда ОтчетОбъект = Отчеты[Фрагменты[1]].Создать(); #Если Сервер И Не Сервер Тогда ОтчетОбъект = Обработки.ирКонсольКомпоновокДанных.Создать(); #КонецЕсли СхемаКомпоновки = ОтчетОбъект.СхемаКомпоновкиДанных; //ИначеЕсли Фрагменты[0] = ирОбщий.ПеревестиСтроку("ВнешнийОтчет") Тогда // // https://forum.mista.ru/topic.php?id=857116 // ОтчетОбъект = ВнешниеОтчеты.Создать(Фрагменты[1]); // #Если Сервер И Не Сервер Тогда // ОтчетОбъект = ВнешниеОтчеты.Создать(); // #КонецЕсли // СхемаКомпоновки = ОтчетОбъект.СхемаКомпоновкиДанных; Иначе СообщитьЛкс("Не поддерживаемый тип метаданных отчета - " + Фрагменты[0]); Возврат; КонецЕсли; КонецЕсли; ОтладитьЛкс(СхемаКомпоновки,, Форма.Отчет.КомпоновщикНастроек.ПолучитьНастройки()); КонецПроцедуры Процедура НастроитьДинамическийСписокАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма); Если ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") Тогда Возврат; КонецЕсли; ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТекущийЭлемент); Если ТипЗнч(ДанныеЭлемента) <> Тип("ДинамическийСписок") Тогда Возврат; КонецЕсли; Параметры = Новый Структура("Настройки, ПользовательскиеНастройки, ФиксированныеНастройки, ИсточникДоступныхНастроек"); ЗаполнитьЗначенияСвойств(Параметры, ДанныеЭлемента.КомпоновщикНастроек); Параметры.ИсточникДоступныхНастроек = ДанныеЭлемента.КомпоновщикНастроек.ПолучитьИсточникДоступныхНастроек(); Если ирКэш.НомерВерсииПлатформыЛкс() > 803001 Тогда Выполнить("ОткрытьФорму(""Обработка.ирДинамическийСписок.Форма.НастройкиСпискаУпр"", Параметры, ТекущийЭлемент,,,,, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца)"); Иначе ОткрытьФормуМодально("Обработка.ирДинамическийСписок.Форма.НастройкиСпискаУпр", Параметры, ТекущийЭлемент); КонецЕсли; КонецПроцедуры Процедура ОтборБезЗначенияВТекущейКолонкеАктивнойФормыЛкс(Параметры) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Параметры.Форма); Если Истина И ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") И ТипЗнч(ТекущийЭлемент) <> Тип("ТабличноеПоле") Тогда Возврат; КонецЕсли; ОбщийТипДанныхТаблицы = ОбщийТипДанныхТабличногоПоляЛкс(ТекущийЭлемент); Если Истина И ОбщийТипДанныхТаблицы <> "Список" И ОбщийТипДанныхТаблицы <> "ТабличнаяЧасть" И ОбщийТипДанныхТаблицы <> "НаборЗаписей" Тогда Возврат; КонецЕсли; ТабличноеПолеОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(ТекущийЭлемент); КонецПроцедуры Процедура НайтиВыбратьСсылкуВДинамическомСпискеАктивнойУправляемойФормыЛкс(Форма = Неопределено) Экспорт ТекущийЭлемент = ТекущийЭлементАктивнойФормыЛкс(Форма); Если ТипЗнч(ТекущийЭлемент) <> Тип("ТаблицаФормы") Тогда Возврат; КонецЕсли; ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТекущийЭлемент); Если ТипЗнч(ДанныеЭлемента) <> Тип("ДинамическийСписок") Тогда Возврат; КонецЕсли; НайтиВыбратьСсылкуВДинамическомСпискеПоIDЛкс(ТекущийЭлемент); КонецПроцедуры Процедура НайтиВыбратьСсылкуВДинамическомСпискеПоIDЛкс(Знач ТабличноеПоле, Форма = Неопределено) Экспорт мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли ФормаВводаИдентификатора = мПлатформа.ПолучитьФорму("УникальныйИдентификатор"); НовыйИдентификатор = ФормаВводаИдентификатора.ОткрытьМодально(); Если НовыйИдентификатор = Неопределено Тогда Возврат; КонецЕсли; Ссылка = ирОбщий.ПолучитьМенеджерЛкс(ирОбщий.ИмяТаблицыБДДинамическогоСпискаЛкс(ТабличноеПоле)).ПолучитьСсылку(НовыйИдентификатор); ТабличноеПоле.ТекущаяСтрока = Ссылка; Если ТабличноеПоле.ТекущаяСтрока = Ссылка Тогда СообщитьЛкс("Объект найден и установлен текущей строкой"); Иначе Если Форма = Неопределено Тогда Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле); КонецЕсли; Если Не ирОбщий.ЛиСуществуетОбъектПоСсылкеЛкс(Ссылка) Тогда Если ТабличноеПоле.РежимВыбора Тогда Ответ = Вопрос("Объект не найден в таблице. Выбрать ссылку?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда Форма.ОповеститьОВыборе(Ссылка); КонецЕсли; Иначе СообщитьЛкс("Объект не найден в таблице"); КонецЕсли; Иначе Если ТабличноеПоле.РежимВыбора Тогда Ответ = Вопрос("Объект найден в таблице, но не отвечает текущему отбору. Выбрать ссылку?", РежимДиалогаВопрос.ОКОтмена); Если Ответ = КодВозвратаДиалога.ОК Тогда Форма.ОповеститьОВыборе(Ссылка); КонецЕсли; Иначе СообщитьЛкс("Объект найден в таблице, но не отвечает текущему отбору"); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры // Нужно объединить этот метод с ТаблицаЗначенийИзТабличногоПоляЛкс Функция ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(Знач ТаблицаФормы, Знач МассивСтрок = Неопределено) Экспорт ДанныеЭлемента = ДанныеЭлементаФормыЛкс(ТаблицаФормы); Если ТипЗнч(ДанныеЭлемента) = Тип("ДинамическийСписок") Тогда ИмяОсновнойТаблицы = ИмяТаблицыБДДинамическогоСпискаЛкс(ТаблицаФормы); Если ЗначениеЗаполнено(ИмяОсновнойТаблицы) Тогда Возврат Неопределено; КонецЕсли; ДанныеЭлемента = Неопределено; КонецЕсли; Если МассивСтрок = Неопределено И ТипЗнч(ДанныеЭлемента) = Тип("ДанныеФормыДерево") Тогда Результат = ДанныеФормыВЗначение(ДанныеЭлемента, Тип("ДеревоЗначений")); // Для табличных частей не работает Иначе Если ДанныеЭлемента = Неопределено Тогда Если МассивСтрок = Неопределено Тогда МассивСтрок = ВыделенныеСтрокиТабличногоПоляЛкс(ТаблицаФормы); КонецЕсли; Иначе //ТипЗначенияТаблицы = ирОбщий.ПолучитьТипЗначенияЭлементаФормыЛкс(ТаблицаФормы, Ложь); //Если ТипЗначенияТаблицы <> Неопределено Тогда // ТипЗначенияТаблицы = ТипЗначенияТаблицы.Типы()[0]; // ИмяОбщегоТипа = ОбщийТипДанныхТабличногоПоляЛкс(ТаблицаФормы, Истина); // ОбъектМДТаблицы = Метаданные.НайтиПоТипу(ТипЗначенияТаблицы); // Если ОбъектМДТаблицы <> Неопределено Тогда // ВыгрузкаРезультата = Новый ТаблицаЗначений; // Если ИмяОбщегоТипа = "ТабличнаяЧасть" Тогда // // Через поля таблицы БД нельзя, т.к. у ТЧ может не быть проекции в БД // Для Каждого МетаРеквизит Из ОбъектМДТаблицы.Реквизиты Цикл // Результат.Колонки.Добавить(МетаРеквизит.Имя, МетаРеквизит.Тип, МетаРеквизит.Представление()); // КонецЦикла; // Иначе // ПоляТаблицыБД = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ОбъектМДТаблицы); // Для Каждого ПолеБД Из ПоляТаблицыБД Цикл // Результат.Колонки.Добавить(ПолеБД.Имя, ПолеБД.ТипЗначения, ПолеБД.Заголовок); // КонецЦикла; // КонецЕсли; // КонецЕсли; //КонецЕсли; Если МассивСтрок = Неопределено Тогда МассивСтрок = ДанныеЭлемента; КонецЕсли; КонецЕсли; #Если Сервер И Не Сервер Тогда МассивСтрок = Новый Массив; #КонецЕсли Результат = Новый ТаблицаЗначений; Если МассивСтрок.Количество() > 0 Тогда КолонкиДобавлены = Ложь; КолонкаСРеквизитом = ""; Для Каждого ИдентификаторСтроки Из МассивСтрок Цикл Если ТипЗнч(ИдентификаторСтроки) = Тип("Число") Тогда ДанныеСтроки = ТаблицаФормы.ДанныеСтроки(ИдентификаторСтроки); Иначе ДанныеСтроки = ИдентификаторСтроки; КонецЕсли; Если Не КолонкиДобавлены Тогда Если ТипЗнч(ИдентификаторСтроки) = Тип("Число") Тогда Результат.Колонки.Добавить("_КлючИсточника"); КонецЕсли; ДобавитьКолонкиГруппыФормыВТаблицуЗначений(ТаблицаФормы.ПодчиненныеЭлементы, Результат, ДанныеСтроки); ТекущееПоле = ТаблицаФормы.ТекущийЭлемент; Если ТекущееПоле <> Неопределено Тогда ПутьКДаннымПоля = НайтиПутьКДаннымПоляТаблицыФормыЛкс(ДанныеСтроки, ТекущееПоле.Имя); ИмяРеквизитаКоллекции = ПутьКДаннымПоля; Если Найти(ПутьКДаннымПоля, ".") > 0 Тогда КолонкаСРеквизитом = ПутьКДаннымПоля; ИмяРеквизитаКоллекции = СтрЗаменить(КолонкаСРеквизитом, ".", "_"); КонецЕсли; Если Результат.Колонки.Найти(ИмяРеквизитаКоллекции) = Неопределено Тогда Результат.Колонки.Добавить(ИмяРеквизитаКоллекции); КонецЕсли; КонецЕсли; КолонкиДобавлены = Истина; КонецЕсли; НоваяСтрока = Результат.Добавить(); Если ТипЗнч(ИдентификаторСтроки) = Тип("Число") Тогда НоваяСтрока._КлючИсточника = ИдентификаторСтроки; КонецЕсли; ЗаполнитьЗначенияСвойств(НоваяСтрока, ДанныеСтроки); КонецЦикла; Если ЗначениеЗаполнено(КолонкаСРеквизитом) Тогда ЗначенияКолонкиСРеквизитом = ПрочитатьРеквизитПоМассивуСсылокЛкс(Результат.ВыгрузитьКолонку(ПервыйФрагментЛкс(КолонкаСРеквизитом)), ПоследнийФрагментЛкс(КолонкаСРеквизитом)); Результат.ЗагрузитьКолонку(ЗначенияКолонкиСРеквизитом, СтрЗаменить(КолонкаСРеквизитом, ".", "_")); КонецЕсли; Результат = ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Результат); ИначеЕсли ДанныеЭлемента <> Неопределено Тогда ДобавитьКолонкиГруппыФормыВТаблицуЗначений(ТаблицаФормы.ПодчиненныеЭлементы, Результат, ДанныеЭлемента); КонецЕсли; //Если ВыделенныеСтрокиВосстановить <> Неопределено Тогда // ТаблицаФормы.ВыделенныеСтроки.Очистить(); // Для Каждого ВыделеннаяСтрока Из ВыделенныеСтрокиВосстановить Цикл // ТаблицаФормы.ВыделенныеСтроки.Добавить(ВыделеннаяСтрока); // КонецЦикла; //КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Процедура ДобавитьКолонкиГруппыФормыВТаблицуЗначений(Знач КолонкиИсточника, Знач Результат, Знач СтрокаИлиКоллекция) Для Каждого ПолеТаблицыФормы Из КолонкиИсточника Цикл Если ТипЗнч(ПолеТаблицыФормы) = Тип("ГруппаФормы") Тогда ДобавитьКолонкиГруппыФормыВТаблицуЗначений(ПолеТаблицыФормы.ПодчиненныеЭлементы, Результат, СтрокаИлиКоллекция); Продолжить; КонецЕсли; ПолноеИмяПоля = ПолеТаблицыФормы.Имя; ПутьКДанным = НайтиПутьКДаннымПоляТаблицыФормыЛкс(СтрокаИлиКоллекция, ПолноеИмяПоля); Если ЗначениеЗаполнено(ПутьКДанным) Тогда Результат.Колонки.Добавить(СтрЗаменить(ПутьКДанным, ".", "_"),, ПутьКДанным); КонецЕсли; КонецЦикла; КонецПроцедуры Функция ОткрытьСтатистикаMSSQLПоПоследнимЗапросамЛкс(ДатаНачала, ДатаКонца) Экспорт ОтчетОбъект = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирСтатистикаПоЗапросамСУБД"); #Если Сервер И Не Сервер Тогда ОтчетОбъект = Отчеты.ирСтатистикаПоЗапросамСУБД.Создать(); #КонецЕсли КлючВарианта = "Последние"; ФормаОтчета = ОтчетОбъект.ПолучитьФорму(,, КлючВарианта); ФормаОтчета.ПараметрКлючВарианта = КлючВарианта; ФормаОтчета.Открыть(); НастройкиОтчета = ФормаОтчета.КомпоновщикНастроек.Настройки; #Если Сервер И Не Сервер Тогда НастройкиОтчета = Компоновщик.Настройки; #КонецЕсли НастройкиОтчета.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПопавшиеВПоследниеМинут")).Использование = Ложь; НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра("НачалоИнтервала", ДатаНачала); НастройкиОтчета.ПараметрыДанных.УстановитьЗначениеПараметра("КонецИнтервала", ДатаКонца); ФормаОтчета.ДействияФормыСформировать(); КонецФункции #КонецЕсли #Если Клиент Тогда // Эта обертка нужно для возможности привязать ее к команде панели инструментов Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт #Если ВебКлиент Или МобильныйКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе ОтладитьОтложенныйОбъектЛкс(); #КонецЕсли КонецПроцедуры Процедура УстановитьПрикреплениеФормыВУправляемомПриложенииЛкс(Этаформа, ПроверитьДоступностьВвода = Ложь, ПоложениеПрикрепленногоОкна = Неопределено) Экспорт #Если ТолстыйКлиентУправляемоеПриложение Тогда // 8.3.17 здесь почему то не проверяет синтаксический контроль! Если ПроверитьДоступностьВвода И Не Этаформа.ВводДоступен() Тогда // При открытии формы ВводДоступен() всегда равно Ложь Возврат; КонецЕсли; Если ПоложениеПрикрепленногоОкна = Неопределено Тогда Если ЭтаФорма.СостояниеОкна = ВариантСостоянияОкна.Прикрепленное Тогда ПоложениеПрикрепленногоОкна = ЭтаФорма.ПоложениеПрикрепленногоОкна; КонецЕсли; КонецЕсли; Если ПоложениеПрикрепленногоОкна <> Неопределено Тогда WSHShell = Новый COMОбъект("WScript.Shell"); Если ирКэш.НомерВерсииПлатформыЛкс() >= 803017 Тогда Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда КомандаАктивацииПунктаОкна = "{UP 2}"; Иначе КомандаАктивацииПунктаОкна = "{UP 4}"; КонецЕсли; WSHShell.SendKeys("%-"); // Такой вызов меню окна не работает в 8.3.15-16 WSHShell.SendKeys(КомандаАктивацииПунктаОкна); WSHShell.SendKeys("{ENTER}"); // Снизу может находиться пункт меню "Сообщения", если было выведено хотя бы одно сообщение //Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда // WSHShell.SendKeys("{UP 3}"); //ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда // WSHShell.SendKeys("{UP 2}"); //ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда // WSHShell.SendKeys("{UP 5}"); //ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда // WSHShell.SendKeys("{UP 4}"); //КонецЕсли; Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда WSHShell.SendKeys("{Down 4}"); ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда WSHShell.SendKeys("{Down 5}"); ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда WSHShell.SendKeys("{Down 2}"); ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда WSHShell.SendKeys("{Down 3}"); КонецЕсли; WSHShell.SendKeys("{ENTER}"); ИначеЕсли ирКэш.НомерВерсииПлатформыЛкс() >= 803015 Тогда // WSHShell.SendKeys("%-"); // Такой вызов меню окна не работает в 8.3.15-16 Иначе WSHShell.SendKeys("%"); WSHShell.SendKeys("{Down 1}"); WSHShell.SendKeys("{О}"); Если ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Верх Тогда WSHShell.SendKeys("{UP 4}"); ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Низ Тогда WSHShell.SendKeys("{UP 3}"); ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Лево Тогда WSHShell.SendKeys("{UP 6}"); ИначеЕсли ПоложениеПрикрепленногоОкна = ВариантПрикрепленияОкна.Право Тогда WSHShell.SendKeys("{UP 5}"); КонецЕсли; WSHShell.SendKeys("{ENTER}"); КонецЕсли; КонецЕсли; #КонецЕсли КонецПроцедуры Процедура ОткрытьСписокИнструментовЛкс() Экспорт ОткрытьПанельИнструментовЛкс(Истина); КонецПроцедуры Процедура ОткрытьПанельИнструментовЛкс(ТолькоОткрытьНастройки = Ложь) Экспорт #Если ВебКлиент Или МобильныйКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе ФормаСпискаИнструментов = ПолучитьФормуЛкс("Обработка.ирПортативный.Форма.Форма"); ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = ТолькоОткрытьНастройки; ФормаСпискаИнструментов.Открыть(); #КонецЕсли КонецПроцедуры Процедура СохранитьНастройкиПользователяЛкс() Экспорт #Если ВебКлиент Или МобильныйКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе СохранитьНастройкиПользователя(); #КонецЕсли КонецПроцедуры Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт #Если ВебКлиент Или МобильныйКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда СообщитьЛкс("Команда недоступна в варианте Расширение"); Возврат; КонецЕсли; Форма = ирКэш.Получить().ПолучитьФорму("НастройкиАлгоритмов"); Форма.Открыть(); #КонецЕсли КонецПроцедуры Процедура ОткрытьРегистрацияCOMКомпонентЛкс() Экспорт #Если ВебКлиент Тогда СообщитьЛкс("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе Форма = ирКэш.Получить().ПолучитьФорму("РегистрацияCOMКомпонент"); Форма.Открыть(); #КонецЕсли КонецПроцедуры Процедура ОткрытьГлобальноеМенюЛкс(АктивнаяФорма = Неопределено) Экспорт #Если ВебКлиент Тогда Сообщить("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе Если АктивнаяФорма = Неопределено Тогда АктивнаяФорма = АктивнаяУправляемаяФормаЛкс(); КонецЕсли; мПлатформа = ирКэш.Получить(); #Если Сервер И Не Сервер Тогда мПлатформа = Обработки.ирПлатформа.Создать(); #КонецЕсли Форма = мПлатформа.ПолучитьФорму("ГлобальноеМеню"); Если Не Форма.Открыта() Тогда Форма.АктивнаяФорма = АктивнаяФорма; Форма.ОткрытьМодально(); КонецЕсли; #КонецЕсли КонецПроцедуры // Открывает справку по первой подсистеме метаданных переданного объекта // // Параметры: // Объект - любой объект, имеющий метаданные. // Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт #Если ВебКлиент Тогда Сообщить("Команда недоступна в вебклиенте"); #ИначеЕсли ТонкийКлиент Тогда ОткрытьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая"); #Иначе Если Ложь Или ТипЗнч(Объект) = Тип("Неопределено") Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения") Тогда // ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда ПолноеИмяМД = СлужебныеДанныеФормыЛкс(Объект).ИмяФормы; ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда ПолноеИмяМД = Объект.ИмяФормы; Иначе Если ТипЗнч(Объект) = Тип("Тип") Тогда ОбъектМД = Метаданные.НайтиПоТипу(Объект); Иначе ОбъектМД = Объект.Метаданные(); КонецЕсли; ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешняяОбработка.", "Обработка."); ПолноеИмяМД = СтрЗаменить(ПолноеИмяМД, "ВнешнийОтчет.", "Отчет."); КонецЕсли; Форма = ирКэш.Получить().ПолучитьФорму("ОПодсистеме",, ПолноеИмяМД); Форма.Открыть(); #КонецЕсли КонецПроцедуры // ОткрытьСправкуПоПодсистемеЛкс() Функция ОткрытьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт #Если ТонкийКлиент Или ВебКлиент Тогда Форма = ПолучитьФорму("Обработка.ирПортативный.Форма.ПерезапускСеансаУправляемая", Параметры, Владелец, Уникальность, Окно); #Иначе Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно); #КонецЕсли Форма.Открыть(); Возврат Форма; КонецФункции #КонецЕсли // Получает первый фрагмент, отделяемый разделителем от строки. // Написана для оптимизации по скорости. // // Параметры: // пСтрока - Строка - которую разбиваем; // *пРазделитель - Строка, "." - символ-разделитель; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина. // // Возвращаемое значение: // - Строка - первый фрагмент строки; // Неопределено - в строке не обнаружен разделитель. // Функция ПервыйФрагментЛкс(пСтрока, Разделитель = ".", ЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Позиция = Найти(пСтрока, Разделитель); Если Позиция > 0 Тогда Возврат Лев(пСтрока, Позиция - 1); Иначе Если ЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; Иначе Возврат ""; КонецЕсли; КонецЕсли; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Позиция = Найти(пСтрока, Разделитель);   Если Позиция > 0 Тогда   Возврат Лев(пСтрока, Позиция - 1);   Иначе   Если ЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда   Возврат пСтрока;   Иначе   Возврат "";   КонецЕсли;   КонецЕсли;   КонецФункции // ПервыйФрагментЛкс() Функция СтрКончаетсяНаЛкс(ПерваяСтрока, ВтораяСтрока, СУчетомРегистра = Ложь) Экспорт КонецСтроки = Прав(ПерваяСтрока, СтрДлина(ВтораяСтрока)); Если СУчетомРегистра Тогда Результат = КонецСтроки = ВтораяСтрока; Иначе Результат = НРег(КонецСтроки) = НРег(ВтораяСтрока); КонецЕсли; Возврат Результат; КонецФункции // Получает последний фрагмент, отделяемый разделителем от строки. // // Параметры: // пСтрока - Строка - в которой ищем; // *пМаркер – Строка, "." – отсекающий маркер; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки // в случае, если маркер не найден. // // Возвращаемое значение: // Неопределено - маркер не найден; // – Число – позиция маркера. // Функция ПоследнийФрагментЛкс(пСтрока, пМаркер = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Подстрока = пСтрока; МаркерНайден = Ложь; Пока пМаркер <> "" Цикл Позиция = Найти(Подстрока, пМаркер); Если Позиция = 0 Тогда Прервать; КонецЕсли; МаркерНайден = Истина; Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер)); КонецЦикла; Если Истина И Не МаркерНайден И пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; ИначеЕсли МаркерНайден Тогда Возврат Подстрока; Иначе Возврат ""; КонецЕсли; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Подстрока = пСтрока;   МаркерНайден = Ложь;   Пока пМаркер <> "" Цикл   Позиция = Найти(Подстрока, пМаркер);   Если Позиция = 0 Тогда   Прервать;   КонецЕсли;   МаркерНайден = Истина;   Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер));   КонецЦикла;   Если Истина   И Не МаркерНайден   И пЛиИспользоватьГраницуЕслиМаркерНеНайден   Тогда   Возврат пСтрока;   ИначеЕсли МаркерНайден Тогда   Возврат Подстрока;   Иначе   Возврат "";   КонецЕсли;   КонецФункции // ПоследнийФрагментЛкс() Функция ИменительныйПадежПериодаЛкс(Знач ЛюбойПадеж) Экспорт ЛюбойПадеж = Нрег(ЛюбойПадеж); Если ЛюбойПадеж = "года" Тогда Результат = "год"; ИначеЕсли ЛюбойПадеж = "полугодия" Тогда Результат = "полугодие"; ИначеЕсли ЛюбойПадеж = "квартала" Тогда Результат = "квартал"; ИначеЕсли ЛюбойПадеж = "месяца" Тогда Результат = "месяц"; ИначеЕсли ЛюбойПадеж = "декады" Тогда Результат = "декада"; ИначеЕсли ЛюбойПадеж = "недели" Тогда Результат = "неделя"; ИначеЕсли ЛюбойПадеж = "дня" Тогда Результат = "день"; ИначеЕсли ЛюбойПадеж = "часа" Тогда Результат = "час"; ИначеЕсли ЛюбойПадеж = "минуты" Тогда Результат = "минута"; ИначеЕсли ЛюбойПадеж = "секунды" Тогда Результат = "секунда"; Иначе ВызватьИсключение "Период не опознан """ + ЛюбойПадеж + """"; КонецЕсли; Возврат Результат; КонецФункции Процедура ДобавитьЕслиНужноПравыйСлешВФайловыйПутьЛкс(КаталогИсполняемыхФайлов) Экспорт Если Прав(КаталогИсполняемыхФайлов, 1) <> "\" Тогда КаталогИсполняемыхФайлов = КаталогИсполняемыхФайлов + "\"; КонецЕсли; КонецПроцедуры // Проверяет правильность заполнения реквизитов объекта // Параметры: // Объект - // ОбязательныеПоля - Строка(0,П), Массив // Отказ - Булево // Заголовок - Строка(0,П) // // Возвращаемое значение: Булево - истина, если проверка пройдена успешно Функция ПроверитьЗаполнениеРеквизитовОбъектаЛкс(Знач Объект, Знач ОбязательныеПоля = "", Отказ = Ложь) Экспорт Результат = Истина; Попытка ОбменДаннымиЗагрузка = Объект.ОбменДанными.Загрузка; Исключение ОбменДаннымиЗагрузка = Ложь; КонецПопытки; Если ОбменДаннымиЗагрузка Тогда Возврат Результат; КонецЕсли; Если ТипЗнч(ОбязательныеПоля) = Тип("Строка") Тогда МассивПолей = СтрРазделитьЛкс(ОбязательныеПоля, ",", Истина); ОбязательныеПоля = Новый Соответствие; Для каждого Значение Из МассивПолей Цикл ОбязательныеПоля[Значение] = ""; КонецЦикла; //ОбязательныеПоля = Новый Структура(ОбязательныеПоля); КонецЕсли; РеквизитыМД = Объект.Метаданные().Реквизиты; Для каждого КлючЗначение Из ОбязательныеПоля Цикл ПутьКДанным = КлючЗначение.Ключ; Значение = Вычислить("Объект." + ПутьКДанным); Если Не ЗначениеЗаполнено(Значение) Тогда // надо ругаться Если Не ЗначениеЗаполнено(КлючЗначение.Значение) Тогда Фрагменты = СтрРазделитьЛкс(ПутьКДанным); ИндексСтрокиТЧ = Неопределено; Если Фрагменты.Количество() > 1 Тогда ИндексСтрокиТЧ = СтрокаМеждуМаркерамиЛкс(Фрагменты[0], "[", "]", Ложь); Если ИндексСтрокиТЧ <> Неопределено Тогда ИндексСтрокиТЧ = Число(ИндексСтрокиТЧ); //ИмяТЧ = ПолучитьПервыйФрагментИис(Фрагменты[0], "["); КонецЕсли; КонецЕсли; //ПредставлениеРеквизита = РеквизитыМД[КлючЗначение.Ключ].Представление(); ПредставлениеРеквизита = СокрЛП(Фрагменты[Фрагменты.ВГраница()]); СтрокаСообщения = "Не заполнено значение реквизита """ + ПредставлениеРеквизита + """"; Если ИндексСтрокиТЧ <> Неопределено Тогда СтрокаСообщения = СтрокаСообщения + " в строке №" + Формат(ИндексСтрокиТЧ + 1, "ЧГ=") + " таблицы """ + СокрЛП(ирОбщий.ПервыйФрагментЛкс(Фрагменты[0], "[")) + """"; КонецЕсли; Иначе СтрокаСообщения = КлючЗначение.Значение; КонецЕсли; Отказ = Истина; СообщитьЛкс(СтрокаСообщения, СтатусСообщения.Внимание); Результат = Ложь; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ОписанияТиповПересекаютсяЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов1 = Новый ОписаниеТипов; ОписаниеТипов2 = Новый ОписаниеТипов; #КонецЕсли Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл Если Истина И ИсключаяПримитивныеТипы И (Ложь Или Тип = Тип("Булево") Или Тип = Тип("Строка") Или Тип = Тип("Число") Или Тип = Тип("Дата")) Тогда Продолжить; КонецЕсли; Если ОписаниеТипов2.СодержитТип(Тип) Тогда Возврат Истина; КонецЕсли; КонецЦикла; Возврат Ложь; КонецФункции // // Параметры: // ВариантКвалификаторов - Число - 0 - пересекать, 1 - брать от ОписаниеТипов1, 2 - брать от ОписаниеТипов2 Функция ПересечениеОписанийТиповЛкс(ОписаниеТипов1, ОписаниеТипов2, ИсключаяПримитивныеТипы = Ложь, ВариантКвалификаторов = 0) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов1 = Новый ОписаниеТипов; ОписаниеТипов2 = Новый ОписаниеТипов; #КонецЕсли МассивОбщихТипов = Новый Массив; Если ВариантКвалификаторов = 1 Тогда КвалификаторыЧисла = ОписаниеТипов1.КвалификаторыЧисла; КвалификаторыСтроки = ОписаниеТипов1.КвалификаторыСтроки; КвалификаторыДаты = ОписаниеТипов1.КвалификаторыДаты; Иначе КвалификаторыЧисла = ОписаниеТипов2.КвалификаторыЧисла; КвалификаторыСтроки = ОписаниеТипов2.КвалификаторыСтроки; КвалификаторыДаты = ОписаниеТипов2.КвалификаторыДаты; Если ВариантКвалификаторов = 0 Тогда КвалификаторыЧисла = Новый КвалификаторыЧисла( Мин(КвалификаторыЧисла.Разрядность, ОписаниеТипов1.КвалификаторыЧисла.Разрядность), Мин(КвалификаторыЧисла.РазрядностьДробнойЧасти, ОписаниеТипов1.КвалификаторыЧисла.РазрядностьДробнойЧасти), КвалификаторыЧисла.ДопустимыйЗнак); Если КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная И ОписаниеТипов1.КвалификаторыСтроки.ДопустимаяДлина = ДопустимаяДлина.Переменная Тогда ДопустимаяДлинаНовая = ДопустимаяДлина.Переменная; Иначе ДопустимаяДлинаНовая = ДопустимаяДлина.Фиксированная; КонецЕсли; КвалификаторыСтроки = Новый КвалификаторыСтроки( Мин(КвалификаторыСтроки.Длина, ОписаниеТипов1.КвалификаторыСтроки.Длина), ДопустимаяДлинаНовая); Если КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда ЧастиДатыНовая = ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты; ИначеЕсли КвалификаторыДаты.ЧастиДаты <> ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты И ОписаниеТипов1.КвалификаторыДаты.ЧастиДаты <> ЧастиДаты.ДатаВремя Тогда ЧастиДатыНовая = ЧастиДаты.ДатаВремя; Иначе ЧастиДатыНовая = КвалификаторыДаты.ЧастиДаты; КонецЕсли; КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДатыНовая); КонецЕсли; КонецЕсли; Для Каждого Тип Из ОписаниеТипов1.Типы() Цикл Если Истина И ИсключаяПримитивныеТипы И (Ложь Или Тип = Тип("Булево") Или Тип = Тип("Строка") Или Тип = Тип("Число") Или Тип = Тип("Дата")) Тогда Продолжить; КонецЕсли; Если ОписаниеТипов2.СодержитТип(Тип) Тогда МассивОбщихТипов.Добавить(Тип); КонецЕсли; КонецЦикла; Результат = Новый ОписаниеТипов(МассивОбщихТипов,,, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыДаты); Возврат Результат; КонецФункции // Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка. // // Параметры: // Строка – Строка. // // Возвращаемое значение: // Булево. // Функция ЛиИмяПеременнойЛкс(Строка) Экспорт Если ПустаяСтрока(Строка) Тогда Возврат Ложь; КонецЕсли; Пустышка = Новый Структура; Попытка Пустышка.Вставить(Строка); Возврат Истина; Исключение Возврат Ложь; КонецПопытки; КонецФункции // ЛиИмяПеременнойЛкс() // Пространство имен текущей конфигурации. // Возвращаемое значение: // Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config"; КонецФункции Функция БезопасноПолучитьЗначениеСвойстваЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка); ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы); ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка]; Возврат ЗаголовокЭлемента; КонецФункции Функция ВосстановитьТекущуюСтрокуТаблицыФормыЛкс(ТаблицаФормы, Знач КлючТекущейСтроки, ДанныеТаблицы = Неопределено, ИмяКлючевойКолонки = "Ссылка") Экспорт Если КлючТекущейСтроки <> Неопределено Тогда Если ДанныеТаблицы = Неопределено Тогда ДанныеТаблицы = ТаблицаФормы.Значение; КонецЕсли; Если ТипЗнч(КлючТекущейСтроки) <> Тип("Структура") Тогда КлючТекущейСтроки = Новый Структура(ИмяКлючевойКолонки, КлючТекущейСтроки); КонецЕсли; НайденныеСтроки = ДанныеТаблицы.НайтиСтроки(КлючТекущейСтроки); Если НайденныеСтроки.Количество() > 0 Тогда Строка = НайденныеСтроки[0]; Попытка ИдентификаторСтроки = Строка.ПолучитьИдентификатор(); Исключение ИдентификаторСтроки = Строка; КонецПопытки; ТаблицаФормы.ТекущаяСтрока = ИдентификаторСтроки; Возврат Истина; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции Функция ПолучитьКлючТекущейСтрокиЛкс(ТаблицаФормы, ИмяКлючевойКолонки = "Ссылка") Экспорт ТекущиеДанные = ТаблицаФормы.ТекущиеДанные; Если ТекущиеДанные <> Неопределено Тогда КлючТекущейСтроки = ТекущиеДанные[ИмяКлючевойКолонки]; КонецЕсли; Возврат КлючТекущейСтроки; КонецФункции Функция ИмяФормыИзФормыЛкс(ЭтаФорма) Экспорт Если ТипЗнч(ЭтаФорма) = Тип("УправляемаяФорма") Тогда Результат = ЭтаФорма.ИмяФормы; Иначе Результат = СлужебныеДанныеФормыЛкс(ЭтаФорма).ИмяФормы; КонецЕсли; Возврат Результат; КонецФункции Функция СлужебныеДанныеФормыЛкс(ЭтаФорма) Экспорт Результат = Неопределено; #Если Клиент Тогда Если ТипЗнч(ЭтаФорма) = Тип("Форма") Тогда Результат = ЭтаФорма.Панель.Страницы[0].Значение; Если Результат = Неопределено Тогда Результат = Новый Структура(); ЭтаФорма.Панель.Страницы[0].Значение = Результат; КонецЕсли; Иначе #КонецЕсли Попытка Результат = ЭтаФорма.мСлужебныеДанные; Исключение КонецПопытки; #Если Клиент Тогда КонецЕсли; #КонецЕсли Возврат Результат; КонецФункции Процедура ОчиститьПодчиненныеЭлементыФормыЛкс(Знач Родитель, КоличествоНеудаляемых = 1) Экспорт Если Ложь #Если Клиент Тогда Или ТипЗнч(Родитель) = Тип("Панель") #КонецЕсли Тогда Родитель.Страницы.Очистить(); ИначеЕсли Ложь #Если Клиент Тогда Или ТипЗнч(Родитель) = Тип("ТабличноеПоле") #КонецЕсли Тогда Родитель.Колонки.Очистить(); Иначе ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Родитель); ПодчиненныеЭлементы = Родитель.ПодчиненныеЭлементы; НачальноеКоличество = ПодчиненныеЭлементы.Количество(); Для Счетчик = 1 По НачальноеКоличество Цикл ПодчиненныйЭлемент = ПодчиненныеЭлементы[НачальноеКоличество - Счетчик]; Если ПодчиненныеЭлементы.Количество() > КоличествоНеудаляемых Тогда ЭтаФорма.Элементы.Удалить(ПодчиненныйЭлемент); Иначе // Статистически добавленные нельзя удалять ПодчиненныйЭлемент.Видимость = Ложь; КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры Процедура УстановитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы; #Если Сервер И Не Сервер Тогда НеготовыеСтраницы = Новый СписокЗначений; #КонецЕсли ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя); Если ЭлементСписка <> Неопределено И Готовность Тогда НеготовыеСтраницы.Удалить(ЭлементСписка); ИначеЕсли ЭлементСписка = Неопределено И Не Готовность Тогда НеготовыеСтраницы.Добавить(Страница.Имя); КонецЕсли; КонецПроцедуры Функция ПолучитьГотовностьДанныхСтраницыЛкс(ЭтаФорма, Страница, Готовность = Истина) Экспорт НеготовыеСтраницы = СлужебныеДанныеФормыЛкс(ЭтаФорма).НеготовыеСтраницы; #Если Сервер И Не Сервер Тогда НеготовыеСтраницы = Новый СписокЗначений; #КонецЕсли ЭлементСписка = НеготовыеСтраницы.НайтиПоЗначению(Страница.Имя); Результат = ЭлементСписка = Неопределено; Возврат Результат; КонецФункции Процедура СоздатьКолонкиТабличногоПоляЛкс(ТабличноеПоле, ЗаменитьКолонкуНомерСтроки = Ложь) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда ОчиститьПодчиненныеЭлементыФормыЛкс(ТабличноеПоле, 0); ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ТабличноеПоле); ПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(ТабличноеПоле); РеквизитыТаблицы = ЭтаФорма.ПолучитьРеквизиты(ПутьКДанным); Для Каждого РеквизитТаблицы Из РеквизитыТаблицы Цикл ПолеФормы = ЭтаФорма.Элементы.Добавить(ТабличноеПоле.Имя + РеквизитТаблицы.Имя, Тип("ПолеФормы"), ТабличноеПоле); ПолеФормы.Вид = ВидПоляФормы.ПолеВвода; Попытка ПолеФормы.ПутьКДанным = ПутьКДанным + "." + РеквизитТаблицы.Имя; Исключение // При РеквизитТаблицы.Имя = "КоличествоСтрок" КонецПопытки; КонецЦикла; Иначе ТабличноеПоле.СоздатьКолонки(); Если ЗаменитьКолонкуНомерСтроки И ТабличноеПоле.Значение.Колонки.Найти("НомерСтроки") <> Неопределено Тогда ТабличноеПоле.Колонки.НомерСтроки.Данные = ""; ТабличноеПоле.Колонки.НомерСтроки.ТолькоПросмотр = Истина; КонецЕсли; КонецЕсли; КонецПроцедуры Функция ДанныеСтрокиТабличногоПоляЛкс(ТабличноеПоле, Знач Строка = Неопределено) Экспорт Если ТипЗнч(ТабличноеПоле) = Тип("ТаблицаФормы") Тогда Если Строка = Неопределено Тогда Строка = ТабличноеПоле.ТекущаяСтрока; КонецЕсли; Если Строка <> Неопределено Тогда ДанныеТаблицы = ДанныеЭлементаФормыЛкс(ТабличноеПоле); #Если Сервер И Не Сервер Тогда ДанныеТаблицы = Новый ТаблицаЗначений; #КонецЕсли Строка = ДанныеТаблицы.НайтиПоИдентификатору(Строка); КонецЕсли; Иначе Если Строка = Неопределено Тогда Строка = ТабличноеПоле.ТекущиеДанные; КонецЕсли; КонецЕсли; Возврат Строка; КонецФункции Функция ПолучитьТипЗначенияЭлементаФормыЛкс(ЭлементФормы, ВызыватьИсключение = Истина) Экспорт Попытка ТипЗначения = ЭлементФормы.ТипЗначения; Исключение // Упр ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(ЭлементФормы); Попытка ТипЗначения = ЭтаФорма.мСлужебныеДанные.ТипыЗначений[ЭлементФормы.Имя]; Исключение Если ВызыватьИсключение Тогда ВызватьИсключение; КонецЕсли; КонецПопытки; КонецПопытки; Возврат ТипЗначения; КонецФункции // Чтобы функция всегда возвращала правильное значение в управлямой форме, должен быть // выполнен общий обработчик формы _ПриСозданииНаСервереИис. // // Параметры: // Поле - <тип> - // // Возвращаемое значение: // Функция ДанныеЭлементаФормыЛкс(Знач Элемент, выхПутьКДанным = "") Экспорт Попытка // Обычная форма Данные = Элемент.Значение; Попытка выхПутьКДанным = Элемент.Данные; Исключение // Колонка табличного поля выхПутьКДанным = Неопределено; КонецПопытки; Возврат Данные; Исключение КонецПопытки; Если Ложь #Если Клиент Тогда Или ТипЗнч(Элемент) = Тип("ПолеТабличногоДокумента") #КонецЕсли Тогда Данные = Элемент; Иначе ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(Элемент, Тип("УправляемаяФорма")); // Переменная ЭтаФорма используется в Вычислить ниже выхПутьКДанным = ПутьКДаннымЭлементаУправляемойФормыЛкс(Элемент, , ЭтаФорма); Если Не ЗначениеЗаполнено(выхПутьКДанным) Тогда выхПутьКДанным = Элемент.Имя; КонецЕсли; Попытка Данные = Вычислить("ЭтаФорма." + выхПутьКДанным); Исключение Данные = Неопределено; КонецПопытки; Если Данные = Неопределено Тогда ЧастыеИменаОбъектов = Новый Массив; ЧастыеИменаОбъектов.Добавить("Объект"); ЧастыеИменаОбъектов.Добавить("Запись"); ЧастыеИменаОбъектов.Добавить("Отчет"); ЧастыеИменаОбъектов.Добавить("Обработка"); ЧастыеИменаОбъектов.Добавить("Задача"); Для Каждого ИмяОбъекта Из ЧастыеИменаОбъектов Цикл выхПутьКДанным = ИмяОбъекта + "." + Элемент.Имя; Попытка Данные = Вычислить("ЭтаФорма." + выхПутьКДанным); Прервать; Исключение КонецПопытки; КонецЦикла; Если Данные = Неопределено Тогда Для Счетчик = 1 По СтрДлина(Элемент.Имя) Цикл выхПутьКДанным = Лев(Элемент.Имя, Счетчик) + "." + Сред(Элемент.Имя, Счетчик + 1); Попытка Данные = Вычислить("ЭтаФорма." + выхПутьКДанным); Прервать; Исключение КонецПопытки; КонецЦикла; КонецЕсли; Если Данные = Неопределено Тогда выхПутьКДанным = Неопределено; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Данные; КонецФункции Функция ИдентификаторСтрокиТабличногоПоляЛкс(Знач НоваяСтрока) Экспорт Если Ложь Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементКоллекции") Или ТипЗнч(НоваяСтрока) = Тип("ДанныеФормыЭлементДерева") Тогда НоваяСтрока = НоваяСтрока.ПолучитьИдентификатор(); КонецЕсли; Возврат НоваяСтрока; КонецФункции Функция НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт Структура = Новый Структура(Свойство); Для каждого Элемент Из Коллекция Цикл Если Истина И ТипЭлемента <> Неопределено И ТипЗнч(Элемент) <> ТипЭлемента Тогда Продолжить; КонецЕсли; ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство); Если Структура[Свойство] = Значение Тогда Результат = Элемент; Прервать; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ЗначенияСвойстваКоллекцииЛкс(Знач Коллекция, Знач Свойство = "Имя", Знач ТипЭлемента = Неопределено) Экспорт Результат = Новый Массив; Для каждого Элемент Из Коллекция Цикл Если Истина И ТипЭлемента <> Неопределено И ТипЗнч(Элемент) <> ТипЭлемента Тогда Продолжить; КонецЕсли; Результат.Добавить(Элемент[Свойство]); КонецЦикла; Возврат Результат; КонецФункции Функция РежимОтладкиИзКоманднойСтрокиЛкс(Знач СтрокаЗапускаПроцесса) Экспорт МаркерОтладки = "-debug"; ПозицияСтрокиТипаОтладчика = Найти(НРег(СтрокаЗапускаПроцесса), Нрег(МаркерОтладки)); Если ЗначениеЗаполнено(ПозицияСтрокиТипаОтладчика) Тогда СтрокаОтладчика = СокрЛ(Сред(СтрокаЗапускаПроцесса, ПозицияСтрокиТипаОтладчика + СтрДлина(МаркерОтладки))); Если Найти(НРег(СтрокаОтладчика), "-http") = 1 Тогда РежимОтладки = "http"; Иначе РежимОтладки = "tcp"; КонецЕсли; Иначе РежимОтладки = "нет"; КонецЕсли; Возврат РежимОтладки; КонецФункции // Заполнить() Функция СтрЗаменитьЛкс(ГдеЗаменять, Знач ЧтоЗаменять, Знач НаЧтоЗаменять, ОставитьЧтоЗаменять = Ложь, ВыброситьИсключениеПриОтсутствии = Истина) Экспорт Если ВыброситьИсключениеПриОтсутствии И Найти(ГдеЗаменять, ЧтоЗаменять) < 1 Тогда ВызватьИсключение "Шаблонная строка """ + ЧтоЗаменять + """ не найдена в тексте"; КонецЕсли; Если ОставитьЧтоЗаменять Тогда НаЧтоЗаменять = ЧтоЗаменять + НаЧтоЗаменять; КонецЕсли; ГдеЗаменять = СтрЗаменить(ГдеЗаменять, ЧтоЗаменять, НаЧтоЗаменять); Возврат ГдеЗаменять; КонецФункции Функция СтрНайтиЛкс(Знач Строка, Знач ПодстрокаПоиска, Знач НаправлениеПоискаСКонца = Ложь, Знач НачальнаяПозиция = Неопределено, Знач НомерВхождения = 1) Экспорт Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803005 Тогда Возврат Вычислить("СтрНайти(Строка, ПодстрокаПоиска, ?(НаправлениеПоискаСКонца, НаправлениеПоиска.СКонца, НаправлениеПоиска.СНачала), НачальнаяПозиция, НомерВхождения)"); КонецЕсли; ТекущаяПозиция = 0; ЗнакНаправленияДвижения = 0; ДлинаСтрПоиска = СтрДлина(ПодстрокаПоиска); Попытка Если НачальнаяПозиция <> Неопределено Тогда НачальнаяПозиция = Число(НачальнаяПозиция); Если НачальнаяПозиция <= 0 ИЛИ НачальнаяПозиция > СтрДлина(Строка) Тогда ВызватьИсключение (""); КонецЕсли; КонецЕсли; Исключение ВызватьИсключение("Недопустимое значение параметра (параметр номер '4')"); КонецПопытки; Если НаправлениеПоискаСКонца Тогда НачальнаяПозиция = ?(НачальнаяПозиция <> Неопределено, НачальнаяПозиция, СтрДлина(Строка)); ЗнакНаправленияДвижения = -1; Иначе НачальнаяПозиция = ?(НачальнаяПозиция <> Неопределено, НачальнаяПозиция, 1); ЗнакНаправленияДвижения = 1; КонецЕсли; // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Пока Истина И НомерВхождения <> 0 И (Ложь Или (Истина И Не НаправлениеПоискаСКонца И НачальнаяПозиция <= СтрДлина(Строка)) Или (Истина И НаправлениеПоискаСКонца И НачальнаяПозиция >= 0)) Цикл Позиция = Найти(Сред(Строка, НачальнаяПозиция, ДлинаСтрПоиска), ПодстрокаПоиска); Если Позиция Тогда ТекущаяПозиция = НачальнаяПозиция; НачальнаяПозиция = ТекущаяПозиция + ДлинаСтрПоиска * ЗнакНаправленияДвижения; НомерВхождения = НомерВхождения - 1; Иначе НачальнаяПозиция = НачальнаяПозиция + 1 * ЗнакНаправленияДвижения; КонецЕсли; КонецЦикла; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Пока Истина   И НомерВхождения <> 0   И (Ложь   Или (Истина   И Не НаправлениеПоискаСКонца   И НачальнаяПозиция <= СтрДлина(Строка))   Или (Истина   И НаправлениеПоискаСКонца   И НачальнаяПозиция >= 0))   Цикл   Позиция = Найти(Сред(Строка, НачальнаяПозиция, ДлинаСтрПоиска), ПодстрокаПоиска);   Если Позиция Тогда   ТекущаяПозиция = НачальнаяПозиция;   НачальнаяПозиция = ТекущаяПозиция + ДлинаСтрПоиска * ЗнакНаправленияДвижения;   НомерВхождения = НомерВхождения - 1;   Иначе   НачальнаяПозиция = НачальнаяПозиция + 1 * ЗнакНаправленияДвижения;   КонецЕсли;   КонецЦикла;   Если НомерВхождения Тогда ТекущаяПозиция = 0; КонецЕсли; Возврат ТекущаяПозиция; КонецФункции // Функция разбивает строку разделителем. // // Параметры: // пСтрока - Строка - которую разбиваем; // *пРазделитель - Строка, "." - символ-разделитель; // *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП. // *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив. // // Возвращаемое значение: // Массив - фрагментов. // Функция СтрРазделитьЛкс(Знач Стр, Знач Разделитель = ".", Знач ОбрезатьНепечатныеСимволы = Ложь, Знач ОставлятьПустуюСтроку = Истина) Экспорт МассивСтрок = Новый Массив; Если Истина И Не ОставлятьПустуюСтроку И ПустаяСтрока(Стр) Тогда Возврат МассивСтрок; КонецЕсли; //Если Найти(Стр, Символы.ПС) = 0 Тогда // // Этот способ проще, но дольше и не допускает наличия переносов строк // ТекстовыйДокумент = Новый ТекстовыйДокумент; // ТекстовыйДокумент.УстановитьТекст(СтрЗаменить(Стр, Разделитель, Символы.ПС) + " "); // КоличествоСтрок = ТекстовыйДокумент.КоличествоСтрок(); // Для Счетчик = 1 По КоличествоСтрок Цикл // Фрагмент = ТекстовыйДокумент.ПолучитьСтроку(Счетчик); // Если ОбрезатьНепечатныеСимволы Тогда // Фрагмент = СокрЛП(Фрагмент); // КонецЕсли; // Если Счетчик = КоличествоСтрок Тогда // Фрагмент = Сред(Фрагмент, 1, СтрДлина(Фрагмент) - 1); // КонецЕсли; // МассивСтрок.Добавить(Фрагмент); // КонецЦикла; // //лСтрока = СтрЗаменить(Стр, Разделитель, Символы.ПС); // //// Баг платформы. СтрЧислоСтрок не учитывает терминальный перевод строки. // //ЧислоСтрок = СтрЧислоСтрок(лСтрока + " "); // //Для Счетчик = 1 По ЧислоСтрок Цикл // // Фрагмент = СтрПолучитьСтроку(лСтрока, Счетчик); // // Если ОбрезатьНепечатныеСимволы Тогда // // Фрагмент = СокрЛП(Фрагмент); // // КонецЕсли; // // МассивСтрок.Добавить(Фрагмент); // //КонецЦикла; // Оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. #Если Сервер И Не Сервер Тогда Если Разделитель = " " Тогда Стр = СокрЛП(Стр); Пока 1=1 Цикл Поз = Найти(Стр, Разделитель); Если Поз=0 Тогда МассивСтрок.Добавить(Стр); Возврат МассивСтрок; КонецЕсли; МассивСтрок.Добавить(Лев(Стр, Поз-1)); Стр = СокрЛ(Сред(Стр, Поз)); КонецЦикла; Иначе ДлинаРазделителя = СтрДлина(Разделитель); Пока 1=1 Цикл Поз = Найти(Стр, Разделитель); Если Поз=0 Тогда Фрагмент = Стр; Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Возврат МассивСтрок; КонецЕсли; Фрагмент = Лев(Стр, Поз-1); Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Стр = Сред(Стр, Поз+ДлинаРазделителя); КонецЦикла; КонецЕсли; #КонецЕсли // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы ""Инструменты разработчика"" (http://devtool1c.ucoz.ru) Если Разделитель = " " Тогда   Стр = СокрЛП(Стр);   Пока 1=1 Цикл   Поз = Найти(Стр, Разделитель);   Если Поз=0 Тогда   МассивСтрок.Добавить(Стр);   Возврат МассивСтрок;   КонецЕсли;   МассивСтрок.Добавить(Лев(Стр, Поз-1));   Стр = СокрЛ(Сред(Стр, Поз));   КонецЦикла;   Иначе   ДлинаРазделителя = СтрДлина(Разделитель);   Пока 1=1 Цикл   Поз = Найти(Стр, Разделитель);   Если Поз=0 Тогда   Фрагмент = Стр;   Если ОбрезатьНепечатныеСимволы Тогда   Фрагмент = СокрЛП(Фрагмент);   КонецЕсли;   МассивСтрок.Добавить(Фрагмент);   Возврат МассивСтрок;   КонецЕсли;   Фрагмент = Лев(Стр, Поз-1);   Если ОбрезатьНепечатныеСимволы Тогда   Фрагмент = СокрЛП(Фрагмент);   КонецЕсли;   МассивСтрок.Добавить(Фрагмент);   Стр = Сред(Стр, Поз+ДлинаРазделителя);   КонецЦикла;   КонецЕсли;   Возврат МассивСтрок; КонецФункции // Получает подстроку заключенную между первым вхождением начального маркера и первым вхождением // в правой части конечного маркера. Сами маркеры не включаются в результат. Опционально - если // маркер не найден, то границей считается граница строки. // // Параметры: // пСтрока - Строка - в которой ищем; // *пНачальныйМаркер - Строка, *Неопределено - начальный маркер подстроки; // *пКонечныйМаркер - Строка, *Неопределено - конечный маркер подстроки; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки // в случае, если маркер не найден; // *пЛиВключатьМаркеры - Булево, *Ложь - включение маркеров в результат. // // Возвращаемое значение: // Неопределено - обязательные условия не выполнены; // Строка – найденная подстрока. // Функция СтрокаМеждуМаркерамиЛкс(пСтрока, пНачальныйМаркер = Неопределено, пКонечныйМаркер = Неопределено, пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина, пЛиВключатьМаркеры = Ложь, ВыброситьИсключениеЕслиНеНайдено = Ложь) Экспорт ПозицияНачальногоМаркера = Найти(пСтрока, пНачальныйМаркер); Если Истина И ПозицияНачальногоМаркера = 0 И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь Тогда Если ВыброситьИсключениеЕслиНеНайдено Тогда ВызватьИсключение "Не найдено вхождение начального маркера"; Иначе Возврат Неопределено; КонецЕсли; КонецЕсли; Если Ложь ИЛИ пНачальныйМаркер = Неопределено ИЛИ ПозицияНачальногоМаркера = 0 Тогда ПозицияНачальногоМаркера = - СтрДлина(пНачальныйМаркер); КонецЕсли; Стр = Сред(пСтрока, ПозицияНачальногоМаркера + СтрДлина(пНачальныйМаркер)); ПозицияКонечногоМаркера = Найти(Стр, пКонечныйМаркер); Если Истина И ПозицияКонечногоМаркера = 0 И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь Тогда Если ВыброситьИсключениеЕслиНеНайдено Тогда ВызватьИсключение "Не найдено вхождение конечного маркера"; Иначе Возврат Неопределено; КонецЕсли; КонецЕсли; Если Ложь ИЛИ пКонечныйМаркер = Неопределено ИЛИ ПозицияКонечногоМаркера = 0 Тогда ПозицияКонечногоМаркера = СтрДлина(Стр) + 1; КонецЕсли; Результат = Лев(Стр, ПозицияКонечногоМаркера - 1); Если пЛиВключатьМаркеры Тогда Если пНачальныйМаркер <> Неопределено Тогда Результат = пНачальныйМаркер + Результат; КонецЕсли; Если пКонечныйМаркер <> Неопределено Тогда Результат = Результат + пКонечныйМаркер; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ПервыеНепечатныеСимволыЛкс(ТекстНовогоМетода) Экспорт RegExp = ирКэш.ВычислительРегулярныхВыраженийЛкс(); RegExp.Global = Ложь; RegExp.Pattern = "\S"; Результат = RegExp.Execute(ТекстНовогоМетода); Если Результат.Count > 0 Тогда ТекстСмещения = Лев(ТекстНовогоМетода, Результат.Item(0).FirstIndex); Иначе ТекстСмещения = ""; КонецЕсли; Возврат ТекстСмещения; КонецФункции Функция ЛиВнутриСтроковогоЛитералаЛкс(ТекущееНачалоСтроки) Экспорт Возврат (?(Лев(СокрЛ(ТекущееНачалоСтроки), 1) = "|", 1, 0) + СтрЧислоВхождений(ТекущееНачалоСтроки, """")) % 2 = 1; КонецФункции Функция НеблокирующиеМетаданныеБСП() Экспорт #Если ТолстыйКлиентУправляемоеПриложение Тогда ИменаМД = ирСервер.НеблокирующиеМетаданныеБСП(); #Иначе Массив = Новый Массив; ОбщегоНазначенияПереопределяемыйМой = Вычислить("ОбщегоНазначенияПереопределяемый"); #Если Сервер И Не Сервер Тогда ОбщегоНазначенияПереопределяемыйМой = ОбщегоНазначенияПереопределяемый; #КонецЕсли ОбщегоНазначенияПереопределяемыйМой.ПриДобавленииИсключенийПоискаСсылок(Массив); ИменаМД = Новый Массив; Для Каждого ОбъектМД Из Массив Цикл Если ТипЗнч(ОбъектМД) = Тип("ОбъектМетаданных") Тогда ПолноеИмяМД = ОбъектМД.ПолноеИмя(); Иначе ПолноеИмяМД = ОбъектМД; КонецЕсли; ИменаМД.Добавить(ПолноеИмяМД); КонецЦикла; #КонецЕсли Возврат ИменаМД; КонецФункции // Дополняет массив МассивПриемник значениями из массива МассивИсточник. // // Параметры: // МассивПриемник - Массив - массив, в который необходимо добавить значения. // МассивИсточник - Массив - массив значений для заполнения. // ТолькоУникальныеЗначения - Булево - если истина, то в массив будут включены только уникальные значения. // Процедура ДополнитьМассивЛкс(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт Если ТолькоУникальныеЗначения Тогда УникальныеЗначения = Новый Соответствие; Для Каждого Значение Из МассивПриемник Цикл УникальныеЗначения.Вставить(Значение, Истина); КонецЦикла; Для Каждого Значение Из МассивИсточник Цикл Если УникальныеЗначения[Значение] = Неопределено Тогда МассивПриемник.Добавить(Значение); УникальныеЗначения.Вставить(Значение, Истина); КонецЕсли; КонецЦикла; Иначе Для Каждого Значение Из МассивИсточник Цикл МассивПриемник.Добавить(Значение); КонецЦикла; КонецЕсли; КонецПроцедуры // Удаляет повторяющиеся элементы массива. // // Параметры: // Массив - Массив - массив произвольных значений. // // Возвращаемое значение: // Массив - коллекция уникальных элементов. // Функция СвернутьМассивЛкс(Массив) Экспорт Результат = Новый Массив; ДополнитьМассивЛкс(Результат, Массив, Истина); Возврат Результат; КонецФункции /////////////////////////////////////////////////// // Управляемые формы // Рекурсивно идет вверх до родителя нужного типа // Параметры: // ТипРодителя - Тип, *Неопределено - Неопределено=Тип("УправляемаяФорма") Возвращаемое значение: // Функция РодительЭлементаУправляемойФормыЛкс(Знач Элемент, ТипРодителя = Неопределено) Экспорт ТипУправляемаяФорма = Тип("УправляемаяФорма"); Если ТипРодителя = Неопределено Тогда ТипРодителя = ТипУправляемаяФорма; КонецЕсли; Пока ТипЗнч(Элемент) <> ТипРодителя Цикл Если ТипЗнч(Элемент) = ТипУправляемаяФорма Тогда Элемент = Неопределено; Прервать; КонецЕсли; Попытка Элемент = Элемент.Родитель; Исключение // Ошибка платформы http://www.hostedredmine.com/issues/880476 Родитель = Неопределено; Прервать; КонецПопытки; КонецЦикла; Возврат Элемент; КонецФункции // Путь - можно передавать как полный путь к реквизиту, так и путь к родительскому реквизиту // // Параметры: // ЭтаФорма - <тип> - // Путь - <тип>, "" - // ИмяРеквизита - <тип>, "" - // // Возвращаемое значение: // Функция ПолучитьРеквизитФормыЛкс(ЭтаФорма, Знач Путь = "", Знач ИмяРеквизита = "") Экспорт Если Не ЗначениеЗаполнено(ИмяРеквизита) Тогда Фрагменты = ирОбщий.СтрРазделитьЛкс(Путь); ИмяРеквизита = Фрагменты[Фрагменты.Количество() - 1]; Фрагменты.Удалить(Фрагменты.Количество() - 1); Путь = ирОбщий.СтрСоединитьЛкс(Фрагменты, "."); КонецЕсли; Результат = Неопределено; РеквизитыФормы = ЭтаФорма.ПолучитьРеквизиты(Путь); Для Каждого РеквизитФормы Из РеквизитыФормы Цикл Если НРег(РеквизитФормы.Имя) = Нрег(ИмяРеквизита) Тогда Результат = РеквизитФормы; Прервать; КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции // ПолучитьРеквизитФормы() // Получить тип реквизита формы // // Параметры: // ЭтаФорма - <тип> - // Путь - <тип>, "" - // ИмяРеквизита - <тип> - // // Возвращаемое значение: // Функция ПолучитьТипРеквизитаФормыЛкс(ЭтаФорма, Путь = "", ИмяРеквизита = "") Экспорт РеквизитФормы = ПолучитьРеквизитФормыЛкс(ЭтаФорма, Путь, ИмяРеквизита); Результат = РеквизитФормы.ТипЗначения.Типы()[0]; Возврат Результат; КонецФункции // ПолучитьРеквизитФормы() // Получить путь К данным элемента управляемой формы. Чтобы функция возвращала правильное значение, в форме должен быть // выполнен общий обработчик формы _ПриСозданииНаСервереИис. // // Параметры: // Поле - <тип> - // // Возвращаемое значение: // Функция ПутьКДаннымЭлементаУправляемойФормыЛкс(Знач ЭлементФормы, ОтносительноРодителя = Ложь, Знач ЭтаФорма = Неопределено) Экспорт Если ЭтаФорма = Неопределено Тогда ЭтаФорма = РодительЭлементаУправляемойФормыЛкс(ЭлементФормы, Тип("УправляемаяФорма")); КонецЕсли; ПутьКДаннымПоля = ""; Если ЭлементФормы <> ЭтаФорма Тогда СнимокФормы = Новый Структура("мСлужебныеДанные"); ЗаполнитьЗначенияСвойств(СнимокФормы, ЭтаФорма); //СообщитьЛкс(Поле.Имя); // Для отладки http://www.hostedredmine.com/issues/850205, http://www.hostedredmine.com/issues/850204 Если СнимокФормы.мСлужебныеДанные <> Неопределено И Не ЭтаФорма.мСлужебныеДанные.ПутиКДанным.Свойство(ЭлементФормы.Имя, ПутьКДаннымПоля) Тогда ПутьКДаннымПоля = ""; КонецЕсли; Если ОтносительноРодителя Тогда ПутьКДаннымПоля = ПоследнийФрагментЛкс(ПутьКДаннымПоля); КонецЕсли; КонецЕсли; Возврат ПутьКДаннымПоля; КонецФункции Процедура СкопироватьКнопкиКоманднойПанелиУправляемойФормыЛкс(Знач КоманднаяПанельИсточник, Знач КоманднаяПанельПриемник, Знач ПрефиксИмени) Экспорт ЭтаФорма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(КоманднаяПанельИсточник); ЭлементыФормы = ЭтаФорма.Элементы; Для Каждого КнопкаОбразец Из КоманднаяПанельИсточник.ПодчиненныеЭлементы Цикл Если Ложь Или ТипЗнч(КнопкаОбразец) = Тип("ГруппаФормы") Или Не ЗначениеЗаполнено(КнопкаОбразец.ИмяКоманды) Тогда // Это - системная команда Продолжить; КонецЕсли; ИмяНовойКнопки = ПрефиксИмени + КнопкаОбразец.Имя; НоваяКнопка = ЭлементыФормы.Добавить(ИмяНовойКнопки, ТипЗнч(КнопкаОбразец), КоманднаяПанельПриемник); ЗаполнитьЗначенияСвойств(НоваяКнопка, КнопкаОбразец,, "Имя"); КонецЦикла; КонецПроцедуры Функция НайтиСтрокуДереваФормыПоАдресуЛкс(НачальнаяСтрока, КлючиУровней, Знач ИмяКлючевойКолонки = "Ссылка") Экспорт ТекущаяСтрока = НачальнаяСтрока; Уровень = 0; Для Уровень = 0 По КлючиУровней.Количество() - 1 Цикл ЭлементыДерева = ТекущаяСтрока.ПолучитьЭлементы(); лТекущаяСтрока = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыДерева, ИмяКлючевойКолонки, КлючиУровней[Уровень]); Если лТекущаяСтрока <> Неопределено Тогда ТекущаяСтрока = лТекущаяСтрока; Иначе Прервать; КонецЕсли; КонецЦикла; Возврат ТекущаяСтрока; КонецФункции Процедура НастроитьЗаголовкиАвтоТаблицыФормыДинамическогоСпискаЛкс(Знач ОсновнойЭУ, Знач ПолноеИмяТаблицы, Знач РежимИмяСиноним) Экспорт ПоляТаблицы = ирОбщий.ПолучитьПоляТаблицыМДЛкс(ПолноеИмяТаблицы); ПоляТаблицы = ПоляТаблицы.Скопировать(); СтрокаПоляИденитификатора = ПоляТаблицы.Добавить(); СтрокаПоляИденитификатора.Имя = "ИдентификаторСсылкиЛкс"; СтрокаПоляИденитификатора.Заголовок = "Идентификатор ссылки"; Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл Колонка = ОсновнойЭУ.ПодчиненныеЭлементы.Найти(ОсновнойЭУ.Имя + ПолеТаблицы.Имя); Если Колонка = Неопределено Тогда Продолжить; КонецЕсли; Если РежимИмяСиноним Тогда Колонка.Заголовок = ПолеТаблицы.Имя; Иначе Колонка.Заголовок = ПолеТаблицы.Заголовок; КонецЕсли; КонецЦикла; КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка()