//////////////////////////////////////////////////////////////////////////////// // Подсистема "Инструменты разработчика" // // Авторское право (с) 2007, Старых С.А. // Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме, // с модификациями или без, при соблюдении следующих условий: // - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском // праве, этот список условий и нижеследующий отказ от гарантий. // - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об // авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других // материалах, поставляемых при распространении. // // ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ" // БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, // ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ, // ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ // ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО // РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ // ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ, // НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА // ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ // ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ. #Если Не ТонкийКлиент И Не ВебКлиент Тогда //////////////////////////////////////////////////////////////////////////////// // РАБОТА С МЕТАДАННЫМИ И ТИПАМИ // Получает массив имен всех примитивных типов. // // Параметры: // Нет. // // Возвращаемое значение: // Массив – имен типов. // Функция ЛксПолучитьПримитивныеТипы(Имена = Ложь) Экспорт МассивИменТипов = Новый Массив; МассивИменТипов.Добавить("Null"); МассивИменТипов.Добавить("Неопределено"); МассивИменТипов.Добавить("Число"); МассивИменТипов.Добавить("Строка"); МассивИменТипов.Добавить("Дата"); МассивИменТипов.Добавить("Булево"); МассивИменТипов.Добавить("Тип"); Если Имена Тогда МассивТипов = МассивИменТипов; Иначе МассивТипов = Новый Массив; Для Каждого ИмяТипа Из МассивИменТипов Цикл МассивТипов.Добавить(Тип(ИмяТипа)); КонецЦикла; КонецЕсли; Возврат МассивТипов; КонецФункции // ЛксПолучитьПримитивныеТипы() // Получает тип из описания типов, типа или значения. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Тип - найденный тип. // Функция ЛксПолучитьТипОбъекта(пОбъект) ТипОбъекта = Тип("Неопределено"); ТипПараметра = ТипЗнч(пОбъект); Если ТипПараметра = Тип("ОписаниеТипов") Тогда Если пОбъект.Типы().Количество() > 0 Тогда ТипОбъекта = пОбъект.Типы()[0]; КонецЕсли; ИначеЕсли ТипПараметра <> Тип("Тип") Тогда ТипОбъекта = ТипПараметра; Иначе ТипОбъекта = пОбъект; КонецЕсли; Возврат ТипОбъекта; КонецФункции // ЛксПолучитьТипОбъекта() // Проверяет, является ли строка именем корневого типа объекта БД. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом объекта БД; // Ложь – иначе. // Функция ЛксЛиКорневойТипОбъектаБД(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "БизнесПроцесс" ИЛИ КорневойТип = "Задача" ИЛИ КорневойТип = "Документ" ИЛИ КорневойТип = "ПланВидовРасчета" ИЛИ КорневойТип = "ПланВидовХарактеристик" ИЛИ КорневойТип = "ПланОбмена" ИЛИ КорневойТип = "ПланСчетов" ИЛИ КорневойТип = "Справочник" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКорневойТипОбъектаБД() // Проверяет, является ли строка именем корневого типа ссылки. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом ссылки; // Ложь – иначе. // Функция ЛксЛиКорневойТипСсылки(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "Перечисление" ИЛИ КорневойТип = "ТочкаМаршрутаБизнесПроцессаСсылка" ИЛИ ЛксЛиКорневойТипОбъектаБД(КорневойТип) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКорневойТипСсылки() // Проверяет, является ли строка именем корневого типа регистра БД. // // Параметры: // пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа. // // Возвращаемое значение: // Истина – тип является корневым типом регистра БД; // Ложь – иначе. // Функция ЛксЛиКорневойТипРегистраБД(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "РегистрСведений" ИЛИ КорневойТип = "РегистрНакопления" ИЛИ КорневойТип = "РегистрБухгалтерии" ИЛИ КорневойТип = "РегистрРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКорневойТипРегистраБД() Функция ЛксЛиКорневойТипПоследовательности(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "Последовательность" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛксЛиКорневойТипЖурналаДокументов(КорневойТип) Экспорт Если Ложь ИЛИ КорневойТип = "ЖурналДокументов" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ЛксЛиКорневойТипТаблицыБД(КорневойТип) Экспорт Если Ложь Или ЛксЛиКорневойТипЖурналаДокументов(КорневойТип) Или ЛксЛиКорневойТипОбъектаБД(КорневойТип) Или ЛксЛиКорневойТипРегистраБД(КорневойТип) Или ЛксЛиКорневойТипПоследовательности(КорневойТип) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // Проверяет, является ли строка именем типа вложенной таблицы БД. // // Параметры: // ТипТаблицы - Строка, Неопределено - имя типа таблицы. // // Возвращаемое значение: // Булево. // Функция ЛксЛиТипВложеннойТаблицыБД(ТипТаблицы) Экспорт Если Ложь ИЛИ ТипТаблицы = "ТабличнаяЧасть" ИЛИ ТипТаблицы = "ВидыСубконто" ИЛИ ТипТаблицы = "БазовыеВидыРасчета" ИЛИ ТипТаблицы = "ВедущиеВидыРасчета" ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиТипВложеннойТаблицыБД() // Проверяет, корневой тип на наличие реквизита "Код". // // Параметры: // КорневойТип - Строка, Произвольный. // // Возвращаемое значение: // Истина – реквизит "Код" имеется; // Ложь – иначе. // Функция ЛксЛиКорневойТипОбъектаСКодом(КорневойТип) Экспорт Если Ложь Или КорневойТип = "ПланВидовХарактеристик" Или КорневойТип = "ПланОбмена" Или КорневойТип = "ПланСчетов" Или КорневойТип = "ПланРасчета" Или КорневойТип = "Справочник" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКорневойТипОбъектаСКодом() // Проверяет, корневой тип на наличие реквизита "Предопределенный". // // Параметры: // КорневойТип - Строка, Произвольный. // // Возвращаемое значение: // Истина – реквизит "Предопределенный" имеется; // Ложь – иначе. // Функция ЛксЛиКорневойТипОбъектаСПредопределенным(КорневойТип) Экспорт Если Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланСчетов" Или КорневойТип = "ПланВидовХарактеристик" Или КорневойТип = "ПланВидовРасчета" Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКорневойТипОбъектаСПредопределенным() // Проверяет, метаданные на иерархию. // Иначе говоря проверяется начилие реквизита "Родитель". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией; // Ложь – иначе. // Функция ЛксЛиМетаданныеИерархическогоОбъекта(пМетаданныеТипа) Экспорт КорневойТип = ЛксПолучитьКорневойТипКонфигурации(пМетаданныеТипа); Если Ложь Или КорневойТип = "ПланСчетов" Или (Истина И (Ложь Или КорневойТип = "Справочник" Или КорневойТип = "ПланВидовХарактеристик") И пМетаданныеТипа.Иерархический) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиМетаданныеИерархическогоОбъекта() // Проверяет, метаданные на иерархию с группами. // Иначе говоря проверяется начилие реквизита "ЭтоГруппа". // // Параметры: // пМетаданныеТипа - ОбъектМетаданных, Неопределено. // // Возвращаемое значение: // Истина – метаданные с иерархией групп; // Ложь – иначе. // Функция ЛксЛиМетаданныеОбъектаСГруппами(пМетаданныеТипа) Экспорт //КорневойТип = ЛксПолучитьКорневойТипКонфигурации(пМетаданныеТипа); ТипТаблицы = ирНеглобальный.ПолучитьТипТаблицыБДЛкс(пМетаданныеТипа); Если Ложь Или (Истина И ТипТаблицы = "Справочник" И пМетаданныеТипа.Иерархический И пМетаданныеТипа.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов) Или (Истина И ТипТаблицы = "ПланВидовХарактеристик" И пМетаданныеТипа.Иерархический) Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиМетаданныеОбъектаСГруппами() // Проверяет, является ли значение ссылкой на объект БД. // // Параметры: // пЗначение – ОбъектМетаданных, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является ссылкой на объект БД; // Ложь – значение не является ссылкой на объект БД. // Функция ЛксЛиСсылкаНаОбъектБД(пЗначение) Экспорт Возврат ЛксЛиКорневойТипОбъектаБД(ЛксПолучитьКорневойТипКонфигурации(пЗначение, Истина)); КонецФункции // ЛксЛиСсылкаНаОбъектБД // Проверяет, является ли значение ссылкой на значение перечисления. // // Параметры: // пЗначение – Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является ссылкой на объект БД; // Ложь – значение не является ссылкой на объект БД. // Функция ЛксЛиСсылкаНаПеречисление(пЗначение) Экспорт Возврат (ЛксПолучитьКорневойТипКонфигурации(пЗначение) = "Перечисление"); КонецФункции // ЛксЛиСсылкаНаПеречисление() // Проверяет, является ли ключом записи регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип ключа записи регистра подтвержден; // Ложь – тип ключа записи регистра не подтвержден. // Функция ЛксЛиКлючЗаписиРегистра(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "ключ записи:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКлючЗаписиРегистра() // Проверяет, является ли записью регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип записи регистра подтвержден; // Ложь – тип записи регистра не подтвержден. // Функция ЛксЛиЗаписьРегистра(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "запись:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиКлючЗаписиБД() // Проверяет, является ли набором записей регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип набора записей регистра подтвержден; // Ложь – тип набора записей регистра не подтвержден. // Функция ЛксЛиНаборЗаписейРегистра(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "набор записей:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиНаборЗаписейРегистра() // Проверяет, является ли субконтом описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип субконто подтвержден; // Ложь – тип субконто не подтвержден. // Функция ЛксЛиСубконто(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "субконто:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиСубконто() // Проверяет, является ли менеджером записи регистра описание типов, тип или значение. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Тип, ОписаниеТипов, Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – тип менеджер записи регистра подтвержден; // Ложь – тип менеджер записи регистра не подтвержден. // Функция ЛксЛиМенеджерЗаписиРегистра(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "менеджер записи:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиМенеджерЗаписиРегистра() // Проверяет, является ли значение табличной частью внешней обработки. // // Параметры: // пЗначение – Произвольный – проверяемое значение. // // Возвращаемое значение: // Истина – значение является табличной частью внешней обработки; // Ложь – значение не является табличной частью внешней обработки. // Функция ЛксЛиТабличнаяЧастьВнешнейОбработки(пЗначение) Экспорт СтрокаТипЗначения = ЛксПолучитьПервыйФрагмент(Строка(пЗначение)); Возврат (СтрокаТипЗначения = "ВнешняяОбработкаТабличнаяЧасть"); КонецФункции // ЛксЛиВнешняяОбработка() // Получает ссылочный тип по метаданным. // // Параметры: // пМетаданные – ОбъектМетаданных. // // Возвращаемое значение: // – Тип - ссылочный; // Неопределено – тип нельзя получить. // Функция ЛксПолучитьСсылочныйТипПоМетаданным(пМетаданные) Экспорт Результат = Неопределено; КорневойТип = ЛксПолучитьКорневойТипКонфигурации(пМетаданные, Истина); Если ЛксЛиКорневойТипОбъектаБД(КорневойТип) Тогда Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя); КонецЕсли; Возврат Результат; КонецФункции // ЛксПолучитьСсылочныйТипПоМетаданным() // Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем метаданные. // // Возвращаемое значение: // – Метаданные - полученные; // Неопределено - не удалось получить метаданные. // Функция ЛксПолучитьМетаданные(пОбъект) Экспорт Если ТипЗнч(пОбъект) = Тип("Строка") Тогда Если ПустаяСтрока(пОбъект) Тогда Результат = Неопределено; Иначе Фрагменты = ЛксПолучитьМассивИзСтрокиСРазделителем(пОбъект); Если Фрагменты.Количество() = 3 Тогда // ВидыСубконто, Изменения ПолноеИмяМД = Фрагменты[0] + "." + Фрагменты[1]; Иначе ПолноеИмяМД = пОбъект; КонецЕсли; Результат = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД); КонецЕсли; Возврат Результат; КонецЕсли; ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Результат = Метаданные.НайтиПоТипу(ТипОбъекта); Возврат Результат; КонецФункции // ЛксПолучитьМетаданные() // Получает метаданные списка по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // // Параметры: // пОбъект – Произвольное – проверяемое значение. // // Возвращаемое значение: // – Метаданные - списка; // Неопределено – значение не является списком. // Функция ЛксПолучитьМетаданныеСписка(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); МаркерСписка = "список:"; Если Найти(Строка(ТипОбъекта), МаркерСписка) > 0 Тогда Возврат ЛксПолучитьМетаданные(ТипОбъекта); Иначе Возврат Неопределено; КонецЕсли; КонецФункции // ЛксПолучитьМетаданныеСписка() // Определяет корневой тип конфигурации по описанию типов, типу, метаданным, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем метаданные; // *пЛиТолькоДляКорневого - Булево, *Ложь - возвращать только для объекта корневого типа. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено - не удалось получить имя типа. // Функция ЛксПолучитьКорневойТипКонфигурации(пОбъект, пЛиТолькоДляКорневого = Ложь) Экспорт Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда МетаданныеТипа = пОбъект; Иначе МетаданныеТипа = ЛксПолучитьМетаданные(пОбъект); КонецЕсли; Результат = Неопределено; Если МетаданныеТипа <> Неопределено Тогда ПолноеИмя = МетаданныеТипа.ПолноеИмя(); Если пЛиТолькоДляКорневого Тогда МассивФрагментов = ЛксПолучитьМассивИзСтрокиСРазделителем(ПолноеИмя); Если МассивФрагментов.Количество() = 2 Тогда Результат = МассивФрагментов[0]; КонецЕсли; Иначе Результат = ЛксПолучитьПервыйФрагмент(ПолноеИмя); КонецЕсли; КонецЕсли; Если Результат = "ТабличнаяЧасть" Тогда // Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект Результат = Неопределено; КонецЕсли; Возврат Результат; КонецФункции // ЛксПолучитьКорневойТипКонфигурации() // Определяет имя корневого типа строки табличной части по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем корневой тип строки табличной части. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является строкой табличной части. // Функция ЛксПолучитьКорневойТипСтрокиТабличнойЧасти(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "табличная часть строка:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат ЛксПолучитьПервыйФрагмент(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя()); КонецЕсли; Возврат Неопределено; КонецФункции // ЛксПолучитьКорневойТипСтрокиТабличнойЧасти() // Определяет имя корневого типа табличной части по описанию типов, типу, метаданным, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего определяем корневой тип. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является строкой табличной части. // Функция ЛксПолучитьКорневойТипТабличнойЧасти(пОбъект) Экспорт Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда МетаданныеТипа = пОбъект; Иначе МетаданныеТипа = ЛксПолучитьМетаданные(пОбъект); КонецЕсли; Если МетаданныеТипа <> Неопределено Тогда ПолноеИмя = МетаданныеТипа.ПолноеИмя(); МассивФрагментов = ЛксПолучитьМассивИзСтрокиСРазделителем(ПолноеИмя); Если Истина И МассивФрагментов.Количество() >= 4 И МассивФрагментов[2] = "ТабличнаяЧасть" Тогда Возврат МассивФрагментов[2]; КонецЕсли; КонецЕсли; Возврат Неопределено; КонецФункции // ЛксПолучитьКорневойТипТабличнойЧасти() // Определяет имя корневого типа списка по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем корневой тип строки табличной части. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является списком. // Функция ЛксПолучитьКорневойТипСписка(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "список:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат ЛксПолучитьПервыйФрагмент(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя()); КонецЕсли; Возврат Неопределено; КонецФункции // ЛксПолучитьКорневойТипСписка() // Определяет имя корневого типа ссылки по описанию типов, типу или значению. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем корневой тип строки табличной части. // // Возвращаемое значение: // - Строка – имя типа корневого объекта метаданных; // Неопределено – значение не является ссылкой. // Функция ЛксПолучитьКорневойТипСсылки(пОбъект) Экспорт ТипОбъекта = ЛксПолучитьТипОбъекта(пОбъект); Маркер = "ссылка:"; Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда Возврат ЛксПолучитьПервыйФрагмент(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя()); КонецЕсли; Возврат Неопределено; КонецФункции // ЛксПолучитьКорневойТипСписка() // Определяет имя табличной части по ее метаданным. // // Параметры: // пМетаданные – ОбъектМетаданных – который проверяем. // // Возвращаемое значение: // - Строка – имя табличной части; // Неопределено – это метаданные не табличной части. // Функция ЛксПолучитьИмяТабличнойЧасти(пМетаданные) Экспорт Если пМетаданные <> Неопределено Тогда МассивФрагментов = ЛксПолучитьМассивИзСтрокиСРазделителем(пМетаданные.ПолноеИмя()); Если МассивФрагментов.ВГраница() >= 2 Тогда Если МассивФрагментов[2] = "ТабличнаяЧасть" Тогда Возврат МассивФрагментов[3]; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Неопределено; КонецФункции // ЛксПолучитьИмяТабличнойЧасти() // Получает менеджер по описанию типов, типу, метаданным, ссылке или объекту. // Для описания типов берется первый тип массива типов. // // Параметры: // пОбъект – Произвольный – для чего получаем менеджер. // // Возвращаемое значение: // – МенеджерОбъекта - для ссылки или ссылочного типа; // Неопределено - не удалось получить. // Функция ЛксПолучитьМенеджер(пОбъект) Экспорт Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда МетаданныеОбъекта = пОбъект; Иначе МетаданныеОбъекта = ЛксПолучитьМетаданные(пОбъект); КонецЕсли; Если МетаданныеОбъекта = Неопределено Тогда Возврат Неопределено; КонецЕсли; МассивФрагментов = ЛксПолучитьМассивИзСтрокиСРазделителем(МетаданныеОбъекта.ПолноеИмя()); КорневойТип = МассивФрагментов[0]; Менеджер = Неопределено; Если Истина И МассивФрагментов.Количество() = 4 И КорневойТип = "ВнешнийИсточникДанных" Тогда ИмяТипаМенеджера = МассивФрагментов[0] + "ТаблицаМенеджер." + МассивФрагментов[1] + "." + МассивФрагментов[3]; Иначе //КорневойТип = ЛксПолучитьКорневойТипКонфигурации(МетаданныеОбъекта, Истина); // Изменил 02.03.2012 Если КорневойТип <> Неопределено Тогда ИмяТипаМенеджера = КорневойТип + "Менеджер." + МетаданныеОбъекта.Имя; Иначе ИмяТипаМенеджера = "Неопределено"; КонецЕсли; КонецЕсли; Попытка Менеджер = Новый (ИмяТипаМенеджера); Исключение КонецПопытки; Возврат Менеджер; КонецФункции // ЛксПолучитьМенеджер() // Получает запись регистра по ключу записи. // // Параметры: // пКлючЗаписи – КлючЗаписиРегистра – идентифицирующий запись. // // Возвращаемое значение: // – ЗаписьРегистра – найденная запись. // Функция ЛксПолучитьЗаписьРегистраПоКлючу(пКлючЗаписи) Экспорт МенеджерЗначения = ЛксПолучитьМенеджер(пКлючЗаписи); МенеджерЗаписи = МенеджерЗначения.СоздатьМенеджерЗаписи(); ЗаполнитьЗначенияСвойств(МенеджерЗаписи, пКлючЗаписи); МенеджерЗаписи.Прочитать(); Возврат МенеджерЗаписи; КонецФункции // ЛксПолучитьЗаписьРегистраПоКлючу() // Получает ключ записи регистра по записи или по структуре с указанием метаданных регистра. // // Параметры: // пЗапись – ЗаписьРегистра, Структура – идентифицирующие запись; // пМетаданныеЗначения - ОбъектМетаданных - регистра. // // Возвращаемое значение: // – КлючЗаписиРегистра – сформированный ключ. // Функция ЛксПолучитьКлючПоСтруктуреЗаписиРегистра(пЗапись, пМетаданныеЗначения) Экспорт КорневойТип = ЛксПолучитьКорневойТипКонфигурации(пМетаданныеЗначения); МенеджерЗначения = ЛксПолучитьМенеджер(пМетаданныеЗначения); СтруктураКлюча = Новый Структура; Для Каждого МетаИзмерение Из пМетаданныеЗначения.Измерения Цикл СтруктураКлюча.Вставить(МетаИзмерение.Имя, пЗапись[МетаИзмерение.Имя]); КонецЦикла; Если Ложь Или КорневойТип <> "РегистрСведений" Или НЕ пМетаданныеЗначения.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда СтруктураКлюча.Вставить("Период", пЗапись["Период"]); КонецЕсли; МенеджерЗаписи = МенеджерЗначения.СоздатьКлючЗаписи(СтруктураКлюча); Возврат МенеджерЗаписи; КонецФункции // ЛксПолучитьКлючПоСтруктуреЗаписиРегистра() // Получает список реквизитов объекта БД. // // Параметры: // пОбъект – определитель объекта метаданных; // *ЛиВключатьТолькоЧитаемые - Булево, *Ложь - включать ли в список только читаемые реквизиты; // *ЛиВключатьНедоступные - Булево, *Ложь - включать ли в список недоступные (группы/элементы) реквизиты; // *ЛиСортировать - Булево, *Ложь - отсортировать ли по представлению; // *ЛиСКартинками - Булево, *Ложь - добавлять ли картинки; // *ЛиСТабличнымиЧастями - Булево, *Ложь - включать ли в список табличные части. // // Возвращаемое значение: // СписокЗначений – содержащий в качестве значений имена реквизитов. // Функция ЛксПолучитьСписокРеквизитовОбъектаБД(пОбъект, ЛиВключатьТолькоЧитаемые = Ложь, ЛиВключатьНедоступные = Ложь, ЛиСортировать = Ложь, ЛиСКартинками = Ложь, ЛиСТабличнымиЧастями = Ложь) Экспорт СписокРеквизитов = Новый СписокЗначений; Если пОбъект = Неопределено Тогда Возврат СписокРеквизитов; КонецЕсли; Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда ОбъектМетаданных = пОбъект; Иначе ОбъектМетаданных = ЛксПолучитьМетаданные(пОбъект); КонецЕсли; КорневойТип = ЛксПолучитьКорневойТипКонфигурации(ОбъектМетаданных); ИерархияГрупп = Ложь; КартинкаРеквизита = Неопределено; #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.СлужебныйРеквизит; КонецЕсли; #КонецЕсли Если КорневойТип = "Задача" Тогда СписокРеквизитов.Добавить("БизнесПроцесс", "Бизнес процесс", , КартинкаРеквизита); СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита); Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита); КонецЕсли; Если ОбъектМетаданных.ДлинаНомера > 0 Тогда СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита); КонецЕсли; СписокРеквизитов.Добавить("ТочкаМаршрута", "Точка маршрута", , КартинкаРеквизита); СписокРеквизитов.Добавить("Выполнена", "Выполнена", , КартинкаРеквизита); Для Каждого Рекв из ОбъектМетаданных.РеквизитыАдресации Цикл СписокРеквизитов.Добавить(Рекв.Имя, Рекв.Представление(), , КартинкаРеквизита); КонецЦикла; КонецЕсли; Если КорневойТип = "Документ" Тогда СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита); Если ОбъектМетаданных.ДлинаНомера > 0 Тогда СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита); КонецЕсли; Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("Проведен", "Проведен", , КартинкаРеквизита); КонецЕсли; КонецЕсли; Если КорневойТип = "Справочник" Тогда Если ОбъектМетаданных.Владельцы.Количество() > 0 Тогда СписокРеквизитов.Добавить("Владелец", "Владелец", , КартинкаРеквизита); КонецЕсли; КонецЕсли; ЭтоГруппа = Ложь; Если ЛксЛиКорневойТипОбъектаСКодом(КорневойТип) Тогда Если ОбъектМетаданных.ДлинаКода > 0 Тогда СписокРеквизитов.Добавить("Код", "Код", , КартинкаРеквизита); КонецЕсли; Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита); КонецЕсли; Если ЛксЛиМетаданныеИерархическогоОбъекта(ОбъектМетаданных) Тогда СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита); Если ЛксЛиМетаданныеОбъектаСГруппами(ОбъектМетаданных) Тогда ИерархияГрупп = Истина; Если Не ЛиВключатьНедоступные Тогда ЭтоГруппа = пОбъект.ЭтоГруппа; КонецЕсли; Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ЛксЛиКорневойТипОбъектаСПредопределенным(КорневойТип) Тогда Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита); КонецЕсли; КонецЕсли; Если ЛксЛиКорневойТипОбъектаБД(КорневойТип) Тогда СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита); Если ЛиВключатьТолькоЧитаемые Тогда СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита); КонецЕсли; КонецЕсли; #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.Реквизит; КонецЕсли; #КонецЕсли Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл Если Ложь Или ЛиВключатьНедоступные Или Не ИерархияГрупп Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента Или (Истина И ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Или (Истина И Не ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Тогда СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл Если ирНеглобальный.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Если ЛиСТабличнымиЧастями Тогда #Если Клиент Тогда Если ЛиСКартинками Тогда КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть; КонецЕсли; #КонецЕсли Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл Если Ложь Или ЛиВключатьНедоступные Или Не ИерархияГрупп Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента Или (Истина И ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы) Или (Истина И Не ЭтоГруппа И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента) Тогда СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита); КонецЕсли; КонецЦикла; КонецЕсли; Если ЛиСортировать Тогда СписокРеквизитов.СортироватьПоПредставлению(); КонецЕсли; Возврат СписокРеквизитов; КонецФункции // ЛксПолучитьСписокРеквизитовОбъектаБД() // Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр". // // Параметры: // Порядок – Порядок. // // Возвращаемое значение: // Строка - для установки порядка. // Функция ЛксПолучитьСтрокуПорядка(Порядок) Экспорт Строка = ""; Для Каждого ЭлементПорядка Из Порядок Цикл Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " "; Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда Строка = Строка + "возр"; Иначе Строка = Строка + "убыв"; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 2); КонецФункции // ЛксПолучитьСтрокуПорядка() // Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода. // Безопасность заключается в том, что нет свойств локального контекста // и недоступны доопределенные Свойства глобального контекста. // // Параметры: // ТекстДляВыполнения – Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Процедура ЛксВыполнитьВКонтекстеОбщегоМодуля(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Выполнить(ТекстДляВыполнения); КонецПроцедуры // ЛксВыполнитьВКонтекстеОбщегоМодуля() // Получает копию произвольного объекта. Копирование производится через сериализацию. // // Параметры: // пОбъект – Произвольное – сохраняемое значение; // // Возвращаемое значение: // Произвольный - копия объекта. // Функция ЛксПолучитьКопиюОбъекта(пОбъект) Экспорт НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект)); Возврат НовыйОбъект; КонецФункции // ЛксПолучитьКопиюОбъекта() // Находит элемент коллекции по свойству "ПутьКДанным". // // Параметры: // пКоллекция – Коллекция – все элементы которой имеют свойство "ПутьКДанным"; // пПутьКДанным – Строка – искомое значение. // // Возвращаемое значение: // – ЭлементКоллекции; // Неопределено - не найден. // Функция ЛксНайтиЭлементКоллекцииПоПутиКДанным(пКоллекция, пПутьКДанным) Экспорт СуществующаяСтрока = Неопределено; Для Каждого ЭлементКоллеции Из пКоллекция Цикл Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда СуществующаяСтрока = ЭлементКоллеции; Прервать; КонецЕсли; КонецЦикла; Возврат СуществующаяСтрока; КонецФункции // ЛксНайтиЭлементКоллекцииПоПутиКДанным() // Находит поле настройки по пути к данным. // // Параметры: // пПоляНастройки – ПоляНастройки; // пПутьКДанным – Строка – путь к данным поля в виде разыменовывания; // *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю. // // Возвращаемое значение: // ПолеНастройки – найденное поле; // Неопределено - иначе. // Функция ЛксНайтиПолеНастройкиПоПутиКДанным(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт ПоляНастройки = пПоляНастройки; МассивФрагментов = ЛксПолучитьМассивИзСтрокиСРазделителем(пПутьКДанным); ТекущееПоле = Неопределено; Для Каждого Фрагмент Из МассивФрагментов Цикл пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент; ТекущееПоле = ЛксНайтиЭлементКоллекцииПоПутиКДанным(ПоляНастройки, пПутьКТекущемуПолю); Если ТекущееПоле = Неопределено Тогда Прервать; КонецЕсли; ПоляНастройки = ТекущееПоле.Поля; КонецЦикла; Возврат ТекущееПоле; КонецФункции // ЛксНайтиПолеНастройкиПоПутиКДанным() // Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно. // // Параметры: // пЭлементОтбораПриемник – ЭлементОтбора – куда копируем; // пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем. // Процедура ЛксСкопироватьЭлементОтбора(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование"); МассивСвойствЭлементаОтбора = Новый Массив; МассивСвойствЭлементаОтбора.Добавить("ВидСравнения"); МассивСвойствЭлементаОтбора.Добавить("Значение"); МассивСвойствЭлементаОтбора.Добавить("ЗначениеС"); МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо"); Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл Значение = пЭлементОтбораИсточник[Свойство]; Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда пЭлементОтбораПриемник[Свойство] = Значение; КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксСкопироватьЭлементОтбора() // Порт ЛксСкопироватьОтбор. Процедура ЛксСкопироватьОтборДинамическогоСписка(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь, ТолькоИспользуемые = Ложь) Экспорт ЛксСкопироватьОтбор(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие, ТолькоИспользуемые); КонецПроцедуры // ЛксСкопироватьОтборДинамическогоСписка() // Порт ЛксСкопироватьОтбор. Процедура ЛксСкопироватьОтборСтатический(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь, ТолькоИспользуемые = Ложь) Экспорт ЛксСкопироватьОтбор(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие, ТолькоИспользуемые); КонецПроцедуры // ЛксСкопироватьОтборСтатический() // Копирует отбор. // Если нужно, в приемнике создаются отсутствующие элементы отбора. // // Параметры: // пОтборПриемник – Отбор – куда копируем; // пОтборИсточник - Отбор, Структура - откуда копируем; // пСоздаватьОтсутствующие - Булево, *Ложь - признак создания отсутствующих элементов отбора в источнике. // Процедура ЛксСкопироватьОтбор(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь, ТолькоИспользуемые = Ложь) Экспорт //Если пСоздаватьОтсутствующие Тогда // ДоступныеПоля = пОтборПриемник.ПолучитьДоступныеПоля(); //КонецЕсли; Для Каждого ЭлементОтбораИсточника Из пОтборИсточник Цикл Если Истина И ТолькоИспользуемые И Не ЭлементОтбораИсточника.Использование Тогда Продолжить; КонецЕсли; Если ТипЗнч(ЭлементОтбораИсточника) = Тип("КлючИЗначение") Тогда ЭлементОтбораИсточника = ЭлементОтбораИсточника.Значение; КонецЕсли; //Если ЭлементОтбораИсточника.Имя = "" Тогда // Сообщить("Невозможно определить элемент отбора приемника при копировании отбора.", // СтатусСообщения.Внимание); // Продолжить; //КонецЕсли; ЭлементОтбораПриемника = пОтборПриемник.Найти(ЭлементОтбораИсточника.Имя); Если ЭлементОтбораПриемника = Неопределено Тогда Если Истина И пСоздаватьОтсутствующие //И ЛксНайтиПолеНастройкиПоПутиКДанным(ДоступныеПоля, ЭлементОтбораИсточника.ПутьКДанным) <> Неопределено Тогда Попытка ЭлементОтбораПриемника = пОтборПриемник.Добавить(ЭлементОтбораИсточника.ПутьКДанным, ЭлементОтбораИсточника.Имя); Исключение Продолжить; КонецПопытки; Иначе Продолжить; КонецЕсли; КонецЕсли; ЛксСкопироватьЭлементОтбора(ЭлементОтбораПриемника, ЭлементОтбораИсточника); КонецЦикла; КонецПроцедуры // ЛксСкопироватьОтбор() // Получает инвертированный вид сравнения. // // Параметры: // ВидСравнения – ВидСравнения. // // Возвращаемое значение: // ВидСравнения; // Функция ЛксПолучитьИнвертированныйВидСравнения(пВидСравнения) Экспорт МассивИнвертируемыхТиповСравнения = Новый Массив; МассивИнвертируемыхТиповСравнения.Добавить("ВИерархии"); МассивИнвертируемыхТиповСравнения.Добавить("ВСписке"); МассивИнвертируемыхТиповСравнения.Добавить("Равно"); МассивИнвертируемыхТиповСравнения.Добавить("Содержит"); МассивИнвертируемыхТиповСравнения.Добавить("ВСпискеПоИерархии"); Для Каждого ТипСравнения Из МассивИнвертируемыхТиповСравнения Цикл ПрямойТипСравнения = Вычислить("ВидСравнения." + ТипСравнения); Если ПрямойТипСравнения = пВидСравнения Тогда Возврат Вычислить("ВидСравнения.Не" + ТипСравнения); КонецЕсли; ОбратныйТипСравнения = Вычислить("ВидСравнения.Не" + ТипСравнения); Если ОбратныйТипСравнения = пВидСравнения Тогда Возврат Вычислить("ВидСравнения." + ТипСравнения); КонецЕсли; КонецЦикла; Возврат пВидСравнения; КонецФункции // ЛксПолучитьИнвертированныйВидСравнения() // Копирует один порядок в другой. Приемник перед копированием очищается. // // Параметры: // пПорядокПриемник – Порядок – куда копируем; // пПорядокИсточник - Порядок - откуда копируем. // Процедура ЛксСкопироватьПорядок(пПорядокПриемник, пПорядокИсточник) Экспорт пПорядокПриемник.Очистить(); Для Каждого ЭлементПорядка Из пПорядокИсточник Цикл пПорядокПриемник.Добавить(ЭлементПорядка.ПутьКДанным, ЭлементПорядка.Имя, , ЭлементПорядка.Направление); КонецЦикла; КонецПроцедуры // ЛксСкопироватьПорядок() // Возвращает текущее время в миллисекундах. // // Параметры: // Нет. // // Возвращаемое значение: // Число. // Функция ЛксПолучитьТекущееВремяВМиллисекундах() Экспорт Попытка Scr = Новый COMОбъект("MSScriptControl.ScriptControl"); Исключение Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат 0; КонецПопытки; Scr.Language = "javascript"; Время = Scr.Eval("new Date().getTime()"); Возврат Время; КонецФункции // Выполняет запрос. Опционально сообщает его текст и время выполнения. // Удобно для оптимизации. // // Параметры: // Запрос – Запрос; // *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения. // *Заголовок - Строка, *"" - название запроса. // // Возвращаемое значение: // РезультатЗапроса. // Функция ЛксВыполнитьЗамеритьЗапрос(Запрос, ЛиОтладка = Ложь, Заголовок = "") Экспорт Если ЛиОтладка Тогда ВремяНачала = ЛксПолучитьТекущееВремяВМиллисекундах(); КонецЕсли; Результат = Запрос.Выполнить(); Если ЛиОтладка Тогда Текст = Новый ТекстовыйДокумент; Текст.УстановитьТекст(Запрос.Текст); Текст.Показать(Заголовок + " - " + Строка(ЛксПолучитьТекущееВремяВМиллисекундах() - ВремяНачала) + " мс"); КонецЕсли; Возврат Результат; КонецФункции // ЛксВыполнитьЗамеритьЗапрос() // Получает константу языка запросов заданного типа с учетом квалификаторов описания типов. // // Параметры: // ТипПоля – Тип; // ОписаниеТипов - ОписаниеТипов - для обращения к квалифицаторам. // // Возвращаемое значение: // Строка. // Функция ЛксПолучитьКонстантуТипаЗапроса(ТипПоля, ОписаниеТипов = Неопределено) Экспорт Если ТипПоля = Тип("Строка") Тогда Результат = "ВЫРАЗИТЬ("""" КАК СТРОКА(" + Формат(ОписаниеТипов.КвалификаторыСтроки.Длина, "ЧН=; ЧГ=") + "))"; ИначеЕсли ТипПоля = Тип("Число") Тогда Результат = "ВЫРАЗИТЬ(0 КАК ЧИСЛО(" + Формат(ОписаниеТипов.КвалификаторыЧисла.Разрядность, "ЧН=; ЧГ=") + ", " + Формат(ОписаниеТипов.КвалификаторыЧисла.РазрядностьДробнойЧасти, "ЧН=; ЧГ=") + "))"; ИначеЕсли ТипПоля = Тип("Дата") Тогда Если ОписаниеТипов.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда Результат = "ДАТАВРЕМЯ(1,1,1)"; Иначе Результат = "ДАТАВРЕМЯ(1,1,1,0,0,0)"; КонецЕсли; ИначеЕсли ТипПоля = Тип("Булево") Тогда Результат = "ИСТИНА"; ИначеЕсли ТипПоля = Тип("NULL") Тогда Результат = "NULL"; ИначеЕсли ТипПоля = Тип("НЕОПРЕДЕЛЕНО") Тогда Результат = "НЕОПРЕДЕЛЕНО"; ИначеЕсли ТипПоля = Тип("ВидДвиженияНакопления") Тогда Результат = "ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)"; ИначеЕсли ТипПоля = Тип("ВидДвиженияБухгалтерии") Тогда Результат = "ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет)"; ИначеЕсли ТипПоля = Тип("ВидСчета") Тогда Результат = "ЗНАЧЕНИЕ(ВидСчета.Активный)"; Иначе МетаданныеТипаПоля = Метаданные.НайтиПоТипу(ТипПоля); Если МетаданныеТипаПоля <> Неопределено Тогда // Баг платформы 8.1.10.50 Если ЛксПолучитьКорневойТипКонфигурации(МетаданныеТипаПоля) = "ПланОбмена" Тогда Результат = "НЕОПРЕДЕЛЕНО"; Возврат Результат; КонецЕсли; Результат = "ЗНАЧЕНИЕ(" + МетаданныеТипаПоля.ПолноеИмя() + ".ПустаяСсылка)"; Иначе //Сообщить("Неизвестный тип поля при формировании имитатора результата: " + ТипПоля, СтатусСообщения.Важное); Результат = "NULL"; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьКонстантуТипаЗапроса() // Возвращает текст запроса только из констант, дающий идентичный переданному набор колонок. // // Параметры: // КоллекцияПолей – КоллекцияКолонокРезультатаЗапроса. // // Возвращаемое значение: // Текст. // Функция ЛксПолучитьЗапросИмитаторКоллекцииПолей(КоллекцияПолей) Экспорт // Формирование запроса-имитатора ОписаниеПолей = ""; Для Каждого Колонка Из КоллекцияПолей Цикл ОписаниеПолей = ОписаниеПолей + ", "; МассивТипов = Колонка.ТипЗначения.Типы(); НачальноеКоличество = МассивТипов.Количество(); Для СчетчикМассивТипов = 1 По НачальноеКоличество Цикл ТипПоля = МассивТипов[НачальноеКоличество - СчетчикМассивТипов]; Если ТипПоля = Тип("NULL") Тогда МассивТипов.Удалить(НачальноеКоличество - СчетчикМассивТипов); КонецЕсли; КонецЦикла; Если МассивТипов.Количество() = 0 Тогда ОписаниеПолей = ОписаниеПолей + "НЕОПРЕДЕЛЕНО"; ИначеЕсли МассивТипов.Количество() = 1 Тогда ТипПоля = МассивТипов[0]; ОписаниеПолей = ОписаниеПолей + ЛксПолучитьКонстантуТипаЗапроса(ТипПоля, Колонка.ТипЗначения); Иначе ОписаниеПолей = ОписаниеПолей + "ВЫБОР"; Для Каждого ТипПоля Из МассивТипов Цикл ОписаниеПолей = ОписаниеПолей + " КОГДА ЛОЖЬ ТОГДА " + ЛксПолучитьКонстантуТипаЗапроса(ТипПоля, Колонка.ТипЗначения); КонецЦикла; ОписаниеПолей = ОписаниеПолей + " КОНЕЦ"; КонецЕсли; ОписаниеПолей = ОписаниеПолей + " КАК " + Колонка.Имя; КонецЦикла; Результат = "ВЫБРАТЬ " + Сред(ОписаниеПолей, 3); Возврат Результат; КонецФункции // ЛксПолучитьЗапросИмитаторКоллекцииПолей() // Присваивает первому параметру второй в случае их неравенства. // Удобно использовать для избежания установки признака модифицированности // объекта в случае присвоения реквизиту объекта его же значения. // // Параметры: // Переменная – Произвольный – переменная, которой нужно присвоить значение; // Значение – Произвольный – присваиваемое значение; // // Возвращаемое значение: // Переменная – Произвольный - конечное значение переменной. // Функция ЛксПрисвоитьЕслиНеРавно(Переменная, Значение) Экспорт Если Переменная <> Значение Тогда Переменная = Значение; КонецЕсли; Возврат Переменная; КонецФункции // Получает индекс картинки отражающей корневой тип и статус ссылки. // Индекс потом используется с общей картинкой ЛксСостояниеСсылки. // // Параметры: // пСсылка – Ссылка – целевая; // *пЛиОпределятьСтатусСсылки - Булево, *Неопределено - признак необходимости определения статуса. // // Возвращаемое значение: // – Число – индекс картинки. // Функция ЛксПолучитьИндексКартинкиСсылки(пСсылка, пЛиОпределятьСтатусСсылки = Неопределено) Экспорт Если пЛиОпределятьСтатусСсылки = Неопределено Тогда //пЛиОпределятьСтатусСсылки = ПараметрыСеанса.ЛксОпределятьСтатусСсылкиПриВыводе; пЛиОпределятьСтатусСсылки = Ложь; КонецЕсли; КорневойТип = ЛксПолучитьКорневойТипКонфигурации(пСсылка); ИндексКартинки = -1; Если КорневойТип = "Документ" Тогда ИндексКартинки = 0; Если пЛиОпределятьСтатусСсылки Тогда Если пСсылка.Проведен Тогда ИндексКартинки = 0; ИначеЕсли пСсылка.ПометкаУдаления Тогда ИндексКартинки = 1; Иначе ИндексКартинки = 2; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "Справочник" Тогда ИндексКартинки = 3; Если пЛиОпределятьСтатусСсылки Тогда Если пСсылка.ПометкаУдаления Тогда ИндексКартинки = ?(пСсылка.ЭтоГруппа, 6, 4); Иначе ИндексКартинки = ?(пСсылка.ЭтоГруппа, 5, 3); КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "Задача" Тогда ИндексКартинки = 7; Если пЛиОпределятьСтатусСсылки Тогда Если пСсылка.ПометкаУдаления Тогда ИндексКартинки = 8; Иначе ИндексКартинки = 7; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда ИндексКартинки = 9; Если пЛиОпределятьСтатусСсылки Тогда Если пСсылка.ПометкаУдаления Тогда ИндексКартинки = 10; Иначе ИндексКартинки = 9; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "ПланОбмена" Тогда ИндексКартинки = 15; Если пЛиОпределятьСтатусСсылки Тогда Если пСсылка.ПометкаУдаления Тогда ИндексКартинки = 16; Иначе ИндексКартинки = 15; КонецЕсли; КонецЕсли; ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда ИндексКартинки = 17; //Если пЛиОпределятьСтатусСсылки Тогда // Если пСсылка.ПометкаУдаления Тогда // ИндексКартинки = 18; // Иначе // ИндексКартинки = 17; // КонецЕсли; //КонецЕсли; //ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда // ИндексКартинки = 11; // Если пЛиОпределятьСтатусСсылки Тогда // Если пСсылка.ПометкаУдаления Тогда // ИндексКартинки = 12; // Иначе // ИндексКартинки = 11; // КонецЕсли; // КонецЕсли; ИначеЕсли КорневойТип = "Перечисление" Тогда ИндексКартинки = 11; ИначеЕсли КорневойТип = "РегистрСведений" Тогда ИндексКартинки = 12; ИначеЕсли КорневойТип = "Константа" Тогда ИндексКартинки = 14; КонецЕсли; Возврат ИндексКартинки; КонецФункции // ЛксПолучитьИндексКартинкиСсылки() // Добавляет в таблицу значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЛксЗагрузитьВТаблицуЗначений(ТаблицаИсточник, ТаблицаПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт СтрокаСовпадающихКолонок = ""; Разделитель = ","; Если ТипЗнч(ТаблицаИсточник) = Тип("ТаблицаЗначений") Тогда КолонкиИсточника = ТаблицаИсточник.Колонки; Иначе КолонкиИсточника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаИсточник)).Реквизиты; КонецЕсли; Если ТипЗнч(ТаблицаПриемник) = Тип("ТаблицаЗначений") Тогда КолонкиПриемника = ТаблицаПриемник.Колонки; Иначе КолонкиПриемника = Метаданные.НайтиПоТипу(ТипЗнч(ТаблицаПриемник)).Реквизиты; КонецЕсли; Для каждого Колонка Из КолонкиПриемника Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); Для каждого СтрокаТаблицыИсточника Из ТаблицаИсточник Цикл СтрокаТаблицыПриемника = ТаблицаПриемник.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтрокаТаблицыИсточника, СтрокаСовпадающихКолонок); //Для каждого ЭлементМассива Из МассивСовпадающихКолонок Цикл // СтрокаТаблицыПриемника[ЭлементМассива] = СтрокаТаблицыИсточника[ЭлементМассива]; //КонецЦикла; Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаТаблицыПриемника, СтруктураНовыхЗначений); КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксЗагрузитьВТаблицуЗначений() // Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЛксЗагрузитьВДеревоЗначений(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию = Неопределено, СтруктураНовыхЗначений = Неопределено) Экспорт СтрокаСовпадающихКолонок = ""; Разделитель = ","; КолонкиИсточника = ДеревоИсточник.Колонки; Для каждого Колонка Из ДеревоПриемник.Колонки Цикл Если СтруктураНовыхЗначений <> Неопределено Тогда Если СтруктураНовыхЗначений.Свойство(Колонка.Имя) Тогда Продолжить; КонецЕсли; КонецЕсли; Если КолонкиИсточника.Найти(Колонка.Имя) <> Неопределено Тогда СтрокаСовпадающихКолонок = СтрокаСовпадающихКолонок + Разделитель+ Колонка.Имя; КонецЕсли; КонецЦикла; СтрокаСовпадающихКолонок = Сред(СтрокаСовпадающихКолонок, СтрДлина(Разделитель) + 1); ЛксЗагрузитьВСтрокиДереваЗначений(ДеревоИсточник, ДеревоПриемник, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок); КонецПроцедуры // ЛксЗагрузитьВДеревоЗначений() // Непростетирована. Добавляет в дерево значений строки из другой таблицы значений и // в них значения колонок с совпадающими наименованиями. // // Параметры: // ТаблицаИсточник - таблица значений, откуда берутся значения; // ТаблицаПриемник - таблица значений, куда добавляются строки; // *СтруктураЗначенийПоУмолчанию - Структура, *Неопределено - значения по умолчанию для добавляемых строк; // *СтруктураНовыхЗначений - Структура, *Неопределено - значения колонок для добавляемых строк, имеют высший приоритет. // Процедура ЛксЗагрузитьВСтрокиДереваЗначений(СтрокаРодительИсточника, СтрокаРодительПриемника, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок) Экспорт СтрокиПриемника = СтрокаРодительПриемника.Строки; Для каждого СтрокаИсточника Из СтрокаРодительИсточника.Строки Цикл СтрокаПриемника = СтрокиПриемника.Добавить(); Если СтруктураЗначенийПоУмолчанию <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураЗначенийПоУмолчанию); КонецЕсли; // Заполним значения в совпадающих колонках. ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, СтрокаСовпадающихКолонок); Если СтруктураНовыхЗначений <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтруктураНовыхЗначений); КонецЕсли; ЛксЗагрузитьВСтрокиДереваЗначений(СтрокаИсточника, СтрокаПриемника, СтруктураЗначенийПоУмолчанию, СтруктураНовыхЗначений, СтрокаСовпадающихКолонок); КонецЦикла; КонецПроцедуры // ЛксЗагрузитьВДеревоЗначений() // Выводит сообщение пользователю. Способ вывода определяется модальным режимом. // В модальном режиме используется Предупреждение(), в немодальном Сообщить(). // // Параметры: // ТекстСообщения – Строка; // МодальныйРежим – Булево, *Ложь; // *Статус - СтатусСообщения, *Неопределено. // Процедура ЛксСообщитьСУчетомМодальности(ТекстСообщения, МодальныйРежим = Ложь, Статус = Неопределено) Экспорт Если Статус = Неопределено Тогда Статус = СтатусСообщения.Обычное; КонецЕсли;; #Если Клиент Тогда Если МодальныйРежим Тогда Предупреждение(ТекстСообщения); Иначе #КонецЕсли Сообщить(ТекстСообщения, Статус); #Если Клиент Тогда КонецЕсли; #КонецЕсли КонецПроцедуры // ЛксСообщитьСУчетомМодальности() // Сообщает итог индикации (длительность). // // Параметры: // Индикатор – Структура – индикатора, полученная методом ЛксПолучитьИндикаторПроцесса. // Процедура ЛксСообщитьИтогИндикации(Индикатор) Экспорт ТекущаяДата = ТекущаяДата(); ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса; //Часов = Цел(ПрошлоВремени / 3600); //Осталось = ПрошлоВремени - (Часов * 3600); //Минут = Цел(ПрошлоВремени / 60); //Секунд = Цел(Цел(ПрошлоВремени - (Минут * 60))); //ПрошлоВремениСтрока = Формат(Часов, "ЧЦ=2; ЧН=00; ЧВН=") + ":" // + Формат(Минут, "ЧЦ=2; ЧН=00; ЧВН=") + ":" // + Формат(Секунд, "ЧЦ=2; ЧН=00; ЧВН="); ПрошлоВремениСтрока = формат(Дата(1,1,1) + ПрошлоВремени, "ДЛФ=T; ДП="); ТекстСообщения = Индикатор.ПредставлениеПроцесса + " завершено, обработано " + Индикатор.Счетчик + " элементов за " + ПрошлоВремениСтрока + " (" + ПрошлоВремени + " сек)."; Если Индикатор.Счетчик > 0 Тогда ТекстСообщения = ТекстСообщения + " Грубое среднее время обработки элемента - " + Формат(ПрошлоВремени / Индикатор.Счетчик * 1000, "ЧЦ=15; ЧДЦ=2; ЧН=") + " мс"; КонецЕсли; Сообщить(ТекстСообщения); КонецПроцедуры // ЛксОбработатьИндикатор() // Получает более подробное представление значения, чем штатное приведение к строковому типу. // // Параметры: // Значение – Произвольный – что нужно представить. // // Возвращаемое значение: // Строка – представление. // Функция ЛксПолучитьРасширенноеПредставлениеЗначения(Значение, КолонкаТабличногоПоля = Неопределено) Экспорт Результат = ""; КоличествоЭлементов = ирНеглобальный.ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение); Если КоличествоЭлементов <> Неопределено Тогда Результат = "(" + КоличествоЭлементов + ")"; КонецЕсли; Если ТипЗнч(Значение) = Тип("Граница") Тогда //Результат = "<" + Результат + ">"; Результат = Результат + Значение + ":" + Значение.ВидГраницы + ", " + Значение.Значение; ИначеЕсли Ложь Или ТипЗнч(Значение) = Тип("Массив") Или ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда //Результат = "<" + Результат + ">"; ПредставлениеКоллекции = ""; МаксимальноеЧислоДляПредставления = 10; Для Каждого ЭлементМассива Из Значение Цикл Если ПредставлениеКоллекции <> "" Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + ";"; КонецЕсли; ПредставлениеКоллекции = ПредставлениеКоллекции + ЭлементМассива; МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1; Если МаксимальноеЧислоДляПредставления = 0 Тогда ПредставлениеКоллекции = ПредставлениеКоллекции + ";..."; Прервать; КонецЕсли; КонецЦикла; Результат = Результат + Значение + ":" + ПредставлениеКоллекции; ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда ирПлатформа = ирКэш.Получить(); ИмяОбщегоТипа = ирПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(Значение); ПолноеИмяОсновногоКласса = ЛксПолучитьСтрокуМеждуМаркерами(ИмяОбщегоТипа, "{", "}", Ложь); ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", ""); Результат = Результат + ИмяОбщегоТипа; Иначе СтрокаФормата = ""; Если КолонкаТабличногоПоля <> Неопределено Тогда СтрокаФормата = КолонкаТабличногоПоля.Формат; Если Истина И ПустаяСтрока(СтрокаФормата) И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода") Тогда КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла; СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти; КонецЕсли; КонецЕсли; Результат = Результат + Формат(Значение, СтрокаФормата); КонецЕсли; Возврат Результат; КонецФункции // ЛксПолучитьПредставлениеЗначение() // Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств. // Отсутствие свойства приравнивается к значению Неопределено. // // Параметры: // Первый – Произвольный – первый объект для сравнения; // Второй – Произвольный – первый объект для сравнения; // СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения. // // Возвращаемое значение: // Булево – Равны ли значения всех указанных свойств. // Функция ЛксСравнитьЗначенияСвойств(Первый, Второй, СвойстваДляСравнения) Экспорт Структура1 = Новый Структура(СвойстваДляСравнения); ЗаполнитьЗначенияСвойств(Структура1, Первый); Структура2 = Новый Структура(СвойстваДляСравнения); ЗаполнитьЗначенияСвойств(Структура2, Второй); Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2); Возврат Результат; КонецФункции // ЛксСравнитьЗначенияСвойств() #Если Клиент Тогда // Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно. // Иными словам колонка отображает данные, хранимые отдельно. // // Параметры: // ОформлениеЯчейки – ОформлениеЯчейки // Значение - Произвольный - значение для отображения. // Процедура ЛксОформитьЯчейкуСРасширеннымЗначением(ОформлениеЯчейки, Значение, КолонкаТабличногоПоля = Неопределено) Экспорт ТипЗначения = ТипЗнч(Значение); Если Истина И ТипЗначения = Тип("Булево") И ОформлениеЯчейки.ОтображатьФлажок Тогда // Иначе КартинкаТипа = ирНеглобальный.ПолучитьПиктограммуТипаЛкс(ТипЗначения); Если КартинкаТипа <> Неопределено Тогда ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа); КонецЕсли; КонецЕсли; РасширенноеПредставление = ЛксПолучитьРасширенноеПредставлениеЗначения(Значение, КолонкаТабличногоПоля); Если Ложь Или ОформлениеЯчейки.Текст = РасширенноеПредставление Тогда Возврат; КонецЕсли; //ОформлениеЯчейки.ТолькоПросмотр = Истина; //ОформлениеЯчейки.ЦветФона = ЦветаСтиля.ирЦветФонаРасширенногоПредставленияЗначения; ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление); КонецПроцедуры // ЛксОформитьЯчейкуСРасширеннымЗначением() // Находит файлы в иерархии заданного каталога локальной файловой системы. // // Параметры: // Путь – Строка; // Маска – Строка. // // Возвращаемое значение: // Массив – элементы типа Файл. // Функция ЛксНайтиФайлыВИерархии(Путь, Маска) Экспорт НайденныеКаталоги = НайтиФайлы(Путь, "*.*"); МассивРезультатов = Новый Массив; Для каждого НайденныйФайл Из НайденныеКаталоги Цикл Если НайденныйФайл.ЭтоКаталог() Тогда МассивРезультатов.Добавить(ЛксНайтиФайлыВИерархии(НайденныйФайл.ПолноеИмя, Маска)); КонецЕсли; КонецЦикла; МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска)); Результат = Новый Массив; Для Каждого ЭлементРезультат Из МассивРезультатов Цикл Для Каждого Файл Из ЭлементРезультат Цикл Результат.Добавить(Файл); КонецЦикла; КонецЦикла; Возврат Результат; КонецФункции // ЛксНайтиФайлыВИерархии() // Проверяет, является ли тип типом элемента формы. // // Параметры: // пТип – Тип – проверяемый тип. // // Возвращаемое значение: // Истина – тип элемента формы подтвержден; // Ложь – тип элемента формы не подтвержден. // Функция ЛксЛиТипЭлементаФормы(пТип) Экспорт Если Ложь ИЛИ пТип = Тип("Индикатор") ИЛИ пТип = Тип("Кнопка") ИЛИ пТип = Тип("КоманднаяПанель") ИЛИ пТип = Тип("Надпись") ИЛИ пТип = Тип("Панель") ИЛИ пТип = Тип("Переключатель") ИЛИ пТип = Тип("ПолеВвода") ИЛИ пТип = Тип("ПолеВыбора") ИЛИ пТип = Тип("ПолеСписка") ИЛИ пТип = Тип("ПолеТекстовогоДокумента") ИЛИ пТип = Тип("ПолеТабличногоДокумента") ИЛИ пТип = Тип("ПолосаРегулирования") ИЛИ пТип = Тип("ТабличноеПоле") ИЛИ пТип = Тип("РамкаГруппы") ИЛИ пТип = Тип("Флажок") Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиТипЭлементаФормы() // Получает структуру свойств объекта по имени типа или объекту. // Свойства должны располагаться в порядке: // - общие, // - ролевые в порядке невлияния на предшествующие. // // Параметры: // пОбъект - Произвольный - имя типа или сам объект; // пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения. // // Возвращаемое значение: // – Структура – свойств. // Функция ЛксПолучитьСтруктуруСвойствОбъекта(пОбъект, пЛиДляСохранения = Ложь) Экспорт СтруктураСвойств = Новый Структура; ТипОбъекта = ТипЗнч(пОбъект); МетаОбъект = ЛксПолучитьМетаданные(ТипОбъекта); Если МетаОбъект <> Неопределено Тогда КорневойТип = ЛксПолучитьКорневойТипКонфигурации(МетаОбъект, Истина); Если Ложь ИЛИ КорневойТип = "Обработка" ИЛИ КорневойТип = "Отчет" Тогда Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; КонецЕсли; Если ЛксПолучитьКорневойТипСтрокиТабличнойЧасти(ТипОбъекта) <> Неопределено Тогда Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; КонецЕсли; Если Истина И ТипОбъекта <> Тип("Тип") И ТипОбъекта <> Тип("ОписаниеТипов") И ТипОбъекта <> Тип("ОбъектМетаданных") Тогда Если ЛксПолучитьКорневойТипСписка(ТипОбъекта) <> Неопределено Тогда СтруктураСвойств.Вставить("Колонки"); СтруктураСвойств.Вставить("Порядок"); СтруктураСвойств.Вставить("Отбор"); ИначеЕсли ЛксЛиНаборЗаписейРегистра(ТипОбъекта) Тогда СтруктураСвойств.Вставить("Отбор"); КонецЕсли; КонецЕсли; //ИначеЕсли Ложь // ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели") // ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля") // ИЛИ ТипОбъекта = Тип("СтраницыПанели") // ИЛИ ТипОбъекта = Тип("ЭлементыФормы") // ИЛИ ТипОбъекта = Тип("ПоляНастройки") //Тогда // Для Каждого Элемент Из пОбъект Цикл // СтруктураСвойств.Вставить(Элемент.Имя); // КонецЦикла; // ИначеЕсли Ложь Или ТипОбъекта = Тип("СтрокаТаблицыЗначений") Или ТипОбъекта = Тип("СтрокаДереваЗначений") Тогда Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл СтруктураСвойств.Вставить(МетаРеквизит.Имя); КонецЦикла; ИначеЕсли ЛксЛиТипЭлементаФормы(ТипОбъекта) Тогда СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("ИзменяетДанные"); СтруктураСвойств.Вставить("ПервыйВГруппе"); СтруктураСвойств.Вставить("ПропускатьПриВводе"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КонтекстноеМеню"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("Лево"); СтруктураСвойств.Вставить("Верх"); СтруктураСвойств.Вставить("Высота"); СтруктураСвойств.Вставить("Ширина"); КонецЕсли; СтруктураСвойств.Вставить("Подсказка"); СтруктураСвойств.Вставить("ПорядокОбхода"); СтруктураСвойств.Вставить("ПорядокОтображения"); СтруктураСвойств.Вставить("ПрозрачныйФон"); СтруктураСвойств.Вставить("Рамка"); Если ТипОбъекта = Тип("Кнопка") Тогда СтруктураСвойств.Вставить("РежимМеню"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("МногострочныйРежим"); СтруктураСвойств.Вставить("ПоложениеКартинки"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("Шрифт"); СтруктураСвойств.Вставить("Кнопки"); ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда СтруктураСвойств.Вставить("АвтоЗаполнение"); СтруктураСвойств.Вставить("Вспомогательная"); СтруктураСвойств.Вставить("ВыравниваниеКнопок"); СтруктураСвойств.Вставить("ИсточникДействий"); СтруктураСвойств.Вставить("Кнопки"); СтруктураСвойств.Вставить("Ориентация"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда СтруктураСвойств.Вставить("БегущаяСтрока"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ГиперСсылка"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Панель") Тогда СтруктураСвойств.Вставить("Страницы"); СтруктураСвойств.Вставить("АвтоПорядокОбхода"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("ОтображениеЗакладок"); СтруктураСвойств.Вставить("ПорядокОбхода"); СтруктураСвойств.Вставить("РазмерКартинки"); СтруктураСвойств.Вставить("РаспределятьПоСтраницам"); СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("ТекущаяСтраница"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("ВыбираемоеЗначение"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ПоложениеЗаголовка"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ОграничениеТипа"); СтруктураСвойств.Вставить("КнопкаВыбора"); СтруктураСвойств.Вставить("РежимВыбораИзСписка"); СтруктураСвойств.Вставить("КнопкаСпискаВыбора"); СтруктураСвойств.Вставить("СписокВыбора"); СтруктураСвойств.Вставить("АвтоВыборНезаполненного"); СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного"); СтруктураСвойств.Вставить("АвтоПереносСтрок"); СтруктураСвойств.Вставить("ВертикальноеПоложение"); СтруктураСвойств.Вставить("БыстрыйВыбор"); СтруктураСвойств.Вставить("ВыбиратьТип"); СтруктураСвойств.Вставить("ВыборГруппИЭлементов"); СтруктураСвойств.Вставить("ВыборНезаполненного"); СтруктураСвойств.Вставить("ВыборПоВладельцу"); СтруктураСвойств.Вставить("ВыделенныйТекст"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ВысотаСпискаВыбора"); СтруктураСвойств.Вставить("ГоризонтальноеПоложение"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КартинкаКнопкиВыбора"); СтруктураСвойств.Вставить("КнопкаОткрытия"); СтруктураСвойств.Вставить("КнопкаОчистки"); СтруктураСвойств.Вставить("КнопкаРегулирования"); СтруктураСвойств.Вставить("МаксимальноеЗначение"); СтруктураСвойств.Вставить("Маска"); СтруктураСвойств.Вставить("МинимальноеЗначение"); СтруктураСвойств.Вставить("МногострочныйРежим"); СтруктураСвойств.Вставить("ОтметкаНезаполненного"); СтруктураСвойств.Вставить("РасширенноеРедактирование"); СтруктураСвойств.Вставить("РедактированиеТекста"); СтруктураСвойств.Вставить("РежимВыбораНезаполненного"); СтруктураСвойств.Вставить("РежимПароля"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаКнопки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаКнопки"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ШиринаСпискаВыбора"); СтруктураСвойств.Вставить("Шрифт"); СтруктураСвойств.Вставить("ЭлементСвязиПоТипу"); СтруктураСвойств.Вставить("Значение"); ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ВысотаСпискаВыбора"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КартинкаКнопкиВыбора"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("КнопкаВыбора"); СтруктураСвойств.Вставить("КнопкаОткрытия"); СтруктураСвойств.Вставить("КнопкаОчистки"); СтруктураСвойств.Вставить("КнопкаРегулирования"); СтруктураСвойств.Вставить("СписокВыбора"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ШиринаСпискаВыбора"); СтруктураСвойств.Вставить("Значение"); ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ОтображатьКартинку"); СтруктураСвойств.Вставить("ОтображатьПометку"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ТекущаяСтрока"); ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда // **** Доделать СтруктураСвойств.Вставить("ТипЗначения"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("АвтоВводНовойСтроки"); СтруктураСвойств.Вставить("АвтоКонтекстноеМеню"); СтруктураСвойств.Вставить("АвтоОбновление"); СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию"); СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку"); СтруктураСвойств.Вставить("Дерево"); СтруктураСвойств.Вставить("ИерархическийПросмотр"); СтруктураСвойств.Вставить("ИзменятьАвтоОбновление"); СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр"); СтруктураСвойств.Вставить("ИзменятьСпособРедактирования"); СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя"); СтруктураСвойств.Вставить("ПериодАвтоОбновления"); СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки"); СтруктураСвойств.Вставить("РодительВерхнегоУровня"); СтруктураСвойств.Вставить("РежимВыбора"); СтруктураСвойств.Вставить("РежимВыделения"); СтруктураСвойств.Вставить("РежимВыделенияСтроки"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("СпособРедактирования"); СтруктураСвойств.Вставить("ТекущийРодитель"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("Колонки"); СтруктураСвойств.Вставить("НастройкаОтбора"); СтруктураСвойств.Вставить("НастройкаПорядка"); СтруктураСвойств.Вставить("ТекущаяКолонка"); СтруктураСвойств.Вставить("ТекущаяСтрока"); СтруктураСвойств.Вставить("ТекущиеДанные"); СтруктураСвойств.Вставить("ВыделенныеСтроки"); // **** //ВертикальнаяПолосаПрокрутки //ВертикальныеЛинии //Вывод //ВысотаПодвала //ВысотаШапки //ГоризонтальнаяПолосаПрокрутки //ГоризонтальныеЛинии //ИзменятьНастройкуКолонок //ИзменятьПозициюКолонок //ИзменятьПорядокСтрок //ИзменятьСоставСтрок //НачальноеОтображениеДерева //НачальноеОтображениеСписка //Подвал //ПропускатьПриВводе //РазрешитьНачалоПеретаскивания //РазрешитьПеретаскивание //РежимВводаСтрок //ФиксацияСлева //ФиксацияСправа //ЦветТекста //ЦветТекстаВыделения //ЦветТекстаКнопки //ЦветТекстаПодвала //ЦветТекстаШапки //ЦветФона //ЦветФонаВыделения //ЦветФонаКнопки //ЦветФонаПодвала //ЦветФонаЧередованияСтрок //ЦветФонаШапки //ЧередованиеЦветовСтрок //Шапка //Ширина //Шрифт //ШрифтПодвала //ШрифтШапки ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ОтображатьВыделение"); СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания"); СтруктураСвойств.Вставить("РазрешитьПеретаскивание"); СтруктураСвойств.Вставить("Свертка"); СтруктураСвойств.Вставить("ЦветРамки"); ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("Шрифт"); ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда СтруктураСвойств.Вставить("ТриСостояния"); СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ПоложениеЗаголовка"); СтруктураСвойств.Вставить("ЦветРамки"); СтруктураСвойств.Вставить("ЦветТекста"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветФона"); СтруктураСвойств.Вставить("ЦветФонаПоля"); КонецЕсли; ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда СтруктураСвойств.Вставить("ТипКнопки"); СтруктураСвойств.Вставить("Действие"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("ИзменяетДанные"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Картинка"); СтруктураСвойств.Вставить("КнопкаПоУмолчанию"); СтруктураСвойств.Вставить("Кнопки"); СтруктураСвойств.Вставить("Отображение"); СтруктураСвойств.Вставить("Подсказка"); СтруктураСвойств.Вставить("Пометка"); СтруктураСвойств.Вставить("ПорядокКнопок"); СтруктураСвойств.Вставить("Пояснение"); СтруктураСвойств.Вставить("СочетаниеКлавиш"); СтруктураСвойств.Вставить("Текст"); ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КартинкаЗаголовка"); СтруктураСвойств.Вставить("Раскрыта"); ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда СтруктураСвойств.Вставить("АвтоВысотаЯчейки"); СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного"); СтруктураСвойств.Вставить("Видимость"); СтруктураСвойств.Вставить("ВыделятьОтрицательные"); СтруктураСвойств.Вставить("ВысотаЯчейки"); СтруктураСвойств.Вставить("ГиперСсылка"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале"); СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке"); СтруктураСвойств.Вставить("Данные"); СтруктураСвойств.Вставить("ДанныеФлажка"); СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки"); СтруктураСвойств.Вставить("Доступность"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("КартинкаПодвала"); СтруктураСвойств.Вставить("КартинкаШапки"); СтруктураСвойств.Вставить("КартинкиСтрок"); СтруктураСвойств.Вставить("ОтображатьВПодвале"); СтруктураСвойств.Вставить("ОтображатьВШапке"); СтруктураСвойств.Вставить("ОтображатьИерархию"); СтруктураСвойств.Вставить("ПодсказкаВШапке"); СтруктураСвойств.Вставить("Положение"); СтруктураСвойств.Вставить("ПропускатьПриВводе"); СтруктураСвойств.Вставить("РежимРедактирования"); СтруктураСвойств.Вставить("ТекстПодвала"); СтруктураСвойств.Вставить("ТекстШапки"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("ТриСостоянияФлажка"); СтруктураСвойств.Вставить("Формат"); СтруктураСвойств.Вставить("ЦветТекстаПодвала"); СтруктураСвойств.Вставить("ЦветТекстаПоля"); СтруктураСвойств.Вставить("ЦветТекстаШапки"); СтруктураСвойств.Вставить("ЦветФонаПодвала"); СтруктураСвойств.Вставить("ЦветФонаПоля"); СтруктураСвойств.Вставить("ЦветФонаШапки"); СтруктураСвойств.Вставить("Ширина"); СтруктураСвойств.Вставить("ШрифтПодвала"); СтруктураСвойств.Вставить("ШрифтТекста"); СтруктураСвойств.Вставить("ШрифтШапки"); СтруктураСвойств.Вставить("ЭлементУправления"); СтруктураСвойств.Вставить("ИзменениеРазмера"); СтруктураСвойств.Вставить("ИзменятьВидимость"); СтруктураСвойств.Вставить("ИзменятьНастройку"); СтруктураСвойств.Вставить("ИзменятьПозицию"); ИначеЕсли ТипОбъекта = Тип("Форма") Тогда СтруктураСвойств.Вставить("АвтоЗаголовок"); СтруктураСвойств.Вставить("Высота"); СтруктураСвойств.Вставить("Заголовок"); СтруктураСвойств.Вставить("ЗакрыватьПриВыборе"); СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца"); СтруктураСвойств.Вставить("ИзменениеРазмера"); СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна"); СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна"); СтруктураСвойств.Вставить("КартинкаЗаголовка"); СтруктураСвойств.Вставить("КлючУникальности"); СтруктураСвойств.Вставить("МножественныйВыбор"); СтруктураСвойств.Вставить("Модифицированность"); СтруктураСвойств.Вставить("НачальноеЗначениеВыбора"); СтруктураСвойств.Вставить("Панель"); СтруктураСвойств.Вставить("ПоведениеКлавишиEnter"); СтруктураСвойств.Вставить("ПоложениеОкна"); СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна"); СтруктураСвойств.Вставить("РазрешитьСоединятьОкно"); СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное"); СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное"); СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся"); СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное"); СтруктураСвойств.Вставить("РежимВыбора"); СтруктураСвойств.Вставить("РежимРабочегоСтола"); СтруктураСвойств.Вставить("СоединяемоеОкно"); СтруктураСвойств.Вставить("СостояниеОкна"); СтруктураСвойств.Вставить("СпособОтображенияОкна"); СтруктураСвойств.Вставить("Стиль"); СтруктураСвойств.Вставить("ТолькоПросмотр"); СтруктураСвойств.Вставить("Ширина"); СтруктураСвойств.Вставить("ЭлементыФормы"); СтруктураСвойств.Вставить("ТекущийЭлемент"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("ВладелецФормы"); СтруктураСвойств.Вставить("МодальныйРежим"); КонецЕсли; ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПостроительОтчета") ИЛИ пОбъект = "ПостроительОтчета" Тогда СтруктураСвойств.Вставить("Текст"); СтруктураСвойств.Вставить("ДоступныеПоля"); СтруктураСвойств.Вставить("ВыбранныеПоля"); СтруктураСвойств.Вставить("ИзмеренияКолонки"); СтруктураСвойств.Вставить("ИзмеренияСтроки"); СтруктураСвойств.Вставить("Отбор"); СтруктураСвойств.Вставить("Параметры"); // не все ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПолеНастройки") ИЛИ пОбъект = "ПолеНастройки" Тогда СтруктураСвойств.Вставить("Измерение"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Отбор"); СтруктураСвойств.Вставить("Поле"); СтруктураСвойств.Вставить("Порядок"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("СписокЗначений"); СтруктураСвойств.Вставить("ТипЗначения"); Если НЕ пЛиДляСохранения Тогда СтруктураСвойств.Вставить("Поля"); СтруктураСвойств.Вставить("Родитель"); КонецЕсли; ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета") ИЛИ пОбъект = "ИзмерениеПостроителяОтчета" Тогда СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("ТипИзмерения"); // не все ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета") ИЛИ пОбъект = "ПолеПостроителяОтчета" Тогда СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); ИначеЕсли Ложь ИЛИ ТипОбъекта = Тип("ЭлементОтбора") ИЛИ пОбъект = "ЭлементОтбора" Тогда СтруктураСвойств.Вставить("ВидСравнения"); СтруктураСвойств.Вставить("Значение"); СтруктураСвойств.Вставить("ЗначениеПо"); СтруктураСвойств.Вставить("ЗначениеС"); СтруктураСвойств.Вставить("Имя"); СтруктураСвойств.Вставить("Использование"); СтруктураСвойств.Вставить("Представление"); СтруктураСвойств.Вставить("ПутьКДанным"); СтруктураСвойств.Вставить("ТипЗначения"); КонецЕсли; Возврат СтруктураСвойств; КонецФункции // ЛксПолучитьСтруктуруСвойствОбъекта() // Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно. // // Параметры: // *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено; // *СтартоваяСтрока - Число, *0 - стартовое смещение строки; // *СтартоваяКолонка - Число, *0 - стартовое смещение колонки; // *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса; // *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо Сообщить(). // *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено; // *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка. // // Возвращаемое значение: // Строка – истинное описание ошибки. // Функция ЛксПоказатьОшибкуВЗапросеИлиПрограммномКоде(ПолеТекстовогоДокумента = Неопределено, СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено, ИмяМодуля = Неопределено, ПредставлениеКонтекста = "") Экспорт НомерСтроки = 0; Если ИмяМодуля <> Неопределено Тогда Вступление = Символы.Таб; Иначе Вступление = ""; КонецЕсли; Если ИнформацияОбОшибке = Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке(); КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И ИмяМодуля <> Неопределено И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; Если ЯзыкПрограммы = 2 Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; Если ИнформацияОбОшибке <> Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЕсли; Выражение = ""; Если Выражение = "" Тогда Маркер = "Ошибка в выражении """; Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3); КонецЕсли; КонецЕсли; Если Выражение = "" Тогда Маркер = "Поле не найдено """; Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда МаркерНайден = Истина; Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1); КонецЕсли; КонецЕсли; Если Выражение <> "" Тогда ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст(); ПозицияВыражения = Найти(ТекстПоля, Выражение); Если ПозицияВыражения > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение)); Пустышка = 0; НомерСтроки = 0; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка); КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ИнформацияОбОшибке.Причина <> Неопределено И ИнформацияОбОшибке.ИмяМодуля <> "" И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ФигурноеОписаниеОшибки = ЛксПолучитьСтрокуМеждуМаркерами(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь); Если ФигурноеОписаниеОшибки <> Неопределено Тогда ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И ИнформацияОбОшибке.ИмяМодуля <> "" И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля Тогда ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке); Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке); КонецЕсли; МаксимальныйНомерСтроки = 100000; Если ПолеТекстовогоДокумента <> Неопределено Тогда МаксимальныйНомерСтроки = ПолеТекстовогоДокумента.КоличествоСтрок(); КонецЕсли; ФигурноеОписаниеОшибки = ЛксПолучитьСтрокуМеждуМаркерами(ИнформацияОбОшибке.Описание, "{", "}", Ложь); ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если НомерСтроки = 0 Тогда НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки); Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда СтрокаКоординатыОшибки = ЛксПолучитьСтрокуМеждуМаркерами(ФигурноеОписаниеОшибки, "(", ")", Ложь); Если СтрокаКоординатыОшибки <> Неопределено Тогда НомерКолонки = 0; МассивФрагментов = ЛксПолучитьМассивИзСтрокиСРазделителем(СтрокаКоординатыОшибки, ","); СтрокаНомерСтроки = МассивФрагментов[0]; Попытка НомерСтроки = Число(СтрокаНомерСтроки); Исключение КонецПопытки; НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки); Если МассивФрагментов.Количество() > 1 Тогда СтрокаНомерКолонки = МассивФрагментов[1]; Попытка НомерКолонки = Число(СтрокаНомерКолонки); Исключение КонецПопытки; НомерКолонки = НомерКолонки + СтартоваяКолонка; КонецЕсли; Если НомерСтроки = 0 Тогда НомерКолонки = 1; НомерСтроки = 1; КонецЕсли; ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")"); КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 0 И НомерСтроки <= 0 Тогда ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки; Иначе ОписаниеОшибки = "Строка " + НомерСтроки + ": " + ОписаниеОшибки; КонецЕсли; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина); КонецЕсли; ТекстСообщения = ""; Если ПолеТекстовогоДокумента <> Неопределено Тогда Если НомерСтроки > 0 Тогда ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 1000); КонецЕсли; ТекстСообщения = ТекстСообщения + ЛксПолучитьПредставлениеИзИдентификатора(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста; ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки; ПолныйТекстСообщения = Вступление + ТекстСообщения; Если ЛиМодально Тогда Предупреждение(ТекстСообщения); Иначе Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное); КонецЕсли; Иначе ПолныйТекстСообщения = Вступление + ТекстСообщения; Если ЛиМодально Тогда Предупреждение(ОписаниеОшибки); Иначе Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное); КонецЕсли; КонецЕсли; Возврат ПолныйТекстСообщения; КонецФункции // ЛксПоказатьОшибкуВЗапросеИлиПрограммномКоде() // Рассчитыват и устанавливает ширину колонок табличного документа. Ориентирована на обработку // результата построителя отчета. // // Параметры: // ТабличныйДокумент – ТабличныйДокумент; // *ЛиМинимальный – Булево, *Ложь – признак установки необходимой ширины, иначе достаточной; // *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием; // *ШиринаОбластиПолей - Число, *0 - ширина области полей (не показателей); // *РассчитыватьШиринуКолонкиПоНазванию - Булево, *Истина - признак расчета ширины колонки по названию; // *МинимальнаяШиринаКолонкиПоказатель - Число, *10 - минимальная ширина колонки показателя; // *ПорогКоличестваЯчеекДляАнализа - Число, *100000 - пороговое количество ячеек для анализа (усечение по высоте). // Процедура ЛксРассчитатьИУстановитьШиринуКолонок(ТабличныйДокумент, ЛиМинимальный = Ложь, ЛиИгнорироватьОбрезание = Ложь, ШиринаОбластиПолей = 0, РассчитыватьШиринуКолонкиПоНазванию = Ложь, МинимальнаяШиринаКолонкиПоказатель = 10, ПорогКоличестваЯчеекДляАнализа = 10000) Экспорт Перем МаксимальнаяШиринаКолонки; Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных; Перем ОбластьШапки, ОбластьПодвала; Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста; Перем КоличествоУровнейГруппировокСтрок, Отступ; Перем ШириныКолонок; СтрокаСостояния = "Расчет ширины колонок табличного документа "; КоличествоОбновленийСостояния = 100; // Ограничение максимальной ширины колонки МаксимальнаяШиринаКолонки = 50; // Массив, в который будут помещаться ширины колонок ШириныКолонок = Новый Массив; // Получим количество уровней группировок в отчете для учета автоматического отступа КоличествоУровнейГруппировокСтрок = ТабличныйДокумент.КоличествоУровнейГруппировокСтрок(); // Инициализируем начальные строки НачальнаяСтрока = 0; НачалоДанных = 0; // Найдем в результирующем документе область шапки таблицы ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаТаблицы"); Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины НачальнаяСтрока = ОбластьШапки.Верх; НачалоДанных = ОбластьШапки.Низ + 1; Иначе // Если область шапки таблицы не найдена, найдем область шапки строк ОбластьШапки = ТабличныйДокумент.Области.Найти("ШапкаСтрок"); Если ТипЗнч(ОбластьШапки) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Из шапки таблицы получим начальную строку с которой будем рассчитывать ширины НачальнаяСтрока = ОбластьШапки.Верх; НачалоДанных = ОбластьШапки.Низ + 1; КонецЕсли; КонецЕсли; // Получим область подвала отчета и вычислим конечную строку расчета ОбластьПодвала = ТабличныйДокумент.Области.Найти("Подвал"); Если ТипЗнч(ОбластьПодвала) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда // Область подвала найдена КонечнаяСтрока = ОбластьПодвала.Верх - 1; Иначе // Область подвала не найдена КонечнаяСтрока = ТабличныйДокумент.ВысотаТаблицы; КонецЕсли; СтарыйПрогресс = 0; КоличествоЯчеекПоказателейДляРасчета = (КонечнаяСтрока - НачальнаяСтрока) * (ТабличныйДокумент.ШиринаТаблицы - 1); Если КоличествоЯчеекПоказателейДляРасчета > ПорогКоличестваЯчеекДляАнализа Тогда КонечнаяСтрока = Мин(КонечнаяСтрока, ПорогКоличестваЯчеекДляАнализа / (ТабличныйДокумент.ШиринаТаблицы - 1)); КонецЕсли; // Переберем все колонки отчета Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл ПрогрессКолонок = ТекущаяКолонка / ТабличныйДокумент.ШиринаТаблицы / КонечнаяСтрока; АвтоОтступ = 0; // Переберем строки, которые будут использованы для расчета ширин колонок Для ТекущаяСтрока = НачальнаяСтрока По КонечнаяСтрока Цикл ОбработкаПрерыванияПользователя(); Прогресс = КоличествоОбновленийСостояния * ПрогрессКолонок * ТекущаяСтрока; Если Прогресс - СтарыйПрогресс >= 1 Тогда СтарыйПрогресс = Прогресс; ЛксСостояние(СтрокаСостояния + Цел(100 * ПрогрессКолонок * ТекущаяСтрока) + "%"); КонецЕсли; ШиринаКолонки = 0; // Получим область текущей ячейки ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка); Если ОбластьЯчейки.Лево <> ТекущаяКолонка Или ОбластьЯчейки.Верх <> ТекущаяСтрока Тогда // Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой Продолжить; КонецЕсли; // Данная ячейка обрезает текст Если Истина И ЛиИгнорироватьОбрезание И ОбластьЯчейки.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Обрезать Тогда Продолжить; КонецЕсли; Если КоличествоУровнейГруппировокСтрок > 0 И ТекущаяСтрока = НачалоДанных Тогда // Для первой строки с данными получим значение автоотступа АвтоОтступ = ОбластьЯчейки.АвтоОтступ; КонецЕсли; // Получим текст ячейки ТекстЯчейки = ОбластьЯчейки.Текст; КоличествоСтрокВТекстеЯчейки = СтрЧислоСтрок(ТекстЯчейки); // Для каждой строки из текста ячейки рассчитаем количество символов в строке Для НомерСтрокиТекста = 1 По КоличествоСтрокВТекстеЯчейки Цикл ШиринаТекстаЯчейки = СтрДлина(СтрПолучитьСтроку(ТекстЯчейки, НомерСтрокиТекста)); Если Истина И НЕ РассчитыватьШиринуКолонкиПоНазванию И ТекущаяСтрока < НачалоДанных И ШиринаТекстаЯчейки > 0 Тогда ШиринаТекстаЯчейки = МинимальнаяШиринаКолонкиПоказатель; КонецЕсли; // Если используется автоотступ, то прибавим к ширине ячейки его величину Если АвтоОтступ <> Неопределено И АвтоОтступ > 0 Тогда ШиринаТекстаЯчейки = ШиринаТекстаЯчейки + КоличествоУровнейГруппировокСтрок * АвтоОтступ; КонецЕсли; ШиринаКолонки = Макс(ШиринаКолонки, ШиринаТекстаЯчейки); КонецЦикла; Если ШиринаКолонки > МаксимальнаяШиринаКолонки Тогда // Ограничим ширину колонки ШиринаКолонки = МаксимальнаяШиринаКолонки; КонецЕсли; Если ШиринаКолонки <> 0 Тогда // Ширина колонки рассчитана // Определим, сколько ячеек по ширине используется в области для текущей ячейки КоличествоКолонок = ОбластьЯчейки.Право - ОбластьЯчейки.Лево; // Переберем все ячейки, расположенные в области Для НомерКолонки = 0 По КоличествоКолонок Цикл Если ШириныКолонок.ВГраница() >= ТекущаяКолонка - 1 + НомерКолонки Тогда // В массиве ширин колонок уже был элемент для текущей колонки Если ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Неопределено Тогда // Значение ширины колонки еще не было установлено ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = ШиринаКолонки / (КоличествоКолонок + 1); Иначе // Значение ширины колонки уже было установлено // Вычислим максимум ширины колонки ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Макс(ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки], ШиринаКолонки / (КоличествоКолонок + 1)); КонецЕсли; Иначе // В массиве ширин колонок еще не было элемента для данной колонки // Добавим элемент в массив ширин колонок ШириныКолонок.Вставить(ТекущаяКолонка - 1 + НомерКолонки, ШиринаКолонки / (КоличествоКолонок + 1)); КонецЕсли; КонецЦикла; КонецЕсли; КонецЦикла; // Конец цикла перебора строк КонецЦикла; // Конец цикла перебора колонок // Переберем все элементы в массиве вычисленных ширин колонок Для ТекущаяКолонка = 0 По ШириныКолонок.ВГраница() Цикл Если ШиринаОбластиПолей >= ТекущаяКолонка Тогда УстановитьМинимальнуюШирину = Ложь; Иначе УстановитьМинимальнуюШирину = ЛиМинимальный; КонецЕсли; Если ШириныКолонок[ТекущаяКолонка] <> Неопределено Тогда ОбластьКолонки = ТабличныйДокумент.Область(, ТекущаяКолонка + 1, НачалоДанных, ТекущаяКолонка + 1); // Ширина колонок установлена // Установим ширину области ячеек Если УстановитьМинимальнуюШирину Тогда ОбластьКолонки.ШиринаКолонки = Макс(ШириныКолонок[ТекущаяКолонка] + 1, МинимальнаяШиринаКолонкиПоказатель); Иначе ОбластьКолонки.ШиринаКолонки = ШириныКолонок[ТекущаяКолонка] + 1; КонецЕсли; КонецЕсли; КонецЦикла; ЛксСостояние(""); КонецПроцедуры // ЛксРассчитатьИУстановитьШиринуКолонок() // Устанавливает отбор построителя по расшифровке, содержащей NULL'ы. // Устанавливает значение каждого NULL элемента отбора в "<Отсутствует>" и вид сравнения в "Равно". // Для измерений, которые могут содержать значенение "NULL" в запросах в секции условий построителя следует // писать "ЕСТЬNULL(ПутьКДаннымИзмерения, "<Отсутствует>") КАК ИмяИзмерения". // // Параметры: // пПостроительОтчета – ПостроительОтчета – чей отбор обрабатываем; // пРасшифровка - Структура - расшифровка. // Процедура ЛксУстановитьОтборПостроителяПриРасшифровке(пПостроительОтчета, пРасшифровка) Экспорт Для каждого ЭлементРасшифровки Из пРасшифровка Цикл Если ЭлементРасшифровки.Значение = NULL Тогда ЭлементОтбора = пПостроительОтчета.Отбор[ЭлементРасшифровки.Ключ]; Если ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка")) Тогда ЭлементОтбора.Значение = "<Отсутствует>"; Если ЭлементОтбора.ВидСравнения = ВидСравнения.ВИерархии Тогда ЭлементОтбора.ВидСравнения = ВидСравнения.Равно; КонецЕсли; Иначе Сообщить("Запрос не поддерживает расшифровку по отсутствующему значению элемента отбора """ + ЭлементОтбора.Представление + """!"); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксУстановитьОтборПостроителяПриРасшифровке() // Получает копию построителя отчетов. // // Параметры: // Оригинал – ПостроительОтчета. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ЛксПолучитьКопиюПостроителяОтчета(Оригинал, ВосстанавливатьНастройки = Истина) Экспорт Копия = Новый ПостроительОтчета; Для Каждого ДоступноеПоле Из Оригинал.ДоступныеПоля Цикл ЗаполнитьЗначенияСвойств(Копия.ДоступныеПоля.Добавить(ДоступноеПоле.Имя, ДоступноеПоле.Представление), ДоступноеПоле); КонецЦикла; Если ВосстанавливатьНастройки Тогда Копия.Текст = Оригинал.Текст; Копия.ЗаполнитьНастройки(); // Баг платформы. Без этого почему то иногда измерения не восстанавливаются! Копия.УстановитьНастройки(Оригинал.ПолучитьНастройки()); КонецЕсли; Возврат Копия; КонецФункции // ЛксПолучитьКопиюПостроителяОтчета() // Возвращает менеджер временных таблиц, в котором создана временная таблица по переданному источнику. // // Параметры: // ВнешнийИсточник – ТаблицаЗначений; // ИмяТаблицы – Строка; // *МенеджерВременныхТаблиц – МенеджерВременныхТаблиц, *Неопределено. // // Возвращаемое значение: // МенеджерВременныхТаблиц. // Функция ЛксПолучитьВременнуюТаблицу(ВнешнийИсточник, ИмяТаблицы, МенеджерВременныхТаблиц = Неопределено) Экспорт Если МенеджерВременныхТаблиц = Неопределено Тогда МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; КонецЕсли; ТекстВЫБРАТЬ = ""; Для Каждого Колонка Из ВнешнийИсточник.Колонки Цикл ТекстВЫБРАТЬ = ТекстВЫБРАТЬ + ", " + Колонка.Имя; КонецЦикла; ТекстЗапроса = "ВЫБРАТЬ " + Сред(ТекстВЫБРАТЬ, 3); ТекстЗапроса = ТекстЗапроса + " ПОМЕСТИТЬ " + ИмяТаблицы; ТекстЗапроса = ТекстЗапроса + " ИЗ &ВнешнийИсточник КАК ВнешнийИсточник"; Запрос = Новый Запрос(ТекстЗапроса); Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц; Запрос.УстановитьПараметр("ВнешнийИсточник", ВнешнийИсточник); Запрос.Выполнить(); Возврат МенеджерВременныхТаблиц; КонецФункции // ЛксПолучитьВременнуюТаблицу() Функция ЛксПолучитьТекстСостоянияИндикатора(Индикатор) Экспорт Счетчик = Индикатор.Счетчик; Если Истина И Индикатор.ЛиВыводитьВремя И Счетчик > 0 И Счетчик < Индикатор.КоличествоПроходов Тогда ТекущаяДата = ТекущаяДата(); ПрошлоВремени = ТекущаяДата - Индикатор.ДатаНачалаПроцесса; Осталось = ПрошлоВремени * (Индикатор.КоличествоПроходов / Счетчик - 1); ОсталосьДней = Цел(Осталось / (24*60*60)); ТекстОсталось = ", Осталось: ~"; Если ОсталосьДней > 0 Тогда ТекстОсталось = ТекстОсталось + ОсталосьДней + "д"; КонецЕсли; ТекстОсталось = ТекстОсталось + формат(Дата(1,1,1) + Осталось, "ДЛФ=T"); Иначе ТекстОсталось = ""; КонецЕсли; Если Индикатор.КоличествоПроходов > 0 Тогда ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Формат(Счетчик / Индикатор.КоличествоПроходов * 100, "ЧЦ=3; ЧДЦ=0; ЧН=") + "%" + ТекстОсталось; Иначе ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " "; КонецЕсли; Возврат ТекстСостояния; КонецФункции // ЛксПолучитьТекстСостоянияИндикатора() // Открывает справку по первой подсистеме метаданных переданного объекта // // Параметры: // Объект - любой объект, имеющий метаданные. // Процедура ЛксОткрытьСправкуПоПодсистеме(Объект) Экспорт Если Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 Тогда Для Каждого Подсистема Из Объект.Метаданные().Подсистемы Цикл //Если Подсистема.Имя = "" Тогда //КонецЕсли; Прервать; КонецЦикла; ОткрытьСправку(Подсистема); Иначе МассивПодсистем = Новый Массив; МассивПодсистем.Добавить(Метаданные.Подсистемы.ИнструментыРазработчика.Подсистемы.КонтекстнаяПодсказка); МассивПодсистем.Добавить(Метаданные.Подсистемы.ИнструментыРазработчика); ОбъектМД = Объект.Метаданные(); Для Каждого Подсистема Из МассивПодсистем Цикл Если Подсистема.Состав.Содержит(ОбъектМД) Тогда ОткрытьСправку(Подсистема); Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры // ЛксОткрытьСправкуПоПодсистеме() // Создает новый экземпляр обработки и открывает его форму. // // Параметры: // Объект - ОбработкаОбъект, ОтчетОбъект. // // Возвращаемое значение: // Форма. // Функция ЛксОткрытьНовоеОкноОбработки(ЭтотОбъект) Экспорт НоваяКонсоль = ЛксПолучитьМенеджер(ЭтотОбъект).Создать(); Форма = НоваяКонсоль.ПолучитьФорму(); Форма.Открыть(); Возврат Форма; КонецФункции // ЛксОткрытьНовоеОкноОбработки() // Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицой или деревом значений. // Процедура ЛксОткрытьФормуЗаменыСсылокИзТабличногоПоля(ТабличноеПоле) Экспорт Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда Возврат; КонецЕсли; ФормаОбработки = Обработки.ирПоискДублейИЗаменаСсылок.ПолучитьФорму(); Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки; Если ВыделенныеСтроки.Количество() = 0 Тогда Возврат ; КонецЕсли; ИмяКолонки = ТабличноеПоле.ТекущаяКолонка.Данные; МассивСсылок = Новый Массив; Для Каждого Строка Из ВыделенныеСтроки Цикл ЗначениеСтроки = Строка[ИмяКолонки]; ТипЗначения = ТипЗнч(ЗначениеСтроки); Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда Продолжить; КонецЕсли; МассивСсылок.Добавить(ЗначениеСтроки); КонецЦикла; ФормаОбработки.ОткрытьДляЗаменыПоСпискуСсылок(МассивСсылок); ИначеЕсли ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(ТабличноеПоле.Значение, ТабличноеПоле.ТекущаяКолонка.Имя); КонецЕсли; КонецПроцедуры // ЛксОткрытьФормуЗаменыСсылокИзТабличногоПоля() //////////////////////////////////////////////////////////////////////////////// // ТЕХНОЛОГИЯ КОМПОНЕНТ // Возвращает кнопку командной панели компоненты по ее имени из макета. // // Параметры: // ОбъектКомпоненты - ОбработкаОбъект - компонента; // КраткоеИмяКнопки – Строка - имя кнопки из макета компоненты; // *КоманднаяПанель - КоманднаяПанель, *Неопределено - на случай, если у компоненты несколько командных панелей. // // Возвращаемое значение: // Кнопка. // Функция ЛксПолучитьКнопкуКоманднойПанелиЭкземпляраКомпоненты(ОбъектКомпоненты, КраткоеИмяКнопки, Знач КоманднаяПанель = Неопределено) Экспорт Если КоманднаяПанель = Неопределено Тогда КоманднаяПанель = ОбъектКомпоненты.КоманднаяПанель; КонецЕсли; ПолноеИмяКнопки = ЛксСформироватьИмяЭлементаУправленияЭкземпляра(ОбъектКомпоненты.ИмяКласса, ОбъектКомпоненты.Имя, КраткоеИмяКнопки); Кнопка = КоманднаяПанель.Кнопки.Найти(ПолноеИмяКнопки); Если Кнопка = Неопределено Тогда Для Каждого Подменю Из КоманднаяПанель.Кнопки Цикл Если Подменю.ТипКнопки <> ТипКнопкиКоманднойПанели.Подменю Тогда Продолжить; КонецЕсли; Кнопка = ЛксПолучитьКнопкуКоманднойПанелиЭкземпляраКомпоненты(ОбъектКомпоненты, КраткоеИмяКнопки, Подменю); Если Кнопка <> Неопределено Тогда Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Возврат Кнопка; КонецФункции // ЛксПолучитьКнопкуКоманднойПанелиЭкземпляраКомпоненты() // Формирует имя элемента управления экземпляра компоненты. // // Параметры: // ИмяКласса – Строка; // ИмяЭкземпляра - Строка; // КраткоеИмяЭлементаУправления – Строка. // // Возвращаемое значение: // Строка - имя. // Функция ЛксСформироватьИмяЭлементаУправленияЭкземпляра(ИмяКласса, ИмяЭкземпляра, КраткоеИмяЭлементаУправления) Экспорт Возврат ИмяКласса + "_" + ИмяЭкземпляра + "_" + КраткоеИмяЭлементаУправления; КонецФункции // ЛксСформироватьИмяЭлементаУправленияЭкземпляра() // <Описание функции> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ЛксПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпоненты() Экспорт ТаблицаСобытий = Новый ТаблицаЗначений; ТаблицаСобытий.Колонки.Добавить("СобытиеОбъекта"); ТаблицаСобытий.Колонки.Добавить("БлижайшийВидАлгоритма"); ТаблицаСобытий.Колонки.Добавить("ИмяСобытия"); ТаблицаСобытий.Колонки.Добавить("Компонента"); ТаблицаСобытий.Колонки.Добавить("ВызовОбработчика"); Возврат ТаблицаСобытий; КонецФункции // ЛксПолучитьНовуюТаблицуСобытийЭлементаУправленияКомпоненты() // Добавляет в кнопки командной панели приемника коллекцию кнопок командной панели источника. // // Параметры: // ОбъектКомпоненты - ОбработкаОбъект - компонента; // КнопкиМакета – КоллекцияКнопокКоманднойПанели – источник; // КнопкиПриемника – КоллекцияКнопокКоманднойПанели – приемник; // *ДействияКнопокКомпонент - ТаблицаЗначений, *Неопределено; // Процедура ЛксДобавитьКнопкиКоманднойПанелиКомпоненты(ОбъектКомпоненты, КнопкиМакета, КнопкаПриемника, ДействияКнопокКомпонент = Неопределено, ОбщийПриемник = Неопределено) Экспорт КнопкиПриемника = КнопкаПриемника.Кнопки; ИмяКласса = ОбъектКомпоненты.ИмяКласса; Если ДействияКнопокКомпонент = Неопределено Тогда ДействиеТранслятор = Новый Действие("Клс" + ИмяКласса + "Нажатие"); Иначе ЭтоКоманднаяПанель = (ТипЗнч(КнопкаПриемника) = Тип("КоманднаяПанель")); ДопКнопкиКомандныхПанелей = ОбъектКомпоненты.ДопКнопкиКомандныхПанелей; ДопКнопкиКоманднойПанели = Новый Массив; ДопКнопкиКомандныхПанелей.Вставить(КнопкаПриемника.Имя, ДопКнопкиКоманднойПанели); ДействиеТранслятор = Новый Действие("КнопкаКоманднойПанели_Действие") КонецЕсли; ИмяЭкземпляра = ОбъектКомпоненты.Имя; Для Каждого КнопкаМакета Из КнопкиМакета Цикл Кнопка = Неопределено; Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Действие Тогда Если Истина И Строка(КнопкаМакета.Действие) = "" Тогда // Это пустое действие Кнопка = КнопкиПриемника.Добавить(, КнопкаМакета.ТипКнопки); ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя"); Кнопка.Имя = ЛксСформироватьИмяЭлементаУправленияЭкземпляра(ИмяКласса, ИмяЭкземпляра, КнопкаМакета.Имя); Кнопка.Действие = ДействиеТранслятор; Если ДействияКнопокКомпонент <> Неопределено Тогда СтрокаДействия = ДействияКнопокКомпонент.Добавить(); СтрокаДействия.Кнопка = Кнопка; СтрокаДействия.Компонента = ОбъектКомпоненты; ВызовОбработчика = "Действие_"; Если ОбщийПриемник = Неопределено Тогда ВызовОбработчика = ВызовОбработчика + КнопкаМакета.Имя; Иначе ВызовОбработчика = ВызовОбработчика + ОбщийПриемник; КонецЕсли; СтрокаДействия.ВызовОбработчика = ВызовОбработчика + "(П0, П1)"; КонецЕсли; Иначе Кнопка = КнопкиПриемника.Добавить(КнопкаМакета.Имя, КнопкаМакета.ТипКнопки, , КнопкаМакета.Действие); // Автокартинки предопределенных действий платформа подключает до вызова ПередОткрытием, а потом они уже пустые Если КнопкаМакета.Картинка.Вид <> ВидКартинки.Пустая Тогда Кнопка.Картинка = КнопкаМакета.Картинка; КонецЕсли; ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Имя, ТипКнопки, Действие, Картинка"); КонецЕсли; КонецЕсли; Если Кнопка = Неопределено Тогда Кнопка = КнопкиПриемника.Добавить(); ЗаполнитьЗначенияСвойств(Кнопка, КнопкаМакета, , "Действие, Имя"); Если КнопкаМакета.ТипКнопки = ТипКнопкиКоманднойПанели.Подменю Тогда ЛксДобавитьКнопкиКоманднойПанелиКомпоненты(ОбъектКомпоненты, КнопкаМакета.Кнопки, Кнопка, ДействияКнопокКомпонент, ОбщийПриемник); КонецЕсли; КонецЕсли; Если Истина И ДействияКнопокКомпонент <> Неопределено И ЭтоКоманднаяПанель Тогда ДопКнопкиКоманднойПанели.Добавить(Кнопка.Имя); КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксДобавитьКнопкиКоманднойПанелиКомпоненты() // Возвращает имя экземляра компоненты, которой принадлежит элемент управления. // // Параметры: // ЭлементУправления – ЭлементУправления. // // Возвращаемое значение: // Строка - имя. // Функция ЛксПолучитьИмяЭкземпляра(ЭлементУправления) Экспорт Результат = ЛксПолучитьМассивИзСтрокиСРазделителем(ЭлементУправления.Имя, "_")[1]; Возврат Результат; КонецФункции // ЛксПолучитьИмяЭкземпляра() // Устанавливает свойство у элементов именованной коллекции. // // Параметры: // Коллекция – Любая индексированная коллекция; // МассивИлиСтрока – Массив (индексов), Строка (имена элементов, разделенные запятыми), *Неопределено - фильтр; // Свойство – Строка - имя Свойства которое нужно установить; // ЗначениеСвойства – Произвольный. // Процедура ЛксУстановитьСвойствоВКоллекции(Коллекция, МассивИлиСтрока = Неопределено, Свойство, ЗначениеСвойства) Экспорт ДоступенИндексСвойств = Лев(Свойство, 1) <> "-"; Если МассивИлиСтрока <> Неопределено Тогда Если ТипЗнч(МассивИлиСтрока) = Тип("Строка") Тогда МассивИндексов = ЛксПолучитьМассивИзСтрокиСРазделителем(МассивИлиСтрока, ",", Истина); Иначе МассивИндексов = МассивИлиСтрока; КонецЕсли; Для Каждого ИмяЭлемента Из МассивИндексов Цикл ЭлементКоллекции = Коллекция[ИмяЭлемента]; Если ДоступенИндексСвойств Тогда ЭлементКоллекции[Свойство] = ЗначениеСвойства; Иначе Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства"); КонецЕсли; КонецЦикла; Иначе Для Каждого ЭлементКоллекции Из Коллекция Цикл Если ДоступенИндексСвойств Тогда ЭлементКоллекции[Свойство] = ЗначениеСвойства; Иначе Выполнить("ЭлементКоллекции." + Сред(Свойство, 2) + " = ЗначениеСвойства"); КонецЕсли; КонецЦикла; КонецЕсли; КонецПроцедуры // ЛксУстановитьСвойствоВКоллекции() //////////////////////////////////////////////////////////////////////////////// // КОМПОНОВКА // Глобальный обработчик события ПриПолученииДанных для табличных полей доступных полей компоновки. // // Параметры: // ОформленияСтрок – ОформленияСтрок. // Процедура ЛксПриПолученииДанныхДоступныхПолейКомпоновки(ОформленияСтрок) Экспорт Для каждого ОформлениеСтроки Из ОформленияСтрок Цикл ИндексКартинки = Неопределено; ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки; Попытка ЭтоПапка = ДанныеСтроки.Папка; ЭтоРесурс = ДанныеСтроки.Ресурс; Исключение ЭтоПапка = Ложь; ЭтоРесурс = Ложь; КонецПопытки; Если ЭтоПапка Тогда ПапкаСРесурсами = ДанныеСтроки.Элементы.Количество() > 0; Для каждого ДоступноеПоле Из ДанныеСтроки.Элементы Цикл Если Не ДоступноеПоле.Ресурс Тогда ПапкаСРесурсами = Ложь; Прервать; КонецЕсли; КонецЦикла; Если ПапкаСРесурсами Тогда ИндексКартинки = 17; КонецЕсли; КонецЕсли; Если Не ЭтоРесурс И Не ЭтоПапка Тогда ИндексКартинки = ирНеглобальный.ПолучитьИндексКартинкиТипаЛкс(ДанныеСтроки.ТипЗначения); КонецЕсли; Если ИндексКартинки <> Неопределено Тогда ОформлениеСтроки.Ячейки[0].ОтображатьКартинку = Истина; ОформлениеСтроки.Ячейки[0].ИндексКартинки = ИндексКартинки; КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксПриПолученииДанныхДоступныхПолейКомпоновки() // Подключает обработчики событий для табличного поля отбора компоновки данных. // // Параметры: // ТабличноеПоле – ТабличноеПоле – отбора компоновки. // Процедура ЛксПодключитьОбработчикиСобытийДоступныхПолейКомпоновки(ТабличноеПоле) Экспорт ТабличноеПоле.УстановитьДействие("ПриПолученииДанных", Новый Действие("ПриПолученииДанныхДоступныхПолей")); ТабличноеПоле.Колонки[0].КартинкиСтрок = БиблиотекаКартинок.ирТипыДоступныхПолейКомпоновки; КонецПроцедуры // ЛксПодключитьОбработчикиСобытийДоступныхПолейКомпоновки() // Получает линейную структуру наборов данных запросов компоновки. Работает и со схемой и с макетом. // Содержит рекурсивный вызов. // // Параметры: // НаборыДанных – НаборыДанныхСхемыКомпоновкиДанных, НаборыДанныхМакетаКомпоновкиДанных; // *СтруктураНаборовДанных – Структура, *Неопрелено - Структура("Имя", Структура("КоллекцияВладелец, НаборДанных")) // // Возвращаемое значение: // Структура. // Функция ЛксПолучитьСтруктуруНаборовДанныхЗапросов(НаборыДанных, СтруктураНаборовДанных = Неопределено) Экспорт Если СтруктураНаборовДанных = Неопределено Тогда СтруктураНаборовДанных = Новый Структура; КонецЕсли; Для каждого НаборДанных Из НаборыДанных Цикл Если Ложь Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Или ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда Если Не ЗначениеЗаполнено(НаборДанных.Имя) Тогда // Платформа генерит такие наборы для служебных целей ИмяНабора = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", ""); Иначе ИмяНабора = НаборДанных.Имя; КонецЕсли; СтруктураНаборовДанных.Вставить(ИмяНабора, Новый Структура("КоллекцияВладелец, НаборДанных", НаборыДанных, НаборДанных)); ИначеЕсли Ложь Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеМакетаКомпоновкиДанных") Или ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъединениеСхемыКомпоновкиДанных") Тогда ЛксПолучитьСтруктуруНаборовДанныхЗапросов(НаборДанных.Элементы, СтруктураНаборовДанных); КонецЕсли; КонецЦикла; Возврат СтруктураНаборовДанных; КонецФункции // ЛксПолучитьСтруктуруНаборовДанныхЗапросов() // Получает макет компоновки данных по схеме с использованием временных таблиц. // // Параметры: // Схема – СхемаКомпоновкиДанных; // Настройки - НастройкиКомпоновкиДанных; // *ВнешниеНаборыДанных – Структура, *Неопределено - туда добавляются временные таблицы; // *ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных, *Неопределено; // *ЛиОтладка - Булево, *Ложь - показывать тексты запросов и время выполнения этапов. // // Возвращаемое значение: // МакетКомпоновкиДанных. // Функция ЛксПолучитьМакетКомпоновкиДанныхСВременнымиТаблицами(Схема, Настройки, ВнешниеНаборыДанных = Неопределено, ДанныеРасшифровки = Неопределено, ЛиОтладка = Ложь, СвойМакетОформления = Неопределено) Экспорт RegExp = Новый COMОбъект("VBScript.RegExp"); RegExp.Global = Истина; RegExp.MultiLine = Истина; RegExp.IgnoreCase = Истина; // Допустим 1 уровень скобок. шСкобки = "\([^\)\(]*?\)"; RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(.*?)""\)"; Если ВнешниеНаборыДанных = Неопределено Тогда ВнешниеНаборыДанных = Новый Структура; КонецЕсли; Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных; // Выполним создание всех временных таблиц. Временной таблицей считаем набор данных запрос, // имя которого начинается с "@". Наборы данных временных таблиц удаляются из предварительной схемы. ПредварительнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема)); НаборыДанныхСхемы = ПредварительнаяСхема.НаборыДанных; ЕстьВременныеТаблицы = Ложь; НачальноеКоличество = НаборыДанныхСхемы.Количество(); Для СчетчикНаборыДанныхСхемы = 1 По НачальноеКоличество Цикл НаборДанных = НаборыДанныхСхемы[НачальноеКоличество - СчетчикНаборыДанныхСхемы]; Если Истина И Лев(НаборДанных.Имя, 1) = "@" И ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросСхемыКомпоновкиДанных") Тогда ВременнаяСхема = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Схема)); // Кривое копирование набора данных в новую схемы, где он будет один. ВременнаяСхема.СвязиНаборовДанных.Очистить(); НаборыДанныхВременнойСхемы = ВременнаяСхема.НаборыДанных; НаборыДанныхВременнойСхемыВГраница = НаборыДанныхВременнойСхемы.Количество() - 1; Для СчетчикВременнойСхемы = 0 По НаборыДанныхВременнойСхемыВГраница Цикл НаборДанныхВременнойСхемы = НаборыДанныхВременнойСхемы[НаборыДанныхВременнойСхемыВГраница - СчетчикВременнойСхемы]; Если НаборДанныхВременнойСхемы.Имя <> НаборДанных.Имя Тогда НаборыДанныхВременнойСхемы.Удалить(НаборДанныхВременнойСхемы); КонецЕсли; КонецЦикла; Для Каждого ПолеНабора Из НаборыДанныхВременнойСхемы[0].Поля Цикл ПолеНабора.ОграничениеИспользования.Поле = Ложь; ПолеНабора.ВыражениеПредставления = ПолеНабора.ПутьКДанным; КонецЦикла; КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ВременнаяСхема)); КомпоновщикНастроек.ЗагрузитьНастройки(Настройки); КомпоновщикНастроек.Настройки.Структура.Очистить(); КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить(); КомпоновщикНастроек.Восстановить(); ВременныеНастройки = КомпоновщикНастроек.Настройки; // Установим использование параметров Для Каждого ЭлементПараметра Из ВременныеНастройки.ПараметрыДанных.Элементы Цикл ЭлементПараметра.Использование = Истина; КонецЦикла; // Установим структуру и выбранные поля ЭлементСтруктуры = ВременныеНастройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")); ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных")); Для Каждого ДоступноеПоле Из ВременныеНастройки.ДоступныеПоляВыбора.Элементы Цикл // Чтобы пропустить системные папки Если Не ДоступноеПоле.Папка Тогда НовоеВыбранноеПоле = ВременныеНастройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных")); НовоеВыбранноеПоле.Поле = ДоступноеПоле.Поле; НовоеВыбранноеПоле.Использование = Истина; КонецЕсли; КонецЦикла; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ВременнаяСхема, ВременныеНастройки); Запрос.Текст = МакетКомпоновкиДанных.НаборыДанных[0].Запрос; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение); КонецЦикла; Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1"); ЛксВыполнитьЗамеритьЗапрос(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя); //// Недоступные поля набора данных цепляются в настройках при совпадаении имен с выбранными полями //// http://partners.v8.1c.ru/forum/thread.jsp?id=514094 //Для Каждого Поле Из НаборДанных.Поля Цикл // Поле.ПутьКДанным = "_поле_" + Поле.ПутьКДанным; //КонецЦикла; НаборыДанныхСхемы.Удалить(НаборДанных); ЕстьВременныеТаблицы = Истина; КонецЕсли; КонецЦикла; Если Не ЕстьВременныеТаблицы Тогда Если ЛиОтладка Тогда ВремяНачалаКомпоновкиМакета = ЛксПолучитьТекущееВремяВМиллисекундах(); КонецЕсли; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, Настройки, ДанныеРасшифровки, СвойМакетОформления); Если ЛиОтладка Тогда Сообщить("Компоновка макета - " + Строка(ЛксПолучитьТекущееВремяВМиллисекундах() - ВремяНачалаКомпоновкиМакета) + " мс"); КонецЕсли; Иначе // Выполним получение результата предварительного запроса КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПредварительнаяСхема)); КомпоновщикНастроек.ЗагрузитьНастройки(Настройки); КомпоновщикНастроек.Восстановить(); ПредварительныеНастройки = КомпоновщикНастроек.Настройки; Если ЛиОтладка Тогда ВремяНачалаКомпоновкиМакета = ЛксПолучитьТекущееВремяВМиллисекундах(); КонецЕсли; МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(ПредварительнаяСхема, ПредварительныеНастройки, ДанныеРасшифровки, СвойМакетОформления); Если ЛиОтладка Тогда Сообщить("Компоновка макета - " + Строка(ЛксПолучитьТекущееВремяВМиллисекундах() - ВремяНачалаКомпоновкиМакета) + " мс"); КонецЕсли; Для Каждого Параметр Из МакетКомпоновкиДанных.ЗначенияПараметров Цикл Запрос.УстановитьПараметр(Параметр.Имя, Параметр.Значение); КонецЦикла; СтруктураНаборовДанныхЗапросовМакета = ЛксПолучитьСтруктуруНаборовДанныхЗапросов(МакетКомпоновкиДанных.НаборыДанных); Для Каждого ЭлементНаборДанныхМакета Из СтруктураНаборовДанныхЗапросовМакета Цикл НаборДанных = ЭлементНаборДанныхМакета.Значение.НаборДанных; Запрос.Текст = НаборДанных.Запрос; Запрос.Текст = RegExp.Replace(Запрос.Текст, "$1"); РезультатЗапроса = ЛксВыполнитьЗамеритьЗапрос(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя); ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса); КонецЦикла; // Получение конечного макета Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец; НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных; НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных")); // Копируем Свойства набора данных запроса в набор данных объекта ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос); НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя; Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл ПолеРезультата = НаборДанныхОбъект.Поля.Добавить(); ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала); ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль); КонецЦикла; КоллекцияВладелец.Удалить(НаборДанныхЗапрос); КонецЦикла; КонецЕсли; // Баг платформы. Пустая дата превращается в Неопределено. Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл Если ПараметрСхемы.ОграничениеИспользования Тогда Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя); ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение); КонецЕсли; КонецЕсли; КонецЦикла; Возврат МакетКомпоновкиДанных; КонецФункции // ЛксПолучитьМакетКомпоновкиДанныхСВременнымиТаблицами() // Выводит результат СКД с установкой вертикальной автофиксации. // Параметры: // Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет; // ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных; // ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных; // МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей; // РазрешитьПрерывание - Булево, *Истина. // Процедура ЛксВывестиРезультатКомпоновкиСАвтофиксациейСтрок(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки, Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина) Экспорт ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(Таб); ПроцессорВывода.НачатьВывод(); ФиксацияВыполнена = Ложь; Если МассивИгнорируемыхПолей = Неопределено Тогда МассивИгнорируемыхПолей = Новый Массив; КонецЕсли; Пока Истина Цикл ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий(); Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда Прервать; КонецЕсли; Если РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; // Автофиксация Если Истина И Автофиксация И Не ФиксацияВыполнена Тогда Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля(); Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда Таб.ФиксацияСверху = Таб.ВысотаТаблицы; ФиксацияВыполнена = Истина; Прервать; КонецЕсли; КонецЦикла; Если ФиксацияВыполнена Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных); Если РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; КонецЦикла; ПроцессорВывода.ЗакончитьВывод(); КонецПроцедуры // ЛксВывестиРезультатКомпоновкиСАвтофиксациейСтрок #КонецЕсли // Переустанавливает значения недоступных параметров из схемы (антибаг платформы). // // Параметры: // СхемаКомпоновкиДанных – СхемаКомпоновкиДанных; // КомпоновщикНастроек – КомпоновщикНастроекКомпоновкиДанных. // Процедура ЛксОбновитьЗначенияНедоступныхПараметровИзСхемы(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр); Если Истина И ПараметрСхемы <> Неопределено И ПараметрСхемы.ОграничениеИспользования Тогда //Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда // Попытка // ЗначениеПараметра.Значение = Вычислить(); // Исключение // КонецПопытки; //Иначе ЗначениеПараметра.Значение = ПараметрСхемы.Значение; //КонецЕсли; //ЗначениеПараметра.Использование = Истина; КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксОбновитьЗначенияНедоступныхПараметровИзСхемы() Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок(СхемаКомпоновкиДанных) Экспорт ПолеКоличества = "КоличествоСтрокАвто"; ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить(); ВычисляемоеПоле.Выражение = "1"; ВычисляемоеПоле.Заголовок = "Количество строк (авто)"; ВычисляемоеПоле.ПутьКДанным = ПолеКоличества; РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить(); РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества; РесурсКоличествоЗаписей.Выражение = "Сумма(1)"; КонецПроцедуры // Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений. // // Параметры: // СтруктураТаблиц – Структура – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция ЛксСоздатьСхемуПоТаблицамЗначений(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь, ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт Если СхемаКомпоновкиДанных = Неопределено Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; ИсточникДанных = ЛксДобавитьЛокальныйИсточникДанных(СхемаКомпоновкиДанных); КонецЕсли; Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл ирНеглобальный.СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КлючИЗначение.Значение.Колонки, КлючИЗначение.Ключ, СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей); КонецЦикла; Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок(СхемаКомпоновкиДанных); КонецЕсли; Возврат СхемаКомпоновкиДанных; КонецФункции // ЛксСоздатьСхемуПоТаблицамЗначений() // Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки. // // Параметры: // ПоляНастройки – ПоляНастройки – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция ЛксСоздатьСхемуПоПолямНастройки(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "НаборДанных1") Экспорт Если СхемаКомпоновкиДанных = Неопределено Тогда СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных; ИсточникДанных = ЛксДобавитьЛокальныйИсточникДанных(СхемаКомпоновкиДанных); КонецЕсли; НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных")); НаборДанных.Имя = ИмяНабора; НаборДанных.ИсточникДанных = ИсточникДанных.Имя; НаборДанных.ИмяОбъекта = ИмяНабора; Для Каждого ПолеНастройки Из ПоляНастройки Цикл Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных")); Поле.ПутьКДанным = ПолеНастройки.Имя; Поле.Поле = ПолеНастройки.ПутьКДанным; Поле.Заголовок = ПолеНастройки.Представление; Поле.ТипЗначения = ПолеНастройки.ТипЗначения; ОграничениеИспользования = Поле.ОграничениеИспользования; ОграничениеИспользования.Поле = Не ПолеНастройки.Поле; ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор; ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок; ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение; ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0; ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов; ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения; ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения; КонецЦикла; Возврат СхемаКомпоновкиДанных; КонецФункции // ЛксСоздатьСхемуПоПолямНастройки() // Функция добавляет в схему компоновки источник данных с типом "Local" Функция ЛксДобавитьЛокальныйИсточникДанных(СхемаКомпоновкиДанных) Экспорт ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить(); ИсточникДанных.Имя = "ИсточникДанных1"; ИсточникДанных.ТипИсточникаДанных = "Local"; Возврат ИсточникДанных; КонецФункции // Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных Функция ЛксДобавитьНаборДанныхЗапрос(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "НаборДанных1") Экспорт НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных")); НаборДанных.Имя = ИмяНабораДанных; НаборДанных.ИсточникДанных = ИсточникДанных.Имя; Возврат НаборДанных; КонецФункции // Устаревшее! Новая - ирНеглобальный.ПолучитьВыражениеПорядкаКомпоновкиНаЯзыкеЛкс // Получает строку для установки порядка компоновки. // // Параметры: // ПорядокКомпоновки – ПорядокКомпоновкиДанных. // // Возвращаемое значение: // Строка - для установки порядка. // Функция ЛксПолучитьСтрокуПорядкаКомпоновки(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено) Экспорт Строка = ""; Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл Если Ложь Или Не ЭлементПорядка.Использование Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных") Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле Тогда Продолжить; КонецЕсли; ИмяПоля = "" + ЭлементПорядка.Поле; Если СимволЗаменыТочки <> Неопределено Тогда ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки); КонецЕсли; Строка = Строка + ", " + ИмяПоля + " "; Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда Строка = Строка + "Возр"; Иначе Строка = Строка + "Убыв"; КонецЕсли; КонецЦикла; Возврат Сред(Строка, 3); КонецФункции // ЛксПолучитьСтрокуПорядкаКомпоновки() // Трансформирует порядок в порядок компоновки. // // Параметры: // ПорядокКомпоновки – ПорядокКомпоновкиДанных; // Порядок - Порядок. // Процедура ЛксТрансформироватьПорядокВПорядокКомпоновки(ПорядокКомпоновки, Порядок) Экспорт ЭлементыКомпоновки = ПорядокКомпоновки.Элементы; ЭлементыКомпоновки.Очистить(); Для Каждого Элемент Из Порядок Цикл ЭлементКомпоновки = ЭлементыКомпоновки.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных")); ЭлементКомпоновки.Использование = Истина; ЭлементКомпоновки.Поле = Новый ПолеКомпоновкиДанных(Элемент.ПутьКДанным); Если Элемент.Направление = НаправлениеСортировки.Возр Тогда ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр; Иначе//Если Элемент.Направление = НаправлениеСортировки.Убыв Тогда ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв; КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксТрансформироватьПорядокВПорядокКомпоновки() // Конструктор массива через Параметры. // // Параметры: // *п... – Произвольный – элементы массива. // // Возвращаемое значение: // Массив - полученный массив. // Функция ЛксБыстрыйМассив( п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено, п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено, п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено, п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено ) Экспорт Перем М; М = Новый Массив(); Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли; Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли; Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли; Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли; Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли; Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли; Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли; Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли; Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли; Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли; Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли; Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли; Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли; Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли; Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли; Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли; Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли; Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли; Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли; Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли; Возврат М; КонецФункции // ЛксБыстрыйМассив() //////////////////////////////////////////////////////////////////////////////// // РАБОТА СО СТРОКАМИ // <Описание функции> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // – <Тип.Вид> – <описание значения> // <продолжение описания значения>; // <Значение2> – <Тип.Вид> – <описание значения> // <продолжение описания значения>. // Функция ЛксПолучитьОбъектВВидеСтрокиXML(пОбъект) Экспорт Поток = Новый ЗаписьXML; Поток.УстановитьСтроку(); Попытка ЗаписатьXML(Поток, пОбъект); Исключение Возврат "Значения типа """ + ТипЗнч(пОбъект) + """ не могут быть представлены в XML"; КонецПопытки; Результат = Поток.Закрыть(); Возврат Результат; КонецФункции // ЛксПолучитьОбъектВВидеСтрокиXML() // <Описание функции> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // Строка - путь к файлу. // Функция ЛксПолучитьФайлЗначенияДляИнтерактивногоСравнения(Значение, Название, ПолучатьXMLПредставление = Истина) Экспорт Текст = Новый ТекстовыйДокумент; Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда Значение = Значение.Получить(); КонецЕсли; Если ПолучатьXMLПредставление Тогда Представление = ЛксПолучитьОбъектВВидеСтрокиXML(Значение); Иначе Представление = Значение; КонецЕсли; Текст.УстановитьТекст(ЛксПолучитьТекстИзXML(Представление)); Путь = ПолучитьИмяВременногоФайла(Название); Текст.Записать(Путь); Возврат Путь; КонецФункции // ЛксПолучитьФайлЗначенияДляИнтерактивногоСравнения() // Получает строку путем отсечения заданного числа последних символов. // // Параметры: // пСтрока – Строка – исходная; // пДлинаКонца - Число, *1 - количество отсекаемых символов; // // Возвращаемое значение: // – Строка. // Функция ЛксПолучитьСтрокуБезКонца(пСтрока, пДлинаКонца = 1) Экспорт Если СтрДлина(пСтрока) < пДлинаКонца Тогда Возврат ""; Иначе Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца); КонецЕсли; КонецФункции // ЛксПолучитьСтрокуБезКонца() // Функция разбивает строку разделителем. // // Параметры: // пСтрока - Строка - которую разбиваем; // *пРазделитель - Строка, "." - символ-разделитель; // *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП. // *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив. // // Возвращаемое значение: // Массив - фрагментов. // Функция ЛксПолучитьМассивИзСтрокиСРазделителем(Знач Стр, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь, ОставлятьПустуюСтроку = Истина) Экспорт МассивСтрок = Новый Массив; Если Истина И Не ОставлятьПустуюСтроку И ПустаяСтрока(Стр) Тогда Возврат МассивСтрок; КонецЕсли; //лСтрока = СтрЗаменить(Стр, Разделитель, Символы.ПС); //// Баг платформы. СтрЧислоСтрок не учитывает терминальный перевод строки. //ЧислоСтрок = СтрЧислоСтрок(лСтрока + " "); //Для Счетчик = 1 По ЧислоСтрок Цикл // Фрагмент = СтрПолучитьСтроку(лСтрока, Счетчик); // Если ОбрезатьНепечатныеСимволы Тогда // Фрагмент = СокрЛП(Фрагмент); // КонецЕсли; // МассивСтрок.Добавить(Фрагмент); //КонецЦикла; Если Разделитель = " " Тогда Стр = СокрЛП(Стр); Пока 1=1 Цикл Поз = Найти(Стр,Разделитель); Если Поз=0 Тогда МассивСтрок.Добавить(Стр); Возврат МассивСтрок; КонецЕсли; МассивСтрок.Добавить(Лев(Стр,Поз-1)); Стр = СокрЛ(Сред(Стр,Поз)); КонецЦикла; Иначе ДлинаРазделителя = СтрДлина(Разделитель); Пока 1=1 Цикл Поз = Найти(Стр,Разделитель); Если Поз=0 Тогда Фрагмент = Стр; Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Возврат МассивСтрок; КонецЕсли; Фрагмент = Лев(Стр,Поз-1); Если ОбрезатьНепечатныеСимволы Тогда Фрагмент = СокрЛП(Фрагмент); КонецЕсли; МассивСтрок.Добавить(Фрагмент); Стр = Сред(Стр,Поз+ДлинаРазделителя); КонецЦикла; КонецЕсли; Возврат МассивСтрок; КонецФункции // ЛксПолучитьМассивИзСтрокиСРазделителем() // Функция собирает строку из элементов массива с разделителем. // // Параметры: // пМассив - Массив - из которого формируем строку; // *пРазделитель - Строка - символ-разделитель. // // Возвращаемое значение: // Строка. // Функция ЛксПолучитьСтрокуСРазделителемИзМассива(пМассив, пРазделитель = ", ") Экспорт Результат = ""; Для Каждого Элемент Из пМассив Цикл Результат = Результат + пРазделитель + Строка(Элемент); КонецЦикла; Возврат Сред(Результат, СтрДлина(пРазделитель) + 1); КонецФункции // ЛксПолучитьСтрокуСРазделителемИзМассива() // Получает первый фрагмент, отделяемый разделителем от строки. // Написана для оптимизации по скорости. // // Параметры: // пСтрока - Строка - которую разбиваем; // *пРазделитель - Строка, "." - символ-разделитель; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина. // // Возвращаемое значение: // - Строка - первый фрагмент строки; // Неопределено - в строке не обнаружен разделитель. // Функция ЛксПолучитьПервыйФрагмент(пСтрока, пРазделитель = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт Позиция = Найти(пСтрока, пРазделитель); Если Позиция > 0 Тогда Возврат Лев(пСтрока, Позиция - 1); Иначе Если пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; Иначе Возврат пСтрока; КонецЕсли; КонецЕсли; КонецФункции // ЛксПолучитьПервыйФрагмент() // Получает последний фрагмент, отделяемый разделителем от строки. // // Параметры: // пСтрока - Строка - в которой ищем; // *пМаркер – Строка, "." – отсекающий маркер; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки // в случае, если маркер не найден. // // Возвращаемое значение: // Неопределено - маркер не найден; // – Число – позиция маркера. // Функция ЛксПолучитьПоследнийФрагмент(пСтрока, пМаркер = ".", пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина) Экспорт Подстрока = пСтрока; МаркерНайден = Ложь; Пока пМаркер <> "" Цикл Позиция = Найти(Подстрока, пМаркер); Если Позиция = 0 Тогда Прервать; КонецЕсли; МаркерНайден = Истина; Подстрока = Сред(Подстрока, Позиция + СтрДлина(пМаркер)); КонецЦикла; Если Истина И Не МаркерНайден И пЛиИспользоватьГраницуЕслиМаркерНеНайден Тогда Возврат пСтрока; ИначеЕсли МаркерНайден Тогда Возврат Подстрока; Иначе Возврат ""; КонецЕсли; КонецФункции // ЛксПолучитьПоследнийФрагмент() // Получает подстроку заключенную между первым вхождением начального маркера и первым вхождением // в правой части конечного маркера. Сами маркеры не включаются в результат. Опционально - если // маркер не найден, то границей считается граница строки. // // Параметры: // пСтрока - Строка - в которой ищем; // *пНачальныйМаркер - Строка, *Неопределено - начальный маркер подстроки; // *пКонечныйМаркер - Строка, *Неопределено - конечный маркер подстроки; // *пЛиИспользоватьГраницуЕслиМаркерНеНайден - Булево, *Истина - разрешение использования границ строки // в случае, если маркер не найден; // *пЛиВключатьМаркеры - Булево, *Ложь - включение маркеров в результат. // // Возвращаемое значение: // Неопределено - обязательные условия не выполнены; // Строка – найденная подстрока. // Функция ЛксПолучитьСтрокуМеждуМаркерами(пСтрока, пНачальныйМаркер = Неопределено, пКонечныйМаркер = Неопределено, пЛиИспользоватьГраницуЕслиМаркерНеНайден = Истина, пЛиВключатьМаркеры = Ложь) Экспорт ПозицияНачальногоМаркера = Найти(пСтрока, пНачальныйМаркер); Если Истина И ПозицияНачальногоМаркера = 0 И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь Тогда Возврат Неопределено; КонецЕсли; Если Ложь ИЛИ пНачальныйМаркер = Неопределено ИЛИ ПозицияНачальногоМаркера = 0 Тогда ПозицияНачальногоМаркера = - СтрДлина(пНачальныйМаркер); КонецЕсли; Стр = Сред(пСтрока, ПозицияНачальногоМаркера + СтрДлина(пНачальныйМаркер)); ПозицияКонечногоМаркера = Найти(Стр, пКонечныйМаркер); Если Истина И ПозицияКонечногоМаркера = 0 И пЛиИспользоватьГраницуЕслиМаркерНеНайден = Ложь Тогда Возврат Неопределено; КонецЕсли; Если Ложь ИЛИ пКонечныйМаркер = Неопределено ИЛИ ПозицияКонечногоМаркера = 0 Тогда ПозицияКонечногоМаркера = СтрДлина(Стр) + 1; КонецЕсли; Результат = Лев(Стр, ПозицияКонечногоМаркера - 1); Если пЛиВключатьМаркеры Тогда Если пНачальныйМаркер <> Неопределено Тогда Результат = пНачальныйМаркер + Результат; КонецЕсли; Если пКонечныйМаркер <> Неопределено Тогда Результат = Результат + пКонечныйМаркер; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // ЛксПолучитьСтрокуМеждуМаркерами() // Получает представление из идентификатора по правилу // "Дебиторка_По_контрагентамСИнтерваламиСНГДля__Руководства" => "Дебиторка По контрагентам с интервалами СНГ для Руководства". // После символа "_" регистр не меняется, а сам символ заменяется на " ". // // Параметры: // ИсходнаяСтрока – Строка – идентификатор. // // Возвращаемое значение: // – Строка – представление. // Функция ЛксПолучитьПредставлениеИзИдентификатора(ИсходнаяСтрока) Экспорт СтрокаВозврата = Сред(ИсходнаяСтрока, 1, 1); Для Сч = 2 По СтрДлина(ИсходнаяСтрока) Цикл ПредыдущийСимвол = Сред(ИсходнаяСтрока, Сч - 1, 1); ТекущийСимвол = Сред(ИсходнаяСтрока, Сч, 1); СледующийСимвол = Сред(ИсходнаяСтрока, Сч + 1, 1); ПослеследующийСимвол = Сред(ИсходнаяСтрока, Сч + 2, 1); Если ТекущийСимвол = "_" Тогда СтрокаВозврата = СтрокаВозврата + " "; Продолжить; ИначеЕсли Истина И ВРЕГ(ТекущийСимвол) = ТекущийСимвол // В идентификаторе не должны встречаться пробелы. Поэтому было решено закомментировать следующую строку. //И ПредыдущийСимвол <> " " Тогда Если Ложь ИЛИ ВРЕГ(ПредыдущийСимвол) <> ПредыдущийСимвол ИЛИ (Истина И ПредыдущийСимвол <> "_" И ВРЕГ(ПредыдущийСимвол) = ПредыдущийСимвол И ВРЕГ(СледующийСимвол) <> СледующийСимвол) Тогда СтрокаВозврата = СтрокаВозврата + " "; Если Ложь ИЛИ ВРЕГ(СледующийСимвол) <> СледующийСимвол ИЛИ ВРЕГ(ПослеследующийСимвол) <> ПослеследующийСимвол Тогда ТекущийСимвол = НРЕГ(ТекущийСимвол); КонецЕсли; КонецЕсли; КонецЕсли; СтрокаВозврата = СтрокаВозврата + ТекущийСимвол; КонецЦикла; Возврат СтрокаВозврата; КонецФункции // ЛксПолучитьПредставлениеИзИдентификатора() // Преобразует строку для использования в регулярных выражениях. // Производится // // Параметры: // пТекст – Строка. // // Возвращаемое значение: // Строка – для вставки в регулярные выражения. // Функция ЛксПреобразоватьТекстДляРегулярныхВыражений(пТекст) Экспорт Текст = пТекст; СтрокаСпецСимволов = "\[]^$()?*+."; Для Счетчик = 1 По СтрДлина(СтрокаСпецСимволов) Цикл СпецСимвол = Сред(СтрокаСпецСимволов, Счетчик, 1); Текст = СтрЗаменить(Текст, СпецСимвол, "\" + СпецСимвол); КонецЦикла; Возврат Текст; КонецФункции // ЛксПреобразоватьТекстДляРегулярныхВыражений() // Преобразует строку для правого операнда оператора ПОДОБНО языка запросов. // // Параметры: // пТекст – Строка. // // Возвращаемое значение: // Строка. // Функция ЛксПреобразоватьСтрокуДляПОДОБНО(Знач Результат, Спецсимвол = "~") Экспорт ЗарезервированныеСимволы = Новый Массив; ЗарезервированныеСимволы.Добавить("~"); //ЗарезервированныеСимволы.Добавить("%"); ЗарезервированныеСимволы.Добавить("_"); ЗарезервированныеСимволы.Добавить("["); ЗарезервированныеСимволы.Добавить("-"); ЗарезервированныеСимволы.Добавить("]"); Для Каждого ЗарезервированныйСимвол Из ЗарезервированныеСимволы Цикл Результат = СтрЗаменить(Результат, ЗарезервированныйСимвол, Спецсимвол + ЗарезервированныйСимвол); КонецЦикла; Возврат Результат; КонецФункции // ЛксПреобразоватьСтрокуДляПОДОБНО() // Получает строку путем повтора переданной строки заданное количество раз. // // Параметры: // СтрокаДляПовтора – Строка; // ЧислоПовторов – Число. // // Возвращаемое значение: // Строка. // Функция ЛксПолучитьСтрокуПовтором(СтрокаДляПовтора, ЧислоПовторов) Экспорт Результат = ""; Для Счетчик = 1 По ЧислоПовторов Цикл Результат = Результат + СтрокаДляПовтора; КонецЦикла; Возврат Результат; КонецФункции // ЛксПолучитьСтрокуПовтором() // Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка. // // Параметры: // Строка – Строка. // // Возвращаемое значение: // Булево. // Функция ЛксЛиИмяПеременной(Строка) Экспорт Если ПустаяСтрока(Строка) Тогда Возврат Ложь; КонецЕсли; Пустышка = Новый Структура; Попытка Пустышка.Вставить(Строка); Возврат Истина; Исключение Возврат Ложь; КонецПопытки; КонецФункции // ЛксЛиИмяПеременной() // Обновляет в строковом свойстве объекта часть, которая следует за маркером. // Если маркер не находится, то он добавляется. // // Параметры: // пОбъект – Объект, Строка - объект, строковое свойство которого будем обновлять, или само свойство по ссылке; // *пИмяСвойства – Строка, *"" – имя строкового Свойства объекта, указывается в случае, если свойство не передается по ссылке; // пНовыйТекст - Строка - новая часть, которая следует за разделителем; // *пМаркер - Строка, *"," - маркер. // Процедура ЛксОбновитьТекстПослеМаркераВСтроке(пОбъектИлиСвойство, пИмяСвойства = "", пНовыйТекст, пМаркер = ", ") Экспорт Если пИмяСвойства <> "" Тогда СтараяСтрока = пОбъектИлиСвойство[пИмяСвойства]; Иначе СтараяСтрока = пОбъектИлиСвойство; КонецЕсли; ПозицияРазделителя = Найти(СтараяСтрока, пМаркер); Если ПозицияРазделителя = 0 Тогда ПозицияРазделителя = СтрДлина(СтараяСтрока) + 1; КонецЕсли; НоваяСтрока = Лев(СтараяСтрока, ПозицияРазделителя - 1) + пМаркер + пНовыйТекст; Если пИмяСвойства <> "" Тогда пОбъектИлиСвойство[пИмяСвойства] = НоваяСтрока; Иначе пОбъектИлиСвойство = НоваяСтрока; КонецЕсли; КонецПроцедуры // ЛксОбновитьТекстПослеМаркераВСтроке() // Заменяет текущее выделение в поле текстового документа новым текстом. // После этого устанавливает выделение на вставленный фрагмент. // // Параметры: // ПолеТекстовогоДокумента - ПолеТекстовогоДокумента; // НовыйТекст – Строка. // Процедура ЛксЗаменитьВыделенныйТекстСохраняяГраницыВыделения(ПолеТекстовогоДокумента, НовыйТекст) Экспорт Перем НачальнаяСтрока; Перем НачальнаяКолонка; Перем КонечнаяСтрока; Перем КонечнаяКолонка; ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1, НачальнаяСтрока, НачальнаяКолонка); НачальнаяГраница = СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) + 1; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка); ПолеТекстовогоДокумента.ВыделенныйТекст = НовыйТекст; КонечнаяГраница = НачальнаяГраница + СтрДлина(НовыйТекст); Если КонечнаяГраница > СтрДлина(ПолеТекстовогоДокумента.ПолучитьТекст()) Тогда КонечнаяГраница = КонечнаяГраница - 1; КонецЕсли; ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяГраница, КонечнаяГраница); КонецПроцедуры // ЛксЗаменитьВыделенныйТекстСохраняяГраницыВыделения() // Взято отсюда http://infostart.ru/public/100845/ // ИсходныеДанные - <примитивное значение>, ДвоичныеДАнные, ХранилищеЗначения // // Возвращаемое значение // Число Функция ЛксВычислитьХэш(ИсходныеДанные, Хэш=5381, М=33, Разрядность=18446744073709551616) Экспорт // приведем к строке Если ТипЗнч(ИсходныеДанные) = Тип("ДвоичныеДанные") Тогда СтрокаДляКодирования = Base64Строка(ИсходныеДанные); ИначеЕсли ТипЗнч(ИсходныеДанные) = Тип("ХранилищеЗначения") Тогда СтрокаДляКодирования = ЗначениеВСтрокуВнутр(ИсходныеДанные); Иначе СтрокаДляКодирования = Строка(ИсходныеДанные); КонецЕсли; ДлинаБлока = 11; НачПозиция = 1; ДлинаСтроки = СтрДлина(СтрокаДляКодирования); Пока НачПозиция <= ДлинаСтроки Цикл СтрокаБлока = Сред(СтрокаДляКодирования, НачПозиция, ДлинаБлока); ДлинаПодстроки = СтрДлина(СтрокаБлока); Если ДлинаПодстроки = ДлинаБлока Тогда Хэш = ((((((((((( Хэш*М + КодСимвола(СтрокаБлока, 1))*М + КодСимвола(СтрокаБлока, 2))*М + КодСимвола(СтрокаБлока, 3))*М + КодСимвола(СтрокаБлока, 4))*М + КодСимвола(СтрокаБлока, 5))*М + КодСимвола(СтрокаБлока, 6))*М + КодСимвола(СтрокаБлока, 7))*М + КодСимвола(СтрокаБлока, 8))*М + КодСимвола(СтрокаБлока, 9))*М + КодСимвола(СтрокаБлока, 10))*М + КодСимвола(СтрокаБлока, 11)) Иначе Для к = 1 По ДлинаПодстроки Цикл Хэш = М * Хэш + КодСимвола(СтрокаБлока, к) КонецЦикла КонецЕсли; Хэш = Хэш % Разрядность; НачПозиция = НачПозиция + ДлинаБлока КонецЦикла; Возврат Хэш; КонецФункции Функция ЛксПолучитьГУИДИнверсныйИзПрямого(ПрямойГУИД) Экспорт С = СтрЗаменить(ПрямойГУИД, "-", ""); Возврат Сред(С,17,16)+Сред(С,13,4)+Сред(С,9,4)+Сред(С,1,4)+Сред(С,5,4); КонецФункции Функция ЛксПолучитьГУИДПрямойИзИнверсного(ИнверсныйГУИД) Экспорт С = ИнверсныйГУИД; Возврат Сред(С,25,8)+"-"+Сред(С,21,4)+"-"+Сред(С,17,4)+"-"+Сред(С,1,4)+"-"+Сред(С,5,12); КонецФункции Функция ЛксПолучитьОписаниеТиповВсеСсылки() Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку( " | cc:AnyRef |"); Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); Возврат Результат; КонецФункции Функция ЛксПолучитьОписаниеТиповВсеРедактируемыеТипы() Экспорт ОписаниеТипов = ЛксПолучитьОписаниеТиповВсеСсылки(); ДополнительныеТипы = Новый Массив(); ДополнительныеТипы.Добавить(Тип("Строка")); ДополнительныеТипы.Добавить(Тип("Число")); ДополнительныеТипы.Добавить(Тип("Дата")); ДополнительныеТипы.Добавить(Тип("Булево")); ДополнительныеТипы.Добавить(Тип("СписокЗначений")); ДополнительныеТипы.Добавить(Тип("Массив")); ДополнительныеТипы.Добавить(Тип("ОписаниеТипов")); ДополнительныеТипы.Добавить(Тип("МоментВремени")); ДополнительныеТипы.Добавить(Тип("Граница")); ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала")); ДополнительныеТипы.Добавить(Тип("СтандартныйПериод")); ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений")); ДополнительныеТипы.Добавить(Тип("ДеревоЗначений")); ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления")); ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии")); ДополнительныеТипы.Добавить(Тип("ВидСчета")); ДополнительныеТипы.Добавить(Тип("Тип")); ДополнительныеТипы.Добавить(Тип("Null")); //ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация //ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор")); // Из-за бага платформы отключены //ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления")); //ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления")); КвалификаторыЧисла = Новый КвалификаторыЧисла(20, 3); ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла); Возврат ОписаниеТипов; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ДЕРЕВЬЯМИ Процедура ЛксДобавитьКолонкуЕслиНет(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено, Заголовок = Неопределено, Ширина = 0) Экспорт Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда Возврат; КонецЕсли; КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина); КонецПроцедуры // ЛксДобавитьКолонкуЕслиНет() Функция ЛксПолучитьСтрокуПутиВДереве(СтрокаДерева, ИмяКолонки) Экспорт ТекущийУровень = СтрокаДерева[ИмяКолонки]; Если СтрокаДерева.Родитель = Неопределено Тогда Результат = ТекущийУровень; Иначе Результат = ЛксПолучитьСтрокуПутиВДереве(СтрокаДерева.Родитель, ИмяКолонки) + "." + ТекущийУровень; КонецЕсли; Возврат Результат; КонецФункции // ЛксПолучитьСтрокуПутиВДереве() Функция ЛксНайтиПоСтрокеПутиВДереве(СтрокаДерева, ИмяКолонки, Путь) Экспорт ТекущийУровень = ЛксПолучитьПервыйФрагмент(Путь); ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2); ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки); Если ТекущаяСтрока <> Неопределено Тогда Возврат ЛксНайтиПоСтрокеПутиВДереве(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть); Иначе Возврат СтрокаДерева; КонецЕсли; КонецФункции // ЛксНайтиПоСтрокеПутиВДереве() Функция ЛксПолучитьМассивПутиВДереве(СтрокаДерева, ИмяКолонки) Экспорт Если СтрокаДерева.Родитель = Неопределено Тогда Результат = Новый Массив; Иначе Результат = ЛксПолучитьМассивПутиВДереве(СтрокаДерева.Родитель, ИмяКолонки); КонецЕсли; Результат.Добавить(СтрокаДерева[ИмяКолонки]); Возврат Результат; КонецФункции // ЛксПолучитьМассивПутиВДереве() Функция ЛксНайтиПоМассивуПутиВДереве(СтрокаДерева, ИмяКолонки, Путь, Позиция = 0) Экспорт Индекс = Позиция; ТекущийУровень = Путь[Индекс]; ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки); Если Истина И ТекущаяСтрока <> Неопределено И Индекс < Путь.ВГраница() Тогда Возврат ЛксНайтиПоМассивуПутиВДереве(ТекущаяСтрока, ИмяКолонки, Путь, Позиция + 1); Иначе Возврат ТекущаяСтрока; КонецЕсли; КонецФункции // ЛксНайтиПоМассивуПутиВДереве() // Процедура заполняет колонку дерева значением. // // Параметры // ЭлементДЗ - ДеревоЗначений; // ИмяКолонки - Строка; // ЗначениеКолонки - Произвольный. // Процедура ЛксЗаполнитьКолонкуДерева(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки; ЛксЗаполнитьКолонкуДерева(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки); КонецЦикла; КонецПроцедуры // ЛксЗаполнитьКолонкуДерева // Процедура удаляет все строки дерева со значением в колонке. // // Параметры // ЭлементДЗ - ДеревоЗначений; // ИмяКолонки - Строка; // ЗначениеКолонки - Произвольный. // Процедура ЛксУдалитьСтрокиДереваПоЗначениюВКолонке(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт НачальноеКоличество = ЭлементДЗ.Строки.Количество(); Для Счетчик = 1 По НачальноеКоличество Цикл ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик]; Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока); Иначе ЛксУдалитьСтрокиДереваПоЗначениюВКолонке(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки); КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксУдалитьСтрокиДереваПоЗначениюВКолонке // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция ЛксПолучитьТекстИзXML(Текст) Экспорт //{ Заменяем символы, критичные для XML Текст = СтрЗаменить(Текст,"&","&"); Текст = СтрЗаменить(Текст,"<","<"); Текст = СтрЗаменить(Текст,">",">"); Возврат Текст; КонецФункции // ЛксПолучитьТекстИзXML() Функция ЛксСтрокаВнутрВХМЛТело(вхСтрока, выхХМЛТело = Неопределено) Экспорт //{ Получение одной длинной строки выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,""); выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,""); //} //{ Заменяем символы, критичные для XML // & на & // < на < // > на > выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&"); выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","<"); выхХМЛТело = СтрЗаменить(выхХМЛТело,">",">"); //{ Замена одинарных символов выхХМЛТело = СтрЗаменить(выхХМЛТело,",",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"{",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"}",""); //} //{ Удаляем лишние блоки и выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""); выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""); //} //{ Добавляем перенос строки к и к для удобства поиска различий выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС); выхХМЛТело = СтрЗаменить(выхХМЛТело,"",""+СИМВОЛЫ.ПС); //} Возврат выхХМЛТело; КонецФункции // Получает структуру для индикации прогресса цикла. // // Параметры: // КоличествоПроходов – Число - максимальное значение счетчика; // ПредставлениеПроцесса – Строка, *"Выполнено" – отображаемое название процесса; // КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора; // ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса; // РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс. // МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений, // эта реализация не поддерживает дробные значения; // ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации // // Возвращаемое значение: // Структура - которую потом нужно будет передавать в метод ЛксОбработатьИндикатор. // Функция ЛксПолучитьИндикаторПроцесса(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение", Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1, ТаблицаИндикаторов = Неопределено) Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если ТаблицаИндикаторов.Количество() = 0 Тогда #Если Клиент Тогда ПодключитьОбработчикОжидания("ЛксОсвободитьВсеИндикаторыПроцессов", 0.1, Истина); #КонецЕсли ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов"; КонецЕсли; Индикатор = ТаблицаИндикаторов.Добавить(); Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда #Если Клиент Тогда ЛксСостояние(ПредставлениеПроцесса + "..."); #КонецЕсли КоличествоПроходов = 0; КонецЕсли; Индикатор.КоличествоПроходов = КоличествоПроходов; Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса; Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя; Индикатор.РазрешитьПрерывание = РазрешитьПрерывание; Индикатор.ДатаНачалаПроцесса = ТекущаяДата(); Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления; //Индикатор.ДатаСледующегоОбновления = Дата('00010101'); Если КоличествоОбновлений > 0 Тогда Шаг = КоличествоПроходов / КоличествоОбновлений; Иначе Шаг = 0; КонецЕсли; Индикатор.Шаг = Шаг; //Индикатор.СледующийСчетчик = 0; //Индикатор.Счетчик = 0; Возврат Индикатор; КонецФункции // ЛксПолучитьИндикаторПроцесса() // Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния) // Параметры: // СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор // ВывестиИтогИндикации - Булево // ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове // Процедура ЛксОсвободитьИндикаторПроцесса(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если Индикатор = Неопределено Тогда Если ТаблицаИндикаторов.Количество() > 0 Тогда Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1]; КонецЕсли; КонецЕсли; Если Индикатор <> Неопределено Тогда Если ВывестиИтогИндикации Тогда ЛксСообщитьИтогИндикации(Индикатор); КонецЕсли; Если ТаблицаИндикаторов <> Неопределено Тогда Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда ТаблицаИндикаторов.Удалить(Индикатор); КонецЕсли; КонецЕсли; КонецЕсли; Если Ложь Или ТаблицаИндикаторов = Неопределено Или ТаблицаИндикаторов.Количество() = 0 Тогда НовоеСостояние = ""; Иначе НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния; КонецЕсли; #Если Клиент Тогда Состояние(НовоеСостояние); #КонецЕсли КонецПроцедуры Процедура ЛксОсвободитьВсеИндикаторыПроцессов() Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; //Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл // ЛксОбработатьИндикатор(СтрокаИндикатора, , Истина); //КонецЦикла; ТаблицаИндикаторов.Очистить(); КонецПроцедуры // Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла. // // Параметры: // Индикатор – Структура – индикатора, полученная методом ЛксПолучитьИндикаторПроцесса; // Счетчик – Число, *Неопределено – внешний счетчик цикла. // Процедура ЛксОбработатьИндикатор(Индикатор, Счетчик = Неопределено) Экспорт Если Счетчик = Неопределено Тогда Попытка Счетчик = Индикатор.Счетчик; Исключение // Бывает, что строка таблицы индикаторов уже была удалена Возврат; КонецПопытки; Счетчик = Счетчик + 1; КонецЕсли; Индикатор.Счетчик = Счетчик; #Если Клиент Тогда Если Индикатор.РазрешитьПрерывание Тогда ОбработкаПрерыванияПользователя(); КонецЕсли; #КонецЕсли ОбновитьИндикатор = Истина; Если Ложь Или Счетчик < Индикатор.КоличествоПроходов Или Индикатор.КоличествоПроходов = 0 Тогда ТекущаяДата = ТекущаяДата(); Если Индикатор.МинимальныйПериодОбновления > 0 Тогда Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления; Иначе ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; Если ОбновитьИндикатор Тогда Если Индикатор.Шаг > 0 Тогда Если Счетчик >= Индикатор.СледующийСчетчик Тогда Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг); Иначе ОбновитьИндикатор = Ложь; КонецЕсли; //Иначе // ОбновитьИндикатор = Ложь; // ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " "; // Состояние(ТекстСостояния); КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда #Если Клиент Тогда Состояние(""); #КонецЕсли ОбновитьИндикатор = Ложь; КонецЕсли; КонецЕсли; Если ОбновитьИндикатор Тогда Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг); Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда МассивИндикаторов = Индикатор.Владелец(); Иначе МассивИндикаторов = Новый Массив; МассивИндикаторов.Добавить(Индикатор); КонецЕсли; #Если Клиент Тогда ТекстСостояния = ""; Для Каждого лИндикатор Из МассивИндикаторов Цикл Если ТекстСостояния <> "" Тогда ТекстСостояния = ТекстСостояния + ".>> "; КонецЕсли; ТекстСостояния = ТекстСостояния + ЛксПолучитьТекстСостоянияИндикатора(лИндикатор); КонецЦикла; лИндикатор.ТекстСостояния = ТекстСостояния; Состояние(ТекстСостояния); #КонецЕсли КонецЕсли; КонецПроцедуры // ЛксОбработатьИндикатор() Процедура ЛксСостояние(СтрокаСостояния = "") Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов; Если ТаблицаИндикаторов.Количество() > 0 Тогда Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1]; СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния; КонецЕсли; #Если Клиент Тогда Состояние(СтрокаСостояния); #КонецЕсли КонецПроцедуры #Если Клиент Тогда //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ФОРМАМИ Функция ЛксВыбратьСсылку(ПолноИмяМДИлиОбъектМД, НачальноеЗначениеВыбора = Неопределено) Экспорт Если ТипЗнч(ПолноИмяМДИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда ПолноеИмяМД = ПолноИмяМДИлиОбъектМД.ПолноеИмя(); Иначе ПолноеИмяМД = ПолноИмяМДИлиОбъектМД; КонецЕсли; СтруктураПараметры = Новый Структура; //СтруктураПараметры.Вставить("РежимВыбора", Истина); СтруктураПараметры.Вставить("ТекущаяСтрока", НачальноеЗначениеВыбора); Попытка ФормаВыбора = ПолучитьФорму(ПолноеИмяМД + ".ФормаВыбора", СтруктураПараметры, , Новый УникальныйИдентификатор); Исключение ФормаВыбора = ПолучитьФорму(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор); ФормаВыбора.РежимВыбора = Истина; КонецПопытки; Результат = ФормаВыбора.ОткрытьМодально(); //Результат = ОткрытьФормуМодально(ПолноеИмяМД + ".ФормаВыбора", СтруктураПараметры); Возврат Результат; КонецФункции // <Описание процедуры> // // Параметры: // <Параметр1> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>; // <Параметр2> – <Тип.Вид> – <описание параметра> // <продолжение описания параметра>. // Функция ЛксСравнитьЗначенияИнтерактивноЧерезXMLСтроку(Значение1, Значение2, Модально = Ложь, Название1 = Неопределено, Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставление = Истина) Экспорт Путь1 = ЛксПолучитьФайлЗначенияДляИнтерактивногоСравнения(Значение1, Название1, ПолучатьXMLПредставление); Путь2 = ЛксПолучитьФайлЗначенияДляИнтерактивногоСравнения(Значение2, Название2, ПолучатьXMLПредставление); // Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится. Если СравнениеФайлов = Неопределено Тогда СравнениеФайлов = Новый СравнениеФайлов; КонецЕсли; СравнениеФайлов.ПервыйФайл = Путь1; СравнениеФайлов.ВторойФайл = Путь2; СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь; СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент; Если Модально Тогда СравнениеФайлов.ПоказатьРазличияМодально(); Иначе СравнениеФайлов.ПоказатьРазличия(); КонецЕсли; Возврат СравнениеФайлов.Сравнить(); КонецФункции // ЛксСравнитьЗначенияИнтерактивноЧерезXMLСтроку() // Сравнивает табличный документ, полученный из элемента управления с предыдущим. // // Параметры: // СравнительТабличныхДокументов – Массив, *Неопределено – переменная для хранения предыдущего табличного документа. // ЭлементУправления – ТабличноеПоле, ПолеТабличногоДокумента – откуда получаем содержимое. // Процедура ЛксСравнитьСодержимоеЭлементаУправления(МассивСравнения, ЭлементУправления) Экспорт Если МассивСравнения = Неопределено Тогда МассивСравнения = Новый Массив; КонецЕсли; Если МассивСравнения.Количество() = 2 Тогда МассивСравнения.Удалить(0); КонецЕсли; Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда СравниваемыйДокумент = Новый ТекстовыйДокумент; СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст()); ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда СравниваемыйДокумент = Новый ТекстовыйДокумент; СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение); ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Тогда //СравниваемыйДокумент = Новый ТабличныйДокумент; //лПостроительОтчета = Новый ПостроительОтчета; //лПостроительОтчета.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЭлементУправления.Значение); //лПостроительОтчета.ЗаполнитьНастройки(); //Если лПостроительОтчета.ВыбранныеПоля.Количество() = 0 Тогда // Возврат; //КонецЕсли; //лПостроительОтчета.Вывести(СравниваемыйДокумент); СравниваемыйДокумент = ирНеглобальный.ВывестиТаблицуВТабличныйДокументЛкс(ЭлементУправления.Значение); Иначе//Если ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Тогда СравниваемыйДокумент = ЭлементУправления.ПолучитьОбласть(); КонецЕсли; МассивСравнения.Добавить(СравниваемыйДокумент); Если МассивСравнения.Количество() = 2 Тогда Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет); Если Ответ = КодВозвратаДиалога.Нет Тогда Возврат; КонецЕсли; Массив = Новый Массив; Для Индекс = 0 По 1 Цикл Массив.Добавить(ПолучитьИмяВременногоФайла("mxl")); ТабличныйДокумент = МассивСравнения[Индекс]; ТабличныйДокумент.Записать(Массив[Индекс]); КонецЦикла; СравнениеФайлов = Новый СравнениеФайлов; СравнениеФайлов.ПервыйФайл = Массив[0]; СравнениеФайлов.ВторойФайл = Массив[1]; Если ТипЗнч(МассивСравнения[0]) = Тип("ТабличныйДокумент") Тогда СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент; Иначе СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент; КонецЕсли; Если НЕ СравнениеФайлов.Сравнить() Тогда СравнениеФайлов.ПоказатьРазличия(); Иначе Предупреждение("Документы идентичны!"); КонецЕсли; КонецЕсли; КонецПроцедуры // ЛксСравнитьСодержимоеПоля() Процедура ЛксВвестиИУстановитьШиринуКолонокТабличногоПоля(ТабличноеПоле) Экспорт ВведенноеЗначениеШирины = 10; Если ВвестиЧисло(ВведенноеЗначениеШирины, "Введите новую ширину колонки для всех колонок", 5, 0) Тогда ЛксУстановитьСвойствоВКоллекции(ТабличноеПоле.Колонки, , "-Ширина", ВведенноеЗначениеШирины); КонецЕсли; КонецПроцедуры // ЛксВвестиИУстановитьШиринуКолонокТабличногоПоля() // Пропорционально сжимает ширины колонок табличного поля. // // Параметры: // ТабличноеПоле – ТабличноеПоле; // Сжатие – Число, *2 – коэффициент сжатия; // УважатьЗапретИзмененияРазмера – Булево, *Истина – не сжимать колонки с запретом изменения размера; // Процедура ЛксСжатьКолонкиТабличногоПоля(ТабличноеПоле, Сжатие = 2, УважатьЗапретИзмененияРазмера = Истина) Экспорт МассивКолонокДляОбработки = Новый Массив; Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл Ширина = Колонка.Ширина; Если Ширина = 0 Тогда // Антибаг платформы. Ширина = 10; КонецЕсли; Если Ложь Или Не УважатьЗапретИзмененияРазмера Или Колонка.ИзменениеРазмера = ИзменениеРазмераКолонки.Изменять Тогда НоваяШирина = Ширина / Сжатие; НоваяШирина = Макс(НоваяШирина, 1); Колонка.Ширина = НоваяШирина; КонецЕсли; КонецЦикла; КонецПроцедуры // ЛксСжатьКолонкиТабличногоПоля() // Интерактивно записывает значение в элемент управления. Интерактивность заключается в срабатывании // события ПриИзменении у элемента управления. // // Параметры: // ЭлементУправления – ЭлементУправления – которому присваиваем значение; // Значение – Произвольный – присваиваемое значение; // *ФормаИнициатор - Форма, *Неопределено - которая будет использована в качестве инициатора события; // если не указана, то будет создана временная форма-пустышка. // Процедура ЛксИнтерактивноЗаписатьВЭлементУправления(ЭлементУправления, Значение, ФормаИнициатор = Неопределено) Экспорт Перем СтарыйВладелец, СтарыйЗакрыватьПриВыборе; Если ФормаИнициатор = Неопределено Тогда ФормаИнициатор = ПолучитьОбщуюФорму("ирПустышка", ЭлементУправления); Иначе СтарыйВладелец = ФормаИнициатор.ВладелецФормы; СтарыйЗакрыватьПриВыборе = ФормаИнициатор.ЗакрыватьПриВыборе; ФормаИнициатор.ВладелецФормы = ЭлементУправления; ФормаИнициатор.ЗакрыватьПриВыборе = Ложь; КонецЕсли; НовоеЗначение = ЭлементУправления.ОграничениеТипа.ПривестиЗначение(Значение); Если Ложь Или НовоеЗначение <> Значение Или ЭлементУправления.ТолькоПросмотр Тогда Возврат; КонецЕсли; ФормаИнициатор.ОповеститьОВыборе(Значение); Если СтарыйЗакрыватьПриВыборе <> Неопределено Тогда ФормаИнициатор.ВладелецФормы = СтарыйВладелец; ФормаИнициатор.ЗакрыватьПриВыборе = СтарыйЗакрыватьПриВыборе; КонецЕсли; КонецПроцедуры // ЛксИнтерактивноЗаписатьВЭлементУправления() // Интерактивно записывает значение в элемент управления (только поле ввода) колонки табличного поля. // Интерактивность заключается в срабатывании события ПриИзменении у элемента управления. // Строка табличного поля должна находиться в режиме редактирования, // иначе никаких изменений данных не произойдет. // // Параметры: // ТабличноеПоле - ТабличноеПоле - строка которого редактируется; // Колонка – КолонкаТабличногоПоля – в элемент управления которой записываем; // Значение – Произвольный – присваиваемое значение; // *ФормаИнициатор - Форма, *Неопределено - которая будет использована в качестве инициатора события; // если не указана, то будет создана временная форма-пустышка; // *ВосстанавитьТекущуюКолонку – Булево, *Истина; // *ВключитьРежимРедактирования – Булево, *Истина. // Процедура ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля(ТабличноеПоле, Колонка, Значение, ФормаИнициатор = Неопределено, ВосстанавитьТекущуюКолонку = Истина, ВключитьРежимРедактирования = Истина, КонтролироватьТекущиеДанные = Ложь) Экспорт ЭлементУправления = Колонка.ЭлементУправления; Если ТипЗнч(ЭлементУправления) <> Тип("ПолеВвода") Тогда Возврат; КонецЕсли; Если ЛксПолучитьКорневойТипКонфигурации(ЭлементУправления.Значение) = "Справочник" Тогда Если Ложь Или (Истина И ЗначениеЗаполнено(ЭлементУправления.ВыборПоВладельцу) И Значение.Владелец <> ЭлементУправления.ВыборПоВладельцу) Или (Истина И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Элементы И Значение.ЭтоГруппа) Или (Истина И ЭлементУправления.ВыборГруппИЭлементов = ИспользованиеГруппИЭлементов.Группы И Не Значение.ЭтоГруппа) Тогда Возврат; КонецЕсли; КонецЕсли; Если ВосстанавитьТекущуюКолонку Тогда СтараяТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка; КонецЕсли; ЛксПрисвоитьЕслиНеРавно(ТабличноеПоле.ТекущаяКолонка, Колонка); Если ВключитьРежимРедактирования Тогда ТабличноеПоле.ИзменитьСтроку(); КонецЕсли; ЛксИнтерактивноЗаписатьВЭлементУправления(ЭлементУправления, Значение, ФормаИнициатор); Если Истина И КонтролироватьТекущиеДанные И Колонка.Данные <> "" Тогда // В табличных полях компоновки ломается Если Значение <> ТабличноеПоле.ТекущиеДанные[Колонка.Данные] Тогда // Такое случается в некоторых состояниях формы (пока Открыта() = Ложь) ТабличноеПоле.ТекущиеДанные[Колонка.Данные] = Значение; КонецЕсли; КонецЕсли; Если ВосстанавитьТекущуюКолонку Тогда ЛксПрисвоитьЕслиНеРавно(ТабличноеПоле.ТекущаяКолонка, СтараяТекущаяКолонка); КонецЕсли; КонецПроцедуры // ЛксИнтерактивноЗаписатьВКолонкуТабличногоПоля() // Проверяет колонку табличного поля на интерактивную доступность. // // Параметры: // пКолонка – КолонкаТабличногоПоля. // // Возвращаемое значение: // Истина - колонка интерактивно доступна; // Ложь - иначе. // Функция ЛксЛиИнтерактивноДоступнаяКолонка(пКолонка) Экспорт Если Истина И пКолонка.Доступность И пКолонка.Видимость И Не пКолонка.ТолькоПросмотр И (Ложь Или пКолонка.ДанныеФлажка <> "" Или (Истина И пКолонка.ЭлементУправления <> Неопределено И пКолонка.ЭлементУправления.Доступность)) Тогда Попытка Если пКолонка.ЭлементУправления.ТолькоПросмотр Тогда Возврат Ложь; КонецЕсли; Исключение КонецПопытки; Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции // ЛксЛиИнтерактивноДоступнаяКолонка() // Копирует привязки между элементами форм. // // Параметры: // пФорма – Форма – в которую копируем; // ЭлементПриемник – ЭлементУправления; // ЭлементИсточник – ЭлементУправления. // Процедура ЛксСкопироватьПривязки(пФорма, ЭлементПриемник, ЭлементИсточник) Экспорт Перем ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента; Границы = Новый Массив; Границы.Добавить(ГраницаЭлементаУправления.Верх); Границы.Добавить(ГраницаЭлементаУправления.Низ); Границы.Добавить(ГраницаЭлементаУправления.Лево); Границы.Добавить(ГраницаЭлементаУправления.Право); Для Каждого Граница Из Границы Цикл ЭлементИсточник.ПолучитьПривязку( Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента); Если ПервыйЭлемент <> Неопределено Тогда ПервыйЭлемент = пФорма.ЭлементыФормы.Найти(ПервыйЭлемент.Имя); Если ПервыйЭлемент = Неопределено Тогда ПервыйЭлемент = пФорма.Панель; КонецЕсли; КонецЕсли; Если ВторойЭлемент <> Неопределено Тогда ВторойЭлемент = пФорма.ЭлементыФормы.Найти(ВторойЭлемент.Имя); Если ВторойЭлемент = Неопределено Тогда ВторойЭлемент = пФорма.Панель; КонецЕсли; КонецЕсли; ЭлементПриемник.УстановитьПривязку(Граница, ПервыйЭлемент, ГраницаПервогоЭлемента, ВторойЭлемент, ГраницаВторогоЭлемента); КонецЦикла; КонецПроцедуры // ЛксСкопироватьПривязки() // Заполняет форму по ее макету. Используется для динамического добавления элементов // в типовые формы, чтобы облегчить их обновление. Макет формы, если явно не указан, // ищется среди форм объекта метаданных формы по имени "Лкс"+<ИмяФормы>+"Макет". // Для измененных элементов в макете к имени следует добавлять через "_" суффиксы // в соответствии с изменениями: "Привязка", "Размер", "Позиция", "Внутри" (для коллекций). // Следует вызывать в обработчике ПередОткрытием формы. // Ограничения. // 1. Без явного указания макета работает только для основной формы объекта. // 2. Нельзя добавлять элементы в панели и поля табличного документа, т.к. у элемента нельзя // определить родителя. // 3. Нельзя, чтобы форма и макет имели разные размеры. Обрабатываеся. // 4. Нельзя добавлять и изменять элементы, привязанные косвенно к низу формы. // 5. Иногда элементы, привязанные косвенно к правой границе формы неверно располагаются. // 6. Нельзя, чтобы оригинальные имена измененных элементов включали "_". Обрабатывается. // // Параметры: // пФорма – Форма – которую настраиваем; // *пМакет – Форма - макет, по которому настраиваем. // Процедура ЛксНастроитьФормуПоМакету(пФорма, пМакетФормы) Экспорт МакетФормы = пМакетФормы; СоответствиеПривязки = Новый Соответствие; Если Ложь Или пФорма.Высота <> МакетФормы.Высота Или пФорма.Ширина <> МакетФормы.Ширина Тогда Сообщить("Не соответствие размеров формы при заполнении по макету", СтатусСообщения.Важное); КонецЕсли; //ЗаполнитьЗначенияСвойств(пФорма, МакетФормы, , "ДокументОбъект, Данные, ЭтотОбъект, Панель, ЭлементыФормы"); //ЗаполнитьЗначенияСвойств(пФорма.Панель, МакетФормы.Панель, , "Данные"); ЭлементыФормы = пФорма.ЭлементыФормы; Для Каждого ЭлементМакета Из МакетФормы.ЭлементыФормы Цикл ИмяЭлемента = ЭлементМакета.Имя; ЭлементФормы = ЭлементыФормы.Добавить(ТипЗнч(ЭлементМакета), ИмяЭлемента, Ложь, пФорма.Панель); Если ТипЗнч(ЭлементМакета) = Тип("КоманднаяПанель") Тогда ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, Кнопки, ИсточникДействий"); Если ЭлементМакета.ИсточникДействий = пМакетФормы Тогда ЭлементФормы.ИсточникДействий = пФорма; КонецЕсли; ИначеЕсли ТипЗнч(ЭлементМакета) = Тип("ТабличноеПоле") Тогда ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные, ТекущаяСтрока"); Иначе ЗаполнитьЗначенияСвойств(ЭлементФормы, ЭлементМакета, , "Имя, Данные"); КонецЕсли; СоответствиеПривязки.Вставить(ЭлементФормы, ЭлементМакета); КонецЦикла; // Установи новые привязки Для Каждого Привязка Из СоответствиеПривязки Цикл ЭлементФормы = Привязка.Ключ; ЭлементМакета = Привязка.Значение; ЛксСкопироватьПривязки(пФорма, ЭлементФормы, ЭлементМакета); КонецЦикла; КонецПроцедуры // ЛксНастроитьФормуПоМакету() // Изменяет свернутость всех строк табличного поля дерева значений. // // Параметры: // ДЗ – ТабличноеПоле – связанное с деревом значений и включенным режимом Дерево; // Свернуть – Булево, *Истина - новое значение свернутости. // Процедура ЛксДеревоЗначенийСвернуть(ДЗ, Свернуть = Истина) Экспорт Если ТипЗнч(ДЗ.Значение) = Тип("ДеревоЗначений") Тогда ЛксДеревоЗначенийСвернутьСлуж(ДЗ, Свернуть, ДЗ.Значение.Строки); КонецЕсли; КонецПроцедуры Процедура ЛксДеревоЗначенийСвернутьСлуж(ДЗ, Свернуть, Строки) Для Каждого Стр Из Строки Цикл Если Свернуть Тогда ДЗ.Свернуть(Стр); Иначе ДЗ.Развернуть(Стр); КонецЕсли; ЛксДеревоЗначенийСвернутьСлуж(ДЗ, Свернуть, Стр.Строки); КонецЦикла; КонецПроцедуры Процедура ЛксДеревоКонсолиПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки) Экспорт Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; Если ЗначениеПеретаскивания.Свойство("Тип") Тогда Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда ТекущийРодитель = Строка; Пока ТекущийРодитель <> Неопределено Цикл Если ТекущийРодитель = ЗначениеПеретаскивания.Значение Тогда ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.НеОбрабатывать; Возврат; КонецЕсли; ТекущийРодитель = ТекущийРодитель.Родитель; КонецЦикла; СтандартнаяОбработка = Ложь; ПараметрыПеретаскивания.ДопустимыеДействия = ДопустимыеДействияПеретаскивания.Копирование; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ЛксДеревоКонсолиПеретаскивание(ЭтаФорма, Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Колонка, ИмяТипаСроки) Экспорт Если ТипЗнч(ПараметрыПеретаскивания.Значение) = Тип("Структура") Тогда ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение; Если ЗначениеПеретаскивания.Свойство("Тип") Тогда Если НРег(ЗначениеПеретаскивания.Тип) = Нрег(ИмяТипаСроки) Тогда СтандартнаяОбработка = Ложь; Если Строка <> Неопределено Тогда РодительскаяСтрока = Строка; Иначе РодительскаяСтрока = Элемент.Значение; КонецЕсли; НоваяСтрокаЗапросов = РодительскаяСтрока.Строки.Добавить(); ЛксСкопироватьСтрокиДерева(ЗначениеПеретаскивания.Значение, НоваяСтрокаЗапросов); Если ЗначениеПеретаскивания.Значение.Родитель = НоваяСтрокаЗапросов.Родитель Тогда НоваяСтрокаЗапросов.Запрос = ирНеглобальный.ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(РодительскаяСтрока.Строки, ЗначениеПеретаскивания.Значение.Запрос, "Запрос", Ложь); КонецЕсли; Элемент.ТекущаяСтрока = НоваяСтрокаЗапросов; Если ПараметрыПеретаскивания.Действие = ДействиеПеретаскивания.Перемещение Тогда РодительСтроки = ЗначениеПеретаскивания.Значение.Родитель; Если РодительСтроки = Неопределено Тогда РодительСтроки = Элемент.Значение; Если ЗначениеПеретаскивания.Значение.Владелец() <> РодительСтроки Тогда // Строка другой формы. Не будем ее удалять РодительСтроки = Неопределено; КонецЕсли; КонецЕсли; Если РодительСтроки <> Неопределено Тогда РодительСтроки.Строки.Удалить(ЗначениеПеретаскивания.Значение); КонецЕсли; КонецЕсли; Если Элемент.ИзменяетДанные Тогда ЭтаФорма.Модифицированность = Истина; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ЛксДеревоКонсолиНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение, ИмяТипаСроки) Экспорт Элемент.ТекущаяСтрока = Элемент.ТекущаяСтрока; // Для сохранения изменений в строке ЗначениеПеретаскивания = Новый Структура("Тип, Значение", ИмяТипаСроки, Элемент.ТекущаяСтрока); ПараметрыПеретаскивания.Значение = ЗначениеПеретаскивания; КонецПроцедуры Процедура ЛксСкопироватьСтрокиДерева(СтрокаИсточник, СтрокаПриемник) Экспорт Дерево = СтрокаПриемник.Владелец(); Для Каждого Колонка Из Дерево.Колонки Цикл СтрокаПриемник[Колонка.Имя] = ЛксПолучитьКопиюОбъекта(СтрокаИсточник[Колонка.Имя]); КонецЦикла; Для Каждого Строка Из СтрокаИсточник.Строки Цикл НоваяСтрока = СтрокаПриемник.Строки.Добавить(); ЛксСкопироватьСтрокиДерева(Строка, НоваяСтрока); КонецЦикла; КонецПроцедуры Процедура ЛксИзменитьСвернутость(Видимость, ГлавныйЭлемент, Разделитель, Панель, Направление, ПодчиненныйЭлемент = Неопределено, ПропорциональныйРазмер = Истина) Экспорт Если Разделитель = Неопределено Тогда Разделитель = ГлавныйЭлемент; КонецЕсли; Если ТипЗнч(Разделитель) = Тип("Разделитель") Тогда Если Разделитель.Ориентация = Ориентация.Авто Тогда // возможно это касается только свертки вправо Сообщить("Корректная работа свертки с разделителем """ + Разделитель.Имя + """ с ориентацией Авто невозможна из-за ошибки платформы", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; //ПервыйЭлемент = 0; //ГраницаПервогоЭлемента = 0; //ВторойЭлемент = 0; //ГраницаВторогоЭлемента = 0; Если ирНеглобальный.СтрокиРавныЛкс(Направление, "лево") Тогда Если Видимость Тогда // откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель, ГраницаЭлементаУправления.Право); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право); КонецЕсли; ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево); КонецЕсли; //Разделитель.Ширина = ШиринаРазделителя; Иначе // скроем Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Лево; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Лево; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ГлавныйЭлемент, ГраницаЭлементаУправления.Право); КонецЕсли; КонецЕсли; ИначеЕсли ирНеглобальный.СтрокиРавныЛкс(Направление, "право") Тогда Если Видимость Тогда // откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, Разделитель, ГраницаЭлементаУправления.Лево); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель, ГраницаЭлементаУправления.Право); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Право); КонецЕсли; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево, Разделитель, ГраницаЭлементаУправления.Право); //Разделитель.Ширина = ШиринаРазделителя; КонецЕсли; Иначе // Скроем Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Лево); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Лево); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Право; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Право; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Право, ГлавныйЭлемент, ГраницаЭлементаУправления.Лево); КонецЕсли; КонецЕсли; ИначеЕсли ирНеглобальный.СтрокиРавныЛкс(Направление, "низ") Тогда Если Видимость Тогда // Откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель, ГраницаЭлементаУправления.Низ); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ); КонецЕсли; ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); КонецЕсли; //Разделитель.Высота = ШиринаРазделителя; Иначе // Скроем Если Разделитель <> ГлавныйЭлемент Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх); ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Низ; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Низ; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ГлавныйЭлемент, ГраницаЭлементаУправления.Верх); КонецЕсли; КонецЕсли; ИначеЕсли ирНеглобальный.СтрокиРавныЛкс(Направление, "верх") Тогда Если Видимость Тогда // Откроем Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх); КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Нет; Если Разделитель <> ГлавныйЭлемент Тогда ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Нет; Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Разделитель, ГраницаЭлементаУправления.Низ); Если ПропорциональныйРазмер Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Верх, Панель, ГраницаЭлементаУправления.Низ); Иначе Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Панель, ГраницаЭлементаУправления.Низ); КонецЕсли; ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ, Разделитель, ГраницаЭлементаУправления.Верх); //Разделитель.Высота = ШиринаРазделителя; КонецЕсли; Иначе // Скроем Если Разделитель <> ГлавныйЭлемент Тогда Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Низ); ГлавныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Низ); Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ); ГлавныйЭлемент.Свертка = РежимСверткиЭлементаУправления.Верх; КонецЕсли; Разделитель.Свертка = РежимСверткиЭлементаУправления.Верх; Если ПодчиненныйЭлемент <> Неопределено Тогда ПодчиненныйЭлемент.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ГлавныйЭлемент, ГраницаЭлементаУправления.Низ); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры // ЛксИзменитьСвернутость() Процедура ЛксУстановитьТекстСОткатом(ПолеТекста, Текст) Экспорт СтарыйТекст = ПолеТекста.ПолучитьТекст(); ПолеТекста.УстановитьГраницыВыделения(1, СтрДлина(СтарыйТекст) + 1); ПолеТекста.ВыделенныйТекст = Текст; КонецПроцедуры // ЛксУстановитьТекстСОткатом() // Основным элементом страницы считается одноименный с ней элемент формы. // Процедура ЛксОбновитьЗаголовкиСтраницПанелей(ЭтаФорма) Экспорт ЭлементыФормы = ЭтаФорма.ЭлементыФормы; Для Каждого ЭлементФормы Из ЭлементыФормы Цикл Если ТипЗнч(ЭлементФормы) <> Тип("Панель") Тогда Продолжить; КонецЕсли; ТабличноеПолеСтраниц = ЭлементыФормы.Найти("Страницы" + ЭлементФормы.Имя); Если ТипЗнч(ТабличноеПолеСтраниц) = тип("ТабличноеПоле") Тогда ТаблицаСтраниц = ТабличноеПолеСтраниц.Значение; Иначе ТаблицаСтраниц = Неопределено; КонецЕсли; Для Каждого Страница Из ЭлементФормы.Страницы Цикл Если Страница.Имя = "" Тогда // Служебная страница. Появляется после очистки страниц. Продолжить; КонецЕсли; ЭУ = ЭлементыФормы.Найти(Страница.Имя); Если ЭУ = Неопределено Тогда Продолжить; КонецЕсли; Если Страница.Значение = Null Тогда Количество = "-"; Иначе Суффикс = ""; Количество = Неопределено; Если ТипЗнч(ЭУ) = Тип("ТабличноеПоле") Тогда ЗначениеЭУ = ЭУ.Значение; Если Количество = Неопределено Тогда Попытка Количество = ЗначениеЭУ.Количество(); Исключение КонецПопытки; КонецЕсли; Если Количество = Неопределено Тогда Попытка Количество = ЗначениеЭУ.Элементы.Количество(); //Суффикс = "*"; Исключение КонецПопытки; КонецЕсли; Если Количество = Неопределено Тогда Попытка Количество = ЗначениеЭУ.Строки.Количество(); Суффикс = "*"; Исключение КонецПопытки; КонецЕсли; //Если Количество = 0 Тогда // Попытка // КоличествоКолонок = ЗначениеЭУ.Колонки.Количество(); // Исключение // КоличествоКолонок = 1; // КонецПопытки; // Если КоличествоКолонок = 0 Тогда // Количество = "-"; // КонецЕсли; //КонецЕсли; ИначеЕсли ТипЗнч(ЭУ) = Тип("ПолеТабличногоДокумента") Тогда Количество = ?(ЭУ.ВысотаТаблицы > 0, 1, 0); ИначеЕсли ТипЗнч(ЭУ) = Тип("ПолеТекстовогоДокумента") Тогда Количество = ?(ЭУ.КоличествоСтрок() > 0, 1, 0); ИначеЕсли ТипЗнч(ЭУ) = Тип("Панель") Тогда Количество = ЭУ.Страницы.Количество(); Если Количество = 1 Тогда Если ЭУ.Страницы[0].Имя = "" Тогда Количество = 0; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ТаблицаСтраниц <> Неопределено Тогда СтрокаСтраницы = ТаблицаСтраниц.Найти(Страница.Имя, "ИмяСтраницы"); СтрокаСтраницы.Количество = Количество; КонецЕсли; ЛксОбновитьТекстПослеМаркераВСтроке(Страница.Заголовок, , "" + Количество + Суффикс + ")", "("); КонецЦикла; КонецЦикла; КонецПроцедуры // ЛксОбновитьЗаголовкиСтраницПанелей() // <Описание процедуры> // // Параметры: // Ссылка – Ссылка, КлючЗаписи, КонстантаМенеджер; // ПолноеИмя - Строка - полное имя метаданных для константы. // Процедура ЛксОткрытьСсылкуИзРезультатаПоискаСсылок(Ссылка, ПолноеИмя = "") Экспорт Если ЛксЛиКлючЗаписиРегистра(Ссылка) Тогда ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(Ссылка)); ПолноеИмя = ОбъектМетаданных.ПолноеИмя(); ФормаСписка = ПолучитьФорму(ОбъектМетаданных.ПолноеИмя() + ".ФормаСписка", Новый Структура("ТекущаяСтрока", Ссылка)); Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда ФормаСписка.ПараметрТекущаяСтрока = Ссылка; КонецЕсли; ФормаСписка.Открыть(); ИначеЕсли ЛксПолучитьПервыйФрагмент(ПолноеИмя) = "Константа" Тогда ФормаСписка = Обработки.ирРедакторКонстант.ПолучитьФорму(); ТекущаяСтрока = ЛксПолучитьПоследнийФрагмент(ПолноеИмя); ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока; ФормаСписка.Открыть(); Иначе ОткрытьЗначение(Ссылка); КонецЕсли; КонецПроцедуры // ЛксОткрытьСсылкуИзРезультатаПоискаСсылок() Функция ЛксПромежуточноеОбновлениеСтроковогоЗначенияПоляВвода(Знач Элемент, Текст) Экспорт НачалоКолонки = 0; НачалоСтроки = 0; КонецКолонки = 0; КонецСтроки = 0; Элемент.ПолучитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки); Элемент.Значение = Текст; Элемент.УстановитьГраницыВыделения(1, 1, КонецСтроки, КонецКолонки); Элемент.ВыделенныйТекст = Элемент.ВыделенныйТекст; Элемент.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки); КонецФункции #КонецЕсли // Параметры: // КоличествоПроходов - Число(Н8,0) // КлючЗамера - Строка // ВыдатьСообщение - Булево // Функция ЛксНачатьЗамер(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт ирПлатформа = ирКэш.Получить(); ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров; Если Не ЗначениеЗаполнено(КлючЗамера) Тогда КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя; КонецЕсли; ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1); СтрокаЗамера = ТаблицаЗамеров.Добавить(); СтрокаЗамера.Ключ = КлючЗамера; СтрокаЗамера.Отладчик = ирНеглобальный.ПолучитьИдентификаторПроцессаОтладчикаЛкс() <> Неопределено; СтрокаЗамера.КоличествоПроходов = КоличествоПроходов; Если Ложь Или ВыдатьСообщение //Или СтрокаЗамера.Отладчик Тогда Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов; Если СтрокаЗамера.Отладчик Тогда Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!"; КонецЕсли; Сообщить(Сообщение); КонецЕсли; СтрокаЗамера.ДатаНачала = ЛксПолучитьТекущееВремяВМиллисекундах(); Результат = КоличествоПроходов; Возврат Результат; КонецФункции // Параметры: // КлючЗамера - Строка - По умолчанию последний замер // Функция ЛксКончитьЗамер(Знач КлючЗамера = "") Экспорт ТекущееВремя = ЛксПолучитьТекущееВремяВМиллисекундах(); Платформа = ирКэш.Получить(); ТаблицаЗамеров = Платформа.мТаблицаЗамеров; Если Не ЗначениеЗаполнено(КлючЗамера) Тогда Если ТаблицаЗамеров.Количество() > 0 Тогда СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1]; КонецЕсли; Иначе СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ"); КонецЕсли; Если СтрокаЗамера = Неопределено Тогда Возврат Неопределено; КонецЕсли; Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала; Длительность = Длительность / 1000; Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с"; Если СтрокаЗамера.КоличествоПроходов > 1 Тогда Среднее = Длительность / СтрокаЗамера.КоличествоПроходов; Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с"; КонецЕсли; Если Ложь Или СтрокаЗамера.Отладчик Или ирНеглобальный.ПолучитьИдентификаторПроцессаОтладчикаЛкс() <> Неопределено Тогда Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!"; КонецЕсли; Сообщить(Сообщение); ТаблицаЗамеров.Удалить(СтрокаЗамера); Результат = Длительность; Возврат Результат; КонецФункции // Конструктор Параметров Алгоритма. // // Параметры: // Алгоритм – СправочникСсылка.ирАлгоритмы. // // Возвращаемое значение: // Структура - ключ - имя, значение - значение. // Функция ирКПА(Знач Алгоритм) Экспорт #Если _ Тогда Алгоритм = Справочники.ирАлгоритмы.ПустаяСсылка(); #КонецЕсли СтруктураПараметров = Новый Структура; Для Каждого СтрокаПараметра Из Алгоритм.Параметры Цикл СтруктураПараметров.Вставить(СтрокаПараметра.Имя, СтрокаПараметра.Значение); КонецЦикла; Возврат СтруктураПараметров; КонецФункции // УК() // Именованный Вызов Алгоритма. Передача параметров выполняется по имени. // // Параметры: // Алгоритм – СправочникСсылка.ирАлгоритмы, Строка - ссылка или GUID или имя сервиса; // *СтруктураПараметров – Структура, *Неопределено - ключи - имена параметров, значения - значения параметров; // *пНастройкаАлгоритма - СправочникСсылка.НаборыЗначенийПараметров2iS, *Неопределено - набор значений параметров, // имеющий приоритет ниже, чем СтруктураПараметров; // *ПреобразоватьРезультатВСтрокуВнутр - Булево, *Ложь - преобразовать результат в строку внутреннюю (сериализовать) // // Возвращаемое значение: // Произвольный. // Функция ирИВА(Знач Алгоритм, Знач СтруктураПараметров = Неопределено) Экспорт Если СтруктураПараметров = Неопределено Тогда СтруктураПараметров = Новый Структура; КонецЕсли; АлгоритмОбъект = ирНеглобальный.ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Алгоритм); Результат = ирКэш.Получить().ВыполнитьМетодАлгоритма(АлгоритмОбъект, 1, СтруктураПараметров); Возврат Результат; КонецФункции // ирИВА() // Позиционный Вызов Алгоритма. Передача параметров выполняется по позиции. // // Параметры // Алгоритм – СправочникСсылка.Сервисы2iS, Строка - ссылки или имя сервиса; // *П... – Произвольный, *Null – параметры сервиса. // // Возвращаемое значение: // Произвольное. // Функция ирПВА(Знач Алгоритм, П0=Null, П1=Null, П2=Null, П3=Null, П4=Null, П5=Null, П6=Null, П7=Null, П8=Null, П9=Null) Экспорт АлгоритмОбъект = ирНеглобальный.ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Алгоритм); Результат = ирКэш.Получить().ВыполнитьМетодАлгоритма(АлгоритмОбъект, 0, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9); Возврат Результат; КонецФункции // УФ() #КонецЕсли // Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных // в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана. // Фиксированные коллекции превращаются в нефиксированные. // // Параметры: // КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция; // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник. // // Возвращаемое значение: // КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник. // Функция ЛксСкопироватьУниверсальнуюКоллекцию(КоллекцияИсходная, КоллекцияПриемник = Неопределено) Экспорт ТипКоллекции = ТипЗнч(КоллекцияИсходная); Если Ложь Или ТипКоллекции = Тип("Массив") Или ТипКоллекции = Тип("ФиксированныйМассив") #Если Не ТонкийКлиент И Не ВебКлиент Тогда Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных") #КонецЕсли Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Массив; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл КоллекцияПриемник.Добавить(Элемент); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Структура") Или ТипКоллекции = Тип("ФиксированнаяСтруктура") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Структура; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли Ложь Или ТипКоллекции = Тип("Соответствие") Или ТипКоллекции = Тип("ФиксированноеСоответствие") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый Соответствие; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение); КонецЦикла; Возврат КоллекцияПриемник; ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда Если КоллекцияПриемник = Неопределено Тогда КоллекцияПриемник = Новый СписокЗначений; КонецЕсли; Для Каждого Элемент Из КоллекцияИсходная Цикл ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент); КонецЦикла; Возврат КоллекцияПриемник; Иначе Сообщить("Неверный тип универсальной коллекции для копирования"); Возврат Неопределено; КонецЕсли; КонецФункции // ЛксСкопироватьУниверсальнуюКоллекцию()