RDT1C/CommonModules/ирОбщий/Ext/Module.bsl
Администратор 026259e17a .
2016-12-04 00:21:34 +03:00

18665 lines
1.2 MiB
Raw Blame History

This file contains ambiguous Unicode characters

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

////////////////////////////////////////////////////////////////////////////////
// Подсистема "Инструменты разработчика"
//
// Авторское право (с) 2007, Старых С.А.
// Разрешается повторное распространение и использование как в виде исходника так и в двоичной форме,
// с модификациями или без, при соблюдении следующих условий:
// - При повторном распространении исходного кода должно оставаться указанное выше уведомление об авторском
// праве, этот список условий и нижеследующий отказ от гарантий.
// - При повторном распространении двоичного кода должно воспроизводиться указанное выше уведомление об
// авторском праве, этот список условий и нижеследующий отказ от гарантий в документации и/или в других
// материалах, поставляемых при распространении.
//
// ЭТО ПРОГРАММА ПРЕДОСТАВЛЕНА БЕСПЛАТНО ДЕРЖАТЕЛЯМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ "КАК ОНА ЕСТЬ"
// БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ,
// ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ,
// ЕСЛИ НЕ ТРЕБУЕТСЯ СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ДЕРЖАТЕЛЬ АВТОРСКИХ
// ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО
// РАЗРЕШЕНО ВЫШЕ, НЕ ОТВЕТСТВЕННЫ ПЕРЕД ВАМИ ЗА УБЫТКИ, ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ
// ПОСЛЕДОВАВШИЕ УБЫТКИ, ПРОИСТЕКАЮЩИЕ ИЗ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
// НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА
// ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ
// ДЕРЖАТЕЛЬ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;
// Выполняет текст алгоритма.
//
// Параметры:
// ТекстДляВыполнения Строка;
// _АлгоритмОбъект - СправочникОбъект
// *СтруктураПараметров - Структура, *Неопределено.
//
Функция ВыполнитьАлгоритм(_ТекстДляВыполнения, _АлгоритмОбъект = Null, _Режим = Null,
_П0 = Null, _П1 = Null, _П2 = Null, _П3 = Null, _П4 = Null, _П5 = Null, _П6 = Null, _П7 = Null, _П8 = Null, _П9 = Null) Экспорт
Перем Результат;
Выполнить(_ТекстДляВыполнения);
Возврат Результат;
КонецФункции
Процедура ВыполнитьАлгоритмБезРезультата(_ТекстДляВыполнения) Экспорт
Выполнить(_ТекстДляВыполнения);
КонецПроцедуры
Функция ВычислитьВыражение(Выражение, Параметры = Неопределено) Экспорт
Возврат Вычислить(Выражение);
КонецФункции
Функция ПолучитьПриглашениеОткрытьОтладчикЛкс() Экспорт
Возврат "Нажмите кнопку ""Подробно"", а затем ""Конфигуратор"", чтобы начать отладку!";
КонецФункции
Процедура ОткрытьОтладчикЛкс() Экспорт
ВызватьИсключение ПолучитьПриглашениеОткрытьОтладчикЛкс();
КонецПроцедуры
Процедура ОбработкаПолученияФормыЛкс(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка) Экспорт
#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
#Иначе
ВыбраннаяФорма = "ОбщаяФорма.ирНевозможноВТонкомКлиенте";
СтандартнаяОбработка = Ложь;
#КонецЕсли
КонецПроцедуры
Функция ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(Знач ИмяПользователяИнфобазы = "", Знач ПарольПользователяИнфобазы = "", КодРазрешения = "", РежимКонфигуратора = Ложь,
РежимЗапуска = "ОбычноеПриложение", РазрешитьОтладку = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Ложь, ДополнительныеПараметры = "", СообщитьСтрокуПараметров = Истина,
СтрокаСоединения = "", ОткрытьПортативныеИнструменты = Ложь) Экспорт
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПараметрыЗапуска = "";
Если РежимКонфигуратора Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " CONFIG";
Иначе
ПараметрыЗапуска = ПараметрыЗапуска + " ENTERPRISE";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
Если ЗначениеЗаполнено(ИмяПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /WA- /N""" + ИмяПользователяИнфобазы + """";
КонецЕсли;
Если ЗначениеЗаполнено(ПарольПользователяИнфобазы) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /P""" + ПарольПользователяИнфобазы + """";
КонецЕсли;
ПараметрыЗапуска = ПараметрыЗапуска + " /UC""" + КодРазрешения + """";
Если РазрешитьОтладку Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Debug";
КонецЕсли;
Если ОчисткаКэшаКлиентСерверныхВызовов Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /ClearCache";
КонецЕсли;
Если ОткрытьПортативныеИнструменты И ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /Execute""" + ирПортативный.ИспользуемоеИмяФайла + """";
КонецЕсли;
Если ЗначениеЗаполнено(ДополнительныеПараметры) Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " " + ДополнительныеПараметры;
КонецЕсли;
Если СтрокиРавныЛкс(РежимЗапуска, "Авто") Тогда
// Из-за этого иногда долго стартует почему то
ПараметрыЗапуска = ПараметрыЗапуска + " /AppAutoCheckMode"; // Автоматический выбор типа приложения для запуска
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "ОбычноеПриложение") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeOrdinaryApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТолстый") Тогда
ПараметрыЗапуска = ПараметрыЗапуска + " /RunModeManagedApplication";
ИначеЕсли СтрокиРавныЛкс(РежимЗапуска, "УправляемоеПриложениеТонкий") Тогда
//ПараметрыЗапуска = ПараметрыЗапуска + "/IBConnectionString""" + СтрЗаменить(СтрокаСоединения, """", """""") + """";
КонецЕсли;
Если СообщитьСтрокуПараметров Тогда
Сообщить(ПараметрыЗапуска);
КонецЕсли;
Возврат ПараметрыЗапуска;
КонецФункции
Функция ПолучитьОписаниеТиповОдногоТипаИзОписанияТиповЛкс(Тип, ОписаниеТипов) Экспорт
#Если _ Тогда
ОписаниеТипов = Новый ОписаниеТипов;
#КонецЕсли
Массив = Новый Массив;
Массив.Добавить(Тип);
Результат = Новый ОписаниеТипов(Массив, ОписаниеТипов.КвалификаторыЧисла, ОписаниеТипов.КвалификаторыСтроки, ОписаниеТипов.КвалификаторыДаты, ОписаниеТипов.КвалификаторыДвоичныхДанных);
Возврат Результат;
КонецФункции
Процедура ОбновитьТипЗначенияИзОписанияТиповЛкс(ТекущаяСтрока, Знач ИмяКолонкиЗначения = "Значение", Знач ИмяКолонкиОписанияТипов = "ОписаниеТипов",
Знач ИмяКолонкиТипаЗначения = "ТипЗначения") Экспорт
ТекущаяСтрока[ИмяКолонкиТипаЗначения] = ПолучитьОписаниеТиповОдногоТипаИзОписанияТиповЛкс(ТипЗнч(ТекущаяСтрока[ИмяКолонкиЗначения]), ТекущаяСтрока[ИмяКолонкиОписанияТипов]);
КонецПроцедуры
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Функция СоздатьСсылочныйОбъектПоМетаданнымЛкс(ОбъектМД, ЭтоГруппаДляНового = Ложь, ИдентификаторСсылки = Неопределено) Экспорт
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор();
КонецЕсли;
Если ЭтоГруппаДляНового Тогда
Менеджер = ПолучитьМенеджерЛкс(ОбъектМД);
Объект = Менеджер.СоздатьГруппу();
Иначе
Объект = Новый (СтрЗаменить(ОбъектМД.ПолноеИмя(), ".", "Объект."));
КонецЕсли;
Объект = ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки);
Возврат Объект;
КонецФункции
Функция ЗаменитьИдентификаторОбъектаЛкс(Объект, ИдентификаторСсылки = Неопределено) Экспорт
Если ИдентификаторСсылки = Неопределено Тогда
ИдентификаторСсылки = Новый УникальныйИдентификатор;
КонецЕсли;
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=967697#967697
//Объект = СериализаторXDTO.ЗаписатьXDTO(Объект);
//Объект.Ref = ИдентификаторСсылки;
//Объект.IsFolder = ЭтоГруппаДляНового;
//Объект = СериализаторXDTO.ПрочитатьXDTO(Объект);
//
// Этот метод опасный, т.к. может привести к нежелательным изменениям в объекте!
ЗаписьХмл = Новый ЗаписьXML;
ЗаписьХмл.УстановитьСтроку();
ЗаписатьXML(ЗаписьХмл, Объект);
СтрокаХмл = ЗаписьХмл.Закрыть();
ИмяЭлементаСсылки = "Ref";
СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаСсылки + ">" + XMLСтрока(Объект.Ссылка) + "</" + ИмяЭлементаСсылки + ">",
"<" + ИмяЭлементаСсылки + ">" + XMLСтрока(ИдентификаторСсылки) + "</" + ИмяЭлементаСсылки + ">");
//ИмяЭлементаЭтоГруппа = "IsFolder";
//Если Найти(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">") > 0 Тогда
// СтрокаХмл = СтрЗаменить(СтрокаХмл, "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(Объект.IsFolder) + "</" + ИмяЭлементаЭтоГруппа + ">",
// "<" + ИмяЭлементаЭтоГруппа + ">" + XMLСтрока(ЭтоГруппаДляНового) + "</" + ИмяЭлементаЭтоГруппа + ">");
//КонецЕсли;
ЧтениеХмл = Новый ЧтениеXML;
ЧтениеХмл.УстановитьСтроку(СтрокаХмл);
Объект = ПрочитатьXML(ЧтениеХмл);
Возврат Объект;
КонецФункции
Функция ПолучитьРежимЗаписиНаСервереПоУмолчаниюЛкс() Экспорт
Результат = Истина
И (Ложь
Или Не ирКэш.ЛиПортативныйРежимЛкс()
Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение;
Возврат Результат;
КонецФункции
Функция СкопироватьКолонкиДереваЗначенийЛкс(ДеревоИсточник, ДеревоПриемник = Неопределено) Экспорт
#Если _ Тогда
ДеревоИсточник = Новый ДеревоЗначений;
#КонецЕсли
Если ДеревоПриемник = Неопределено Тогда
ДеревоПриемник = Новый ДеревоЗначений;
КонецЕсли;
Для Каждого КолонкаДерева Из ДеревоИсточник.Колонки Цикл
ДеревоПриемник.Колонки.Добавить(КолонкаДерева.Имя, КолонкаДерева.ТипЗначения, КолонкаДерева.Заголовок, КолонкаДерева.Ширина);
КонецЦикла;
Возврат ДеревоПриемник;
КонецФункции
// ПропускатьДвиженияВнеПланаОбмена - Булево - при РегистрироватьДвиженияВместеСДокументом = Истина позволяет управлять поведением для тех движений, которые не входят в план обмена,
// Если Истина, то такие движения пропускаются, иначе вызывается исключение
Функция ИзменитьРегистрациюДляУзлаЛкс(УзелИлиМассив, КлючОбъекта, НовоеЗначение, РегистрироватьДвиженияВместеСДокументом = Ложь, ДвиженияВместеСПоследовательностями = Ложь,
ПропускатьДвиженияВнеПланаОбмена = Истина, ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла = Ложь) Экспорт
Если КлючОбъекта = Неопределено Тогда
ВызватьИсключение "Изменение регистрации всех данных недопустимо";
КонецЕсли;
Если ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
ОбъектМД = КлючОбъекта;
Иначе
ОбъектМД = КлючОбъекта.Метаданные();
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
ЭтоДокумент = ЛиКорневойТипДокументаЛкс(ПолучитьПервыйФрагментЛкс(ПолноеИмяМД));
Если ЭтоДокумент И РегистрироватьДвиженияВместеСДокументом И ТипЗнч(КлючОбъекта) = Тип("ОбъектМетаданных") Тогда
Запрос = Новый Запрос("ВЫБРАТЬ Т.Ссылка ИЗ " + ПолноеИмяМД + " КАК Т");
МассивОбъектов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0);
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МассивОбъектов.Количество(), "Изменение регистрации");
Иначе
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(КлючОбъекта);
КонецЕсли;
Если ТипЗнч(УзелИлиМассив) = Тип("Массив") Тогда
Если УзелИлиМассив.Количество() > 0 Тогда
ОдинУзелОбмена = УзелИлиМассив[0];
Иначе
ОдинУзелОбмена = Неопределено;
КонецЕсли;
МассивУзлов = УзелИлиМассив;
Иначе
ОдинУзелОбмена = УзелИлиМассив;
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(УзелИлиМассив);
КонецЕсли;
Если Не ЗначениеЗаполнено(ОдинУзелОбмена) Тогда
Сообщить("Не указан узел для регистрации изменений");
Возврат Ложь;
КонецЕсли;
Если ПроверятьНаличиеТаблицыИзмененийДляКаждогоУзла Тогда
УзлыДляРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов);
Если УзлыДляРегистрации.Количество() = 0 Тогда
Возврат Истина;
КонецЕсли;
Иначе
УзлыДляРегистрации = МассивУзлов;
КонецЕсли;
Успех = Истина;
ирПлатформа = ирКэш.Получить();
Для Каждого Объект Из МассивОбъектов Цикл
Если Индикатор <> Неопределено Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если НовоеЗначение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, Объект);
// Антибаг платформы 8.2.17-8.3.4
Если Истина
И ирПлатформа.ВерсияПлатформы < 803005
И ТипЗнч(Объект) <> Тип("ОбъектМетаданных")
И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбмена, Объект)
Тогда
Успех = Ложь;
Сообщить("Не удалось зарегистрировать изменение """ + Объект + """ из-за ошибки платформы, исправленной в 8.3.5");
КонецЕсли;
Иначе
ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, Объект);
КонецЕсли;
Если РегистрироватьДвиженияВместеСДокументом И ЭтоДокумент Тогда
ОбъектыМД = ирОбщий.ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(ОбъектМД, ДвиженияВместеСПоследовательностями, Истина);
Для Каждого МетаРегистр из ОбъектыМД Цикл
Если Не ОдинУзелОбмена.Метаданные().Состав.Содержит(МетаРегистр) Тогда
Если ПропускатьДвиженияВнеПланаОбмена Тогда
Продолжить;
Иначе
ВызватьИсключение "Движение документа по регистру " + МетаРегистр.ПолноеИмя() + " не может быть зарегистрировано в плане обмена " + ОдинУзелОбмена.Метаданные().Имя;
КонецЕсли;
КонецЕсли;
ИмяТаблицыБДРегистра = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(МетаРегистр);
НаборЗаписей = ирОбщий.СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ИмяТаблицыБДРегистра);
НаборЗаписей.Отбор[0].Установить(Объект.Ссылка);
Если НовоеЗначение Тогда
ПланыОбмена.ЗарегистрироватьИзменения(УзлыДляРегистрации, НаборЗаписей);
// Антибаг платформы 8.2.17-8.3.4
Если Истина
И ирПлатформа.ВерсияПлатформы < 803005
И Не ПланыОбмена.ИзменениеЗарегистрировано(ОдинУзелОбмена, НаборЗаписей)
Тогда
Успех = Ложь;
Сообщить("Не удалось зарегистрировать изменение " + Объект + " из-за ошибки платформы, исправленной в 8.3.5");
КонецЕсли;
Иначе
ПланыОбмена.УдалитьРегистрациюИзменений(УзлыДляРегистрации, НаборЗаписей);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если Индикатор <> Неопределено Тогда
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Успех;
КонецФункции
Функция ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(ОбъектМД, МассивУзлов, ТолькоУзлыСАвторегистрацией = Ложь) Экспорт
УзлыДляРегистрации = Новый Массив;
Для Каждого ПроверяемыйУзел Из МассивУзлов Цикл
ЭлементСостава = ПроверяемыйУзел.Метаданные().Состав.Найти(ОбъектМД);
Если Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или Не ТолькоУзлыСАвторегистрацией
Или ЭлементСостава.АвтоРегистрация = АвтоРегистрацияИзменений.Разрешить)
Тогда
УзлыДляРегистрации.Добавить(ПроверяемыйУзел);
КонецЕсли;
КонецЦикла;
Возврат УзлыДляРегистрации;
КонецФункции
// Копирует регистрацию изменений с узла источника на узлы приемники. Опционально каждый тип данных отдельно равномерно распределяется по узлам приемникам.
// Параметры:
// НомерСообщения - Неопределено - брать номер отправленного с узла, Null - не фильтровать но номеру сообщения, иначе выбираются все изменения с номером равным или меньшим заданного
// Возвращаемое значение: Массив - количество изменений зарегистрированных по каждому узлу
Функция СкопироватьРаспределитьРегистрациюИзмененийПоУзламЛкс(УзелИсточник, УзлыПриемники, Распределять = Ложь, НомерСообщения = Null, МассивМетаданных = Неопределено) Экспорт
#Если _ Тогда
УзелИсточник = ПланыОбмена.ПолныйИис.ПустаяСсылка();
УзлыПриемники = Новый Массив;
#КонецЕсли
#Если Клиент Тогда
Состояние("Выбираем все изменения для узла...");
#КонецЕсли
Если НомерСообщения = Неопределено Тогда
НомерСообщения = УзелИсточник.НомерОтправленного;
КонецЕсли;
Результат = Новый Массив;
Для Счетчик = 1 По УзлыПриемники.Количество() Цикл
Если Распределять И ТипЗнч(УзлыПриемники[Счетчик - 1]) <> ТипЗнч(УзелИсточник) Тогда
ВызватьИсключение "Нельзя распределять на узлы другого плана обмена";
КонецЕсли;
Результат.Добавить(0);
КонецЦикла;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", УзелИсточник);
Запрос.УстановитьПараметр("НомерСообщения", НомерСообщения);
МетаПланОбмена = УзелИсточник.Метаданные();
ТекстЗапроса = "";
ТипыДанныхЗапросов = Новый Массив;
Для Каждого ЭлементСостава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСостава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + ";" + Символы.ПС;
КонецЕсли;
ПолноеИмяМД = МетаОбъект.ПолноеИмя();
ТипыДанныхЗапросов.Добавить(ПолноеИмяМД);
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(ПолноеИмяМД, ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ *
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел";
Если НомерСообщения <> Null Тогда
ТекстЗапроса = ТекстЗапроса = " И НомерСообщения <= &НомерСообщения";
КонецЕсли;
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
РезультатПакета = Запрос.ВыполнитьПакет();
ИндикаторСостава = ПолучитьИндикаторПроцессаЛкс(РезультатПакета.Количество(), "Распределение изменений");
Для ИндексЗапроса = 0 По РезультатПакета.ВГраница() Цикл
ОбработатьИндикаторЛкс(ИндикаторСостава);
РезультатЗапроса = РезультатПакета[ИндексЗапроса];
#Если _ Тогда
РезультатЗапроса1 = Новый Запрос;
РезультатЗапроса = РезультатЗапроса1.Выполнить();
#КонецЕсли
ПолноеИмяМД = ТипыДанныхЗапросов[ИндексЗапроса];
//Если Ложь
// Или РезультатЗапроса.Колонки.Найти("НомерСообщения1") <> Неопределено
// Или РезультатЗапроса.Колонки.Найти("Узел1") <> Неопределено
//Тогда
// ВызватьИсключение "В таблице " + ПолноеИмяМД + " в основной отбор включены измерения с запрещенными именами (НомерСообщения, Узел)";
//КонецЕсли;
ТаблицаКорректна = Истина;
Для Каждого КолонкаРезультата Из РезультатЗапроса.Колонки Цикл
Если Не ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, КолонкаРезультата.Имя) Тогда
Сообщить("Изменения таблицы " + ПолноеИмяМД + " не были скопированы, т.к. она имеет некорректное поле " + КолонкаРезультата.Имя + ", порожденное конфликтом имен полей");
ТаблицаКорректна = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ТаблицаКорректна Тогда
Продолжить;
КонецЕсли;
МакетныйОбъект = "";
ТекущаяГруппаТипаМетаданных = "";
Выборка = РезультатЗапроса.Выбрать();
ИндексУзла = 0;
КоличествоЭлементов = Выборка.Количество();
Если КоличествоЭлементов > 0 Тогда
Если Распределять Тогда
УзлыРегистрации = УзлыПриемники;
Иначе
УзлыРегистрации = ПолучитьРазрешенныеУзлыДляОбъектаМДЛкс(Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД), УзлыПриемники);
Если УзлыРегистрации.Количество() < УзлыПриемники.Количество() Тогда
Сообщить("Изменения таблицы " + ПолноеИмяМД + " были скопированы не на все узлы, т.к. некоторые планы обмена приемников не содержат ее.");
КонецЕсли;
КонецЕсли;
Если УзлыРегистрации.Количество() > 0 Тогда
ИндикаторТаблицы = ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, ПолноеИмяМД);
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМД, МакетныйОбъект, ТекущаяГруппаТипаМетаданных); //, КлючевыеПоля
Пока Выборка.Следующий() Цикл
ОбработатьИндикаторЛкс(ИндикаторТаблицы);
Объект = ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Выборка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Ложь, "НомерСообщения, Узел");
// Регистрация
Если Распределять Тогда
УзелПриемник = УзлыРегистрации[ИндексУзла];
ПланыОбмена.ЗарегистрироватьИзменения(УзелПриемник, Объект);
Результат[ИндексУзла] = Результат[ИндексУзла] + 1;
ИндексУзла = ИндексУзла + 1;
Если ИндексУзла = УзлыРегистрации.Количество() Тогда
ИндексУзла = 0;
КонецЕсли;
Иначе
ПланыОбмена.ЗарегистрироватьИзменения(УзлыРегистрации, Объект);
Результат[0] = Результат[0] + 1;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
КонецЕсли;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЭтоКорректноеПолеТаблицыИзмененийЛкс(ПолноеИмяМД, ИмяПоля) Экспорт
Если Ложь
Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "Узел1")
Или ирОбщий.СтрокиРавныЛкс(ИмяПоля, "НомерСообщения1")
Тогда
//ПолноеИмяРегистра = ирОбщий.ПолучитьСтрокуМеждуМаркерамиЛкс(ПолноеИмяТаблицыБД,, ".Изменения");
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяМД);
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД);
Если ОбъектМД <> Неопределено Тогда
Если ОбъектМД.Измерения.Найти("" + ИмяПоля) = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Истина;
КонецФункции
// ИгнорироватьКолонки - Строка - имена колонок через запятую, которые не будут учитываться
Функция ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(Знач Выборка, Знач МакетныйОбъект, Знач ТекущаяГруппаТипаМетаданных, СчитатьДанныеОбъекта = Истина,
Знач ИгнорироватьКолонки = "", Заблокировать = Ложь) Экспорт
Если ТекущаяГруппаТипаМетаданных = "Ссылочный" Тогда
Объект = Выборка.Ссылка;
Если Заблокировать Тогда
ЗаблокироватьСсылкуВТранзакцииЛкс(Объект);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
Объект = Объект.ПолучитьОбъект();
КонецЕсли;
ИначеЕсли ТекущаяГруппаТипаМетаданных = "Регистр" Тогда
Объект = МакетныйОбъект;
Если ЗначениеЗаполнено(ИгнорироватьКолонки) Тогда
ИгнорироватьКолонки = Нрег(ИгнорироватьКолонки) + ",";
КонецЕсли;
Для Каждого ЭлементОтбора Из Объект.Отбор Цикл
Если Найти(ИгнорироватьКолонки, НРег(ЭлементОтбора.Имя) + ",") > 0 Тогда
Продолжить;
КонецЕсли;
Попытка
ЗначениеПоля = Выборка[ЭлементОтбора.Имя];
Исключение
// Независимый регистр сведений, у измерения не включен ОсновнойОтбор
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеПоля;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если Заблокировать Тогда
ЗаблокироватьНаборЗаписейПоОтборуЛкс(Объект);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
Объект.Прочитать();
КонецЕсли;
ИначеЕсли ТекущаяГруппаТипаМетаданных = "Константа" Тогда
Объект = МакетныйОбъект;
Если Заблокировать Тогда
ЗаблокироватьКонстантуЛкс(Объект);
КонецЕсли;
Если СчитатьДанныеОбъекта Тогда
Объект.Прочитать();
КонецЕсли;
КонецЕсли;
Возврат Объект;
КонецФункции
// Добавляет глобальные переменные и методы в контекст поля текстового документа с контекстной подсказкой.
//
// Параметры
// ПолеТекстовогоДокументаСКонтекстнойПодсказкой - ОбработкаОбъект.ПолеТекстовогоДокументаСКонтекстнойПодсказкой.
//
Процедура ИнициализироватьГлобальныйКонтекстПодсказкиЛкс(ПолеТекстовогоДокументаСКонтекстнойПодсказкой) Экспорт
#Если _ Тогда
ПолеТекстовогоДокументаСКонтекстнойПодсказкой = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
Если ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ЯзыкПрограммы = 1 Тогда
Возврат;
КонецЕсли;
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ОчиститьТаблицуСловЛокальногоКонтекста();
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьПравилоВычисленияФункции(
"ирКПА", "ПравилоВычисленияТипаЗначенияКПА");
МассивГлобальныхПеременных = Новый Массив;
МассивГлобальныхПеременных.Добавить("ирПлатформа");
Для Каждого ИмяГлобальнойПеременной Из МассивГлобальныхПеременных Цикл
Попытка
ГлобальнаяПеременная = ВычислитьВыражение(ИмяГлобальнойПеременной);
Исключение
// ирПлатформа может отсутствовать
Продолжить;
КонецПопытки;
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(ГлобальнаяПеременная));
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста(
ИмяГлобальнойПеременной, "Свойство", Новый ОписаниеТипов(МассивТипов), ГлобальнаяПеременная, Истина);
КонецЦикла;
СтруктураГлобальныхФункций = Новый Структура;
СтруктураГлобальныхФункций.Вставить("Исследовать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Отладить", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Оперировать", Тип("Число"));
СтруктураГлобальныхФункций.Вставить("Наблюдать");
Для Каждого ЭлементГлобальнойФункции Из СтруктураГлобальныхФункций Цикл
Если ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("Тип") Тогда
МассивТипов = Новый Массив;
МассивТипов.Добавить(ЭлементГлобальнойФункции.Значение);
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
ИначеЕсли ТипЗнч(ЭлементГлобальнойФункции.Значение) = Тип("ОписаниеТипов") Тогда
ОписаниеТипов = ЭлементГлобальнойФункции.Значение;
КонецЕсли;
ПолеТекстовогоДокументаСКонтекстнойПодсказкой.ДобавитьСловоЛокальногоКонтекста(
ЭлементГлобальнойФункции.Ключ, "Метод", ОписаниеТипов);
КонецЦикла;
КонецПроцедуры // ИнициализироватьГлобальныйКонтекстПодсказкиЛкс()
// Параметры - ТаблицаЗначений с колонкой Имя
Функция ЛиПараметрыАлгоритмыКорректныЛкс(Параметры) Экспорт
Результат = Истина;
Если Параметры.Количество() = 0 Тогда
Возврат Результат;
КонецЕсли;
Для Каждого СтрокаПараметра Из Параметры Цикл
Если Не ЛиИмяПеременнойЛкс(СтрокаПараметра.Имя) Тогда
Результат = Ложь;
Сообщить("Имя параметра """ + СтрокаПараметра.Имя + """ не отвечает правилам формирования имен встроенного языка",
СтатусСообщения.Внимание);
КонецЕсли;
КонецЦикла;
НеуникальныеИмена = ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Параметры, "Имя");
Для Каждого НеуникальноеИмя Из НеуникальныеИмена Цикл
Сообщить("Параметр """ + НеуникальноеИмя + """ встречается более одного раза", СтатусСообщения.Внимание);
Результат = Ложь;
КонецЦикла;
Возврат Результат;
КонецФункции // ПараметрыКорректны()
// Возможно нужно объединить с ПолучитьМетаданныеЛкс
Функция ПолучитьМетаданныеПоПолномуИмениЛкс(ПолноеИмяМД) Экспорт
Объект = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД);
Результат = Объект.Метаданные();
Возврат Результат;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МЕТАДАННЫМИ И ТИПАМИ
// Получает тип из описания типов, типа или значения.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Тип - найденный тип.
//
Функция ПолучитьТипОбъектаЛкс(пОбъект)
ТипОбъекта = Тип("Неопределено");
ТипПараметра = ТипЗнч(пОбъект);
Если ТипПараметра = Тип("ОписаниеТипов") Тогда
Если пОбъект.Типы().Количество() > 0 Тогда
ТипОбъекта = пОбъект.Типы()[0];
КонецЕсли;
ИначеЕсли ТипПараметра <> Тип("Тип") Тогда
ТипОбъекта = ТипПараметра;
Иначе
ТипОбъекта = пОбъект;
КонецЕсли;
Возврат ТипОбъекта;
КонецФункции // ПолучитьТипОбъектаЛкс()
// Проверяет, является ли строка именем корневого типа объекта БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина тип является корневым типом объекта БД;
// Ложь иначе.
//
Функция ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "БизнесПроцесс"
ИЛИ КорневойТип = "Задача"
ИЛИ КорневойТип = "Документ"
ИЛИ КорневойТип = "ПланВидовРасчета"
ИЛИ КорневойТип = "ПланВидовХарактеристик"
ИЛИ КорневойТип = "ПланОбмена"
ИЛИ КорневойТип = "ПланСчетов"
ИЛИ КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКонстантыЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Константа"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипПланаОбменаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "ПланОбмена"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипДокументаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Документ"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем корневого типа ссылки.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина тип является корневым типом ссылки;
// Ложь иначе.
//
Функция ЛиКорневойТипСсылкиЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Перечисление"
ИЛИ КорневойТип = "Точки" // Грязно
ИЛИ ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипСсылкиЛкс()
// Проверяет, является ли строка именем корневого типа регистра БД.
//
// Параметры:
// пИмяКорневогоТипа - Строка, Неопределено - имя корневого типа.
//
// Возвращаемое значение:
// Истина тип является корневым типом регистра БД;
// Ложь иначе.
//
Функция ЛиКорневойТипРегистраБДЛкс(КорневойТип, СчитатьПоследовательностьРегистром = Истина) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
ИЛИ КорневойТип = "РегистрНакопления"
ИЛИ КорневойТип = "РегистрБухгалтерии"
ИЛИ КорневойТип = "ДвиженияССубконто"
ИЛИ КорневойТип = "РегистрРасчета"
ИЛИ КорневойТип = "Перерасчет"
ИЛИ (Истина
И СчитатьПоследовательностьРегистром
И КорневойТип = "Последовательность")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраРасчетаЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипРегистраСведенийЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "РегистрСведений"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипПеречисленияЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Перечисление"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "Перечисление"
ИЛИ ТипТаблицы = "Точки"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипРегистраБДЛкс()
Функция ЛиКорневойТипПоследовательностиЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "Последовательность"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "ЖурналДокументов"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКорневойТипКритерияОтбораЛкс(КорневойТип) Экспорт
Если Ложь
ИЛИ КорневойТип = "КритерийОтбора"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С МЕТАДАННЫМИ И ТИПАМИ
Функция ЛиКорневойТипТаблицыБДЛкс(КорневойТип) Экспорт
Если Ложь
Или ЛиКорневойТипЖурналаДокументовЛкс(КорневойТип)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип)
Или ЛиКорневойТипРегистраБДЛкс(КорневойТип)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Проверяет, является ли строка именем типа вложенной таблицы БД.
//
// Параметры:
// ТипТаблицы - Строка, Неопределено - имя типа таблицы.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "ТабличнаяЧасть"
ИЛИ ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипВложеннойТаблицыБДЛкс()
Функция ЛиИмяПредопределеннойТабличнойЧастиЛкс(ТипТаблицы) Экспорт
Если Ложь
ИЛИ ТипТаблицы = "ВидыСубконто"
ИЛИ ТипТаблицы = "БазовыеВидыРасчета"
ИЛИ ТипТаблицы = "ВедущиеВидыРасчета"
ИЛИ ТипТаблицы = "ВытесняющиеВидыРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипВложеннойТаблицыБДЛкс()
// Проверяет, корневой тип на наличие реквизита "Код".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина реквизит "Код" имеется;
// Ложь иначе.
//
Функция ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Экспорт
Если Ложь
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланОбмена"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланРасчета"
Или КорневойТип = "Справочник"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСКодомЛкс()
// Проверяет, корневой тип на наличие реквизита "Предопределенный".
//
// Параметры:
// КорневойТип - Строка, Произвольный.
//
// Возвращаемое значение:
// Истина реквизит "Предопределенный" имеется;
// Ложь иначе.
//
Функция ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Экспорт
Если Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланСчетов"
Или КорневойТип = "ПланВидовХарактеристик"
Или КорневойТип = "ПланВидовРасчета"
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКорневойТипОбъектаСПредопределеннымЛкс()
// Проверяет, метаданные на иерархию.
// Иначе говоря проверяется начилие реквизита "Родитель".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина метаданные с иерархией;
// Ложь иначе.
//
Функция ЛиМетаданныеИерархическогоОбъектаЛкс(пМетаданныеТипа) Экспорт
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа);
Если Ложь
Или КорневойТип = "ПланСчетов"
Или (Истина
И (Ложь
Или КорневойТип = "Справочник"
Или КорневойТип = "ПланВидовХарактеристик")
И пМетаданныеТипа.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеИерархическогоОбъектаЛкс()
// Проверяет, метаданные на иерархию с группами.
// Иначе говоря проверяется начилие реквизита "ЭтоГруппа".
//
// Параметры:
// пМетаданныеТипа - ОбъектМетаданных, Неопределено.
//
// Возвращаемое значение:
// Истина метаданные с иерархией групп;
// Ложь иначе.
//
Функция ЛиМетаданныеОбъектаСГруппамиЛкс(пМетаданныеТипа) Экспорт
//ТипТаблицы = ПолучитьТипТаблицыБДЛкс(пМетаданныеТипа);
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданныеТипа, Истина);
Если Ложь
Или (Истина
И КорневойТип = "Справочник"
И пМетаданныеТипа.Иерархический
И пМетаданныеТипа.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов)
Или (Истина
И КорневойТип = "ПланВидовХарактеристик"
И пМетаданныеТипа.Иерархический)
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМетаданныеОбъектаСГруппамиЛкс()
// Проверяет, является ли значение ссылкой на объект БД.
//
// Параметры:
// пЗначение ОбъектМетаданных, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина значение является ссылкой на объект БД;
// Ложь значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаОбъектБДЛкс(пЗначение, ИсключаяСсылкиМетаданных = Истина) Экспорт
//Результат = ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьКорневойТипКонфигурацииЛкс(пЗначение, Истина));
Результат = ЛиТипСсылкиНаОбъектБДЛкс(ТипЗнч(пЗначение), ИсключаяСсылкиМетаданных);
Возврат Результат;
КонецФункции // ЛиСсылкаНаОбъектБДЛкс
Функция ЛиТипСсылкиНаОбъектБДЛкс(Тип, ИсключаяСсылкиМетаданных = Истина) Экспорт
Результат = Ложь;
ХмлТип = XMLТип(Тип);
Если ХмлТип <> Неопределено Тогда
Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда
Если Ложь
Или Не ИсключаяСсылкиМетаданных
Или (Истина
И Найти(ХмлТип.ИмяТипа, "BusinessProcessRoutePointRef.") = 0
И Найти(ХмлТип.ИмяТипа, "EnumRef.") = 0)
Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТипСсылкиТочкиМаршрутаЛкс(Тип) Экспорт
XMLТип = XMLТип(Тип);
Если XMLТип <> Неопределено Тогда
Если Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0 Тогда
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
// Получить структуру отбора по связям И параметрам выбора
//
// Параметры:
// ЭтаФорма - <тип> -
// ПолеФормыИлиРеквизитМетаданных - <тип> -
// ДляОчистки - <тип>, Ложь -
//
// Возвращаемое значение:
//
Функция ПолучитьСтруктуруОтбораПоСвязямИПараметрамВыбораЛкс(ЭтотОбъект, ПолеФормыИлиРеквизитМетаданных, ОбъектВладелец = Неопределено, ДляОчистки = Ложь) Экспорт
Попытка
СвязиПараметровВыбора = ПолеФормыИлиРеквизитМетаданных.СвязиПараметровВыбора;
Исключение
Возврат Новый Структура();
КонецПопытки;
ПараметрыВыбора = ПолеФормыИлиРеквизитМетаданных.ПараметрыВыбора;
Отбор = Новый Структура();
МаркерОтбора = НРег("Отбор.");
Для Каждого СвязьПараметраВыбора Из СвязиПараметровВыбора Цикл
#Если _ Тогда
СвязьПараметраВыбора = Новый СвязьПараметраВыбора;
#КонецЕсли
Если Истина
И ДляОчистки
И СвязьПараметраВыбора.ИзменениеЗначения = РежимИзмененияСвязанногоЗначения.НеИзменять
Тогда
Продолжить;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(СвязьПараметраВыбора.ПутьКДанным);
ИмяРеквизита = Фрагменты[Фрагменты.ВГраница()];
Если Фрагменты.Количество() = 1 Тогда
Если ОбъектВладелец = Неопределено Тогда
ОбъектДляРеквизита = ЭтотОбъект;
Иначе
ОбъектДляРеквизита = ОбъектВладелец;
КонецЕсли;
Иначе
ОбъектДляРеквизита = ЭтотОбъект;
КонецЕсли;
Попытка
ЗначениеДанных = Вычислить("ОбъектДляРеквизита." + ИмяРеквизита);
Исключение
// Например поле таблицы или на сервере текущая строка таблицы
Продолжить;
КонецПопытки;
Если Найти(НРег(СвязьПараметраВыбора.Имя), МаркерОтбора) <> 1 Тогда
// Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор"
Продолжить;
КонецЕсли;
Отбор.Вставить(Сред(СвязьПараметраВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ЗначениеДанных);
КонецЦикла;
Для Каждого ПараметрВыбора Из ПараметрыВыбора Цикл
#Если _ Тогда
ПараметрВыбора = Новый ПараметрВыбора;
#КонецЕсли
Если Найти(НРег(ПараметрВыбора.Имя), МаркерОтбора) <> 1 Тогда
// Там можно писать любой текст и даже сам дизайнер иногда вставляет "_Отбор" вместо "Отбор"
Продолжить;
КонецЕсли;
Отбор.Вставить(Сред(ПараметрВыбора.Имя, СтрДлина(МаркерОтбора) + 1), ПараметрВыбора.Значение);
КонецЦикла;
Возврат Отбор;
КонецФункции
// Проверяет, является ли значение ссылкой на значение перечисления.
//
// Параметры:
// пЗначение Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина значение является ссылкой на объект БД;
// Ложь значение не является ссылкой на объект БД.
//
Функция ЛиСсылкаНаПеречислениеЛкс(пЗначение) Экспорт
Возврат (ПолучитьКорневойТипКонфигурацииЛкс(пЗначение) = "Перечисление");
КонецФункции // ЛиСсылкаНаПеречислениеЛкс()
// Проверяет, является ли ключом записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип ключа записи регистра подтвержден;
// Ложь тип ключа записи регистра не подтвержден.
//
Функция ЛиКлючЗаписиРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "ключ записи:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиКлючЗаписиРегистраЛкс()
// Проверяет, является ли записью регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип записи регистра подтвержден;
// Ложь тип записи регистра не подтвержден.
//
Функция ЛиЗаписьРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "запись:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛксЛиКлючЗаписиБД()
// Проверяет, является ли набором записей регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип набора записей регистра подтвержден;
// Ложь тип набора записей регистра не подтвержден.
//
Функция ЛиНаборЗаписейРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "набор записей:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиНаборЗаписейРегистраЛкс()
// Проверяет, является ли субконтом описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип субконто подтвержден;
// Ложь тип субконто не подтвержден.
//
Функция ЛиСубконтоЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "субконто:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиСубконтоЛкс()
// Проверяет, является ли менеджером записи регистра описание типов, тип или значение.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Тип, ОписаниеТипов, Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина тип менеджер записи регистра подтвержден;
// Ложь тип менеджер записи регистра не подтвержден.
//
Функция ЛиМенеджерЗаписиРегистраЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "менеджер записи:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиМенеджерЗаписиРегистраЛкс()
// Проверяет, является ли значение табличной частью внешней обработки.
//
// Параметры:
// пЗначение Произвольный проверяемое значение.
//
// Возвращаемое значение:
// Истина значение является табличной частью внешней обработки;
// Ложь значение не является табличной частью внешней обработки.
//
Функция ЛиТабличнаяЧастьВнешнейОбработкиЛкс(пЗначение) Экспорт
СтрокаТипЗначения = ПолучитьПервыйФрагментЛкс(Строка(пЗначение));
Возврат (СтрокаТипЗначения = "ВнешняяОбработкаТабличнаяЧасть");
КонецФункции // ЛксЛиВнешняяОбработка()
// Получает ссылочный тип по метаданным.
//
// Параметры:
// пМетаданные ОбъектМетаданных.
//
// Возвращаемое значение:
// Тип - ссылочный;
// Неопределено тип нельзя получить.
//
Функция ПолучитьСсылочныйТипПоМетаданнымЛкс(пМетаданные) Экспорт
Результат = Неопределено;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(пМетаданные, Истина);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Результат = Тип(КорневойТип + "Ссылка." + пМетаданные.Имя);
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСсылочныйТипПоМетаданнымЛкс()
// Получает метаданные по полному имени, описанию типов, типу, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем метаданные.
//
// Возвращаемое значение:
// Метаданные - полученные;
// Неопределено - не удалось получить метаданные.
//
Функция ПолучитьМетаданныеЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("Строка") Тогда
Если ПустаяСтрока(пОбъект) Тогда
Результат = Неопределено;
Иначе
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(пОбъект);
Если Фрагменты.Количество() = 3 Тогда
// ВидыСубконто, Изменения
ПолноеИмяМД = Фрагменты[0] + "." + Фрагменты[1];
Иначе
ПолноеИмяМД = пОбъект;
КонецЕсли;
Результат = Метаданные.НайтиПоПолномуИмени(ПолноеИмяМД);
КонецЕсли;
Возврат Результат;
КонецЕсли;
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Результат = Метаданные.НайтиПоТипу(ТипОбъекта);
Возврат Результат;
КонецФункции // ПолучитьМетаданныеЛкс()
// Получает метаданные списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
//
// Параметры:
// пОбъект Произвольное проверяемое значение.
//
// Возвращаемое значение:
// Метаданные - списка;
// Неопределено значение не является списком.
//
Функция ПолучитьМетаданныеСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
МаркерСписка = "список:";
Если Найти(Строка(ТипОбъекта), МаркерСписка) > 0 Тогда
Возврат ПолучитьМетаданныеЛкс(ТипОбъекта);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции // ПолучитьМетаданныеСпискаЛкс()
// Определяет корневой тип конфигурации по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем метаданные;
// *пЛиТолькоДляКорневого - Булево, *Ложь - возвращать только для объекта корневого типа.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено - не удалось получить имя типа.
//
Функция ПолучитьКорневойТипКонфигурацииЛкс(пОбъект, пЛиТолькоДляКорневого = Ложь) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Результат = Неопределено;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
Если пЛиТолькоДляКорневого Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если МассивФрагментов.Количество() = 2 Тогда
Результат = МассивФрагментов[0];
КонецЕсли;
Иначе
Результат = ПолучитьПервыйФрагментЛкс(ПолноеИмя);
КонецЕсли;
КонецЕсли;
Если Результат = "ТабличнаяЧасть" Тогда
// Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьКорневойТипКонфигурацииЛкс()
// Определяет имя корневого типа строки табличной части по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "табличная часть строка:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс()
// Определяет имя корневого типа табличной части по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего определяем корневой тип.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является строкой табличной части.
//
Функция ПолучитьКорневойТипТабличнойЧастиЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеТипа = пОбъект;
Иначе
МетаданныеТипа = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеТипа <> Неопределено Тогда
ПолноеИмя = МетаданныеТипа.ПолноеИмя();
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Истина
И МассивФрагментов.Количество() >= 4
И МассивФрагментов[2] = "ТабличнаяЧасть"
Тогда
Возврат МассивФрагментов[2];
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипТабличнойЧастиЛкс()
// Определяет имя корневого типа списка по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является списком.
//
Функция ПолучитьКорневойТипСпискаЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "список:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСпискаЛкс()
// Определяет имя корневого типа ссылки по описанию типов, типу или значению.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем корневой тип строки табличной части.
//
// Возвращаемое значение:
// - Строка имя типа корневого объекта метаданных;
// Неопределено значение не является ссылкой.
//
Функция ПолучитьКорневойТипСсылкиЛкс(пОбъект) Экспорт
ТипОбъекта = ПолучитьТипОбъектаЛкс(пОбъект);
Маркер = "ссылка:";
Если Найти(Строка(ТипОбъекта), Маркер) > 0 Тогда
Возврат ПолучитьПервыйФрагментЛкс(Метаданные.НайтиПоТипу(ТипОбъекта).ПолноеИмя());
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьКорневойТипСпискаЛкс()
// Определяет имя табличной части по ее метаданным.
//
// Параметры:
// пМетаданные ОбъектМетаданных который проверяем.
//
// Возвращаемое значение:
// - Строка имя табличной части;
// Неопределено это метаданные не табличной части.
//
Функция ПолучитьИмяТабличнойЧастиЛкс(пМетаданные) Экспорт
Если пМетаданные <> Неопределено Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пМетаданные.ПолноеИмя());
Если МассивФрагментов.ВГраница() >= 2 Тогда
Если МассивФрагментов[2] = "ТабличнаяЧасть" Тогда
Возврат МассивФрагментов[3];
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции // ПолучитьИмяТабличнойЧастиЛкс()
// Получает менеджер по описанию типов, типу, метаданным, ссылке или объекту.
// Для описания типов берется первый тип массива типов.
//
// Параметры:
// пОбъект Произвольный для чего получаем менеджер.
//
// Возвращаемое значение:
// МенеджерОбъекта - для ссылки или ссылочного типа;
// Неопределено - не удалось получить.
//
Функция ПолучитьМенеджерЛкс(пОбъект) Экспорт
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
МетаданныеОбъекта = пОбъект;
Иначе
МетаданныеОбъекта = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
Если МетаданныеОбъекта = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(МетаданныеОбъекта.ПолноеИмя());
КорневойТип = МассивФрагментов[0];
Менеджер = Неопределено;
Если Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
ИмяТипаМенеджера = МассивФрагментов[0] + "ТаблицаМенеджер." + МассивФрагментов[1] + "." + МассивФрагментов[3];
Иначе
//КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаданныеОбъекта, Истина); // Изменил 02.03.2012
Если КорневойТип <> Неопределено Тогда
ИмяТипаМенеджера = КорневойТип + "Менеджер." + МетаданныеОбъекта.Имя;
Иначе
ИмяТипаМенеджера = "Неопределено";
КонецЕсли;
КонецЕсли;
Попытка
Менеджер = Новый (ИмяТипаМенеджера);
Исключение
КонецПопытки;
Возврат Менеджер;
КонецФункции // ПолучитьМенеджерЛкс()
// Получает запись регистра по ключу записи.
//
// Параметры:
// пКлючЗаписи КлючЗаписиРегистра идентифицирующий запись.
//
// Возвращаемое значение:
// ЗаписьРегистра найденная запись.
//
Функция ПолучитьЗаписьРегистраПоКлючуЛкс(пКлючЗаписи) Экспорт
МенеджерЗначения = ПолучитьМенеджерЛкс(пКлючЗаписи);
МенеджерЗаписи = МенеджерЗначения.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, пКлючЗаписи);
МенеджерЗаписи.Прочитать();
Возврат МенеджерЗаписи;
КонецФункции // ПолучитьЗаписьРегистраПоКлючуЛкс()
// Больше не используется. Кандидат на удаление.
// Получает список реквизитов объекта БД.
//
// Параметры:
// пОбъект определитель объекта метаданных;
// *ЛиВключатьТолькоЧитаемые - Булево, *Ложь - включать ли в список только читаемые реквизиты;
// *ЛиВключатьНедоступные - Булево, *Ложь - включать ли в список недоступные (группы/элементы) реквизиты;
// *ЛиСортировать - Булево, *Ложь - отсортировать ли по представлению;
// *ЛиСКартинками - Булево, *Ложь - добавлять ли картинки;
// *ЛиСТабличнымиЧастями - Булево, *Ложь - включать ли в список табличные части.
//
// Возвращаемое значение:
// СписокЗначений содержащий в качестве значений имена реквизитов.
//
Функция ПолучитьСписокРеквизитовОбъектаБДЛкс(пОбъект, ЛиВключатьТолькоЧитаемые = Ложь,
ЛиВключатьНедоступные = Ложь, ЛиСортировать = Ложь, ЛиСКартинками = Ложь, ЛиСТабличнымиЧастями = Ложь) Экспорт
СписокРеквизитов = Новый СписокЗначений;
Если пОбъект = Неопределено Тогда
Возврат СписокРеквизитов;
КонецЕсли;
Если ТипЗнч(пОбъект) = Тип("ОбъектМетаданных") Тогда
ОбъектМетаданных = пОбъект;
Иначе
ОбъектМетаданных = ПолучитьМетаданныеЛкс(пОбъект);
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМетаданных);
ИерархияГрупп = Ложь;
КартинкаРеквизита = Неопределено;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.СлужебныйРеквизит;
КонецЕсли;
#КонецЕсли
Если КорневойТип = "Задача" Тогда
СписокРеквизитов.Добавить("БизнесПроцесс", "Бизнес процесс", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
СписокРеквизитов.Добавить("ТочкаМаршрута", "Точка маршрута", , КартинкаРеквизита);
СписокРеквизитов.Добавить("Выполнена", "Выполнена", , КартинкаРеквизита);
Для Каждого Рекв из ОбъектМетаданных.РеквизитыАдресации Цикл
СписокРеквизитов.Добавить(Рекв.Имя, Рекв.Представление(), , КартинкаРеквизита);
КонецЦикла;
КонецЕсли;
Если КорневойТип = "Документ" Тогда
СписокРеквизитов.Добавить("Дата", "Дата", , КартинкаРеквизита);
Если ОбъектМетаданных.ДлинаНомера > 0 Тогда
СписокРеквизитов.Добавить("Номер", "Номер", , КартинкаРеквизита);
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Проведен", "Проведен", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если КорневойТип = "Справочник" Тогда
Если ОбъектМетаданных.Владельцы.Количество() > 0 Тогда
СписокРеквизитов.Добавить("Владелец", "Владелец", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
ЭтоГруппа = Ложь;
Если ЛиКорневойТипОбъектаСКодомЛкс(КорневойТип) Тогда
Если ОбъектМетаданных.ДлинаКода > 0 Тогда
СписокРеквизитов.Добавить("Код", "Код", , КартинкаРеквизита);
КонецЕсли;
Если ОбъектМетаданных.ДлинаНаименования > 0 Тогда
СписокРеквизитов.Добавить("Наименование", "Наименование", , КартинкаРеквизита);
КонецЕсли;
Если ЛиМетаданныеИерархическогоОбъектаЛкс(ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить("Родитель", "Родитель", , КартинкаРеквизита);
Если ЛиМетаданныеОбъектаСГруппамиЛкс(ОбъектМетаданных) Тогда
ИерархияГрупп = Истина;
Если Не ЛиВключатьНедоступные Тогда
ЭтоГруппа = пОбъект.ЭтоГруппа;
КонецЕсли;
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("ЭтоГруппа", "Это группа", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипОбъектаСПредопределеннымЛкс(КорневойТип) Тогда
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Предопределенный", "Предопределенный", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
СписокРеквизитов.Добавить("ПометкаУдаления", "Пометка удаления", , КартинкаРеквизита);
Если ЛиВключатьТолькоЧитаемые Тогда
СписокРеквизитов.Добавить("Ссылка", "Ссылка", , КартинкаРеквизита);
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.Реквизит;
КонецЕсли;
#КонецЕсли
Для Каждого МетаРеквизит Из ОбъектМетаданных.Реквизиты Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаРеквизит.Имя, МетаРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда
Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
Если ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
СписокРеквизитов.Добавить(ОбщийРеквизит.Имя, ОбщийРеквизит.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСТабличнымиЧастями Тогда
#Если Клиент Тогда
Если ЛиСКартинками Тогда
КартинкаРеквизита = БиблиотекаКартинок.ТабличнаяЧасть;
КонецЕсли;
#КонецЕсли
Для Каждого МетаТабличнаяЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
Если Ложь
Или ЛиВключатьНедоступные
Или Не ИерархияГрупп
Или МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппыИЭлемента
Или (Истина
И ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Или (Истина
И Не ЭтоГруппа
И МетаРеквизит.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Тогда
СписокРеквизитов.Добавить(МетаТабличнаяЧасть.Имя, МетаТабличнаяЧасть.Представление(), , КартинкаРеквизита);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЛиСортировать Тогда
СписокРеквизитов.СортироватьПоПредставлению();
КонецЕсли;
Возврат СписокРеквизитов;
КонецФункции // ПолучитьСписокРеквизитовОбъектаБДЛкс()
// Получает строку для установки порядка. Пример "Контрагент убыв, Номенклатура.Код возр".
//
// Параметры:
// Порядок Порядок.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаЛкс(Порядок) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из Порядок Цикл
Строка = Строка + ", " + ЭлементПорядка.ПутьКДанным + " ";
Если ЭлементПорядка.Направление = НаправлениеСортировки.Возр Тогда
Строка = Строка + "возр";
Иначе
Строка = Строка + "убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 2);
КонецФункции // ПолучитьСтрокуПорядкаЛкс()
// Выполняет текст на внутреннем языке. Применяется для безопасного выполнения произвольного кода.
// Безопасность заключается в том, что нет свойств локального контекста
// и недоступны доопределенные Свойства глобального контекста.
//
// Параметры:
// ТекстДляВыполнения Строка;
// *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля.
//
Процедура ВыполнитьВКонтекстеОбщегоМодуляЛкс(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт
Выполнить(ТекстДляВыполнения);
КонецПроцедуры // ВыполнитьВКонтекстеОбщегоМодуляЛкс()
// Получает копию произвольного объекта. Копирование производится через сериализацию.
//
// Параметры:
// пОбъект Произвольное сохраняемое значение;
//
// Возвращаемое значение:
// Произвольный - копия объекта.
//
Функция ПолучитьКопиюОбъектаЛкс(пОбъект, ИспользоватьXDTO = Ложь) Экспорт
Если ИспользоватьXDTO Тогда
НовыйОбъект = СериализаторXDTO.ПрочитатьXDTO(СериализаторXDTO.ЗаписатьXDTO(пОбъект));
Иначе
НовыйОбъект = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(пОбъект));
КонецЕсли;
Возврат НовыйОбъект;
КонецФункции // ПолучитьКопиюОбъектаЛкс()
// Находит элемент коллекции по свойству "ПутьКДанным".
//
// Параметры:
// пКоллекция Коллекция все элементы которой имеют свойство "ПутьКДанным";
// пПутьКДанным Строка искомое значение.
//
// Возвращаемое значение:
// ЭлементКоллекции;
// Неопределено - не найден.
//
Функция НайтиЭлементКоллекцииПоПутиКДаннымЛкс(пКоллекция, пПутьКДанным) Экспорт
СуществующаяСтрока = Неопределено;
Для Каждого ЭлементКоллеции Из пКоллекция Цикл
Если ЭлементКоллеции.ПутьКДанным = пПутьКДанным Тогда
СуществующаяСтрока = ЭлементКоллеции;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат СуществующаяСтрока;
КонецФункции // НайтиЭлементКоллекцииПоПутиКДаннымЛкс()
// Находит поле настройки по пути к данным.
//
// Параметры:
// пПоляНастройки ПоляНастройки;
// пПутьКДанным Строка путь к данным поля в виде разыменовывания;
// *пПутьКТекущемуПолю - Строка, "" - путь к текущему полю.
//
// Возвращаемое значение:
// ПолеНастройки найденное поле;
// Неопределено - иначе.
//
Функция НайтиПолеНастройкиПоПутиКДаннымЛкс(пПоляНастройки, пПутьКДанным, пПутьКТекущемуПолю = "") Экспорт
ПоляНастройки = пПоляНастройки;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(пПутьКДанным);
ТекущееПоле = Неопределено;
Для Каждого Фрагмент Из МассивФрагментов Цикл
пПутьКТекущемуПолю = пПутьКТекущемуПолю + ?(пПутьКТекущемуПолю = "", "", ".") + Фрагмент;
ТекущееПоле = НайтиЭлементКоллекцииПоПутиКДаннымЛкс(ПоляНастройки, пПутьКТекущемуПолю);
Если ТекущееПоле = Неопределено Тогда
Прервать;
КонецЕсли;
ПоляНастройки = ТекущееПоле.Поля;
КонецЦикла;
Возврат ТекущееПоле;
КонецФункции // НайтиПолеНастройкиПоПутиКДаннымЛкс()
// Копирует один элемент отбора в другой. Если Использование = Ложь, то копируется только оно.
//
// Параметры:
// пЭлементОтбораПриемник ЭлементОтбора куда копируем;
// пЭлементОтбораИсточник - ЭлементОтбора - откуда копируем.
//
Процедура СкопироватьЭлементОтбораЛкс(пЭлементОтбораПриемник, пЭлементОтбораИсточник) Экспорт
ЗаполнитьЗначенияСвойств(пЭлементОтбораПриемник, пЭлементОтбораИсточник, "Представление, Использование");
МассивСвойствЭлементаОтбора = Новый Массив;
МассивСвойствЭлементаОтбора.Добавить("ВидСравнения");
МассивСвойствЭлементаОтбора.Добавить("Значение");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеС");
МассивСвойствЭлементаОтбора.Добавить("ЗначениеПо");
Для Каждого Свойство Из МассивСвойствЭлементаОтбора Цикл
Значение = пЭлементОтбораИсточник[Свойство];
Если пЭлементОтбораПриемник[Свойство] <> Значение Тогда
пЭлементОтбораПриемник[Свойство] = Значение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // СкопироватьЭлементОтбораЛкс()
// Порт СкопироватьОтборЛкс.
Процедура СкопироватьОтборДинамическогоСпискаЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь,
ТолькоИспользуемые = Ложь) Экспорт
СкопироватьОтборЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие, ТолькоИспользуемые);
КонецПроцедуры // СкопироватьОтборДинамическогоСпискаЛкс()
// Порт СкопироватьОтборЛкс.
Процедура СкопироватьОтборСтатическийЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь,
ТолькоИспользуемые = Ложь) Экспорт
СкопироватьОтборЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие, ТолькоИспользуемые);
КонецПроцедуры // СкопироватьОтборСтатическийЛкс()
// Копирует отбор.
// Если нужно, в приемнике создаются отсутствующие элементы отбора.
//
// Параметры:
// пОтборПриемник Отбор куда копируем;
// пОтборИсточник - Отбор, Структура - откуда копируем;
// пСоздаватьОтсутствующие - Булево, *Ложь - признак создания отсутствующих элементов отбора в источнике.
//
Процедура СкопироватьОтборЛкс(пОтборПриемник, пОтборИсточник, пСоздаватьОтсутствующие = Ложь,
ТолькоИспользуемые = Ложь) Экспорт
//Если пСоздаватьОтсутствующие Тогда
// ДоступныеПоля = пОтборПриемник.ПолучитьДоступныеПоля();
//КонецЕсли;
Для Каждого ЭлементОтбораИсточника Из пОтборИсточник Цикл
Если Истина
И ТолькоИспользуемые
И Не ЭлементОтбораИсточника.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбораИсточника) = Тип("КлючИЗначение") Тогда
ЭлементОтбораИсточника = ЭлементОтбораИсточника.Значение;
КонецЕсли;
//Если ЭлементОтбораИсточника.Имя = "" Тогда
// Сообщить("Невозможно определить элемент отбора приемника при копировании отбора.",
// СтатусСообщения.Внимание);
// Продолжить;
//КонецЕсли;
ЭлементОтбораПриемника = пОтборПриемник.Найти(ЭлементОтбораИсточника.Имя);
Если ЭлементОтбораПриемника = Неопределено Тогда
Если Истина
И пСоздаватьОтсутствующие
//И НайтиПолеНастройкиПоПутиКДаннымЛкс(ДоступныеПоля, ЭлементОтбораИсточника.ПутьКДанным) <> Неопределено
Тогда
Попытка
ЭлементОтбораПриемника = пОтборПриемник.Добавить(ЭлементОтбораИсточника.ПутьКДанным, ЭлементОтбораИсточника.Имя);
Исключение
Продолжить;
КонецПопытки;
Иначе
Продолжить;
КонецЕсли;
КонецЕсли;
СкопироватьЭлементОтбораЛкс(ЭлементОтбораПриемника, ЭлементОтбораИсточника);
КонецЦикла;
КонецПроцедуры // СкопироватьОтборЛкс()
// Получает инвертированный вид сравнения.
//
// Параметры:
// ВидСравнения ВидСравнения.
//
// Возвращаемое значение:
// ВидСравнения;
//
Функция ПолучитьИнвертированныйВидСравненияЛкс(пВидСравнения) Экспорт
МассивИнвертируемыхТиповСравнения = Новый Массив;
МассивИнвертируемыхТиповСравнения.Добавить("ВИерархии");
МассивИнвертируемыхТиповСравнения.Добавить("ВСписке");
МассивИнвертируемыхТиповСравнения.Добавить("Равно");
МассивИнвертируемыхТиповСравнения.Добавить("Содержит");
МассивИнвертируемыхТиповСравнения.Добавить("ВСпискеПоИерархии");
Для Каждого ТипСравнения Из МассивИнвертируемыхТиповСравнения Цикл
ПрямойТипСравнения = Вычислить("ВидСравнения." + ТипСравнения);
Если ПрямойТипСравнения = пВидСравнения Тогда
Возврат Вычислить("ВидСравнения.Не" + ТипСравнения);
КонецЕсли;
ОбратныйТипСравнения = Вычислить("ВидСравнения.Не" + ТипСравнения);
Если ОбратныйТипСравнения = пВидСравнения Тогда
Возврат Вычислить("ВидСравнения." + ТипСравнения);
КонецЕсли;
КонецЦикла;
Возврат пВидСравнения;
КонецФункции // ПолучитьИнвертированныйВидСравненияЛкс()
// Копирует один порядок в другой. Приемник перед копированием очищается.
//
// Параметры:
// пПорядокПриемник Порядок куда копируем;
// пПорядокИсточник - Порядок - откуда копируем.
//
Процедура СкопироватьПорядокЛкс(пПорядокПриемник, пПорядокИсточник) Экспорт
пПорядокПриемник.Очистить();
Для Каждого ЭлементПорядка Из пПорядокИсточник Цикл
пПорядокПриемник.Добавить(ЭлементПорядка.ПутьКДанным, ЭлементПорядка.Имя, , ЭлементПорядка.Направление);
КонецЦикла;
КонецПроцедуры // СкопироватьПорядокЛкс()
// Возвращает текущее время в миллисекундах.
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Число.
//
Функция ПолучитьТекущееВремяВМиллисекундахЛкс() Экспорт
Попытка
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; ЧН=") + " мс";
КонецЕсли;
Сообщить(ТекстСообщения);
КонецПроцедуры // ОбработатьИндикаторЛкс()
// Получает более подробное представление значения, чем штатное приведение к строковому типу.
//
// Параметры:
// Значение Произвольный что нужно представить.
//
// Возвращаемое значение:
// Строка представление.
//
Функция ПолучитьРасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля = Неопределено, ДобавлятьПредставлениеТипа = Ложь) Экспорт
Результат = "";
Разделитель = ", ";
КоличествоЭлементов = ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение);
Если КоличествоЭлементов <> Неопределено Тогда
Результат = "(" + КоличествоЭлементов + ")";
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Граница") Тогда
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + Значение.ВидГраницы + ", " + Значение.Значение;
ИначеЕсли ТипЗнч(Значение) = Тип("ОписаниеТипов") Тогда
#Если _ Тогда
Значение = Новый ОписаниеТипов;
#КонецЕсли
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Коллекция = Значение.Типы();
Для Каждого Тип Из Коллекция Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + Тип;
Если Тип = Тип("Число") Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + "(" + Значение.КвалификаторыЧисла.Разрядность + "," + Значение.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")";
ИначеЕсли Тип = Тип("Строка") Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + "(" + XMLСтрока(Значение.КвалификаторыСтроки.Длина) + ")";
ИначеЕсли Тип = Тип("Дата") Тогда
Если Значение.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Время Тогда
ПредставлениеКвалификатора = "В";
ИначеЕсли Значение.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда
ПредставлениеКвалификатора = "ДВ";
ИначеЕсли Значение.КвалификаторыДаты.ЧастиДаты = ЧастиДаты.Дата Тогда
ПредставлениеКвалификатора = "Д";
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + "(" + ПредставлениеКвалификатора + ")";
КонецЕсли;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если Коллекция.Количество() > 1 Тогда
Результат = "(" + XMLСтрока(Коллекция.Количество()) + ")";
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Массив")
Или ТипЗнч(Значение) = Тип("ФиксированныйМассив")
Или ТипЗнч(Значение) = Тип("СписокЗначений")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Для Каждого ЭлементМассива Из Значение Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + ЭлементМассива;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли Ложь
Или ТипЗнч(Значение) = Тип("Структура")
Или ТипЗнч(Значение) = Тип("Соответствие")
Тогда
ПредставлениеКоллекции = "";
МаксимальноеЧислоДляПредставления = 20;
Для Каждого КлючИЗначение Из Значение Цикл
Если ПредставлениеКоллекции <> "" Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель;
КонецЕсли;
ПредставлениеКоллекции = ПредставлениеКоллекции + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение;
МаксимальноеЧислоДляПредставления = МаксимальноеЧислоДляПредставления - 1;
Если МаксимальноеЧислоДляПредставления = 0 Тогда
ПредставлениеКоллекции = ПредставлениеКоллекции + Разделитель + "...";
Прервать;
КонецЕсли;
КонецЦикла;
Если ДобавлятьПредставлениеТипа Тогда
Результат = Результат + ТипЗнч(Значение);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Результат = Результат + ": ";
КонецЕсли;
Результат = Результат + ПредставлениеКоллекции;
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
ирПлатформа = ирКэш.Получить();
ИмяОбщегоТипа = ирПлатформа.ПолучитьПолноеИмяТипаCOMОбъекта(Значение);
ПолноеИмяОсновногоКласса = ПолучитьСтрокуМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь);
ИмяОбщегоТипа = СтрЗаменить(ИмяОбщегоТипа, ".{" + ПолноеИмяОсновногоКласса + "}", "");
Результат = Результат + ИмяОбщегоТипа;
//ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
// Результат = Результат + """" + Значение + """";
Иначе
СтрокаФормата = "";
Если КолонкаТабличногоПоля <> Неопределено Тогда
СтрокаФормата = КолонкаТабличногоПоля.Формат;
// Отключено из-за потери дробной части при 0,0. Зачем это было сделано изначально, пока не разобрался
//Если Истина
// И ПустаяСтрока(СтрокаФормата)
// И ТипЗнч(КолонкаТабличногоПоля.ЭлементУправления) = Тип("ПолеВвода")
//Тогда
// КвалификаторыЧисла = КолонкаТабличногоПоля.ЭлементУправления.ТипЗначения.КвалификаторыЧисла;
// СтрокаФормата = "ЧЦ = " + КвалификаторыЧисла.Разрядность + "; ЧДЦ = " + КвалификаторыЧисла.РазрядностьДробнойЧасти;
//КонецЕсли;
КонецЕсли;
Результат = Результат + Формат(Значение, СтрокаФормата);
КонецЕсли;
Возврат Результат;
КонецФункции // ЛксПолучитьПредставлениеЗначение()
// Сравнивает значения свойств объекта <Первый> со значениями свойств объекта <Второй>. Сопоставление производится по именам свойств.
// Отсутствие свойства приравнивается к значению Неопределено.
//
// Параметры:
// Первый Произвольный первый объект для сравнения;
// Второй Произвольный первый объект для сравнения;
// СвойстваДляСравнения - Строка - перечисленные через запятую свойства для сравнения.
//
// Возвращаемое значение:
// Булево Равны ли значения всех указанных свойств.
//
Функция СравнитьЗначенияСвойствЛкс(Первый, Второй, СвойстваДляСравнения) Экспорт
Структура1 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура1, Первый);
Структура2 = Новый Структура(СвойстваДляСравнения);
ЗаполнитьЗначенияСвойств(Структура2, Второй);
Результат = ЗначениеВСтрокуВнутр(Структура1) = ЗначениеВСтрокуВнутр(Структура2);
Возврат Результат;
КонецФункции // СравнитьЗначенияСвойствЛкс()
#Если Клиент Тогда
Процедура ИзменитьОтборКлиентаПоМетаданнымЛкс(ТабличноеПоле, Знач ИмяКолонкиСреднегоИмениМД = "Метаданные", ЭтоКолонкаПолногоИмениМД = Ложь) Экспорт
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегистры", Истина);
лСтруктураПараметров.Вставить("ОтображатьПерерасчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", Истина);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", Истина);
лСтруктураПараметров.Вставить("ОтображатьРегламентныеЗадания", Истина);
лСтруктураПараметров.Вставить("ОтображатьОтчеты", Истина);
лСтруктураПараметров.Вставить("ОтображатьОбработки", Истина);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", Истина);
лСтруктураПараметров.Вставить("МножественныйВыбор", Истина);
лДоступныеОбъекты = ТабличноеПоле.Значение.Выгрузить();
лДоступныеОбъекты.Свернуть(ИмяКолонкиСреднегоИмениМД);
лДоступныеОбъекты = лДоступныеОбъекты.ВыгрузитьКолонку(ИмяКолонкиСреднегоИмениМД);
Если ЭтоКолонкаПолногоИмениМД Тогда
ДоступныеОбъекты = Новый Массив;
Для Каждого ПолноеИмяМД Из лДоступныеОбъекты Цикл
СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
ДоступныеОбъекты.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
//лСтруктураПараметров.Вставить("ОтображатьВиртуальныеТаблицы", Истина);
//лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", Истина);
ДоступныеОбъекты = лДоступныеОбъекты;
КонецЕсли;
ЭлементОтбора = ТабличноеПоле.ОтборСтрок[ИмяКолонкиСреднегоИмениМД];
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке
Тогда
лНачальноеЗначениеВыбора = ЭлементОтбора.Значение.ВыгрузитьЗначения();
Если ЭтоКолонкаПолногоИмениМД Тогда
НачальноеЗначениеВыбора = Новый Массив;
Для Каждого ПолноеИмяМД Из лНачальноеЗначениеВыбора Цикл
СреднееИмяМД = ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
НачальноеЗначениеВыбора.Добавить(СреднееИмяМД);
КонецЦикла;
Иначе
НачальноеЗначениеВыбора = лНачальноеЗначениеВыбора;
КонецЕсли;
Иначе
НачальноеЗначениеВыбора = ДоступныеОбъекты;
КонецЕсли;
мПлатформа = ирКэш.Получить();
Форма = мПлатформа.ПолучитьФорму("ВыборОбъектаМетаданных");
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ЗначениеВыбора <> Неопределено Тогда
Если ЭтоКолонкаПолногоИмениМД Тогда
ТаблицаВсехТаблицБД = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс();
МассивИменМД = Новый Массив;
Для Каждого СреднееИмяМД Из ЗначениеВыбора Цикл
СтрокаОписанияТаблицы = ТаблицаВсехТаблицБД.Найти(СреднееИмяМД, "ПолноеИмя");
Если СтрокаОписанияТаблицы <> Неопределено Тогда
МассивИменМД.Добавить(СтрокаОписанияТаблицы.ПолноеИмяМД);
Иначе
МассивИменМД.Добавить(СреднееИмяМД);
КонецЕсли;
КонецЦикла;
Иначе
МассивИменМД = ЗначениеВыбора;
КонецЕсли;
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(МассивИменМД);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокЗначений;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьДиалогЗаменыИдентификаторовОбъектовЛкс(Знач Объекты) Экспорт
ФормаОбработки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Дерево = Новый ДеревоЗначений;
Дерево.Колонки.Добавить("Объект");
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(Объекты.Количество(), "Создание дублей объектов");
НачатьТранзакцию();
Попытка
Для Каждого Объект Из Объекты Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КопияОбъекта = Объект.Ссылка.ПолучитьОбъект();
ирОбщий.ЗаменитьИдентификаторОбъектаЛкс(КопияОбъекта);
Попытка
КопияОбъекта.ОбменДанными.Загрузка = Истина;
Исключение
Сообщить("Для узлов планов обмена групповая замена внутренних идентификаторов не поддерживается");
Возврат;
КонецПопытки;
КопияОбъекта.Записать();
СтрокаГруппы = Дерево.Строки.Добавить();
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = КопияОбъекта.Ссылка;
СтрокаЭлемента = СтрокаГруппы.Строки.Добавить();
СтрокаЭлемента[0] = Объект;
КонецЦикла;
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ЗафиксироватьТранзакцию();
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
ФормаОбработки.ОткрытьДляЗаменыПоДеревуСсылок(Дерево,, Ложь);
ФормаОбработки.ОтключатьКонтрольЗаписи = Истина;
ФормаОбработки.РазрешитьУдалениеСНарушениемСсылочнойЦелостности = Ложь;
КонецПроцедуры // ПередОткрытием()
// Оформляет ячейку табличного поля, допускающую значения, не имеющие стандартного отображения в платформе и хранимые отдельно.
// Иными словам колонка отображает данные, хранимые отдельно.
//
// Параметры:
// ОформлениеЯчейки ОформлениеЯчейки
// Значение - Произвольный - значение для отображения.
//
Процедура ОформитьЯчейкуСРасширеннымЗначениемЛкс(ОформлениеЯчейки, Знач Значение = Неопределено, КолонкаТабличногоПоля = Неопределено, ВыводитьПиктограммуТипа = Истина) Экспорт
Если Значение = Неопределено Тогда
Значение = ОформлениеЯчейки.Значение;
КонецЕсли;
Если ВыводитьПиктограммуТипа Тогда
ТипЗначения = ТипЗнч(Значение);
Если Истина
И ТипЗначения = Тип("Булево")
И ОформлениеЯчейки.ОтображатьФлажок
Тогда
//
Иначе
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
ОформлениеЯчейки.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
РасширенноеПредставление = ПолучитьРасширенноеПредставлениеЗначенияЛкс(Значение, КолонкаТабличногоПоля);
Если Ложь
Или ОформлениеЯчейки.Текст = РасширенноеПредставление
Тогда
Возврат;
КонецЕсли;
//ОформлениеЯчейки.ТолькоПросмотр = Истина;
//ОформлениеЯчейки.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаРасширенногоПредставленияЗначения");
ОформлениеЯчейки.УстановитьТекст(РасширенноеПредставление);
КонецПроцедуры // ОформитьЯчейкуСРасширеннымЗначениемЛкс()
// Находит файлы в иерархии заданного каталога локальной файловой системы.
//
// Параметры:
// Путь Строка;
// Маска Строка.
//
// Возвращаемое значение:
// Массив элементы типа Файл.
//
Функция НайтиФайлыВИерархииЛкс(Путь, Маска) Экспорт
НайденныеКаталоги = НайтиФайлы(Путь, "*.*");
МассивРезультатов = Новый Массив;
Для каждого НайденныйФайл Из НайденныеКаталоги Цикл
Если НайденныйФайл.ЭтоКаталог() Тогда
МассивРезультатов.Добавить(НайтиФайлыВИерархииЛкс(НайденныйФайл.ПолноеИмя, Маска));
КонецЕсли;
КонецЦикла;
МассивРезультатов.Добавить(НайтиФайлы(Путь, Маска));
Результат = Новый Массив;
Для Каждого ЭлементРезультат Из МассивРезультатов Цикл
Для Каждого Файл Из ЭлементРезультат Цикл
Результат.Добавить(Файл);
КонецЦикла;
КонецЦикла;
Возврат Результат;
КонецФункции // НайтиФайлыВИерархииЛкс()
// Проверяет, является ли тип типом элемента формы.
//
// Параметры:
// пТип Тип проверяемый тип.
//
// Возвращаемое значение:
// Истина тип элемента формы подтвержден;
// Ложь тип элемента формы не подтвержден.
//
Функция ЛиТипЭлементаФормыЛкс(пТип) Экспорт
Если Ложь
ИЛИ пТип = Тип("Индикатор")
ИЛИ пТип = Тип("Кнопка")
ИЛИ пТип = Тип("КоманднаяПанель")
ИЛИ пТип = Тип("Надпись")
ИЛИ пТип = Тип("Панель")
ИЛИ пТип = Тип("Переключатель")
ИЛИ пТип = Тип("ПолеВвода")
ИЛИ пТип = Тип("ПолеВыбора")
ИЛИ пТип = Тип("ПолеСписка")
ИЛИ пТип = Тип("ПолеТекстовогоДокумента")
ИЛИ пТип = Тип("ПолеТабличногоДокумента")
ИЛИ пТип = Тип("ПолосаРегулирования")
ИЛИ пТип = Тип("ТабличноеПоле")
ИЛИ пТип = Тип("РамкаГруппы")
ИЛИ пТип = Тип("Флажок")
Тогда
Возврат Истина;
КонецЕсли;
Возврат Ложь;
КонецФункции // ЛиТипЭлементаФормыЛкс()
// Получает структуру свойств объекта по имени типа или объекту.
// Свойства должны располагаться в порядке:
// - общие,
// - ролевые в порядке невлияния на предшествующие.
//
// Параметры:
// пОбъект - Произвольный - имя типа или сам объект;
// пЛиДляСохранения - Булево, *Ложь - признак получения свойств для сохранения.
//
// Возвращаемое значение:
// Структура свойств.
//
Функция ПолучитьСтруктуруСвойствОбъектаЛкс(пОбъект, пЛиДляСохранения = Ложь) Экспорт
СтруктураСвойств = Новый Структура;
ТипОбъекта = ТипЗнч(пОбъект);
МетаОбъект = ПолучитьМетаданныеЛкс(ТипОбъекта);
Если МетаОбъект <> Неопределено Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(МетаОбъект, Истина);
Если Ложь
ИЛИ КорневойТип = "Обработка"
ИЛИ КорневойТип = "Отчет"
Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
Для Каждого МетаРеквизит Из МетаОбъект.ТабличныеЧасти Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если ПолучитьКорневойТипСтрокиТабличнойЧастиЛкс(ТипОбъекта) <> Неопределено Тогда
Для Каждого МетаРеквизит Из МетаОбъект.Реквизиты Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
КонецЕсли;
Если Истина
И ТипОбъекта <> Тип("Тип")
И ТипОбъекта <> Тип("ОписаниеТипов")
И ТипОбъекта <> Тип("ОбъектМетаданных")
Тогда
Если ПолучитьКорневойТипСпискаЛкс(ТипОбъекта) <> Неопределено Тогда
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Отбор");
ИначеЕсли ЛиНаборЗаписейРегистраЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Отбор");
КонецЕсли;
КонецЕсли;
//ИначеЕсли Ложь
// ИЛИ ТипОбъекта = Тип("КнопкиКоманднойПанели")
// ИЛИ ТипОбъекта = Тип("КолонкиТабличногоПоля")
// ИЛИ ТипОбъекта = Тип("СтраницыПанели")
// ИЛИ ТипОбъекта = Тип("ЭлементыФормы")
// ИЛИ ТипОбъекта = Тип("ПоляНастройки")
//Тогда
// Для Каждого Элемент Из пОбъект Цикл
// СтруктураСвойств.Вставить(Элемент.Имя);
// КонецЦикла;
//
ИначеЕсли Ложь
Или ТипОбъекта = Тип("СтрокаТаблицыЗначений")
Или ТипОбъекта = Тип("СтрокаДереваЗначений")
Тогда
Для Каждого МетаРеквизит Из пОбъект.Владелец().Колонки Цикл
СтруктураСвойств.Вставить(МетаРеквизит.Имя);
КонецЦикла;
ИначеЕсли ЛиТипЭлементаФормыЛкс(ТипОбъекта) Тогда
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("ПервыйВГруппе");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КонтекстноеМеню");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Лево");
СтруктураСвойств.Вставить("Верх");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Ширина");
КонецЕсли;
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("ПорядокОтображения");
СтруктураСвойств.Вставить("ПрозрачныйФон");
СтруктураСвойств.Вставить("Рамка");
Если ТипОбъекта = Тип("Кнопка") Тогда
СтруктураСвойств.Вставить("РежимМеню");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ПоложениеКартинки");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("Кнопки");
ИначеЕсли ТипОбъекта = Тип("КоманднаяПанель") Тогда
СтруктураСвойств.Вставить("АвтоЗаполнение");
СтруктураСвойств.Вставить("Вспомогательная");
СтруктураСвойств.Вставить("ВыравниваниеКнопок");
СтруктураСвойств.Вставить("ИсточникДействий");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Ориентация");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Надпись") Тогда
СтруктураСвойств.Вставить("БегущаяСтрока");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ПоложениеКартинкиНадписи");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Панель") Тогда
СтруктураСвойств.Вставить("Страницы");
СтруктураСвойств.Вставить("АвтоПорядокОбхода");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("ОтображениеЗакладок");
СтруктураСвойств.Вставить("ПорядокОбхода");
СтруктураСвойств.Вставить("РазмерКартинки");
СтруктураСвойств.Вставить("РаспределятьПоСтраницам");
СтруктураСвойств.Вставить("РежимПрокручиваемыхСтраниц");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ТекущаяСтраница");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Переключатель") Тогда
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("ВыбираемоеЗначение");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("ПолеВвода") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОграничениеТипа");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("РежимВыбораИзСписка");
СтруктураСвойств.Вставить("КнопкаСпискаВыбора");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("АвтоВыборНезаполненного");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("АвтоПереносСтрок");
СтруктураСвойств.Вставить("ВертикальноеПоложение");
СтруктураСвойств.Вставить("БыстрыйВыбор");
СтруктураСвойств.Вставить("ВыбиратьТип");
СтруктураСвойств.Вставить("ВыборГруппИЭлементов");
СтруктураСвойств.Вставить("ВыборНезаполненного");
СтруктураСвойств.Вставить("ВыборПоВладельцу");
СтруктураСвойств.Вставить("ВыделенныйТекст");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("ГоризонтальноеПоложение");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("МаксимальноеЗначение");
СтруктураСвойств.Вставить("Маска");
СтруктураСвойств.Вставить("МинимальноеЗначение");
СтруктураСвойств.Вставить("МногострочныйРежим");
СтруктураСвойств.Вставить("ОтметкаНезаполненного");
СтруктураСвойств.Вставить("РасширенноеРедактирование");
СтруктураСвойств.Вставить("РедактированиеТекста");
СтруктураСвойств.Вставить("РежимВыбораНезаполненного");
СтруктураСвойств.Вставить("РежимПароля");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаКнопки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаКнопки");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Шрифт");
СтруктураСвойств.Вставить("ЭлементСвязиПоТипу");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеВыбора") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ВысотаСпискаВыбора");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КартинкаКнопкиВыбора");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("КнопкаВыбора");
СтруктураСвойств.Вставить("КнопкаОткрытия");
СтруктураСвойств.Вставить("КнопкаОчистки");
СтруктураСвойств.Вставить("КнопкаРегулирования");
СтруктураСвойств.Вставить("СписокВыбора");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ШиринаСпискаВыбора");
СтруктураСвойств.Вставить("Значение");
ИначеЕсли ТипОбъекта = Тип("ПолеСписка") Тогда
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ОтображатьКартинку");
СтруктураСвойств.Вставить("ОтображатьПометку");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ТекущаяСтрока");
ИначеЕсли ТипОбъекта = Тип("ТабличноеПоле") Тогда
// **** Доделать
СтруктураСвойств.Вставить("ТипЗначения");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("АвтоВводНовойСтроки");
СтруктураСвойств.Вставить("АвтоКонтекстноеМеню");
СтруктураСвойств.Вставить("АвтоОбновление");
СтруктураСвойств.Вставить("АктивизироватьПоУмолчанию");
СтруктураСвойств.Вставить("ВосстанавливатьТекущуюСтроку");
СтруктураСвойств.Вставить("Дерево");
СтруктураСвойств.Вставить("ИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьАвтоОбновление");
СтруктураСвойств.Вставить("ИзменятьИерархическийПросмотр");
СтруктураСвойств.Вставить("ИзменятьСпособРедактирования");
СтруктураСвойств.Вставить("ИзменятьТекущегоРодителя");
СтруктураСвойств.Вставить("ПериодАвтоОбновления");
СтруктураСвойств.Вставить("ПроверкаОтображенияНовойСтроки");
СтруктураСвойств.Вставить("РодительВерхнегоУровня");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимВыделения");
СтруктураСвойств.Вставить("РежимВыделенияСтроки");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("СпособРедактирования");
СтруктураСвойств.Вставить("ТекущийРодитель");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("Колонки");
СтруктураСвойств.Вставить("НастройкаОтбора");
СтруктураСвойств.Вставить("НастройкаПорядка");
СтруктураСвойств.Вставить("ТекущаяКолонка");
СтруктураСвойств.Вставить("ТекущаяСтрока");
СтруктураСвойств.Вставить("ТекущиеДанные");
СтруктураСвойств.Вставить("ВыделенныеСтроки");
// ****
//ВертикальнаяПолосаПрокрутки
//ВертикальныеЛинии
//Вывод
//ВысотаПодвала
//ВысотаШапки
//ГоризонтальнаяПолосаПрокрутки
//ГоризонтальныеЛинии
//ИзменятьНастройкуКолонок
//ИзменятьПозициюКолонок
//ИзменятьПорядокСтрок
//ИзменятьСоставСтрок
//НачальноеОтображениеДерева
//НачальноеОтображениеСписка
//Подвал
//ПропускатьПриВводе
//РазрешитьНачалоПеретаскивания
//РазрешитьПеретаскивание
//РежимВводаСтрок
//ФиксацияСлева
//ФиксацияСправа
//ЦветТекста
//ЦветТекстаВыделения
//ЦветТекстаКнопки
//ЦветТекстаПодвала
//ЦветТекстаШапки
//ЦветФона
//ЦветФонаВыделения
//ЦветФонаКнопки
//ЦветФонаПодвала
//ЦветФонаЧередованияСтрок
//ЦветФонаШапки
//ЧередованиеЦветовСтрок
//Шапка
//Ширина
//Шрифт
//ШрифтПодвала
//ШрифтШапки
ИначеЕсли ТипОбъекта = Тип("ПолеТабличногоДокумента") Тогда
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ОтображатьВыделение");
СтруктураСвойств.Вставить("РазрешитьНачалоПеретаскивания");
СтруктураСвойств.Вставить("РазрешитьПеретаскивание");
СтруктураСвойств.Вставить("Свертка");
СтруктураСвойств.Вставить("ЦветРамки");
ИначеЕсли ТипОбъекта = Тип("РамкаГруппы") Тогда
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("Шрифт");
ИначеЕсли ТипОбъекта = Тип("Флажок") Тогда
СтруктураСвойств.Вставить("ТриСостояния");
СтруктураСвойств.Вставить("ВертикальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("ГоризонтальнаяПолосаПрокрутки");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ПоложениеЗаголовка");
СтруктураСвойств.Вставить("ЦветРамки");
СтруктураСвойств.Вставить("ЦветТекста");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветФона");
СтруктураСвойств.Вставить("ЦветФонаПоля");
КонецЕсли;
ИначеЕсли ТипОбъекта = Тип("КнопкаКоманднойПанели") Тогда
СтруктураСвойств.Вставить("ТипКнопки");
СтруктураСвойств.Вставить("Действие");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("ИзменяетДанные");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Картинка");
СтруктураСвойств.Вставить("КнопкаПоУмолчанию");
СтруктураСвойств.Вставить("Кнопки");
СтруктураСвойств.Вставить("Отображение");
СтруктураСвойств.Вставить("Подсказка");
СтруктураСвойств.Вставить("Пометка");
СтруктураСвойств.Вставить("ПорядокКнопок");
СтруктураСвойств.Вставить("Пояснение");
СтруктураСвойств.Вставить("СочетаниеКлавиш");
СтруктураСвойств.Вставить("Текст");
ИначеЕсли ТипОбъекта = Тип("СтраницаПанели") Тогда
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("Раскрыта");
ИначеЕсли ТипОбъекта = Тип("КолонкаТабличногоПоля") Тогда
СтруктураСвойств.Вставить("АвтоВысотаЯчейки");
СтруктураСвойств.Вставить("АвтоОтметкаНезаполненного");
СтруктураСвойств.Вставить("Видимость");
СтруктураСвойств.Вставить("ВыделятьОтрицательные");
СтруктураСвойств.Вставить("ВысотаЯчейки");
СтруктураСвойств.Вставить("ГиперСсылка");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВКолонке");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВПодвале");
СтруктураСвойств.Вставить("ГоризонтальноеПоложениеВШапке");
СтруктураСвойств.Вставить("Данные");
СтруктураСвойств.Вставить("ДанныеФлажка");
СтруктураСвойств.Вставить("ДополнительнаяКартинкаШапки");
СтруктураСвойств.Вставить("Доступность");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("КартинкаПодвала");
СтруктураСвойств.Вставить("КартинкаШапки");
СтруктураСвойств.Вставить("КартинкиСтрок");
СтруктураСвойств.Вставить("ОтображатьВПодвале");
СтруктураСвойств.Вставить("ОтображатьВШапке");
СтруктураСвойств.Вставить("ОтображатьИерархию");
СтруктураСвойств.Вставить("ПодсказкаВШапке");
СтруктураСвойств.Вставить("Положение");
СтруктураСвойств.Вставить("ПропускатьПриВводе");
СтруктураСвойств.Вставить("РежимРедактирования");
СтруктураСвойств.Вставить("ТекстПодвала");
СтруктураСвойств.Вставить("ТекстШапки");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("ТриСостоянияФлажка");
СтруктураСвойств.Вставить("Формат");
СтруктураСвойств.Вставить("ЦветТекстаПодвала");
СтруктураСвойств.Вставить("ЦветТекстаПоля");
СтруктураСвойств.Вставить("ЦветТекстаШапки");
СтруктураСвойств.Вставить("ЦветФонаПодвала");
СтруктураСвойств.Вставить("ЦветФонаПоля");
СтруктураСвойств.Вставить("ЦветФонаШапки");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ШрифтПодвала");
СтруктураСвойств.Вставить("ШрифтТекста");
СтруктураСвойств.Вставить("ШрифтШапки");
СтруктураСвойств.Вставить("ЭлементУправления");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьВидимость");
СтруктураСвойств.Вставить("ИзменятьНастройку");
СтруктураСвойств.Вставить("ИзменятьПозицию");
ИначеЕсли ТипОбъекта = Тип("Форма") Тогда
СтруктураСвойств.Вставить("АвтоЗаголовок");
СтруктураСвойств.Вставить("Высота");
СтруктураСвойств.Вставить("Заголовок");
СтруктураСвойств.Вставить("ЗакрыватьПриВыборе");
СтруктураСвойств.Вставить("ЗакрыватьПриЗакрытииВладельца");
СтруктураСвойств.Вставить("ИзменениеРазмера");
СтруктураСвойств.Вставить("ИзменятьСпособОтображенияОкна");
СтруктураСвойств.Вставить("ИмяСохраненияПоложенияОкна");
СтруктураСвойств.Вставить("КартинкаЗаголовка");
СтруктураСвойств.Вставить("КлючУникальности");
СтруктураСвойств.Вставить("МножественныйВыбор");
СтруктураСвойств.Вставить("Модифицированность");
СтруктураСвойств.Вставить("НачальноеЗначениеВыбора");
СтруктураСвойств.Вставить("Панель");
СтруктураСвойств.Вставить("ПоведениеКлавишиEnter");
СтруктураСвойств.Вставить("ПоложениеОкна");
СтруктураСвойств.Вставить("ПоложениеПрикрепленногоОкна");
СтруктураСвойств.Вставить("РазрешитьСоединятьОкно");
СтруктураСвойств.Вставить("РазрешитьСостояниеОбычное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрикрепленное");
СтруктураСвойств.Вставить("РазрешитьСостояниеПрячущееся");
СтруктураСвойств.Вставить("РазрешитьСостояниеСвободное");
СтруктураСвойств.Вставить("РежимВыбора");
СтруктураСвойств.Вставить("РежимРабочегоСтола");
СтруктураСвойств.Вставить("СоединяемоеОкно");
СтруктураСвойств.Вставить("СостояниеОкна");
СтруктураСвойств.Вставить("СпособОтображенияОкна");
СтруктураСвойств.Вставить("Стиль");
СтруктураСвойств.Вставить("ТолькоПросмотр");
СтруктураСвойств.Вставить("Ширина");
СтруктураСвойств.Вставить("ЭлементыФормы");
СтруктураСвойств.Вставить("ТекущийЭлемент");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("ВладелецФормы");
СтруктураСвойств.Вставить("МодальныйРежим");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПостроительОтчета")
ИЛИ пОбъект = "ПостроительОтчета"
Тогда
СтруктураСвойств.Вставить("Текст");
СтруктураСвойств.Вставить("ДоступныеПоля");
СтруктураСвойств.Вставить("ВыбранныеПоля");
СтруктураСвойств.Вставить("ИзмеренияКолонки");
СтруктураСвойств.Вставить("ИзмеренияСтроки");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Параметры");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеНастройки")
ИЛИ пОбъект = "ПолеНастройки"
Тогда
СтруктураСвойств.Вставить("Измерение");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Отбор");
СтруктураСвойств.Вставить("Поле");
СтруктураСвойств.Вставить("Порядок");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("СписокЗначений");
СтруктураСвойств.Вставить("ТипЗначения");
Если НЕ пЛиДляСохранения Тогда
СтруктураСвойств.Вставить("Поля");
СтруктураСвойств.Вставить("Родитель");
КонецЕсли;
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ИзмерениеПостроителяОтчета")
ИЛИ пОбъект = "ИзмерениеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипИзмерения");
// не все
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ПолеПостроителяОтчета")
ИЛИ пОбъект = "ПолеПостроителяОтчета"
Тогда
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
ИначеЕсли Ложь
ИЛИ ТипОбъекта = Тип("ЭлементОтбора")
ИЛИ пОбъект = "ЭлементОтбора"
Тогда
СтруктураСвойств.Вставить("ВидСравнения");
СтруктураСвойств.Вставить("Значение");
СтруктураСвойств.Вставить("ЗначениеПо");
СтруктураСвойств.Вставить("ЗначениеС");
СтруктураСвойств.Вставить("Имя");
СтруктураСвойств.Вставить("Использование");
СтруктураСвойств.Вставить("Представление");
СтруктураСвойств.Вставить("ПутьКДанным");
СтруктураСвойств.Вставить("ТипЗначения");
КонецЕсли;
Возврат СтруктураСвойств;
КонецФункции // ПолучитьСтруктуруСвойствОбъектаЛкс()
// Сообщает об ошибке в тексте запроса и устанавливает выделение на ошибочную строку, если это возможно.
//
// Параметры:
// *ПолеТекстовогоДокумента - ПолеТекстовогоДокумента, *Неопределено;
// *СтартоваяСтрока - Число, *0 - стартовое смещение строки;
// *СтартоваяКолонка - Число, *0 - стартовое смещение колонки;
// *ЯзыкПрограммы - Число, *0 - признак обработки ошибки при установке текста запроса;
// *ЛиМодально - Булево, *Ложь - модальный режим формы - будет использовано Предупреждение() вместо Сообщить().
// *ИнформацияОбОшибке - ИнформацияОбОшибке, *Неопределено;
// *ИмяМодуля - Строка, *Неопределено - имя модуля в котором произошла ошибка.
//
// Возвращаемое значение:
// Строка истинное описание ошибки.
//
Функция ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс(ПолеТекстовогоДокумента = Неопределено,
СтартоваяСтрока = 0, СтартоваяКолонка = 0, ЯзыкПрограммы = 0, ЛиМодально = Ложь, ИнформацияОбОшибке = Неопределено,
ИмяМодуля = Неопределено, ПредставлениеКонтекста = "") Экспорт
НомерСтроки = 0;
Если ИмяМодуля <> Неопределено Тогда
Вступление = Символы.Таб;
Иначе
Вступление = "";
КонецЕсли;
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(ОписаниеОшибки, Истина, ЛиМодально);
Если Истина
И ЯзыкПрограммы = 0
И ИмяМодуля <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ОписаниеОшибки;
КонецЕсли;
Если ЯзыкПрограммы = 2 Тогда
Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЦикла;
Выражение = "";
Если Выражение = "" Тогда
Маркер = "Ошибка в выражении """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 2, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 3);
КонецЕсли;
КонецЕсли;
Если Выражение = "" Тогда
Маркер = "Поле не найдено """;
Если Найти(НРег(ИнформацияОбОшибке.Описание), Нрег(Маркер)) = 1 Тогда
МаркерНайден = Истина;
Выражение = Сред(ИнформацияОбОшибке.Описание, СтрДлина(Маркер) + 1, СтрДлина(ИнформацияОбОшибке.Описание) - СтрДлина(Маркер) - 1);
КонецЕсли;
КонецЕсли;
Если Выражение <> "" Тогда
ТекстПоля = ПолеТекстовогоДокумента.ПолучитьТекст();
ПозицияВыражения = Найти(ТекстПоля, Выражение);
Если ПозицияВыражения > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(ПозицияВыражения, ПозицияВыражения + СтрДлина(Выражение));
Пустышка = 0;
НомерСтроки = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НомерСтроки, Пустышка, Пустышка, Пустышка);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ИнформацияОбОшибке.Причина <> Неопределено
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ФигурноеОписаниеОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{", "}", Ложь);
Если ФигурноеОписаниеОшибки <> Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И ИнформацияОбОшибке.ИмяМодуля <> ""
И ИнформацияОбОшибке.ИмяМодуля <> ИмяМодуля
Тогда
ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
МаксимальныйНомерСтроки = 100000;
Если ПолеТекстовогоДокумента <> Неопределено Тогда
МаксимальныйНомерСтроки = ПолеТекстовогоДокумента.КоличествоСтрок();
КонецЕсли;
ФигурноеОписаниеОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ИнформацияОбОшибке.Описание, "{", "}", Ложь);
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если НомерСтроки = 0 Тогда
НомерСтроки = Мин(ИнформацияОбОшибке.НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если ИнформацияОбОшибке.ИсходнаяСтрока = "" Тогда
СтрокаКоординатыОшибки = ПолучитьСтрокуМеждуМаркерамиЛкс(ФигурноеОписаниеОшибки, "(", ")", Ложь);
Если СтрокаКоординатыОшибки <> Неопределено Тогда
НомерКолонки = 0;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаКоординатыОшибки, ",");
СтрокаНомерСтроки = МассивФрагментов[0];
Попытка
НомерСтроки = Число(СтрокаНомерСтроки);
Исключение
КонецПопытки;
НомерСтроки = Мин(НомерСтроки + СтартоваяСтрока, МаксимальныйНомерСтроки);
Если МассивФрагментов.Количество() > 1 Тогда
СтрокаНомерКолонки = МассивФрагментов[1];
Попытка
НомерКолонки = Число(СтрокаНомерКолонки);
Исключение
КонецПопытки;
НомерКолонки = НомерКолонки + СтартоваяКолонка;
КонецЕсли;
Если НомерСтроки = 0 Тогда
НомерКолонки = 1;
НомерСтроки = 1;
КонецЕсли;
ОписаниеОшибки = СтрЗаменить(ОписаниеОшибки, ФигурноеОписаниеОшибки, "(" + НомерСтроки + "," + НомерКолонки + ")");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЯзыкПрограммы = 0
И НомерСтроки <= 0
Тогда
Если ЗначениеЗаполнено(ОписаниеОшибки) Тогда
ОписаниеОшибки = "Ошибка передачи переменной: " + ОписаниеОшибки;
Иначе
ОписаниеОшибки = "Ошибка без описания";
КонецЕсли;
Иначе
ОписаниеОшибки = "Строка " + НомерСтроки + ": " + ОписаниеОшибки;
КонецЕсли;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ТекстСообщения = "";
Если ПолеТекстовогоДокумента <> Неопределено Тогда
Если НомерСтроки > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НомерСтроки, 1, НомерСтроки, 1000);
КонецЕсли;
ТекстСообщения = ТекстСообщения + ПолучитьПредставлениеИзИдентификатораЛкс(ПолеТекстовогоДокумента.Имя) + ПредставлениеКонтекста;
ТекстСообщения = ТекстСообщения + ": " + ОписаниеОшибки;
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
Иначе
ПолныйТекстСообщения = Вступление + ТекстСообщения;
Если ЛиМодально Тогда
Предупреждение(ОписаниеОшибки);
Иначе
Сообщить(ПолныйТекстСообщения, СтатусСообщения.Важное);
КонецЕсли;
КонецЕсли;
Возврат ПолныйТекстСообщения;
КонецФункции
Функция ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(Знач ОписаниеОшибки, ЭтоПроизвольныйАлгоритм = Ложь, Знач ЛиМодально = Ложь) Экспорт
Результат = Ложь;
Если Истина
//И (Ложь
// Или Не ирКэш.ЛиПортативныйРежимЛкс()
// Или ирПортативный.ЛиСерверныйМодульДоступенЛкс())
И Найти(ОписаниеОшибки, "мутабельн") > 0
И Найти(ОписаниеОшибки, "Записать") > 0
Тогда
ТекстСообщения = "Чтобы избежать ошибки передачи мутабельного значения при записи объектов, используйте ";
Если ЭтоПроизвольныйАлгоритм Тогда
ТекстСообщения = ТекстСообщения + "функцию ""ирОбщий.ЗаписатьОбъектЛкс(Объект, Истина)""";
Иначе
ТекстСообщения = ТекстСообщения + "опцию ""Запись на сервере"" инструмента";
КонецЕсли;
Если ирКэш.ЛиПортативныйРежимЛкс() И Не ирПортативный.ЛиСерверныйМодульДоступенЛкс() Тогда
ТекстСообщения = ТекстСообщения + ", которая станет доступной после указания пользователя внешнего соединения в настройках инструментов";
КонецЕсли;
Если ЛиМодально Тогда
Предупреждение(ТекстСообщения);
Иначе
Сообщить(ТекстСообщения, СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
КонецЕсли;
Возврат Результат;
КонецФункции // ПоказатьОшибкуВЗапросеИлиПрограммномКодеЛкс()
// Рассчитыват и устанавливает ширину колонок табличного документа. Ориентирована на обработку
// результата построителя отчета.
//
// Параметры:
// ТабличныйДокумент ТабличныйДокумент;
// *ЛиМинимальный Булево, *Ложь признак установки необходимой ширины, иначе достаточной;
// *ЛиИгнорироватьОбразание - Булево, *Ложь - признак игнорирования ячеек с обрезанием;
// *ШиринаОбластиПолей - Число, *0 - ширина области полей (не показателей);
// *РассчитыватьШиринуКолонкиПоНазванию - Булево, *Истина - признак расчета ширины колонки по названию;
// *МинимальнаяШиринаКолонкиПоказатель - Число, *10 - минимальная ширина колонки показателя;
// *ПорогКоличестваЯчеекДляАнализа - Число, *100000 - пороговое количество ячеек для анализа (усечение по высоте).
//
Процедура РассчитатьИУстановитьШиринуКолонокЛкс(ТабличныйДокумент, ЛиМинимальный = Ложь,
ЛиИгнорироватьОбрезание = Ложь, ШиринаОбластиПолей = 0, РассчитыватьШиринуКолонкиПоНазванию = Ложь,
МинимальнаяШиринаКолонкиПоказатель = 10, ПорогКоличестваЯчеекДляАнализа = 10000) Экспорт
Перем МаксимальнаяШиринаКолонки;
Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных;
Перем ОбластьШапки, ОбластьПодвала;
Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста;
Перем КоличествоУровнейГруппировокСтрок, Отступ;
Перем ШириныКолонок;
СтрокаСостояния = "Расчет ширины колонок табличного документа ";
КоличествоОбновленийСостояния = 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; ЧН=") + "%" + ТекстОсталось;
Иначе
ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
КонецЕсли;
Возврат ТекстСостояния;
КонецФункции // ПолучитьТекстСостоянияИндикатораЛкс()
// Открывает справку по первой подсистеме метаданных переданного объекта
//
// Параметры:
// Объект - любой объект, имеющий метаданные.
//
Процедура ОткрытьСправкуПоПодсистемеЛкс(Объект = Неопределено) Экспорт
Если Ложь
Или ТипЗнч(Объект) = Тип("Неопределено")
Или ТипЗнч(Объект) = Тип("ОкноКлиентскогоПриложения")
Тогда
//
ИначеЕсли ТипЗнч(Объект) = Тип("Форма") Тогда
ПолноеИмяМД = ПолучитьДопСвойстваФормыЛкс(Объект).ИмяФормы;
ИначеЕсли ТипЗнч(Объект) = Тип("УправляемаяФорма") Тогда
ПолноеИмяМД = Объект.ИмяФормы;
Иначе
Если ТипЗнч(Объект) = Тип("Тип") Тогда
ОбъектМД = Метаданные.НайтиПоТипу(Объект);
Иначе
ОбъектМД = Объект.Метаданные();
КонецЕсли;
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
КонецЕсли;
ОткрытьФормуЛкс("Обработка.ирПлатформа.Форма.ОПодсистеме",,, ПолноеИмяМД);
КонецПроцедуры // ОткрытьСправкуПоПодсистемеЛкс()
Процедура ПанельИнструментовОПодсистемеЛкс() Экспорт
ОткрытьСправкуПоПодсистемеЛкс();
КонецПроцедуры
// Открывает обработку ирПоискДублейИЗаменаСсылок и заполняет группы дублей по табличному полю, связанному с таблицой или деревом значений.
//
Процедура ОткрытьФормуЗаменыСсылокИзТабличногоПоляЛкс(ТабличноеПоле) Экспорт
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ФормаОбработки = ПолучитьФормуЛкс("Обработка.ирПоискДублейИЗаменаСсылок.Форма");
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений") Тогда
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() = 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");
РезультатЗапроса = ВыполнитьЗамеритьЗапросЛкс(Запрос, ЛиОтладка, "Предварительный запрос - " + НаборДанных.Имя);
ВнешниеНаборыДанных.Вставить(НаборДанных.Имя, РезультатЗапроса);
КонецЦикла;
// Получение конечного макета
Для Каждого ЭлементНаборДанных Из СтруктураНаборовДанныхЗапросовМакета Цикл
КоллекцияВладелец = ЭлементНаборДанных.Значение.КоллекцияВладелец;
НаборДанныхЗапрос = ЭлементНаборДанных.Значение.НаборДанных;
НаборДанныхОбъект = КоллекцияВладелец.Добавить(Тип("НаборДанныхОбъектМакетаКомпоновкиДанных"));
// Копируем Свойства набора данных запроса в набор данных объекта
ЗаполнитьЗначенияСвойств(НаборДанныхОбъект, НаборДанныхЗапрос);
НаборДанныхОбъект.ИмяОбъекта = НаборДанныхЗапрос.Имя;
Для Каждого ПолеНабораДанныхОригинала Из НаборДанныхЗапрос.Поля Цикл
ПолеРезультата = НаборДанныхОбъект.Поля.Добавить();
ЗаполнитьЗначенияСвойств(ПолеРезультата, ПолеНабораДанныхОригинала);
ЗаполнитьЗначенияСвойств(ПолеРезультата.Роль, ПолеНабораДанныхОригинала.Роль);
КонецЦикла;
КоллекцияВладелец.Удалить(НаборДанныхЗапрос);
КонецЦикла;
КонецЕсли;
// Баг платформы. Пустая дата превращается в Неопределено.
Для Каждого ПараметрСхемы Из ПредварительнаяСхема.Параметры Цикл
Если ПараметрСхемы.ОграничениеИспользования Тогда
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ЗначениеПараметра = МакетКомпоновкиДанных.ЗначенияПараметров.Найти(ПараметрСхемы.Имя);
ЗначениеПараметра.Значение = ПараметрСхемы.ТипЗначения.ПривестиЗначение(ЗначениеПараметра.Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат МакетКомпоновкиДанных;
КонецФункции // ПолучитьМакетКомпоновкиДанныхСВременнымиТаблицамиЛкс()
// Выводит результат СКД с установкой вертикальной автофиксации.
// Параметры:
// Таб - ТабличныеДокумент, ПолеТабличногоДокумента - куда выводим отчет;
// ПроцессорКомпоновкиДанных - ПроцессорКомпоновкиДанных;
// ЭлементыРасшировки - ЭлементыРасшифровкиКомпоновкиДанных;
// МассивИгнорируемыхПолей - Массив, *Неопределено - массив имен игнорируемых полей;
// РазрешитьПрерывание - Булево, *Истина.
//
Процедура ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(Таб, ПроцессорКомпоновкиДанных, ЭлементыРасшировки,
Знач МассивИгнорируемыхПолей = Неопределено, РазрешитьПрерывание = Истина, Автофиксация = Истина, выхЭлементыРезультата = Неопределено) Экспорт
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Таб);
ПроцессорВывода.НачатьВывод();
ФиксацияВыполнена = Ложь;
Если МассивИгнорируемыхПолей = Неопределено Тогда
МассивИгнорируемыхПолей = Новый Массив;
КонецЕсли;
Пока Истина Цикл
ЭлементРезультатаКомпоновкиДанных = ПроцессорКомпоновкиДанных.Следующий();
Если ЭлементРезультатаКомпоновкиДанных = Неопределено Тогда
Прервать;
КонецЕсли;
Если РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
// Автофиксация
Если Истина
И Автофиксация
И Не ФиксацияВыполнена
Тогда
Для Каждого ЗначениеПараметра Из ЭлементРезультатаКомпоновкиДанных.ЗначенияПараметров Цикл
Если ТипЗнч(ЗначениеПараметра.Значение) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолейРасшифровки = ЭлементыРасшировки[ЗначениеПараметра.Значение].ПолучитьПоля();
Для Каждого ЗначениеПоляРасшифровки Из ЗначенияПолейРасшифровки Цикл
Если МассивИгнорируемыхПолей.Найти(ЗначениеПоляРасшифровки.Поле) = Неопределено Тогда
Таб.ФиксацияСверху = Таб.ВысотаТаблицы;
ФиксацияВыполнена = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФиксацияВыполнена Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпоновкиДанных);
Если Истина
И выхЭлементыРезультата <> Неопределено
И выхЭлементыРезультата.Количество() < 10000
Тогда
выхЭлементыРезультата.Добавить(ЭлементРезультатаКомпоновкиДанных);
КонецЕсли;
Если РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры // ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс
#КонецЕсли
// Переустанавливает значения недоступных параметров из схемы (антибаг платформы).
//
// Параметры:
// СхемаКомпоновкиДанных СхемаКомпоновкиДанных;
// КомпоновщикНастроек КомпоновщикНастроекКомпоновкиДанных.
//
Процедура ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс(КомпоновщикНастроек, СхемаКомпоновкиДанных) Экспорт
Для Каждого ЗначениеПараметра Из КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти("" + ЗначениеПараметра.Параметр);
Если Истина
И ПараметрСхемы <> Неопределено
И ПараметрСхемы.ОграничениеИспользования
Тогда
//Если ЗначениеЗаполнено(ЗначениеПараметра.Выражение) Тогда
// Попытка
// ЗначениеПараметра.Значение = Вычислить();
// Исключение
// КонецПопытки;
//Иначе
ЗначениеПараметра.Значение = ПараметрСхемы.Значение;
//КонецЕсли;
//ЗначениеПараметра.Использование = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОбновитьЗначенияНедоступныхПараметровИзСхемыЛкс()
Процедура ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных) Экспорт
ПолеКоличества = "КоличествоСтрокАвто";
ВычисляемоеПоле = СхемаКомпоновкиДанных.ВычисляемыеПоля.Добавить();
ВычисляемоеПоле.Выражение = "1";
ВычисляемоеПоле.Заголовок = "Количество строк (авто)";
ВычисляемоеПоле.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
РесурсКоличествоЗаписей.ПутьКДанным = ПолеКоличества;
РесурсКоличествоЗаписей.Выражение = "Сумма(1)";
КонецПроцедуры
// Создает новую или добавляет в существующую схему компоновки наборы данных объекты из структуры таблиц значений.
//
// Параметры:
// СтруктураТаблиц Структура <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоТаблицамЗначенийЛкс(СтруктураТаблиц, СхемаКомпоновкиДанных = Неопределено, СоздаватьПапкиПолей = Ложь,
СоздаватьРесурсыЧисловыхПолей = Ложь, ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок = Истина) Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураТаблиц Цикл
СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(СхемаКомпоновкиДанных, КлючИЗначение.Значение.Колонки, КлючИЗначение.Ключ,
СоздаватьПапкиПолей, СоздаватьРесурсыЧисловыхПолей);
КонецЦикла;
Если ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
Возврат СхемаКомпоновкиДанных;
КонецФункции // СоздатьСхемуПоТаблицамЗначенийЛкс()
// Создает новую или добавляет в существующую схему компоновки набор данных объект из полей настройки.
//
// Параметры:
// ПоляНастройки ПоляНастройки <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция СоздатьСхемуПоПолямНастройкиЛкс(ПоляНастройки, СхемаКомпоновкиДанных = Неопределено, ИмяНабора = "НаборДанных1") Экспорт
Если СхемаКомпоновкиДанных = Неопределено Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных);
КонецЕсли;
НаборДанных = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабора;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
НаборДанных.ИмяОбъекта = ИмяНабора;
Для Каждого ПолеНастройки Из ПоляНастройки Цикл
Поле = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
Поле.ПутьКДанным = ПолеНастройки.Имя;
Поле.Поле = ПолеНастройки.ПутьКДанным;
Поле.Заголовок = ПолеНастройки.Представление;
Поле.ТипЗначения = ПолеНастройки.ТипЗначения;
ОграничениеИспользования = Поле.ОграничениеИспользования;
ОграничениеИспользования.Поле = Не ПолеНастройки.Поле;
ОграничениеИспользования.Условие = Не ПолеНастройки.Отбор;
ОграничениеИспользования.Порядок = Не ПолеНастройки.Порядок;
ОграничениеИспользования.Группировка = Не ПолеНастройки.Измерение;
ЗначениеОграничения = ПолеНастройки.Поля.Количество() = 0;
ОграничениеИспользованияРеквизитов = Поле.ОграничениеИспользованияРеквизитов;
ОграничениеИспользованияРеквизитов.Поле = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Условие = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Порядок = ЗначениеОграничения;
ОграничениеИспользованияРеквизитов.Группировка = ЗначениеОграничения;
КонецЦикла;
Возврат СхемаКомпоновкиДанных;
КонецФункции // СоздатьСхемуПоПолямНастройкиЛкс()
// Параметры:
// Поле -
// Доступность -
// ПрименитьГруппировка -
// ПрименитьПоле -
// ПрименитьПорядок -
// ПрименитьУсловие -
// Возвращаемое значение:
//
Функция УстановитьОграниченияИспользованияПоляНабораДанныхСхемыКомпоновкиЛкс(Знач Поле, Знач Ограничивать = Ложь, Знач ПрименитьГруппировка = Истина,
Знач ПрименитьПоле = Истина, Знач ПрименитьПорядок = Истина, Знач ПрименитьУсловие = Истина) Экспорт
МассивГруппОграничений = Новый Массив;
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользования);
Попытка
МассивГруппОграничений.Добавить(Поле.ОграничениеИспользованияРеквизитов);
Исключение
КонецПопытки;
Для Каждого ОграничениеИспользования Из МассивГруппОграничений Цикл
Если ПрименитьГруппировка Тогда
ОграничениеИспользования.Группировка = Ограничивать;
КонецЕсли;
Если ПрименитьПоле Тогда
ОграничениеИспользования.Поле = Ограничивать;
КонецЕсли;
Если ПрименитьПорядок Тогда
ОграничениеИспользования.Порядок = Ограничивать;
КонецЕсли;
Если ПрименитьУсловие Тогда
ОграничениеИспользования.Условие = Ограничивать;
КонецЕсли;
КонецЦикла;
КонецФункции
// Функция добавляет в схему компоновки источник данных с типом "Local"
Функция ДобавитьЛокальныйИсточникДанныхЛкс(СхемаКомпоновкиДанных) Экспорт
ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "ИсточникДанных1";
ИсточникДанных.ТипИсточникаДанных = "Local";
Возврат ИсточникДанных;
КонецФункции
// Функция добавляет набор данных - запрос в указанную в параметре коллекцию наборов данных
Функция ДобавитьНаборДанныхЗапросЛкс(НаборыДанных, ИсточникДанных, ИмяНабораДанных = "НаборДанных1") Экспорт
НаборДанных = НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
НаборДанных.Имя = ИмяНабораДанных;
НаборДанных.ИсточникДанных = ИсточникДанных.Имя;
Возврат НаборДанных;
КонецФункции
// Устаревшее! Новая - ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.ПолучитьВыражениеПорядкаКомпоновкиНаЯзыке
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки ПорядокКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьСтрокуПорядкаКомпоновкиЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено) Экспорт
Строка = "";
Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + "Возр";
Иначе
Строка = Строка + "Убыв";
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс()
// Трансформирует порядок в порядок компоновки.
//
// Параметры:
// ПорядокКомпоновки ПорядокКомпоновкиДанных;
// Порядок - Порядок.
//
Процедура ТрансформироватьПорядокВПорядокКомпоновкиЛкс(ПорядокКомпоновки, Порядок) Экспорт
ЭлементыКомпоновки = ПорядокКомпоновки.Элементы;
ЭлементыКомпоновки.Очистить();
Для Каждого Элемент Из Порядок Цикл
ЭлементКомпоновки = ЭлементыКомпоновки.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементКомпоновки.Использование = Истина;
ЭлементКомпоновки.Поле = Новый ПолеКомпоновкиДанных(Элемент.ПутьКДанным);
Если Элемент.Направление = НаправлениеСортировки.Возр Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр;
Иначе//Если Элемент.Направление = НаправлениеСортировки.Убыв Тогда
ЭлементКомпоновки.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Убыв;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ТрансформироватьПорядокВПорядокКомпоновкиЛкс()
// Конструктор массива через Параметры.
//
// Параметры:
// *п... Произвольный элементы массива.
//
// Возвращаемое значение:
// Массив - полученный массив.
//
Функция БыстрыйМассивЛкс(
п1 = Неопределено, п2 = Неопределено, п3 = Неопределено, п4 = Неопределено, п5 = Неопределено,
п6 = Неопределено, п7 = Неопределено, п8 = Неопределено, п9 = Неопределено, п10= Неопределено,
п11= Неопределено, п12= Неопределено, п13= Неопределено, п14= Неопределено, п15= Неопределено,
п16= Неопределено, п17= Неопределено, п18= Неопределено, п19= Неопределено, п20= Неопределено
) Экспорт
Перем М;
М = Новый Массив();
Если п1 = Неопределено Тогда Возврат М; Иначе М.Добавить(п1 ); КонецЕсли;
Если п2 = Неопределено Тогда Возврат М; Иначе М.Добавить(п2 ); КонецЕсли;
Если п3 = Неопределено Тогда Возврат М; Иначе М.Добавить(п3 ); КонецЕсли;
Если п4 = Неопределено Тогда Возврат М; Иначе М.Добавить(п4 ); КонецЕсли;
Если п5 = Неопределено Тогда Возврат М; Иначе М.Добавить(п5 ); КонецЕсли;
Если п6 = Неопределено Тогда Возврат М; Иначе М.Добавить(п6 ); КонецЕсли;
Если п7 = Неопределено Тогда Возврат М; Иначе М.Добавить(п7 ); КонецЕсли;
Если п8 = Неопределено Тогда Возврат М; Иначе М.Добавить(п8 ); КонецЕсли;
Если п9 = Неопределено Тогда Возврат М; Иначе М.Добавить(п9 ); КонецЕсли;
Если п10= Неопределено Тогда Возврат М; Иначе М.Добавить(п10); КонецЕсли;
Если п11= Неопределено Тогда Возврат М; Иначе М.Добавить(п11); КонецЕсли;
Если п12= Неопределено Тогда Возврат М; Иначе М.Добавить(п12); КонецЕсли;
Если п13= Неопределено Тогда Возврат М; Иначе М.Добавить(п13); КонецЕсли;
Если п14= Неопределено Тогда Возврат М; Иначе М.Добавить(п14); КонецЕсли;
Если п15= Неопределено Тогда Возврат М; Иначе М.Добавить(п15); КонецЕсли;
Если п16= Неопределено Тогда Возврат М; Иначе М.Добавить(п16); КонецЕсли;
Если п17= Неопределено Тогда Возврат М; Иначе М.Добавить(п17); КонецЕсли;
Если п18= Неопределено Тогда Возврат М; Иначе М.Добавить(п18); КонецЕсли;
Если п19= Неопределено Тогда Возврат М; Иначе М.Добавить(п19); КонецЕсли;
Если п20= Неопределено Тогда Возврат М; Иначе М.Добавить(п20); КонецЕсли;
Возврат М;
КонецФункции // БыстрыйМассивЛкс()
////////////////////////////////////////////////////////////////////////////////
// РАБОТА СО СТРОКАМИ
// <Описание функции>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
// Возвращаемое значение:
// Строка - путь к файлу.
//
Функция ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение, Название, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Если Ложь
Или ТипЗнч(Значение) = Тип("ТабличныйДокумент")
Или ТипЗнч(Значение) = Тип("ТекстовыйДокумент")
Тогда
Документ = Значение;
Иначе
Документ = Новый ТекстовыйДокумент;
Если ТипЗнч(Значение) = Тип("ХранилищеЗначения") Тогда
Значение = Значение.Получить();
КонецЕсли;
Если ТипЗнч(Значение) <> Тип("Строка") И ПолучатьXMLПредставлениеДляНеизвестныхТипов Тогда
Представление = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение);
Иначе
Представление = Значение;
КонецЕсли;
Документ.УстановитьТекст(ПолучитьТекстИзXMLЛкс(Представление));
КонецЕсли;
Путь = ПолучитьИмяВременногоФайла(Название);
Документ.Записать(Путь);
Возврат Путь;
КонецФункции // ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс()
// Получает строку путем отсечения заданного числа последних символов.
//
// Параметры:
// пСтрока Строка исходная;
// пДлинаКонца - Число, *1 - количество отсекаемых символов;
//
// Возвращаемое значение:
// Строка.
//
Функция ПолучитьСтрокуБезКонцаЛкс(пСтрока, пДлинаКонца = 1) Экспорт
Если СтрДлина(пСтрока) < пДлинаКонца Тогда
Возврат "";
Иначе
Возврат Лев(пСтрока, СтрДлина(пСтрока) - пДлинаКонца);
КонецЕсли;
КонецФункции // ПолучитьСтрокуБезКонцаЛкс()
// Функция разбивает строку разделителем.
//
// Параметры:
// пСтрока - Строка - которую разбиваем;
// *пРазделитель - Строка, "." - символ-разделитель;
// *ОбрезатьНепечатныеСимволы - Булево, *Ложь - делать СокрЛП.
// *ОставлятьПустуюСтроку - Булево, *Истина - если передана пустая строка, то добавлять ее в массив.
//
// Возвращаемое значение:
// Массив - фрагментов.
//
Функция ПолучитьМассивИзСтрокиСРазделителемЛкс(Знач Стр, Разделитель = ".", ОбрезатьНепечатныеСимволы = Ложь, ОставлятьПустуюСтроку = Истина) Экспорт
МассивСтрок = Новый Массив;
Если Истина
И Не ОставлятьПустуюСтроку
И ПустаяСтрока(Стр)
Тогда
Возврат МассивСтрок;
КонецЕсли;
//лСтрока = СтрЗаменить(Стр, Разделитель, Символы.ПС);
//// Баг платформы. СтрЧислоСтрок не учитывает терминальный перевод строки.
//ЧислоСтрок = СтрЧислоСтрок(лСтрока + " ");
//Для Счетчик = 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.УстановитьСтроку(
"<TypeDescription xmlns=""http://v8.1c.ru/8.1/data/core"">
| <TypeSet xmlns:cc=""http://v8.1c.ru/8.1/data/enterprise/current-config"">cc:AnyRef</TypeSet>
|</TypeDescription>");
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Возврат Результат;
КонецФункции
Функция ПолучитьОписаниеТиповВсеРедактируемыеТипыЛкс() Экспорт
ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс();
ДополнительныеТипы = Новый Массив();
ДополнительныеТипы.Добавить(Тип("Строка"));
ДополнительныеТипы.Добавить(Тип("Число"));
ДополнительныеТипы.Добавить(Тип("Дата"));
ДополнительныеТипы.Добавить(Тип("Булево"));
ДополнительныеТипы.Добавить(Тип("СписокЗначений"));
ДополнительныеТипы.Добавить(Тип("Массив"));
ДополнительныеТипы.Добавить(Тип("ОписаниеТипов"));
ДополнительныеТипы.Добавить(Тип("МоментВремени"));
ДополнительныеТипы.Добавить(Тип("Граница"));
ДополнительныеТипы.Добавить(Тип("СтандартнаяДатаНачала"));
ДополнительныеТипы.Добавить(Тип("СтандартныйПериод"));
ДополнительныеТипы.Добавить(Тип("ТаблицаЗначений"));
ДополнительныеТипы.Добавить(Тип("ДеревоЗначений"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияНакопления"));
ДополнительныеТипы.Добавить(Тип("ВидДвиженияБухгалтерии"));
ДополнительныеТипы.Добавить(Тип("ВидСчета"));
ДополнительныеТипы.Добавить(Тип("Тип"));
ДополнительныеТипы.Добавить(Тип("Null"));
ДополнительныеТипы.Добавить(Тип("ПолеКомпоновкиДанных"));
//ДополнительныеТипы.Добавить(Тип("ВидТочкиМаршрутаБизнесПроцесса")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
//ДополнительныеТипы.Добавить(Тип("ВидПериодаРегистраРасчета")); // нельзя добавить, т.к. для этого типа не поддерживается сериализация
ДополнительныеТипы.Добавить(Тип("УникальныйИдентификатор"));
// Из-за бага платформы отключены
//ДополнительныеТипы.Добавить(Тип("ПериодичностьАгрегатаРегистраНакопления"));
//ДополнительныеТипы.Добавить(Тип("ИспользованиеАгрегатаРегистраНакопления"));
КвалификаторыЧисла = Новый КвалификаторыЧисла; //(25, 5); // Важно!
ОписаниеТипов = Новый ОписаниеТипов(ОписаниеТипов, ДополнительныеТипы, , КвалификаторыЧисла);
Возврат ОписаниеТипов;
КонецФункции
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ДЕРЕВЬЯМИ
Процедура ДобавитьКолонкуЕслиНетЛкс(КолонкиДереваИлиТаблицы, ИмяКолонки, ОписаниеТипов = Неопределено,
Заголовок = Неопределено, Ширина = 0) Экспорт
Если КолонкиДереваИлиТаблицы.Найти(ИмяКолонки) <> Неопределено Тогда
Возврат;
КонецЕсли;
КолонкиДереваИлиТаблицы.Добавить(ИмяКолонки, ОписаниеТипов, Заголовок, Ширина);
КонецПроцедуры // ДобавитьКолонкуЕслиНетЛкс()
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт
Результат = СтрокаДерева[ИмяКолонки];
Если СтрокаДерева.Родитель = Неопределено Тогда
Если Истина
И ИгнорироватьПростойПервыйУровень
И СтрокаДерева.Владелец().Строки.Количество() = 1
Тогда
Результат = Неопределено;
КонецЕсли;
Иначе
РезультатСверху = ПолучитьСтрокуПутиВДеревеЛкс(СтрокаДерева.Родитель, ИмяКолонки, ИгнорироватьПростойПервыйУровень);
Если РезультатСверху <> Неопределено Тогда
Результат = РезультатСверху + "." + Результат;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьСтрокуПутиВДеревеЛкс()
// ИгнорироватьПростойПервыйУровень - Булево - если на первом уровне только одна строка, то игнорировать ее
Функция НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки, Путь, ИгнорироватьПростойПервыйУровень = Ложь) Экспорт
Если Истина
И ИгнорироватьПростойПервыйУровень
И ТипЗнч(СтрокаДерева) = Тип("ДеревоЗначений")
И СтрокаДерева.Строки.Количество() = 1
Тогда
Возврат НайтиПоСтрокеПутиВДеревеЛкс(СтрокаДерева.Строки[0], ИмяКолонки, Путь);
КонецЕсли;
ТекущийУровень = ПолучитьПервыйФрагментЛкс(Путь);
ОстальнойПуть = Сред(Путь, СтрДлина(ТекущийУровень) + 2);
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
Если ТекущаяСтрока <> Неопределено Тогда
Возврат НайтиПоСтрокеПутиВДеревеЛкс(ТекущаяСтрока, ИмяКолонки, ОстальнойПуть);
Иначе
Возврат СтрокаДерева;
КонецЕсли;
КонецФункции // НайтиПоСтрокеПутиВДеревеЛкс()
Функция ПолучитьМассивПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки) Экспорт
Если СтрокаДерева.Родитель = Неопределено Тогда
Результат = Новый Массив;
Иначе
Результат = ПолучитьМассивПутиВДеревеЛкс(СтрокаДерева.Родитель, ИмяКолонки);
КонецЕсли;
Результат.Добавить(СтрокаДерева[ИмяКолонки]);
Возврат Результат;
КонецФункции // ПолучитьМассивПутиВДеревеЛкс()
Функция НайтиПоМассивуПутиВДеревеЛкс(СтрокаДерева, ИмяКолонки, Путь, Позиция = 0) Экспорт
Индекс = Позиция;
ТекущийУровень = Путь[Индекс];
ТекущаяСтрока = СтрокаДерева.Строки.Найти(ТекущийУровень, ИмяКолонки);
Если Истина
И ТекущаяСтрока <> Неопределено
И Индекс < Путь.ВГраница()
Тогда
Возврат НайтиПоМассивуПутиВДеревеЛкс(ТекущаяСтрока, ИмяКолонки, Путь, Позиция + 1);
Иначе
Возврат ТекущаяСтрока;
КонецЕсли;
КонецФункции // НайтиПоМассивуПутиВДеревеЛкс()
// Процедура заполняет колонку дерева значением.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура ЗаполнитьКолонкуДереваЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
Для Каждого ПодчиненнаяСтрока Из ЭлементДЗ.Строки Цикл
ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки;
ЗаполнитьКолонкуДереваЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЦикла;
КонецПроцедуры // ЗаполнитьКолонкуДереваЛкс
// Процедура удаляет все строки дерева со значением в колонке.
//
// Параметры
// ЭлементДЗ - ДеревоЗначений;
// ИмяКолонки - Строка;
// ЗначениеКолонки - Произвольный.
//
Процедура УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ЭлементДЗ, ИмяКолонки, ЗначениеКолонки) Экспорт
НачальноеКоличество = ЭлементДЗ.Строки.Количество();
Для Счетчик = 1 По НачальноеКоличество Цикл
ПодчиненнаяСтрока = ЭлементДЗ.Строки[НачальноеКоличество - Счетчик];
Если ПодчиненнаяСтрока[ИмяКолонки] = ЗначениеКолонки Тогда
ЭлементДЗ.Строки.Удалить(ПодчиненнаяСтрока);
Иначе
УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс(ПодчиненнаяСтрока, ИмяКолонки, ЗначениеКолонки);
КонецЕсли;
КонецЦикла;
КонецПроцедуры // УдалитьСтрокиДереваПоЗначениюВКолонкеЛкс
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция ПолучитьТекстИзXMLЛкс(Текст) Экспорт
//{ Заменяем символы, критичные для XML
Текст = СтрЗаменить(Текст,"&amp;","&");
Текст = СтрЗаменить(Текст,"&lt;","<");
Текст = СтрЗаменить(Текст,"&gt;",">");
Возврат Текст;
КонецФункции // ПолучитьТекстИзXMLЛкс()
Функция СтрокаВнутрВХМЛТелоЛкс(вхСтрока, выхХМЛТело = Неопределено) Экспорт
//{ Получение одной длинной строки
выхХМЛТело = СтрЗаменить(вхСтрока,СИМВОЛЫ.ПС,"");
выхХМЛТело = СтрЗаменить(выхХМЛТело,СИМВОЛЫ.ВК,"");
//}
//{ Заменяем символы, критичные для XML
// & на &amp;
// < на &lt;
// > на &gt;
выхХМЛТело = СтрЗаменить(выхХМЛТело,"&","&amp;");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"<","&lt;");
выхХМЛТело = СтрЗаменить(выхХМЛТело,">","&gt;");
//{ Замена одинарных символов
выхХМЛТело = СтрЗаменить(выхХМЛТело,",","</data><data>");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"{","<elem><data>");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"}","</data></elem>");
//}
//{ Удаляем лишние блоки <data><elem> и </data></elem>
выхХМЛТело = СтрЗаменить(выхХМЛТело,"<data><elem>","<elem>");
выхХМЛТело = СтрЗаменить(выхХМЛТело,"</elem></data>","</elem>");
//}
//{ Добавляем перенос строки к </data> и к </elem> для удобства поиска различий
выхХМЛТело = СтрЗаменить(выхХМЛТело,"</elem>","</elem>"+СИМВОЛЫ.ПС);
выхХМЛТело = СтрЗаменить(выхХМЛТело,"</data>","</data>"+СИМВОЛЫ.ПС);
//}
Возврат выхХМЛТело;
КонецФункции
// Получает структуру для индикации прогресса цикла.
//
// Параметры:
// КоличествоПроходов Число - максимальное значение счетчика;
// ПредставлениеПроцесса Строка, *"Выполнено" отображаемое название процесса;
// КоличествоОбновлений - Число, *100 - всего количество обновлений индикатора;
// ЛиВыводитьВремя - Булево, *Истина - выводить приблизительное время до окончания процесса;
// РазрешитьПрерывание - Булево, *Истина - разрешает пользователю прерывать процесс.
// МинимальныйПериодОбновления - Число, *1 - с, обновлять не чаще чем этот период, 0 - по количеству обновлений,
// эта реализация не поддерживает дробные значения;
// ТаблицаИндикаторов - ТаблицаЗначений,* - передается при необходимости многоуровневой индикации
//
// Возвращаемое значение:
// Структура - которую потом нужно будет передавать в метод ОбработатьИндикаторЛкс.
//
Функция ПолучитьИндикаторПроцессаЛкс(Знач КоличествоПроходов = 0, ПредставлениеПроцесса = "Выполнение",
Знач КоличествоОбновлений = 0, ЛиВыводитьВремя = Истина, РазрешитьПрерывание = Истина, МинимальныйПериодОбновления = 1,
ТаблицаИндикаторов = Неопределено) Экспорт
ирПлатформа = ирКэш.Получить();
Если Не ЗначениеЗаполнено(КоличествоПроходов) Тогда
//#Если Клиент Тогда
// СостояниеЛкс(ПредставлениеПроцесса + "...");
//#КонецЕсли
КоличествоПроходов = 0;
КонецЕсли;
КоличествоПроходов = Цел(КоличествоПроходов);
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() = 0 Тогда
#Если Клиент Тогда
ПодключитьГлобальныйОбработчикОжиданияЛкс("ОсвободитьВсеИндикаторыПроцессовОтложенноЛкс");
#КонецЕсли
ИначеЕсли ТаблицаИндикаторов.Количество() >= 10 Тогда
ВызватьИсключение "Превышена допустимая глубина вложенности индикаторов";
КонецЕсли;
Индикатор = ТаблицаИндикаторов.Добавить();
Индикатор.КоличествоПроходов = КоличествоПроходов;
Индикатор.ПредставлениеПроцесса = ПредставлениеПроцесса;
Индикатор.ЛиВыводитьВремя = ЛиВыводитьВремя;
Индикатор.РазрешитьПрерывание = РазрешитьПрерывание;
Индикатор.ДатаНачалаПроцесса = ТекущаяДата();
Индикатор.МинимальныйПериодОбновления = МинимальныйПериодОбновления;
Индикатор.ДатаСледующегоОбновления = Индикатор.ДатаНачалаПроцесса + Индикатор.МинимальныйПериодОбновления;
Если КоличествоОбновлений > 0 Тогда
Шаг = КоличествоПроходов / КоличествоОбновлений;
Иначе
Шаг = 0;
КонецЕсли;
Индикатор.Шаг = Шаг;
//Индикатор.СледующийСчетчик = 0;
//Индикатор.Счетчик = 0;
Возврат Индикатор;
КонецФункции // ПолучитьИндикаторПроцессаЛкс()
// Вызов метода при без параметра СтрокаИндикатора освобождает один полученный последним индикатор процесса. В качестве параметра этого метода можно передавать и конкретный индикатор процесса. При освобождении индикатора процесса выполняется либо его удаление из базы данных (без постоянного хранения состояния), либо сохранение его текущего состояния в базу данных (с постоянным хранением состояния)
// Параметры:
// СтрокаИндикатора - Неопределено, СтрокаТаблицыЗначений - Если Неопределено, то освобождается последний индикатор
// ВывестиИтогИндикации - Булево
// ТолькоВосстановитьСостояние - Булево - Устанавливается при обратном COM вызове
//
Процедура ОсвободитьИндикаторПроцессаЛкс(Знач Индикатор = Неопределено, Знач ВывестиИтогИндикации = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если Индикатор = Неопределено Тогда
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
КонецЕсли;
КонецЕсли;
Если Индикатор <> Неопределено Тогда
Если ВывестиИтогИндикации Тогда
СообщитьИтогИндикацииЛкс(Индикатор);
КонецЕсли;
Если ТаблицаИндикаторов <> Неопределено Тогда
Если ТаблицаИндикаторов.Индекс(Индикатор) <> -1 Тогда
ТаблицаИндикаторов.Удалить(Индикатор);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Ложь
Или ТаблицаИндикаторов = Неопределено
Или ТаблицаИндикаторов.Количество() = 0
Тогда
НовоеСостояние = "";
Иначе
НовоеСостояние = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1].ТекстСостояния;
КонецЕсли;
#Если Клиент Тогда
Состояние(НовоеСостояние);
#КонецЕсли
КонецПроцедуры
Процедура ОсвободитьВсеИндикаторыПроцессовЛкс() Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
//Для Каждого СтрокаИндикатора Из ТаблицаИндикаторов Цикл
// ОбработатьИндикаторЛкс(СтрокаИндикатора, , Истина);
//КонецЦикла;
ТаблицаИндикаторов.Очистить();
КонецПроцедуры
// Проверяет и обновляет индикатор. Нужно вызывать на каждом проходе индицируемого цикла.
//
// Параметры:
// Индикатор Структура индикатора, полученная методом ПолучитьИндикаторПроцессаЛкс;
// Счетчик Число, *Неопределено внешний счетчик цикла.
//
Процедура ОбработатьИндикаторЛкс(Индикатор, Счетчик = Неопределено) Экспорт
Если Счетчик = Неопределено Тогда
Попытка
Счетчик = Индикатор.Счетчик;
Исключение
// Бывает, что строка таблицы индикаторов уже была удалена
Возврат;
КонецПопытки;
Счетчик = Счетчик + 1;
КонецЕсли;
Индикатор.Счетчик = Счетчик;
#Если Клиент Тогда
Если Индикатор.РазрешитьПрерывание Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
#КонецЕсли
ОбновитьИндикатор = Истина;
Если Ложь
Или Счетчик < Индикатор.КоличествоПроходов
Или Индикатор.КоличествоПроходов = 0
Тогда
ТекущаяДата = ТекущаяДата();
Если Индикатор.МинимальныйПериодОбновления > 0 Тогда
Если ТекущаяДата >= Индикатор.ДатаСледующегоОбновления Тогда
Индикатор.ДатаСледующегоОбновления = ТекущаяДата + Индикатор.МинимальныйПериодОбновления;
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндикатор Тогда
Если Индикатор.Шаг > 0 Тогда
Если Счетчик >= Индикатор.СледующийСчетчик Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Иначе
ОбновитьИндикатор = Ложь;
КонецЕсли;
//Иначе
// ОбновитьИндикатор = Ложь;
// ТекстСостояния = Индикатор.ПредставлениеПроцесса + ": " + Счетчик + " ";
// Состояние(ТекстСостояния);
КонецЕсли;
КонецЕсли;
Иначе
Если ТипЗнч(Индикатор) <> Тип("СтрокаТаблицыЗначений") Тогда
#Если Клиент Тогда
Состояние("");
#КонецЕсли
ОбновитьИндикатор = Ложь;
КонецЕсли;
КонецЕсли;
Если ОбновитьИндикатор Тогда
Индикатор.СледующийСчетчик = Цел(Счетчик + Индикатор.Шаг);
Если ТипЗнч(Индикатор) = Тип("СтрокаТаблицыЗначений") Тогда
МассивИндикаторов = Индикатор.Владелец();
Иначе
МассивИндикаторов = Новый Массив;
МассивИндикаторов.Добавить(Индикатор);
КонецЕсли;
#Если Клиент Тогда
ТекстСостояния = "";
Для Каждого лИндикатор Из МассивИндикаторов Цикл
Если ТекстСостояния <> "" Тогда
ТекстСостояния = ТекстСостояния + ".>> ";
КонецЕсли;
ТекстСостояния = ТекстСостояния + ПолучитьТекстСостоянияИндикатораЛкс(лИндикатор);
КонецЦикла;
лИндикатор.ТекстСостояния = ТекстСостояния;
Состояние(ТекстСостояния);
#КонецЕсли
КонецЕсли;
КонецПроцедуры // ОбработатьИндикаторЛкс()
Процедура СостояниеЛкс(СтрокаСостояния = "") Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаИндикаторов = ирПлатформа.мТаблицаИндикаторов;
Если ТаблицаИндикаторов.Количество() > 0 Тогда
Индикатор = ТаблицаИндикаторов[ТаблицаИндикаторов.Количество() - 1];
СтрокаСостояния = Индикатор.ТекстСостояния + ".>> " + СтрокаСостояния;
КонецЕсли;
#Если Клиент Тогда
Состояние(СтрокаСостояния);
#КонецЕсли
КонецПроцедуры
#Если Клиент Тогда
Процедура ПодключитьГлобальныйОбработчикОжиданияЛкс(ИмяМетода, Интервал = 0.1, Однократно = Истина) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ирПортативный.ПолучитьФорму().ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина);
Иначе
ПодключитьОбработчикОжидания(ИмяМетода, 0.1, Истина);
КонецЕсли;
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// РАБОТА С ФОРМАМИ
// РежимОткрытия - Булево - Истина - Открытие, иначе Сохранение
Функция ВыбратьФайлЛкс(РежимОткрытия = Истина, Расширение = "", ОписаниеФормата = "", Знач ПолноеИмяФайла = "", Знач Каталог = "", Знач КраткоеИмя = "") Экспорт
Если Не ЗначениеЗаполнено(Расширение) Тогда
Расширение = "*";
КонецЕсли;
Если РежимОткрытия = Истина Тогда
РежимДиалога = РежимДиалогаВыбораФайла.Открытие;
Иначе
РежимДиалога = РежимДиалогаВыбораФайла.Сохранение;
КонецЕсли;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалога);
Если ЗначениеЗаполнено(ПолноеИмяФайла) Тогда
Файл = Новый Файл(ПолноеИмяФайла);
ВыборФайла.Каталог = Файл.Путь;
ВыборФайла.ПолноеИмяФайла = Файл.Имя;
Иначе
ВыборФайла.Каталог = Каталог;
ВыборФайла.ПолноеИмяФайла = КраткоеИмя;
КонецЕсли;
ВыборФайла.Фильтр = ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата);
ВыборФайла.Расширение = Расширение;
Если Не ВыборФайла.Выбрать() Тогда
Возврат Неопределено;
КонецЕсли;
Возврат ВыборФайла.ПолноеИмяФайла;
КонецФункции
Процедура ПолучитьМассивЗначенийПеретаскиванияЛкс(Знач ПараметрыПеретаскивания, выхМассивЗначений, выхТипЗначенияПеретаскивания = Неопределено) Экспорт
ЗначениеПеретаскивания = ПараметрыПеретаскивания.Значение;
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания);
Если выхТипЗначенияПеретаскивания = Тип("Массив") Тогда
выхТипЗначенияПеретаскивания = ТипЗнч(ЗначениеПеретаскивания[0]);
выхМассивЗначений = ЗначениеПеретаскивания;
Иначе
выхМассивЗначений = Новый Массив;
выхМассивЗначений.Добавить(ЗначениеПеретаскивания);
КонецЕсли;
КонецПроцедуры
// Параметры:
// КлючеваяКолонка - Строка - используется при отборе
Процедура ИзменитьПометкиВыделенныхСтрокЛкс(Знач ТабличноеПоле, ИмяКолонкиПометки = "Пометка", НовоеЗначениеПометки = Истина, КлючеваяКолонка = "НомерСтроки", СтруктураОтбора = Неопределено) Экспорт
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() <= 1 Тогда
ВыделенныеСтроки = ТабличноеПоле.Значение;
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Или СтруктураОтбора <> Неопределено Тогда
Построитель = ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора);
#Если _ Тогда
Построитель = Новый ПостроительЗапроса;
#КонецЕсли
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить(КлючеваяКолонка);
НомераОтобранныхСтрок = Построитель.Результат.Выгрузить();
НомераОтобранныхСтрок.Индексы.Добавить(КлючеваяКолонка);
КонецЕсли;
КонецЕсли;
Для каждого Строка из ВыделенныеСтроки Цикл
Если Истина
И НомераОтобранныхСтрок <> Неопределено
И НомераОтобранныхСтрок.Найти(Строка[КлючеваяКолонка], КлючеваяКолонка) = Неопределено
Тогда
Продолжить;
КонецЕсли;
Строка[ИмяКолонкиПометки] = НовоеЗначениеПометки;
КонецЦикла;
КонецПроцедуры
Функция ВыбратьСсылкуЛкс(ПолноИмяИлиОбъектМД, НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт
Если ТипЗнч(ПолноИмяИлиОбъектМД) = Тип("ОбъектМетаданных") Тогда
ПолноИмяМД = ПолноИмяИлиОбъектМД.ПолноеИмя();
Иначе
ПолноИмяМД = ПолноИмяИлиОбъектМД;
КонецЕсли;
Результат = ОткрытьФормуСпискаЛкс(ПолноИмяМД,, ИспользоватьДинамическийСписокИР,, Истина,, НачальноеЗначениеВыбора, Истина);
Возврат Результат;
КонецФункции
Процедура ВыбратьИЗаполнитьТабличнуюЧастьОбъектаБДЛкс(ТаблицаИсточник, НачальноеПолноеИмяОбъекта = "") Экспорт
ФормаВыбораОбъектаБД = ирОбщий.ПолучитьФормуВыбораОбъектаМетаданныхЛкс(,, НачальноеПолноеИмяОбъекта,, Истина,, Истина, Истина,, Истина,,, Истина);
РезультатВыбора = ФормаВыбораОбъектаБД.ОткрытьМодально();
Если РезультатВыбора = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектМД = ирОбщий.НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(РезультатВыбора.ПолноеИмяОбъекта);
ЭтоНаборЗаписей = ирОбщий.ЛиРегистровыйОбъектМетаданных(ОбъектМД);
Если ЭтоНаборЗаписей Тогда
ПолноеИмяМДСписка = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмяМДСписка = ОбъектМД.Родитель().ПолноеИмя();
КонецЕсли;
МакетныйОбъект = Неопределено;
ТекущаяГруппаТипаМетаданных = Неопределено;
ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяМДСписка, МакетныйОбъект, ТекущаяГруппаТипаМетаданных);
Если ЭтоНаборЗаписей Тогда
ОбъектБД = МакетныйОбъект;
ТаблицаПриемник = ОбъектБД;
Иначе
ВыбраннаяСтрока = ОткрытьФормуСпискаЛкс(ПолноеИмяМДСписка,,,, Истина,,, Истина);
Если ВыбраннаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ОбъектБД = ирОбщий.ПолучитьОбъектДанныхИзСтрокиРезультатаЗапросаЛкс(ВыбраннаяСтрока, МакетныйОбъект, ТекущаяГруппаТипаМетаданных, Истина);
ТаблицаПриемник = ОбъектБД[ОбъектМД.Имя];
КонецЕсли;
Если ТаблицаПриемник.Количество() > 0 Тогда
Если ЭтоНаборЗаписей Тогда
ТекстВопроса = "Хотите очистить набор записей в памяти перед заполнением?";
Иначе
ТекстВопроса = "Выбранная табличная часть объекта не пустая. Хотите очистить ее в памяти перед заполнением?";
КонецЕсли;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТаблицаПриемник.Очистить();
КонецЕсли;
КонецЕсли;
ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник);
ОбработкаРедактора = ирОбщий.ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД");
#Если _ Тогда
ОбработкаРедактора = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
ФормаРедактора = ОбработкаРедактора.РедактироватьМодифицированныйОбъект(ОбъектБД);
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(РезультатВыбора.ПолноеИмяОбъекта);
КонецПроцедуры
// <Описание процедуры>
//
// Параметры:
// <Параметр1> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>;
// <Параметр2> <Тип.Вид> <описание параметра>
// <продолжение описания параметра>.
//
Функция СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(Значение1, Значение2, Модально = Ложь,
Название1 = Неопределено, Название2 = Неопределено, СравнениеФайлов = Неопределено, ПолучатьXMLПредставлениеДляНеизвестныхТипов = Истина) Экспорт
Путь1 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение1, Название1, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
Путь2 = ПолучитьФайлЗначенияДляИнтерактивногоСравненияЛкс(Значение2, Название2, ПолучатьXMLПредставлениеДляНеизвестныхТипов);
// Думал, так будет использовать существующее окно, но этого не происходит. Пока оставил, может потом появится.
Если СравнениеФайлов = Неопределено Тогда
СравнениеФайлов = Новый СравнениеФайлов;
КонецЕсли;
СравнениеФайлов.ПервыйФайл = Путь1;
СравнениеФайлов.ВторойФайл = Путь2;
СравнениеФайлов.ИгнорироватьПустоеПространство = Ложь;
Если Истина
И ТипЗнч(Значение1) = Тип("ТабличныйДокумент")
И ТипЗнч(Значение2) = Тип("ТабличныйДокумент")
Тогда
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТабличныйДокумент;
Иначе
СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.ТекстовыйДокумент;
КонецЕсли;
Если Модально Тогда
СравнениеФайлов.ПоказатьРазличияМодально();
Иначе
СравнениеФайлов.ПоказатьРазличия();
КонецЕсли;
Возврат СравнениеФайлов.Сравнить();
КонецФункции // СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс()
// Сравнивает табличный документ, полученный из элемента управления с предыдущим.
//
// Параметры:
// СравнительТабличныхДокументов Массив, *Неопределено переменная для хранения предыдущего табличного документа.
// ЭлементУправления ТабличноеПоле, ПолеТабличногоДокумента откуда получаем содержимое.
//
Процедура СравнитьСодержимоеЭлементаУправленияЛкс(МассивИлиКлючСравнения, ЭлементУправления) Экспорт
Если ТипЗнч(МассивИлиКлючСравнения) <> Тип("Массив") Тогда
МассивСравнения = ирКэш.ПолучитьБуферСравненияЛкс(МассивИлиКлючСравнения);
КонецЕсли;
Если МассивСравнения.Количество() = 2 Тогда
МассивСравнения.Удалить(0);
КонецЕсли;
Если ТипЗнч(ЭлементУправления) = Тип("ПолеТекстовогоДокумента") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.ПолучитьТекст());
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ПолеВвода") Тогда
СравниваемыйДокумент = Новый ТекстовыйДокумент;
СравниваемыйДокумент.УстановитьТекст(ЭлементУправления.Значение);
ИначеЕсли ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Тогда
//СравниваемыйДокумент = Новый ТабличныйДокумент;
//лПостроительОтчета = Новый ПостроительОтчета;
//лПостроительОтчета.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЭлементУправления.Значение);
//лПостроительОтчета.ЗаполнитьНастройки();
//Если лПостроительОтчета.ВыбранныеПоля.Количество() = 0 Тогда
// Возврат;
//КонецЕсли;
//лПостроительОтчета.Вывести(СравниваемыйДокумент);
//
//СравниваемыйДокумент = ВывестиТаблицуВТабличныйДокументЛкс(ЭлементУправления.Значение);
//
СравниваемыйДокумент = ВывестиТабличноеПолеКоллекцииВТабличныйДокументЛкс(ЭлементУправления);
//СравниваемыйДокумент.Показать(); // Для отладки
Иначе//Если ТипЗнч(ЭлементУправления) = Тип("ТабличноеПоле") Тогда
СравниваемыйДокумент = ЭлементУправления.ПолучитьОбласть();
КонецЕсли;
МассивСравнения.Добавить(СравниваемыйДокумент);
Если МассивСравнения.Количество() = 2 Тогда
Ответ = Вопрос("Сравнить с предыдущим?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
СравниваемыйДокумент1 = МассивСравнения[0];
СравниваемыйДокумент2 = МассивСравнения[1];
СравнитьЗначенияИнтерактивноЧерезXMLСтрокуЛкс(СравниваемыйДокумент1, СравниваемыйДокумент2);
КонецЕсли;
КонецПроцедуры
Функция ВывестиТабличноеПолеКоллекцииВТабличныйДокументЛкс(Знач ТабличноеПоле) Экспорт
Результат = Новый ТабличныйДокумент;
НомерКолонки = 1;
НомерСтроки = 1;
ОбластьТаблицы = Результат.Область();
ОбластьТаблицы.ЦветРамки = ЦветаСтиля.ЦветРамки;
ОбластьЗаголовков = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
ОбластьЗаголовков.ЦветФона = ТабличноеПоле.ЦветФонаШапки;
ОбластьЗаголовков.ЦветТекста = ТабличноеПоле.ЦветТекстаШапки;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Если Колонка.Видимость Тогда
ОбластьЗаголовка = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ОбластьЗаголовка.ЦветФона = Колонка.ЦветФонаШапки;
ОбластьЗаголовка.ЦветТекста = Колонка.ЦветТекстаШапки;
ОбластьЗаголовка.ШиринаКолонки = Колонка.Ширина;
ОбластьЗаголовка.Текст = Колонка.ТекстШапки;
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЗаголовка, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличноеПоле.Значение.Количество());
Для Каждого СтрокаИсточника Из ТабличноеПоле.Значение Цикл
ОбработатьИндикаторЛкс(Индикатор);
НомерСтроки = НомерСтроки + 1;
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(СтрокаИсточника);
ОбластьСтроки = Результат.Область(НомерСтроки, 0, НомерСтроки, 0);
ЗаполнитьЗначенияСвойств(ОбластьСтроки, ОформлениеСтроки, "Шрифт, ЦветТекста, ЦветФона");
НомерКолонки = 1;
Для Каждого Колонка Из ТабличноеПоле.Колонки Цикл
Если Колонка.Видимость Тогда
ОформлениеЯчейки = ОформлениеСтроки.Ячейки[Колонка.Имя];
ОбластьЯчейки = Результат.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
ЗаполнитьЗначенияСвойств(ОбластьЯчейки, ОформлениеЯчейки, "Шрифт, ЦветТекста, ЦветФона, Текст");
УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(ОбластьЯчейки, ТабличноеПоле);
НомерКолонки = НомерКолонки + 1;
КонецЕсли;
КонецЦикла;
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
Возврат Результат;
КонецФункции
Процедура УстановитьГраницыОбластиТабличногоДокументаИзТабличногоПоляЛкс(Знач ОбластьЯчейки, Знач ЭлементУправления) Экспорт
ЛинияСплошная = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная);
Если ЭлементУправления.ГоризонтальныеЛинии Тогда
ОбластьЯчейки.ГраницаСверху = ЛинияСплошная;
ОбластьЯчейки.ГраницаСнизу = ЛинияСплошная;
КонецЕсли;
Если ЭлементУправления.ВертикальныеЛинии Тогда
ОбластьЯчейки.ГраницаСлева = ЛинияСплошная;
ОбластьЯчейки.ГраницаСправа = ЛинияСплошная;
КонецЕсли;
КонецПроцедуры // ЛксСравнитьСодержимоеПоля()
Процедура ВвестиИУстановитьШиринуКолонокТабличногоПоляЛкс(ТабличноеПоле) Экспорт
ВведенноеЗначениеШирины = 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, КонецСтроки, КонецКолонки);
Элемент.ВыделенныйТекст = Элемент.ВыделенныйТекст;
Элемент.УстановитьГраницыВыделения(НачалоСтроки, НачалоКолонки, КонецСтроки, КонецКолонки);
КонецФункции
///////////////////////////////////////////////////////
// Выпуск портативных ИР
Функция ПоказатьТабличныйДокументИзОбщихКартинокПодсистемыЛкс() Экспорт
ТабличныйДокумент = Новый ТабличныйДокумент;
ШрифтЖирный = Новый Шрифт(,,Истина);
ТабличныйДокумент.Область("R1C1:R1C1").Текст = "Имя";
ТабличныйДокумент.Область("R1C2:R1C2").Текст = "Картинка";
ТабличныйДокумент.Область("R1C1:R1C2").Шрифт = ШрифтЖирный;
Для Каждого ОбщаяКартинка Из Метаданные.ОбщиеКартинки Цикл
Если Не Метаданные.Подсистемы.ИнструментыРазработчика.Состав.Содержит(ОбщаяКартинка) Тогда
Продолжить;
КонецЕсли;
Рисунок = ТабличныйДокумент.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
Рисунок.Картинка = БиблиотекаКартинок[ОбщаяКартинка.Имя];
Рисунок.Имя = ОбщаяКартинка.Имя;
Рисунок.РазмерКартинки = РазмерКартинки.РеальныйРазмер;
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы + 1;
ТабличныйДокумент.Область("R" + XMLСтрока(ВысотаТаблицы) + "C1:R" + XMLСтрока(ВысотаТаблицы) + "C1").Текст = ОбщаяКартинка.Имя;
Рисунок.Расположить(ТабличныйДокумент.Область("R" + XMLСтрока(ВысотаТаблицы) + "C2:R" + XMLСтрока(ВысотаТаблицы) + "C2"));
КонецЦикла;
ТабличныйДокумент.Показать("ОбщиеКартинки");
КонецФункции
Функция СгенерироватьМодульИнициализацииФормПодсистемыДляПортативногоРежимаЛкс() Экспорт
ТекстМодуля = Новый ЗаписьXML;
ТекстМодуля.УстановитьСтроку("");
//ТекстМодуля.ЗаписатьБезОбработки("
//|Перем ирОбщий Экспорт;
//|Перем ирСервер Экспорт;
//|Перем ирКэш Экспорт;
//|Перем ирПривилегированный Экспорт;
//|Перем ирПортативный Экспорт;
//|
//|Перем ирПлатформа Экспорт;
//|");
мПлатформа = ирКэш.Получить();
#Если _ Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
ТипыМетаданных = мПлатформа.ПолучитьТаблицуТиповМетаОбъектов(Истина, Ложь, Ложь);
ИндикаторТиповМетаданных = ПолучитьИндикаторПроцессаЛкс(ТипыМетаданных.Количество(), "Типы метаданных");
Для Каждого СтрокаТипаМетаданных Из ТипыМетаданных Цикл
ОбработатьИндикаторЛкс(ИндикаторТиповМетаданных);
Если СтрокаТипаМетаданных.Единственное = "Перерасчет" Тогда
КоллекцияМетаОбъектов = Новый Массив;
Для Каждого МетаРегистрРасчета Из Метаданные.РегистрыРасчета Цикл
Для Каждого Перерасчет Из МетаРегистрРасчета.Перерасчеты Цикл
КоллекцияМетаОбъектов.Добавить(Перерасчет);
КонецЦикла;
КонецЦикла;
Иначе
КоллекцияМетаОбъектов = Метаданные[СтрокаТипаМетаданных.Множественное];
КонецЕсли;
Индикатор2 = ПолучитьИндикаторПроцессаЛкс(КоллекцияМетаОбъектов.Количество(), СтрокаТипаМетаданных.Множественное);
Для Каждого МетаОбъект Из КоллекцияМетаОбъектов Цикл
Если Не Метаданные.Подсистемы.ИнструментыРазработчика.Состав.Содержит(МетаОбъект) Тогда
Продолжить;
КонецЕсли;
ОбработатьИндикаторЛкс(Индикатор2);
Попытка
МетаФормы = МетаОбъект.Формы;
Исключение
Продолжить;
КонецПопытки;
МенеджерОбъектаМетаданных = ПолучитьМенеджерЛкс(МетаОбъект);
Индикатор3 = ПолучитьИндикаторПроцессаЛкс(МетаФормы.Количество(), "Формы");
Для Каждого МетаФорма Из МетаФормы Цикл
ОбработатьИндикаторЛкс(Индикатор3);
ПолноеИмяФормы = МетаФорма.ПолноеИмя();
Сообщить(ПолноеИмяФормы);
//ПолноеИмяФормы = МетаОбъект.ПолноеИмя() + ".Форма." + МетаФорма.Имя;
Попытка
//Форма = ПолучитьФорму(ПолноеИмяФормы); // Так исключение не сработает и будет отображен диалог об ошибке. Особенность платформы
Форма = МенеджерОбъектаМетаданных.ПолучитьФорму(МетаФорма.Имя,,Новый УникальныйИдентификатор());
Исключение
Сообщить("Ошибка при получении формы " + ПолноеИмяФормы + ": " + ОписаниеОшибки());
Продолжить;
КонецПопытки;
ТелоМетода = Новый ЗаписьXML;
ТелоМетода.УстановитьСтроку("");
ПроверитьСвойстваОбъектаДляПортативногоРежимаЛкс("ЭтаФорма", Форма, ТелоМетода);
ТелоМетода = ТелоМетода.Закрыть();
ТекстМодуля.ЗаписатьБезОбработки("
|Процедура ИнициализироватьФорму_" + мПлатформа.ПолучитьИдентификаторИзПредставления(ПолноеИмяФормы) + "(ЭтаФорма) Экспорт
|
|" + ТелоМетода + "
|КонецПроцедуры
|");
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
КонецЦикла;
ОсвободитьИндикаторПроцессаЛкс();
Результат = ТекстМодуля.Закрыть();
Возврат Результат;
КонецФункции
Процедура ПроверитьСвойстваОбъектаДляПортативногоРежимаЛкс(ПутьКОбъекту, Объект, ТелоМетода)
мПлатформа = ирКэш.Получить();
#Если _ Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтруктураТипа = мПлатформа.ПолучитьСтруктуруТипаИзЗначения(Объект);
ВнутренняяТаблицаСлов = мПлатформа.ПолучитьТаблицуСловСтруктурыТипа(СтруктураТипа);
Для Каждого ВнутренняяСтрокаСлова Из ВнутренняяТаблицаСлов Цикл
Если ВнутренняяСтрокаСлова.ТипСлова = "Свойство" Тогда
ИмяСвойства = ВнутренняяСтрокаСлова.Слово;
Если Ложь
Или ИмяСвойства = "ИсточникДействий"
Или ИмяСвойства = "КонтекстноеМеню"
Тогда
// Защита от длинных путей и зацикливания
Продолжить;
КонецЕсли;
Попытка
Структура = Новый Структура(ИмяСвойства);
Исключение
// "КартинкаКнопкиВыбора#&^@^%&*^#1"
Продолжить;
КонецПопытки;
Попытка
ЗаполнитьЗначенияСвойств(Структура, Объект);
Исключение
// Не всегда доступное свойство
Продолжить;
КонецПопытки;
ЗначениеСвойства = Структура[ИмяСвойства];
Если ТипЗнч(ЗначениеСвойства) = Тип("Картинка") Тогда
Если ЗначениеСвойства.Вид = ВидКартинки.ИзБиблиотеки Тогда
ИмяОбщейКартинки = СериализаторXDTO.записатьXDTO(ЗначениеСвойства).ref.ЛокальноеИмя;
Если Метаданные.ОбщиеКартинки.Найти(ИмяОбщейКартинки) <> Неопределено Тогда
ТелоМетода.ЗаписатьБезОбработки(Символы.Таб + ПутьКОбъекту + "." + ИмяСвойства + " = ирОбщий.ПолучитьОбщуюКартинкуЛкс("""
+ ИмяОбщейКартинки + """);" + Символы.ПС);
КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Цвет") Тогда
ИмяЦветаСтиля = СериализаторXDTO.записатьXDTO(ЗначениеСвойства).ЛексическоеЗначение;
ПозицияСкобки = Найти(ИмяЦветаСтиля, "}");
Если ПозицияСкобки > 0 Тогда
ИмяЦветаСтиля = Сред(ИмяЦветаСтиля, ПозицияСкобки + 1);
Если Метаданные.ЭлементыСтиля.Найти(ИмяЦветаСтиля) <> Неопределено Тогда
ТелоМетода.ЗаписатьБезОбработки(Символы.Таб + ПутьКОбъекту + "." + ИмяСвойства + " = ирОбщий.ПолучитьЦветСтиляЛкс("""
+ ИмяЦветаСтиля + """);" + Символы.ПС);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если мПлатформа.мМассивТиповЭлементовУправления.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда
ПроверитьСвойстваОбъектаДляПортативногоРежимаЛкс(ПутьКОбъекту + "." + ИмяСвойства, ЗначениеСвойства, ТелоМетода);
КонецЕсли;
Если ЭтоКоллекцияЛкс(ЗначениеСвойства) Тогда
ЕстьИндексПоИмени = Ложь;
Для Каждого ЭлементКоллекции Из ЗначениеСвойства Цикл
Если Не ЕстьИндексПоИмени Тогда
Попытка
Пустышка = Вычислить("ЗначениеСвойства." + ЭлементКоллекции.Имя);
Исключение
// Если к элементу по имени нельзя обратиться, то он нас не интересует.
Прервать;
КонецПопытки;
КонецЕсли;
ЕстьИндексПоИмени = Истина;
Если Ложь
Или мПлатформа.мМассивТиповЭлементовУправления.Найти(ТипЗнч(ЭлементКоллекции)) <> Неопределено
Или ТипЗнч(ЭлементКоллекции) = Тип("КнопкаКоманднойПанели")
Тогда
ПроверитьСвойстваОбъектаДляПортативногоРежимаЛкс(ПутьКОбъекту + "." + ИмяСвойства + "." + ЭлементКоллекции.Имя, ЭлементКоллекции, ТелоМетода);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецЕсли
//Для Объект = Неопределено возвращает Ложь, работает только для русского и английского языков платформы
// Параметры:
// КоличествоПараметров - нужно задать заведомо большее значение, чем может быть у метода
Функция МетодРеализованЛкс(Объект, ИмяМетода, КоличествоПараметров = 100) Экспорт
Если Объект = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Выражение = "Объект." + ИмяМетода + "(" + ПолучитьСтрокуПовторомЛкс(",", КоличествоПараметров) + ")";
Попытка
Выполнить(Выражение);
Исключение
Инфо = ИнформацияОбОшибке();
Описание = Инфо.Описание;
//Сообщить(Описание);
КонецПопытки;
Результат = Ложь
Или Описание = "Слишком много фактических параметров"
Или Описание = "Too many actual parameters";
Возврат Результат;
КонецФункции
// Параметры:
// КоличествоПроходов - Число(Н8,0)
// КлючЗамера - Строка
// ВыдатьСообщение - Булево
//
Функция НачатьЗамерЛкс(Знач КоличествоПроходов = 1, Знач КлючЗамера = "", Знач ВыдатьСообщение = Ложь) Экспорт
ирПлатформа = ирКэш.Получить();
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
КлючЗамера = "Замер" + ТаблицаЗамеров.Колонки[0].Имя;
КонецЕсли;
ТаблицаЗамеров.Колонки[0].Имя = "_" + XMLСтрока(Число(Сред(ТаблицаЗамеров.Колонки[0].Имя, 2)) + 1);
СтрокаЗамера = ТаблицаЗамеров.Добавить();
СтрокаЗамера.Ключ = КлючЗамера;
#Если Клиент Тогда
СтрокаЗамера.Отладчик = ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено;
#КонецЕсли
СтрокаЗамера.КоличествоПроходов = КоличествоПроходов;
Если Ложь
Или ВыдатьСообщение
//Или СтрокаЗамера.Отладчик
Тогда
Сообщение = "Начало замера """ + СтрокаЗамера.Ключ + """, количество проходов = " + КоличествоПроходов;
Если СтрокаЗамера.Отладчик Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
Сообщить(Сообщение);
КонецЕсли;
СтрокаЗамера.ДатаНачала = ПолучитьТекущееВремяВМиллисекундахЛкс();
Результат = КоличествоПроходов;
Возврат Результат;
КонецФункции
// Параметры:
// КлючЗамера - Строка - По умолчанию последний замер
//
Функция КончитьЗамерЛкс(Знач КлючЗамера = "") Экспорт
ТекущееВремя = ПолучитьТекущееВремяВМиллисекундахЛкс();
ирПлатформа = ирКэш.Получить();
ТаблицаЗамеров = ирПлатформа.мТаблицаЗамеров;
Если Не ЗначениеЗаполнено(КлючЗамера) Тогда
Если ТаблицаЗамеров.Количество() > 0 Тогда
СтрокаЗамера = ТаблицаЗамеров[ТаблицаЗамеров.Количество() - 1];
КонецЕсли;
Иначе
СтрокаЗамера = ТаблицаЗамеров.Найти(КлючЗамера, "Ключ");
КонецЕсли;
Если СтрокаЗамера = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Длительность = ТекущееВремя - СтрокаЗамера.ДатаНачала;
Длительность = Длительность / 1000;
Сообщение = "Окончание замера """ + СтрокаЗамера.Ключ + """ - Длительность = " + XMLСтрока(Длительность) + "с";
Если СтрокаЗамера.КоличествоПроходов > 1 Тогда
Среднее = Длительность / СтрокаЗамера.КоличествоПроходов;
Сообщение = Сообщение + ", Среднее = " + XMLСтрока(Среднее) + "с";
КонецЕсли;
Если Ложь
Или СтрокаЗамера.Отладчик
Или ирПлатформа.ПолучитьИдентификаторПроцессаОтладчика() <> Неопределено
Тогда
Сообщение = Сообщение + ". Отладчик подключен и неравномерно замедляет выполнение кода!";
КонецЕсли;
Сообщить(Сообщение);
ТаблицаЗамеров.Удалить(СтрокаЗамера);
Результат = Длительность;
Возврат Результат;
КонецФункции
Функция ПолучитьПостроительТабличногоПоляСОтборомКлиентаЛкс(ТабличноеПоле, СтруктураОтбора = Неопределено) Экспорт
ВременнныйПостроительЗапроса = Новый ПостроительЗапроса;
ВременнныйПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличноеПоле.Значение);
Попытка
ОтборСтрок = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Если ОтборСтрок <> Неопределено Тогда
СкопироватьОтборЛкс(ВременнныйПостроительЗапроса.Отбор, ОтборСтрок, Истина);
КонецЕсли;
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ВременнныйПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ).Установить(КлючИЗначение.Значение);
КонецЦикла;
КонецЕсли;
Возврат ВременнныйПостроительЗапроса;
КонецФункции
Функция ПолучитьСтруктуруВыделенияТекстаЛкс() Экспорт
Структура = Новый Структура();
Структура.Вставить("НачальнаяСтрока");
Структура.Вставить("НачальнаяКолонка");
Структура.Вставить("КонечнаяСтрока");
Структура.Вставить("КонечнаяКолонка");
Возврат Структура;
КонецФункции
Функция ПолеТекстаолучитьДиапазонВыделенияЛкс(ПолеТекста) Экспорт
СтруктуруВыделения = ПолучитьСтруктуруВыделенияТекстаЛкс();
ПолеТекста.ПолучитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка,
СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка);
Возврат СтруктуруВыделения;
КонецФункции
Функция ПолеТекста_УстановитьДиапазонВыделенияЛкс(Знач ПолеТекста, Знач СтруктуруВыделения) Экспорт
ПолеТекста.УстановитьГраницыВыделения(СтруктуруВыделения.НачальнаяСтрока, СтруктуруВыделения.НачальнаяКолонка,
СтруктуруВыделения.КонечнаяСтрока, СтруктуруВыделения.КонечнаяКолонка);
Возврат Неопределено;
КонецФункции
// Копирует таблицу значений из исходной таблицы значений с удалением типа Null из описаний типов колонок.
// Параметры:
// ОбработатьТолькоКолонки - Строка - имена колонок разделенные запятыми
// НеОбрабатыватьКолонки - Строка - имена колонок разделенные запятыми
//
// Возвращаемое значение:
// ТаблицаЗначений
//
Функция ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(Знач Таблица, ЗагружатьДанныеВНовуюТаблицу = Истина, ОбрабатыватьТолькоКолонки = "", НеОбрабатыватьКолонки = "") Экспорт
Результат = Новый ТаблицаЗначений;
НовыеКолонки = Результат.Колонки;
ИсходныеКолонки = Таблица.Колонки;
ИменаОбрабатываемыхКолонок = Новый Массив();
Если ОбрабатыватьТолькоКолонки <> "" Тогда
ИменаОбрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОбрабатыватьТолькоКолонки, ",", Истина);
КонецЕсли;
ИменаНеобрабатываемыхКолонок = Новый Массив();
Если НеОбрабатыватьКолонки <> "" Тогда
ИменаНеобрабатываемыхКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(НеОбрабатыватьКолонки, ",", Истина);
КонецЕсли;
Для Каждого Колонка Из ИсходныеКолонки Цикл
Если Ложь
Или (Истина
И ОбрабатыватьТолькоКолонки <> ""
И ИменаОбрабатываемыхКолонок.Найти(Колонка.Имя) = Неопределено)
Или (Истина
И НеОбрабатыватьКолонки <> ""
И ИменаНеобрабатываемыхКолонок.Найти(Колонка.Имя) <> Неопределено)
Тогда
ОписаниеТипов = Колонка.ТипЗначения;
Иначе
ОписаниеТипов = Новый ОписаниеТипов(Колонка.ТипЗначения, , "NULL");
КонецЕсли;
НовыеКолонки.Добавить(Колонка.Имя, ОписаниеТипов, Колонка.Заголовок, Колонка.Ширина);
КонецЦикла;
Если ЗагружатьДанныеВНовуюТаблицу Тогда
ЗагрузитьВТаблицуЗначенийЛкс(Таблица, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиСсылочныйОбъектМетаданных(ОбъектМД, ДляТабличнойЧастиПроверятьРодителя = Истина) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Истина
И Не ДляТабличнойЧастиПроверятьРодителя
И МассивФрагментов.Количество() > 2
Тогда
Возврат Ложь;
КонецЕсли;
КорневойТип = МассивФрагментов[0];
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
Возврат Истина;
ИначеЕсли Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиРегистровыйОбъектМетаданных(ОбъектМД) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
КорневойТип = МассивФрагментов[0];
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) Тогда
Возврат Истина;
ИначеЕсли Истина
И МассивФрагментов.Количество() = 4
И КорневойТип = "ВнешнийИсточникДанных"
Тогда
Возврат (ОбъектМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.НеобъектныеДанные);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ЛиТипВнешнегоИсточникаДанных(Метаданные) Экспорт
Если ТипЗнч(Метаданные) <> Тип("Строка") Тогда
ПолноеИмя = Метаданные.ПолноеИмя();
Иначе
ПолноеИмя = Метаданные;
КонецЕсли;
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмя);
Возврат КорневойТип = "ВнешнийИсточникДанных";
КонецФункции
Функция ПолучитьИмяТипаИзМетаданныхЛкс(ОбъектМД, Расширение = "Ссылка") Экспорт
Если ТипЗнч(ОбъектМД) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Фрагменты.Количество() = 4 Тогда
СтрокаТипа = Фрагменты[0] + Фрагменты[2] + Расширение + "." + Фрагменты[1] + "." + Фрагменты[3];
Иначе
СтрокаТипа = Фрагменты[0] + Расширение + "." + Фрагменты[1];
КонецЕсли;
Возврат СтрокаТипа;
КонецФункции // ПолучитьИмяТипаИзМетаданныхЛкс()
Функция ПолучитьИмяТаблицыИзМетаданныхЛкс(Знач ОбъектМД, ЛиТаблицаИзменений = Ложь, ЛиДвиженияССубконтоДляРегистраБухгалтерии = Истина,
ТолькоРазрешенные = Ложь) Экспорт
Если ТипЗнч(ОбъектМД) <> Тип("Строка") Тогда
ПолноеИмя = ОбъектМД.ПолноеИмя();
Иначе
ПолноеИмя = ОбъектМД;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если ТолькоРазрешенные Тогда
Если ТипЗнч(ОбъектМД) = Тип("Строка") Тогда
Если Фрагменты.Количество() > 1 Тогда
ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]); // очень долгая операция, поэтому лучше не устанавливать флаг ТолькоРазрешенные
Иначе
//ОбъектМД = Метаданные[Фрагменты[0]];
ОбъектМД = Неопределено;
КонецЕсли;
КонецЕсли;
Если Истина
И ОбъектМД <> Неопределено
И Не ПравоДоступа("Чтение", ОбъектМД)
Тогда
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
Если Истина
И Фрагменты[0] = "Константа"
И Фрагменты.Количество() = 2
И Не ЛиТаблицаИзменений
Тогда
Если Не ирКэш.ИндивидуальныеТаблицыКонстантДоступныЛкс() Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс("Константы");
КонецЕсли;
КонецЕсли;
Если Фрагменты.Количество() = 4 Тогда
Если Ложь
Или СтрокиРавныЛкс(Фрагменты[2], "ТабличнаяЧасть")
Или СтрокиРавныЛкс(Фрагменты[2], "Перерасчет")
//Или СтрокиРавныЛкс(Фрагменты[2], "Таблица")
Тогда
Фрагменты.Удалить(2);
КонецЕсли;
КонецЕсли;
ИмяТаблицы = ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
Если Истина
И ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмя)
И Не ЛиТаблицаИзменений
И ЛиДвиженияССубконтоДляРегистраБухгалтерии
Тогда
ИмяТаблицы = ИмяТаблицы + ".ДвиженияССубконто";
КонецЕсли;
Если ЛиТаблицаИзменений Тогда
ИмяТаблицы = ИмяТаблицы + ".Изменения";
КонецЕсли;
Возврат ИмяТаблицы;
КонецФункции // ПолучитьИмяТаблицыИзМетаданныхЛкс()
Функция ПолучитьОпределениеТаблицыБДДляИЗЛкс(ИмяТаблицы) Экспорт
Результат = ИмяТаблицы;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ИмяТаблицы);
Если ТипТаблицы = "ДвиженияССубконто" Тогда
Результат = Результат + "(,, {Регистратор.*, НомерСтроки, Активность})";
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьМакетныйОбъектДанныхТаблицыБДЛкс(ПолноеИмяТаблицы, выхМакетныйОбъект, выхТекущаяГруппаТипаМетаданных = Неопределено, выхКлючевыеПоля = Неопределено) Экспорт
выхКлючевыеПоля = Новый Массив;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Объект."));
выхТекущаяГруппаТипаМетаданных = "Ссылочный";
выхКлючевыеПоля.Добавить("Ссылка");
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
выхМакетныйОбъект = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицы);
выхТекущаяГруппаТипаМетаданных = "Регистр";
Для Каждого ЭлементОтбора Из выхМакетныйОбъект.Отбор Цикл
выхКлючевыеПоля.Добавить(ЭлементОтбора.ПутьКДанным);
КонецЦикла;
Иначе
выхМакетныйОбъект = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "МенеджерЗначения."));
выхТекущаяГруппаТипаМетаданных = "Константа";
КонецЕсли;
КонецПроцедуры
Функция ЛиПолноеИмяРегистраБухгалтерииЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Результат = Истина
И Фрагменты.Количество() = 2
И (Ложь
Или Фрагменты[0] = "AccountingRegister"
Или Фрагменты[0] = "РегистрБухгалтерии");
Возврат Результат;
КонецФункции
// Создает тип из метаданных.
//
// Параметры:
// Метаданные ОбъектМетаданных;
// *Расширение - Строка, "Ссылка" - расширение типа.
//
// Возвращаемое значение:
// Тип.
//
Функция ПолучитьТипИзМетаданныхЛкс(ОбъектМД, Расширение = "Ссылка") Экспорт
Возврат Тип(ПолучитьИмяТипаИзМетаданныхЛкс(ОбъектМД, Расширение));
КонецФункции // ПолучитьТипИзМетаданных()
Функция ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Экспорт
ЭлементСостава = ОбщийРеквизит.Состав.Найти(ОбъектМетаданных);
Результат = Истина
И ЭлементСостава <> Неопределено
И (Ложь
Или ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Использовать
Или (Истина
И ЭлементСостава.Использование = Метаданные.СвойстваОбъектов.ИспользованиеОбщегоРеквизита.Авто
И ОбщийРеквизит.АвтоИспользование = Метаданные.СвойстваОбъектов.АвтоИспользованиеОбщегоРеквизита.Использовать));
Возврат Результат;
КонецФункции
Функция ПолучитьАлгоритмОбъектПоИдентификаторуЛкс(Знач Алгоритм) Экспорт
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = "" + Алгоритм;
Если Найти(Алгоритм, "-") > 0 Тогда
// Передан GUID
Алгоритм = Справочники.ирАлгоритмы.ПолучитьСсылку(Новый УникальныйИдентификатор(Алгоритм));
Иначе
// Передано имя алгоритма
Попытка
Алгоритм = ПредопределенноеЗначение("Справочник.ирАлгоритмы." + Алгоритм);
Исключение
КонецПопытки;
Если ТипЗнч(Алгоритм) <> Тип("СправочникСсылка.ирАлгоритмы") Тогда
Алгоритм = Справочники.ирАлгоритмы.НайтиПоНаименованию(Алгоритм, Истина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Алгоритм) Тогда
ВызватьИсключение "Алгоритм по идентификатору """ + Алгоритм + """ не найден";
КонецЕсли;
Возврат Алгоритм.ПолучитьОбъект();
КонецФункции
//Если объекту не назначена ссылка, назначает эту ссылку
Функция ПолучитьТочнуюСсылкуОбъектаЛкс(ОбъектБД) Экспорт
Ссылка = ОбъектБД.Ссылка;
Если Ссылка.Пустая() Тогда
Ссылка = ОбъектБД.ПолучитьСсылкуНового();
Если Ссылка.Пустая() Тогда
Ссылка = XMLЗначение(ТипЗнч(Ссылка), "" + Новый УникальныйИдентификатор);
ОбъектБД.УстановитьСсылкуНового(Ссылка);
КонецЕсли;
КонецЕсли;
Возврат Ссылка;
КонецФункции
Функция ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(Знач Текст) Экспорт
Текст = Символы.ПС + Текст;
Текст = СтрЗаменить(Текст, Символы.ПС, Символы.ПС + "|");
Текст = СтрЗаменить(Текст, """", """""");
Текст = """" + Текст + """";
Возврат Текст;
КонецФункции // ПолучитьСтроковыйЛитералИзМногострочногоТекста()
Функция ПолучитьВсеСтрокиДереваЗначенийЛкс(СтрокаИлиДеревоЗначений) Экспорт
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ДеревоЗначений = СтрокаИлиДеревоЗначений.Владелец();
Иначе
ДеревоЗначений = СтрокаИлиДеревоЗначений;
КонецЕсли;
Идентификатор = "_" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
ДеревоЗначений.Колонки.Добавить(Идентификатор);
ВсеСтроки = СтрокаИлиДеревоЗначений.Строки.НайтиСтроки(Новый Структура(Идентификатор,), Истина);
ДеревоЗначений.Колонки.Удалить(Идентификатор);
Если ТипЗнч(СтрокаИлиДеревоЗначений) = Тип("СтрокаДереваЗначений") Тогда
ВсеСтроки.Добавить(СтрокаИлиДеревоЗначений);
КонецЕсли;
Возврат ВсеСтроки;
КонецФункции // ПолучитьВсеСтрокиДереваЗначений()
Функция СериализацииРавныЛкс(Таблица1, Таблица2) Экспорт
Хмл1 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица1);
Хмл2 = СохранитьОбъектВВидеСтрокиXMLЛкс(Таблица2);
Возврат (Хмл1 = Хмл2);
КонецФункции
// ВариантОбрезания - 1
// ВариантОбрезания - 2
Функция ПолучитьИнформациюОбОшибкеБезВерхнегоМодуляЛкс(ИнформацияОбОшибке = Неопределено, ВариантОбрезания = 2) Экспорт
Если ИнформацияОбОшибке = Неопределено Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
КонецЕсли;
Если ВариантОбрезания = 1 Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ИнформацияОбОшибке.Причина <> Неопределено Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
ИначеЕсли Истина
И ВариантОбрезания = 2
И ИнформацияОбОшибке.Причина <> Неопределено
Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
Иначе
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// МаксимальнаяГлубинаПричины - на сколько уровней вниз надо опуститься, пока есть вложенная причина
Функция ПредставлениеИнформацииОбОшибкеЛкс(Знач ИнформацияОбОшибке, Знач МаксимальнаяГлубинаПричины = 0, УбратьСтрокуКодаСПервогоУровня = Ложь) Экспорт
#Если _ Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
ОписаниеОшибки = "";
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
Для Счетчик = 1 По МаксимальнаяГлубинаПричины Цикл
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке.Причина;
#Если _ Тогда
ИнформацияОбОшибке = ИнформацияОбОшибке();
#КонецЕсли
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
Если УбратьСтрокуКодаСПервогоУровня Тогда
ОписаниеОшибки = ИнформацияОбОшибке.Описание;
Если ТипЗнч(ИнформацияОбОшибке.Причина) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ОписаниеОшибки + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке.Причина);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ОписаниеОшибки) Тогда
Если ТипЗнч(ИнформацияОбОшибке) = Тип("ИнформацияОбОшибке") Тогда
ОписаниеОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
Иначе
// Такое может случаться в свойстве ИнформацияОбОшибке объекта ФоновоеЗадание из-за ошибки платформы
ОписаниеОшибки = "Описание ошибки отсутствует";
КонецЕсли;
КонецЕсли;
Возврат ОписаниеОшибки;
КонецФункции
// Первая строка табличного документа содержит заголовки
Функция ПолучитьТаблицуИзТабличногоДокументаЛкс(Знач ТабличныйДокумент, ЛиПерваяСтрокаСодержитИменаКолонок = Истина, ДлинаСтрокиТипаКолонки = 150,
ВычислятьНетипизированныеЗначения = Ложь, ЛиВтораяСтрокаСодержитТипыЗначений = Ложь) Экспорт
#Если _ Тогда
ТабличныйДокумент = Новый ТабличныйДокумент
#КонецЕсли
ТаблицаПриемник = Новый ТаблицаЗначений;
НачальнаяСтрока = 1;
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
НачальнаяСтрока = НачальнаяСтрока + 1;
КонецЕсли;
ТипизированныеКолонки = Новый Соответствие;
Для Счетчик = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Если ЛиПерваяСтрокаСодержитИменаКолонок Тогда
ИмяКолонки = ТабличныйДокумент.Область(1, Счетчик).Текст;
Иначе
ИмяКолонки = "Колонка" + Счетчик;
КонецЕсли;
Если ЛиВтораяСтрокаСодержитТипыЗначений Тогда
ИменаТипов = ТабличныйДокумент.Область(2, Счетчик).Текст;
ТипизированныеКолонки[Счетчик] = 1;
Иначе
ИменаТипов = "";
КонецЕсли;
ТаблицаПриемник.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов(ИменаТипов));
КонецЦикла;
// Цикл перебора строк табличного документа
ВысотаТаблицы = ТабличныйДокумент.ВысотаТаблицы;
//Индикатор = ПолучитьИндикаторПроцессаЛкс(ТабличныйДокумент.ВысотаТаблицы);
Для НомерСтроки = НачальнаяСтрока По ВысотаТаблицы Цикл
// Добавление строки результирующей таблицы
НоваяСтрокаТЗ = ТаблицаПриемник.Добавить();
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Область = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ТекстЯчейки = Область.Текст;
Если Не ЗначениеЗаполнено(ТекстЯчейки) Тогда
Поддокумент = ТабличныйДокумент.ПолучитьОбласть(НомерСтроки, НомерКолонки);
Если Поддокумент.Рисунки.Количество() > 0 Тогда
ТекстЯчейки = Поддокумент.Рисунки[0].Картинка;
КонецЕсли;
КонецЕсли;
ЗначениеЯчейки = ТекстЯчейки;
Если Ложь
Или ВычислятьНетипизированныеЗначения
Или ТипизированныеКолонки[НомерКолонки] <> Неопределено
Тогда
Попытка
ЗначениеЯчейки = Вычислить(ЗначениеЯчейки);
Исключение
КонецПопытки;
КонецЕсли;
НоваяСтрокаТЗ[НомерКолонки - 1] = ЗначениеЯчейки;
КонецЦикла;
КонецЦикла;
Возврат ТаблицаПриемник;
КонецФункции
Функция ПолучитьИдентификаторТипаЛкс(Тип) Экспорт
Результат = ПолучитьСтрокуМеждуМаркерамиЛкс("" + ЗначениеВСтрокуВнутр(Тип), ",", "}", Ложь);
Возврат Результат;
КонецФункции
Функция ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(Знач ТекстПрограммы = "") Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
#Если Клиент Тогда
ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс();
#Иначе
ВызватьИсключение "Получение текста из буфера обмена возможно только на клиенте";
#КонецЕсли
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой");
#Если _ Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
ПолеВстроенногоЯзыка.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,,,, Истина, ТекстПрограммы);
СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова, Определение", "Свойство", "Статистический"));
//СтрокиЛокальныхПеременных = ПолеВстроенногоЯзыка.ТаблицаСлов.НайтиСтроки(Новый Структура("ТипСлова", "Свойство"));
Для Каждого СтрокаПеременной Из СтрокиЛокальныхПеременных Цикл
Параметры.Вставить(СтрокаПеременной.Слово);
КонецЦикла;
Возврат Параметры;
КонецФункции
// КолонкиНабора - КоллекцияКолонокДереваЗначений, КоллекцияКолонокТаблицыЗначений, КоллекцияКолонокРезультатаЗапроса
Функция СоздатьИлиОбновитьНаборДанныхОбъектПоМетаданнымЛкс(Знач СхемаКомпоновкиДанных, Знач КолонкиНабора, Знач ИмяНабора = "Основной",
Знач СоздаватьПапкиПолей = Ложь, СоздаватьРесурсыЧисловыхПолей = Ложь) Экспорт
#Если _ Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Результат = СхемаКомпоновкиДанных.НаборыДанных.Найти(ИмяНабора);
Если Результат = Неопределено Тогда
Результат = СхемаКомпоновкиДанных.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
КонецЕсли;
Результат.Имя = ИмяНабора;
Результат.ИсточникДанных = СхемаКомпоновкиДанных.ИсточникиДанных[0].Имя;
Результат.ИмяОбъекта = ИмяНабора;
Для Каждого ЭлементМетаданных Из КолонкиНабора Цикл
Если Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаДереваЗначений")
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаТаблицыЗначений")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("КолонкаРезультатаЗапроса")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ИмяПоля;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ПолеНастройки")
Тогда
ИмяПоля = ЭлементМетаданных.Имя;
ЗаголовокПоля = ЭлементМетаданных.Представление;
ИначеЕсли Ложь
Или ТипЗнч(ЭлементМетаданных) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")
Тогда
ИмяПоля = "" + ЭлементМетаданных.Поле;
ЗаголовокПоля = ЭлементМетаданных.Заголовок;
Иначе
Продолжить;
КонецЕсли;
Поле = Результат.Поля.Найти(ИмяПоля);
Если Поле = Неопределено Тогда
Поле = Результат.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПутьКДанным = ИмяПоля;
Если СоздаватьПапкиПолей Тогда
ПутьКДанным = Результат.Имя + "." + ПутьКДанным;
КонецЕсли;
Поле.ПутьКДанным = ПутьКДанным;
Поле.Поле = ИмяПоля;
Поле.Заголовок = ЗаголовокПоля;
Поле.ТипЗначения = ЭлементМетаданных.ТипЗначения;
Если Истина
И СоздаватьРесурсыЧисловыхПолей
И Поле.ТипЗначения.СодержитТип(Тип("Число"))
Тогда
Ресурс = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
Ресурс.Выражение = "Сумма(" + ИмяПоля + ")";
Ресурс.ПутьКДанным = ИмяПоля;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ЗаполнитьПараметрыСхемыПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос) Экспорт
#Если _ Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
ОписанияПараметров = Запрос.НайтиПараметры(); // Здесь могут быть ложные ошибки синтаксического контроля
Для Каждого ОписаниеПараметра Из ОписанияПараметров Цикл
Если Не Запрос.Параметры.Свойство(ОписаниеПараметра.Имя) Тогда
Запрос.Параметры.Вставить(ОписаниеПараметра.Имя);
КонецЕсли;
КонецЦикла;
Для Каждого КлючИЗначение Из Запрос.Параметры Цикл
ЗначениеПараметра = КлючИЗначение.Значение;
Если ТипЗнч(ЗначениеПараметра) = Тип("Массив") Тогда
Список = Новый СписокЗначений;
Список.ЗагрузитьЗначения(ЗначениеПараметра);
ЗначениеПараметра = Список;
КонецЕсли;
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Найти(КлючИЗначение.Ключ);
Если ПараметрСхемы = Неопределено Тогда
ПараметрСхемы = СхемаКомпоновкиДанных.Параметры.Добавить();
КонецЕсли;
ПараметрСхемы.Имя = КлючИЗначение.Ключ;
ПараметрСхемы.ДоступенСписокЗначений = ТипЗнч(ЗначениеПараметра) = Тип("СписокЗначений");
//Тип надо задавать, чтобы значение корректно записалось. Иначе ссылки будут преобразованы к строке.
МассивТипов = Новый Массив;
МассивТипов.Добавить(ТипЗнч(КлючИЗначение.Значение));
Если Не ПараметрСхемы.ДоступенСписокЗначений Тогда
ПараметрСхемы.ТипЗначения = Новый ОписаниеТипов(МассивТипов);
КонецЕсли;
ПараметрСхемы.Значение = ЗначениеПараметра;
КонецЦикла;
КонецПроцедуры
Функция СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Знач СхемаКомпоновкиДанных, Знач Запрос, Знач ИмяНабора = "Основной",
Представления = Неопределено) Экспорт
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(СхемаКомпоновкиДанных.НаборыДанных, СхемаКомпоновкиДанных.ИсточникиДанных[0]);
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = Запрос.Текст;
Если Представления <> Неопределено Тогда
Для Каждого КлючИЗначение Из Представления Цикл
ПолеНабора = НаборДанных.Поля.Найти(КлючИЗначение.Ключ);
Если ПолеНабора = Неопределено Тогда
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
КонецЕсли;
ПолеНабора.Поле = КлючИЗначение.Ключ;
ПолеНабора.ПутьКДанным = КлючИЗначение.Ключ;
ПолеНабора.Заголовок = КлючИЗначение.Значение;
КонецЦикла;
КонецЕсли;
ЗаполнитьПараметрыСхемыПоЗапросуЛкс(СхемаКомпоновкиДанных, Запрос);
Возврат НаборДанных;
КонецФункции
// Представления - Структура
Функция ПолучитьСхемуКомпоновкиПоЗапросуЛкс(Знач ЗапросИлиТекст, ИмяНабораДанных = "НаборДанных1", Представления = Неопределено) Экспорт
Схема = Новый СхемаКомпоновкиДанных;
ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
Если ТипЗнч(ЗапросИлиТекст) = Тип("Строка") Тогда
Запрос = Новый Запрос;
Запрос.Текст = ЗапросИлиТекст;
Иначе
Запрос = ЗапросИлиТекст;
КонецЕсли;
СоздатьИлиОбновитьНаборДанныхЗапросПоЗапросуЛкс(Схема, Запрос, ИмяНабораДанных, Представления);
Возврат Схема;
КонецФункции
Функция ПолучитьСхемуКомпоновкиПоОбъектуМетаданныхЛкс(Знач ПолноеИмяИлиОбъектМД, ИмяНабораДанных = "НаборДанных1", ДобавитьАвтополеКоличествоСтрок = Истина,
ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "", ИменаВместоПредставлений = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяИлиОбъектМД) = Тип("Строка") Тогда
ПолноеИмяМД = ПолноеИмяИлиОбъектМД;
Иначе
ПолноеИмяМД = ПолноеИмяИлиОбъектМД.ПолноеИмя();
КонецЕсли;
ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
Схема = ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность, ДобавитьАвтополеКоличествоСтрок, ИндексПараметраПериодичность, ПсевдонимТаблицы,
ИменаВместоПредставлений);
Возврат Схема;
КонецФункции
Функция ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
Запрос = Новый Запрос;
Запрос.Текст = ПолучитьТекстаЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность) + " ГДЕ ЛОЖЬ";
Попытка
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Исключение
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = Запрос.Текст;
Попытка
ПостроительЗапроса.ЗаполнитьНастройки(); // Долгий способ пробуем только если быстрый не удался
Исключение
Если ВызыватьИсключениеПриОтсутствииПрав Тогда
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
ТаблицаРезультата.Колонки.Добавить(ДоступноеПоле.ПутьКДанным, ДоступноеПоле.ТипЗначения);
КонецЦикла;
КонецПопытки;
Если ТаблицаРезультата <> Неопределено Тогда
ПоляТаблицы = ПолучитьТаблицуСКолонкамиБезТипаNullЛкс(ТаблицаРезультата).Колонки;
КонецЕсли;
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("Имя");
Результат.Колонки.Добавить("ТипЗначения");
Результат.Колонки.Добавить("Метаданные");
Результат.Колонки.Добавить("Заголовок");
Для Каждого ПолеТаблицы Из ПоляТаблицы Цикл
СтрокаПоля = Результат.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаПоля, ПолеТаблицы);
КонецЦикла;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если Истина
И ТипТаблицы <> "ДвиженияССубконто"
И ТипТаблицы <> "ВиртуальнаяТаблица"
Тогда
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, Истина);
Если ОбъектМД <> Неопределено Тогда
РодительМД = ОбъектМД.Родитель();
Если ТипТаблицы <> "Перерасчет" И ТипЗнч(РодительМД) <> Тип("ОбъектМетаданныхКонфигурация") Тогда
ОбъектМД = РодительМД;
КонецЕсли;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ОбъектМД);
СтрокиСтруктурыТаблицы = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("ИмяТаблицы", ПолноеИмяТаблицыБД));
Если СтрокиСтруктурыТаблицы.Количество() = 0 Тогда
Если Истина
И ТипТаблицы <> "Изменения"
И ТипТаблицы <> "Границы"
Тогда
Сообщить("Не удалось найти метаданные полей таблицы " + ПолноеИмяТаблицыБД);
Иначе
// Для отладки
// Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы.
// Сюда попадаем для границ последовательностей, у которых ошибочно пустое имя таблицы.
Пустышка = 1;
КонецЕсли;
Иначе
Если СтрокиСтруктурыТаблицы.Количество() > 1 Тогда
Пустышка = 1; // Для отладки. Сюда попадаем для констант, у которых у таблицы изменений имя ошибочно указано то же, что и у основной таблицы
КонецЕсли;
Для Каждого ПолеТаблицы Из СтрокиСтруктурыТаблицы[0].Поля Цикл
Если Истина
И ЗначениеЗаполнено(ПолеТаблицы.Метаданные)
И (Ложь
Или ПолеТаблицы.ИмяПоля <> "НомерСтроки"
Или Найти(ПолеТаблицы.Метаданные, ".ТабличнаяЧасть.") = 0)
Тогда
СтрокаПоля = Результат.Найти(ПолеТаблицы.ИмяПоля, "Имя");
Если СтрокаПоля <> Неопределено Тогда
СтрокаПоля.Метаданные = Метаданные.НайтиПоПолномуИмени(ПолеТаблицы.Метаданные);
Заголовок = СтрокаПоля.Метаданные.Представление();
Если ЗначениеЗаполнено(Заголовок) Тогда
СтрокаПоля.Заголовок = Заголовок;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьПоляТаблицыМДЛкс(ПолноеИмяМД, ВызыватьИсключениеПриОтсутствииПрав = Истина, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
ПоляТаблицы = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВызыватьИсключениеПриОтсутствииПрав, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность);
Возврат ПоляТаблицы;
КонецФункции
// Добавляет в набор данных поле набора данных
Функция ДобавитьПолеНабораДанныхЛкс(НаборДанных, Поле, Заголовок, ПутьКДанным = Неопределено) Экспорт
Если ПутьКДанным = Неопределено Тогда
ПутьКДанным = Поле;
КонецЕсли;
ПолеНабораДанных = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабораДанных.Поле = Поле;
ПолеНабораДанных.Заголовок = Заголовок;
ПолеНабораДанных.ПутьКДанным = ПутьКДанным;
Возврат ПолеНабораДанных;
КонецФункции
Функция ДобавитьПоляПериодаВНаборДанныхЛкс(НаборДанных)
СписокПериодов = Новый СписокЗначений;
СписокПериодов.Добавить("ПериодСекунда", "Период секунда");
СписокПериодов.Добавить("ПериодМинута", "Период минута");
СписокПериодов.Добавить("ПериодЧас", "Период час");
СписокПериодов.Добавить("ПериодДень", "Период день");
СписокПериодов.Добавить("ПериодНеделя", "Период неделя");
СписокПериодов.Добавить("ПериодДекада", "Период декада");
СписокПериодов.Добавить("ПериодМесяц", "Период месяц");
СписокПериодов.Добавить("ПериодКвартал", "Период квартал");
СписокПериодов.Добавить("ПериодПолугодие", "Период полугодие");
СписокПериодов.Добавить("ПериодГод", "Период год");
ИмяПапки = "Периоды";
СписокПолейНабораДанных = Новый СписокЗначений;
ПапкаПолейНабораДанных = НаборДанных.Поля.Добавить(Тип("ПапкаПолейНабораДанныхСхемыКомпоновкиДанных"));
ПапкаПолейНабораДанных.Заголовок = ИмяПапки;
ПапкаПолейНабораДанных.ПутьКДанным = ИмяПапки;
Для каждого Период Из СписокПериодов Цикл
ПолеНабораДанных = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабораДанных.Поле = Период.Значение;
ПолеНабораДанных.Заголовок = Период.Представление;
ПолеНабораДанных.ПутьКДанным = ИмяПапки + "." + Период.Значение;
СписокПолейНабораДанных.Добавить(ПолеНабораДанных);
КонецЦикла;
Возврат СписокПолейНабораДанных;
КонецФункции
// Функция добавляет поле итога в схему компоновки данных. Если параметр Выражение не указан, используется Сумма(ПутьКДанным)
Функция ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, ПутьКДанным, Выражение = Неопределено) Экспорт
#Если _ Тогда
СхемаКомпоновкиДанных = Новый СхемаКомпоновкиДанных;
#КонецЕсли
Если Выражение = Неопределено Тогда
Выражение = "Сумма(" + ПутьКДанным + ")";
КонецЕсли;
ПолеИтога = СхемаКомпоновкиДанных.ПоляИтога.Добавить();
ПолеИтога.ПутьКДанным = ПутьКДанным;
ПолеИтога.Выражение = Выражение;
Возврат ПолеИтога;
КонецФункции
Процедура ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, СхемаКомпоновкиДанных) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
ПолноеИмяМД = ПолноеИмяТаблицыБД;
Иначе
ИмяВиртуальнойТаблицы = "";
ПолноеИмяМД = ПолноеИмяТаблицыБД;
КонецЕсли;
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ЛиКорневойТипРегистраБДЛкс(КорневойТип) И Не СтрокиРавныЛкс(ТипТаблицы, "Изменения") Тогда
// Добавляем измерения
Для каждого Измерение Из ОбъектМД.Измерения Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Измерение.Имя, Измерение.Синоним);
КонецЦикла;
// Добавляем реквизиты
Если Истина
И Не ЛиКорневойТипПоследовательностиЛкс(КорневойТип)
И Не СтрокиРавныЛкс(ТипТаблицы, "Перерасчет")
Тогда
//Если ПустаяСтрока(ИмяВиртуальнойТаблицы) Тогда
Для каждого Реквизит Из ОбъектМД.Реквизиты Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Реквизит.Имя, Реквизит.Синоним);
КонецЦикла;
//КонецЕсли;
// Добавляем поля периода
Если Ложь
Или ИмяВиртуальнойТаблицы = "ОстаткиИОбороты"
Или ИмяВиртуальнойТаблицы = "Обороты"
Или (Истина
И КорневойТип = "РегистрБухгалтерии"
И ИмяВиртуальнойТаблицы = "")
Тогда
ДобавитьПоляПериодаВНаборДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0]);
КонецЕсли;
// Добавляем ресурсы
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Если КорневойТип = "РегистрБухгалтерии" ТОгда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
Если НЕ Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборот", Ресурс.Синоним + " кор. оборот", Ресурс.Имя + "КорОборот");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборот");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборотДт", Ресурс.Синоним + " кор. оборот Дт", Ресурс.Имя + "КорОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КорОборотКт", Ресурс.Синоним + " кор. оборот Кт", Ресурс.Имя + "КорОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КорОборотКт");
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОборотыДтКт" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Дт", Ресурс.Синоним + " Дт", Ресурс.Имя + "Дт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Дт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Кт", Ресурс.Синоним + " Кт", Ресурс.Имя + "Кт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Кт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстаток", Ресурс.Синоним + " нач. остаток", Ресурс.Имя + "НачальныйОстаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстаток");
Если КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстатокДт", Ресурс.Синоним + " нач. остаток Дт", Ресурс.Имя + "НачальныйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйОстатокКт", Ресурс.Синоним + " нач. остаток Кт", Ресурс.Имя + "НачальныйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйРазвернутыйОстатокДт", Ресурс.Синоним + " нач. развернутый остаток Дт", Ресурс.Имя + "НачальныйРазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйРазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "НачальныйРазвернутыйОстатокКт", Ресурс.Синоним + " нач. развернутый остаток Кт", Ресурс.Имя + "НачальныйРазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "НачальныйРазвернутыйОстатокКт");
КонецЕсли;
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Оборот", Ресурс.Синоним + " оборот", Ресурс.Имя + "Оборот");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Оборот");
Если КорневойТип = "РегистрНакопления" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Приход", Ресурс.Синоним + " приход", Ресурс.Имя + "Приход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Приход");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Расход", Ресурс.Синоним + " расход", Ресурс.Имя + "Расход");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Расход");
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотДт", Ресурс.Синоним + " оборот Дт", Ресурс.Имя + "ОборотДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОборотКт", Ресурс.Синоним + " оборот Кт", Ресурс.Имя + "ОборотКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстаток", Ресурс.Синоним + " кон. остаток", Ресурс.Имя + "КонечныйОстаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстаток");
Если КорневойТип = "РегистрБухгалтерии" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстатокДт", Ресурс.Синоним + " кон. остаток Дт", Ресурс.Имя + "КонечныйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйОстатокКт", Ресурс.Синоним + " кон. остаток Кт", Ресурс.Имя + "КонечныйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйРазвернутыйОстатокДт", Ресурс.Синоним + " кон. развернутый остаток Дт", Ресурс.Имя + "КонечныйРазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйРазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "КонечныйРазвернутыйОстатокКт", Ресурс.Синоним + " кон. развернутый остаток Кт", Ресурс.Имя + "КонечныйРазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "КонечныйРазвернутыйОстатокКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "Остатки" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Остаток", Ресурс.Синоним + " остаток", Ресурс.Имя + "Остаток");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Остаток");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОстатокДт", Ресурс.Синоним + " остаток Дт", Ресурс.Имя + "ОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "ОстатокКт", Ресурс.Синоним + " остаток Кт", Ресурс.Имя + "ОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "ОстатокКт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "РазвернутыйОстатокДт", Ресурс.Синоним + " развернутый остаток Дт", Ресурс.Имя + "РазвернутыйОстатокДт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "РазвернутыйОстатокДт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "РазвернутыйОстатокКт", Ресурс.Синоним + " развернутый остаток Кт", Ресурс.Имя + "РазвернутыйОстатокКт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "РазвернутыйОстатокКт");
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
Если Ресурс.Тип.СодержитТип(Тип("Число")) Тогда
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя, Ресурс.Имя);
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
Если КорневойТип = "РегистрБухгалтерии" Тогда
Если Ресурс.Балансовый Тогда
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Дт", Ресурс.Синоним + " Дт", Ресурс.Имя + "Дт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Дт");
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя + "Кт", Ресурс.Синоним + " Кт", Ресурс.Имя + "Кт");
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя + "Кт");
КонецЕсли;
Иначе
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Ресурс.Имя, Ресурс.Синоним);
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Ресурс.Имя);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
ИначеЕсли ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы) Тогда
Если ИмяВиртуальнойТаблицы = "" Тогда
ОбъектМетаданных = ОбъектМД;
Иначе
ОбъектМетаданных = ОбъектМД.ТабличныеЧасти.Найти(ИмяВиртуальнойТаблицы);
Если ОбъектМетаданных = Неопределено Тогда
ОбъектМетаданных = ОбъектМД;
КонецЕсли;
КонецЕсли;
Для каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
ДобавитьПолеНабораДанныхЛкс(СхемаКомпоновкиДанных.НаборыДанных[0], Реквизит.Имя, Реквизит.Синоним);
Если Реквизит.Тип.СодержитТип(Тип("Число")) Тогда
ДобавитьПолеИтогаЛкс(СхемаКомпоновкиДанных, Реквизит.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, НастройкаКомпоновки) Экспорт
#Если _ Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
Иначе
ИмяВиртуальнойТаблицы = "";
КонецЕсли;
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
ВыбранныеПоля = НастройкаКомпоновки.Выбор;
Если ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
ВыбранныеПоляНачальныйОстаток = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляНачальныйОстаток.Заголовок = "Нач. остаток";
ВыбранныеПоляНачальныйОстаток.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
Если КорневойТип = "РегистрНакопления" Тогда
ВыбранныеПоляПриход = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляПриход.Заголовок = "Приход";
ВыбранныеПоляПриход.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
ВыбранныеПоляРасход = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляРасход.Заголовок = "Расход";
ВыбранныеПоляРасход.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
ВыбранныеПоляОбороты = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляОбороты.Заголовок = "Обороты";
ВыбранныеПоляОбороты.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
КонецЕсли;
ВыбранныеПоляКонечныйОстаток = НастройкаКомпоновки.Выбор.Элементы.Добавить(Тип("ГруппаВыбранныхПолейКомпоновкиДанных"));
ВыбранныеПоляКонечныйОстаток.Заголовок = "Кон. остаток";
ВыбранныеПоляКонечныйОстаток.Расположение = РасположениеПоляКомпоновкиДанных.Горизонтально;
КонецЕсли;
Если КорневойТип = "РегистрНакопления" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот");
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстаток");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляПриход, Ресурс.Имя + "Приход");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляРасход, Ресурс.Имя + "Расход");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстаток");
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
КонецЕсли;
КонецЦикла;
ИначеЕсли КорневойТип = "РегистрСведений" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
КонецЦикла;
ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда
Для каждого Ресурс Из ОбъектМД.Ресурсы Цикл
Если ИмяВиртуальнойТаблицы = "Обороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотКт");
ИначеЕсли ИмяВиртуальнойТаблицы = "ОборотыДтКт" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Оборот");
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОборотКт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "Остатки" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "ОстатокКт");
ИначеЕсли ИмяВиртуальнойТаблицы = "ОстаткиИОбороты" Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляНачальныйОстаток, Ресурс.Имя + "НачальныйОстатокКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "ОборотДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляОбороты, Ресурс.Имя + "ОборотКт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстатокДт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоляКонечныйОстаток, Ресурс.Имя + "КонечныйОстатокКт");
ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Дт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Кт");
КонецЕсли;
ИначеЕсли ИмяВиртуальнойТаблицы = "" Тогда
Если Ресурс.Балансовый Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя);
Иначе
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Дт");
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, Ресурс.Имя + "Кт");
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
//Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Тогда
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицыБД);
#Если _ Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(ВыбранныеПоля, ПолеТаблицыБД.Имя);
КонецЦикла;
//КонецЕсли;
КонецПроцедуры
Процедура ДобавитьПолеГруппировкиЛкс(Группировка, Наименование, Синоним)
Если Группировка.Найти(Наименование, "Поле") = Неопределено Тогда
ГруппировкаСтр = Группировка.Добавить();
ГруппировкаСтр.Поле = Наименование;
ГруппировкаСтр.Использование = Истина;
ГруппировкаСтр.Представление = Синоним;
КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, НастройкаКомпоновки) Экспорт
#Если _ Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
КорневойТип = ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицыБД);
Если СтрокиРавныЛкс(ТипТаблицы, "ВиртуальнаяТаблица") Тогда
ИмяВиртуальнойТаблицы = ПолучитьПоследнийФрагментЛкс(ПолноеИмяТаблицыБД);
Иначе
ИмяВиртуальнойТаблицы = "";
КонецЕсли;
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
////ПолеГруппировки = ЭлементСтруктуры.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
//Если ТипТаблицы = "Справочники" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Наименование", "Наименование");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Ссылка.Наименование", "Наименование");
// КонецЕсли;
//ИначеЕсли ТипТаблицы = "Документы" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Ссылка", "Ссылка");
//ИначеЕсли Истина
// И ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Количество() > 0
// И ОбъектМД.Измерения.Количество() > 0
//Тогда
// Если ТипТаблицы = "РегистрБухгалтерии" Тогда
// Если ИмяВиртуальнойТаблицы = "" Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Регистратор", "Регистратор");
// ИначеЕсли ИмяВиртуальнойТаблицы = "ДвиженияССубконто" Тогда
// ЭлементСтруктуры.ПоляГруппировки.Элементы.Удалить(ПолеГруппировки);
// // Группировки по забалансовым
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя, Измерение.Синоним);
// КонецЕсли
// КонецЦикла;
// // ИзмеренияДт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Дт", Измерение.Синоним + " Дт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоДт" + К, "СубконтоДт" + К);
// КонецЦикла;
// // ИзмеренияКт
// Для каждого Измерение Из ОбъектМД.Измерения Цикл
// Если НЕ Измерение.Балансовый Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, Измерение.Имя + "Кт", Измерение.Синоним + " Кт");
// КонецЕсли
// КонецЦикла;
// Для К = 1 По 3 Цикл
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СубконтоКт" + К, "СубконтоКт" + К);
// КонецЦикла;
// Иначе
// Если ЭлементСтруктуры.ПоляГруппировки.ДоступныеПоляПолейГруппировок.Элементы.Найти("Счет")<> Неопределено Тогда
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "Счет", "Счет");
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетДт", "СчетДт");
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка, "СчетКт", "СчетКт");
// КонецЕсли;
// КонецЕсли;
// Иначе
// ДобавитьПолеГруппировкиЛкс(ПараметрыОтчета.Группировка,
// ОбъектМД.Измерения[0].Имя,
// ОбъектМД.Измерения[0].Синоним);
// КонецЕсли
//КонецЕсли;
ЭлементПорядка = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
КонецПроцедуры
Функция ПолучитьСхемуКомпоновкиТаблицыБДЛкс(ПолноеИмяТаблицыБД, ВыражениеПараметраПериодичность = Неопределено, ДобавитьАвтополеКоличествоСтрок = Истина,
Знач ИндексПараметраПериодичность = Неопределено, Знач ПсевдонимТаблицы = "Т", ИменаВместоПредставлений = Ложь, РасширенноеЗаполнение = Ложь) Экспорт
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(Схема.НаборыДанных, ИсточникДанных);
#Если _ Тогда
НаборДанных = Схема.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
НаборДанных.Запрос = ПолучитьТекстаЗапросаПолейТаблицыБДЛкс(ПолноеИмяТаблицыБД, ИндексПараметраПериодичность, ВыражениеПараметраПериодичность, ПсевдонимТаблицы, Ложь);
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(Схема);
КонецЕсли;
Если Ложь
Или ИменаВместоПредставлений
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 // Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
Если ИменаВместоПредставлений Тогда
ПолеНабора.Заголовок = ДоступноеПоле.Имя;
Иначе
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если РасширенноеЗаполнение Тогда
ДобавитьПоляНабораДанныхЛкс(ПолноеИмяТаблицыБД, Схема);
ЗаполнитьСтруктуруКомпоновкиПоУмолчаниюПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, Схема.НастройкиПоУмолчанию);
ДобавитьВыбранныеПоляКомпоновкиПоТаблицеБДЛкс(ПолноеИмяТаблицыБД, Схема.НастройкиПоУмолчанию);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "Title", Метаданные[Отчет.ТипДанных][Отчет.ИмяОбъекта].Синоним);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "TitleOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "FilterOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
//БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметрВывода(
// Отчет.КомпоновщикНастроек, "DataParametersOutput", ТипВыводаТекстаКомпоновкиДанных.НеВыводить);
КонецЕсли;
Возврат Схема;
КонецФункции
Функция ПолучитьТекстаЗапросаПолейТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = Неопределено, ПсевдонимТаблицы = "Т",
БлокироватьПолучениеДанных = Истина) Экспорт
ОписаниеТаблицы = ПолучитьОписаниеТаблицыБДИис(ПолноеИмяТаблицыБД);
ПараметрыВиртуальнойТаблицы = "";
Если БлокироватьПолучениеДанных Тогда
ИндексПараметраОтбора = ОписаниеТаблицы.ИндексПараметраОтбора;
Иначе
ИндексПараметраОтбора = Неопределено;
КонецЕсли;
МаксимальныйИндекс = ИндексПараметраОтбора;
Если ИндексПараметраПериодичность <> Неопределено Тогда
Если МаксимальныйИндекс <> Неопределено Тогда
МаксимальныйИндекс = Макс(МаксимальныйИндекс, ИндексПараметраПериодичность);
Иначе
МаксимальныйИндекс = ИндексПараметраПериодичность;
КонецЕсли;
КонецЕсли;
Если МаксимальныйИндекс <> Неопределено Тогда
МассивВыраженийПараметров = Новый Массив;
Для Счетчик = 0 По МаксимальныйИндекс Цикл
МассивВыраженийПараметров.Добавить("");
КонецЦикла;
Если ИндексПараметраОтбора <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраОтбора] = "ЛОЖЬ";
КонецЕсли;
Если ИндексПараметраПериодичность <> Неопределено Тогда
МассивВыраженийПараметров[ИндексПараметраПериодичность] = ВыражениеПараметраПериодичность;
КонецЕсли;
ПараметрыВиртуальнойТаблицы = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивВыраженийПараметров);
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрыВиртуальнойТаблицы) Тогда
ПолноеИмяТаблицыБД = ПолноеИмяТаблицыБД + "(" + ПараметрыВиртуальнойТаблицы + ")";
КонецЕсли;
Если Не ЗначениеЗаполнено(ПсевдонимТаблицы) Тогда
ПсевдонимТаблицы = "Т";
КонецЕсли;
ТекстЗапроса = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Возврат ТекстЗапроса;
КонецФункции
Функция _ПолучитьСхемуКомпоновкиПоВсемТаблицамБДЛкс(ТаблицаВсехТаблицБД, ИмяНабораДанных = "НаборДанных1",
ДобавитьАвтополеКоличествоСтрок = Истина, ПсевдонимТаблицы = "Т", ИндексПараметраПериодичность = Неопределено, ВыражениеПараметраПериодичность = "") Экспорт
КорневаяСхема = Новый СхемаКомпоновкиДанных;
НастройкиПоУмолчанию = КорневаяСхема.НастройкиПоУмолчанию;
Для Каждого ОписаниеТаблицы Из ТаблицаВсехТаблицБД Цикл
ПолноеИмяТаблицыБД = ОписаниеТаблицы.ПолноеИмя;
Схема = Новый СхемаКомпоновкиДанных;
ИсточникДанных = ДобавитьЛокальныйИсточникДанныхЛкс(Схема);
НаборДанных = ДобавитьНаборДанныхЗапросЛкс(Схема.НаборыДанных, ИсточникДанных);
#Если _ Тогда
НаборДанных = Схема.НаборыДанных.Добавить();
#КонецЕсли
НаборДанных.АвтоЗаполнениеДоступныхПолей = Истина;
//ПолноеИмяТаблицыБД = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД);
НаборДанных.Запрос = "ВЫБРАТЬ " + ПсевдонимТаблицы + ".* ИЗ " + ПолноеИмяТаблицыБД + " КАК " + ПсевдонимТаблицы;
Если ДобавитьАвтополеКоличествоСтрок Тогда
ДобавитьВСхемуКомпоновкиАвтополеКоличествоСтрокЛкс(Схема);
КонецЕсли;
// Антибаг платформы в режиме совместимости. Предопределенные реквизиты имеют англ. имена полей
Если Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1 Тогда
Построитель = Новый ПостроительЗапроса(НаборДанных.Запрос);
Построитель.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из Построитель.ДоступныеПоля Цикл
ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНабора.Поле = ДоступноеПоле.ПутьКДанным;
//ПолеНабора.ПутьКДанным = ДоступноеПоле.ПутьКДанным;
ПолеНабора.Заголовок = ДоступноеПоле.Представление;
КонецЦикла;
КонецЕсли;
ВложеннаяСхема = КорневаяСхема.ВложенныеСхемыКомпоновкиДанных.Добавить();
//ВложеннаяСхема.Заголовок = ОписаниеТаблицы.Представление;
ВложеннаяСхема.Схема = Схема;
ВложеннаяСхема.Имя = СтрЗаменить(ПолноеИмяТаблицыБД, ".", "_1_");
ЭлементСтруктуры = НастройкиПоУмолчанию.Структура.Добавить(Тип("НастройкиВложенногоОбъектаКомпоновкиДанных"));
ЭлементСтруктуры.УстановитьИдентификатор(ВложеннаяСхема.Имя);
КонецЦикла;
Возврат КорневаяСхема;
КонецФункции
Функция ДобавитьДоступнуюТаблицуБДЛкс(ДоступныеТаблицыБД, ПолноеИмя, ПолноеИмяМД = "", ТипТаблицы = "", Имя = "", Представление = "", СхемаТаблицы = "", ПроверятьУникальность = Ложь,
ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(ПолноеИмя) Тогда
ПолноеИмя = ПолноеИмяМД;
КонецЕсли;
Фрагменты = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмя);
Если Фрагменты.Количество() > 1 Тогда
//Если Не ЗначениеЗаполнено(СхемаТаблицы) Тогда
// СхемаТаблицы = Фрагменты[0];
//КонецЕсли;
Фрагменты.Удалить(0);
КонецЕсли;
Если ПроверятьУникальность Тогда
СтрокаТаблицы = ДоступныеТаблицыБД.Найти(НРег(ПолноеИмя), "НПолноеИмя");
Иначе
СтрокаТаблицы = Неопределено;
КонецЕсли;
Если СтрокаТаблицы = Неопределено Тогда
СтрокаТаблицы = ДоступныеТаблицыБД.Добавить();
СтрокаТаблицы.Схема = СхемаТаблицы;
СтрокаТаблицы.ПолноеИмяМД = ПолноеИмяМД;
СтрокаТаблицы.ПолноеИмя = ПолноеИмя;
СтрокаТаблицы.НПолноеИмя = НРег(СтрокаТаблицы.ПолноеИмя);
СтрокаТаблицы.ИндексПараметраОтбора = ИндексПараметраОтбора;
Если Не ЗначениеЗаполнено(Имя) Тогда
СтрокаТаблицы.Имя = ирОбщий.ПолучитьСтрокуСРазделителемИзМассиваЛкс(Фрагменты, ".");
Иначе
СтрокаТаблицы.Имя = Имя;
КонецЕсли;
СтрокаТаблицы.Представление = Представление;
Если Не ЗначениеЗаполнено(ТипТаблицы) Тогда
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмя);
КонецЕсли;
СтрокаТаблицы.Тип = ТипТаблицы;
Если ТипТаблицы = "Перерасчет" Тогда
МетаРегистрРасчета = ОбъектМД.Родитель();
СтрокаТаблицы.Имя = МетаРегистрРасчета.Имя + "." + СтрокаТаблицы.Имя;
СтрокаТаблицы.Представление = МетаРегистрРасчета.Представление() + "." + СтрокаТаблицы.Представление;
КонецЕсли;
//СтрокаТаблицы.Описание = МетаИсточник.Представление();
КонецЕсли;
Возврат СтрокаТаблицы;
КонецФункции
Функция ПолучитьИндексКартинкиТипаТаблицыБДЛкс(ТипТаблицы) Экспорт
ИндексКартинки = 14;
Если ТипТаблицы = "Константы" Тогда
ИндексКартинки = 2;
ИначеЕсли ТипТаблицы = "Константа" Тогда
ИндексКартинки = 2;
//ИначеЕсли ТипТаблицы = "ТабличнаяЧасть" Тогда
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
ИндексКартинки = 20;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
ИндексКартинки = 27;
ИначеЕсли ТипТаблицы = "ВиртуальнаяТаблица" Тогда
ИндексКартинки = 28;
ИначеЕсли ТипТаблицы = "ВнешнийИсточникДанных" Тогда
ИндексКартинки = 29;
ИначеЕсли ТипТаблицы = "Справочник" Тогда
ИндексКартинки = 3;
ИначеЕсли ТипТаблицы = "Перечисление" Тогда
ИндексКартинки = 4;
ИначеЕсли ТипТаблицы = "Документ" Тогда
ИндексКартинки = 5;
ИначеЕсли ТипТаблицы = "ЖурналДокументов" Тогда
ИндексКартинки = 6;
ИначеЕсли ТипТаблицы = "Последовательность" Тогда
ИндексКартинки = 7;
ИначеЕсли ТипТаблицы = "РегистрНакопления" Тогда
ИндексКартинки = 8;
ИначеЕсли ТипТаблицы = "РегистрСведений" Тогда
ИндексКартинки = 9;
ИначеЕсли ТипТаблицы = "РегистрБухгалтерии" Тогда
ИндексКартинки = 10;
ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда
ИндексКартинки = 11;
ИначеЕсли ТипТаблицы = "ПланОбмена" Тогда
ИндексКартинки = 19;
ИначеЕсли ТипТаблицы = "Задача" Тогда
ИндексКартинки = 17;
ИначеЕсли ТипТаблицы = "БизнесПроцесс" Тогда
ИндексКартинки = 18;
ИначеЕсли ТипТаблицы = "РегистрРасчета" Тогда
ИндексКартинки = 26;
ИначеЕсли ТипТаблицы = "ПланВидовРасчета" Тогда
ИндексКартинки = 25;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 22;
ИначеЕсли ТипТаблицы = "Перечисление" Тогда
ИндексКартинки = 23;
ИначеЕсли ТипТаблицы = "ПланСчетов" Тогда
ИндексКартинки = 24;
ИначеЕсли ТипТаблицы = "Перерасчет" Тогда
ИндексКартинки = 30;
ИначеЕсли СтрокиРавныЛкс(ТипТаблицы, "Table") Тогда
ИндексКартинки = 3;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
Функция НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(Знач Коллекция, Знач Свойство, Знач Значение, Знач ТипЭлемента = Неопределено) Экспорт
Структура = Новый Структура(Свойство);
Для каждого Элемент Из Коллекция Цикл
Если Истина
И ТипЭлемента <> Неопределено
И ТипЗнч(Элемент) <> ТипЭлемента
Тогда
Продолжить;
КонецЕсли;
ЗаполнитьЗначенияСвойств(Структура, Элемент, Свойство);
Если Структура[Свойство] = Значение Тогда
Результат = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПредставлениюЛкс(Знач ЭлементыНастройки, Знач Представление = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыНастройки, "Представление", Представление, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Представление = Представление;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(Знач ЭлементыНастройки, Знач Поле = "", Знач ПроверятьУникальность = Истина,
Знач ИспользованиеДляНового = Истина) Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Попытка
ЭлементыНастройки = ЭлементыНастройки.Элементы;
Исключение
КонецПопытки;
Если ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовПорядкаКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ЭлементПорядкаКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияВыбранныхПолейКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ВыбранноеПолеКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияПолейГруппировкиКомпоновкиДанных") Тогда
ТипЭлемента = Тип("ПолеГруппировкиКомпоновкиДанных");
ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовУсловногоОформленияКомпоновкиДанных") Тогда
ТипЭлемента = Неопределено;
//ИначеЕсли ТипЗнч(ЭлементыНастройки) = Тип("КоллекцияЭлементовОтбораКомпоновкиДанных") Тогда
// ТипЭлемента = Тип("ЭлементОтбораКомпоновкиДанных");
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементНастроек = НайтиЭлементКоллекцииПоЗначениюСвойстваЛкс(ЭлементыНастройки, "Поле", Поле, ТипЭлемента);
КонецЕсли;
Если ЭлементНастроек = Неопределено Тогда
Если ТипЭлемента <> Неопределено Тогда
ЭлементНастроек = ЭлементыНастройки.Добавить(ТипЭлемента);
Иначе
ЭлементНастроек = ЭлементыНастройки.Добавить();
КонецЕсли;
ЭлементНастроек.Поле = Поле;
ЭлементНастроек.Использование = ИспользованиеДляНового;
КонецЕсли;
Возврат ЭлементНастроек;
КонецФункции
Функция НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(Знач Группировки, Знач Поле = "") Экспорт
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
ЭлементСуществует = Ложь;
Для Каждого Группировка Из Группировки Цикл
Поля = Группировка.ПоляГруппировки.Элементы;
Если Ложь
Или (Истина
И Поля.Количество() = 0
И "" + Поле = "")
Или (Истина
И Поля.Количество() = 1
И Поля[0].Поле = Поле)
Тогда
ЭлементСуществует = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЭлементСуществует Тогда
Группировка = Группировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
Если "" + Поле <> "" Тогда
ПолеГруппировки = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Поле = Поле;
КонецЕсли;
КонецЕсли;
Группировка.Использование = Истина;
Возврат Группировка;
КонецФункции
Функция НайтиЭлементОтбораКомпоновкиЛкс(Знач Отбор, Знач ИменаПолей, Знач НайденныеЭлементы = Неопределено, Знач ТолькоВключенныеНаРавенствоЗначению = Ложь,
Знач ВключатьПодчиненные = Ложь) Экспорт
Если ТипЗнч(Отбор) = Тип("ОтборКомпоновкиДанных") Тогда
ЭлементыОтбора = Отбор.Элементы;
Иначе
ЭлементыОтбора = Отбор;
КонецЕсли;
Если ТипЗнч(ИменаПолей) = Тип("Строка") Тогда
МассивИменПолей = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаПолей, ",", Истина);
Иначе
МассивИменПолей = ИменаПолей;
КонецЕсли;
МассивПолей = Новый Массив;
Для Каждого ИмяПоля Из МассивИменПолей Цикл
МассивПолей.Добавить(Новый ПолеКомпоновкиДанных(ИмяПоля));
КонецЦикла;
МассивПолейПуст = МассивПолей.Количество() = 0;
Если НайденныеЭлементы = Неопределено Тогда
НайденныеЭлементы = Новый Соответствие;
КонецЕсли;
Для Каждого ЭлементОтбора ИЗ ЭлементыОтбора Цикл
Если Истина
И ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И (Ложь
Или Не ТолькоВключенныеНаРавенствоЗначению
Или (Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно
И ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных")
И ТипЗнч(ЭлементОтбора.ПравоеЗначение) <> Тип("ПолеКомпоновкиДанных")))
Тогда
Если Ложь
Или МассивПолейПуст
Или МассивПолей.Найти(ЭлементОтбора.ЛевоеЗначение) <> Неопределено
Тогда
НайденныеЭлементы.Вставить("" + ЭлементОтбора.ЛевоеЗначение, ЭлементОтбора);
КонецЕсли;
ИначеЕсли Истина
И ВключатьПодчиненные
И ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
НайтиЭлементОтбораКомпоновкиЛкс(ЭлементОтбора.Элементы, МассивИменПолей, НайденныеЭлементы, ТолькоВключенныеНаРавенствоЗначению);
КонецЕсли;
КонецЦикла;
Если МассивИменПолей.Количество() = 1 Тогда
Результат = НайденныеЭлементы[МассивИменПолей[0]];
Иначе
Результат = НайденныеЭлементы;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиДобавитьЭлементОтбораКомпоновкиЛкс(Знач ЭлементыОтбора, Знач Поле = "", Знач Значение = Неопределено, Знач Сравнение = "", Знач ДоступныеПоляОтбора = Неопределено,
Знач ПроверятьУникальность = Истина) Экспорт
Если ТипЗнч(ЭлементыОтбора) = Тип("НастройкиКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Отбор;
КонецЕсли;
Если ТипЗнч(ЭлементыОтбора) = Тип("ОтборКомпоновкиДанных") Тогда
ДоступныеПоляОтбора = ЭлементыОтбора.ДоступныеПоляОтбора;
ЭлементыОтбора = ЭлементыОтбора.Элементы;
ИначеЕсли ТипЗнч(ЭлементыОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ЭлементыОтбора = ЭлементыОтбора.Элементы;
Иначе
ЭлементыОтбора = ЭлементыОтбора;
КонецЕсли;
Если ТипЗнч(Поле) = Тип("Строка") Тогда
Поле = Новый ПолеКомпоновкиДанных(Поле);
КонецЕсли;
Если ПроверятьУникальность Тогда
ЭлементОтбора = НайтиЭлементОтбораКомпоновкиЛкс(ЭлементыОтбора, "" + Поле);
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Поле;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
КонецЕсли;
// Вид сравнения
Если ТипЗнч(Сравнение) = Тип("ВидСравненияКомпоновкиДанных") Тогда
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравненияКомпоновкиДанных.ВСписке;
Иначе
Сравнение = ВидСравненияКомпоновкиДанных.Равно;
КонецЕсли;
КонецЕсли;
Если Истина
И Сравнение = ВидСравненияКомпоновкиДанных.Равно
И Значение = Неопределено
И ДоступныеПоляОтбора <> Неопределено
Тогда
ДоступноеПолеОтбора = ДоступныеПоляОтбора.НайтиПоле(Поле);
Если ДоступноеПолеОтбора <> Неопределено Тогда
Значение = ДоступноеПолеОтбора.Тип.ПривестиЗначение(Значение);
Если Истина
И Значение = ""
И ДоступноеПолеОтбора.Тип.КвалификаторыСтроки.Длина = 0
Тогда
Сравнение = ВидСравненияКомпоновкиДанных.Содержит;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЭлементОтбора.ВидСравнения = Сравнение;
ЭлементОтбора.ПравоеЗначение = Значение;
ЭлементОтбора.Использование = Истина;
Возврат ЭлементОтбора;
КонецФункции
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
Функция ПолучитьНеуникальныеЗначенияКолонкиТаблицыЛкс(Таблица, ИмяКолонки, ИгнорироватьРегистрДляПростогоСтрокогоТипа = Истина) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(, ИмяКолонки);
Иначе
КопияТаблицы = Таблица.Выгрузить(, ИмяКолонки);
КонецЕсли;
Типы = КопияТаблицы.Колонки[ИмяКолонки].ТипЗначения.Типы();
Если Истина
И Типы.Количество() = 1
И Типы[0] = Тип("Строка")
И ИгнорироватьРегистрДляПростогоСтрокогоТипа
Тогда
ИмяКолонкиНрег = ИмяКолонки + "_Нрег777233464645";
КопияТаблицы.Колонки.Добавить(ИмяКолонкиНрег);
Для Каждого СтрокаКопииТаблицы Из КопияТаблицы Цикл
СтрокаКопииТаблицы[ИмяКолонкиНрег] = НРег(СтрокаКопииТаблицы[ИмяКолонки]);
КонецЦикла;
Иначе
ИмяКолонкиНрег = ИмяКолонки;
КонецЕсли;
КолонкаКоличества = ИмяКолонки + "7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИмяКолонкиНрег, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
МассивНеуникальных.Добавить(СтрокаКопии[ИмяКолонкиНрег]);
КонецЕсли;
КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, НаборЗаписей
// ИменаКолонок - Строка - имена колонок через запятую
Функция ПолучитьНеуникальныеКлючиКолонкиТаблицыЛкс(Таблица, ИменаКолонок) Экспорт
Если ТипЗнч(Таблица) = Тип("ТаблицаЗначений") Тогда
КопияТаблицы = Таблица.Скопировать(, ИменаКолонок);
Иначе
КопияТаблицы = Таблица.Выгрузить(, ИменаКолонок);
КонецЕсли;
КолонкаКоличества = "Количество7773534765"; //гарантировано уникальное имя колонки
КопияТаблицы.Колонки.Добавить(КолонкаКоличества);
КопияТаблицы.ЗаполнитьЗначения(1, КолонкаКоличества);
КопияТаблицы.Свернуть(ИменаКолонок, КолонкаКоличества);
КопияТаблицы.Сортировать(КолонкаКоличества + " Убыв");
МассивНеуникальных = Новый Массив;
Для Индекс = 0 По КопияТаблицы.Количество() - 1 Цикл
СтрокаКопии = КопияТаблицы[Индекс];
Если СтрокаКопии[КолонкаКоличества] > 1 Тогда
НеуникальныйКлюч = Новый Структура(ИменаКолонок);
ЗаполнитьЗначенияСвойств(НеуникальныйКлюч, СтрокаКопии);
МассивНеуникальных.Добавить(НеуникальныйКлюч);
КонецЕсли;
КонецЦикла;
Возврат МассивНеуникальных;
КонецФункции // ПолучитьНеуникальныеЗначенияКолонки()
Функция СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт
НаборЗаписей = Новый (ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД));
Возврат НаборЗаписей;
КонецФункции
Функция ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, РасширениеТипа = "НаборЗаписей") Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
Если Фрагменты.Количество() > 2 Тогда
Если Фрагменты[0] = "РегистрРасчета" Тогда
ИмяТипа = "Перерасчет" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[2];
ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда
ИмяТипа = "РегистрБухгалтерии" + РасширениеТипа + "." + Фрагменты[1];
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ИмяТипа = "ВнешнийИсточникДанныхТаблица" + РасширениеТипа + "." + Фрагменты[1] + "." + Фрагменты[3];
КонецЕсли;
Иначе
ИмяТипа = СтрЗаменить(ПолноеИмяТаблицыБД, ".", РасширениеТипа + ".");
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ПолучитьТипКлючаЗаписиТаблицыЛкс(ПолноеИмяТаблицы) Экспорт
ТипТаблицы = ирОбщий.ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
Результат = Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяТаблицы));
ИначеЕсли Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
И ТипТаблицы <> "Перерасчет"
И ТипТаблицы <> "Последовательность"
Тогда
Результат = Тип(СтрЗаменить(ПолноеИмяТаблицы, ".", "КлючЗаписи."));
Иначе
Результат = Тип("Неопределено");
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ВернутьСтруктуру - Булево - возвращать структуру иначе список значений
// ДляПодчиненногоРегистраДобавлятьРегистраторИНомерСтроки - Булево - добавлять кроме полей натурального ключа еше поля альтернативного ключ из регистратора и номера строки
//
Функция ПолучитьСтруктуруКлючаТаблицыБДЛкс(Знач ПолноеИмяТаблицыБД, ВключатьНомерСтроки = Истина, ВернутьСтруктуру = Истина, ДляПодчиненногоРегистраДобавлятьРегистраторИНомерСтроки = Ложь) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД);
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
СписокПолей = Новый СписокЗначений;
Если Ложь
Или ЛиТипТаблицыМетассылкиЛкс(ТипТаблицы)
Или ЛиКорневойТипСсылочногоОбъектаБДЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
ИначеЕсли ЛиКорневойТипРегистраБДЛкс(ТипТаблицы) Тогда
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
#Если _ Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
Если Истина
И ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
И ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
//Если ОбъектМД.ПериодичностьРегистраСведений = Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.ПозицияРегистратора Тогда
СписокПолей.Добавить(НаборЗаписей.Отбор.Регистратор.ТипЗначения, "Регистратор");
//ИначеЕсли ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
// СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период");
//КонецЕсли;
Для Каждого Измерение Из ОбъектМД.Измерения Цикл
СписокПолей.Добавить(Измерение.Тип, Измерение.Имя);
КонецЦикла;
КонецЕсли;
Если Ложь
Или ДляПодчиненногоРегистраДобавлятьРегистраторИНомерСтроки
Или СписокПолей.Количество() = 0
Тогда
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если Ложь
Или ЭлементОтбора.Использование
Или ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Тогда
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЕсли;
КонецЦикла;
Если ВключатьНомерСтроки Тогда
Если ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Дата"), "Период");
ИначеЕсли Истина
И ТипТаблицы <> "Перерасчет"
И (Ложь
Или ТипТаблицы <> "РегистрСведений"
Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору)
Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки");
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
Если ВключатьНомерСтроки Тогда
СписокПолей.Добавить(Новый ОписаниеТипов("Число"), "НомерСтроки");
КонецЕсли;
ИначеЕсли ТипТаблицы = "Изменения" Тогда
// Такой способ может быть долгим при частых вызовах
ПостроительЗапроса = Новый ПостроительЗапроса;
ПостроительЗапроса.Текст = "ВЫБРАТЬ * ИЗ " + ПолноеИмяТаблицыБД + " КАК _Таблица_";
ПостроительЗапроса.ЗаполнитьНастройки();
Для Каждого ДоступноеПоле Из ПостроительЗапроса.ДоступныеПоля Цикл
Если Ложь
Или СтрокиРавныЛкс(ДоступноеПоле.ПутьКДанным, "НомерСообщения")
Тогда
Продолжить;
КонецЕсли;
СписокПолей.Добавить(ДоступноеПоле.ТипЗначения, ДоступноеПоле.ПутьКДанным);
КонецЦикла;
ИначеЕсли ТипТаблицы = "Внешняя" Тогда
ТаблицаМД = Метаданные.НайтиПоПолномуИмени(ПолноеИмяТаблицыБД);
Если ТаблицаМД.ТипДанныхТаблицы = Метаданные.СвойстваОбъектов.ТипДанныхТаблицыВнешнегоИсточникаДанных.ОбъектныеДанные Тогда
СписокПолей.Добавить(Новый ОписаниеТипов(ПолучитьИмяТипаДанныхТаблицыРегистраЛкс(ПолноеИмяТаблицыБД, "Ссылка")), "Ссылка");
Иначе
НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
СписокПолей.Добавить(ЭлементОтбора.ТипЗначения, ЭлементОтбора.Имя);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ВернутьСтруктуру Тогда
Результат = Новый Структура();
Для Каждого ЭлементСписка Из СписокПолей Цикл
Результат.Вставить(ЭлементСписка.Представление, ЭлементСписка.Значение);
КонецЦикла;
Иначе
Результат = СписокПолей;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьXMLКлючОбъектаБДЛкс(Знач ОбъектДанных, Знач ИспользоватьСсылкуДляСсылочных = Ложь) Экспорт
Если ОбъектДанных = Неопределено Тогда
Результат = "Неопределено";
Возврат Результат;
КонецЕсли;
ПредставлениеОбъекта = "";
Если ТипЗнч(ОбъектДанных) = Тип("УдалениеОбъекта") Тогда
Класс = "Удаление";
Иначе
Попытка
ЭтоНовый = ОбъектДанных.ЭтоНовый();
Класс = "Ссылочный";
ПредставлениеОбъекта = "" + ОбъектДанных + ",";
Исключение
Попытка
УникальныйИдентификатор = ОбъектДанных.УникальныйИдентификатор();
Класс = "Ссылочный";
Исключение
Попытка
Пустышка = ОбъектДанных.Модифицированность();
Класс = "НаборЗаписей";
Исключение
Попытка
Пустышка = ОбъектДанных.Значение;
Класс = "Константы";
Исключение
Класс = "Примитив";
КонецПопытки;
КонецПопытки;
КонецПопытки;
КонецПопытки;
Если Истина
И Класс = "Ссылочный"
И ИспользоватьСсылкуДляСсылочных
Тогда
Результат = ОбъектДанных;
Возврат Результат;
КонецЕсли;
КонецЕсли;
XMLКлюч = "" + XMLТипЗнч(ОбъектДанных).ИмяТипа + "(";
Если Класс = "Ссылочный" Тогда
Если ЭтоНовый = Истина Тогда
УникальныйИдентификатор = "!" + ОбъектДанных.ПолучитьСсылкуНового().УникальныйИдентификатор();
КонецЕсли;
Если УникальныйИдентификатор = Неопределено Тогда
УникальныйИдентификатор = ОбъектДанных.Ссылка.УникальныйИдентификатор();
КонецЕсли;
XMLКлюч = XMLКлюч + ПредставлениеОбъекта + УникальныйИдентификатор;
ИначеЕсли Класс = "Удаление" Тогда
XMLКлюч = XMLКлюч + ПолучитьXMLКлючОбъектаБДЛкс(ОбъектДанных.Ссылка);
ИначеЕсли Класс = "НаборЗаписей" Тогда
ПредставлениеОтбора = "";
Разделитель = ", ";
Для Каждого ЭлементОтбора Из ОбъектДанных.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ПредставлениеОтбора = ПредставлениеОтбора + Разделитель + ЭлементОтбора.Имя
+ ":" + ПолучитьXMLКлючОбъектаБДЛкс(ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
XMLКлюч = XMLКлюч + Сред(ПредставлениеОтбора, СтрДлина(Разделитель) + 1);
ИначеЕсли Класс = "Константы" Тогда
//
Иначе
// Примитивный тип
XMLКлюч = XMLКлюч + ОбъектДанных;
КонецЕсли;
XMLКлюч = XMLКлюч + ")";
Результат = XMLКлюч;
Возврат Результат;
КонецФункции
// Параметры:
// Объект - ОбъектБД, ОбъектМД
Функция ПолучитьТабличныеЧастиОбъектаЛкс(Объект) Экспорт
Если ТипЗнч(Объект) = Тип("ОбъектМетаданных") Тогда
мдОбъекта = Объект;
ОбъектБД = Неопределено;
Иначе
мдОбъекта = Объект.Метаданные();
ОбъектБД = Объект;
КонецЕсли;
СтруктураТЧ = Новый Структура();
ЭтоСправочник = Метаданные.Справочники.Индекс(мдОбъекта) >= 0;
Если Не ЛиСсылочныйОбъектМетаданных(мдОбъекта, Ложь) Тогда
Возврат СтруктураТЧ;
КонецЕсли;
Для Каждого МетаТЧ из мдОбъекта.ТабличныеЧасти Цикл
// Для реквизитов справочников, принадлежащих только группе или только элементу нужно игнорировать те объекты, для которых эти реквизиты не используются
Если Истина
И ЭтоСправочник
И ОбъектБД <> Неопределено
Тогда
Если Ложь
Или (Истина
И ОбъектБД.ЭтоГруппа
И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента)
Или (Истина
И Не ОбъектБД.ЭтоГруппа
И МетаТЧ.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы)
Тогда
Продолжить
КонецЕсли;
КонецЕсли;
СтруктураТЧ.Вставить(МетаТЧ.Имя, МетаТЧ.Представление());
КонецЦикла;
Если Метаданные.ПланыСчетов.Индекс(мдОбъекта) >= 0 Тогда
Если мдОбъекта.ВидыСубконто <> Неопределено Тогда
СтруктураТЧ.Вставить("ВидыСубконто", "Виды субконто");
КонецЕсли;
КонецЕсли;
Если Метаданные.ПланыВидовРасчета.Индекс(мдОбъекта) >= 0 Тогда
Если мдОбъекта.ЗависимостьОтВидовРасчета <> Метаданные.СвойстваОбъектов.ИспользованиеБазыПланаВидовРасчета.НеИспользовать Тогда
СтруктураТЧ.Вставить("БазовыеВидыРасчета", "Базовые виды расчета");
КонецЕсли;
СтруктураТЧ.Вставить("ВедущиеВидыРасчета", "Ведущие виды расчета");
Если мдОбъекта.ИспользованиеПериодаДействия Тогда
СтруктураТЧ.Вставить("ВытесняющиеВидыРасчета", "Вытесняющие виды расчета");
КонецЕсли;
КонецЕсли;
Возврат СтруктураТЧ;
КонецФункции
Функция ЛиСтрокаСодержитВсеПодстрокиЛкс(Знач Строка, Знач Подстроки) Экспорт
Если ТипЗнч(Подстроки) = Тип("Строка") Тогда
Подстроки = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина);
КонецЕсли;
НСтрока = НРег(Строка);
Для Каждого Фрагмент Из Подстроки Цикл
Если Найти(НСтрока, Фрагмент) = 0 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Функция ПолучитьСтрокуТаблицыБДПоКлючуЛкс(ПолноеИмяТаблицы, СтруктураКлюча) Экспорт
Запрос = Новый Запрос;
ТекстЗапроса = "ВЫБРАТЬ Т.* ИЗ " + ПолноеИмяТаблицы + " КАК Т ГДЕ ИСТИНА ";
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
ТекстЗапроса = ТекстЗапроса + " И Т." + КлючИЗначение.Ключ + " = &" + КлючИЗначение.Ключ;
КонецЦикла;
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураКлюча, Запрос.Параметры);
Запрос.Текст = ТекстЗапроса;
СтрокаРезультата = Запрос.Выполнить().Выгрузить()[0];
Возврат СтрокаРезультата;
КонецФункции
// Присваивает ячейке по указателю значение. Если после этого ячейка получает другое значение, то ячейке присваивается ее старое значение.
Функция БезопасноПрисвоитьПроизвольнуюСсылкуЛкс(П1, П2) Экспорт
СтароеП1 = П1;
П1 = П2;
Если П1 <> П2 Тогда
П1 = СтароеП1;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // БезопасноПрисвоитьПроизвольнуюСсылку()
// ЛиНаходитьОбразующий - Булево - находить ближайший объект метаданных, если точный найти не удается
Функция НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД, ЛиНаходитьОбразующий = Ложь) Экспорт
Результат = Неопределено;
Если Истина
И Не ПустаяСтрока(ПолноеИмяТаблицыБД)
И ПолноеИмяТаблицыБД <> "Константы"
Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
ОбразующийМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]);
Если Ложь
Или ОбразующийМД = Неопределено
Или Фрагменты.Количество() = 2
Тогда
Результат = ОбразующийМД;
Иначе
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда
ДочерняяКоллекция = ОбразующийМД.ТабличныеЧасти;
ИначеЕсли Фрагменты[0] = "РегистрРасчета" Тогда
ДочерняяКоллекция = ОбразующийМД.Перерасчеты;
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ДочерняяКоллекция = ОбразующийМД.Таблицы;
Если Фрагменты.Количество() = 4 Тогда
Результат = ДочерняяКоллекция.Найти(Фрагменты[3]);
КонецЕсли;
//ИначеЕсли Фрагменты[0] = "РегистрБухгалтерии" Тогда
ИначеЕсли Ложь
Или ЛиКорневойТипРегистраБДЛкс(Фрагменты[0])
Или Фрагменты[0] = "Константа"
Тогда
Результат = ОбразующийМД;
Иначе
ВызватьИсключение "Неизвестный корневой тип метаданных(" + Фрагменты[0] + ") с дочерней таблицей";
КонецЕсли;
Если Результат = Неопределено И Фрагменты.Количество() = 3 Тогда
ДочернийОбъектМД = ДочерняяКоллекция.Найти(Фрагменты[2]);
Если ДочернийОбъектМД <> Неопределено Тогда
Результат = ДочернийОбъектМД;
ИначеЕсли ЛиНаходитьОбразующий Тогда
// ВидыСубконто, Изменения
Результат = ОбразующийМД;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПолучитьМетаданныеЛкс()
Функция ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ИмяТаблицыБД) Экспорт
ОписаниеТаблицыБД = ПолучитьОписаниеТаблицыБДИис(ИмяТаблицыБД);
Если Истина
И ОписаниеТаблицыБД <> Неопределено
И ОписаниеТаблицыБД.Тип = "Точки"
Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИмяТаблицыБД);
Результат = "ТочкаМаршрутаБизнесПроцессаСсылка." + Фрагменты[1];
Иначе
Результат = СтрЗаменить(ИмяТаблицыБД, ".", "Ссылка.");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьОписаниеТаблицыБДИис(ИмяТаблицыБД) Экспорт
Возврат ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Найти(НРег(ИмяТаблицыБД), "НПолноеИмя");
КонецФункции
Функция ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицыБД) Экспорт
//ОписаниеТаблицы = ирКэш.ПолучитьТаблицуВсехТаблицБДЛкс().Найти(НРег(ПолноеИмяТаблицыБД), "НПолноеИмя");
//Если ОписаниеТаблицы <> Неопределено Тогда
// Возврат ОписаниеТаблицы.Тип;
//КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяТаблицыБД);
ТипТаблицы = Фрагменты[0];
Если Фрагменты.Количество() > 2 Тогда
ПоследнийФрагмент = Фрагменты[Фрагменты.ВГраница()];
Если Ложь
Или ПоследнийФрагмент = "Изменения"
Или ПоследнийФрагмент = "ДвиженияССубконто"
Или ПоследнийФрагмент = "Границы"
Тогда
ТипТаблицы = ПоследнийФрагмент;
//// Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(МассивФрагментов[0]) Тогда
//// //ТипТаблицы = "ТабличнаяЧасть";
//// ТипТаблицы = МассивФрагментов[2];
//// КонецЕсли;
Иначе
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(Фрагменты[0]) Тогда
ОбъектМД = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ПолноеИмяТаблицыБД);
Если ОбъектМД = Неопределено Тогда
ТипТаблицы = Фрагменты[2];
Иначе
ТипТаблицы = "ТабличнаяЧасть";
КонецЕсли;
//ИначеЕсли СтрокиРавныЛкс(Фрагменты[2], "ДвиженияССубконто") Тогда
// ТипТаблицы = Фрагменты[0];
ИначеЕсли Фрагменты[0] = "РегистрРасчета" Тогда
ТипТаблицы = "Перерасчет";
ИначеЕсли Фрагменты[0] = "ВнешнийИсточникДанных" Тогда
ТипТаблицы = "Внешняя";
Иначе
ТипТаблицы = "ВиртуальнаяТаблица";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ТипТаблицы;
КонецФункции
// ВариантИсточников - Число, *0
// 0 - Основные таблицы
// 1 - Таблицы изменений
// 2 - Внутреннее соединение основных таблиц с их таблицами изменений с отбором по узлу
Функция ПолучитьТекстЗапросаПоВыбраннымТаблицамЛкс(МассивИменОбъектовМД, ВариантИсточников = 0, ПервыеNКаждойТаблицы = 0, ПодключатьПоляКоличестваДвижений = Ложь) Экспорт
ЛитералЗаменыОтсутствующихПолей = "НЕОПРЕДЕЛЕНО"; // NULL нельзя использовать из-за ошибок платформы 8.2.14
// Сначала определим общие реквизиты
ПроверяемыеПоля = Новый Массив;
ТипыОбъектовМД = Новый Структура;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
ТипОбъектаМД = ПолучитьТипТаблицыБДЛкс(ИмяОбъектаМД);
ТипыОбъектовМД.Вставить(ТипОбъектаМД);
КонецЦикла;
Если ТипыОбъектовМД.Количество() > 1 Тогда
ТипОбъектаМД = Неопределено;
КонецЕсли;
Если ЗначениеЗаполнено(ТипОбъектаМД) Тогда
ирКэш.Получить().ИнициализацияОписанияМетодовИСвойств();
СтрокаКорневогоТипа = ирКэш.Получить().ПолучитьСтрокуТипаМетаОбъектов(ТипОбъектаМД);
Если СтрокаКорневогоТипа <> Неопределено Тогда
СтрокаВида = ирКэш.Получить().ТаблицаИменЭлементовКоллекций.Найти(СтрокаКорневогоТипа.Множественное, "ИмяКоллекции");
Если СтрокаВида <> Неопределено Тогда
ИмяОбщегоТипа = ТипОбъектаМД + "." + СтрокаВида.ИмяЭлементаКоллекции;
Если ВариантИсточников = 1 Тогда
ИмяОбщегоТипа = ИмяОбщегоТипа + ".Изменения";
КонецЕсли;
СтрокиИменПолей = ирКэш.Получить().ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ЯзыкПрограммы", ИмяОбщегоТипа, 1));
Для Каждого СтрокаСлова Из СтрокиИменПолей Цикл
Если Ложь
Или СтрокаСлова.ТипСлова = "Таблица"
Тогда
Продолжить;
КонецЕсли;
ПроверяемыеПоля.Добавить(СтрокаСлова.Слово);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ТекстЗапроса = "";
// Находим максимум общих реквизитов
ОбщиеМетаПоля = Новый Массив;
ЭтоПервыйПроход = Истина;
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
ИмяТаблицы = ИмяОбъектаМД;
ОбъектМетаданных = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ИмяОбъектаМД);
Если ВариантИсточников > 0 Тогда
ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных);
Если ЕстьТаблицаИзменений Тогда
Если ВариантИсточников = 1 Тогда
ИмяТаблицы = ИмяОбъектаМД + ".Изменения";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КоллекцияПолей = Новый Массив();
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ИмяТаблицы);
#Если _ Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для Каждого ПолеТаблицы Из ПоляТаблицыБД Цикл
Если ПолеТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Продолжить;
КонецЕсли;
ИмяПоля = ПолеТаблицы.Имя;
Если Ложь
Или ПроверяемыеПоля.Найти(ИмяПоля) <> Неопределено
Тогда
Продолжить;
КонецЕсли;
КоллекцияПолей.Добавить(ИмяПоля);
КонецЦикла;
Если ЭтоПервыйПроход Тогда
Для Каждого ИмяПоля Из КоллекцияПолей Цикл
ОбщиеМетаПоля.Добавить(ИмяПоля);
КонецЦикла;
Иначе
НачальноеКоличество = ОбщиеМетаПоля.Количество();
Для СчетчикОбщиеМетаПоля = 1 По НачальноеКоличество Цикл
ИмяПоля = ОбщиеМетаПоля[НачальноеКоличество - СчетчикОбщиеМетаПоля];
Если КоллекцияПолей.Найти(ИмяПоля) = Неопределено Тогда
ОбщиеМетаПоля.Удалить(НачальноеКоличество - СчетчикОбщиеМетаПоля);
КонецЕсли;
КонецЦикла;
Если ОбщиеМетаПоля.Количество() = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
ЭтоПервыйПроход = Ложь;
КонецЦикла;
ТекстОбщихМетаПолей = "";
Для Каждого ИмяПоля Из ОбщиеМетаПоля Цикл
Если Истина
И ЛиКорневойТипСсылкиЛкс(МассивИменОбъектовМД[0])
И ВариантИсточников > 0
Тогда
ИмяПоля = "Ссылка." + ИмяПоля;
КонецЕсли;
ТекстОбщихМетаПолей = ТекстОбщихМетаПолей + ", Т." + ИмяПоля;
КонецЦикла;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(МассивИменОбъектовМД.Количество(), "Генерация текста запроса");
#КонецЕсли
Для Каждого ИмяОбъектаМД Из МассивИменОбъектовМД Цикл
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
ИмяТаблицы = ИмяОбъектаМД;
ОбъектМетаданных = НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы);
КорневойТипТаблицы = ирОбщий.ПолучитьПервыйФрагментЛкс(ИмяТаблицы);
ТекстУсловияСоединения = "";
Если ВариантИсточников > 0 Тогда
ЕстьТаблицаИзменений = ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМетаданных);
Если ЕстьТаблицаИзменений Тогда
Если ВариантИсточников = 1 Тогда
ИмяТаблицы = ИмяОбъектаМД + ".Изменения";
Иначе
ТекстУсловияСоединения = "_Изменения_.Узел = &Узел";
СтруктураКлючаИзменений = ирОбщий.ПолучитьСтруктуруКлючаТаблицыБДЛкс(ИмяТаблицы + ".Изменения");
Для Каждого КлючИЗначение Из СтруктураКлючаИзменений Цикл
Если ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Ключ, "Узел") Тогда
Продолжить;
КонецЕсли;
Если ТекстУсловияСоединения <> "" Тогда
ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " И";
КонецЕсли;
ТекстУсловияСоединения = ТекстУсловияСоединения + " _Изменения_." + КлючИЗначение.Ключ + " = Т." + КлючИЗначение.Ключ;
КонецЦикла;
ТекстУсловияСоединения = Символы.ПС + " ВНУТРЕННЕЕ СОЕДИНЕНИЕ " + ИмяТаблицы + ".Изменения КАК _Изменения_
| ПО " + ТекстУсловияСоединения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПодключатьПоляКоличестваДвижений Тогда
Если ирОбщий.ЛиКорневойТипДокументаЛкс(КорневойТипТаблицы) Тогда
ТекстОбщееКоличествоДвижений = "";
Для Каждого МетаРегистр Из ОбъектМетаданных.Движения Цикл
ПолноеИмяРегистра = МетаРегистр.ПолноеИмя();
КраткоеИмяРегистра = МетаРегистр.Имя;
ТекстУсловияСоединения = ТекстУсловияСоединения + Символы.ПС + " { ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ _Регистр_.Регистратор, КОЛИЧЕСТВО(*) КАК КоличествоСтрок
| ИЗ " + ПолноеИмяРегистра + " КАК _Регистр_ СГРУППИРОВАТЬ ПО _Регистр_.Регистратор) КАК " + КраткоеИмяРегистра + "
| ПО " + КраткоеИмяРегистра + ".Регистратор = Т.Ссылка}";
ВыражениеКоличества = "ЕСТЬNULL(" + КраткоеИмяРегистра + ".КоличествоСтрок, 0)";
Если ТекстОбщееКоличествоДвижений <> "" Тогда
ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + " + ";
КонецЕсли;
ТекстОбщееКоличествоДвижений = ТекстОбщееКоличествоДвижений + ВыражениеКоличества;
ТекстОбщееКоличествоДвижений = ВыражениеКоличества + " КАК КоличествоСтрок" + КраткоеИмяРегистра + ", " + ТекстОбщееКоличествоДвижений;
КонецЦикла;
Если ЗначениеЗаполнено(ТекстОбщееКоличествоДвижений) Тогда
ТекстУсловияСоединения = ТекстУсловияСоединения + "
|{ГДЕ " + ТекстОбщееКоличествоДвижений + " КАК КоличествоСтрокВсеРегистры}";
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ВариантИсточников <> 1 Тогда
ТекстНеобязательныхПолей = "";
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ИмяТаблицы);
#Если _ Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
Для Каждого ПроверяемоеПоле Из ПроверяемыеПоля Цикл
Если ПоляТаблицыБД.Найти(ПроверяемоеПоле, "Имя") = Неопределено Тогда
ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", " + ЛитералЗаменыОтсутствующихПолей + " КАК " + ПроверяемоеПоле;
Иначе
ТекстНеобязательныхПолей = ТекстНеобязательныхПолей + ", Т." + ПроверяемоеПоле;
КонецЕсли;
КонецЦикла;
//КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "
|ОБЪЕДИНИТЬ ВСЕ
|";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ ";
Если ЗначениеЗаполнено(ПервыеNКаждойТаблицы) Тогда
ТекстЗапроса = ТекстЗапроса + "ПЕРВЫЕ " + XMLСтрокаервыеNКаждойТаблицы) + " ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + """" + ИмяТаблицы + """ КАКолноеИмяТаблицы" + ТекстНеобязательныхПолей + ТекстОбщихМетаПолей + " ИЗ " + ИмяТаблицы + " КАК Т"
+ ТекстУсловияСоединения;
КонецЦикла;
//Если ЗначениеЗаполнено(ПервыеNОбщие) Тогда
// ТекстЗапроса = "ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрокаервыеNОбщие) + " * ИЗ (" + ТекстЗапроса + ") КАК Т";
//КонецЕсли;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Возврат ТекстЗапроса;
КонецФункции
Функция ЕстьТаблицаИзмененийОбъектаМетаданных(ПолноеИмяИлиОбъектМетаданных) Экспорт
ЕстьТаблицаИзменений = Ложь;
Если ТипЗнч(ПолноеИмяИлиОбъектМетаданных) = Тип("Строка") Тогда
ОбъектМетаданных = Метаданные.НайтиПоПолномуИмени(ПолноеИмяИлиОбъектМетаданных);
Если ОбъектМетаданных = Неопределено Тогда
ВызватьИсключение "Объект метаданных не найден """ + ПолноеИмяИлиОбъектМетаданных + """";
КонецЕсли;
Иначе
ОбъектМетаданных = ПолноеИмяИлиОбъектМетаданных;
КонецЕсли;
Для Каждого МетаПланОбмена Из Метаданные.ПланыОбмена Цикл
Если МетаПланОбмена.Состав.Содержит(ОбъектМетаданных) Тогда
ЕстьТаблицаИзменений = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ЕстьТаблицаИзменений;
КонецФункции
Функция СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект) Экспорт
Структура = Новый Структура;
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Если ОбменДанными <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
КонецЕсли;
Если ОбменДанными <> Неопределено Тогда
СтруктураОбменаДанными = Новый Структура;
СтруктураОбменаДанными.Вставить("Загрузка", ОбменДанными.Загрузка);
Если Получатели <> Неопределено Тогда
Узлы = Новый Массив;
Для Каждого Получатель Из ОбменДанными.Получатели Цикл
Узлы.Добавить(Получатель);
КонецЦикла;
Получатели = Новый Структура;
Получатели.Вставить("Автозаполнение", ОбменДанными.Получатели.Автозаполнение);
Получатели.Вставить("Узлы", Узлы);
СтруктураОбменаДанными.Вставить("Отправитель", ОбменДанными.Отправитель);
СтруктураОбменаДанными.Вставить("Получатели", Получатели);
КонецЕсли;
Структура.Вставить("ОбменДанными", СтруктураОбменаДанными);
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойстваXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект.ДополнительныеСвойства);
Структура.Вставить("ДополнительныеСвойстваXML", ДополнительныеСвойстваXML);
КонецЕсли;
Возврат Структура;
КонецФункции // СериализоватьПараметрыОбменаДанными()
Процедура ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, СтруктураДополнительныхСвойств) Экспорт
Если СтруктураДополнительныхСвойств.Свойство("ОбменДанными") Тогда
ОбменДанными = Объект.ОбменДанными;
СтруктураОбменаДанными = СтруктураДополнительныхСвойств.ОбменДанными;
ЗаполнитьЗначенияСвойств(ОбменДанными, СтруктураОбменаДанными);
Если СтруктураОбменаДанными.Свойство("Получатели") Тогда
ЗаполнитьЗначенияСвойств(ОбменДанными.Получатели, СтруктураОбменаДанными.Получатели);
ОбменДанными.Получатели.Очистить();
Для Каждого Получатель Из СтруктураОбменаДанными.Получатели.Узлы Цикл
ОбменДанными.Получатели.Добавить(Получатель);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Объект) <> Тип("УдалениеОбъекта") Тогда
ДополнительныеСвойства = ВосстановитьОбъектИзСтрокиXMLЛкс(СтруктураДополнительныхСвойств.ДополнительныеСвойстваXML);
СкопироватьУниверсальнуюКоллекциюЛкс(ДополнительныеСвойства, Объект.ДополнительныеСвойства);
КонецЕсли;
КонецПроцедуры // ВосстановитьПараметрыОбменаДаннымиЛкс()
// Записывает объект с параметризованным контекстом (клиент/сервер).
// Обеспечивает запись объекта с попытками. Позволяет обойти неинтенсивные дедлоки и превышения ожиданий блокировки.
// Также обеспечивает обход оптимистичных объектных блокировок в случае, если в БД пишутся точно те же данные объекта, что и актуальные.
// Эффективно для многопоточной записи объектов.
Процедура ЗаписатьОбъектЛкс(Объект, НаСервере = Ложь, РежимЗаписи = Неопределено, РежимПроведения = Неопределено, ОтключатьКонтрольЗаписи = Неопределено,
БезАвторегистрацииИзменений = Неопределено) Экспорт
Если НаСервере Тогда
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
ирСервер.ЗаписатьОбъектXMLЛкс(ОбъектXML, ДополнительныеСвойства, РежимЗаписи, РежимПроведения, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
//#Если Клиент Тогда
// Попытка
// СсылкаОбъекта = Объект.Ссылка;
// Исключение
// КонецПопытки;
// Если СсылкаОбъекта <> Неопределено Тогда
// // При групповых обработках видимо будут большие потери
// ОповеститьОбИзменении(СсылкаОбъекта);
// КонецЕсли;
//#КонецЕсли
Иначе
НачалоПопыток = ТекущаяДата();
// Для обхода дедлоков и оптимистичной объектной блокировки при высокой параллельности
Если РежимЗаписи = Неопределено Тогда
ПопытокЗаписиОбъекта = 5;
Иначе
ПопытокЗаписиОбъекта = 3;
КонецЕсли;
ПредельнаяДлительность = 20;
Для СчетчикПопыток = 1 По ПопытокЗаписиОбъекта Цикл
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Попытка
Если РежимЗаписи = Неопределено Тогда
Объект.Записать();
ИначеЕсли РежимЗаписи = "ПометкаУдаления" Тогда
Объект.Записать();
Объект.ОбменДанными.Загрузка = Ложь;
Объект.УстановитьПометкуУдаления(Не Объект.ПометкаУдаления);
ИначеЕсли Истина
И ТипЗнч(РежимЗаписи) = Тип("РежимЗаписиДокумента")
И РежимЗаписи <> РежимЗаписиДокумента.Запись
Тогда
Объект.ОбменДанными.Загрузка = Ложь;
Объект.Записать(РежимЗаписи, РежимПроведения);
Иначе
Объект.Записать(РежимЗаписи);
КонецЕсли;
Прервать;
Исключение
НужноВызватьИсключение = Истина;
ОписаниеОшибки = ОписаниеОшибки();
НовоеОписаниеОшибки = "";
Если ТранзакцияАктивна() Тогда
//НовоеОписаниеОшибки = "Транзакция активна" + Символы.ПС + ОписаниеОшибки;
Иначе
НОписаниеОшибки = НРег(ОписаниеОшибки);
Если Истина
И РежимЗаписи = Неопределено
И (Ложь
Или Найти(НОписаниеОшибки, "несоответствия версии или отсутствия записи базы данных") > 0
Или Найти(НОписаниеОшибки, "version mismatch or lack of database record") > 0)
Тогда
НужноВызватьИсключение = Ложь;
ТекущийXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект, Ложь);
//Объект.Прочитать(); // Чтение с блокировкой нам не нужно
ОбъектДляСравнения = ПеречитатьОбъектЗапросомЛкс(Объект);
Если Объект <> Неопределено Тогда
НовыйXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ОбъектДляСравнения, Ложь);
Если ТекущийXML = НовыйXML Тогда
Прервать;
Иначе
Попытка
лРежимЗагрузка = Объект.ОбменДанными.Загрузка;
Исключение
лРежимЗагрузка = Неопределено;
КонецПопытки;
ПолноеИмяМД = Объект.Метаданные().ПолноеИмя();
Если лРежимЗагрузка = Истина И СчетчикПопыток = 2 Тогда
Сообщить("Возможно в обработчиках ПередЗаписью объекта " + ПолноеИмяМД + " в режиме Загрузка выполняется его нестабильная модификация");
КонецЕсли;
НужноВызватьИсключение = СчетчикПопыток = ПопытокЗаписиОбъекта;
Если НужноВызватьИсключение Тогда
НовоеОписаниеОшибки = "Обход оптимистичной блокировки объекта " + ПолноеИмяМД + " отменен из-за его нестабильной модификации в обработчиках ПередЗаписью (Загрузка="
+ XMLСтрока(лРежимЗагрузка) + ")" + Символы.ПС + ОписаниеОшибки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИначеЕсли Ложь
Или Найти(ОписаниеОшибки, "взаимоблокировк") > 0
Или Найти(ОписаниеОшибки, "deadlock") > 0
Тогда
НужноВызватьИсключение = Ложь;
КонецЕсли;
КонецЕсли;
Если Не НужноВызватьИсключение Тогда
Если СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли ТекущаяДата() - НачалоПопыток >= ПредельнаяДлительность Тогда
//НовоеОписаниеОшибки = "Кончилось время записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
ИначеЕсли СчетчикПопыток = ПопытокЗаписиОбъекта Тогда
//НовоеОписаниеОшибки = "Кончились попытки записи" + Символы.ПС + ОписаниеОшибки;
НужноВызватьИсключение = Истина;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
Если ВОписанииОшибкиЕстьПередачаМутабельногоЗначенияЛкс(НОписаниеОшибки, Ложь) Тогда
ВызватьИсключение;
КонецЕсли;
#КонецЕсли
Если НужноВызватьИсключение Тогда
СостояниеОбъекта = ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект);
Если ЗначениеЗаполнено(СостояниеОбъекта) Тогда
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
НовоеОписаниеОшибки = НовоеОписаниеОшибки + СостояниеОбъекта;
Иначе
НовоеОписаниеОшибки = ОписаниеОшибки + СостояниеОбъекта;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(НовоеОписаниеОшибки) Тогда
ВызватьИсключение НовоеОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецЕсли;
КонецПопытки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПредставлениеДопСвойствОбъектаЛкс(Объект)
Попытка
ДополнительныеСвойства = Объект.ДополнительныеСвойства;
Исключение
ДополнительныеСвойства = Новый Структура;
КонецПопытки;
СостояниеОбъекта = "";
Для Каждого КлючИЗначение Из ДополнительныеСвойства Цикл
СостояниеОбъекта = СостояниеОбъекта + Символы.ПС + КлючИЗначение.Ключ + ": " + КлючИЗначение.Значение;
КонецЦикла;
Возврат СостояниеОбъекта;
КонецФункции
// Позволяет перечитать объект грязным чтением, т.е. без учета блокировок. Не перечитывает свойство ВерсияДанных!
// На выходе объект имеет модифицированноть. Для удаленного объекта возвращает Неопределено.
Функция ПеречитатьОбъектЗапросомЛкс(Знач Объект) Экспорт
ОбъектМД = Объект.Метаданные();
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ * ИЗ " + ОбъектМД.ПолноеИмя() + " КАК Т ГДЕ Т.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
ТаблицаОбъекта = Запрос.Выполнить().Выгрузить();
Если ТаблицаОбъекта.Количество() > 0 Тогда
СтрокаДанных = ТаблицаОбъекта[0];
Для Каждого КолонкаТаблицы Из ТаблицаОбъекта.Колонки Цикл
ЗначениеРеквизита = СтрокаДанных[КолонкаТаблицы.Имя];
Если ЗначениеРеквизита = Null Тогда
// Реквизит (но не табличная часть) недоступен по признаку ЭтоГруппа. Если к нему обратиться у объекта, то будет ошибка "Ошибка установки значения свойства '...': Реквизит недоступен для группы"
Продолжить;
КонецЕсли;
Пустышка = Объект[КолонкаТаблицы.Имя]; // Проверяем корректность вычисления выражения перед его использованием в попытке
Если КолонкаТаблицы.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) Тогда
Попытка
Объект[КолонкаТаблицы.Имя].Загрузить(ЗначениеРеквизита);
Исключение
// Табличная часть недоступна по признаку ЭтоГруппа. Выдается ошибка "Ошибка при вызове метода контекста (Загрузить): Объект недоступен для изменения"
КонецПопытки;
Иначе
Попытка
Объект[КолонкаТаблицы.Имя] = ЗначениеРеквизита;
Исключение
// Реквизит предназначен только для чтения
КонецПопытки;
КонецЕсли;
КонецЦикла;
Иначе
Объект = Неопределено;
КонецЕсли;
Возврат Объект;
КонецФункции
// Антибаг платформы https://partners.v8.1c.ru/forum/topic/1168440
Процедура НаборЗаписейПослеЗагрузкиИзТаблицыЗначенийЛкс(НаборЗаписей) Экспорт
#Если _ Тогда
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
#КонецЕсли
ОбъектМД = НаборЗаписей.Метаданные();
КорневойТип = ПолучитьПервыйФрагментЛкс(ОбъектМД.ПолноеИмя());
Если КорневойТип = "РегистрБухгалтерии" Тогда
Для Каждого Проводка Из НаборЗаписей Цикл
ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Ресурсы, ОбъектМД);
ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, ОбъектМД.Измерения, ОбъектМД);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ОчиститьПоляРегистраБухгалтерииПоПризнакамУчетаЛкс(Проводка, КоллекцияПолей, ОбъектМД) Экспорт
Для Каждого Поле Из КоллекцияПолей Цикл
Если Истина
И Не Поле.Балансовый
И Поле.ПризнакУчета <> Неопределено
Тогда
ИмяПризнакаУчета = Поле.ПризнакУчета.Имя;
Если ОбъектМД.Корреспонденция Тогда
Если Не Проводка.СчетДт[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Дт"], Неопределено);
КонецЕсли;
Если Не Проводка.СчетКт[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя + "Кт"], Неопределено);
КонецЕсли;
Иначе
Если Не Проводка.Счет[ИмяПризнакаУчета] Тогда
ПрисвоитьЕслиНеРавноЛкс(Проводка[Поле.Имя], Неопределено);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УстановитьПараметрыЗаписиОбъектаЛкс(Знач Объект, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт
Попытка
ОбменДанными = Объект.ОбменДанными;
Исключение
// Элемент плана обмена в 8.3.4-
ОбменДанными = Неопределено;
КонецПопытки;
Если ОбменДанными <> Неопределено Тогда
Если ОтключатьКонтрольЗаписи <> Неопределено Тогда
ОбменДанными.Загрузка = ОтключатьКонтрольЗаписи;
КонецЕсли;
Если БезАвторегистрацииИзменений <> Неопределено Тогда
Попытка
Получатели = ОбменДанными.Получатели;
Исключение
// Элемент плана обмена в 8.3.5+
Получатели = Неопределено;
КонецПопытки;
Если Получатели <> Неопределено Тогда
Получатели.Автозаполнение = Не БезАвторегистрацииИзменений;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура УдалитьОбъектЛкс(Объект, НаСервере = Ложь, ОтключатьКонтрольЗаписи = Неопределено, БезАвторегистрацииИзменений = Неопределено) Экспорт
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, ОтключатьКонтрольЗаписи, БезАвторегистрацииИзменений);
Если НаСервере Тогда
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
ирСервер.УдалитьОбъектЛкс(ХМЛ, ДополнительныеСвойства);
#Если Клиент Тогда
ОповеститьОбИзменении(Объект.Ссылка);
#КонецЕсли
Иначе
Объект.Удалить();
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкуУдаленияОбъектаЛкс(Объект, НаСервере = Ложь, ЗначениеПометки = Истина, БезАвторегистрацииИзменений = Неопределено) Экспорт
Если НаСервере Тогда
ДополнительныеСвойства = СериализоватьДополнительныеСвойстваОбъектаЛкс(Объект);
ОбъектXML = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
ирСервер.УстановитьПометкуУдаленияОбъектаЛкс(ОбъектXML, ДополнительныеСвойства, ЗначениеПометки);
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(ОбъектXML);
ВосстановитьДополнительныеСвойстваОбъектаЛкс(Объект, ДополнительныеСвойства);
Иначе
УстановитьПараметрыЗаписиОбъектаЛкс(Объект, , БезАвторегистрацииИзменений);
//Если РежимЗаписи = Неопределено Тогда
// Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//Иначе
Объект.УстановитьПометкуУдаления(ЗначениеПометки);
//КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Источник - http://infostart.ru/public/125988/
Функция ВыбратьПоГруппировкамЛкс(Выборка, Группировки, СИерархией = Ложь) Экспорт
МетаВыборка = Новый Соответствие;
врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкам;
Если СИерархией Тогда
врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
КонецЕсли;
МетаВыборка.Вставить("ОбходРезультата", врОбходРезультата);
МассивГруппировок = Новый Массив;
врСтрГруппировки = Группировки;
Пока Истина Цикл
Поз = Найти( врСтрГруппировки, "," );
Если Поз = 0 Тогда
МассивГруппировок.Добавить(СокрЛП(врСтрГруппировки));
Прервать;
КонецЕсли;
МассивГруппировок.Добавить( СокрЛП( Лев(врСтрГруппировки,Поз-1) ) );
врСтрГруппировки = Сред( врСтрГруппировки, Поз+1 );
КонецЦикла;
МетаВыборка.Вставить("Группировки", МассивГруппировок);
врВыборка = Выборка;
Для пц=0 По МассивГруппировок.Количество()-2 Цикл
врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]);
МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня);
Если не врВыборкаУровня.Следующий() Тогда
Прервать;
КонецЕсли;
врВыборка = врВыборкаУровня;
КонецЦикла;
врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]);
МетаВыборка.Вставить("Выборка", врВыборкаУровня);
МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня);
Возврат МетаВыборка;
КонецФункции // ВыбратьПоГруппировкамЛкс
// Источник - http://infostart.ru/public/125988/
Функция СледующийПоГруппировкамЛкс(МетаВыборка, Уровень = Неопределено) Экспорт
Если Уровень = Неопределено Тогда
Уровень = МетаВыборка["Группировки"].Количество()-1;
КонецЕсли;
Если Уровень < 0 Тогда
Возврат Ложь;
КонецЕсли;
врВыборка = МетаВыборка["_Выборка"+Строка(Уровень)];
Если врВыборка.Следующий() Тогда
Возврат Истина;
КонецЕсли;
Если СледующийПоГруппировкамЛкс(МетаВыборка, Уровень-1) Тогда
МассивГруппировок = МетаВыборка["Группировки"];
врВыборкаРодитель = МетаВыборка["_Выборка"+Строка(Уровень-1)];
врВыборка = врВыборкаРодитель.Выбрать(МетаВыборка["ОбходРезультата"],МассивГруппировок[Уровень]);
МетаВыборка["_Выборка"+Строка(Уровень)] = врВыборка;
Если Уровень = МассивГруппировок.Количество()-1 Тогда
МетаВыборка["Выборка"] = врВыборка;
КонецЕсли;
Возврат СледующийПоГруппировкамЛкс(МетаВыборка, Уровень);
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции // зфСледующийПоГруппировкам
// ИспользоватьОбщийКаталогНастроек - использовать значение ключа ConfLocation из файла conf.cfg
Функция ПолучитьКаталогНастроекПриложения1СЛкс(ИспользоватьОбщийКаталогНастроек = Истина, СоздатьЕслиОтсутствует = Ложь, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьКаталогНастроекПриложения1СЛкс(ИспользоватьОбщийКаталогНастроек, СоздатьЕслиОтсутствует);
Иначе
КаталогКонфигурацииПриложения = КаталогПрограммы() + "conf";
Если ИспользоватьОбщийКаталогНастроек Тогда
ФайлУказатель = Новый Файл(КаталогКонфигурацииПриложения + "\conf.cfg");
Если ФайлУказатель.Существует() Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ФайлУказатель.ПолноеИмя);
Текст = ТекстовыйДокумент.ПолучитьТекст();
НовыйКаталогКонфигурацииПриложения = ПолучитьСтрокуМеждуМаркерамиЛкс(Текст, "ConfLocation=", Символы.ПС);
НовыйКаталог = Новый Файл(НовыйКаталогКонфигурацииПриложения);
Если НовыйКаталог.Существует() Тогда
КаталогКонфигурацииПриложения = НовыйКаталогКонфигурацииПриложения;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если СоздатьЕслиОтсутствует Тогда
Файл = Новый Файл(КаталогКонфигурацииПриложения);
Если Не Файл.Существует() Тогда
СоздатьКаталог(КаталогКонфигурацииПриложения);
КонецЕсли;
КонецЕсли;
Результат = КаталогКонфигурацииПриложения;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс();
Иначе
КаталогКонфигурацииПриложения = ПолучитьКаталогНастроекПриложения1СЛкс(Ложь);
Результат = КаталогКонфигурацииПриложения + "\logcfg.xml";
Файл = Новый Файл(Результат);
Если Файл.Существует() Тогда
Возврат Результат;
КонецЕсли;
КаталогКонфигурацииПриложения = ПолучитьКаталогНастроекПриложения1СЛкс(Истина);
Результат = КаталогКонфигурацииПриложения + "\logcfg.xml";
Файл = Новый Файл(Результат);
Если Файл.Существует() Тогда
Возврат Результат;
КонецЕсли;
Результат = Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьКаталогТехножурналаЛкс(НаСервере = Ложь) Экспорт
ИмяФайлаНастроекЖурнала = ПолучитьИмяФайлаАктивнойНастройкиТехноЖурналаЛкс(НаСервере);
Если ЗначениеЗаполнено(ИмяФайлаНастроекЖурнала) Тогда
ТекстХМЛ = ПрочитатьТекстИзФайлаЛкс(ИмяФайлаНастроекЖурнала, , НаСервере);
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.УстановитьСтроку(ТекстХМЛ);
ПостроительДом = Новый ПостроительDOM();
Попытка
ДокументДОМ = ПостроительДом.Прочитать(ЧтениеХМЛ);
Исключение
Сообщить("Ошибка чтения настройки техножурнала: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Если ДокументДОМ <> Неопределено Тогда
Узлы = ДокументДом.ПолучитьЭлементыПоИмени("log");
Если Узлы.Количество() > 0 Тогда
Атрибут = Узлы.Элемент(0).Атрибуты.ПолучитьИменованныйЭлемент("location");
Если Атрибут <> Неопределено Тогда
Результат = Атрибут.ТекстовоеСодержимое;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиТехножурналВключенЛкс(НаСервере = Ложь, ВыводитьСообщения = Ложь) Экспорт
КаталогЖурнала = "";
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
Если НаСервере Тогда
#Если Клиент Тогда
КаталогЖурнала = ВосстановитьЗначение("ирАнализТехножурнала.КаталогЖурналаСервера");
КаталогЖурналаВзятИзНастроекЧтения = Истина;
#КонецЕсли
КонецЕсли;
Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда
КаталогЖурнала = ПолучитьКаталогТехножурналаЛкс(НаСервере);
КаталогЖурналаВзятИзНастроекЧтения = Ложь;
КонецЕсли;
Если ЗначениеЗаполнено(КаталогЖурнала) Тогда
Если Не ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере, ВыводитьСообщения) Тогда
Возврат Истина;
Иначе
Если ВыводитьСообщения Тогда
Если КаталогЖурналаВзятИзНастроекЧтения Тогда
Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в настройках чтения анализа техножурнала", СтатусСообщения.Внимание);
Иначе
Сообщить("Каталог техножурнала """ + КаталогЖурнала + """ недоступен. Использован каталог, заданный в текущей настройке техножурнала", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если ВыводитьСообщения Тогда
Если НаСервере Тогда
Сообщить("Каталог техножурнала сервера не удалось прочитать из текущей настройки техножурнала и не задан в настройках чтения инструмента ""Анализ техножурнала""");
Иначе
Сообщить("Каталог техножурнала клиента не удалось прочитать из текущей настройки техножурнала");
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьСообщения = Истина) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала);
Иначе
Результат = Ложь;
ФайлКаталог = Новый Файл(КаталогЖурнала);
Если Не ФайлКаталог.Существует() Тогда
Результат = Истина;
Иначе
БлокирующиеФайлы = НайтиФайлы(КаталогЖурнала, "*.*");
Для Каждого БлокирующийФайл Из БлокирующиеФайлы Цикл
Если Не БлокирующийФайл.ЭтоКаталог() Тогда
Если ВыводитьСообщения Тогда
ТекстСообщения = "В корне каталога """ + КаталогЖурнала + """ техножурнала ";
Если НаСервере Тогда
ТекстСообщения = ТекстСообщения + "сервера";
Иначе
ТекстСообщения = ТекстСообщения + "клиента";
КонецЕсли;
Сообщить(ТекстСообщения + " обнаружены блокирующие файлы. Для работы журнала их необходимо удалить.",
СтатусСообщения.Внимание);
КонецЕсли;
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЛиКлиентЗапущенНаКомпьютереСервераЛкс() Экспорт
Результат = НРег(ирСервер.ПолучитьИмяКомпьютераЛкс()) = НРег(ИмяКомпьютера());
Возврат Результат;
КонецФункции
Функция ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
ирСервер.ЗаписатьТекстВФайлЛкс(ПолноеИмяФайла, Текст, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Текст);
ТекстовыйДокумент.Записать(ПолноеИмяФайла, Кодировка);
КонецЕсли;
КонецФункции
Функция ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка = Неопределено, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПрочитатьТекстИзФайлаЛкс(ПолноеИмяФайла, Кодировка);
Иначе
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ПолноеИмяФайла, Кодировка);
Результат = ТекстовыйДокумент.ПолучитьТекст();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НайтиИменаФайловЛкс(Путь, Маска = Неопределено, ИскатьВПодкаталогах = Истина, НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.НайтиИменаФайловЛкс(Путь, Маска, ИскатьВПодкаталогах);
Иначе
Файлы = НайтиФайлы(Путь, Маска, ИскатьВПодкаталогах);
Результат = Новый Массив;
Для Каждого Файл Из Файлы Цикл
Результат.Добавить(Файл.ПолноеИмя);
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ИзданиеПлатформы - Строка(0,П)
//
Функция ПолучитьКаталогПустойИнфобазыЛкс(Знач ИзданиеПлатформы = "") Экспорт
Если Не ЗначениеЗаполнено(ИзданиеПлатформы) Тогда
ИзданиеПлатформы = ирКэш.Получить().ИДВерсииПлатформы;
КонецЕсли;
ShellApplication = Новый COMobject("Shell.Application");
КаталогПустойИнфобазы = ShellApplication.NameSpace(28).Self.Path;
КаталогПустойИнфобазы = КаталогПустойИнфобазы + "\1C\1Cv" + ИзданиеПлатформы + "\EmptyDB";
Результат = КаталогПустойИнфобазы;
Возврат Результат;
КонецФункции
// Параметры:
// СоздаватьБазуВСлучаеОтсутствия - Булево
//
Функция ПолучитьСтрокуСоединенияПустойИнфобазыЛкс(ИзданиеПлатформы = "", Знач СоздаватьБазуВСлучаеОтсутствия = Истина) Экспорт
КаталогПустойИнфобазы = ПолучитьКаталогПустойИнфобазыЛкс(ИзданиеПлатформы);
Если СоздаватьБазуВСлучаеОтсутствия Тогда
ФайлПустойИнфобазы = Новый Файл(КаталогПустойИнфобазы + "\1CV8.1CD");
Если Не ФайлПустойИнфобазы.Существует() Тогда
СтрокаПараметров = "CREATEINFOBASE File=" + КаталогПустойИнфобазы + ";";
//СтрокаПараметров = СтрокаПараметров + " /AddInList ууууу";
ИмяФайлаЛога = ПолучитьИмяВременногоФайла();
СтрокаПараметров = СтрокаПараметров + " /out" + ИмяФайлаЛога;
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8.exe"" " + СтрокаПараметров;
ирКэш.Получить().ЗапуститьСкрытоеПриложениеИДождатьсяЗавершения(СтрокаЗапуска); //ВыполнитьСкрытуюКомандуОС
КонецЕсли;
КонецЕсли;
СтрокаСоединения = "File=""" + КаталогПустойИнфобазы + """;";
Результат = СтрокаСоединения;
Возврат Результат;
КонецФункции
// Создает COM объект клиента 1C и подключает его к базе по указанной строке соединения.
// Параметры:
// СтрокаСоединения - Строка
// ИмяПользователя - Строка
// ПарольПользователя - Строка
// ТипCOMОбъекта - Строка, *"Application" - "Application" или "ComConnector"
// Видимость - Булево - для Application
// ОбработатьИсключениеПодключения - Булево, *Ложь - при Истина исключение обрабатывается внутри метода и возвращется его описание в качестве результата
// ИмяСервераПроцессов - Строка - имя сервера, на котором создавать COM объект
//
// Возвращаемое значение:
// COMОбъект - клиента 1C, Строка - описание исключения
//
Функция СоздатьСеансИнфобазы1С8Лкс(Знач СтрокаСоединения = "", Знач ИмяПользователя = "", Знач ПарольПользователя = "",
Знач ТипCOMОбъекта = "Application", Знач Видимость = Ложь, Знач ОбработатьИсключениеПодключения = Ложь,
ОписаниеОшибки = "", ИмяСервераПроцессов = "", КодРазрешения = "") Экспорт
ДопСтрокаСоединения = "";
Если ЗначениеЗаполнено(ИмяПользователя) Тогда
ДопСтрокаСоединения = ДопСтрокаСоединения + "Usr=""" + ИмяПользователя + """;" + "Pwd=""" + ПарольПользователя + """;";
КонецЕсли;
Если ЗначениеЗаполнено(КодРазрешения) Тогда
ДопСтрокаСоединения = ДопСтрокаСоединения + "UC=""" + КодРазрешения + """;";
КонецЕсли;
#Если Клиент Тогда
Состояние("Подключение к базе через COM...");
#КонецЕсли
ИмяCOMКласса = "v" + ирКэш.Получить().ИДВерсииПлатформы;
Если Найти(ТипCOMОбъекта, ".") = 0 Тогда
ИмяCOMКласса = ИмяCOMКласса + ".";
КонецЕсли;
ИмяCOMКласса = ИмяCOMКласса + ТипCOMОбъекта;
Соединение = Новый COMОбъект(ИмяCOMКласса, ИмяСервераПроцессов);
Если Не ЗначениеЗаполнено(СтрокаСоединения) Тогда
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КонецЕсли;
ПолнаяСтрокаСоединения = СтрокаСоединения + ДопСтрокаСоединения;
Попытка
РезультатСоединения = Соединение.Connect(ПолнаяСтрокаСоединения);
Исключение
#Если Клиент Тогда
Состояние("");
#КонецЕсли
Если ОбработатьИсключениеПодключения Тогда
ОписаниеОшибки = ОписаниеОшибки();
Возврат ОписаниеОшибки;
Иначе
ВызватьИсключение;
КонецЕсли;
КонецПопытки;
#Если Клиент Тогда
Состояние("");
#КонецЕсли
мПлатформа = ирКэш.Получить();
Если Найти(ТипCOMОбъекта, "Application") > 0 Тогда
#Если Клиент Тогда
Состояние("Ожидание инициализации сеанса...");
Для Счетчик = 1 По 20 Цикл
ОбработкаПрерыванияПользователя();
Попытка
Соединение.Visible = Видимость;
Прервать;
Исключение
// Тонкий клиент еще не готов
КонецПопытки;
мПлатформа.Sleep(1);
КонецЦикла;
Состояние("");
Результат = Соединение;
#КонецЕсли
ИначеЕсли Найти(ТипCOMОбъекта, "ComConnector") > 0 Тогда
Результат = РезультатСоединения;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗапуститьСеансПодПользователемЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта = "", РежимЗапуска = "Авто", КодРазрешения = "",
СообщитьКоманднуюСтроку = Ложь, ОткрытьПортативныеИнструменты = Истина, ОчисткаКэшаКлиентСерверныхВызовов = Истина, РазрешитьОтладку = Истина, ДополнительныеПараметры = "") Экспорт
Если ЗначениеЗаполнено(ТипCOMОбъекта) Тогда
Соединение = СоздатьСеансИнфобазы1С8Лкс(, ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, ТипCOMОбъекта, Истина,,,, КодРазрешения);
Иначе
#Если Клиент Тогда
//Если ирКэш.Получить().ВерсияПлатформы = 802015 Тогда
// Предупреждение("В релиза 8.2.15 функция недоступна", 20); // Антибаг платформы 8.2.15
// Возврат;
//КонецЕсли;
Если РежимЗапуска = "Авто" Тогда
// Антибаг платформы. При передачи этого режима в явном виде в некоторых случаях пароль в командной строке игнорируется
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяИнфобазы);
Если ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда
КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий";
ИначеЕсли ПользовательИБ.РежимЗапуска = РежимЗапускаКлиентскогоПриложения.ОбычноеПриложение Тогда
КонечныйРежимЗапуска = "ОбычноеПриложение";
Иначе //Авто
Если Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда
КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий";
Иначе
КонечныйРежимЗапуска = "ОбычноеПриложение";
КонецЕсли;
КонецЕсли;
Иначе
КонечныйРежимЗапуска = РежимЗапуска;
КонецЕсли;
ПараметрыЗапуска = ПолучитьПараметрыЗапускаПриложения1СТекущейБазыЛкс(ИмяПользователяИнфобазы, ПарольПользователяИнфобазы, КодРазрешения, Ложь, КонечныйРежимЗапуска,
РазрешитьОтладку, ОчисткаКэшаКлиентСерверныхВызовов, ДополнительныеПараметры, СообщитьКоманднуюСтроку, , ОткрытьПортативныеИнструменты);
ТекущаяДата = ирСервер.ПолучитьТекущуюДатуЛкс();
Если КонечныйРежимЗапуска = "УправляемоеПриложениеТонкий" Тогда
СтрокаЗапуска = """" + КаталогПрограммы() + "1cv8c.exe"" " + ПараметрыЗапуска;
ЗапуститьПриложение(СтрокаЗапуска);
Иначе
ЗапуститьСистему(ПараметрыЗапуска);
КонецЕсли;
Состояние("Ожидание запуска сеанса...");
Успех = Ложь;
ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс();
Пока Не Успех Цикл
ОбработкаПрерыванияПользователя();
Если ирСервер.ПолучитьТекущуюДатуЛкс() - ДатаПоследнегоВопроса >= 5 Тогда
Ответ = Вопрос("Продолжить ожидание сеанса (5 сек)?", РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Нет Тогда
Прервать;
КонецЕсли;
ДатаПоследнегоВопроса = ирСервер.ПолучитьТекущуюДатуЛкс();
КонецЕсли;
Сеансы = ПолучитьСеансыИнформационнойБазы();
Успех = Ложь;
Для Каждого Сеанс Из Сеансы Цикл
Если Истина
И Сеанс.НачалоСеанса >= ТекущаяДата
И НРег(Сеанс.ИмяКомпьютера) = НРег(ИмяКомпьютера())
И Сеанс.Пользователь <> Неопределено
И НРег(Сеанс.Пользователь.Имя) = НРег(ИмяПользователяИнфобазы)
Тогда
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Состояние("");
#Иначе
ВызватьИсключение "Запуск приложения допускается только на клиенте";
#КонецЕсли
КонецЕсли;
Возврат Соединение;
КонецФункции
// Параметры:
// XML -
// Тип -
// ИспользоватьXDTO -
// СообщатьОбОшибках -
//
Функция ВосстановитьОбъектИзСтрокиXMLЛкс(Знач ФайлИлиXML = "", Знач Тип = "", Знач ИспользоватьXDTO = Истина, Знач СообщатьОбОшибках = Истина) Экспорт
Если Ложь
Или ТипЗнч(ФайлИлиXML) = Тип("Файл")
Или ЗначениеЗаполнено(ФайлИлиXML)
Тогда
ЧтениеXML = Новый ЧтениеXML;
Если ТипЗнч(ФайлИлиXML) = Тип("Файл") Тогда
ЧтениеXML.ОткрытьФайл(ФайлИлиXML);
Иначе
ЧтениеXML.УстановитьСтроку(ФайлИлиXML);
КонецЕсли;
Попытка
Если ИспользоватьXDTO Тогда
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Иначе
Результат = ПрочитатьXML(ЧтениеXML);
КонецЕсли;
Исключение
Если СообщатьОбОшибках Тогда
Сообщить(ОписаниеОшибки(), СтатусСообщения.Важное);
КонецЕсли;
ЧтениеXML.Закрыть();
КонецПопытки;
// Антибаг платформы 8.2-8.3.6 СериализаторXDTO некорректно восстанавливает пустую табличную часть поверх непустой https://partners.v8.1c.ru/forum/t/1329468/m/1329468
Попытка
Пустышка = Результат.Модифицированность();
МетаТЧи = Результат.Метаданные().ТабличныеЧасти;
Исключение
МетаТЧи = Новый Массив;
КонецПопытки;
Для Каждого МетаТЧ Из МетаТЧи Цикл
ТЧ = Результат[МетаТЧ.Имя];
Если ТЧ.Количество() = 0 Тогда
Попытка
ТЧ.Вставить(0);
Исключение
// Недоступна по разделению группа/элемент с неадекватной ошибкой https://partners.v8.1c.ru/forum/t/1374212/m/1374212
Продолжить;
КонецПопытки;
ТЧ.Удалить(0);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Результат = Неопределено Тогда
Если ЗначениеЗаполнено(Тип) Тогда
Результат = Новый (Тип);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВосстановитьНастройкуКомпоновкиИзСтрокиXMLЛкс(Знач XML = "", Знач СообщатьОбОшибках = Истина) Экспорт
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(XML, Тип("НастройкиКомпоновкиДанных"), , СообщатьОбОшибках);
Возврат Результат;
КонецФункции
// Параметры:
// Объект -
// ИспользоватьXDTO -
//
Функция СохранитьОбъектВВидеСтрокиXMLЛкс(Знач Объект, Знач ИспользоватьXDTO = Истина, ИмяФайла = "", СообщатьОбОшибках = Истина) Экспорт
Поток = Новый ЗаписьXML;
Если ЗначениеЗаполнено(ИмяФайла) Тогда
Поток.ОткрытьФайл(ИмяФайла);
Иначе
Поток.УстановитьСтроку();
КонецЕсли;
Попытка
Если ИспользоватьXDTO Тогда
СериализаторXDTO.ЗаписатьXML(Поток, Объект);
Иначе
ЗаписатьXML(Поток, Объект);
КонецЕсли;
Исключение
Поток.Закрыть();
Если СообщатьОбОшибках Тогда
ВызватьИсключение;
КонецЕсли;
Поток = Неопределено;
КонецПопытки;
Если Поток = Неопределено Тогда
Результат = Неопределено;
Иначе
Результат = Поток.Закрыть();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ЗаписатьОбъектДляОтладкиЛкс(Объект, АдресРезультата = Неопределено) Экспорт
#Если Не Клиент Тогда
Если ТранзакцияАктивна() Тогда
лАдресРезультата = ПоместитьВоВременноеХранилище(Неопределено, Новый УникальныйИдентификатор);
СтрокаХМЛ = СохранитьОбъектВВидеСтрокиXMLЛкс(Объект);
Параметры = Новый Массив();
Параметры.Добавить(СтрокаХМЛ);
Параметры.Добавить(лАдресРезультата);
ФоновоеЗадание = ФоновыеЗадания.Выполнить("ирОбщий.ЗаписатьОбъектДляОтладкиЛкс", Параметры,, "Запись объекта для отладки (ИР)");
ФоновоеЗадание.ОжидатьЗавершения(3);
Результат = ПолучитьИзВременногоХранилища(лАдресРезультата);
Иначе
#КонецЕсли
Если ТипЗнч(Объект) = Тип("Строка") Тогда
Объект = ВосстановитьОбъектИзСтрокиXMLЛкс(Объект);
КонецЕсли;
Объект.Записать();
Результат = Объект.Ссылка;
Если АдресРезультата <> Неопределено Тогда
ПоместитьВоВременноеХранилище(Результат, АдресРезультата);
КонецЕсли;
#Если Не Клиент Тогда
КонецЕсли;
#КонецЕсли
Возврат Результат;
КонецФункции
Функция ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаЗначений, БазовоеИмяИлиСтрока, ИмяКлючевойКолонки = "Имя", ИмяДолжноБытьИдентификатором = Истина,
ЗаменаПустойСтроки = "_", Знач ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке = 50) Экспорт
ТекущийИндекс = 0;
Если Ложь
Или ТипЗнч(БазовоеИмяИлиСтрока) = Тип("СтрокаТаблицыЗначений")
Или ТипЗнч(БазовоеИмяИлиСтрока) = Тип("СтрокаДереваЗначений")
Тогда
ИсключаемаяСтрока = БазовоеИмяИлиСтрока;
БазовоеИмя = БазовоеИмяИлиСтрока[ИмяКлючевойКолонки];
//ТекущийИндекс = 1;
Иначе
БазовоеИмя = БазовоеИмяИлиСтрока;
КонецЕсли;
Если ИмяДолжноБытьИдентификатором Тогда
ДопустимаяДлинаИдентификатора = ТаблицаЗначений.Колонки[ИмяКлючевойКолонки].ТипЗначения.КвалификаторыСтроки.Длина;
Если Не ЗначениеЗаполнено(ДопустимаяДлинаИдентификатора) Тогда
ДопустимаяДлинаИдентификатора = ДопустимаяДлинаИдентификатораЕслиНеЗаданаВКолонке;
КонецЕсли;
БазовоеИмя = ирКэш.Получить().ПолучитьИдентификаторИзПредставления(БазовоеИмя, ЗаменаПустойСтроки);
БазовоеИмя = Лев(БазовоеИмя, ДопустимаяДлинаИдентификатора);
Иначе
Если ПустаяСтрока(БазовоеИмя) Тогда
БазовоеИмя = ЗаменаПустойСтроки;
КонецЕсли;
КонецЕсли;
Пока Истина Цикл
ТекущийПсевдоним = БазовоеИмя + Формат(ТекущийИндекс, "ЧГ=");
СтрокиОдноименных = ТаблицаЗначений.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ТекущийПсевдоним));
Если Ложь
Или СтрокиОдноименных.Количество() = 0
Или (Истина
И СтрокиОдноименных.Количество() = 1
И ИсключаемаяСтрока <> Неопределено
И СтрокиРавныЛкс(ТекущийПсевдоним, ИсключаемаяСтрока[ИмяКлючевойКолонки])
)
Тогда
Прервать;
КонецЕсли;
ТекущийИндекс = ТекущийИндекс + 1;
КонецЦикла;
Возврат ТекущийПсевдоним;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ЭлементОтбора - <тип> -
// Сравнение - <тип>, "" -
// Значение - <тип> -
// ЗначениеПо - <тип> -
// Использование - <тип>, Истина -
// ПриводитьТипДляНеопределено - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьЭлементОтбораЛкс(Знач ЭлементОтбора, Знач Сравнение = "", Знач Значение, Знач ЗначениеПо, Знач Использование = Истина,
Знач ПриводитьТипДляНеопределено = Истина) Экспорт
Если ТипЗнч(Значение) = Тип("ФиксированныйМассив") Тогда
Значение = Новый Массив(Значение);
КонецЕсли;
Если ТипЗнч(Значение) = Тип("Массив") Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.ЗагрузитьЗначения(Значение);
Значение = СписокЗначений;
ИначеЕсли Истина
И ПриводитьТипДляНеопределено
И Значение = Неопределено
Тогда
Значение = ЭлементОтбора.ТипЗначения.ПривестиЗначение(Значение);
КонецЕсли;
// Вид сравнения
Если СтрокиРавныЛкс(Сравнение, "Авто") Тогда
Сравнение = ОпределитьВидСравненияПоЗначениюЛкс(Значение);
ИначеЕсли ТипЗнч(Сравнение) = Тип("ВидСравнения") Тогда
ИначеЕсли Истина
И Сравнение <> Неопределено
И Сравнение <> ""
Тогда // Добавлено 25.03.2012
ВызватьИсключение "Неверный тип сравнения """ + ТипЗнч(Сравнение) + """";
Иначе
Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда
Сравнение = ВидСравнения.ВСписке;
Иначе
Сравнение = ВидСравнения.Равно;
КонецЕсли;
КонецЕсли;
// Еще надо сделать автоопределение Сожержит, как у компоновки
ЭлементОтбора.ВидСравнения = Сравнение;
Попытка
Если ЗначениеПо <> Неопределено Тогда
ЭлементОтбора.ЗначениеС = Значение;
ЭлементОтбора.ЗначениеПО = ЗначениеПо;
Иначе
ЭлементОтбора.Значение = Значение;
КонецЕсли;
Исключение
ВызватьИсключение "Ошибка установки значения типа """ + ТипЗнч(Значение) + """ элементу отбора """ + ЭлементОтбора.Имя + """: " + ОписаниеОшибки();
КонецПопытки;
Попытка
ЭлементОтбора.Использование = Использование;
Исключение
// Сюда попадаем для элемента отбора набора записей с регистратором
КонецПопытки;
КонецФункции
// Установить отбор по структуре иис
//
// Параметры:
// Отбор - <тип> -
// СтруктураОтбора - <тип> -
// Сравнение - <тип>, "Авто" -
// ДобавлятьСсылкуВПутьКДанным - <тип>, Ложь -
// СброситьПередУстановкой - <тип>, Истина -
//
// Возвращаемое значение:
//
Функция УстановитьОтборПоСтруктуреЛкс(Знач Отбор, Знач СтруктураОтбора, Знач Сравнение = "Авто", Знач ДобавлятьСсылкуВПутьКДанным = Ложь,
Знач СброситьПередУстановкой = Истина) Экспорт
Если СброситьПередУстановкой Тогда
Отбор.Сбросить();
КонецЕсли;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ПутьКДанным = КлючИЗначение.Ключ;
Если ДобавлятьСсылкуВПутьКДанным Тогда
ПутьКДанным = "Ссылка." + ПутьКДанным;
КонецЕсли;
НайтиДобавитьЭлементОтбораЛкс(Отбор, ПутьКДанным, Сравнение, КлючИЗначение.Значение, , , КлючИЗначение.Ключ);
КонецЦикла;
КонецФункции
Процедура ЗаполнитьНаборЗаписейПоОтборуЛкс(НаборЗаписей) Экспорт
#Если _ Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
СтруктураЗначенийОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
СтруктураЗначенийОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
ЗаполнитьЗначенияСвойств(СтрокаНабора, СтруктураЗначенийОтбора);
КонецЦикла;
КонецПроцедуры
// Параметры:
// Объект - - Ссылочный объект или запись регистра
// Отбор - Отбор
//
Функция УстановитьЗначенияРеквизитовПоОтборуЛкс(Объект, Отбор) Экспорт
Для Каждого ЭлементОтбора Из Отбор Цикл
Если Ложь
Или Не ЭлементОтбора.Использование
Или ЭлементОтбора.ВидСравнения <> ВидСравнения.Равно
Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = ЭлементОтбора.Имя;
ЗначениеОтбора = ЭлементОтбора.Значение;
Попытка
Объект[ИмяРеквизита] = ЗначениеОтбора;
Исключение
// Сюда попадаем например для ЭтоГруппа
КонецПопытки;
КонецЦикла;
КонецФункции
// Определить вид сравнения по значению иис
//
// Параметры:
// Значение - <тип> -
// РежимКомпоновки - <тип>, Ложь -
// ДоступныеВидыСравнения - <тип>, Неопределено -
//
// Возвращаемое значение:
//
Функция ОпределитьВидСравненияПоЗначениюЛкс(Знач Значение, Знач РежимКомпоновки = Ложь, Знач ДоступныеВидыСравнения = Неопределено) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если РежимКомпоновки Тогда
КоллекцияВидовСравнения = ВидСравненияКомпоновкиДанных;
Иначе
КоллекцияВидовСравнения = ВидСравнения;
КонецЕсли;
Если ТипЗначения = Тип("СписокЗначений") Тогда
Результат = КоллекцияВидовСравнения.ВСписке;
ИначеЕсли Истина
И ТипЗначения = Тип("Строка")
И ДоступныеВидыСравнения <> Неопределено
И ДоступныеВидыСравнения.НайтиПоЗначению(КоллекцияВидовСравнения.Содержит) <> Неопределено
Тогда
Результат = КоллекцияВидовСравнения.Содержит;
Иначе
Результат = КоллекцияВидовСравнения.Равно;
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗначения);
Если ОбъектМД <> Неопределено Тогда
//ТипМетаданных = ОбщийИис.ПолучитьТипМетаданныхИис(ОбъектМД);
//Если ТипМетаданных = Справочники.ТипыМетаданныхИис.Справочник Тогда
// Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
// Если Значение.ЭтоГруппа Тогда
// Результат = КоллекцияВидовСравнения.ВИерархии;
// КонецЕсли;
// Иначе // иерархия элементов
// Результат = КоллекцияВидовСравнения.ВИерархии;
// КонецЕсли;
//ИначеЕсли ТипМетаданных = Справочники.ТипыМетаданныхИис.ПланВидовХарактеристик Тогда
// Если Значение.ЭтоГруппа Тогда
// Результат = КоллекцияВидовСравнения.ВИерархии;
// КонецЕсли;
//КонецЕсли;
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ОбъектМД.ПолноеИмя());
Если ТипТаблицы = "Справочник" Тогда
Если ОбъектМД.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
Иначе // иерархия элементов
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
ИначеЕсли ТипТаблицы = "ПланВидовХарактеристик" Тогда
Если Значение.ЭтоГруппа Тогда
Результат = КоллекцияВидовСравнения.ВИерархии;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Сравнение - Строка, ВидСравнения - "Авто" - для автоматического выбора, по умолчанию Равно или ВСписке
//
// Параметры:
// ОтборИлиОбъект - <тип> -
// ПутьКДанным - <тип>, "" -
// Сравнение - <тип>, "" -
// Значение - <тип>, Неопределено -
// ЗначениеПо - <тип>, Неопределено -
// Использование - <тип>, Истина -
// Имя - <тип>, "" -
// Представление - <тип>, "" -
//
// Возвращаемое значение:
//
Функция НайтиДобавитьЭлементОтбораЛкс(Знач ОтборИлиОбъект, Знач ПутьКДанным = "", Знач Сравнение = "", Знач Значение = Неопределено, Знач ЗначениеПо = Неопределено,
Знач Использование = Истина, Знач Имя = "", Знач Представление = "") Экспорт
Если ТипЗнч(ОтборИлиОбъект) = Тип("Отбор") Тогда
Отбор = ОтборИлиОбъект;
Иначе
Отбор = ОтборИлиОбъект.Отбор;
КонецЕсли;
// Ищем или добавляем новый элемент отбора
ЭлементОтбора = Неопределено;
//Если Имя <> Неопределено Тогда
// ЭлементОтбора= Отбор.Найти(Имя);
//КонецЕсли;
Если Имя <> Неопределено Тогда
Для Каждого ЭлОтбора Из Отбор Цикл
Если Ложь
Или ЭлОтбора.Имя = Имя
Или ЭлОтбора.Представление = Имя
Тогда
ЭлементОтбора = ЭлОтбора;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если ЭлементОтбора = Неопределено Тогда
Попытка
ЭлементОтбора = Отбор.Добавить(ПутьКДанным, Имя, Представление);
Исключение
ВызватьИсключение "Ошибка добавления элемента отбора """ + ПутьКДанным + """ построителя запроса: " + ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
УстановитьЭлементОтбораЛкс(ЭлементОтбора, Сравнение, Значение, ЗначениеПо, Использование);
Результат = ЭлементОтбора;
Возврат Результат;
КонецФункции
Процедура ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, Префикс = "Т") Экспорт
#Если _ Тогда
Запрос = Новый Запрос;
#КонецЕсли
ТекстЗапроса = Запрос.Текст;
Параметры = Новый Структура;
СкопироватьУниверсальнуюКоллекциюЛкс(Запрос.Параметры, Параметры);
Для Каждого КлючИЗначение Из Параметры Цикл
Если Найти(КлючИЗначение.Ключ, Префикс) = 1 Тогда
ВызватьИсключение "Начало имени параметра " + КлючИЗначение.Ключ + " совпадает с префиксом " + Префикс;
КонецЕсли;
НовоеИмя = Префикс + КлючИЗначение.Ключ;
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&" + КлючИЗначение.Ключ, "&" + НовоеИмя);
Запрос.УстановитьПараметр(НовоеИмя, КлючИЗначение.Значение);
КонецЦикла;
Запрос.Текст = ТекстЗапроса;
КонецПроцедуры
// ТаблицаПараметров - ТаблицаЗначений, ТабличнаяЧасть
Функция НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров, ИмяКолонкиИмени = "Имя", ИмяКолонкиЗначения = "Значение", ЗначениеПараметра,
ИмяПараметра = Неопределено, ОбновитьКопиюСвойстваВНижнемРегистре = Ложь) Экспорт
Если ТипЗнч(ТаблицаПараметров) = Тип("ТаблицаЗначений") Тогда
МакетТаблицы = ТаблицаПараметров;
Иначе
МакетТаблицы = ТаблицаПараметров.ВыгрузитьКолонки();
КонецЕсли;
Строки = ТаблицаПараметров.НайтиСтроки(Новый Структура(ИмяКолонкиЗначения, ЗначениеПараметра));
Если Строки.Количество() > 0 Тогда
Результат = Строки[0];
Иначе
Если ТипЗнч(ЗначениеПараметра) = Тип("Строка") Тогда
ИмяПараметра = ПолучитьАвтоУникальноеИмяВКоллекцииСтрокЛкс(ТаблицаПараметров, "П", ИмяКолонкиИмени);
Иначе
ОбъектМД = ЗначениеПараметра.Метаданные();
//Префикс = НРег(Лев(ОбъектМД.Имя, 1));
Префикс = "";
Если ИмяПараметра = Неопределено Тогда
ИмяПараметра = "" + ЗначениеПараметра;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяПараметра) Тогда
ИмяПараметра = ОбъектМД.Имя + "Пустая";
КонецЕсли;
ИмяПараметра = Префикс + ирКэш.Получить().ПолучитьИдентификаторИзПредставления(ИмяПараметра);
ДопустимаяДлинаСтроки = МакетТаблицы.Колонки[ИмяКолонкиИмени].ТипЗначения.КвалификаторыСтроки.Длина;
Если ДопустимаяДлинаСтроки > 0 Тогда
ИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки);
КонецЕсли;
КонецЕсли;
СтруктураСвойствПараметра = Новый Структура;
СтруктураСвойствПараметра.Вставить(ИмяКолонкиИмени, ИмяПараметра);
Счетчик = 0;
Пока ТаблицаПараметров.НайтиСтроки(СтруктураСвойствПараметра).Количество() > 0 Цикл
Счетчик = Счетчик + 1;
СтрокаНомера = "" + Счетчик;
Если ДопустимаяДлинаСтроки > 0 Тогда
лИмяПараметра = Лев(ИмяПараметра, ДопустимаяДлинаСтроки - СтрДлина(СтрокаНомера));
Иначе
лИмяПараметра = ИмяПараметра;
КонецЕсли;
СтруктураСвойствПараметра[ИмяКолонкиИмени] = лИмяПараметра + СтрокаНомера;
КонецЦикла;
СтруктураСвойствПараметра.Вставить("ЭтоВыражение", Ложь);
СтруктураСвойствПараметра.Вставить(ИмяКолонкиЗначения, ЗначениеПараметра);
СтрокаНовогоПараметра = ТаблицаПараметров.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаНовогоПараметра, СтруктураСвойствПараметра);
Если ОбновитьКопиюСвойстваВНижнемРегистре Тогда
ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаНовогоПараметра, ИмяКолонкиИмени);
КонецЕсли;
Результат = СтрокаНовогоПараметра;
КонецЕсли;
Возврат Результат;
КонецФункции // ДобавитьПараметрЗначение()
Функция ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицыИлиНаборЗаписей, КлючНабора, ДобавитьИЗаполнитьСтрокуНабора = Ложь) Экспорт
Если ТипЗнч(ПолноеИмяТаблицыИлиНаборЗаписей) = Тип("Строка") Тогда
НаборЗаписей = СоздатьНаборЗаписейПоИмениТаблицыБДЛкс(ПолноеИмяТаблицыИлиНаборЗаписей);
Иначе
НаборЗаписей = ПолноеИмяТаблицыИлиНаборЗаписей;
КонецЕсли;
#Если _ Тогда
НаборЗаписей = РегистрыСведений.Журнал_АвтозаданияИис.СоздатьНаборЗаписей();
#КонецЕсли
//СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолучитьИмяТаблицыИзМетаданныхЛкс(НаборЗаписей.Метаданные()), Ложь,, Истина);
//Для Каждого ПолеКлюча Из СтруктураКлюча Цикл
// ИмяПоля = ПолеКлюча.Ключ;
// Попытка
// ЗначениеКлюча = КлючНабора[ИмяПоля];
// Исключение
// // Имеет смысл для регистров сведений
// Продолжить;
// КонецПопытки;
// ЭлементОтбора = НаборЗаписей.Отбор[ИмяПоля];
// ЭлементОтбора.Значение = ЗначениеКлюча;
// ЭлементОтбора.Использование = Истина;
//КонецЦикла;
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
ИмяПоля = ЭлементОтбора.Имя;
Попытка
ЗначениеКлюча = КлючНабора[ИмяПоля];
Исключение
// Имеет смысл для регистров сведений
Продолжить;
КонецПопытки;
ЭлементОтбора.Значение = ЗначениеКлюча;
ЭлементОтбора.Использование = Истина;
КонецЦикла;
Если ДобавитьИЗаполнитьСтрокуНабора Тогда
ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючНабора);
КонецЕсли;
Возврат НаборЗаписей;
КонецФункции
// Получает копию таблицы значений с минимальными типами колонок для содержания всех данных.
// Параметры:
// ТаблицаДанных - ТаблицаЗначений
// СужатьТолькоПроизвольныеКолонки - Булево - обрабатывать только колонки с пустым (произвольным) типом
//
Функция ПолучитьТаблицуСМинимальнымиТипамиКолонокЛкс(Знач ТаблицаДанных, СужатьТолькоПроизвольныеКолонки = Ложь) Экспорт
#Если _ Тогда
ТаблицаДанных = Новый ТаблицаЗначений;
#КонецЕсли
ОставляемыеКолонки = "";
СужаемыеКолонки = Новый Массив();
Для Каждого КолонкаДанных Из ТаблицаДанных.Колонки Цикл
Если Истина
И СужатьТолькоПроизвольныеКолонки
И КолонкаДанных.ТипЗначения.Типы().Количество() > 0
Тогда
ОставляемыеКолонки = ОставляемыеКолонки + "," + КолонкаДанных.Имя;
Иначе
СужаемыеКолонки.Добавить(КолонкаДанных);
КонецЕсли;
КонецЦикла;
Если ОставляемыеКолонки <> "" Тогда
ТипизированнаяТаблица = ТаблицаДанных.Скопировать(, ОставляемыеКолонки);
Иначе
ТипизированнаяТаблица = Новый ТаблицаЗначений;
КонецЕсли;
//Состояние("Оптимизация типов колонок");
МетаданныеТаблицыИзменены = Ложь;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(СужаемыеКолонки.Количество(), "Анализ колонок");
Для Каждого КолонкаДанных Из СужаемыеКолонки Цикл
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
Типы = Новый Массив;
ТаблицаКолонки = ТаблицаДанных.Скопировать(, КолонкаДанных.Имя);
ТаблицаКолонки.Свернуть(КолонкаДанных.Имя);
СтароеОписаниеТипов = КолонкаДанных.ТипЗначения;
Для Каждого СтрокаДанных Из ТаблицаКолонки Цикл
ТипЗначения = ТипЗнч(СтрокаДанных[КолонкаДанных.Имя]);
Если Типы.Найти(ТипЗначения) = Неопределено Тогда
Типы.Добавить(ТипЗначения);
КонецЕсли;
КонецЦикла;
Если Типы.Количество() = 0 Тогда
Типы = КолонкаДанных.ТипЗначения.Типы();
// Чтобы от супертипов через точку не было много соединений, оставляем только 2 типа
Пока Типы.Количество() > 2 Цикл
Типы.Удалить(0);
КонецЦикла;
КонецЕсли;
Если Типы.Количество() <> СтароеОписаниеТипов.Типы().Количество() Тогда
МетаданныеТаблицыИзменены = Истина;
КонецЕсли;
НовоеОписаниеТипов = Новый ОписаниеТипов(Типы, , , СтароеОписаниеТипов.КвалификаторыЧисла, СтароеОписаниеТипов.КвалификаторыСтроки, СтароеОписаниеТипов.КвалификаторыДаты);
ТипизированнаяТаблица.Колонки.Добавить(КолонкаДанных.Имя, НовоеОписаниеТипов, КолонкаДанных.Заголовок);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Если МетаданныеТаблицыИзменены Тогда
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаДанных.Количество() / 100, "Оптимизация таблицы");
Для Индекс = 0 По ТаблицаДанных.Количество() - 1 Цикл
Если Индекс % 100 = 0 Тогда
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
КонецЕсли;
Если ОставляемыеКолонки <> "" Тогда
СтрокаТипизированнойТаблицы = ТипизированнаяТаблица[Индекс];
Иначе
СтрокаТипизированнойТаблицы = ТипизированнаяТаблица.Добавить();
КонецЕсли;
ЗаполнитьЗначенияСвойств(СтрокаТипизированнойТаблицы, ТаблицаДанных[Индекс]);
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
Иначе
ТипизированнаяТаблица = ТаблицаДанных.Скопировать();
КонецЕсли;
Результат = ТипизированнаяТаблица;
Возврат Результат;
КонецФункции
// ************************
// WMI
Функция ПолучитьСтруктуруИзЗначенияWMIЛкс(ЗначениеWMI) Экспорт
Результат = Новый Структура;
Для каждого СвойствоWMI из ЗначениеWMI Цикл
Если ТипЗнч(СвойствоWMI.Value) = Тип("COMSafeArray") Тогда
ЗначениеСвойства = СвойствоWMI.Value.Выгрузить();// возможно массив надо будет переделать
Иначе
ЗначениеСвойства = СвойствоWMI.Value;
//ИмяТипа = ПолучитьИмяТипаИзКвалификаторовWMIЛкс(СвойствоWMI);
//Если СтрокиРавныЛкс(ИмяТипа, "Дата") Тогда
Если СвойствоWMI.CIMTYPE = 101 Тогда //datetime
ЗначениеСвойства = СтрокаДатыWMIВДатуЛкс(ЗначениеСвойства);
КонецЕсли;
КонецЕсли;
Результат.Вставить(СвойствоWMI.Name, ЗначениеСвойства);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолучитьИмяТипаИзКвалификаторовWMIЛкс(Свойство) Экспорт
ИмяТипа = "";
Попытка
Квалификаторы = Свойство.Qualifiers_;
Исключение
// Нет у системных свойств
Квалификаторы = Новый Массив();
КонецПопытки;
Для Каждого Квалификатор Из Квалификаторы Цикл
Если СтрокиРавныЛкс("CIMTYPE", Квалификатор.Name) Тогда
ИмяТипа = Нрег(Квалификатор.Value);
Прервать;
КонецЕсли;
КонецЦикла;
Если Ложь
Или Найти(ИмяТипа, "int") > 0
Тогда
ИмяТипа = "Число";
ИначеЕсли Ложь
Или Найти(ИмяТипа, "date") > 0
Или Найти(ИмяТипа, "time") > 0
Тогда
ИмяТипа = "Дата";
ИначеЕсли Ложь
Или Найти(ИмяТипа, "string") > 0
Или Найти(ИмяТипа, "char") > 0
Тогда
ИмяТипа = "Строка";
ИначеЕсли ТипЗнч(ИмяТипа) = Тип("COMОбъект") Тогда
ИмяТипа = "COMОбъект.{WbemScripting.SwbemLocator}." + ИмяТипа;
КонецЕсли;
Возврат ИмяТипа;
КонецФункции
Функция ПолучитьОписаниеЭлементаWMIЛкс(ЭлементКоллекции, ИмяСвойства = "Description") Экспорт
ОписаниеЭлемента = "";
Квалификаторы = ЭлементКоллекции.qualifiers_;
Попытка
КвалификаторОписание = Квалификаторы.item(ИмяСвойства);
Исключение
КвалификаторОписание = Неопределено;
КонецПопытки;
Если КвалификаторОписание <> Неопределено Тогда
ОписаниеЭлемента = КвалификаторОписание.Value;
КонецЕсли;
Возврат ОписаниеЭлемента;
КонецФункции
Функция ПолучитьДокументациюСвойстваWMIЛкс(ИмяКласса, ИмяСвойства, СлужбаWMI = Неопределено) Экспорт
Если СлужбаWMI = Неопределено Тогда
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс();
КонецЕсли;
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписанияСвойств = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Properties_;
Попытка
ОписаниеСвойства = ОписанияСвойств.item(ИмяСвойства);
Исключение
Возврат "";
КонецПопытки;
ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства);
ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "CIMTYPE");
Если ТипЗначений <> Неопределено Тогда
ТекстОписания = ТекстОписания + "
|Type: " + ТипЗначений;
КонецЕсли;
ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеСвойства, "Units");
Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда
ТекстОписания = ТекстОписания + "
|Unit: " + ЕдиницаИзмерения;
КонецЕсли;
Возврат ТекстОписания;
КонецФункции
Функция ПолучитьДокументациюМетодаWMIЛкс(ИмяКласса, ИмяМетода, СлужбаWMI = Неопределено) Экспорт
Если СлужбаWMI = Неопределено Тогда
СлужбаWMI = ирКэш.ПолучитьCOMОбъектWMIЛкс();
КонецЕсли;
wbemFlagUseAmendedQualifiers = 131072; //&H20000
ОписанияМетодов = СлужбаWMI.Get(ИмяКласса, wbemFlagUseAmendedQualifiers).Methods_;
Попытка
ОписаниеМетода = ОписанияМетодов.item(ИмяМетода);
Исключение
Возврат "";
КонецПопытки;
ТекстОписания = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода);
ТипЗначений = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "CIMTYPE");
Если ТипЗначений <> Неопределено Тогда
ТекстОписания = ТекстОписания + "
|Type: " + ТипЗначений;
КонецЕсли;
ЕдиницаИзмерения = ПолучитьОписаниеЭлементаWMIЛкс(ОписаниеМетода, "Units");
Если ЗначениеЗаполнено(ЕдиницаИзмерения) Тогда
ТекстОписания = ТекстОписания + "
|Unit: " + ЕдиницаИзмерения;
КонецЕсли;
Возврат ТекстОписания;
КонецФункции
// Параметры:
// СтрокаДаты - Строка(0,П)
//
Функция СтрокаДатыWMIВДатуЛкс(Знач СтрокаДаты = "") Экспорт
Если Не ЗначениеЗаполнено(СтрокаДаты) Тогда
Возврат Дата(1,1,1);
Иначе
Строка = Лев(СтрокаДаты, 4) + Сред(СтрокаДаты, 5, 2) + Сред(СтрокаДаты, 7, 2)
+ Сред (СтрокаДаты, 9, 2) + Сред(СтрокаДаты, 11, 2) + Сред(СтрокаДаты, 13, 2);
Попытка
Результат = Дата(Строка);
Исключение
Сообщить("Ошибка преобразования даты WMI из строки """ + СтрокаДаты + """: " + ОписаниеОшибки());
Возврат Дата(1,1,1);
КонецПопытки;
Результат = Результат + Вычислить("0." + Сред(СтрокаДаты, 16, 6));
КонецЕсли;
Возврат Результат;
КонецФункции
// WMI
// *************************
// ************************
// ADO
Функция ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С = Неопределено) Экспорт
Если РезультатТаблица = Неопределено Тогда
РезультатТаблица = Новый ТаблицаЗначений;
КонецЕсли;
мПлатформа = ирКэш.Получить();
FieldКолонка = Новый Соответствие;
Для каждого Field Из РезультатRecordset.Fields Цикл
Если ПустаяСтрока(Field.Name) Тогда
ИмяКолонки = ":?";
Для о=1 По СтрДлина(Field.Name)-1 Цикл
ИмяКолонки = ИмяКолонки + "?";
КонецЦикла;
Иначе
ИмяКолонки = Field.Name;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(ИмяКолонки) Тогда
ИмяКолонки = мПлатформа.ПолучитьИдентификаторИзПредставления(ИмяКолонки);
КонецЕсли;
// контроль полей - двойников по именам
НомерДвойника=0;
Пока РезультатТаблица.Колонки.Найти(ИмяКолонки + Формат(НомерДвойника,"ЧГ=0")) <> Неопределено Цикл
НомерДвойника = НомерДвойника + 1;
КонецЦикла;
ИмяКолонки = ИмяКолонки + Формат(НомерДвойника, "ЧГ=0");
Если Типизировать1С = Истина Тогда
Тип1С = FieldADO_ПолучитьТип1CЛкс(Field);
Иначе
Тип1С = Неопределено;
КонецЕсли;
//Если Тип1С=Неопределено Тогда
// Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,,"["+Name+"]");
//Иначе
Колонка = РезультатТаблица.Колонки.Добавить(ИмяКолонки,Тип1С);
//КонецЕсли;
FieldКолонка.Вставить(Field, Колонка);
КонецЦикла;
Возврат FieldКолонка;
КонецФункции
// выгружает результат запроса ADO (объект 'ADODB.Recordset') в таблицу значений с выводом прогресса состояния выгрузки
Функция ПреобразоватьРезультатADOВТаблицуЗначенийЛкс(РезультатRecordset, Типизировать1С = Ложь, BynaryToHex = Ложь, RecordsAffected = 0,
ИгнорироватьНеподдерживаемыеТипы = Ложь, ЗагружатьЭлементов = Неопределено) Экспорт
РезультатТаблица = Новый ТаблицаЗначений;
Если РезультатRecordset = Неопределено Тогда
Возврат РезультатТаблица;
КонецЕсли;
Если ЗначениеЗаполнено(ЗагружатьЭлементов) Тогда
КоличествоЭлементов = Мин(ЗагружатьЭлементов, РезультатRecordset.RecordCount);
Иначе
КоличествоЭлементов = РезультатRecordset.RecordCount;
КонецЕсли;
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоличествоЭлементов, "Загрузка результата");
Если РезультатRecordset.State=0 Тогда
// Выполнена команда
РезультатТаблица.Колонки.Добавить("ExecutionInfo",,"Информация о выполнении:");
Стр = РезультатТаблица.Добавить();
Стр.ExecutionInfo = "Число записей, обработанных запросом: "+ RecordsAffected;
Иначе
FieldКолонка = ирОбщий.ПолучитьКолонкиRecordsetADOЛкс(РезультатТаблица, РезультатRecordset, Типизировать1С);
// Открыта выборка
ТипCOMSafeArray = Тип("COMSafeArray");
adBinaryType = ирОбщий.intTypeADOЛкс("adBinary");
adVarBinaryType = ирОбщий.intTypeADOЛкс("adVarBinary");
adLongVarBinaryType = ирОбщий.intTypeADOЛкс("adLongVarBinary");
ПервыйРаз = Истина;
Счетчик = 0;
РезультатRecordset.MoveFirst();
Пока РезультатRecordset.EOF() = 0 Цикл
Если Индикатор.Счетчик = КоличествоЭлементов Тогда
Прервать;
КонецЕсли;
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
Счетчик = Счетчик + 1;
СтрНов = РезультатТаблица.Добавить();
Для каждого Field Из РезультатRecordset.Fields Цикл
Попытка
ЗначениеПоля = Field.Value;
Исключение
Если Не ИгнорироватьНеподдерживаемыеТипы Тогда
ВызватьИсключение "ADO. Невозможно прочитать значение типа " + XMLСтрока(Field.Type) + " из колонки результата """ + Field.Name + """";
КонецЕсли;
ЗначениеПоля = Неопределено;
КонецПопытки;
Индекс = РезультатТаблица.Колонки.Индекс(FieldКолонка.Получить(Field));
Если Истина
И ТипЗнч(ЗначениеПоля)=ТипCOMSafeArray
И BynaryToHex = Истина
И (Ложь
Или Field.Type=adBinaryType
Или Field.Type=adVarBinaryType
//ИЛИ (Field.Type=adLongVarBinaryType)
)
Тогда
// преобразование COMSafeArray в строку HEX
СтрНов[Индекс] = BinaryCOMSafeArrayToHEXЛкс(ЗначениеПоля);
Иначе
// преобразование типа неявное
СтрНов[Индекс] = ЗначениеПоля;
КонецЕсли;
КонецЦикла;
РезультатRecordset.MoveNext();
КонецЦикла;
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
КонецЕсли;
Возврат РезультатТаблица;
КонецФункции
// *** УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ***
// подбирает описание типа 1С, соответствующее типу ADO
Функция ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision0,NumericScale0) Экспорт
Тип1С = Неопределено;
Если Precision0 > 0 И NumericScale0 >= 0 Тогда
Если Precision0 < NumericScale0 Тогда
// кривой вариант настроек типа ADO (может иногда возвращаться провайдерами данных)
Precision = Precision0 + NumericScale0;
Иначе
Precision = Precision0;
КонецЕсли;
UseМаксЧисло = (Precision > 32);
Иначе
// совсем кривой вариант
UseМаксЧисло = Истина;
КонецЕсли;
NumericScale = ?(NumericScale0 < 0, 0, NumericScale0);
NumericScaleM = ?(NumericScale > 10, 10, NumericScale);
Если Type = intTypeADOЛкс("adEmpty") Тогда
ИначеЕсли Type = intTypeADOЛкс("adSmallInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adInteger") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adSingle") Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adDouble") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision+NumericScale, NumericScale, ДопустимыйЗнак.Любой));
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adCurrency")Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adDate") Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата));
ИначеЕсли Type = intTypeADOЛкс("adBSTR") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adIDispatch")Тогда
ИначеЕсли Type = intTypeADOЛкс("adError") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adBoolean") Тогда
Тип1С = Новый ОписаниеТипов("Булево");
ИначеЕсли Type = intTypeADOЛкс("adVariant") Тогда
ИначеЕсли Type = intTypeADOЛкс("adIUnknown")Тогда
ИначеЕсли Type = intTypeADOЛкс("adDecimal") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adTinyInt") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedTinyInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedSmallInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adBigInt") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Любой));
ИначеЕсли Type = intTypeADOЛкс("adUnsignedBigInt")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(20, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adFileTime")Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adGUID") Тогда
//Тип1С = Новый ОписаниеТипов("УникальныйИдентификатор");
ИначеЕсли Type = intTypeADOЛкс("adBinary") Тогда
ИначеЕсли Type = intTypeADOЛкс("adChar") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adWChar") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adNumeric") Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adUserDefined")Тогда
ИначеЕсли Type = intTypeADOЛкс("adDBDate") Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Дата));
ИначеЕсли Type = intTypeADOЛкс("adDBTime") Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.Время));
ИначеЕсли Type = intTypeADOЛкс("adDBTimeStamp")Тогда
Тип1С = Новый ОписаниеТипов("Дата", , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя));
ИначеЕсли Type = intTypeADOЛкс("adChapter") Тогда
Тип1С = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(Precision, 0, ДопустимыйЗнак.Неотрицательный));
ИначеЕсли Type = intTypeADOЛкс("adPropVariant")Тогда
ИначеЕсли Type = intTypeADOЛкс("adVarNumeric")Тогда
Если UseМаксЧисло Тогда
// взвешанно-максимальный числовой тип
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(32, NumericScaleM, ДопустимыйЗнак.Любой));
Иначе
Тип1С = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(Precision, NumericScale, ДопустимыйЗнак.Любой));
КонецЕсли;
ИначеЕсли Type = intTypeADOЛкс("adVarChar") Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adLongVarChar")Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adVarWChar")Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(Size, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adLongVarWChar")Тогда
Тип1С = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(0, ДопустимаяДлина.Переменная));
ИначеЕсли Type = intTypeADOЛкс("adVarBinary")Тогда
ИначеЕсли Type = intTypeADOЛкс("adLongVarBinary")Тогда
ИначеЕсли Type = intTypeADOЛкс("AdArray") Тогда
Иначе // Тип1С = Неопределено;
КонецЕсли;
Возврат Тип1С;
КонецФункции // ПреобразоватьТипADO_Тип1СЛкс()
// возвращает описание типа 1С, соответствующее типу объекта ADODB.Field
// значение Неопределено соответствует значению произвольного типа 1С
Функция FieldADO_ПолучитьТип1CЛкс(FieldADOЛкс) Экспорт
Попытка
Type = FieldADOЛкс.Type;
DefinedSize = FieldADOЛкс.DefinedSize;
Precision = FieldADOЛкс.Precision;
NumericScale = FieldADOЛкс.NumericScale;
Исключение
Возврат Неопределено;
КонецПопытки;
Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,DefinedSize,Precision,NumericScale);
КонецФункции
// возвращает описание типа 1С, соответствующее типу объекта ADODB.Parameter
// значение Неопределено соответствует значению произвольного типа 1С
Функция ParameterADO_ПолучитьТип1CЛкс(ParameterADOЛкс) Экспорт
Попытка
Type = ParameterADOЛкс.Type;
Size = ParameterADOЛкс.Size;
Precision = ParameterADOЛкс.Precision;
NumericScale = ParameterADOЛкс.NumericScale;
Исключение
Возврат Неопределено;
КонецПопытки;
Возврат ПреобразоватьТипADO_Тип1СЛкс(Type,Size,Precision,NumericScale);
КонецФункции
// возвращает структуру с полями объекта ADODB.Field
Функция FieldADOЛкс(стрName,стрType,чисDefinedSize,чисPrecision,чисNumericScale,Value=Неопределено) Экспорт
ПолеADO = Новый Структура("Name,Type,DefinedSize,Precision,NumericScale,Value");
ТипЧисло = Тип("Число");
Если стрName <> Неопределено Тогда
ПолеADO.Вставить("Name",СокрЛП(стрName));
КонецЕсли;
Если стрType <> Неопределено Тогда
Если ТипЗнч(стрType) = ТипЧисло Тогда
// дополнительный контроль числа на допустимое значение
ПолеADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType)));
Иначе
ПолеADO.Вставить("Type",intTypeADOЛкс(стрType));
КонецЕсли;
КонецЕсли;
Если чисDefinedSize <> Неопределено Тогда
Если ТипЗнч(чисDefinedSize)=ТипЧисло Тогда
ПолеADO.Вставить("DefinedSize",Цел(чисDefinedSize));
Иначе
ПолеADO.Вставить("DefinedSize",0);
КонецЕсли;
КонецЕсли;
Если чисPrecision <> Неопределено Тогда
Если ТипЗнч(чисPrecision)=ТипЧисло Тогда
ПолеADO.Вставить("Precision",Цел(чисPrecision));
Иначе
ПолеADO.Вставить("Precision",0);
КонецЕсли;
КонецЕсли;
Если чисNumericScale <> Неопределено Тогда
Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда
ПолеADO.Вставить("NumericScale",Цел(чисNumericScale));
Иначе
ПолеADO.Вставить("NumericScale",0);
КонецЕсли;
КонецЕсли;
Если Value <> Неопределено Тогда
ПолеADO.Вставить("Value",Value);
КонецЕсли;
Возврат ПолеADO;
КонецФункции
// возвращает структуру с полями объекта ADODB.Parameter
Функция ParameterADOЛкс(стрName,стрDirection,стрType,чисSize,чисNumericScale,чисPrecision,чисAttributes=0,Value=Неопределено) Экспорт
ПараметрADO = Новый Структура("Name,Direction,Type,Size,NumericScale,Precision,Attributes,Value");
ТипЧисло = Тип("Число");
Если стрName <> Неопределено Тогда
ПараметрADO.Вставить("Name",СокрЛП(стрName));
КонецЕсли;
Если чисAttributes <> Неопределено Тогда
Если ТипЗнч(чисAttributes)=ТипЧисло И чисAttributes > 0 Тогда
ПараметрADO.Вставить("Attributes",Цел(чисAttributes));
КонецЕсли;
КонецЕсли;
Если стрDirection <> Неопределено Тогда
Если ТипЗнч(стрDirection) = ТипЧисло Тогда
// дополнительный контроль числа на допустимое значение
ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(strDirectionParADOЛкс(стрDirection)));
Иначе
ПараметрADO.Вставить("Direction",intDirectionParADOЛкс(стрDirection));
КонецЕсли;
КонецЕсли;
Если стрType <> Неопределено Тогда
Если ТипЗнч(стрType) = ТипЧисло Тогда
// дополнительный контроль числа на допустимое значение
ПараметрADO.Вставить("Type",intTypeADOЛкс(strTypeADOЛкс(стрType)));
Иначе
ПараметрADO.Вставить("Type",intTypeADOЛкс(стрType));
КонецЕсли;
КонецЕсли;
Если чисSize <> Неопределено Тогда
Если ТипЗнч(чисSize)=ТипЧисло Тогда
ПараметрADO.Вставить("Size",Цел(чисSize));
Иначе
ПараметрADO.Вставить("Size",0);
КонецЕсли;
КонецЕсли;
Если чисNumericScale <> Неопределено Тогда
Если ТипЗнч(чисNumericScale)=ТипЧисло Тогда
ПараметрADO.Вставить("NumericScale",Цел(чисNumericScale));
Иначе
ПараметрADO.Вставить("NumericScale",0);
КонецЕсли;
КонецЕсли;
Если чисPrecision <> Неопределено Тогда
Если ТипЗнч(чисPrecision)=ТипЧисло Тогда
ПараметрADO.Вставить("Precision",Цел(чисPrecision));
Иначе
ПараметрADO.Вставить("Precision",0);
КонецЕсли;
КонецЕсли;
Если Value <> Неопределено Тогда
ПараметрADO.Вставить("Value",Value);
КонецЕсли;
Возврат ПараметрADO;
КонецФункции
Функция DigitDECtoHEXЛкс(ЦыфраD)
Если ЦыфраD=0 Тогда
Возврат "0";
ИначеЕсли ЦыфраD>=1 И ЦыфраD<=9 Тогда
Возврат ""+ЦыфраD;
ИначеЕсли ЦыфраD=10 Тогда
Возврат "A";
ИначеЕсли ЦыфраD=11 Тогда
Возврат "B";
ИначеЕсли ЦыфраD=12 Тогда
Возврат "C";
ИначеЕсли ЦыфраD=13 Тогда
Возврат "D";
ИначеЕсли ЦыфраD=14 Тогда
Возврат "E";
ИначеЕсли ЦыфраD=15 Тогда
Возврат "F";
Иначе
Возврат "?";
КонецЕсли;
КонецФункции
Функция DigitHEXtoDECЛкс(ЦыфраH)
Если ЦыфраH="0" ИЛИ ЦыфраH="1" ИЛИ ЦыфраH="2" ИЛИ ЦыфраH="3" ИЛИ ЦыфраH="4" ИЛИ ЦыфраH="5" ИЛИ ЦыфраH="6" ИЛИ ЦыфраH="7" ИЛИ ЦыфраH="8" ИЛИ ЦыфраH="9" Тогда
Возврат Цел(ЦыфраH);
ИначеЕсли ЦыфраH="a" ИЛИ ЦыфраH="A" Тогда
Возврат 10;
ИначеЕсли ЦыфраH="b" ИЛИ ЦыфраH="B" Тогда
Возврат 11;
ИначеЕсли ЦыфраH="c" ИЛИ ЦыфраH="C" Тогда
Возврат 12;
ИначеЕсли ЦыфраH="d" ИЛИ ЦыфраH="D" Тогда
Возврат 13;
ИначеЕсли ЦыфраH="e" ИЛИ ЦыфраH="E" Тогда
Возврат 14;
ИначеЕсли ЦыфраH="f" ИЛИ ЦыфраH="F" Тогда
Возврат 15;
Иначе
Возврат -1;
КонецЕсли;
КонецФункции
Функция СтрокаHEXtoINTЛкс(Знач СтрокаH) Экспорт
ПрефиксH = Лев(СтрокаH,2);
Если ПрефиксH="0x"
ИЛИ ПрефиксH="0X"
ИЛИ ПрефиксH="0х"
ИЛИ ПрефиксH="0Х" Тогда
СтрокаH=Сред(СтрокаH,3);
КонецЕсли;
Если ПустаяСтрока(СтрокаH) Тогда
Возврат 0;
КонецЕсли;
ДлинаH=СтрДлина(СтрокаH);
ЧислоD=0;
Для о = 1 По ДлинаH Цикл
ЦыфраH = Сред(СтрокаH,о,1);
ЦифраD = DigitHEXtoDECЛкс(ЦыфраH);
Если ЦифраD<0 Тогда
Возврат -1; // нарушение формата 16-тиричного числа
КонецЕсли;
ЧислоD = 16*ЧислоD + ЦифраD;
КонецЦикла;
Возврат ЧислоD;
КонецФункции
// преобразует 16-тиричную строку в COMSafeArray
Функция СтрокаHEXtoCOMSafeArrayЛкс(Знач СтрокаH) Экспорт
ПрефиксH = Лев(СтрокаH,2);
Если Ложь
Или ПрефиксH="0x"
ИЛИ ПрефиксH="0X"
ИЛИ ПрефиксH="0х"
ИЛИ ПрефиксH="0Х"
Тогда
СтрокаH=Сред(СтрокаH,3);
КонецЕсли;
Байты =СтрДлина(СтрокаH);
Байты = 2*Окр(Байты/2,0,1);
ArrayДанные = Новый Массив;
Поза=1;
Для о=1 По Байты Цикл
ДваБайт = Сред(СтрокаH,Поза,2);
ЗначInt = СтрокаHEXtoINTЛкс(ДваБайт);
Если ЗначInt<0 Тогда
Возврат Неопределено;
КонецЕсли;
ArrayДанные.Добавить(ЗначInt);
Поза=Поза+2;
КонецЦикла;
Array = Новый COMSafeArray(ArrayДанные,"VT_UI1",Байты/2);
Возврат Array;
КонецФункции
// преобразует объект УникальныйИдентификатор в COMSafeArray
Функция GUIDToCOMSafeArrayЛкс(GUID) Экспорт
ГУИД = СтрЗаменить(GUID,"-",Символы.ПС);
Если СтрЧислоСтрок(ГУИД)<>5 Тогда
// нарушена каноническая структура строки ГУИД: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12)
Возврат Неопределено; // вдруг ...
КонецЕсли;
// Соответсвие байтов в поле BINARY(16) с частями ГУИД: 4,5,3,2,1 - проверено для 1с-8.1.14
СтрокаH = СтрПолучитьСтроку(ГУИД,4) + СтрПолучитьСтроку(ГУИД,5)+ СтрПолучитьСтроку(ГУИД,3)+ СтрПолучитьСтроку(ГУИД,2)+ СтрПолучитьСтроку(ГУИД,1);
//Сообщить("ГУИД = "+ГУИД);
//Сообщить("СтрокаH = "+СтрокаH);
Возврат СтрокаHEXtoCOMSafeArrayЛкс(СтрокаH);
КонецФункции
// преобразует значение уникального идентификатора ссылки в COMSafeArray
Функция СсылкаToCOMSafeArrayЛкс(Ссылка) Экспорт
Попытка
ГУИД = СокрЛП(Ссылка.УникальныйИдентификатор());
Исключение
// переданное значение не ссылка
Возврат Неопределено;
КонецПопытки;
Возврат GUIDToCOMSafeArrayЛкс(ГУИД);
КонецФункции
// преобразоваение значения COMSafeArray, содержащие 2-байтовые целые в шестнадцатиричную строку
Функция BinaryCOMSafeArrayToHEXЛкс(Array) Экспорт
СтрHEX="";
Если ТипЗнч(Array)<>Тип("COMSafeArray") Тогда
Возврат "?COMSafeArray?";
КонецЕсли;
Массив=Array.Выгрузить();
Для каждого Слово Из Массив Цикл
Если ТипЗнч(Слово)=Тип("Число") Тогда
Слово=Цел(Слово);
Если (Слово<0)ИЛИ(Слово>255) Тогда
СтрHEX=СтрHEX+"??";
Иначе
Байт1=Слово%16;
Байт2=Цел(Слово/16);
СтрHEX=СтрHEX+DigitDECtoHEXЛксайт2)+DigitDECtoHEXЛксайт1);
КонецЕсли;
Иначе
СтрHEX=СтрHEX+"??";
КонецЕсли;
КонецЦикла;
Возврат "0x"+СтрHEX;
КонецФункции
// возвращает свойства параметра ADO из переданной структуры
// с автоматическим подбором значений свойств по значению 1С (если свойство неопределено)
Процедура ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils=Неопределено)
Перем ТипЗначения1С;
Если ТипЗнч(стТипADO)=Тип("Структура") Тогда
стТипADO.Свойство("Direction",Direction);
стТипADO.Свойство("Type",Type);
стТипADO.Свойство("Precision",Precision);
стТипADO.Свойство("NumericScale",NumericScale);
стТипADO.Свойство("Size",Size);
стТипADO.Свойство("Attributes",Attributes);
стТипADO.Свойство("ТипЗначения1С",ТипЗначения1С);
КонецЕсли;
Если Истина
И ТипЗнч(ТипЗначения1С) = Тип("ОписаниеТипов")
И ТипЗначения1С.Типы().Количество() > 0
И НЕ ТипЗначения1С.СодержитТип(ТипЗнч(Значение1С))
Тогда
// приведем значение 1С к указанному типу (актуально для значений Null, возвращаемых запросами 1С)
Значение1С = ТипЗначения1С.ПривестиЗначение(Значение1С);
КонецЕсли;
Если Direction=Неопределено Тогда
Direction=1; // 1 - входящий(Default) ... или 0 - неизвестно ???
КонецЕсли;
Тип1С=ТипЗнч(Значение1С);
Попытка
Ссылка = Значение1С.Ссылка;
Исключение
Ссылка = Неопределено;
Попытка
// перечисления стоят особняком среди "ссылочных" типов
МетаДата = Значение1С.Метаданные();
Если Метаданные.Перечисления.Содержит(МетаДата) Тогда
Ссылка = Значение1С;
КонецЕсли;
Исключение
КонецПопытки;
КонецПопытки;
Если Type=Неопределено Тогда
// попытаемся подобрать по типу 1С
Если Тип1С=Тип("Число") Тогда
//Type = 4; // adSingle
//Type = 5; // adDouble
//Type = 14; // adDecimal
//Type = 131; // adNumeric
//Type = 139; // adVarNumeric
Если Цел(Значение1С)=Значение1С Тогда
Если ?(Значение1С<0,-1,1)*Значение1С <= 2147483647 Тогда // 2^32-1
Type = intTypeADOЛкс("adInteger"); // 3
Иначе
Type = intTypeADOЛкс("adBigInt"); // 20
КонецЕсли;
Иначе
Type = 14; // adDecimal
КонецЕсли;
ИначеЕсли Тип1С=Тип("Строка") Тогда
//Type = 129; // adChar
//Type = 130; // adWChar
//Type = 200; // adVarChar
//Type = 201; // adLongVarChar
//Type = 202; // adVarWChar
//Type = 203; // adLongVarWChar
Если СтрДлина(Значение1С)<=4000 Тогда
Type = intTypeADOЛкс("adVarChar"); // 200
Иначе
Type = intTypeADOЛкс("adLongVarChar"); // 201
КонецЕсли;
ИначеЕсли Тип1С=Тип("Дата") Тогда
//Type = 134; // adDBTime
Если НачалоДня(Значение1С)=Значение1С Тогда
Type = intTypeADOЛкс("adDBDate"); // 133
Иначе
Type = intTypeADOЛкс("adDBTimeStamp"); // 135
КонецЕсли;
ИначеЕсли Тип1С=Тип("Булево") Тогда
Type = intTypeADOЛкс("adBoolean"); // 11
ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда
Type = intTypeADOЛкс("adBinary"); // 128
Size = 16;
Иначе
Если Ссылка <> Неопределено Тогда
// ссылочный тип - преобразуем в COMSafeArray
Type = intTypeADOЛкс("adBinary"); // 128
Size = 16;
Иначе
Type = intTypeADOЛкс("adEmpty"); // 0? (Default)
КонецЕсли;
КонецЕсли;
КонецЕсли;
// ADOUtils.V8DateToDBDate( Дата ) // с учетом YearOffset
// ADOUtils.BooleanParameter( Значение ) // COMSafeArray(1)
// ADOUtils.TypeParameter( Значение ) // COMSafeArray(1) *_TYPE
// ADOUtils.TableNumberParameter( Значение ) // COMSafeArray(4) *_RTRef
// ADOUtils.DataVersionParameter( Значение ) // COMSafeArray(8) _Version
// ADOUtils.RRefParameter( Значение ) // COMSafeArray(16) *IDRRef
Если Ложь
Или Type = intTypeADOЛкс("adBinary") // 128
Или Type = intTypeADOЛкс("adVarBinary")
Тогда // 204
//Если ADOUtils = Неопределено Тогда
// ADOUtils = ПолучитьADOUtils();
// Если ADOUtils = Неопределено Тогда
// ADOUtils = Null; // для избежания повторных инициализаций
// КонецЕсли;
//КонецЕсли;
Если Ссылка <> Неопределено Тогда
// ссылочный тип - преобразуем в COMSafeArray(16)
ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка);
//Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда
// ЗначениеADO = СсылкаToCOMSafeArrayЛкс(Ссылка);
//Иначе
// ЗначениеADO = ADOUtils.RRefParameter(Ссылка);
//КонецЕсли;
ИначеЕсли Тип1С=Тип("УникальныйИдентификатор") Тогда
// ГУИД - преобразуем в COMSafeArray(16)
ЗначениеADO = GUIDToCOMSafeArrayЛкс(Значение1С);
ИначеЕсли Тип1С=Тип("Булево") Тогда
// Булево - преобразуем в COMSafeArray(1)
ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00"));
//Если ADOUtils = Неопределено ИЛИ ADOUtils = Null Тогда
// ЗначениеADO = СтрокаHEXtoCOMSafeArrayЛкс(?(Значение1С,"0x01","0x00"));
//Иначе
// ЗначениеADO = ADOUtils.BooleanParameter(Значение1С);
//КонецЕсли;
Иначе
КонецЕсли;
КонецЕсли;
Если Precision=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adDecimal") // 14
ИЛИ Type = intTypeADOЛкс("adNumeric") // 131
ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139
Тогда
Precision = СтрДлина(СтрЗаменить(Строка(Значение1С)," ",""));
КонецЕсли;
КонецЕсли;
Если NumericScale=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adDecimal") // 14
ИЛИ Type = intTypeADOЛкс("adNumeric") // 131
ИЛИ Type = intTypeADOЛкс("adVarNumeric") // 139
Тогда
NumericScale = СтрДлина(Строка(Значение1С-Цел(Значение1С)));
КонецЕсли;
КонецЕсли;
Если Size=Неопределено Тогда
Если Ложь
Или Type = intTypeADOЛкс("adChar") // 129
ИЛИ Type = intTypeADOЛкс("adWChar") // 130
ИЛИ Type = intTypeADOЛкс("adVarChar") // 200
//ИЛИ Type = intTypeADOЛкс("adLongVarChar") // 201
ИЛИ Type = intTypeADOЛкс("adVarWChar") // 202
//ИЛИ Type = intTypeADOЛкс("adLongVarWChar") // 203
Тогда
Size = СтрДлина(Значение1С);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// создает массив объектов ADODB.Parameter по списку параметров ADO и по списку типов ADO
Функция ParametersArrayПолучитьЛкс(стПараметры,стПарТипADO, ADOUtils = Неопределено) Экспорт
ParametersArray = Новый Массив;
ТипаМассив = Тип("Массив");
ТипаСоответствие = Тип("Соответствие");
cтПараметрыТип = ТипЗнч(стПараметры);
cтПарТипADOТип = ТипЗнч(стПарТипADO);
Если стПараметры = Неопределено Тогда
Возврат ParametersArray;
ИначеЕсли cтПараметрыТип = ТипаМассив ИЛИ cтПараметрыТип = ТипаСоответствие Тогда
Если стПарТипADO <> Неопределено И cтПарТипADOТип <> cтПараметрыТип Тогда
ВызватьИсключение(
"Тип значения списка типов параметров ADO ('"+cтПарТипADOТип+"') не равен
|типу значения списка параметров запроса ('"+cтПараметрыТип+"') !");
КонецЕсли;
Иначе
ВызватьИсключение(
"Не предусмотренный тип значения списка параметров запроса ('"+cтПараметрыТип+"') !");
КонецЕсли;
ОбъектЗапрос = Новый COMОбъект("ADODB.Command");
Индекс = 0;
Для каждого Параметр Из стПараметры Цикл
Если cтПараметрыТип = ТипаМассив Тогда
ПараметрИмя = Неопределено;
Значение1С = Параметр;
ИначеЕсли cтПараметрыТип = ТипаСоответствие Тогда
ПараметрИмя = СокрЛП(Параметр.Ключ);
Значение1С = Параметр.Значение;
Иначе
Продолжить;
КонецЕсли;
Индекс = Индекс + 1;
стТипADO=Неопределено;
Если cтПарТипADOТип=ТипаМассив Тогда
Если Индекс<=стПарТипADO.Количество()-1 Тогда
стТипADO = стПарТипADO.Получить(Индекс);
КонецЕсли;
ИначеЕсли cтПарТипADOТип = ТипаСоответствие Тогда
стТипADO = стПарТипADO.Получить(Параметр.Ключ);
КонецЕсли;
ЗначениеADO = Неопределено;
Attributes = Неопределено;
Direction = Неопределено;
Type = Неопределено;
Precision = Неопределено;
NumericScale = Неопределено;
Size = Неопределено; // прочитаем свойства параметра ADO по полученной структуре типа и значению 1С
ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils);
// создадим параметр ADO и заполним его свойства
Parameter = ОбъектЗапрос.CreateParameter();
Если НЕ ПустаяСтрока(Type) Тогда
Parameter.Type=Type;
КонецЕсли;
Если НЕ ПустаяСтрока(Direction) Тогда
Parameter.Direction=Direction;
КонецЕсли;
Если НЕ ПустаяСтрока(Size) Тогда
Parameter.Size=Size;
КонецЕсли;
Если НЕ ПустаяСтрока(Attributes) Тогда
Parameter.Attributes=Attributes;
КонецЕсли;
Если НЕ ПустаяСтрока(ПараметрИмя) Тогда
Parameter.Name = ПараметрИмя;
КонецЕсли;
Если ЗначениеADO = Неопределено Тогда
Parameter.Value=Значение1С; // преобразование не явное
Иначе
Parameter.Value=ЗначениеADO;
КонецЕсли;
// добавим в массив
ParametersArray.Добавить(Parameter);
КонецЦикла;
Возврат ParametersArray;
КонецФункции // ParametersArrayПолучитьЛкс()
// формирует массив или соответствие со значениями параметров запроса из строки таблицы значений
Функция стПараметры_Получить_ТЗЛкс(тзПараметры,СтрокаПараметров,NamedParameters,Знач ParametersPrefix) Экспорт
Если NamedParameters=Истина Тогда
ParametersPrefix=СокрЛП(ParametersPrefix);
стПараметры=Новый Соответствие;
Для каждого Колонка Из тзПараметры.Колонки Цикл
стПараметры.Вставить(ParametersPrefix+Колонка.Имя,СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка)));
КонецЦикла;
Иначе
стПараметры=Новый Массив;
Для каждого Колонка Из тзПараметры.Колонки Цикл
стПараметры.Добавить(СтрокаПараметров.Получить(тзПараметры.Колонки.Индекс(Колонка)));
КонецЦикла;
КонецЕсли;
Возврат стПараметры;
КонецФункции // стПараметры_Получить_ТЗЛкс()
// добавляет и устанавливает объект ADODB.Parameter в коллекцию параметров
// если не заданы свойства параметра ADO, делается попытка их подбора по типу значения 1С
Функция ADODBCommand_УстановитьПараметрПо1СЛкс(ОбъектЗапрос,Инициализация,Индекс,Name,стТипADO,Значение1С,ADOUtils,ЕррорИнфо) Экспорт
ЗначениеADO=Неопределено;
Attributes=Неопределено;
Direction=Неопределено;
Type=Неопределено;
Precision=Неопределено;
NumericScale=Неопределено;
Size=Неопределено; // прочитаем свойства параметра ADO из переданной структуры по значению 1С
ParameterADOСвойстваЛкс(стТипADO,Значение1С,ЗначениеADO,Direction,Type,Precision,NumericScale,Size,Attributes,ADOUtils);
ЕррорИнфо="";
Попытка
Если ОбъектЗапрос.Prepared = Ложь ИЛИ Инициализация <> Ложь Тогда
// инициализация параметров запроса
Добавить = Ложь;
Если Name = Неопределено Тогда
// по переданному индексу параметра
Parameter = ОбъектЗапрос.CreateParameter();
Добавить = Истина; // создаем без имени
Иначе
// по переданному имени параметра
Попытка
// если уже есть параметр с именем - используем его
Parameter = ОбъектЗапрос.Parameters.Item(Name);
Исключение
Parameter = Неопределено;
КонецПопытки;
Если Parameter = Неопределено Тогда
// если нет - создаем с указанным именем
Parameter = ОбъектЗапрос.CreateParameter();
Parameter.Name = Name;
Добавить = Истина;
КонецЕсли;
КонецЕсли;
Если НЕ ПустаяСтрока(Type) Тогда
Parameter.Type=Type;
КонецЕсли;
Если НЕ ПустаяСтрока(Direction) Тогда
Parameter.Direction=Direction;
КонецЕсли;
Если НЕ ПустаяСтрока(Size) Тогда
Parameter.Size=Size;
КонецЕсли;
Если НЕ ПустаяСтрока(Attributes) И Attributes <> 0 Тогда
Parameter.Attributes=Attributes;
КонецЕсли;
Если Добавить = Истина Тогда
ОбъектЗапрос.Parameters.Append(Parameter);
КонецЕсли;
Иначе
// установка параметра предварительно подготовленного параметризованного запроса
Если Name = Неопределено Тогда
// по переданному индексу параметра
Parameter = ОбъектЗапрос.Parameters.Item(Индекс);
Иначе
// по переданному имени параметра
Parameter = ОбъектЗапрос.Parameters.Item(Name);
КонецЕсли;
КонецЕсли;
Если ЗначениеADO = Неопределено Тогда
Parameter.Value=Значение1С; // преобразование не явное
Иначе
Parameter.Value=ЗначениеADO;
КонецЕсли;
Исключение
ЕррорИнфо=ОписаниеОшибки();
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
// ^^^ УСТАНОВКА ПАРАМЕТРОВ ЗАПРОСА ADO ^^^
// *** ПЕРЕЧИСЛЕНИЯ ADO ***
// возвращает строковое представление типа параметра ADO(свойства Direction) по его числовому значению
Функция strDirectionParADOЛкс(intTypeADOЛкс) Экспорт
intType = Цел(intTypeADOЛкс);
Если intType = 0 Тогда Возврат "adParamUnknown"; // Direction unknown
ИначеЕсли intType = 1 Тогда Возврат "adParamInput"; // Input parameter (Default)
ИначеЕсли intType = 2 Тогда Возврат "adParamOutput"; // Output parameter
ИначеЕсли intType = 3 Тогда Возврат "adParamInputOutput"; // Input and output parameter
ИначеЕсли intType = 4 Тогда Возврат "adParamReturnValue"; // Return value
Иначе Возврат "adParamInput"; // как 1
КонецЕсли;
КонецФункции
// возвращает числовое значения типа параметра ADO(свойства Direction) по его числовому представлению
Функция intDirectionParADOЛкс(strTypeADOЛкс) Экспорт
strType = НРег(strTypeADOЛкс);
Если strType = Нрег("adParamUnknown") Тогда Возврат 0; // Direction unknown
ИначеЕсли strType = Нрег("adParamInput") Тогда Возврат 1; // Input parameter (Default)
ИначеЕсли strType = Нрег("adParamOutput") Тогда Возврат 2; // Output parameter
ИначеЕсли strType = Нрег("adParamInputOutput") Тогда Возврат 3; // Input and output parameter
ИначеЕсли strType = Нрег("adParamReturnValue") Тогда Возврат 4; // Return value
Иначе Возврат 1; // adParamInput
КонецЕсли;
КонецФункции
// возвращает строковое представление типа значения ADO по его числовому значению
Функция strTypeADOЛкс(intTypeADOЛкс) Экспорт
intType = Цел(intTypeADOЛкс);
Если intType = 0 Тогда Возврат "adEmpty"; // no value
ИначеЕсли intType = 2 Тогда Возврат "adSmallInt"; // 2-byte signed integer
ИначеЕсли intType = 3 Тогда Возврат "adInteger"; // 4-byte signed integer
ИначеЕсли intType = 4 Тогда Возврат "adSingle"; // single-precision floating-point value
ИначеЕсли intType = 5 Тогда Возврат "adDouble"; // double-precision floating-point value
ИначеЕсли intType = 6 Тогда Возврат "adCurrency"; // currency value
ИначеЕсли intType = 7 Тогда Возврат "adDate"; // number of days since December 30, 1899 + the fraction of a day
ИначеЕсли intType = 8 Тогда Возврат "adBSTR"; // null-terminated character string
ИначеЕсли intType = 9 Тогда Возврат "adIDispatch"; // pointer to an IDispatch interface on a COM object(currently not supported by ADO)
ИначеЕсли intType = 10 Тогда Возврат "adError"; // 32-bit error code
ИначеЕсли intType = 11 Тогда Возврат "adBoolean"; // boolean value
ИначеЕсли intType = 12 Тогда Возврат "adVariant"; // automation Variant(currently not supported by ADO)
ИначеЕсли intType = 13 Тогда Возврат "adIUnknown"; // pointer to an IUnknown interface on a COM object(currently not supported by ADO)
ИначеЕсли intType = 14 Тогда Возврат "adDecimal"; // exact numeric value with a fixed precision and scale
ИначеЕсли intType = 16 Тогда Возврат "adTinyInt"; // 1-byte signed integer
ИначеЕсли intType = 17 Тогда Возврат "adUnsignedTinyInt"; // 1-byte unsigned integer
ИначеЕсли intType = 18 Тогда Возврат "adUnsignedSmallInt"; // 2-byte unsigned integer
ИначеЕсли intType = 19 Тогда Возврат "adUnsignedInt"; // 4-byte unsigned integer
ИначеЕсли intType = 20 Тогда Возврат "adBigInt"; // 8-byte signed integer
ИначеЕсли intType = 21 Тогда Возврат "adUnsignedBigInt"; // 8-byte unsigned integer
ИначеЕсли intType = 64 Тогда Возврат "adFileTime"; // number of 100-nanosecond intervals since January 1,1601
ИначеЕсли intType = 72 Тогда Возврат "adGUID"; // globally unique identifier (GUID)
ИначеЕсли intType = 128 Тогда Возврат "adBinary"; // binary value
ИначеЕсли intType = 129 Тогда Возврат "adChar"; // string value
ИначеЕсли intType = 130 Тогда Возврат "adWChar"; // null-terminated Unicode character string
ИначеЕсли intType = 131 Тогда Возврат "adNumeric"; // exact numeric value with a fixed precision and scale
ИначеЕсли intType = 132 Тогда Возврат "adUserDefined"; // user-defined variable
ИначеЕсли intType = 133 Тогда Возврат "adDBDate"; // date value (yyyymmdd)
ИначеЕсли intType = 134 Тогда Возврат "adDBTime"; // time value (hhmmss)
ИначеЕсли intType = 135 Тогда Возврат "adDBTimeStamp"; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths)
ИначеЕсли intType = 136 Тогда Возврат "adChapter"; // 4-byte chapter value that identifies rows in a child rowset
ИначеЕсли intType = 138 Тогда Возврат "adPropVariant"; // automation PROPVARIANT
ИначеЕсли intType = 139 Тогда Возврат "adVarNumeric"; // numeric value(Parameter object only)
ИначеЕсли intType = 200 Тогда Возврат "adVarChar"; // string value (Parameter object only)
ИначеЕсли intType = 201 Тогда Возврат "adLongVarChar"; // long string value
ИначеЕсли intType = 202 Тогда Возврат "adVarWChar"; // null-terminated Unicode character string
ИначеЕсли intType = 203 Тогда Возврат "adLongVarWChar"; // long null-terminated Unicode string value
ИначеЕсли intType = 204 Тогда Возврат "adVarBinary"; // binary value (Parameter object only)
ИначеЕсли intType = 205 Тогда Возврат "adLongVarBinary"; // long binary value
ИначеЕсли intType = 8192 Тогда Возврат "AdArray"; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type
Иначе Возврат "adEmpty"; // как 0
КонецЕсли;
КонецФункции
// возвращает числовое значение типа значения ADO по его строковому представлению
Функция intTypeADOЛкс(strTypeADOЛкс) Экспорт
strType = НРег(strTypeADOЛкс);
Если strType = НРег("adEmpty") Тогда Возврат 0; // no value
ИначеЕсли strType = НРег("adSmallInt") Тогда Возврат 2; // 2-byte signed integer
ИначеЕсли strType = НРег("adInteger") Тогда Возврат 3; // 4-byte signed integer
ИначеЕсли strType = НРег("adSingle") Тогда Возврат 4; // single-precision floating-point value
ИначеЕсли strType = НРег("adDouble") Тогда Возврат 5; // double-precision floating-point value
ИначеЕсли strType = НРег("adCurrency") Тогда Возврат 6; // currency value
ИначеЕсли strType = НРег("adDate") Тогда Возврат 7; // number of days since December 30, 1899 + the fraction of a day
ИначеЕсли strType = НРег("adBSTR") Тогда Возврат 8; // null-terminated character string
ИначеЕсли strType = НРег("adIDispatch") Тогда Возврат 9; // pointer to an IDispatch interface on a COM object(currently not supported by ADO)
ИначеЕсли strType = НРег("adError") Тогда Возврат 10; // 32-bit error code
ИначеЕсли strType = НРег("adBoolean") Тогда Возврат 11; // boolean value
ИначеЕсли strType = НРег("adVariant") Тогда Возврат 12; // automation Variant(currently not supported by ADO)
ИначеЕсли strType = НРег("adIUnknown") Тогда Возврат 13; // pointer to an IUnknown interface on a COM object(currently not supported by ADO)
ИначеЕсли strType = НРег("adDecimal") Тогда Возврат 14; // exact numeric value with a fixed precision and scale
ИначеЕсли strType = НРег("adTinyInt") Тогда Возврат 16; // 1-byte signed integer
ИначеЕсли strType = НРег("adUnsignedTinyInt") Тогда Возврат 17; // 1-byte unsigned integer
ИначеЕсли strType = НРег("adUnsignedSmallInt") Тогда Возврат 18;// 2-byte unsigned integer
ИначеЕсли strType = НРег("adUnsignedInt") Тогда Возврат 19; // 4-byte unsigned integer
ИначеЕсли strType = НРег("adBigInt") Тогда Возврат 20; // 8-byte signed integer
ИначеЕсли strType = НРег("adUnsignedBigInt") Тогда Возврат 21; // 8-byte unsigned integer
ИначеЕсли strType = НРег("adFileTime") Тогда Возврат 64; // number of 100-nanosecond intervals since January 1,1601
ИначеЕсли strType = НРег("adGUID") Тогда Возврат 72; // globally unique identifier (GUID)
ИначеЕсли strType = НРег("adBinary") Тогда Возврат 128; // binary value
ИначеЕсли strType = НРег("adChar") Тогда Возврат 129; // string value
ИначеЕсли strType = НРег("adWChar") Тогда Возврат 130; // null-terminated Unicode character string
ИначеЕсли strType = НРег("adNumeric") Тогда Возврат 131; // exact numeric value with a fixed precision and scale
ИначеЕсли strType = НРег("adUserDefined") Тогда Возврат 132; // user-defined variable
ИначеЕсли strType = НРег("adDBDate") Тогда Возврат 133; // date value (yyyymmdd)
ИначеЕсли strType = НРег("adDBTime") Тогда Возврат 134; // time value (hhmmss)
ИначеЕсли strType = НРег("adDBTimeStamp") Тогда Возврат 135; // date/time stamp (yyyymmddhhmmss plus a fraction in billionths)
ИначеЕсли strType = НРег("adChapter") Тогда Возврат 136; // 4-byte chapter value that identifies rows in a child rowset
ИначеЕсли strType = НРег("adPropVariant") Тогда Возврат 138; // automation PROPVARIANT
ИначеЕсли strType = НРег("adVarNumeric") Тогда Возврат 139; // numeric value(Parameter object only)
ИначеЕсли strType = НРег("adVarChar") Тогда Возврат 200; // string value (Parameter object only)
ИначеЕсли strType = НРег("adLongVarChar") Тогда Возврат 201; // long string value
ИначеЕсли strType = НРег("adVarWChar") Тогда Возврат 202; // null-terminated Unicode character string
ИначеЕсли strType = НРег("adLongVarWChar") Тогда Возврат 203; // long null-terminated Unicode string value
ИначеЕсли strType = НРег("adVarBinary") Тогда Возврат 204; // binary value (Parameter object only)
ИначеЕсли strType = НРег("adLongVarBinary") Тогда Возврат 205; // long binary value
ИначеЕсли strType = НРег("AdArray") Тогда Возврат 8192; // 0x2000, flag value combined with another data type constant, indicates an array of that other data type
Иначе Возврат 0; // adEmpty
КонецЕсли;
КонецФункции
// возвращает числовое значение типа курсора по его строковому представлению
Функция strCursorTypeЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adOpenUnspecified"; // Does not specify the type of cursor
ИначеЕсли intV = 0 Тогда Возврат "adOpenForwardOnly"; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default)
ИначеЕсли intV = 1 Тогда Возврат "adOpenKeyset"; // Uses a keyset cursor. Like a dynamic cursor, except...
ИначеЕсли intV = 2 Тогда Возврат "adOpenDynamic"; // Uses a dynamic cursor
ИначеЕсли intV = 3 Тогда Возврат "adOpenStatic"; // Uses a static cursor
Иначе Возврат "adOpenForwardOnly"; // как 0
КонецЕсли;
КонецФункции
// возвращает строковое представление типа курсора по его числовому значению
Функция intCursorTypeЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adOpenUnspecified") Тогда Возврат -1; // Does not specify the type of cursor
ИначеЕсли strV = Нрег("adOpenForwardOnly") Тогда Возврат 0; // Default. Uses a forward-only cursor. Like a static cursor, except... (Default
ИначеЕсли strV = Нрег("adOpenKeyset") Тогда Возврат 1; // Uses a keyset cursor. Like a dynamic cursor, except...
ИначеЕсли strV = Нрег("adOpenDynamic") Тогда Возврат 2; // Uses a dynamic cursor
ИначеЕсли strV = Нрег("adOpenStatic") Тогда Возврат 3; // Uses a static cursor
Иначе Возврат 0; // adOpenForwardOnly
КонецЕсли;
КонецФункции
// возвращает числовое значение местоположения курсора по его строковому представлению
Функция strCursorLocationЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 1 Тогда Возврат "adUseNone"; // Does not use cursor services
ИначеЕсли intV = 2 Тогда Возврат "adUseServer"; // Uses a server-side cursor (Default)
ИначеЕсли intV = 3 Тогда Возврат "adParamOutput"; // Uses a client-side cursor supplied by a local cursor library
Иначе Возврат "adUseServer"; // как 2
КонецЕсли;
КонецФункции
// возвращает строковое представление местоположения курсора по его числовому значению
Функция intCursorLocationЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adUseNone") Тогда Возврат 1; // Does not use cursor services
ИначеЕсли strV = Нрег("adUseServer") Тогда Возврат 2; // Uses a server-side cursor (Default)
ИначеЕсли strV = Нрег("adParamOutput") Тогда Возврат 3; // Uses a client-side cursor supplied by a local cursor library
Иначе Возврат 2; // adUseServer
КонецЕсли;
КонецФункции
// возвращает числовое значение типа блокировки данных по его строковому представлению
Функция strLockTypeЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adLockUnspecified"; // Unspecified type of lock. Clones inherits lock type from the original Recordset
ИначеЕсли intV = 1 Тогда Возврат "adLockReadOnly"; // Read-only records
ИначеЕсли intV = 2 Тогда Возврат "adLockPessimistic"; // Pessimistic locking, record by record. The provider lock records immediately after editing
ИначеЕсли intV = 3 Тогда Возврат "adLockOptimistic"; // Optimistic locking, record by record. The provider lock records only when calling update
ИначеЕсли intV = 4 Тогда Возврат "adLockBatchOptimistic"; // Optimistic batch updates. Required for batch update mode
Иначе Возврат "adLockUnspecified"; // как -1
КонецЕсли;
КонецФункции
// возвращает строковое представление типа блокировки данных по его числовому значению
Функция intLockTypeЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adLockUnspecified") Тогда Возврат -1; // Unspecified type of lock
ИначеЕсли strV = Нрег("adLockReadOnly") Тогда Возврат 1; // Read-only records
ИначеЕсли strV = Нрег("adLockPessimistic") Тогда Возврат 2; // Pessimistic locking, record by record. The provider lock records immediately after editing
ИначеЕсли strV = Нрег("adLockOptimistic") Тогда Возврат 3; // Optimistic locking, record by record. The provider lock records only when calling update
ИначеЕсли strV = Нрег("adLockBatchOptimistic") Тогда Возврат 4; // Optimistic batch updates. Required for batch update mode
Иначе Возврат -1; // adLockUnspecified
КонецЕсли;
КонецФункции
// возвращает числовое значение опции MarshalOptions по его строковому представлению
Функция strMarshalOptionsЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 0 Тогда Возврат "adMarshalAll"; // Returns all rows (Default)
ИначеЕсли intV = 1 Тогда Возврат "adMarshalModifiedOnly"; // Returns only modified rows
Иначе Возврат "adMarshalAll"; // как 0
КонецЕсли;
КонецФункции
// возвращает строковое представление опции MarshalOptions по его числовому значению
Функция intMarshalOptionsЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adMarshalAll") Тогда Возврат 0; // Returns all rows (Default)
ИначеЕсли strV = Нрег("adMarshalModifiedOnly") Тогда Возврат 1; // Returns only modified rows
Иначе Возврат 0; // adMarshalAll
КонецЕсли;
КонецФункции
// возвращает строковое представление типа команды ADO по его числовому значению
Функция strCommandTypeADOЛкс(intTypeADOЛкс) Экспорт
Если ТипЗнч(intTypeADOЛкс) = Тип("Число") Тогда
intType = Цел(intTypeADOЛкс);
Иначе
intType = 0;
КонецЕсли;
Если intType = -1 Тогда Возврат "adCmdUnspecified"; // Unspecified type of command
ИначеЕсли intType = 1 Тогда Возврат "adCmdText"; // строка оператора T-SQL
ИначеЕсли intType = 2 Тогда Возврат "adCmdTable"; // имя таблицы для выборки строк
ИначеЕсли intType = 4 Тогда Возврат "adCmdStoredProc"; // имя хранимой процедуры
ИначеЕсли intType = 8 Тогда Возврат "adCmdUnknown"; // неизвестно, проверять провайдером (Default)
ИначеЕсли intType = 256 Тогда Возврат "adCmdFile"; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only)
ИначеЕсли intType = 512 Тогда Возврат "adCmdTableDirect"; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only)
Иначе Возврат "adCmdUnknown"; // как 8
КонецЕсли;
КонецФункции
// возвращает числовое значение типа команды ADO по его строковому представлению
Функция intCommandTypeADOЛкс(strTypeADOЛкс) Экспорт
strType = Нрег(strTypeADOЛкс);
Если strType = Нрег("adCmdUnspecified") Тогда Возврат -1; // Unspecified type of command
ИначеЕсли strType = Нрег("adCmdText") Тогда Возврат 1; // строка оператора T-SQL
ИначеЕсли strType = Нрег("adCmdTable") Тогда Возврат 2; // имя таблицы для выборки строк
ИначеЕсли strType = Нрег("adCmdStoredProc") Тогда Возврат 4; // имя хранимой процедуры
ИначеЕсли strType = Нрег("adCmdUnknown") Тогда Возврат 8; // неизвестно, проверять провайдером (Default)
ИначеЕсли strType = Нрег("adCmdFile") Тогда Возврат 256; // имя файла of a persistently stored Recordset (with Recordset.Open or Requery only)
ИначеЕсли strType = Нрег("adCmdTableDirect") Тогда Возврат 512; // имя таблицы whose columns are all returned (with Recordset.Open or Requery only)
Иначе Возврат 8; // adCmdUnknown
КонецЕсли;
КонецФункции
// возвращает строковое представление типа команды ADO по его числовому значению
Функция strExecuteOptionЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = -1 Тогда Возврат "adOptionUnspecified"; // Unspecified command
ИначеЕсли intV = 16 Тогда Возврат "adAsyncExecute"; // The command should execute asynchronously
ИначеЕсли intV = 32 Тогда Возврат "adAsyncFetch"; // The remaining rows after specified in the CacheSize should be retrieved asynchronously
ИначеЕсли intV = 64 Тогда Возврат "adAsyncFetchNonBlocking"; // The main thread never blocks while retrieving.
ИначеЕсли intV = 128 Тогда Возврат "adExecuteNoRecords"; // Discard, not return retrieved rows (with Command or Connection.Execute only)
ИначеЕсли intV = 256 Тогда Возврат "adExecuteStream"; // The results of a command execution is a stream (with Connection.Execute only)
ИначеЕсли intV = 512 Тогда Возврат "adExecuteRecord"; // Return a single row as a Record object
Иначе Возврат "adOptionUnspecified"; // как -1
КонецЕсли;
КонецФункции
// возвращает числовое значение типа команды ADO по его строковому представлению
Функция intExecuteOptionЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adOptionUnspecified") Тогда Возврат -1; // Unspecified command
ИначеЕсли strV = Нрег("adAsyncExecute") Тогда Возврат 16; // The command should execute asynchronously
ИначеЕсли strV = Нрег("adAsyncFetch") Тогда Возврат 32; // The remaining rows after specified in the CacheSize should be retrieved asynchronously
ИначеЕсли strV = Нрег("adAsyncFetchNonBlocking") Тогда Возврат 64; // The main thread never blocks while retrieving
ИначеЕсли strV = Нрег("adExecuteNoRecords") Тогда Возврат 128; // Discard, not return retrieved rows (with Command or Connection.Execute only)
ИначеЕсли strV = Нрег("adExecuteStream") Тогда Возврат 256; // The results of a command execution is a stream (with Connection.Execute only)
ИначеЕсли strV = Нрег("adExecuteRecord") Тогда Возврат 512; // Return a single row as a Record object
Иначе Возврат -1; // adOptionUnspecified
КонецЕсли;
КонецФункции
// возвращает строковое представление опции аттрибутов параметра ADO по числовому значению опции
Функция strParameterADOAttributesЛкс(intValue) Экспорт
Если ТипЗнч(intValue) = Тип("Число") Тогда
intV = Цел(intValue);
Иначе
intV = 0;
КонецЕсли;
Если intV = 16 Тогда Возврат "adParamSigned"; // The parameter will accept signed values.
ИначеЕсли intV = 64 Тогда Возврат "adParamNullAble"; // The parameter will accept null values.
ИначеЕсли intV = 128 Тогда Возврат "adParamLong"; // The parameter will accept long binary data.
Иначе Возврат "adParamSigned"; // как 16
КонецЕсли;
КонецФункции
// возвращает числовое значение оцции аттрибутов параметра ADO по строковому представлению опции
Функция intParameterADOAttributesЛкс(strValue) Экспорт
strV = Нрег(strValue);
Если strV = Нрег("adParamSigned") Тогда Возврат 16; // The parameter will accept signed values.
ИначеЕсли strV = Нрег("adParamNullAble") Тогда Возврат 64; // The parameter will accept null values.
ИначеЕсли strV = Нрег("adParamLong") Тогда Возврат 128; // The parameter will accept long binary data.
Иначе Возврат 16; // adParamSigned
КонецЕсли;
КонецФункции
// ^^^ ПЕРЕЧИСЛЕНИЯ ADO ^^^
// ADO
// ************************
// В платформе все корневые элементы древовидных структур содержат в свойстве Родитель Неопределено.
// Поэтому возникает неудобство при работе с этим свойством, заключающееся в необходимости часто проверять его значение на Неопределено.
// Параметры:
// СтрокаДерева - СтрокаДереваЗначений, <Элемент любого иерархического объекта, имеющий родителя>
// Дерево - <Иерархический объект, которому принадлежит элемент> - для дерева значений не нужно передавать
//
Функция ПолучитьРодителяСтрокиДереваЛкс(СтрокаДерева, Дерево = Неопределено) Экспорт
Родитель = СтрокаДерева.Родитель;
Если Родитель = Неопределено Тогда
Если Дерево = Неопределено Тогда
Родитель = СтрокаДерева.Владелец();
Иначе
Родитель = Дерево;
КонецЕсли;
КонецЕсли;
Возврат Родитель;
КонецФункции
// Результат - Неопределено, "*", Число
Функция ПолучитьКоличествоЭлементовКоллекцииЛкс(Значение) Экспорт
Если Не ЭтоКоллекцияЛкс(Значение) Тогда
КоличествоЭлементов = Неопределено;
Иначе
КоличествоЭлементов = "*";
Если ТипЗнч(Значение) = Тип("COMSafeArray") Тогда
КоличествоЭлементов = Значение.GetLength();
ИначеЕсли ТипЗнч(Значение) = Тип("COMОбъект") Тогда
Попытка
КоличествоЭлементов = Значение.Count;
Исключение
КонецПопытки;
КонецЕсли;
Если КоличествоЭлементов = "*" Тогда
Попытка
КоличествоЭлементов = Значение.Количество();
Исключение
КонецПопытки;
КонецЕсли;
КонецЕсли;
Возврат КоличествоЭлементов;
КонецФункции
Функция ЭтоКоллекцияЛкс(Значение) Экспорт
// Антибаг платформы 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1017316#1017316
Если Значение = ПараметрыСеанса Тогда
Возврат Истина;
КонецЕсли;
Попытка
Для Каждого _Элемент Из Значение Цикл
Прервать;
КонецЦикла;
ЭтоКоллекция = Истина;
Исключение
ЭтоКоллекция = Ложь;
КонецПопытки;
Возврат ЭтоКоллекция;
КонецФункции
Функция ПолучитьОбъектПоПолномуИмениМетаданныхЛкс(ПолноеИмяМД) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
ТипМетаданных = Фрагменты[0];
ИмяОбъекта = Фрагменты[1];
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Результат = Новый(ТипМетаданных + "Объект." + ИмяОбъекта);
Иначе
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(ИмяОбъекта, ТипМетаданных);
Попытка
Результат = Менеджер.Создать(ПолноеИмяФайла, Ложь);
Исключение
// Это очень помогает при ошибках функций режима отладки
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
#Если Не ТонкийКлиент И Не ВебКлиент И Клиент Тогда
Функция ПолучитьКоординатыСтрокиДереваЛкс(СтрокаДерева, ИмяКлючевойКолонки = "") Экспорт
Координаты = Новый Массив();
Родитель = СтрокаДерева;
Пока Родитель <> Неопределено Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
Координата = Родитель[ИмяКлючевойКолонки];
Иначе
Координата = ПолучитьРодителяСтрокиДереваЛкс(Родитель).Строки.Индекс(Родитель);
КонецЕсли;
Координаты.Вставить(0, Координата);
Родитель = Родитель.Родитель;
КонецЦикла;
Возврат Координаты;
КонецФункции
Функция ПолучитьСтрокуДереваПоКоординатамЛкс(Дерево, Координаты, ИмяКлючевойКолонки = "") Экспорт
СтрокаДерева = Дерево;
Для Каждого Координата Из Координаты Цикл
Если ЗначениеЗаполнено(ИмяКлючевойКолонки) Тогда
СтрокаДерева = СтрокаДерева.Строки.Найти(Координата, ИмяКлючевойКолонки);
Иначе
СтрокаДерева = СтрокаДерева.Строки[Координата];
КонецЕсли;
КонецЦикла;
Возврат СтрокаДерева;
КонецФункции
Процедура УстановитьТекстПоляСохраняяПозициюЛкс(ПолеТекстовогоДокумента, НовыйТекст) Экспорт
НачальнаяКолонка = 0; НачальнаяСтрока = 0; КонечнаяКолонка = 0; КонечнаяСтрока = 0;
ПолеТекстовогоДокумента.ПолучитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
ПолеТекстовогоДокумента.УстановитьТекст(НовыйТекст);
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(НачальнаяСтрока, НачальнаяКолонка, КонечнаяСтрока, КонечнаяКолонка);
КонецПроцедуры
Функция ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL) Экспорт
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ЗначениеSDBL, ":");
Если Фрагменты.Количество() < 2 Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаНомераТаблицы = Фрагменты[0];
ИдентификаторОбъекта = Фрагменты[1];
ПолноеИмяМД = ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомераТаблицы);
ОбъектМетаданныхНайден = Истина;
Если Не ЗначениеЗаполнено(ПолноеИмяМД) Тогда
ПолноеИмяМД = "НеизвестныйСсылочныйТип" + СтрокаНомераТаблицы;
ОбъектМетаданныхНайден = Ложь;
КонецЕсли;
Результат = ПолноеИмяМД + "._" + ИдентификаторОбъекта;
Если ОбъектМетаданныхНайден Тогда
//СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(Ложь);
// Этот способ не работал для перечислений
//УникальныйИдентификатор = Новый УникальныйИдентификатор(ПолучитьГУИДПрямойИзИнверсногоЛкс(Фрагменты[1]));
//Массив = Новый Массив();
//Если ЗначениеЗаполнено(УникальныйИдентификатор) Тогда
// Массив.Добавить(УникальныйИдентификатор);
//КонецЕсли;
//Значение = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)), Массив);
//
ПустаяСсылка = Новый (Тип(ПолучитьИмяТипаСсылкиТаблицыБДЛкс(ПолноеИмяМД)));
ПустаяСсылкаВнутр = ЗначениеВСтрокуВнутр(ПустаяСсылка);
ФрагментыПустойСсылки = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПустаяСсылкаВнутр, ":");
СсылкаВнутр = ФрагментыПустойСсылки[0] + ":" + ИдентификаторОбъекта + "}";
Попытка
Результат = ЗначениеИзСтрокиВнутр(СсылкаВнутр);
Исключение
// Например, если Фрагменты[1] содержит неверное число символов
КонецПопытки;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(СтрокаНомерТаблицы) Экспорт
СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс();
#Если _ Тогда
СтруктураБД = Новый ТаблицаЗначений;
#КонецЕсли
СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданных();
Для Каждого СтрокаШаблона Из СловарьШаблоновМетаданных.НайтиСтроки(Новый Структура("Значение", 1)) Цикл
ИмяКандидат = СтрЗаменить(СтрокаШаблона.Ключ, "1", СтрокаНомерТаблицы);
СтрокаСтруктуры = СтруктураБД.Найти(ИмяКандидат, "КраткоеИмяТаблицыХранения");
Если СтрокаСтруктуры <> Неопределено Тогда
Возврат СтрокаСтруктуры.Метаданные;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
Функция ПолучитьИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки) Экспорт
Попытка
ТипЗначения = ДанныеСтроки.ТипЗначения;
Исключение
ТипЗначения = Неопределено;
КонецПопытки;
ИндексКартинки = -1;
Если Ложь
Или ДанныеСтроки.ТипСлова = "Ключевое слово"
Или ДанныеСтроки.ТипСлова = "Конструкция"
Тогда
ИндексКартинки = 13;
ИначеЕсли ТипЗначения = "Имя типа" Тогда
ИндексКартинки = 12;
ИначеЕсли ДанныеСтроки.ТипСлова = "Метод" Тогда
Попытка
Пустышка = ДанныеСтроки.Успех;
ЕстьУспех = Истина;
Исключение
ЕстьУспех = Ложь;
КонецПопытки;
Если Ложь
Или (Истина
И ЕстьУспех
И (Ложь
Или ДанныеСтроки.ТаблицаСтруктурТипов = Неопределено
Или ДанныеСтроки.ТаблицаСтруктурТипов.Количество() = 0
Или ДанныеСтроки.ТаблицаСтруктурТипов[0].ИмяОбщегоТипа = ""))
Или (Истина
И Не ЕстьУспех
И ДанныеСтроки.ТипЗначения = "")
Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 0;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 6;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 9;
Иначе
ИндексКартинки = 3;
КонецЕсли;
Иначе
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 1;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 7;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 10;
Иначе
ИндексКартинки = 4;
КонецЕсли;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Свойство" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 2;
ИначеЕсли ДанныеСтроки.Определение = "Метаданные" Тогда
ИндексКартинки = 8;
//ИначеЕсли ДанныеСтроки.Определение = "Локальный" Тогда
// ИндексКартинки = 11;
Иначе
ИндексКартинки = 5;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Таблица" Тогда
ИндексКартинки = 14;
ИначеЕсли ДанныеСтроки.ТипСлова = "Поле" Тогда
Если ДанныеСтроки.Определение = "Предопределенный" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
ИначеЕсли ДанныеСтроки.ТипСлова = "Группа" Тогда
ИндексКартинки = 18;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
// Эта обертка нужно для возможности привязать ее к команде панели инструментов
Процедура ОтладитьОтложенныйОбъектБезПараметровЛкс() Экспорт
ОтладитьОтложенныйОбъектЛкс();
КонецПроцедуры
Процедура ОтладитьОтложенныйОбъектЛкс(СсылкаИлиИмяФайла = Неопределено, УдалитьОбъектПослеУспешногоОткрытия = Ложь) Экспорт
#Если _ Тогда
Ссылка = Справочники.ирОбъектыДляОтладки.ПустаяСсылка();
#КонецЕсли
Если СсылкаИлиИмяФайла = Неопределено Тогда
СсылкаИлиИмяФайла = ПолучитьТекстИзБуфераОбменаОСЛкс();
ЭтоФайл = Неопределено;
Если Не ВвестиСтроку(СсылкаИлиИмяФайла, "Введите результат сохранения объекта") Тогда
СсылкаИлиИмяФайла = ВыбратьОтложенныйОбъектДляОтладкиЛкс();
КонецЕсли;
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
ВычислительРегулярныхВыражений = ирКэш.Получить().RegExp;
ВычислительРегулярныхВыражений.Pattern = "Файл ""(.+)""";
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
Если Результат.Count = 0 Тогда
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
ВычислительРегулярныхВыражений.Pattern = "\b([A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12})\b";
Результат = ВычислительРегулярныхВыражений.Execute(СсылкаИлиИмяФайла);
ЭтоФайл = Ложь;
КонецЕсли;
Иначе
ЭтоФайл = Истина;
КонецЕсли;
Если Результат.Count = 0 Тогда
Сообщить("Введен некорректный результат сохранения объекта для отладки");
Возврат;
КонецЕсли;
СсылкаИлиИмяФайла = Результат.Item(0).SubMatches(0);
Если ЭтоФайл Тогда
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
// Перекладываем из файла в новый элемент справочника
ФайлОбъектаДляОтладки = Новый Файл(СсылкаИлиИмяФайла);
ОбъектДляОтладки = ВосстановитьОбъектИзСтрокиXMLЛкс(ФайлОбъектаДляОтладки);
РезультатОтложения = ОтложитьУпакованныйОбъектДляОтладкиЛкс(ОбъектДляОтладки, СсылкаИлиИмяФайла);
Сообщить(РезультатОтложения);
УдалитьФайлы(ФайлОбъектаДляОтладки.ПолноеИмя);
КонецЕсли;
Иначе
СсылкаИлиИмяФайла = Справочники.ирОбъектыДляОтладки.ПолучитьСсылку(Новый УникальныйИдентификатор(СсылкаИлиИмяФайла));
Если Не ЗначениеЗаполнено(СсылкаИлиИмяФайла) Тогда
Возврат;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
// СтрокаРезультата = ПолучитьИзВременногоХранилища(СсылкаИлиИмяФайла);
// Если СтрокаРезультата = Неопределено Тогда
// Сообщить("Временное хранилище пусто. Вероятно отлаживаемый сеанс завершился.");
// Возврат;
// КонецЕсли;
ЧтениеXML = Новый ЧтениеXML;
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
ЧтениеXML.ОткрытьФайл(СсылкаИлиИмяФайла);
Иначе
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ирОбъектыДляОтладки.XML
|ИЗ
| Справочник.ирОбъектыДляОтладки КАК ирОбъектыДляОтладки
|ГДЕ
| ирОбъектыДляОтладки.Ссылка = &Ссылка
|";
Запрос.УстановитьПараметр("Ссылка", СсылкаИлиИмяФайла);
ТаблицаРезультата = Запрос.Выполнить().Выгрузить();
Если ТаблицаРезультата.Количество() = 0 Тогда
Сообщить("Объект для отладки не найден в справочнике. Вероятно он был удален.");
Возврат;
КонецЕсли;
СтрокаРезультата = ТаблицаРезультата[0];
СтрокаРезультата = СтрокаРезультата.XML;
ЧтениеXML.УстановитьСтроку(СтрокаРезультата);
КонецЕсли;
Попытка
СтруктураПараметров = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Сообщить("Некорректный объект для отладки: " + ОписаниеОшибки, СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
Объект = СтруктураПараметров.Объект;
ТипОперации = СтруктураПараметров.ТипОперации;
Если ТипОперации = "Отладить" Тогда
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = СтруктураПараметров.НастройкаКомпоновки;
Если ТипЗнч(Объект) = Тип("Структура") Тогда
СтруктураЗапроса = Объект;
Объект = Новый Запрос;
Если Истина
И СтруктураЗапроса.Свойство("ВременныеТаблицы")
И СтруктураЗапроса.ВременныеТаблицы <> Неопределено
Тогда
Объект.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = "";
#Если Клиент Тогда
СостояниеЛкс("Подготовка временных таблиц");
#КонецЕсли
ТекстЗапросаПодготовки = "";
Для Каждого КлючИЗначение Из СтруктураЗапроса.ВременныеТаблицы Цикл
Если ТекстЗапросаПодготовки <> "" Тогда
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + ";";
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + ",";
КонецЕсли;
ТекстЗапросаПодготовки = ТекстЗапросаПодготовки + "ВЫБРАТЬ Т.* ПОМЕСТИТЬ " + КлючИЗначение.Ключ + " ИЗ &" + КлючИЗначение.Ключ + " КАК Т";
НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц + КлючИЗначение.Ключ;
КонецЦикла;
Если ЗначениеЗаполнено(ТекстЗапросаПодготовки) Тогда
Объект.Текст = ТекстЗапросаПодготовки;
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураЗапроса.ВременныеТаблицы, Объект.Параметры);
Попытка
Объект.Выполнить();
Исключение
Сообщить("Ошибка восстановления временных таблиц: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
Объект.Параметры.Очистить();
Объект.Текст = СтруктураЗапроса.Текст;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураЗапроса.Параметры, Объект.Параметры);
Для Каждого КлючИЗначение Из СтруктураЗапроса.Параметры Цикл
Объект.Параметры.Вставить(КлючИЗначение.Ключ, ЗначениеИзСтрокиВнутр(КлючИЗначение.Значение));
КонецЦикла;
КонецЕсли;
ОтладитьЛкс(Объект, , НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, СтруктураПараметров.ВнешниеНаборыДанных);
ИначеЕсли ТипОперации = "Исследовать" Тогда
ИсследоватьЛкс(Объект, , СтруктураПараметров.КакКоллекцию);
КонецЕсли;
Если УдалитьОбъектПослеУспешногоОткрытия Тогда
Если ТипЗнч(СсылкаИлиИмяФайла) = Тип("Строка") Тогда
УдалитьФайлы(СсылкаИлиИмяФайла);
Иначе
УдалениеОбъекта = Новый УдалениеОбъекта(СсылкаИлиИмяФайла);
УдалениеОбъекта.ОбменДанными.Загрузка = Истина;
УдалениеОбъекта.Записать();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ВыбратьОтложенныйОбъектДляОтладкиЛкс()
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
СсылкаИлиИмяФайла = ВыбратьСсылкуЛкс(Метаданные.Справочники.ирОбъектыДляОтладки);
Иначе
ПутьДляФайловОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс();
Расширение = ПолучитьРасширениеФайловДляОтладкиЛкс();
лПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, "Файлы снимков объектов для отладки",, ПутьДляФайловОбъектовДляОтладки);
Если лПолноеИмяФайла <> Неопределено Тогда
СсылкаИлиИмяФайла = "Файл """ + лПолноеИмяФайла + """";
КонецЕсли;
КонецЕсли;
Возврат СсылкаИлиИмяФайла;
КонецФункции
// ОформляемыеКолонки - имена колонок, разделенные запятыми
Процедура ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля(ОформлениеСтроки, Знач ОформляемыеКолонки = "") Экспорт
ОформляемыеКолонки = Новый Структура(ОформляемыеКолонки);
НеФильтровтатьКолонки = (ОформляемыеКолонки.Количество() = 0);
Для Каждого Ячейка Из ОформлениеСтроки.Ячейки Цикл
Если Ложь
Или НеФильтровтатьКолонки
Или ОформляемыеКолонки.Свойство(Ячейка.Имя)
Тогда
ЗначениеЯчейки = Ячейка.Значение;
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
Ячейка.УстановитьТекст(ирКэш.Получить().мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки));
Ячейка.ЦветФона = WebЦвета.Роса;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ОтобразитьПустыеЗначенияВЯчейкахТабличногоПоля()
Процедура ПолеВвода_ОкончаниеВводаТекстаЛкс(Элемент, Текст, Значение, СтандартнаяОбработка, РасширенноеЗначение = Null, ЛиТипСтрокаСлужебный = Ложь) Экспорт
Менеджер = Неопределено;
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
Типы = Элемент.ТипЗначения.Типы();
Если Типы.Количество() > 1 Тогда
ПредставлениеЗначения = ПолучитьСтрокуМеждуМаркерамиЛкс(Элемент.Значение, "(", ")");
ЗначениеСсылки = ПреобразоватьЗначениеИзSDBLЛкс(ПредставлениеЗначения);
Если Истина
И ЗначениеСсылки <> Неопределено
И ТипЗнч(ЗначениеСсылки) <> Тип("Строка")
И Элемент.ТипЗначения.СодержитТип(ТипЗнч(ЗначениеСсылки))
Тогда
Ответ = КодВозвратаДиалога.Да;
Если Не ЛиТипСтрокаСлужебный Тогда
Ответ = Вопрос("Хотите вставить строку как ссылку?", РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Нет);
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
Значение = ЗначениеСсылки;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(ЗначениеСсылки) Тогда
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(Элемент.Значение);
Если Фрагменты.Количество() > 1 Тогда
ИмяТипа = Фрагменты[0] + "." + Фрагменты[1];
Попытка
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипа);
Исключение
ОписаниеТипов = Неопределено;
КонецПопытки;
Если ОписаниеТипов <> Неопределено Тогда
Значение = ОписаниеТипов.ПривестиЗначение();
Менеджер = ПолучитьМенеджерЛкс(Значение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Истина
И ЛиТипСтрокаСлужебный
И СтандартнаяОбработка
И ЗначениеЗаполнено(Элемент.Значение)
Тогда
Значение = "";
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЛиТипСсылкиНаОбъектБДЛкс(ТипЗнч(Элемент.Значение)) Тогда
Менеджер = ПолучитьМенеджерЛкс(Элемент.Значение);
КонецЕсли;
Если Менеджер <> Неопределено Тогда
УникальныйИдентификатор = ирКэш.Получить().ПолучитьУникальныйИдентификаторИзСтроки(Текст);
Если УникальныйИдентификатор <> Неопределено Тогда
СтандартнаяОбработка = Ложь;
Значение = Менеджер.ПолучитьСсылку(УникальныйИдентификатор);
Иначе
ОбъектМД = Элемент.Значение.Метаданные();
ПредставлениеТипаДокумента = ОбъектМД.Представление();
Если Найти(Текст, ПредставлениеТипаДокумента) = 1 Тогда
ЧастьТекста = Сред(Текст, СтрДлина(ПредставлениеТипаДокумента) + 2);
RegExp = ирКэш.Получить().RegExp;
RegExp.Pattern = "\ от\ (\d+\.\d+\.\d+\ \d+\:\d+\:\d+)$";
Результаты = RegExp.Execute(ЧастьТекста);
Если Результаты.Count > 0 Тогда
Номер = Лев(ЧастьТекста, Результаты.Item(0).FirstIndex);
Дата = Результаты.Item(0).Submatches(0);
Попытка
Дата = Дата(Дата);
Исключение
Дата = Неопределено;
КонецПопытки;
Если Дата <> Неопределено Тогда
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| _Т.Ссылка
|ИЗ
| " + ОбъектМД.ПолноеИмя() + " КАК _Т
|ГДЕ
| _Т.Номер = &Номер
| И _Т.Дата = &Дата
|";
Запрос.УстановитьПараметр("Номер", Номер);
Запрос.УстановитьПараметр("Дата", Дата);
Значение = Новый СписокЗначений;
Значение.ЗагрузитьЗначения(Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку(0));
Если Значение.Количество() > 0 Тогда
Для Каждого ЭлементСписка Из Значение Цикл
ЭлементСписка.Представление = "" + ЭлементСписка.Значение + " (" + ЭлементСписка.Значение.УникальныйИдентификатор() + ")";
КонецЦикла;
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Если Ложь
Или (Истина
И РасширенноеЗначение <> Null
И ТипЗнч(РасширенноеЗначение) <> ТипЗнч(Элемент.Значение))
Или Элемент.ОграничениеТипа.ПривестиЗначение(Элемент.Значение) <> Элемент.Значение
Тогда
// Откат
СтандартнаяОбработка = Ложь;
Значение = Новый СписокЗначений;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
// Результат - Булево - Истина если значение было изменено
Функция ОткрытьФормуПроизвольногоЗначенияЛкс(РасширенноеЗначение, РедактированиеРазрешено = Истина, СтандартнаяОбработка = Истина,
ЗаголовокФормы = "", РедактироватьМодально = Истина) Экспорт
Результат = Ложь;
ТипРасширенногоЗначения = ТипЗнч(РасширенноеЗначение);
ХмлТип = XMLТипЗнч(РасширенноеЗначение);
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Или ТипРасширенногоЗначения = Тип("МоментВремени")
Или ТипРасширенногоЗначения = Тип("ТабличныйДокумент")
Или ТипРасширенногоЗначения = Тип("Массив")
Или ТипРасширенногоЗначения = Тип("Граница")
Или ТипРасширенногоЗначения = Тип("Строка")
Или ТипРасширенногоЗначения = Тип("УникальныйИдентификатор")
Или ТипРасширенногоЗначения = Тип("Тип")
Или ТипРасширенногоЗначения = Тип("ОписаниеТипов")
Или ТипРасширенногоЗначения = Тип("СписокЗначений")
Тогда
СтандартнаяОбработка = Ложь;
Если Ложь
Или ТипРасширенногоЗначения = Тип("ТаблицаЗначений")
Или ТипРасширенногоЗначения = Тип("ДеревоЗначений")
Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.ТаблицаЗначений", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("МоментВремени") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.МоментВремени", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("ТабличныйДокумент") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.ТабличныйДокумент", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Граница") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.Граница", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Массив") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.Массив", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("УникальныйИдентификатор") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.УникальныйИдентификатор", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("СписокЗначений") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.СписокЗначений", , , РасширенноеЗначение);
ИначеЕсли ТипРасширенногоЗначения = Тип("Строка") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.Текст", , , Новый УникальныйИдентификатор());
ИначеЕсли ТипРасширенногоЗначения = Тип("Тип") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.ВыборРедактируемыхТипов", , , Новый УникальныйИдентификатор());
ФормаРедактирования.МножественныйВыбор = Ложь;
ИначеЕсли ТипРасширенногоЗначения = Тип("ОписаниеТипов") Тогда
ФормаРедактирования = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.ВыборРедактируемыхТипов", , , РасширенноеЗначение);
ФормаРедактирования.МножественныйВыбор = Истина;
КонецЕсли;
Если ЗначениеЗаполнено(ЗаголовокФормы) Тогда
ФормаРедактирования.Заголовок = ЗаголовокФормы;
КонецЕсли;
Если ФормаРедактирования.Открыта() Тогда
ФормаРедактирования.Активизировать();
Возврат Результат;
КонецЕсли;
ФормаРедактирования.ТолькоПросмотр = Не РедактированиеРазрешено;
Если РедактированиеРазрешено Тогда
ФормаРедактирования.НачальноеЗначениеВыбора = ПолучитьКопиюОбъектаЛкс(РасширенноеЗначение); // Опасно
Иначе
ФормаРедактирования.НачальноеЗначениеВыбора = РасширенноеЗначение;
КонецЕсли;
Если РедактированиеРазрешено И РедактироватьМодально Тогда
РезультатВыбора = ФормаРедактирования.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
РасширенноеЗначение = РезультатВыбора;
Результат = Истина;
КонецЕсли;
Иначе
ФормаРедактирования.Открыть();
КонецЕсли;
ИначеЕсли Ложь
Или ТипРасширенногоЗначения = Тип("Число")
Или ТипРасширенногоЗначения = Тип("Строка")
Или ТипРасширенногоЗначения = Тип("Дата")
Или ТипРасширенногоЗначения = Тип("Булево")
Или ТипРасширенногоЗначения = Тип("Неопределено")
Или ТипРасширенногоЗначения = Тип("Null")
Или ТипРасширенногоЗначения = Тип("ПолеКомпоновкиДанных")
Или ТипРасширенногоЗначения = Тип("СтандартнаяДатаНачала")
Или ТипРасширенногоЗначения = Тип("СтандартныйПериод")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияНакопления")
Или ТипРасширенногоЗначения = Тип("ВидДвиженияБухгалтерии")
Или ТипРасширенногоЗначения = Тип("ВидСчета")
Или (Истина
И ХмлТип <> Неопределено
И Найти(ХмлТип.ИмяТипа, "Ref.") > 0)
Тогда
Если ЛиТипСсылкиНаОбъектБДЛкс(ТипРасширенногоЗначения) Тогда
Если Истина
И ЗначениеЗаполнено(РасширенноеЗначение)
И РасширенноеЗначение.ПолучитьОбъект() = Неопределено
Тогда
//ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле);
ОткрытьСсылкуВРедактореОбъектаБДЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Если Ложь
Или Не СтандартнаяОбработка
Или Не РедактированиеРазрешено
Тогда
Если ХмлТип <> Неопределено Тогда
Если Найти(ХмлТип.ИмяТипа, "Ref.") > 0 Тогда
Если Истина
И ЗначениеЗаполнено(РасширенноеЗначение)
И (Ложь
Или Не ЛиТипСсылкиНаОбъектБДЛкс(ТипРасширенногоЗначения)
Или РасширенноеЗначение.ПолучитьОбъект() <> Неопределено
)
Тогда
ОткрытьЗначение(РасширенноеЗначение);
КонецЕсли;
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Если СтандартнаяОбработка Тогда
ОткрытьЗначение(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
Иначе
//Если Истина
// И ТипЗначения1 <> Неопределено
// И ТипЗначения1.ПривестиЗначение(РасширенноеЗначение) <> РасширенноеЗначение
//Тогда
ИсследоватьЛкс(РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
//КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ТабличноеПоле, СтандартнаяОбработка = Ложь, РасширенноеЗначение = Null,
РедактированиеРазрешено = Истина) Экспорт
Колонка = ТабличноеПоле.ТекущаяКолонка;
ВыбраннаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Если РасширенноеЗначение = Null Тогда
Если Не ЗначениеЗаполнено(Колонка.Данные) Тогда
Возврат Ложь;
КонецЕсли;
РасширенноеЗначение = ТабличноеПоле.ТекущаяСтрока[Колонка.Данные];
КонецЕсли;
ОформлениеСтроки = ТабличноеПоле.ОформлениеСтроки(ВыбраннаяСтрока);
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
Если Колонка.ЭлементУправления <> Неопределено Тогда
ТипЗначения1 = Колонка.ЭлементУправления.ТипЗначения;
КонецЕсли;
РедактированиеРазрешено = Истина
И РедактированиеРазрешено
И Не ТабличноеПоле.ТолькоПросмотр
И Не Колонка.ТолькоПросмотр
И Колонка.ЭлементУправления <> Неопределено
И Не Колонка.ЭлементУправления.ТолькоПросмотр
И Не Ячейка.ТолькоПросмотр;
Результат = ОткрытьФормуПроизвольногоЗначенияЛкс(РасширенноеЗначение, РедактированиеРазрешено, СтандартнаяОбработка);
Если Результат Тогда
ВыбраннаяСтрока[Колонка.Данные] = РасширенноеЗначение;
КонецЕсли;
Возврат Результат;
КонецФункции // ОткрытьЗначениеЯчейки()
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаРасширенногоЗначения_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка, РасширенноеЗначение = Null) Экспорт
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = Элемент.Значение;
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Элемент.ОграничениеТипа;
НовыйТип = ирОбщий.ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТип <> Неопределено Тогда
МассивТипов = ирОбщий.БыстрыйМассивЛкс(НовыйТип);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
РасширенноеЗначение = НовоеЗначение;
Элемент.Значение = РасширенноеЗначение; //
ЗначениеИзменено = Истина;
КонецЕсли;
Иначе
Результат = ирОбщий.ОткрытьФормуПроизвольногоЗначенияЛкс(РасширенноеЗначение, Истина, СтандартнаяОбработка);
Если Результат Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
Если Не СтандартнаяОбработка Тогда
Элемент.Значение = РасширенноеЗначение;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// Результат - Булево - Истина если значение было изменено
Функция ПолеВводаКолонкиРасширенногоЗначения_НачалоВыбораЛкс(ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение = Null, ИспользоватьОграничениеТипа = Ложь, СтруктураОтбора = Неопределено) Экспорт
Колонка = ТабличноеПоле.ТекущаяКолонка;
Если РасширенноеЗначение = Null Тогда
РасширенноеЗначение = ТабличноеПоле.ТекущаяСтрока[Колонка.Данные];
КонецЕсли;
ЗначениеИзменено = Ложь;
Если РасширенноеЗначение = Неопределено Тогда
СтандартнаяОбработка = Ложь;
ОграничениеТипа = Неопределено;
Если ИспользоватьОграничениеТипа Тогда
ОграничениеТипа = Колонка.ЭлементУправления.ОграничениеТипа;
Если ОграничениеТипа.Типы().Количество() = 0 Тогда
ОграничениеТипа = Колонка.ЭлементУправления.ТипЗначения;
КонецЕсли;
КонецЕсли;
НовыйТип = ВыбратьРедактируемыйТипЛкс(ОграничениеТипа);
Если НовыйТип <> Неопределено Тогда
МассивТипов = БыстрыйМассивЛкс(НовыйТип);
НовоеОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
НовоеЗначение = НовоеОписаниеТипов.ПривестиЗначение(Неопределено);
РасширенноеЗначение = НовоеЗначение;
ТабличноеПоле.ТекущаяСтрока[Колонка.Данные] = РасширенноеЗначение;
ЗначениеИзменено = Истина;
Если ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(РасширенноеЗначение.Метаданные().ПолноеИмя(), СтруктураОтбора, Ложь, Колонка.ЭлементУправления, Истина);
КонецЕсли;
КонецЕсли;
Иначе
ЗначениеИзменено = ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ТабличноеПоле, СтандартнаяОбработка, РасширенноеЗначение, Истина);
//Если ЗначениеИзменено Тогда
Если Не СтандартнаяОбработка Тогда
ТабличноеПоле.ТекущаяСтрока[Колонка.Данные] = РасширенноеЗначение;//
КонецЕсли;
Если СтандартнаяОбработка Тогда
Если ирОбщий.ЛиСсылкаНаОбъектБДЛкс(РасширенноеЗначение, Ложь) Тогда
ирОбщий.ОткрытьФормуСпискаЛкс(РасширенноеЗначение.Метаданные().ПолноеИмя(), СтруктураОтбора, Ложь, Колонка.ЭлементУправления, Истина,, РасширенноеЗначение);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ЗначениеИзменено;
КонецФункции
// ИменаКолонокСПиктограммамиТипов - Массив, Строка
Процедура ТабличноеПолеПриВыводеСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки, КнопкаРежимаОтображения = Неопределено, Знач ИменаКолонокСПиктограммамиТипов = "") Экспорт
СостоянияКнопки = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
ЛиОтбражатьПустые = Истина
И КнопкаРежимаОтображения <> Неопределено
И (Ложь
Или КнопкаРежимаОтображения.Текст = СостоянияКнопки[1]
Или КнопкаРежимаОтображения.Текст = СостоянияКнопки[2]);
ОтображатьИдентификаторы = Истина
И КнопкаРежимаОтображения <> Неопределено
И (Ложь
Или КнопкаРежимаОтображения.Текст = СостоянияКнопки[2]);
ирПлатформа = ирКэш.Получить();
Если ТипЗнч(ИменаКолонокСПиктограммамиТипов) = Тип("Строка") Тогда
ИменаКолонокСПиктограммамиТипов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонокСПиктограммамиТипов, ",", Истина);
КонецЕсли;
Для Каждого Колонка Из Элемент.Колонки Цикл
Ячейка = ОформлениеСтроки.Ячейки[Колонка.Имя];
ЗначениеЯчейки = Ячейка.Значение;
Если Формат(ЗначениеЯчейки, Колонка.Формат) = Ячейка.Текст Тогда // Здесь могут быть обращения к БД
ПредставлениеЗначения = "";
Если ТипЗнч(ЗначениеЯчейки) <> Тип("Строка") Тогда
ПредставлениеЗначения = ПолучитьРасширенноеПредставлениеЗначенияЛкс(ЗначениеЯчейки, Колонка);
КонецЕсли;
Если ЛиОтбражатьПустые И Не ЭтоКоллекцияЛкс(ЗначениеЯчейки) Тогда
ЦветПустых = Новый Цвет(250, 255, 250); //WebЦвета.Роса;
Если ТипЗнч(ЗначениеЯчейки) = Тип("Строка") Тогда
ПредставлениеЗначения = """" + ЗначениеЯчейки + """";
Ячейка.ЦветФона = ЦветПустых;
Иначе
Попытка
ЗначениеНепустое = ЗначениеЗаполнено(ЗначениеЯчейки);
Исключение
ЗначениеНепустое = Истина;
КонецПопытки;
Если Не ЗначениеНепустое Тогда
ПредставлениеЗначения = ирПлатформа.мПолучитьПредставлениеПустогоЗначения(ЗначениеЯчейки);
Ячейка.ЦветФона = ЦветПустых;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПредставлениеЗначения <> "" Тогда
Ячейка.УстановитьТекст(ПредставлениеЗначения);
КонецЕсли;
КонецЕсли;
Если ОтображатьИдентификаторы Тогда
XMLТип = XMLТипЗнч(ЗначениеЯчейки);
Если Истина
И XMLТип <> Неопределено
И Найти(XMLТип.ИмяТипа, "Ref.") > 0
Тогда
Ячейка.УстановитьТекст(XMLСтрока(ЗначениеЯчейки) + "." + XMLТип.ИмяТипа);
КонецЕсли;
КонецЕсли;
Если ИменаКолонокСПиктограммамиТипов.Найти(Колонка.Имя) <> Неопределено Тогда
Если ТипЗнч(ЗначениеЯчейки) <> Тип("ПолеКомпоновкиДанных") Тогда
ТипЗначения = ТипЗнч(ЗначениеЯчейки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если ОформлениеСтроки.Ячейки.Найти(ИмяКолонкиНомерСтроки) <> Неопределено Тогда
Если ТипЗнч(ДанныеСтроки) = Тип("СтрокаДереваЗначений") Тогда
ИндексСтроки = ПолучитьРодителяСтрокиДереваЛкс(ДанныеСтроки, ДанныеСтроки.Владелец()).Строки.Индекс(ДанныеСтроки);
Иначе
ИндексСтроки = ДанныеСтроки.Владелец().Индекс(ДанныеСтроки);
КонецЕсли;
ОформлениеСтроки.Ячейки[ИмяКолонкиНомерСтроки].УстановитьТекст(XMLСтрока(ИндексСтроки + 1));
ОформлениеСтроки.Ячейки[ИмяКолонкиНомерСтроки].ЦветТекста = Новый Цвет(128, 128, 128);
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПолеВставитьКолонкуНомерСтрокиЛкс(Знач ТабличноеПоле) Экспорт
ИмяКолонкиНомерСтроки = ирКэш.ИмяКолонкиНомерСтрокиЛкс();
Если ТабличноеПоле.Колонки.Найти(ИмяКолонкиНомерСтроки) = Неопределено Тогда
КолонкаТП = ТабличноеПоле.Колонки.Вставить(0);
КолонкаТП.Имя = ИмяКолонкиНомерСтроки;
КолонкаТП.ТекстШапки = "№";
КолонкаТП.ПодсказкаВШапке = "Номер элемента в пределах родителя (служебная)";
КолонкаТП.ТолькоПросмотр = Истина;
КолонкаТП.Ширина = 4;
КонецЕсли;
КонецПроцедуры // ОбновитьТаблицуКолонок()
Процедура РедактироватьСписокПравогоЗначенияОтбораКомпоновкиЛкс(ТабличноеПолеОтбора) Экспорт
ТекущаяСтрока = ТабличноеПолеОтбора.ТекущаяСтрока;
Если Ложь
Или ТекущаяСтрока = Неопределено
Или ТипЗнч(ТекущаяСтрока) = Тип("ОтборКомпоновкиДанных")
Или ТипЗнч(ТекущаяСтрока) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
Тогда
Возврат;
КонецЕсли;
СписокЗначений = ТекущаяСтрока.ПравоеЗначение;
Если ТипЗнч(СписокЗначений) <> Тип("СписокЗначений") Тогда
Возврат;
КонецЕсли;
Результат = ирОбщий.ОткрытьФормуПроизвольногоЗначенияЛкс(СписокЗначений, Истина);
Если Результат Тогда
ТекущаяСтрока.ПравоеЗначение = СписокЗначений;
ТекущаяСтрока.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Процедура КнопкаОтображатьПустыеИИдентификаторыНажатиеЛкс(Кнопка) Экспорт
МассивСостояний = ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс();
Если Кнопка.Текст = МассивСостояний[2] Тогда
Кнопка.Пометка = Ложь;
Кнопка.Текст = МассивСостояний[0];
Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирПусто");
ИначеЕсли Кнопка.Текст = МассивСостояний[1] Тогда
Кнопка.Пометка = Истина;
Кнопка.Текст = МассивСостояний[2];
Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирИдентификатор");
Иначе//Если Кнопка.Текст = МассивСостояний[0] Тогда
Кнопка.Пометка = Истина;
Кнопка.Текст = МассивСостояний[1];
Кнопка.Картинка = ПолучитьОбщуюКартинкуЛкс("ирПусто");
КонецЕсли;
КонецПроцедуры
Функция ПолучитьСостоянияКнопкиОтображатьПустыеИИдентификаторыЛкс()
МассивСостояний = Новый Массив;
МассивСостояний.Добавить("Не отображать");
МассивСостояний.Добавить("Отображать пустые");
МассивСостояний.Добавить("Отображать пустые и идентификаторы");
Возврат МассивСостояний;
КонецФункции
Процедура ПрименитьИзмененияИЗакрытьФормуЛкс(ЭтаФорма, ЗначениеВыбора = Неопределено) Экспорт
ЭтаФорма.Модифицированность = Ложь;
Если Ложь
Или ЭтаФорма.ВладелецФормы <> Неопределено
Или Не ЭтаФорма.Открыта()
Тогда
ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
КонецЕсли;
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть(ЗначениеВыбора);
КонецЕсли;
//Если ЭтаФорма.Открыта() Тогда
// ЭтаФорма.Закрыть(ЗначениеВыбора);
//Иначе//Если ЭтаФорма.МодальныйРежим Тогда
// ЭтаФорма.ОповеститьОВыборе(ЗначениеВыбора);
//КонецЕсли;
КонецПроцедуры // ПрименитьИзмененияИЗакрытьФорму()
Функция НайтиВозможныеСтрокиОписанияСловаВСинтаксПомощникеЛкс(Знач Слово, ЯзыкПрограммы = 0, ПоискСУчетомТипаСлова = Истина) Экспорт
ирКэш.Получить().ИнициализацияОписанияМетодовИСвойств();
МассивВозможныхТиповСлова = Новый Массив;
МассивВозможныхТиповСлова.Добавить("Конструктор");
Слово = НРег(Слово);
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) = "("
Тогда
Если Прав(Слово, 1) = "(" Тогда
Слово = ПолучитьСтрокуБезКонцаЛкс(Слово, 1);
КонецЕсли;
МассивВозможныхТиповСлова.Добавить("Метод");
КонецЕсли;
Если Ложь
Или Не ПоискСУчетомТипаСлова
Или Прав(Слово, 1) <> "("
Тогда
МассивВозможныхТиповСлова.Добавить("Свойство");
МассивВозможныхТиповСлова.Добавить("Конструкция");
МассивВозможныхТиповСлова.Добавить("Событие");
МассивВозможныхТиповСлова.Добавить("Таблица");
КонецЕсли;
ТаблицаСтруктурВозможныхТиповКонтекста = ирКэш.Получить().ПолучитьНовуюТаблицуСтруктурТипа();
Для Каждого ВозможныйТипСлова Из МассивВозможныхТиповСлова Цикл
Если ВозможныйТипСлова = "Конструктор" Тогда
КлючПоиска = Новый Структура("ТипКонтекста, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
Иначе
КлючПоиска = Новый Структура("НСлово, ТипСлова, ЯзыкПрограммы, ТипЯзыка", Слово, ВозможныйТипСлова, ЯзыкПрограммы, "");
КонецЕсли;
НайденныеСтроки = ирКэш.Получить().ТаблицаКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
НайденныеСтроки = ирКэш.Получить().ТаблицаШаблоновКонтекстов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
КонецЦикла;
КлючПоиска = Новый Структура("НСлово, ЯзыкПрограммы", Слово, ЯзыкПрограммы);
НайденныеСтроки = ирКэш.Получить().ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
ЗаполнитьЗначенияСвойств(ТаблицаСтруктурВозможныхТиповКонтекста.Добавить(), Новый Структура("СтрокаОписания", НайденнаяСтрока));
КонецЦикла;
Возврат ТаблицаСтруктурВозможныхТиповКонтекста;
КонецФункции // НайтиВозможныеСтрокиОписанияСлова()
// Открывает форму синтакс-помощника и загружает в нее нужную страницу, подсвечивая заданную строку.
//
// Параметры:
// ВнутреннийПутьКОписанию Строка внутренний путь к странице синтакс-помощника;
// СтрокаДляПодсветки Строка которую нужно подсветить в тексте страницы.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьСтраницуСинтаксПомощникаЛкс(ВнутреннийПутьКОписанию, СтрокаДляПодсветки = "", ВладелецФормы = Неопределено, КлючУникальности = Неопределено) Экспорт
Если ВнутреннийПутьКОписанию = "" Тогда
Возврат Неопределено;
КонецЕсли;
ФормаСправка = ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма", , , КлючУникальности);
ФормаСправка.ВладелецФормы = ВладелецФормы;
ФормаСправка.ОткрытьАдрес(ВнутреннийПутьКОписанию, СтрокаДляПодсветки);
ФормаСправка.ВладелецФормы = Неопределено;
Возврат ФормаСправка;
КонецФункции // ОткрытьСтраницуСинтаксПомощникаЛкс()
// Обходит строки табличного поля и имитирует редактирование и выбор пользователем заданного значения.
//
// Параметры:
// ТабличноеПоле - ТабличноеПоле;
// ЗначениеОбработки - Произвольные - значение, которое будем записывать в ячейки;
// *ФормаИнициатор - Форма, *Неопределено - форма, от имени которой будет записывать;
// *ТипИсточника Строка, *Неопределено "ТаблицаЗначений", "ТабличнаяЧасть";
// *Колонка КолонкаТабличногоПоля, *Неопределено колонка в которой обходим ячейки, по умолчанию текущая;
// *ТолькоВыделенныеСтроки - Булево, *Истина - обходить только выделенные строки.
//
Процедура УстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗЛкс(ТабличноеПоле, ЗначениеОбработки,
ФормаИнициатор = Неопределено, Знач ТипИсточника = Неопределено, Знач Колонка = Неопределено,
Знач ТолькоВыделенныеСтроки = Истина, Знач ИнтерактивноеУстановка = Истина) Экспорт
Если Колонка = Неопределено Тогда
Колонка = ТабличноеПоле.ТекущаяКолонка;
Иначе
ТабличноеПоле.ТекущаяКолонка = Колонка;
КонецЕсли;
ЗначениеТабличногоПоля = ТабличноеПоле.Значение;
Если ТипИсточника = "" Тогда
ТипЗначенияТабличногоПоля = ТипЗнч(ЗначениеТабличногоПоля);
Если ТипЗначенияТабличногоПоля = Тип("ТаблицаЗначений") Тогда
ТипИсточника = "ТаблицаЗначений";
ИначеЕсли ТипЗначенияТабличногоПоля = Тип("ДеревоЗначений") Тогда
ТипИсточника = "ДеревоЗначений";
Иначе
СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(ТипЗначенияТабличногоПоля);
Если Найти(СтруктураТипа.ИмяОбщегоТипа, "<Имя табличной части>") > 0 Тогда
ТипИсточника = "ТабличнаяЧасть";
ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "НаборЗаписей.") > 0 Тогда
ТипИсточника = "НаборЗаписей";
КонецЕсли;
КонецЕсли;
КонецЕсли;
ЕстьОтборСтрок = Ложь
Или ТипИсточника = "ТабличнаяЧасть"
Или ТипИсточника = "НаборЗаписей";
Если ТолькоВыделенныеСтроки Тогда
Если Истина
И ТабличноеПоле.ВыделенныеСтроки.Количество() = 1
И ТипИсточника <> "ДеревоЗначений"
Тогда
ТекстОтбора = "";
Если ЕстьОтборСтрок Тогда
ТекстОтбора = " удовлетворяющие отбору";
КонецЕсли;
Ответ = Вопрос("Выделена только одна строка. Хотите обработать все" + ТекстОтбора + " строки?",
РежимДиалогаВопрос.ДаНет);
Если Ответ = КодВозвратаДиалога.Да Тогда
ТолькоВыделенныеСтроки = Ложь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КлючиСтрокДляОбработки = Новый Массив;
Если ТолькоВыделенныеСтроки Тогда
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючиСтрокДляОбработки.Добавить(ВыделеннаяСтрока);
КонецЦикла;
Иначе
Если ЕстьОтборСтрок Тогда
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЗначениеТабличногоПоля);
Построитель.ВыбранныеПоля.Очистить();
Построитель.ВыбранныеПоля.Добавить("НомерСтроки");
СкопироватьОтборЛкс(Построитель.Отбор, ТабличноеПоле.ОтборСтрок, Истина);
ТаблицаРезультата = Построитель.Результат.Выгрузить();
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаРезультата.НомерСтроки - 1);
КонецЦикла;
ИначеЕсли ТипИсточника = "ТаблицаЗначений" Тогда
Для Каждого СтрокаТаблицы Из ТабличноеПоле.Значение Цикл
КлючиСтрокДляОбработки.Добавить(СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
КонецЕсли;
Индикатор = ПолучитьИндикаторПроцессаЛкс(КлючиСтрокДляОбработки.Количество(), "Групповая установка значения");
// Нужно встать на редактируемую колонку, чтобы сработал режим редактирования
Для Каждого КлючСтроки Из КлючиСтрокДляОбработки Цикл
ОбработатьИндикаторЛкс(Индикатор);
Если ТипЗнч(КлючСтроки) = Тип("Число") Тогда
ТекущаяСтрока = ТабличноеПоле.Значение[КлючСтроки];
Иначе
ТекущаяСтрока = КлючСтроки;
КонецЕсли;
Если ТипЗнч(ЗначениеОбработки) = Тип("Структура") Тогда
ЗаполнитьЗначенияСвойств(ЗначениеОбработки.Параметры, ТекущаяСтрока);
НовоеЗначение = ВычислитьВыражение(ЗначениеОбработки.Формула, ЗначениеОбработки.Параметры);
Иначе
НовоеЗначение = ЗначениеОбработки;
КонецЕсли;
Если ИнтерактивноеУстановка Тогда
ТабличноеПоле.ТекущаяСтрока = ТекущаяСтрока;
//ТабличноеПоле.ИзменитьСтроку();
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(ТабличноеПоле, Колонка, НовоеЗначение, ФормаИнициатор);
ТабличноеПоле.ЗакончитьРедактированиеСтроки(Ложь);
Иначе
ТекущаяСтрока[Колонка.Имя] = НовоеЗначение;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ИнтерактивноУстановитьЗначениеВКолонкеТабличногоПоляТЧИлиТЗ()
Процедура ОформитьФонТекущейСтрокиЛкс(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
Если Элемент.ТекущаяСтрока = ДанныеСтроки Тогда
ОформлениеСтроки.ЦветФона = WebЦвета.СветлоНебесноГолубой;
КонецЕсли;
КонецПроцедуры
Функция ПроверитьЗапуститьОтладчик(Знач ВремяОжиданияЗапуска = 5) Экспорт
ИдентификаторПроцессаОтладчика = Неопределено;
Платформа = ирКэш.Получить();
ПортОтладки = Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
//Если Не УФ(сПроверитьДоступностьКонфигуратора) Тогда
// Сообщить("Конфигуратор уже открыт, но отладка не подключена. Выполните подключение отладчика вручную");
// Перейти ~Конец;
//КонецЕсли;
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164
Если Платформа.ВерсияПлатформы = 802015 Тогда
Предупреждение("Из-за ошибки платформы 8.2.15 запуск и подключение отладчика необходимо выполнять вручную", 20);
Возврат Неопределено;
КонецЕсли;
Если ПортОтладки = Неопределено Тогда
Предупреждение("Включите разрешение отладки в главном меню ""Сервис/Параметры/Системные"" и повторите операцию снова");
Возврат Неопределено;
КонецЕсли;
ПараметрыЗапуска = "CONFIG /DEBUG /DEBUGTARGET""tcp://127.0.0.1:" + ПортОтладки + """";
ЗапуститьСистему(ПараметрыЗапуска);
Платформа.Sleep(ВремяОжиданияЗапуска);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
ИдентификаторПроцессаОтладчика = 0;
КонецЕсли;
Пока Истина Цикл
Платформа.ПолучитьПортДляПодключенияОтладчика(ИдентификаторПроцессаОтладчика);
Если ИдентификаторПроцессаОтладчика = Неопределено Тогда
Ответ = Вопрос("Отладчик еще не подключился. Повторить снова?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
Прервать;
КонецЦикла;
Иначе
Платформа.АктивизироватьОкноПроцесса1С8(Число(ИдентификаторПроцессаОтладчика));
КонецЕсли;
Если ИдентификаторПроцессаОтладчика <> Неопределено Тогда
Результат = Число(ИдентификаторПроцессаОтладчика);
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ОткрытьСсылкуЯчейкиВРедактореОбъектаБДЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ТабличноеПоле.ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Если ТабличноеПоле.ТекущаяКолонка = Неопределено Тогда
Возврат;
КонецЕсли;
ИмяКолонки = ТабличноеПоле.ТекущаяКолонка.Данные;
КонецЕсли;
ЗначениеЯчейки = ТабличноеПоле.ТекущаяСтрока[ИмяКолонки];
XMLТип = XMLТипЗнч(ЗначениеЯчейки);
Если XMLТип = Неопределено Тогда
Возврат;
КонецЕсли;
Если Ложь
Или Найти(XMLТип.ИмяТипа, "Ref.") = 0
Или Найти(XMLТип.ИмяТипа, "BusinessProcessRoutePointRef.") > 0
Тогда
Возврат;
КонецЕсли;
Если Найти(XMLТип.ИмяТипа, "EnumRef.") > 0 Тогда
ОткрытьФормуСпискаЛкс(Метаданные.НайтиПоТипу(ТипЗнч(ЗначениеЯчейки)).ПолноеИмя(),, Истина,,,, ЗначениеЯчейки);
Иначе
ОткрытьСсылкуВРедактореОбъектаБДЛкс(ЗначениеЯчейки);
КонецЕсли;
КонецПроцедуры
Функция ОткрытьСсылкуВРедактореОбъектаБДЛкс(КлючОбъекта, ИскомоеЗначение = Неопределено) Экспорт
РедакторОбъектаБД = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД");
#Если _ Тогда
РедакторОбъектаБД = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
Форма = РедакторОбъектаБД.РедактироватьОбъектСсылки(КлючОбъекта, ИскомоеЗначение);
Возврат Форма;
КонецФункции
Процедура ОткрытьОбъектВРедактореОбъектаБДЛкс(ОбъектБД, ИскомоеЗначение = Неопределено) Экспорт
РедакторОбъектаБД = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирРедакторОбъектаБД");
#Если _ Тогда
РедакторОбъектаБД = Обработки.ирРедакторОбъектаБД.Создать();
#КонецЕсли
РедакторОбъектаБД.РедактироватьМодифицированныйОбъект(ОбъектБД, ИскомоеЗначение);
КонецПроцедуры
// ВариантПросмотра - Строка - "Компактный", "ЯзыкЗапросов", "ВстроенныйЯзык", ...
Функция ПолучитьФормуТекстаЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
Если КлючУникальности = Неопределено Тогда
КлючУникальности = Новый УникальныйИдентификатор();
КонецЕсли;
ФормаПросмотра = ирКэш.Получить().ПолучитьФорму("Текст", ВладелецФормы, КлючУникальности);
ФормаПросмотра.НачальноеЗначениеВыбора = Текст;
ФормаПросмотра.РекомендуемыйВариант = ВариантПросмотра;
ФормаПросмотра.ТолькоПросмотр = ТолькоПросмотр;
Если Не ЗначениеЗаполнено(Заголовок) Тогда
//Заголовок = ФормаПросмотра.Заголовок;
Заголовок = ""; // Чтобы при повторном открытии не оставался старый текст
КонецЕсли;
ФормаПросмотра.Заголовок = Заголовок;
Возврат ФормаПросмотра;
КонецФункции
Функция ОткрытьТекстЛкс(Текст, Знач Заголовок = "", ВариантПросмотра = "Компактный", ТолькоПросмотр = Ложь, КлючУникальности = Неопределено, ВладелецФормы = Неопределено) Экспорт
ФормаПросмотра = ПолучитьФормуТекстаЛкс(Текст, Заголовок, ВариантПросмотра, ТолькоПросмотр, КлючУникальности, ВладелецФормы);
ФормаПросмотра.Открыть();
Возврат ФормаПросмотра;
КонецФункции
Процедура ПолеВводаТекста_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
Если ТипЗнч(Элемент.Значение) = Тип("Строка") Тогда
СтандартнаяОбработка = Ложь;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("Текст", Элемент, Новый УникальныйИдентификатор);
ФормаРедактора.РежимВыбора = Истина;
ФормаРедактора.НачальноеЗначениеВыбора = Элемент.Значение;
ФормаРедактора.Открыть();
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПутьКДаннымТекущейКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле) Экспорт
Если Истина
И ТабличноеПоле.ТекущаяКолонка <> Неопределено
И ТабличноеПоле.ТекущиеДанные <> Неопределено
Тогда
ДанныеКолонки = ТабличноеПоле.ТекущаяКолонка.Данные;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
ДанныеКолонки = ТабличноеПоле.ТекущаяКолонка.ДанныеФлажка;
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Если Ложь
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ТаблицаЗначений")
Или ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений")
Тогда
ДанныеКолонки = ТабличноеПоле.ТекущаяКолонка.ДанныеКартинки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ДанныеКолонки;
КонецФункции
Процедура ТабличноеПоле_ОтборБезЗначенияВТекущейКолонке_КнопкаЛкс(Знач ТабличноеПоле) Экспорт
ДанныеКолонки = ПолучитьПутьКДаннымТекущейКолонкиТабличногоПоляЛкс(ТабличноеПоле);
Если Не ЗначениеЗаполнено(ДанныеКолонки) Тогда
Возврат;
КонецЕсли;
Попытка
Отбор = ТабличноеПоле.Значение.Отбор;
Исключение
Отбор = ТабличноеПоле.ОтборСтрок;
КонецПопытки;
//:Отбор = Новый ("Отбор");
ЭлементОтбора = Отбор[ДанныеКолонки];
ЗначениеЯчейки = ТабличноеПоле.ТекущиеДанные[ДанныеКолонки];
Если ЭлементОтбора.Использование Тогда
Если ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно Тогда
Если Ложь
Или ТипЗнч(ЗначениеЯчейки) <> Тип("Булево")
Или ЭлементОтбора.ТипЗначения.Типы().Количество() > 1
Тогда
СписокЗначений = Новый СписокЗначений;
СписокЗначений.Добавить(ЭлементОтбора.Значение);
СписокЗначений.Добавить(ЗначениеЯчейки);
ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке;
ЭлементОтбора.Значение = СписокЗначений;
КонецЕсли;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.НеВСписке Тогда
СписокЗначений = ЭлементОтбора.Значение;
СписокЗначений.Добавить(ЗначениеЯчейки);
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
ИначеЕсли ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке Тогда
СписокЗначений = ЭлементОтбора.Значение;
СписокЗначений.Удалить(СписокЗначений.НайтиПоЗначению(ЗначениеЯчейки));
// Для обновления отбора
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.Использование = Истина;
Иначе
ЭлементОтбора.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Если Не ЭлементОтбора.Использование Тогда
ЭлементОтбора.Использование = Истина;
Если Истина
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Строка"))
И ЭлементОтбора.ТипЗначения.КвалификаторыСтроки.Длина = 0
Тогда
Если Не ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
// Особенность платформы
ЭлементОтбора.ВидСравнения = ВидСравнения.Содержит;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравнения.НеСодержит;
КонецЕсли;
Иначе
ЭлементОтбора.ВидСравнения = ВидСравнения.НеРавно;
КонецЕсли;
ЭлементОтбора.Значение = ЗначениеЯчейки;
КонецЕсли;
КонецПроцедуры
Функция ЗагрузитьЗначениеИзФайлаЛкс(Расширение = "", ОписаниеФормата = "", Сжатие = Истина) Экспорт
ПолноеИмяФайла = ВыбратьФайлЛкс(, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
ЗипЧтение = Новый ЧтениеZipФайла(ПолноеИмяФайла);
ЗипЧтение.ИзвлечьВсе(ВременныйКаталог);
ПолноеИмяФайла = ВременныйКаталог + "\" + ЗипЧтение.Элементы[0].Имя;
КонецЕсли;
ЧтениеХМЛ = Новый ЧтениеXML;
ЧтениеХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//Результат = ЗначениеИзФайла(ВыборФайла.ПолноеИмяФайла);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеХМЛ);
Исключение
Сообщить(ОписаниеОшибки());
Результат = Неопределено;
КонецПопытки;
ЧтениеХМЛ.Закрыть();
Если Сжатие Тогда
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СохранитьЗначениеВФайлЛкс(Значение, Расширение = "", ОписаниеФормата = "", Сжатие = Истина, УровеньСжатия = Неопределено) Экспорт
ПолноеИмяФайла = ВыбратьФайлЛкс(Ложь, Расширение, ОписаниеФормата);
Если ПолноеИмяФайла = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.ОткрытьФайл(ПолноеИмяФайла);
Попытка
//ЗначениеВФайл(ВыборФайла.ПолноеИмяФайла, Значение);
СериализаторXDTO.ЗаписатьXML(ЗаписьХМЛ, Значение);
Результат = Истина;
Исключение
Сообщить(ОписаниеОшибки());
Результат = Ложь;
КонецПопытки;
ЗаписьХМЛ.Закрыть();
Если Сжатие Тогда
ВременныйКаталог = ПолучитьИмяВременногоФайла();
СоздатьКаталог(ВременныйКаталог);
Файл = Новый Файл(ПолноеИмяФайла);
ИмяВременногоФайла = ВременныйКаталог + "\" + Файл.Имя;
ПереместитьФайл(Файл.ПолноеИмя, ИмяВременногоФайла);
ЗаписьЗип = Новый ЗаписьZipФайла(ПолноеИмяФайла,,,, УровеньСжатия);
ЗаписьЗип.Добавить(ИмяВременногоФайла);
ЗаписьЗип.Записать();
УдалитьФайлы(ВременныйКаталог, "*");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ВыбратьРедактируемыйТипЛкс(ОграничениеТипа = Неопределено, ТолькоПросмотр = Ложь, НачальноеЗначениеВыбора = Неопределено) Экспорт
Если ОграничениеТипа = Неопределено Тогда
ОграничениеТипа = Новый ОписаниеТипов;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов");
ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = НачальноеЗначениеВыбора;
ФормаРедактора.МножественныйВыбор = Ложь;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции // РедактироватьДопустимыеТипы()
Функция РедактироватьОписаниеРедактируемыхТиповЛкс(ОграничениеТипаИлиПолеВвода, ТолькоПросмотр = Ложь) Экспорт
Если ТипЗнч(ОграничениеТипаИлиПолеВвода) = Тип("ОписаниеТипов") Тогда
ВладелецФормы = Неопределено;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода;
Иначе
ВладелецФормы = ОграничениеТипаИлиПолеВвода;
ОграничениеТипа = ОграничениеТипаИлиПолеВвода.Значение;
КонецЕсли;
ФормаРедактора = ирКэш.Получить().ПолучитьФорму("ВыборРедактируемыхТипов", ВладелецФормы);
//ФормаРедактора.ОграничениеТипа = ОграничениеТипа;
ФормаРедактора.НачальноеЗначениеВыбора = ОграничениеТипа;
ФормаРедактора.МножественныйВыбор = Истина;
ФормаРедактора.ТолькоПросмотр = ТолькоПросмотр;
РезультатВыбора = ФормаРедактора.ОткрытьМодально();
Возврат РезультатВыбора;
КонецФункции // РедактироватьДопустимыеТипы()
// ПолноеИмяНачальногоТипаВыбора - Строка - полное имя метаданного
Функция ОткрытьПодборСВыборомТипаЛкс(ВладелецФормы, ОписаниеТипов = Неопределено, Знач НачальноеЗначениеВыбора = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено) Экспорт
Если ТипЗнч(ОписаниеТипов) = Тип("Строка") Тогда
ДоступныеОбъекты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ОписаниеТипов, ",", Истина);
ИначеЕсли ОписаниеТипов <> Неопределено Тогда
ДоступныеОбъекты = Новый Массив();
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМетаданных <> Неопределено Тогда
ДоступныеОбъекты.Добавить(ОбъектМетаданных.ПолноеИмя());
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(НачальноеЗначениеВыбора));
Если ОбъектМД <> Неопределено Тогда
ПолноеИмяНачальногоТипаВыбора = ОбъектМД.ПолноеИмя();
КонецЕсли;
КонецЕсли;
Если Ложь
Или ДоступныеОбъекты = Неопределено
Или ДоступныеОбъекты.Количество() = 0
Или ДоступныеОбъекты.Количество() > 1
Тогда
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", , ВладелецФормы);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ДоступныеОбъекты", ДоступныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", ПолноеИмяНачальногоТипаВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Результат = Форма.ОткрытьМодально();
Если Результат = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ПолноеИмяМД = Результат.ПолноеИмяОбъекта;
Иначе
ПолноеИмяМД = ДоступныеОбъекты[0];
КонецЕсли;
Если ПолноеИмяНачальногоТипаВыбора <> ПолноеИмяМД Тогда
НачальноеЗначениеВыбора = Неопределено;
КонецЕсли;
ТекущаяСтрока = Неопределено;
Отбор = Неопределено;
Если НачальноеЗначениеВыбора <> Неопределено Тогда
ИмяXMLТипа = СериализаторXDTO.XMLТипЗнч(НачальноеЗначениеВыбора).ИмяТипа;
Если Ложь
Или Найти(ИмяXMLТипа, "Ref.") > 0
Или Найти(ИмяXMLТипа, "RecordKey.") > 0
Тогда
ТекущаяСтрока = НачальноеЗначениеВыбора;
Иначе
Отбор = НачальноеЗначениеВыбора.Отбор;
КонецЕсли;
КонецЕсли;
ФормаВыбора = ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор, ИспользоватьДинамическийСписокИР, ВладелецФормы, Истина, Истина, ТекущаяСтрока);
Возврат ФормаВыбора;
КонецФункции
Функция ПолучитьФормуВыбораОбъектаМетаданныхЛкс(ВладелецФормы, КлючУникальности, НачальноеЗначениеВыбора, МножественныйВыбор = Ложь, ОтображатьСсылочныеОбъекты = Ложь,
ОтображатьВыборочныеТаблицы = Ложь, ОтображатьРегистры = Ложь, ОтображатьПоследовательности = Ложь, ОтображатьКонстанты = Ложь, ОтображатьТабличныеЧасти = Ложь,
ОтображатьТаблицыИзменений = Ложь, ОтображатьВнешниеИсточникиДанных = Ложь, ЗапретитьВыбиратьСсылочныеОбъекты = Ложь) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", ВладелецФормы, КлючУникальности);
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
лСтруктураПараметров.Вставить("ОтображатьКонстанты", ОтображатьКонстанты);
лСтруктураПараметров.Вставить("ОтображатьВыборочныеТаблицы", ОтображатьВыборочныеТаблицы);
лСтруктураПараметров.Вставить("ОтображатьТаблицыИзменений", ОтображатьТаблицыИзменений);
лСтруктураПараметров.Вставить("ОтображатьТабличныеЧасти", ОтображатьТабличныеЧасти);
лСтруктураПараметров.Вставить("ОтображатьРегистры", ОтображатьРегистры);
лСтруктураПараметров.Вставить("ОтображатьПоследовательности", ОтображатьПоследовательности);
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", ОтображатьСсылочныеОбъекты);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", ОтображатьВнешниеИсточникиДанных);
лСтруктураПараметров.Вставить("МножественныйВыбор", МножественныйВыбор);
лСтруктураПараметров.Вставить("ЗапретитьВыбиратьСсылочныеОбъекты", ЗапретитьВыбиратьСсылочныеОбъекты);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
Возврат Форма;
КонецФункции
Функция ПолучитьФормуВыбораТаблицыСтруктурыБДЛкс(ЛиИменаБД, ИмяТаблицыХранения = "") Экспорт
Форма = ирОбщий.ПолучитьФормуЛкс("Обработка.ирСтруктураХраненияБД.Форма",,, Истина);
Форма.РежимВыбора = Истина;
Форма.ПараметрИмяТаблицыХранения = ИмяТаблицыХранения;
Форма.ПараметрПоказыватьSDBL = Не ЛиИменаБД;
Форма.ПараметрПоказыватьСУБД = ЛиИменаБД;
Возврат Форма
КонецФункции
// ИсторияФайлов - СписокЗначений
// Кнопки - КнопкиКоманднойПанели
Процедура ОбновитьПодменюИсторииФайловЛкс(ИсторияФайлов, Кнопки, ИмяДействия = "ОткрытьФайлИзИстории") Экспорт
Кнопки.Очистить();
ДлинаПредставления = 100;
ДействиеКнопки = Новый Действие(ИмяДействия);
Для Каждого СтрокаФайла Из ИсторияФайлов Цикл
Файл = Новый Файл(СтрокаФайла.Значение);
ДлинаПути = ДлинаПредставления - СтрДлина(Файл.Имя);
Представление = Лев(Файл.Имя, ДлинаПредставления);
Если ДлинаПути > 0 Тогда
Если ДлинаПути < СтрДлина(Файл.Путь) + 3 Тогда
Представление = Лев(Файл.Путь, ДлинаПути) + "...\" + Представление;
Иначе
Представление = Файл.Путь + Представление;
КонецЕсли;
КонецЕсли;
КнопкаФайла = Кнопки.Добавить("_" + Формат(ИсторияФайлов.Индекс(СтрокаФайла), "ЧГ=;ЧН="), ТипКнопкиКоманднойПанели.Действие, Представление, ДействиеКнопки);
КонецЦикла;
КонецПроцедуры
Процедура ДобавитьВИсториюЭлементЛкс(СписокИстории, ЗначениеЭлемента, РазмерИстории = 20) Экспорт
ЭлементИстории = СписокИстории.НайтиПоЗначению(ЗначениеЭлемента);
Если ЭлементИстории <> Неопределено Тогда
СписокИстории.Удалить(ЭлементИстории);
КонецЕсли;
СписокИстории.Вставить(0, ЗначениеЭлемента);
Пока СписокИстории.Количество() > РазмерИстории Цикл
СписокИстории.Удалить(РазмерИстории);
КонецЦикла;
КонецПроцедуры
Процедура ПоместитьТекстВБуферОбменаОСЛкс(Текст) Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов
//Документ = Новый COMОбъект("HTMLFILE");
Окно = Документ.parentWindow;
Окно.ClipboardData.SetData("Text", Текст);
Конецпроцедуры
Функция ПолучитьТекстИзБуфераОбменаОСЛкс() Экспорт
// http://partners.v8.1c.ru/forum/thread.jsp?id=1075241#1075241
Документ = ирКэш.Получить().СлужебноеПолеHtmlДокумента.Документ; // Так падает после нескольких вызовов
//Документ = Новый COMОбъект("HTMLFILE");
Окно = Документ.parentWindow;
Результат = Окно.ClipboardData.GetData("Text");
Возврат Результат;
КонецФункции
// Параметры:
// Отбор - Структура, Отбор, *Неопределено
Функция ОткрытьФормуСпискаЛкс(ПолноеИмяМД, Отбор = Неопределено, ИспользоватьДинамическийСписокИР = Неопределено, ВладелецФормы = Неопределено, РежимВыбора = Ложь,
МножественныйВыбор = Ложь, ТекущаяСтрока = Неопределено, Модально = Ложь) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяМД);
//МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяМД);
Если Ложь
Или ирОбщий.ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы)
Или ТипТаблицы = "Изменения"
Или ТипТаблицы = "Перерасчет"
//Или МассивФрагментов.Количество() > 2
Тогда
Сообщить("Для таблицы " + ПолноеИмяМД + " форма списка не предусмотрена");
Возврат Неопределено;
КонецЕсли;
Если Истина
И РежимВыбора = Истина
И ирОбщий.ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
Тогда
ИспользоватьДинамическийСписокИР = Истина; // Потому что у форм списков регистров режим выбора можно включить только через основной элемент управления
КонецЕсли;
Если ИспользоватьДинамическийСписокИР = Неопределено Тогда
Ответ = Вопрос("Хотите использовать Динамический список (ИР)?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
ИспользоватьДинамическийСписокИР = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ИспользоватьДинамическийСписокИР Тогда
ФормаСписка = ирОбщий.ПолучитьФормуЛкс("Обработка.ирДинамическийСписок.Форма",, ВладелецФормы, Новый УникальныйИдентификатор);
ФормаСписка.УстановитьОбъектМетаданных(ПолноеИмяМД);
ОтборДинамическогоСписка = ФормаСписка.ЭлементыФормы.ДинамическийСписок.Значение.Отбор;
Иначе
Если ТипЗнч(Отбор) = Тип("Отбор") Тогда
СтруктураОтбора = Новый Структура;
Для Каждого ЭлементОтбора Из Отбор Цикл
Если Истина
И ЭлементОтбора.Использование
И ЭлементОтбора.ВидСравнения = ВидСравнения.Равно
Тогда
СтруктураОтбора.Вставить(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Иначе
СтруктураОтбора = Отбор;
КонецЕсли;
ПараметрыФормы = Новый Структура("РежимВыбора, МножественныйВыбор, ЗакрыватьПриВыборе, ТекущаяСтрока, Отбор",
РежимВыбора, МножественныйВыбор, Не МножественныйВыбор, ТекущаяСтрока, СтруктураОтбора);
Если РежимВыбора Тогда
Попытка
ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаВыбора", ПараметрыФормы, ВладелецФормы);
Исключение
// Например у регистров нет форм выбора
КонецПопытки;
КонецЕсли;
Если ФормаСписка = Неопределено Тогда
ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", ПараметрыФормы, ВладелецФормы);
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
ОтборДинамическогоСписка = ФормаСписка.Отбор;
КонецЕсли;
КонецЕсли;
Если ТипЗнч(ФормаСписка) = Тип("Форма") Тогда
ФормаСписка.РежимВыбора = РежимВыбора;
ФормаСписка.МножественныйВыбор = МножественныйВыбор;
ФормаСписка.ЗакрыватьПриВыборе = Не МножественныйВыбор;
ФормаСписка.НачальноеЗначениеВыбора = ТекущаяСтрока;
КонецЕсли;
Если Истина
И ОтборДинамическогоСписка <> Неопределено
И Отбор <> Неопределено
Тогда
Если ТипЗнч(Отбор) = Тип("Структура") Тогда
Для Каждого КлючИЗначение Из Отбор Цикл
ЭлементОтбора = ОтборДинамическогоСписка[КлючИЗначение.Ключ];
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.Значение = КлючИЗначение.Значение;
КонецЦикла;
Иначе
СкопироватьОтборДинамическогоСпискаЛкс(ОтборДинамическогоСписка, Отбор);
КонецЕсли;
КонецЕсли;
Если Модально Тогда
Результат = ФормаСписка.ОткрытьМодально();
Возврат Результат;
Иначе
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецЕсли;
КонецФункции
Процедура ПолеВводаСИсториейВыборариИзмененииЛкс(ПолеВвода, КлючИстории, ЗапоминатьПоследние = 20, НеЗапоминатьПустыеТипизированные = Истина) Экспорт
Если Ложь
Или (Истина
И Не НеЗапоминатьПустыеТипизированные
И ПолеВвода.Значение <> ПолеВвода.ТипЗначения.ПривестиЗначение(Неопределено))
Или ЗначениеЗаполнено(ПолеВвода.Значение)
Тогда
НовоеЗначениеXML = СохранитьОбъектВВидеСтрокиXMLЛкс(ПолеВвода.Значение);
Если СтрДлина(НовоеЗначениеXML) > 1000 Тогда
Возврат;
КонецЕсли;
КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения";
ПоследниеЗначения = ВосстановитьЗначение(КлючНастройки);
Если ТипЗнч(ПоследниеЗначения) <> Тип("Массив") Тогда
ПоследниеЗначения = Новый Массив;
КонецЕсли;
ПоследниеЗначенияXML = Новый Массив;
Для Каждого Значение Из ПоследниеЗначения Цикл
ПоследниеЗначенияXML.Добавить(СохранитьОбъектВВидеСтрокиXMLЛкс(Значение));
КонецЦикла;
Индекс = ПоследниеЗначенияXML.Найти(НовоеЗначениеXML);
Если Индекс <> Неопределено Тогда
ПоследниеЗначения.Удалить(Индекс);
КонецЕсли;
ПоследниеЗначения.Вставить(0, ПолеВвода.Значение);
Для Счетчик = ЗапоминатьПоследние По ПоследниеЗначения.ВГраница() Цикл
ПоследниеЗначения.Удалить(ЗапоминатьПоследние);
КонецЦикла;
СохранитьЗначение(КлючНастройки, ПоследниеЗначения);
КонецЕсли;
КонецПроцедуры
Процедура ПолеВводаСИсториейВыбора_НачалоВыбораИзСпискаЛкс(ПолеВвода, КлючИстории) Экспорт
// Запоминать последние
КлючНастройки = КлючИстории + "." + ПолеВвода.Имя + ".ПоследниеЗначения";
ПоследниеЗначения = ВосстановитьЗначение(КлючНастройки);
Если ТипЗнч(ПоследниеЗначения) = Тип("Массив") Тогда
ПолеВвода.СписокВыбора.Очистить();
Для Каждого Значение Из ПоследниеЗначения Цикл
НовыйЭлемент = ПолеВвода.СписокВыбора.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Процедура ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка) Экспорт
СтандартнаяОбработка = Ложь;
ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
ВыборФайла.Каталог = Элемент.Значение;
Если Не ВыборФайла.Выбрать() Тогда
Возврат;
КонецЕсли;
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, ВыборФайла.Каталог);
КонецПроцедуры
Функция ОткрытьСсылкуВСпискеЛкс(Ссылка) Экспорт
ПолноеИмяМД = Ссылка.Метаданные().ПолноеИмя();
СтруктураПараметры = Новый Структура;
СтруктураПараметры.Вставить("ТекущаяСтрока", Ссылка);
ФормаСписка = ПолучитьФормуЛкс(ПолноеИмяМД + ".ФормаСписка", СтруктураПараметры, , Новый УникальныйИдентификатор);
ФормаСписка.Открыть();
Возврат ФормаСписка;
КонецФункции
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПоле_ОтобразитьФлажкиЛкс(ОформлениеСтроки, Знач ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки[ИмяКолонки];
//Если Ячейка.ТолькоПросмотр Тогда
// Продолжить;
//КонецЕсли;
Если ТипЗнч(Ячейка.Значение) = Тип("Булево") Тогда
Ячейка.УстановитьФлажок(Ячейка.Значение);
Ячейка.УстановитьТекст("");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПоле__ПриИзмененииФлажкаЛкс(Элемент, Знач Колонка) Экспорт
Если ТипЗнч(Колонка.ЭлементУправления) = Тип("ПолеВвода") Тогда
Если Истина
И Колонка.Данные = ""
И Колонка.ДанныеФлажка = ""
Тогда
ОформлениеСтроки = Элемент.ОформлениеСтроки(Элемент.ТекущаяСтрока);
Колонка.ЭлементУправления.Значение = Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение;
//ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ОформлениеСтроки.Ячейки[Колонка.Имя].Значение);
//глВызватьСобытиеПоОбъектуСистемы(ЭтаФорма.мСвойстваФормы, оПолеВвода, сПриИзменении, ЭтаФорма, Колонка.ЭлементУправления);
Иначе
//МетаданныеТипа = глПолучитьМетаданныеТипа(ТипЗнч(Элемент.Значение), "ТипСписка", Истина);
//РедактированиеВДиалоге = Ложь;
//Если Истина
// И МетаданныеТипа <> Неопределено
// И МетаданныеТипа.КлассМетаданных.Предок = оСсылочный
//Тогда
// Попытка
// ВыбранныйСпособРедактирования = Элемент.СпособРедактирования;
// Исключение
// КонецПопытки;
// РедактированиеВДиалоге = ВыбранныйСпособРедактирования <> СпособРедактированияСписка.ВСписке;
//КонецЕсли;
//РазрешитьИзменение = Истина;
//Если РедактированиеВДиалоге Тогда
//Иначе
//Элемент.ЗакончитьРедактированиеСтроки(Ложь);
Элемент.ИзменитьСтроку();
ЗначениеЯчейки = Колонка.ЭлементУправления.Значение;
Если ТипЗнч(ЗначениеЯчейки) = Тип("Булево") Тогда
ИнтерактивноЗаписатьВКолонкуТабличногоПоляЛкс(Элемент, Колонка, Не ЗначениеЯчейки, , , Ложь);
//Элемент.ТекущаяКолонка = Колонка;
КонецЕсли;
Элемент.ЗакончитьРедактированиеСтроки(Ложь);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьПиктограммуТипаЛкс(Тип) Экспорт
ИмяОбщегоТипа = Неопределено;
КлючПоиска = Новый Структура("ИД", ПолучитьИдентификаторТипаЛкс(Тип));
НайденныеСтроки = ирКэш.Получить().ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
ИмяОбщегоТипа = НайденныеСтроки[0].Слово;
Иначе
//СтруктураТипа = ирКэш.Получить().ПолучитьСтруктуруТипаИзКонкретногоТипа(Тип);
//ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа;
ОбъектМД = Метаданные.НайтиПоТипу(Тип);
Если ОбъектМД <> Неопределено Тогда
ТекущееИмяТипа = ОбъектМД.ПолноеИмя();
ИмяОбщегоТипа = ПолучитьПервыйФрагментЛкс(ТекущееИмяТипа);
КонецЕсли;
КонецЕсли;
Картинка = Неопределено;
Если ИмяОбщегоТипа <> Неопределено Тогда
ИмяКартинки = "ир" + ПолучитьПервыйФрагментЛкс(ИмяОбщегоТипа);
Попытка
Картинка = ПолучитьОбщуюКартинкуЛкс(ИмяКартинки);
Исключение
ИмяКартинки = ИмяОбщегоТипа;
Попытка
Картинка = БиблиотекаКартинок[ИмяКартинки];
Исключение
КонецПопытки;
КонецПопытки;
КонецЕсли;
Возврат Картинка;
КонецФункции
// ИменаКолонок - Строка - имена колонок через запятую
Процедура ТабличноеПоле_ОтобразитьПиктограммыТиповЛкс(ОформлениеСтроки, ИменаКолонок) Экспорт
Если ТипЗнч(ИменаКолонок) = Тип("Строка") Тогда
ИменаКолонок = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаКолонок, ",", Истина);
КонецЕсли;
Для Каждого ИмяКолонки Из ИменаКолонок Цикл
Ячейка = ОформлениеСтроки.Ячейки.Найти(ИмяКолонки);
//:Ячейка=Новый("ОформлениеЯчейки")
Если Ячейка <> Неопределено Тогда
ДанныеКартинки = Ячейка.Значение;
Если ТипЗнч(ДанныеКартинки) = Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
СсылкаКартинка = Неопределено;
ТипЗначения = ТипЗнч(ДанныеКартинки);
Если Истина
И ТипЗначения = Тип("Булево")
И Ячейка.ОтображатьФлажок
Тогда
Продолжить;
КонецЕсли;
КартинкаТипа = ПолучитьПиктограммуТипаЛкс(ТипЗначения);
Если КартинкаТипа <> Неопределено Тогда
Ячейка.УстановитьКартинку(КартинкаТипа);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Функция ТабличноеПоле_СколькоСтрокЛкс(ТабличноеПоле) Экспорт
ЗначениеЭУ = ТабличноеПоле.Значение;
//ТипЗначенияТабличногоПоля = ТипЗнч(ИсточникДействий.Значение);
//ИмяОбщегоТипа = ПолучитьИмяОбщегоТипаИзКонкретногоТипа, ТипЗначенияТабличногоПоля);
Попытка
Количество = ЗначениеЭУ.Количество();
Попытка
Отбор = ТабличноеПоле.ОтборСтрок;
Исключение
КонецПопытки;
Исключение
Попытка
//Коллекция компоновки
Количество = ЗначениеЭУ.Элементы.Количество();
//Суффикс = "*";
Исключение
Попытка
//Или ИмяОбщегоТипа = "ДеревоЗначений"
Количество = ЗначениеЭУ.Строки.Количество();
Суффикс = "*";
Исключение
// ДинамическийСписок
ОбъектМД = Метаданные.НайтиПоТипу(ТабличноеПоле.ТипЗначения.Типы()[0]);
Если ОбъектМД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(ОбъектМД);
ТекстЗапроса = " ИЗ " + ОбъектМД.ПолноеИмя();
Если КорневойТип = "РегистрБухгалтерии" Тогда
ТекстЗапроса = ТекстЗапроса + ".ДвиженияССубконто";
КонецЕсли;
ПостроительПростой = Новый ПостроительЗапроса("ВЫБРАТЬ * " + ТекстЗапроса);
ПостроительПростой.ЗаполнитьНастройки();
ТекстОтбор = "";
Для Каждого ДоступноеПоле Из ПостроительПростой.ДоступныеПоля Цикл
Если Не ДоступноеПоле.Отбор Тогда
Продолжить;
КонецЕсли;
Если ТекстОтбор <> "" Тогда
ТекстОтбор = ТекстОтбор + ", ";
КонецЕсли;
ТекстОтбор = ТекстОтбор + "Т." + ДоступноеПоле.ПутьКДанным;
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ КОЛИЧЕСТВО(*) " + ТекстЗапроса + " КАК Т {ГДЕ " + ТекстОтбор + "}";
ПостроительЗапроса = Новый ПостроительЗапроса(ТекстЗапроса);
ПостроительЗапроса.ЗаполнитьНастройки();
СкопироватьОтборЛкс(ПостроительЗапроса.Отбор, ТабличноеПоле.Значение.Отбор, Истина, Истина);
Отбор = ТабличноеПоле.Значение.Отбор;
Количество = ПостроительЗапроса.Результат.Выгрузить()[0][0];
КонецПопытки;
КонецПопытки;
КонецПопытки;
Текст = "Количество строк ";
Если Отбор <> Неопределено Тогда
Текст = Текст + "с отбором """ + Отбор + """ ";
КонецЕсли;
Сообщить(Текст + "- " + Формат(Количество, "ЧН=") + "(" + Формат(Количество, "ЧН=; ЧГ=") + ")" + Суффикс);
Результат = Количество;
Возврат Результат;
КонецФункции
// Получает картинку для корневого типа конфигурации.
//
// Параметры:
// пКорневойТип Строка корневой тип конфигурации.
//
// Возвращаемое значение:
// Картинка корневого типа конфигурации.
//
Функция ПолучитьКартинкуКорневогоТипаЛкс(пКорневойТип) Экспорт
Если СтрокиРавныЛкс("Изменения", пКорневойТип) Тогда
Возврат ПолучитьОбщуюКартинкуЛкс("ирТаблицаИзменений");
КонецЕсли;
Попытка
Возврат ПолучитьОбщуюКартинкуЛкс("ир" + пКорневойТип);
Исключение
Попытка
Возврат БиблиотекаКартинок[пКорневойТип];
Исключение
КонецПопытки;
КонецПопытки;
Возврат Новый Картинка();
КонецФункции // ПолучитьКартинкуКорневогоТипа()
Функция ОткрытьТекущуюСтрокуТабличногоПоляТаблицыБДВРедактореОбъектаБДЛкс(ТабличноеПоле, ПолноеИмяМД = Неопределено, ДоступныеПоляВыбора = Неопределено) Экспорт
//ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
ТекущаяСтрока = ТабличноеПоле.ТекущиеДанные;
Если ПолноеИмяМД = Неопределено Тогда
ПолноеИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение)).ПолноеИмя();
КонецЕсли;
ТекущаяКолонка = ТабличноеПоле.ТекущаяКолонка;
Если Истина
И ТекущаяКолонка <> Неопределено
И (Ложь
Или ДоступныеПоляВыбора = Неопределено
Или ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(ТекущаяКолонка.Данные)) <> Неопределено)
Тогда
ИмяКолонки = ТекущаяКолонка.Данные;
Иначе
ИмяКолонки = "";
КонецЕсли;
СтруктураКлючаСтроки = Неопределено;
ПолноеИмяТаблицы = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь);
Если ТекущаяСтрока <> Неопределено Тогда
КлючОбъекта = ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ТекущаяСтрока, Истина, СтруктураКлючаСтроки);
КонецЕсли;
Если КлючОбъекта = Неопределено Тогда
Если ЛиКорневойТипСсылочногоОбъектаБДЛкс(ПолучитьПервыйФрагментЛкс(ПолноеИмяТаблицы)) Тогда
КлючОбъекта = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Ссылка."));
Иначе
КлючОбъекта = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "НаборЗаписей."));
КонецЕсли;
КонецЕсли;
ФормаРедактора = ПолучитьФормуЛкс("Обработка.ирРедакторОбъектаБД.Форма", , , ТекущаяСтрока);
ФормаРедактора.мПараметрКлючИлиОбъект = КлючОбъекта;
ФормаРедактора.Открыть();
ФормаРедактора.ПоказатьЯчейкуДанныхОбъекта(ПолноеИмяТаблицы, ИмяКолонки, СтруктураКлючаСтроки);
Возврат ФормаРедактора;
КонецФункции
// Если в текущей строке не достаточно полей для заполнения ключа записи регистра, то всегда возвращается набор записей, не смотря на параметр ДляРегистровСоздатьНаборЗаписей.
Функция ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, Знач ТекущаяСтрока, ДляРегистровСоздатьНаборЗаписей = Ложь, выхСтруктураКлючаСтроки = Неопределено) Экспорт
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(ПолноеИмяТаблицы);
СтруктураКлюча = ПолучитьСтруктуруКлючаТаблицыБДЛкс(ПолноеИмяТаблицы);
Если СтруктураКлюча.Свойство("НомерСтроки") Тогда
выхСтруктураКлючаСтроки = Новый Структура("НомерСтроки");
ИначеЕсли СтруктураКлюча.Свойство("Период") Тогда
выхСтруктураКлючаСтроки = Новый Структура("Период");
Иначе
выхСтруктураКлючаСтроки = Неопределено;
КонецЕсли;
Если выхСтруктураКлючаСтроки <> Неопределено Тогда
ЗаполнитьЗначенияСвойств(выхСтруктураКлючаСтроки, ТекущаяСтрока);
КонецЕсли;
Если ЛиКорневойТипСсылкиЛкс(ТипТаблицы) Тогда
КлючОбъекта = ТекущаяСтрока.Ссылка;
ИначеЕсли ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
КлючОбъекта = ТекущаяСтрока.Ссылка;
ИначеЕсли Ложь
Или ЛиКорневойТипРегистраБДЛкс(ТипТаблицы)
//Или ЛиКорневойТипПоследовательностиЛкс(ТипТаблицы)
Тогда
Если Не ДляРегистровСоздатьНаборЗаписей Тогда
НайденыВсеПоляКлючаЗаписи = Истина;
Для Каждого КлючИЗначение Из СтруктураКлюча Цикл
Попытка
Пустышка = ТекущаяСтрока[КлючИЗначение.Ключ];
Исключение
НайденыВсеПоляКлючаЗаписи = Ложь;
Прервать;
КонецПопытки;
КонецЦикла;
КонецЕсли;
Если Ложь
Или ДляРегистровСоздатьНаборЗаписей
Или Не НайденыВсеПоляКлючаЗаписи
Тогда
КлючОбъекта = ПолучитьНаборЗаписейПоКлючуЛкс(ПолноеИмяТаблицы, ТекущаяСтрока);
Иначе
ЗаполнитьЗначенияСвойств(СтруктураКлюча, ТекущаяСтрока);
МенеджерРегистра = Новый (СтрЗаменить(ПолноеИмяТаблицы, ".", "Менеджер."));
КлючОбъекта = МенеджерРегистра.СоздатьКлючЗаписи(СтруктураКлюча);
КонецЕсли;
Иначе
КлючОбъекта = Неопределено;
КонецЕсли;
Возврат КлючОбъекта;
КонецФункции
Функция _КонтрольРазмераВыборкиПользователемЛкс(ЗапросИлиПостроитель, МаксимальноеЧислоСтрок = 500000) Экспорт
КоличествоСтрокРезультата = ирКэш.Получить().ПолучитьГрубоКоличествоСтрокВРезультатеЗапроса(ЗапросИлиПостроитель);
Если Истина
И ТипЗнч(КоличествоСтрокРезультата) = Тип("Число")
И КоличествоСтрокРезультата > МаксимальноеЧислоСтрок
Тогда
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Все", "Все");
Кнопки.Добавить("Часть", "Первые " + Формат(МаксимальноеЧислоСтрок, "ЧГ="));
Ответ = Вопрос("Загружаемая таблица содержит " + КоличествоСтрокРезультата + " строк. Сколько строк загружать?", Кнопки, , "Часть");
//Если Ответ <> КодВозвратаДиалога.ОК Тогда
// Возврат;
//КонецЕсли;
Если Ответ = "Все" Тогда
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Иначе
МаксимальноеЧислоСтрок = 0;
КонецЕсли;
Возврат МаксимальноеЧислоСтрок;
КонецФункции
// Параметры:
// ИмяКлючевойКолонки - Строка - содержит имя таблицы
//
Функция ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь) Экспорт
#Если _ Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
МассивКлючей = Новый Массив;
Для Каждого СтрокаДерева1 Из ДеревоМетаданных.Строки Цикл
Для Каждого СтрокаДерева2 Из СтрокаДерева1.Строки Цикл
КорневойТип = ПолучитьПервыйФрагментЛкс(СтрокаДерева2[ИмяКлючевойКолонки]);
Если Ложь
Или КорневойТип = "ВнешнийИсточникДанных"
Или КорневойТип = "РегламентноеЗадание"
Тогда
Продолжить;
КонецЕсли;
ИмяТаблицы = СтрокаДерева2[ИмяКлючевойКолонки];
Если ИмяТаблицы = Неопределено Тогда
Продолжить;
КонецЕсли;
Если НайтиОбъектМетаДанныхПоПолномуИмениТаблицыБДЛкс(ИмяТаблицы) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивКлючей.Добавить(ИмяТаблицы);
Для Каждого СтрокаДерева3 Из СтрокаДерева2.Строки Цикл
МассивКлючей.Добавить(СтрокаДерева3[ИмяКлючевойКолонки]);
КонецЦикла;
КонецЦикла;
КонецЦикла;
ТекстПакета = "";
ТекстЗапроса = "";
СчетчикТаблиц = 0;
Для Каждого ПолноеИмяМД Из МассивКлючей Цикл
ТекстЧастиОбъединения = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные);
Если ТекстЧастиОбъединения = Неопределено Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "
|ОБЪЕДИНИТЬ ВСЕ";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + ТекстЧастиОбъединения;
СчетчикТаблиц = СчетчикТаблиц + 1;
Если СчетчикТаблиц = 255 Тогда
СчетчикТаблиц = 0;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
ТекстЗапроса = "";
КонецЕсли;
КонецЦикла;
Если ТекстПакета <> "" Тогда
ТекстПакета = ТекстПакета + "
|;";
КонецЕсли;
ТекстПакета = ТекстПакета + ТекстЗапроса;
Если ЗначениеЗаполнено(ТекстПакета) Тогда
Запрос = Новый Запрос;
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
Запрос.Текст = ТекстПакета;
Состояние("Сбор статистики таблиц...");
РезультатПакета = Запрос.ВыполнитьПакет();
Состояние("");
Результат = Новый Массив();
Для Каждого РезультатЗапроса Из РезультатПакета Цикл
Результат.Добавить(РезультатЗапроса.Выгрузить());
КонецЦикла;
Иначе
Результат = Новый Массив();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьКоличествоИзмененийПоУзлуЛкс(Узел, МассивМетаданных = Неопределено) Экспорт
#Если Клиент Тогда
Состояние("Вычисление количества изменений на узле...");
#КонецЕсли
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Узел", Узел);
МетаПланОбмена = Узел.Метаданные();
ТекстЗапроса = "";
Для Каждого ЭлементСОстава Из МетаПланОбмена.Состав Цикл
МетаОбъект = ЭлементСОстава.Метаданные;
Если Ложь
Или МетаОбъект = Неопределено
Или (Истина
И МассивМетаданных <> Неопределено
И МассивМетаданных.Найти(МетаОбъект) = Неопределено)
Тогда
Продолжить;
КонецЕсли;
Если ТекстЗапроса <> "" Тогда
ТекстЗапроса = ТекстЗапроса + "ОБЪЕДИНИТЬ ВСЕ" + Символы.ПС;
КонецЕсли;
ИмяТаблицыДляПоискаЗарегистрированных = СтрЗаменить(МетаОбъект.ПолноеИмя(), ".Перерасчет.", ".") + ".Изменения";
ТекстЗапроса = ТекстЗапроса + "ВЫБРАТЬ Количество(*) КАК Количество
|ИЗ
| " + ИмяТаблицыДляПоискаЗарегистрированных + " КАК РегистрацияИзменений
|ГДЕ
| РегистрацияИзменений.Узел = &Узел
|";
КонецЦикла;
Если ТекстЗапроса <> "" Тогда
Запрос.Текст = ТекстЗапроса;
ТаблицаКоличестваИзменений = Запрос.Выполнить().Выгрузить();
КоличествоИзменений = ТаблицаКоличестваИзменений.Итог("Количество");
Иначе
КоличествоИзменений = 0;
КонецЕсли;
#Если Клиент Тогда
Состояние("");
#КонецЕсли
Возврат КоличествоИзменений;
КонецФункции
Процедура ОбновитьСтатистикуПоТаблицеОбъектаМДВРезультатеПакетаЛкс(РезультатПакета, ПолноеИмяМД, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Истина) Экспорт
ТекстЗапроса = ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора, ТолькоРазрешенные);
Запрос = Новый Запрос(ТекстЗапроса);
Если СтруктураОтбора <> Неопределено Тогда
СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураОтбора, Запрос.Параметры);
КонецЕсли;
СтруктураКлюча = Новый Структура(ИмяКлючевойКолонки);
КолонкиКоличества = Новый Массив();
КолонкиКоличества.Добавить(ИмяКолонкиКоличества);
Если ЛиТаблицыИзменений Тогда
СтруктураКлюча.Вставить("Узел");
КолонкиКоличества.Добавить("КоличествоВыгруженных");
КолонкиКоличества.Добавить("КоличествоНевыгруженных");
КонецЕсли;
СтатистикаПоТаблице = Запрос.Выполнить().Выгрузить();
СтатистикаПоТаблице.Колонки.Добавить("Найдена", Новый ОписаниеТипов("булево"));
Для Каждого ЭлементПакета Из РезультатПакета Цикл
СтрокиРезультата = ЭлементПакета.НайтиСтроки(Новый Структура(ИмяКлючевойКолонки, ПолноеИмяМД));
Если СтрокиРезультата.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из СтрокиРезультата Цикл
ЗаполнитьЗначенияСвойств(СтруктураКлюча, СтрокаРезультата);
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = 0;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(СтруктураКлюча) Цикл
СтрокаСтатистики.Найдена = Истина;
Для Каждого ИмяКолонкиКоличества Из КолонкиКоличества Цикл
СтрокаРезультата[ИмяКолонкиКоличества] = СтрокаСтатистики[ИмяКолонкиКоличества];
КонецЦикла;
КонецЦикла;
КонецЦикла;
Прервать;
КонецЕсли;
КонецЦикла;
Для Каждого СтрокаСтатистики Из СтатистикаПоТаблице.НайтиСтроки(Новый Структура("Найдена", Ложь)) Цикл
СтрокаРезультата = ЭлементПакета.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаРезультата, СтрокаСтатистики);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьТекстЗапросаСтатистикиПоТаблицеЛкс(ПолноеИмяМД, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок", ЛиТаблицыИзменений = Ложь,
СтруктураОтбора = Неопределено, ТолькоРазрешенные = Ложь) Экспорт
ИмяТаблицы = ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД, ЛиТаблицыИзменений, , ТолькоРазрешенные);
Если ИмяТаблицы = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ТекстЧастиОбъединения = "
|ВЫБРАТЬ
| """ + ПолноеИмяМД + """ КАК " + ИмяКлючевойКолонки + ",
| Количество(*) КАК " + ИмяКолонкиКоличества + ",";
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| Узел,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоНевыгруженных,
| СУММА(ВЫБОР КОГДА Т.НомерСообщения ЕСТЬ NULL ТОГДА 0 ИНАЧЕ 1 КОНЕЦ) КАК КоличествоВыгруженных,";
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| 1
|ИЗ " + ИмяТаблицы + " КАК Т
|ГДЕ 1 = 1";
Если СтруктураОтбора <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
Если ирОбщий.СтрокиРавныЛкс("_ТипУзла_", КлючИЗначение.Ключ) Тогда
ОпределениеПоля = "ТИПЗНАЧЕНИЯ(Т.Узел)";
Иначе
ОпределениеПоля = "Т." + КлючИЗначение.Ключ;
КонецЕсли;
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
| И " + ОпределениеПоля + " В (&" + КлючИЗначение.Ключ + ")";
КонецЦикла;
КонецЕсли;
Если ЛиТаблицыИзменений Тогда
ТекстЧастиОбъединения = ТекстЧастиОбъединения + "
|СГРУППИРОВАТЬ ПО Узел";
КонецЕсли;
Возврат ТекстЧастиОбъединения;
КонецФункции
Процедура ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета, ИмяКлючевойКолонки = "ПолноеИмяОбъекта",
СуммируемыеКолонки = "КоличествоСтрок", СтруктураОтбора = Неопределено) Экспорт
#Если _ Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
ВсеСтрокиДерева = ПолучитьВсеСтрокиДереваЗначенийЛкс(ДеревоМетаданных);
СтруктураСуммируемыхКолонок = Новый Структура(СуммируемыеКолонки);
МассивКолонок = Новый Массив();
Для Каждого КлючИЗначение Из СтруктураСуммируемыхКолонок Цикл
МассивКолонок.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
Для Каждого ИмяСуммируемойКолонки Из МассивКолонок Цикл
СтрокаДерева[ИмяСуммируемойКолонки] = 0;
КонецЦикла;
КонецЦикла;
Для Каждого ТаблицаРезультата Из РезультатПакета Цикл
Для Каждого СтрокаРезультата Из ТаблицаРезультата Цикл
Если СтруктураОтбора <> Неопределено Тогда
ПодходитФильтру = Истина;
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
ЗначениеРезультата = СтрокаРезультата[КлючИЗначение.Ключ];
Если ТипЗнч(КлючИЗначение.Значение) = Тип("Массив") Тогда
Если КлючИЗначение.Значение.Найти(ЗначениеРезультата) = Неопределено Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
Иначе
Если КлючИЗначение.Значение <> ЗначениеРезультата Тогда
ПодходитФильтру = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Не ПодходитФильтру Тогда
Продолжить;
КонецЕсли;
КонецЕсли;
СтрокаДерева = ДеревоМетаданных.Строки.Найти(СтрокаРезультата[ИмяКлючевойКолонки], ИмяКлючевойКолонки, Истина);
Если СтрокаДерева <> Неопределено Тогда
Для Каждого ИмяСуммируемойКолонки Из МассивКолонок Цикл
СтароеКоличество = СтрокаДерева[ИмяСуммируемойКолонки];
СтрокаДерева[ИмяСуммируемойКолонки] = СтрокаДерева[ИмяСуммируемойКолонки] + СтрокаРезультата[ИмяСуммируемойКолонки];
Если СтрокаДерева.Уровень() > 1 Тогда
Продолжить;
КонецЕсли;
Родитель = СтрокаДерева.Родитель;
Пока Родитель <> Неопределено Цикл
КоличествоРодителя = Родитель[ИмяСуммируемойКолонки];
Если ТипЗнч(КоличествоРодителя) <> Тип("Число") Тогда
КоличествоРодителя = 0;
КонецЕсли;
Родитель[ИмяСуммируемойКолонки] = КоличествоРодителя - СтароеКоличество + СтрокаДерева[ИмяСуммируемойКолонки];
Родитель = Родитель.Родитель;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ОбновитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки = "ПолноеИмяОбъекта", ИмяКолонкиКоличества = "КоличествоСтрок",
ЛиТаблицыИзменений = Ложь, СтруктураОтбора = Неопределено) Экспорт
#Если _ Тогда
ДеревоМетаданных = Новый ДеревоЗначений
#КонецЕсли
РезультатПакета = ВычислитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, ИмяКлючевойКолонки, ИмяКолонкиКоличества, ЛиТаблицыИзменений, СтруктураОтбора);
ЗаполнитьКоличествоСтрокТаблицВДеревеМетаданныхЛкс(ДеревоМетаданных, РезультатПакета, ИмяКлючевойКолонки, ИмяКолонкиКоличества);
КонецПроцедуры
Процедура УстановитьЗначениеКолонкиДереваЛкс(ДеревоЗначений, ИмяКолонки = "Пометка", НовоеЗначение = Истина) Экспорт
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ДеревоЗначений);
Для Каждого СтрокаДерева Из ВсеСтроки Цикл
СтрокаДерева.Пометка = НовоеЗначение;
КонецЦикла;
КонецПроцедуры
Функция ПолучитьМетаданныеНаборовЗаписейПоРегистраторуЛкс(мдОбъекта, ВключаяПоследовательности = Ложь, ВключаяПерерасчеты = Ложь) Экспорт
ОбъектыМД = Новый Массив();
Для Каждого МетаРегистр из мдОбъекта.Движения Цикл
ОбъектыМД.Добавить(МетаРегистр);
Если ВключаяПерерасчеты Тогда
Если ЛиКорневойТипРегистраРасчетаЛкс(ПолучитьПервыйФрагментЛкс(МетаРегистр.ПолноеИмя())) Тогда
Для Каждого ПерерасчетМД Из МетаРегистр.Перерасчеты Цикл
ОбъектыМД.Добавить(ПерерасчетМД);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ВключаяПоследовательности Тогда
Для Каждого МетаПоследовательность Из Метаданные.Последовательности Цикл
Если МетаПоследовательность.Документы.Содержит(мдОбъекта) Тогда
ОбъектыМД.Добавить(МетаПоследовательность);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ОбъектыМД;
КонецФункции
// НовыйРежим - Булево - Имя/Синоним
Процедура ТабличноеПоле_ОбновитьКолонкиИмяСинонимЛкс(ТабличноеПоле, НовыйРежим, ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление") Экспорт
КолонкиТП = ТабличноеПоле.Колонки;
КолонкаИмя = КолонкиТП[ИмяКолонкиИмя];
КолонкаСиноним = КолонкиТП[ИмяКолонкиСиноним];
КолонкаИмя.Видимость = НовыйРежим;
КолонкаСиноним.Видимость = Не НовыйРежим;
Если ТипЗнч(ТабличноеПоле.Значение) = Тип("ДеревоЗначений") Тогда
КолонкаИмя.ОтображатьИерархию = НовыйРежим;
КолонкаСиноним.ОтображатьИерархию = Не НовыйРежим;
КонецЕсли;
ИндексКолонкиИмя = КолонкиТП.Индекс(КолонкаИмя);
ИндексКолонкиСиноним = КолонкиТП.Индекс(КолонкаСиноним);
Если НовыйРежим = (ИндексКолонкиИмя > ИндексКолонкиСиноним) Тогда
КолонкиТП.Сдвинуть(КолонкаИмя, ИндексКолонкиСиноним - ИндексКолонкиИмя);
КонецЕсли;
Если НовыйРежим Тогда
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Имя;
Иначе
ТабличноеПоле.ТекущаяКолонка = ТабличноеПоле.Колонки.Представление;
КонецЕсли;
КонецПроцедуры
Процедура ТабличноеПоле_ОформитьЯчейкиИмяСинонимЛкс(ТабличноеПоле, ОформлениеСтроки,
ИмяКолонкиИмя = "Имя", ИмяКолонкиСиноним = "Представление", ИмяКолонкиИндексКартинки = "ИндексКартинки", ДанныеФлажка = "") Экспорт
ДанныеСтроки = ОформлениеСтроки.ДанныеСтроки;
Если ТабличноеПоле.Колонки[ИмяКолонкиИмя].Видимость Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиИмя];
ВедущийИндекс = ТабличноеПоле.Колонки.Индекс(ВедущаяКолонка);
КонецЕсли;
Если ТабличноеПоле.Колонки[ИмяКолонкиСиноним].Видимость Тогда
Если Ложь
Или ВедущаяКолонка = Неопределено
Или ТабличноеПоле.Колонки.Индекс(ТабличноеПоле.Колонки[ИмяКолонкиСиноним]) < ВедущийИндекс
Тогда
ВедущаяКолонка = ТабличноеПоле.Колонки[ИмяКолонкиСиноним];
КонецЕсли;
КонецЕсли;
Если ВедущаяКолонка <> Неопределено Тогда
Ячейка = ОформлениеСтроки.Ячейки[ВедущаяКолонка.Имя];
ИндексКартинки = ДанныеСтроки[ИмяКолонкиИндексКартинки];
Если ИндексКартинки >= 0 Тогда
Ячейка.ОтображатьКартинку = Истина;
Ячейка.ИндексКартинки = ИндексКартинки;
КонецЕсли;
Если ДанныеФлажка <> "" Тогда
Ячейка.ОтображатьФлажок = Истина;
Ячейка.Флажок = ДанныеСтроки[ДанныеФлажка];
КонецЕсли;
КоличествоДочерних = ДанныеСтроки.Строки.Количество();
Если КоличествоДочерних > 0 Тогда
Ячейка.УстановитьТекст(Ячейка.Текст + " (" + КоличествоДочерних + ")");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева) Экспорт
Если Истина
И ТабличноеПолеДерева.ТекущаяКолонка <> Неопределено
И ЗначениеЗаполнено(ТабличноеПолеДерева.ТекущаяКолонка.Данные)
И ТабличноеПолеДерева.Значение.Колонки[ТабличноеПолеДерева.ТекущаяКолонка.Данные].ТипЗначения.СодержитТип(Тип("Строка"))
Тогда
ТекущаяКолонкаТП = ТабличноеПолеДерева.ТекущаяКолонка;
Иначе
Для Каждого КолонкаТП Из ТабличноеПолеДерева.Колонки Цикл
Если Не КолонкаТП.Видимость Тогда
Продолжить;
КонецЕсли;
КолонкаДерева = ТабличноеПолеДерева.Значение.Колонки[КолонкаТП.Данные];
Если КолонкаДерева.ТипЗначения.СодержитТип(Тип("Строка")) Тогда
ТекущаяКолонкаТП = КолонкаТП;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат ТекущаяКолонкаТП;
КонецФункции
Функция НайтиСтрокуТабличногоПоляДереваЗначенийСоСложнымФильтромЛкс(ТабличноеПолеДерева, ПолеВводаФильтра, Подстроки = "") Экспорт
ТекущаяКолонкаТП = ОпределитьВедущуюСтроковуюКолонкуТабличногоПоляЛкс(ТабличноеПолеДерева);
Если ТекущаяКолонкаТП = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ИмяТекущейКолонки = ТекущаяКолонкаТП.Данные;
Если Не ЗначениеЗаполнено(ИмяТекущейКолонки) Тогда
Возврат Неопределено;
КонецЕсли;
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПолеДерева.Значение);
ТекущаяСтрока = ТабличноеПолеДерева.ТекущаяСтрока;
Если Подстроки = "" Тогда
Подстроки = ПолеВводаФильтра.Значение;
КонецЕсли;
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(НРег(Подстроки), " ", Истина);
ИндексСтроки = 0;
Если ТекущаяСтрока <> Неопределено Тогда
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ИндексСтроки = ВсеСтроки.Найти(ТекущаяСтрока) + 1;
КонецЕсли;
КонецЕсли;
Успех = Ложь;
Для ИндексСтроки = ИндексСтроки По ВсеСтроки.Количество() - 1 Цикл
ТекущаяСтрока = ВсеСтроки[ИндексСтроки];
Если ЛиСтрокаСодержитВсеПодстрокиЛкс(ТекущаяСтрока[ИмяТекущейКолонки], Фрагменты) Тогда
ТабличноеПолеДерева.ТекущаяСтрока = ТекущаяСтрока;
ТабличноеПолеДерева.ТекущаяКолонка = ТекущаяКолонкаТП;
Успех = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Успех Тогда
ПолеВводаФильтра.ЦветФонаПоля = Новый Цвет();
Иначе
ТекущаяСтрока = Неопределено;
ПолеВводаФильтра.ЦветФонаПоля = ПолучитьЦветСтиляЛкс("ирЦветФонаОшибки");
КонецЕсли;
Возврат ТекущаяСтрока;
КонецФункции
Процедура ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле, ЧислоПервыхИгнорируемыхСтрок = 0) Экспорт
Счетчик = 0;
Для Каждого Строка Из ТабличноеПоле.Значение.Строки Цикл
Счетчик = Счетчик + 1;
Если Счетчик > ЧислоПервыхИгнорируемыхСтрок Тогда
ТабличноеПоле.Развернуть(Строка, Истина);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_СвернутьВсеСтрокиЛкс(ТабличноеПоле, ВосстановитьТекущуюСтроку = Ложь) Экспорт
МассивТекущихУзлов = Новый Массив;
Если ВосстановитьТекущуюСтроку Тогда
ТекущаяСтрока = ТабличноеПоле.ТекущаяСтрока;
Пока ТекущаяСтрока <> Неопределено Цикл
МассивТекущихУзлов.Добавить(ТекущаяСтрока);
ТекущаяСтрока = ТекущаяСтрока.Родитель;
КонецЦикла;
КонецЕсли;
ВсеСтрокиДерева = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
Для Каждого СтрокаДерева Из ВсеСтрокиДерева Цикл
Если Истина
И ТабличноеПоле.Развернут(СтрокаДерева)
И СтрокаДерева.Строки.Количество() > 0
И МассивТекущихУзлов.Найти(СтрокаДерева) = Неопределено
Тогда
ТабличноеПоле.Свернуть(СтрокаДерева);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ТабличноеПолеДеревоЗначений_АвтоРазвернутьВсеСтрокиЛкс(ТабличноеПоле, МаксимальноеЧислоСтрок = 30, ТекущаяСтрокаУстановлена = Ложь) Экспорт
ВсеСтроки = ПолучитьВсеСтрокиДереваЗначенийЛкс(ТабличноеПоле.Значение);
ЧислоДинамическихСтрок = ВсеСтроки.Количество();
Если ЧислоДинамическихСтрок > 0 Тогда
Если ЧислоДинамическихСтрок <= МаксимальноеЧислоСтрок Тогда
ТабличноеПолеДеревоЗначений_РазвернутьВсеСтрокиЛкс(ТабличноеПоле);
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0].Строки[0];
КонецЕсли;
Иначе
Если Не ТекущаяСтрокаУстановлена Тогда
ТабличноеПоле.ТекущаяСтрока = ТабличноеПоле.Значение.Строки[0];
Если ТабличноеПоле.Значение.Строки.Количество() = 1 Тогда
ТабличноеПоле.Развернуть(ТабличноеПоле.ТекущаяСтрока);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ДобавитьСсылкуВИзбранноеЛкс(Ссылка, ДобавлятьВИзбранноеРаботыПользователя = Истина, ДобавлятьВИзрабнноеИнтерфейснойПанели = Истина) Экспорт
Если ДобавлятьВИзбранноеРаботыПользователя Тогда
Избранное = ХранилищеСистемныхНастроек.Загрузить("Общее/ИзбранноеРаботыПользователя");
Если Избранное = Неопределено Тогда
Избранное = Новый ИзбранноеРаботыПользователя;
КонецЕсли;
ЭлементИзбранного = Новый ЭлементИзбранногоРаботыПользователя;
ЭлементИзбранного.НавигационнаяСсылка = ПолучитьНавигационнуюСсылку(Ссылка);
Избранное.Добавить(ЭлементИзбранного);
ХранилищеСистемныхНастроек.Сохранить("Общее/ИзбранноеРаботыПользователя", "", Избранное);
КонецЕсли;
Если ДобавлятьВИзрабнноеИнтерфейснойПанели Тогда
ФормаИнтерфейснойПанели = ПолучитьФормуЛкс("Обработка.ирИнтерфейснаяПанель.Форма");
СтруктураЭлемента = Новый Структура();
СтруктураЭлемента.Вставить("Вид", Ссылка.Метаданные().ПолноеИмя());
СтруктураЭлемента.Вставить("Представление", "" + Ссылка);
СтруктураЭлемента.Вставить("Имя", "" + Ссылка.УникальныйИдентификатор());
ФормаИнтерфейснойПанели.ДобавитьСтрокуВСтатическуюВетку(СтруктураЭлемента, "Избранное");
Если ФормаИнтерфейснойПанели.Открыта() Тогда
ФормаИнтерфейснойПанели.ЗаполнитьСтатическиеВеткиДереваИнтерфейса(ФормаИнтерфейснойПанели);
Иначе
ФормаИнтерфейснойПанели.СохранитьНастройки(ФормаИнтерфейснойПанели);
КонецЕсли;
КонецЕсли;
КонецФункции
//
Функция ТрансформироватьОтборВОтборКомпоновкиЛкс(Знач ОтборКомпоновкиДанных, Знач ЭлементыОтбора, Знач СоответствиеИмен = Неопределено,
Знач ПроверятьДоступностьПолей = Истина, Знач ДоступныеПоляОтбора = Неопределено, ПропускатьВыключенные = Ложь) Экспорт
Если СоответствиеИмен = Неопределено Тогда
СоответствиеИмен = Новый ТаблицаЗначений();
СоответствиеИмен.Колонки.Добавить("Источник");
//СоответствиеИмен.Колонки.Добавить("Приемник");
КонецЕсли;
Если ДоступныеПоляОтбора = Неопределено Тогда
ДоступныеПоляОтбора = ОтборКомпоновкиДанных.ДоступныеПоляОтбора;
КонецЕсли;
ИндексГраницы = ЭлементыОтбора.Количество() - 1;
ИзмененныеЭлементыОтбора = Новый Массив;
Платформа = ирКэш.Получить();
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если Истина
И ПропускатьВыключенные
И Не ЭлементОтбора.Использование
Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда
ПриемникОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(ПриемникОтбора, ЭлементОтбора);
ТрансформироватьОтборВОтборКомпоновкиЛкс(ПриемникОтбора, ЭлементОтбора.Элементы, СоответствиеИмен, , ДоступныеПоляОтбора);
Продолжить;
КонецЕсли;
Если ТипЗнч(ЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) <> Тип("ПолеКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
//ПутьКДаннымЛевый = Неопределено;
//Если ТипЗнч(ЭлементОтбора.ЛевоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымЛевый = "" + ЭлементОтбора.ЛевоеЗначение;
//Иначе
// ЛевоеЗначение = ЭлементОтбора.ЛевоеЗначение;
//КонецЕсли;
ПутьКДаннымПравый = Неопределено;
Если ТипЗнч(ЭлементОтбора.ПравоеЗначение) = Тип("ПолеКомпоновкиДанных") Тогда
ПутьКДаннымПравый = "" + ЭлементОтбора.ПравоеЗначение;
Иначе
ПравоеЗначение = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
лВидСравнения = ЭлементОтбора.ВидСравнения;
Иначе
СтрокаВидаСравнения = Платформа.СоответствиеВидовСравнения.Найти(ЭлементОтбора.ВидСравнения, "Построитель");
Если СтрокаВидаСравнения = Неопределено Тогда
// %%%% Здесь можно добавить интеллекта
Продолжить;
КонецЕсли;
ПутьКДаннымЛевый = ЭлементОтбора.ПутьКДанным;
ПутьКДаннымПравый = Неопределено;
лВидСравнения = СтрокаВидаСравнения.Компоновка;
ПравоеЗначение = ЭлементОтбора.Значение;
КонецЕсли;
//Если ПутьКДаннымЛевый <> Неопределено Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКДаннымЛевый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивФрагментов, ".");
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ПолеОтбора = Неопределено;
Для Каждого лЭлементОтбора Из ОтборКомпоновкиДанных.Элементы Цикл
Если Истина
И ТипЗнч(лЭлементОтбора) = Тип("ЭлементОтбораКомпоновкиДанных")
И лЭлементОтбора.ЛевоеЗначение = ПолеКомпоновки
И ИзмененныеЭлементыОтбора.Найти(лЭлементОтбора) = Неопределено
Тогда
ПолеОтбора = лЭлементОтбора;
ИзмененныеЭлементыОтбора.Добавить(ПолеОтбора);
Прервать;
КонецЕсли;
КонецЦикла;
Если ПолеОтбора = Неопределено Тогда
ДоступноеПоле = ДоступныеПоляОтбора.НайтиПоле(ПолеКомпоновки);
Если Истина
И ПроверятьДоступностьПолей
И ДоступноеПоле = Неопределено
Тогда
Продолжить;
КонецЕсли;
ПолеОтбора = ОтборКомпоновкиДанных.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ПолеОтбора.ЛевоеЗначение = ПолеКомпоновки;
КонецЕсли;
//Иначе
// ПолеОтбора.ПравоеЗначение = ЛевоеЗначение;
//КонецЕсли;
Если ПутьКДаннымПравый <> Неопределено Тогда
МассивФрагментов = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПутьКДаннымПравый);
СтрокаИсточника = СоответствиеИмен.Найти(НРег(МассивФрагментов[0]), "Источник");
Если СтрокаИсточника <> Неопределено Тогда
МассивФрагментов[0] = СтрокаИсточника.Приемник;
КонецЕсли;
ПутьКДанным = ПолучитьСтрокуСРазделителемИзМассиваЛкс(МассивФрагментов, ".");
ПолеКомпоновки = Новый ПолеКомпоновкиДанных(ПутьКДанным);
ПолеОтбора.ПравоеЗначение = ПолеКомпоновки;
Иначе
ПолеОтбора.ПравоеЗначение = ПравоеЗначение;
КонецЕсли;
ПолеОтбора.ВидСравнения = лВидСравнения;
ПолеОтбора.Использование = ЭлементОтбора.Использование;
КонецЦикла;
КонецФункции
Процедура ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, ИмяКолонки = "") Экспорт
Если ирКэш.Получить().Это2iS Тогда
ДУЛкс("УФ(П1, П2)", "ОткрытьКоллекциюВКонсолиОбработкиДанных", ТабличноеПоле.Значение);
Иначе
ВыделенныеСтроки = ТабличноеПоле.ВыделенныеСтроки;
Если ВыделенныеСтроки.Количество() = 0 Тогда
Возврат ;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
ИмяКолонки = ТабличноеПоле.ТекущаяКолонка.Данные;
КонецЕсли;
Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда
Возврат;
КонецЕсли;
МассивСсылок = Новый Массив;
Для Каждого Строка Из ВыделенныеСтроки Цикл
ЗначениеСтроки = Строка[ИмяКолонки];
ТипЗначения = ТипЗнч(ЗначениеСтроки);
Если Метаданные.НайтиПоТипу(ТипЗначения) = Неопределено Тогда
Продолжить;
КонецЕсли;
МассивСсылок.Добавить(ЗначениеСтроки);
КонецЦикла;
ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок);
КонецЕсли;
КонецПроцедуры // ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс()
Процедура ОткрытьОбъектыИзВыделенныхСтрокВПодбореИОбработкеОбъектовЛкс(ТабличноеПоле, ПолноеИмяТаблицы = "") Экспорт
ПараметрКоманды = Новый Массив();
Для Каждого ВыделеннаяСтрока Из ТабличноеПоле.ВыделенныеСтроки Цикл
КлючОбъекта = ПолучитьКлючСтрокиТаблицыБДИзСтрокиТаблицыЗначенийЛкс(ПолноеИмяТаблицы, ВыделеннаяСтрока);
ПараметрКоманды.Добавить(КлючОбъекта);
КонецЦикла;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ПараметрКоманды);
КонецПроцедуры // ОткрытьОбъектыИзВыделенныхЯчеекВПодбореИОбработкеОбъектовЛкс()
Функция ОткрытьПодборИОбработкуОбъектовИзТабличногоПоляДинамическогоСпискаЛкс(ТабличноеПоле) Экспорт
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ТабличноеПоле.Значение));
Если ОбъектМД <> Неопределено Тогда
Ответ = Вопрос("Обработать только выделенные строки (Да) иначе будет использован текущий отбор (Нет)?", РежимДиалогаВопрос.ДаНет);
Иначе
Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если Ответ = КодВозвратаДиалога.Да Тогда
ПараметрКоманды = Новый Массив();
Для Каждого Строка Из ТабличноеПоле.ВыделенныеСтроки Цикл
ПараметрКоманды.Добавить(Строка);
КонецЦикла;
Форма = ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(ПараметрКоманды);
Иначе
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма",,, ОбъектМД.ПолноеИмя());
Форма.Открыть();
Форма.УстановитьОбластьПоиска();
Форма.СтрокаПоиска = "";
//СкопироватьОтборЛкс(Форма.ПостроительОтчета.Отбор, ИсточникДействий.Значение.Отбор, Истина, Истина);
Форма.Компоновщик.Настройки.Отбор.Элементы.Очистить();
ТрансформироватьОтборВОтборКомпоновкиЛкс(Форма.Компоновщик.Настройки.Отбор, ТабличноеПоле.Значение.Отбор,,,, Истина);
КонецЕсли;
Возврат Форма;
КонецФункции
Функция ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок) Экспорт
Если МассивСсылок.Количество() = 0 Тогда
Возврат Неопределено;
КонецЕсли;
Форма = ПолучитьФормуЛкс("Обработка.ирПодборИОбработкаОбъектов.Форма");
Форма.Открыть();
Форма.ЗагрузитьОбъектыДляОбработки(МассивСсылок);
Возврат Форма;
КонецФункции // ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс()
Функция ПолучитьСтруктуруВосстановленияКонсолиЛкс(ИмяИлиОбъектКонсоли) Экспорт
Если ТипЗнч(ИмяИлиОбъектКонсоли) = Тип("Строка") Тогда
ИмяКонсоли = ИмяИлиОбъектКонсоли;
Иначе
ИмяКонсоли = ИмяИлиОбъектКонсоли.Метаданные().Имя;
КонецЕсли;
Структура = Новый Структура();
Структура.Вставить("БлокировкаВосстановления", Неопределено);
ПрефиксИмениФайлаВосстановления = ИмяКонсоли + "_" + ИмяПользователя() + "_";
Структура.Вставить("ПрефиксИмениФайлаВосстановления", ПрефиксИмениФайлаВосстановления);
ИмяФайлаВосстановления = ирКэш.Получить().КаталогФайловогоКэша + "\" + ПрефиксИмениФайлаВосстановления
+ Формат(НомерСеансаИнформационнойБазы(), "ЧЦ=8; ЧВН=; ЧГ=") + ".tmp";
Структура.Вставить("ФайлВосстановления", Новый Файл(ИмяФайлаВосстановления));
Возврат Структура;
КонецФункции
Функция СохранитьФайлВКонсолиСВосстановлениемЛкс(ДиалогВыбораФайла, Знач ИмяСохраняемогоФайла, ИмяОткрытогоФайла = "", ДанныеДляФайла,
СтруктураВосстановления, ЗапрашиватьИмяФайла = Ложь) Экспорт
#Если _ Тогда
ДиалогВыбораФайла = Новый ДиалогВыбораФайла();
#КонецЕсли
ФайлВосстановления = СтруктураВосстановления.ФайлВосстановления;
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
БлокировкаВосстановления = СтруктураВосстановления.БлокировкаВосстановления;
СохранитьФайл = Истина;
Если НРег(ИмяСохраняемогоФайла) <> НРег(ФайлВосстановления.ПолноеИмя) Тогда
ФайлВыбран = Истина;
лФайл = Новый Файл(ИмяОткрытогоФайла);
ДиалогВыбораФайла.ПолноеИмяФайла = ИмяСохраняемогоФайла;
Если Ложь
Или ПустаяСтрока(ИмяСохраняемогоФайла)
Или ЗапрашиватьИмяФайла
Или Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1
Тогда
Пока Истина Цикл
Если ДиалогВыбораФайла.Выбрать() Тогда
лФайл = Новый Файл(ДиалогВыбораФайла.ПолноеИмяФайла);
Если Найти(Нрег(лФайл.Имя), НРег(ПрефиксИмениФайлаВосстановления)) = 1 Тогда
КодОтвета = Вопрос("Это имя файла зарезервировано. Хотите выбрать другое?", РежимДиалогаВопрос.ОКОтмена);
Если КодОтвета = КодВозвратаДиалога.ОК Тогда
Продолжить;
Иначе
ФайлВыбран = Ложь;
Прервать;
КонецЕсли;
КонецЕсли;
ИмяСохраняемогоФайла = ДиалогВыбораФайла.ПолноеИмяФайла;
ФайлВыбран = Истина;
Прервать;
Иначе
ФайлВыбран = Ложь;
СохранитьФайл = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Иначе
ФайлВыбран = Ложь;
КонецЕсли;
Если СохранитьФайл Тогда
Если Истина
И НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя)
И БлокировкаВосстановления <> Неопределено
Тогда
БлокировкаВосстановления = Неопределено;
КонецЕсли;
ЗначениеВФайл(ИмяСохраняемогоФайла, ДанныеДляФайла);
Если НРег(ИмяСохраняемогоФайла) = НРег(ФайлВосстановления.ПолноеИмя) Тогда
БлокировкаВосстановления = Новый ЗаписьТекста(ИмяСохраняемогоФайла,,,Истина);
КонецЕсли;
КонецЕсли;
Возврат ФайлВыбран;
КонецФункции
Функция ПроверитьВыбратьФайлВосстановленияКонсолиЛкс(СтруктураВосстановления) Экспорт
ПрефиксИмениФайлаВосстановления = СтруктураВосстановления.ПрефиксИмениФайлаВосстановления;
СписокВосстановления = Новый СписокЗначений;
ФайлыВосстановления = НайтиФайлы(ирКэш.Получить().КаталогФайловогоКэша, ПрефиксИмениФайлаВосстановления + "*.tmp");
Для Каждого ФайлВосстановления Из ФайлыВосстановления Цикл
#Если _ Тогда
ФайлВосстановления = Новый Файл();
#КонецЕсли
Попытка
ФайлВосстановления.УстановитьВремяИзменения(ФайлВосстановления.ПолучитьВремяИзменения());
//Пустышка = Новый ЗаписьТекста(ФайлВосстановления.ПолноеИмя, , , Истина);
Исключение
// Файла заблокирован и значит сессия продолжается.
Продолжить;
КонецПопытки;
СписокВосстановления.Добавить(ФайлВосстановления.ПолноеИмя, "" + ФайлВосстановления.ПолучитьВремяИзменения() + " - "
+ ФайлВосстановления.ИмяБезРасширения);
КонецЦикла;
ИмяФайлаВосстановления = "";
Если СписокВосстановления.Количество() > 0 Тогда
СписокВосстановления.СортироватьПоПредставлению(НаправлениеСортировки.Убыв);
СписокВосстановления.Добавить("<Удалить все файлы восстановления>");
ВыбранныйЭлемент = СписокВосстановления.ВыбратьЭлемент("Вы можете открыть файл восстановления прерванной сессии");
Если ВыбранныйЭлемент <> Неопределено Тогда
Если ВыбранныйЭлемент.Значение = "<Удалить все файлы восстановления>" Тогда
Для Каждого ЭлементСписка Из СписокВосстановления Цикл
Если ВыбранныйЭлемент = ЭлементСписка Тогда
Продолжить;
КонецЕсли;
УдалитьФайлы(ЭлементСписка.Значение);
КонецЦикла;
Иначе
ИмяФайлаВосстановления = ВыбранныйЭлемент.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат ИмяФайлаВосстановления;
КонецФункции
Процедура УдалитьФайлВосстановленияКонсолиСБлокировкойЛкс(СтруктураВосстановления) Экспорт
СтруктураВосстановления.БлокировкаВосстановления = Неопределено;
Попытка
УдалитьФайлы(СтруктураВосстановления.ФайлВосстановления.ПолноеИмя);
Исключение
КонецПопытки;
КонецПроцедуры
Процедура СчитатьПорциюВыборкиВТаблицуЛкс(Выборка, ТаблицаПриемник, Знач РазмерПорции = 9999, СчитыватьЧерезКопиюТаблицы = Истина,
СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если _ Тогда
Пустышка = Новый Запрос;
Выборка = Пустышка.Выполнить();
#КонецЕсли
Если СчитыватьЧерезКопиюТаблицы Тогда
// Иначе добавление и заполнение строк при связи с табличным полем будет дольше выполняться
КопияТаблицыПриемника = ТаблицаПриемник.Скопировать();
Если СсылкаНаБуфернуюТаблицу <> Неопределено Тогда
СсылкаНаБуфернуюТаблицу.Вставить("Таблица", КопияТаблицыПриемника);
КонецЕсли;
Иначе
КопияТаблицыПриемника = ТаблицаПриемник;
КонецЕсли;
КоличествоРезультата = Выборка.Количество();
Несчитано = КоличествоРезультата - КопияТаблицыПриемника.Количество();
Если Ложь
Или РазмерПорции > Несчитано
Или РазмерПорции = 0
Тогда
РазмерПорции = Несчитано;
КонецЕсли;
Если Несчитано = РазмерПорции Тогда
ПредставлениеПроцесса = "Загрузка выборки";
Иначе
ПредставлениеПроцесса = "Загрузка порции выборки";
КонецЕсли;
#Если Клиент Тогда
Индикатор = ПолучитьИндикаторПроцессаЛкс(РазмерПорции, ПредставлениеПроцесса);
#КонецЕсли
КолонкиВложенныхТаблиц = Новый Массив();
Для Каждого Колонка Из Выборка.Владелец().Колонки Цикл
Если Колонка.ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
КолонкиВложенныхТаблиц.Добавить(Колонка.Имя);
КонецЕсли;
КонецЦикла;
ЕстьКолонкиВложенныхТаблиц = КолонкиВложенныхТаблиц.Количество() > 0;
РазмерПорцииОсталось = РазмерПорции;
Пока Выборка.Следующий() Цикл
НоваяСтрока = КопияТаблицыПриемника.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
Если ЕстьКолонкиВложенныхТаблиц Тогда
Для Каждого КолонкаВложеннойТаблицы Из КолонкиВложенныхТаблиц Цикл
НоваяСтрока[КолонкаВложеннойТаблицы] = Выборка[КолонкаВложеннойТаблицы].Выгрузить();
КонецЦикла;
КонецЕсли;
Если РазмерПорцииОсталось > 0 Тогда
РазмерПорцииОсталось = РазмерПорцииОсталось - 1;
Если РазмерПорцииОсталось = 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
#Если Клиент Тогда
ОбработатьИндикаторЛкс(Индикатор);
#КонецЕсли
КонецЦикла;
Если РазмерПорции = Несчитано Тогда
Выборка = Неопределено;
КонецЕсли;
#Если Клиент Тогда
ОсвободитьИндикаторПроцессаЛкс();
#КонецЕсли
ТаблицаПриемник = КопияТаблицыПриемника;
КонецПроцедуры // СчитатьПорциюРезультата()
// ТабличноеПоле определяется как источник действий командной панели.
// Параметру ВыборкаРезультата внутри присваивается значение!
Процедура ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатЗапроса, ВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", БезопасныйПорогКоличестваСтрок = 100000, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
#Если _ Тогда
лЗапрос = Новый Запрос;
РезультатЗапроса = лЗапрос.Выполнить();
#КонецЕсли
//БезопасныйПорогКоличестваСтрок = 1; // Для отладки
ВыборкаРезультата = РезультатЗапроса.Выбрать();
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
Если Ложь
Или БезопасныйПорогКоличестваСтрок = 0
Или ВыборкаРезультата.Количество() < БезопасныйПорогКоличестваСтрок
Тогда
ВыборкаРезультата = Неопределено;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Ложь;
ТабличноеПоле.Значение = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.Прямой);
Попытка
Выполнить("ЭтаФорма." + ИмяОбработчикаОбновления + "()");
Исключение
ВызватьИсключение ОписаниеОшибки();
КонецПопытки;
Иначе
ТабличноеПоле.Значение = Новый ТаблицаЗначений;
Для Каждого Колонка Из РезультатЗапроса.Колонки Цикл
ТипЗначения = Колонка.ТипЗначения;
Если ТипЗначения.СодержитТип(Тип("РезультатЗапроса")) Тогда
ТипЗначения = Новый ОписаниеТипов("ТаблицаЗначений");
КонецЕсли;
ТабличноеПоле.Значение.Колонки.Добавить(Колонка.Имя, ТипЗначения, Колонка.Имя, Колонка.Ширина);
КонецЦикла;
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
СчитатьПорциюВыборкиВТаблицуЛкс(ВыборкаРезультата, ТабличноеПоле.Значение, БезопасныйПорогКоличестваСтрок, , СсылкаНаБуфернуюТаблицу);
КонецЕсли;
КонецПроцедуры
// ТабличноеПоле определяется как источник действий командной панели.
Процедура ЗагрузитьВыборкуВТабличноеПолеПолностьюЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель,
ИмяОбработчикаОбновления = "ОбновитьРазмерДинамическойТаблицы", СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ЭтаФорма.ПодключитьОбработчикОжидания(ИмяОбработчикаОбновления, 0.1, Истина);
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
СчитатьПорциюВыборкиВТаблицуЛкс(мВыборкаРезультата, ТабличноеПоле.Значение, 0, , СсылкаНаБуфернуюТаблицу);
КонецПроцедуры
// Параметру КоличествоРезультата внутри присваивается значение!
Процедура ПослеЗагрузкиВыборкиВТабличноеПолеЛкс(ЭтаФорма, мВыборкаРезультата, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, СсылкаНаБуфернуюТаблицу = Неопределено) Экспорт
ТабличноеПоле = КоманднаяПанель.ИсточникДействий;
Если ТипЗнч(мВыборкаРезультата) = Тип("COMОбъект") Тогда
КоличествоРезультата = 0;
Попытка
КоличествоРезультата = мВыборкаРезультата.Count;
Исключение
Если мВыборкаРезультата.State <> 0 Тогда
КоличествоРезультата = мВыборкаРезультата.RecordCount;
КонецЕсли;
КонецПопытки;
ВсеСчитано = КоличествоРезультата = ТабличноеПоле.Значение.Количество();
ИначеЕсли ТипЗнч(мВыборкаРезультата) = Тип("ВыборкаИзРезультатаЗапроса") Тогда
КоличествоРезультата = мВыборкаРезультата.Количество();
Если СсылкаНаБуфернуюТаблицу <> Неопределено И СсылкаНаБуфернуюТаблицу.Свойство("Таблица") Тогда
ТабличноеПоле.Значение = СсылкаНаБуфернуюТаблицу.Таблица;
КонецЕсли;
ВсеСчитано = Ложь;
Иначе
КоличествоРезультата = ТабличноеПоле.Значение.Количество();
ВсеСчитано = Истина;
КонецЕсли;
ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, ТабличноеПоле.Значение.Количество(),
КоличествоРезультата, ВсеСчитано);
КонецПроцедуры
Функция ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(ПолноеИмяТаблицы, ИмяКолонки, ЗначениеОтбора, МаксимальнаяПорция = 0) Экспорт
ПоляТаблицыБД = ирКэш.ПолучитьПоляТаблицыБДЛкс(ПолноеИмяТаблицы);
#Если _ Тогда
ПоляТаблицыБД = ПолучитьСтруктуруХраненияБазыДанных().Колонки;
#КонецЕсли
ТекстПоля = "";
ПсевдонимТаблицы = "Т";
Для Каждого ПолеТаблицыБД Из ПоляТаблицыБД Цикл
Если Ложь
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ХранилищеЗначения"))
Или ПолеТаблицыБД.ТипЗначения.СодержитТип(Тип("ТаблицаЗначений"))
Тогда
Продолжить;
КонецЕсли;
Если ЗначениеЗаполнено(ТекстПоля) Тогда
ТекстПоля = ТекстПоля + ", ";
КонецЕсли;
ТекстПоля = ТекстПоля + ПсевдонимТаблицы + "." + ПолеТаблицыБД.Имя;
КонецЦикла;
ТекстПервые = "";
Если МаксимальнаяПорция > 0 Тогда
ТекстПервые = " ПЕРВЫЕ " + Формат(МаксимальнаяПорция, "ЧГ=") + " ";
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ " + ТекстПервые + " " + ТекстПоля + "
|ИЗ " + ирОбщий.ПолучитьИмяТаблицыИзМетаданныхЛкс(ПолноеИмяТаблицы) + " КАК " + ПсевдонимТаблицы + "
|{ГДЕ " + ПсевдонимТаблицы + "." + ИмяКолонки + "}";
Построитель = Новый ПостроительЗапроса(ТекстЗапроса);
Если ТипЗнч(ЗначениеОтбора) = Тип("СписокЗначений") Тогда
ЭлементОтбора = Построитель.Отбор.Добавить(ИмяКолонки);
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = ЗначениеОтбора;
ЭлементОтбора.Использование = Истина;
Иначе
Построитель.Отбор.Добавить(ИмяКолонки).Установить(ЗначениеОтбора);
КонецЕсли;
Возврат Построитель;
КонецФункции
Функция ЗагрузитьСвязанныеСтрокиТаблицыБДЛкс(ЭтаФорма, ТабличноеПолеСвязанныхКолонок, ТабличноеПолеСвязанныхСтрок, КоманднаяПанельСвязанныхСтрок, мВыборкаРезультатаСтрокиТаблицы,
ЗначениеОтбора) Экспорт
СтрокаСвязаннойКолонки = ТабличноеПолеСвязанныхКолонок.ТекущаяСтрока;
Если СтрокаСвязаннойКолонки = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
ЭтаФорма.СтрокиТаблицыБД = Новый ТаблицаЗначений;
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
//Если ЗначениеОтбора = Неопределено Тогда
// ЗначениеОтбора = СтрокаСвязаннойКолонки.Ссылка;
//КонецЕсли;
Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора);
//ЧислоСтрокДляЗагрузки = ирОбщий.КонтрольРазмераВыборкиПользователемЛкс(Построитель);
//Если ЧислоСтрокДляЗагрузки > 0 Тогда
// Построитель = ПолучитьПостроительВыборкиСвязанныхСтрокЛкс(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки, ЗначениеОтбора, ЧислоСтрокДляЗагрузки);
//КонецЕсли;
//// http://partners.v8.1c.ru/forum/thread.jsp?id=1034151#1034151
////МаксимальныйРазмер = 500000;
////Построитель = ПолучитьПостроительВыборкиСвязанныхСтрок(, МаксимальныйРазмер);
// Антибаг 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1017264#1017264
Если ирКэш.Получить().ВерсияПлатформы >= 802014 Тогда
Если Истина
И СтрокаСвязаннойКолонки.ТипТаблицы = "Изменения"
И Найти(СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, "РегистрСведений.") = 1
Тогда
Если Метаданные.ОбщиеРеквизиты.Количество() > 0 Тогда
Возврат Неопределено;
КонецЕсли;
//Для Каждого ОбщийРеквизит Из Метаданные.ОбщиеРеквизиты Цикл
// ВыбранноеПоле = Построитель.ВыбранныеПоля.Найти(ОбщийРеквизит.Имя);
// Если Истина
// И ВыбранноеПоле <> Неопределено
// И ОбъектМетаданных.Измерения.Найти(ОбщийРеквизит.Имя) = Неопределено
// Тогда
// Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, ОбъектМетаданных) Тогда
// Построитель.ВыбранныеПоля.Удалить(ВыбранноеПоле);
// КонецЕсли;
// КонецЕсли;
//КонецЦикла;
КонецЕсли;
КонецЕсли;
Попытка
РезультатСтрокиТаблицы = Построитель.Результат;
Исключение
// Антибаг платформы 8.2.14 http://partners.v8.1c.ru/forum/thread.jsp?id=1031481#1031481
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
ирОбщий.ЗагрузитьВыборкуВТабличноеПолеПервуюПорциюЛкс(ЭтаФорма, РезультатСтрокиТаблицы, мВыборкаРезультатаСтрокиТаблицы, КоманднаяПанельСвязанныхСтрок);
//Если СтрокиТаблицыБД.Количество() = МаксимальныйРазмер Тогда
// Сообщить("Были выбраны первые " + МаксимальныйРазмер + " строк таблицы");
//КонецЕсли;
СтруктураОтбора = Новый Структура("ПолноеИмяТаблицы, ИмяКолонки", СтрокаСвязаннойКолонки.ПолноеИмяТаблицы, СтрокаСвязаннойКолонки.ИмяКолонки);
ЗаполнитьЗначенияСвойств(СтруктураОтбора, СтрокаСвязаннойКолонки);
ТабличноеПолеСвязанныхСтрок.СоздатьКолонки();
ТабличноеПолеСвязанныхСтрок.ТекущаяКолонка = ТабличноеПолеСвязанныхСтрок.Колонки[СтрокаСвязаннойКолонки.ИмяКолонки];
Для Каждого КолонкаТП Из ТабличноеПолеСвязанныхСтрок.Колонки Цикл
КолонкаТП.ТолькоПросмотр = Истина;
КонецЦикла;
Попытка
ИскомаяСсылка = СтрокаСвязаннойКолонки.Ссылка
Исключение
ИскомаяСсылка = Неопределено;
КонецПопытки;
Если ИскомаяСсылка <> Неопределено Тогда
ТекущаяСтрока = ТабличноеПолеСвязанныхСтрок.Значение.Найти(ИскомаяСсылка, СтрокаСвязаннойКолонки.ИмяКолонки);
Если ТекущаяСтрока <> Неопределено Тогда
ТабличноеПолеСвязанныхСтрок.ТекущаяСтрока = ТекущаяСтрока;
КонецЕсли;
КонецЕсли;
Возврат СтрокаСвязаннойКолонки.ПолноеИмяТаблицы;
КонецФункции
Процедура ОбновитьЧислоЗагруженныхЭлементовВыборкиЛкс(ТабличноеПоле, КоманднаяПанель, ПолеСтрокиКоличестваРезультата, КоличествоЗагружено, КоличествоРезультата, ВсеСчитано) Экспорт
Если ВсеСчитано Тогда
СтрокаКоличествоРезультата = "" + КоличествоЗагружено;
ПолеСтрокиКоличестваРезультата.ЦветФона = Новый Цвет();
Иначе
СтрокаКоличествоРезультата = "" + КоличествоЗагружено + "/" + КоличествоРезультата;
ПолеСтрокиКоличестваРезультата.ЦветФона = ПолучитьЦветСтиляЛкс("ирЦветФонаВычисляемогоЗначения");
КонецЕсли;
ПолеСтрокиКоличестваРезультата.Значение = СтрокаКоличествоРезультата;
КоманднаяПанель.Кнопки.ЗагрузитьПолностью.Доступность = Не ВсеСчитано;
КонецПроцедуры
// Формирует макет компоновки и извлекает из него запрос
// Параметры:
// Схема - СхемаКомпоновкиДанных
// НастройкаКомпоновкиДанных - НастройкиКомпоновкиДанных
// ДобавлятьУпорядочивание - Булево
// ПрефиксИменПараметров - Строка, *"" - используется для переименования параметров, полезно при смешивании нескольких запросов из компоновки в один
// выхСхемаКолонок - Структура, *Неопределено - если не равно Неопределено, то возвращается структура,
// где ключи - имена колонок, а значения - полные имена полей
//
// Результат - Запрос
//
Функция ПолучитьЗапросИзКомпоновкиЛкс(Знач Схема, Знач НастройкаКомпоновкиДанных, Знач ДобавлятьУпорядочивание = Ложь, ПрефиксИменПараметров = "",
ДобавитьВыбранноеПоле = "", выхСхемаКолонок = Неопределено, Автоупорядочивание = Истина, ПроверятьДоступностьПолей = Ложь, СПредставлениямиСсылок = Ложь) Экспорт
НастройкаКомпоновкиДанных = ПолучитьКопиюОбъектаЛкс(НастройкаКомпоновкиДанных);
#Если _ Тогда
НастройкаКомпоновкиДанных = Новый НастройкиКомпоновкиДанных
#КонецЕсли
Если НастройкаКомпоновкиДанных.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура);
КонецЕсли;
Если ЗначениеЗаполнено(ДобавитьВыбранноеПоле) Тогда
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновкиДанных.Выбор, ДобавитьВыбранноеПоле);
КонецЕсли;
Если Не СПредставлениямиСсылок Тогда
Для Каждого ВыбранноеПоле Из НастройкаКомпоновкиДанных.Выбор.Элементы Цикл
Если ТипЗнч(ВыбранноеПоле) <> Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
ВызватьИсключение "Неподдерживаемый тип выбранного поля - " + ТипЗнч(ВыбранноеПоле);
КонецЕсли;
Если ВыбранноеПоле.Использование Тогда
НайтиДобавитьЭлементОтбораКомпоновкиЛкс(НастройкаКомпоновкиДанных.Структура[0].Отбор, "" + ВыбранноеПоле.Поле); // Отбор здесь используется не для фильтрации
КонецЕсли;
КонецЦикла;
НастройкаКомпоновкиДанных.Выбор.Элементы.Очистить();
КонецЕсли;
СтрокаПорядка = ПолучитьСтрокуПорядкаКомпоновкиЛкс(НастройкаКомпоновкиДанных.Порядок);
НастройкаКомпоновкиДанных.Порядок.Элементы.Очистить();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, НастройкаКомпоновкиДанных, ,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Запрос = Новый Запрос;
Если МакетКомпоновки.НаборыДанных.Количество() > 2 Тогда
Сообщить("В макете компоновки обнаружено более одного запроса");
КонецЕсли;
ТекстЗапроса = МакетКомпоновки.НаборыДанных[0].Запрос;
Если ДобавлятьУпорядочивание Тогда
Если ЗначениеЗаполнено(СтрокаПорядка) Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|УПОРЯДОЧИТЬ ПО
| " + СтрокаПорядка;
КонецЕсли;
Если Ложь
Или Автоупорядочивание
//Или ЗначениеЗаполнено(СтрокаПорядка)
Тогда
ТекстЗапроса = ТекстЗапроса + "
|//Секция_Упорядочить. Этот комментарий используется в коде
|АВТОУПОРЯДОЧИВАНИЕ";
КонецЕсли;
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Для Каждого ЗначениеПараметра Из МакетКомпоновки.ЗначенияПараметров Цикл
Запрос.Параметры.Вставить(ЗначениеПараметра.Имя, ЗначениеПараметра.Значение);
КонецЦикла;
Если ПрефиксИменПараметров <> "" Тогда
ДобавитьПрефиксВсемПараметрамЗапросаЛкс(Запрос, ПрефиксИменПараметров);
КонецЕсли;
Если выхСхемаКолонок <> Неопределено Тогда
//выхСхемаКолонок = ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки);
//
НаборДанныхМакета = МакетКомпоновки.НаборыДанных[0];
Для Каждого ПолеНабора Из НаборДанныхМакета.Поля Цикл
выхСхемаКолонок.Вставить(ПолеНабора.Имя, ПолеНабора.ПутьКДанным);
КонецЦикла;
Для Каждого ВложенныйНаборДанных Из НаборДанныхМакета.ВложенныеНаборыДанных Цикл
выхСхемаКолонок.Вставить(ВложенныйНаборДанных.Имя, ВложенныйНаборДанных.ПутьКДанным);
КонецЦикла;
КонецЕсли;
Возврат Запрос;
КонецФункции
Функция ПолучитьТекстОтбораЗапросаКомпоновкиЛкс(ЗапросСОтбором, ПсевдонимТаблицы = "Т") Экспорт
ТекстОтбораДублей = ПолучитьПоследнийФрагментЛкс(ЗапросСОтбором.Текст, "КАК " + ПсевдонимТаблицы + "
|ГДЕ", Ложь);
Если Не ЗначениеЗаполнено(ТекстОтбораДублей) Тогда
ТекстОтбораДублей = " ИСТИНА ";
КонецЕсли;
Возврат ТекстОтбораДублей;
КонецФункции
// Осуществляет вывод результата компоновки в коллекцию значений. По умолчанию в качестве коллекции используется новая таблица значений.
// Параметры:
// СхемаКомпоновки - СхемаКомпоновкиДанных
// НастройкаКомпоновки - НастройкиКомпоновкиДанных
// КоллекцияЗначений - ДеревоЗначений, Массив, СписокЗначений, ТаблицаЗначений - Если не указана, создается ТаблицаЗначений
// ВнешниеНаборыДанных - Структура
// ТолькоСоздатьКолонки - Булево
// СхемаКолонок - Структура - Если Неопределено, то не возвращается
// МаксимальноеЧислоСтрокРезультата - Число(15,2) - Для предотвращения получения слишком большого результата. Если порог превышен, то результат = Неопределено.
// ОтключитьОбщиеИтоги - Булево
// РежимОтладки - Булево
//
Функция СкомпоноватьВКоллекциюЗначенийПоСхемеЛкс(Знач СхемаКомпоновки, Знач НастройкаКомпоновки, КоллекцияЗначений = Неопределено, Знач ВнешниеНаборыДанных,
Знач ТолькоСоздатьКолонки = Ложь, СхемаКолонок = Неопределено, Знач МаксимальноеЧислоСтрокРезультата = 0, Знач ОтключитьОбщиеИтоги = Истина, Знач РежимОтладки = Ложь,
ПроверятьДоступностьПолей = Ложь) Экспорт
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
//ЭлементСтруктуры = НастройкаКомпоновки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
//ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
Если ОтключитьОбщиеИтоги Тогда
НастройкаКомпоновки.ПараметрыВывода.УстановитьЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ВертикальноеРасположениеОбщихИтогов"),
РасположениеИтоговКомпоновкиДанных.Нет);
КонецЕсли;
Если Ложь
Или КоллекцияЗначений = Неопределено
Или ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений")
Или ТипЗнч(КоллекцияЗначений) = Тип("Массив")
Тогда
КоллекцияРезультата = Новый ТаблицаЗначений;
Иначе
КоллекцияРезультата = КоллекцияЗначений;
КонецЕсли;
Если РежимОтладки Тогда
ОтладитьЛкс(СхемаКомпоновки, Ложь, НастройкаКомпоновки, ВнешниеНаборыДанных);
//Возврат Неопределено;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Попытка
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"), ПроверятьДоступностьПолей);
Исключение
//ИнформацияОбОшибке = ИнформацияОбОшибке();
//Если глКэш.ЭтоВидимоеПриложение Тогда
// ПоказатьИнформациюОбОшибке(ИнформацияОбОшибке);
//Иначе
// ВызватьИсключение ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
//КонецЕсли;
ВызватьИсключение;
Возврат Неопределено;
КонецПопытки;
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
//ОтладитьЛкс(МакетКомпоновки, Ложь);
//Возврат Неопределено;
Если МаксимальноеЧислоСтрокРезультата > 0 Тогда
// Здесь тратится дополнительное ощутимое время на предварительный запрос.
ирПлатформа = ирКэш.Получить();
ГрубоеКоличествоСтрокРезультата = ирПлатформа.ПолучитьГрубоКоличествоСтрокВРезультатеКомпоновки(МакетКомпоновки);
Если ГрубоеКоличествоСтрокРезультата > МаксимальноеЧислоСтрокРезультата Тогда
Сообщить("Настройки компоновки приводят к слишком большой выборке данных. Попробуйте задать более сильные ограничения.");
Возврат Неопределено;
КонецЕсли;
КонецЕсли;
//Антибаг платформы 1.14. Удаляем дубли ячеек по именам колонок в макете.
//ИсследоватьЛкс(МакетКомпоновки, Ложь);
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 0 Тогда
ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки;
КоличествоЯчеек = ЯчейкиЗаголовка.Количество();
СтруктураКолонок = Новый Структура;
ИндексЯчейки = 0;
Пока ИндексЯчейки < КоличествоЯчеек Цикл
ЯчейкаКолонки = ЯчейкиЗаголовка[ИндексЯчейки];
ИмяКолонки = ЯчейкаКолонки.Имя;
//ИмяКолонки = ирПлатформа.ПолучитьИдентификаторИзПредставления(ЯчейкаКолонки.Имя); // От этого варианта отказались из-за портативности
ИмяКолонки = СтрЗаменить(ИмяКолонки, ".", "_");
ИмяКолонки = СтрЗаменить(ИмяКолонки, "]", "");
ИмяКолонки = СтрЗаменить(ИмяКолонки, "[", "");
ИмяКолонки = СтрЗаменить(ИмяКолонки, " ", "_");
ЯчейкаКолонки.Имя = ИмяКолонки;
Если СтруктураКолонок.Свойство(ИмяКолонки) Тогда
Для ИндексМакета = 1 По ОписанияМакетовОбластей.Количество() - 1 Цикл
МакетСтроки = ОписанияМакетовОбластей[ИндексМакета];
МакетСтроки.Макет.Ячейки.Удалить(ИндексЯчейки);
КонецЦикла;
ЯчейкиЗаголовка.Удалить(ИндексЯчейки);
КоличествоЯчеек = КоличествоЯчеек - 1;
Иначе
ИндексЯчейки = ИндексЯчейки + 1;
СтруктураКолонок.Вставить(ИмяКолонки);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если СхемаКолонок <> Неопределено Тогда
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
СхемаКолонок.Очистить();
Если ЯчейкиЗаголовка <> Неопределено Тогда
КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество();
Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл
Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл
// Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205
// http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023
ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс];
Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение;
Если ПараметрЯчейки = Неопределено Тогда
Продолжить;
КонецЕсли;
Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение;
ПозицияТочки = Найти(Выражение, ".");
Если Ложь
Или ПозицияТочки = 0
Или Найти(Выражение, " ") > 0
Или Найти(Выражение, "(") > 0
Тогда
//ИмяПоля = "";
Продолжить;
Иначе
ИмяПоля = Сред(Выражение, ПозицияТочки + 1);
КонецЕсли;
СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля);
Прервать;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если ТолькоСоздатьКолонки Тогда
КоллекцияЗначений.Колонки.Очистить();
ЯчейкиЗаголовка = МакетКомпоновки.Макеты[0].Макет.Ячейки;
Для Каждого Ячейка Из ЯчейкиЗаголовка Цикл
//КолонкаКоллекции = КоллекцияЗначений.Колонки.Найти(Ячейка.Имя);
//Если КолонкаКоллекции = Неопределено Тогда
КоллекцияЗначений.Колонки.Добавить(Ячейка.Имя, Ячейка.ТипЗначения, Ячейка.Заголовок,);
//КонецЕсли;
КонецЦикла;
Иначе
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, , Истина);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(КоллекцияРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецЕсли;
//ИсследоватьЛкс(КоллекцияРезультата);
Если ТипЗнч(КоллекцияЗначений) = Тип("СписокЗначений") Тогда
Есть0 = КоллекцияРезультата.Колонки.Количество() > 0;
Есть1 = КоллекцияРезультата.Колонки.Количество() > 1;
Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл
НовыйЭлемент = КоллекцияЗначений.Добавить();
Если Есть0 Тогда
НовыйЭлемент.Значение = СтрокаРезультата[0];
КонецЕсли;
Если Есть1 Тогда
НовыйЭлемент.Представление = СтрокаРезультата[1];
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(КоллекцияЗначений) = Тип("Массив") Тогда
Если КоллекцияРезультата.Колонки.Количество() > 0 Тогда
Для Каждого СтрокаРезультата Из КоллекцияРезультата Цикл
КоллекцияЗначений.Добавить(СтрокаРезультата[0]);
КонецЦикла;
КонецЕсли;
Иначе
КоллекцияЗначений = КоллекцияРезультата;
КонецЕсли;
Результат = КоллекцияЗначений;
Возврат Результат;
КонецФункции
Функция НайтиПоказатьСтрокуВПолеТекстовогоДокументаЛкс(Форма, ПолеТекстовогоДокумента, СтрокаПоиска) Экспорт
Позиция = Найти(Нрег(ПолеТекстовогоДокумента.ПолучитьТекст()), Нрег(СтрокаПоиска));
Если Позиция > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(Позиция, Позиция + СтрДлина(СтрокаПоиска));
Форма.ТекущийЭлемент = ПолеТекстовогоДокумента;
Результат = Истина;
Иначе
Если СтрДлина(ПолеТекстовогоДокумента.ВыделенныйТекст) > 0 Тогда
ПолеТекстовогоДокумента.УстановитьГраницыВыделения(1, 1);
КонецЕсли;
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Элемент - ПолеТабличногоДокумента
//
Функция ПолеТабличногоДокументаолучитьПредставлениеСуммыВыделенныхЯчеекЛкс(Знач Элемент) Экспорт
Сумма = 0;
СчетчикЯчеекСуммы = 0;
СчетчикЯчеекОбщий = 0;
ВыделенныеОбласти = Элемент.ВыделенныеОбласти;
ЕстьИгнорированныеОбласти = Ложь;
НачальноеКоличество = ВыделенныеОбласти.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = ВыделенныеОбласти[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда
Продолжить;
КонецЕсли;
ПлощадьОбласти = (Область.Право - Область.Лево + 1) * (Область.Низ - Область.Верх + 1);
СчетчикЯчеекОбщий = СчетчикЯчеекОбщий + ПлощадьОбласти;
Если ПлощадьОбласти < 10000 Тогда
Для НомерКолонки = Область.Лево по Область.Право Цикл
Для НомерСтроки = Область.Верх по Область.Низ Цикл
ОбластьЯчейки = Элемент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Попытка
Число = Число(ОбластьЯчейки.Текст);
Исключение
Продолжить;
КонецПопытки;
Сумма = Сумма + Число;
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + 1;
КонецЦикла;
КонецЦикла;
Иначе
ЕстьИгнорированныеОбласти = Истина;
КонецЕсли;
КонецЦикла;
СчетчикЯчеекСуммы = "" + СчетчикЯчеекСуммы;
Сумма = "" + Сумма;
Если ЕстьИгнорированныеОбласти Тогда
СчетчикЯчеекСуммы = СчетчикЯчеекСуммы + "+?";
Сумма = Сумма + "+?";
КонецЕсли;
Текст = "" + СчетчикЯчеекСуммы + " из " + СчетчикЯчеекОбщий + " яч. = " + Сумма + "";
Возврат Текст;
КонецФункции
// Таблица - ТаблицаЗначений, ТабличнаяЧасть, РезультатЗапроса
Функция ВывестиТаблицуВТабличныйДокументЛкс(Таблица, Знач ТабличныйДокумент = Неопределено, ДанныеРасшифровки = Неопределено, ИтогиЧисловыхПолей = Истина,
АвтофиксацияШапки = Истина) Экспорт
ВнешниеНаборыДанных = Новый Структура("Основной", Таблица);
СхемаКомпоновки = СоздатьСхемуПоТаблицамЗначенийЛкс(ВнешниеНаборыДанных, , , ИтогиЧисловыхПолей);
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
Для Каждого Колонка Из Таблица.Колонки Цикл
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(НастройкаКомпоновки.Выбор, Колонка.Имя);
КонецЦикла;
ТабличныйДокумент = СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, ТабличныйДокумент, ВнешниеНаборыДанных,
ДанныеРасшифровки, АвтофиксацияШапки,, Истина);
Возврат ТабличныйДокумент;
КонецФункции
Функция СкомпоноватьВТабличныйДокументЛкс(СхемаКомпоновки, НастройкаКомпоновки, Знач ТабличныйДокумент = Неопределено, ВнешниеНаборыДанных = Неопределено,
ДанныеРасшифровки = Неопределено, АвтофиксацияШапки = Истина, ПроверятьДоступностьПолей = Ложь, ВстроитьЗначенияПолейВРасшифровки = Ложь) Экспорт
#Если _ Тогда
НастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновки.Структура.Количество() = 0 Тогда
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(НастройкаКомпоновки.Структура);
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Если ДанныеРасшифровки = Неопределено Тогда
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КонецЕсли;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, НастройкаКомпоновки, ДанныеРасшифровки,,, ПроверятьДоступностьПолей);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки);
Если ТабличныйДокумент = Неопределено Тогда
ТабличныйДокумент = Новый ТабличныйДокумент;
КонецЕсли;
ВывестиРезультатКомпоновкиСАвтофиксациейСтрокЛкс(ТабличныйДокумент, ПроцессорКомпоновки, ДанныеРасшифровки.Элементы,,, АвтофиксацияШапки);
Если ВстроитьЗначенияПолейВРасшифровки Тогда
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ИдентификаторРасшифровки = Ячейка.Расшифровка;
Если ТипЗнч(ИдентификаторРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЗначенияПолей = ДанныеРасшифровки.Элементы[ИдентификаторРасшифровки].ПолучитьПоля();
Если ЗначенияПолей.Количество() > 0 Тогда
Ячейка.Расшифровка = ЗначенияПолей[0].Значение;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат ТабличныйДокумент;
КонецФункции
// мВнешниеНаборыДанных - Структура, Неопределено - не очищается
Функция ДополнитьСтруктуруВнешихНаборовДанныхПустышкамиЛкс(лСхемаКомпоновкиДанных, мВнешниеНаборыДанных = Неопределено) Экспорт
Если мВнешниеНаборыДанных = Неопределено Тогда
мВнешниеНаборыДанных = Новый Структура();
КонецЕсли;
// Создадим пустышки внешних наборов данных, если они не переданы
ОбъектТаблица = 0;
Для Каждого НаборДанных Из лСхемаКомпоновкиДанных.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхОбъектСхемыКомпоновкиДанных") Тогда
Если НаборДанных.ИмяОбъекта = "" Тогда
Продолжить;
КонецЕсли;
Если Не мВнешниеНаборыДанных.Свойство(НаборДанных.ИмяОбъекта, ОбъектТаблица) Тогда
ОбъектТаблица = Новый ТаблицаЗначений;
КонецЕсли;
Попытка
КолонкиОбъектаТаблицы = ОбъектТаблица.Колонки;
Исключение
// Тогда это табличная часть, но возможно и тут будет исключение
КолонкиОбъектаТаблицы = ОбъектТаблица.ВыгрузитьКолонки().Колонки;
КонецПопытки;
Если КолонкиОбъектаТаблицы.Количество() > 0 Тогда
Продолжить;
КонецЕсли;
Для Каждого Поле Из НаборДанных.Поля Цикл
Если ТипЗнч(Поле) = Тип("ПолеНабораДанныхСхемыКомпоновкиДанных") Тогда
Если КолонкиОбъектаТаблицы.Найти(Поле.Поле) = Неопределено Тогда
КолонкиОбъектаТаблицы.Добавить(Поле.Поле, Поле.ТипЗначения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
мВнешниеНаборыДанных.Вставить(НаборДанных.ИмяОбъекта, ОбъектТаблица);
КонецЕсли;
КонецЦикла;
Возврат мВнешниеНаборыДанных;
КонецФункции
Функция ВыбратьТипСсылкиВПолеВводаЛкс(Элемент, СтандартнаяОбработка, ОткрытьФормуВыбораСсылкиПослеВыбораТипа = Истина) Экспорт
Форма = ирКэш.Получить().ПолучитьФорму("ВыборОбъектаМетаданных", Элемент, Элемент);
ТекущееЗначение = Элемент.Значение;
Если ЛиСсылкаНаОбъектБДЛкс(ТекущееЗначение) Тогда
НачальноеЗначениеВыбора = ТекущееЗначение.Метаданные().ПолноеИмя();
КонецЕсли;
лСтруктураПараметров = Новый Структура;
лСтруктураПараметров.Вставить("ОтображатьСсылочныеОбъекты", Истина);
лСтруктураПараметров.Вставить("ОтображатьВнешниеИсточникиДанных", Истина);
лСтруктураПараметров.Вставить("ОтображатьПеречисления", Истина);
лСтруктураПараметров.Вставить("НачальноеЗначениеВыбора", НачальноеЗначениеВыбора);
Форма.НачальноеЗначениеВыбора = лСтруктураПараметров;
ЗначениеВыбора = Форма.ОткрытьМодально();
Если ТипЗнч(ЗначениеВыбора) = Тип("Структура") Тогда
лПолноеИмяОбъекта = Неопределено;
Если ЗначениеВыбора.Свойство("ПолноеИмяОбъекта", лПолноеИмяОбъекта) Тогда
ИмяТипаСсылки = ПолучитьИмяТипаИзМетаданныхЛкс(лПолноеИмяОбъекта);
ОписаниеТипов = Новый ОписаниеТипов(ИмяТипаСсылки);
НовоеЗначение = ОписаниеТипов.ПривестиЗначение(Неопределено);
ИнтерактивноЗаписатьВЭлементУправленияЛкс(Элемент, НовоеЗначение);
Если ОткрытьФормуВыбораСсылкиПослеВыбораТипа Тогда
//Если ЛиСсылкаНаОбъектБДЛкс(НовоеЗначение, Ложь) Тогда
ОткрытьФормуСпискаЛкс(лПолноеИмяОбъекта,, Ложь, Элемент, Истина);
//КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
СтандартнаяОбработка = Ложь;
Возврат Неопределено;
КонецФункции
// Для "Ссылка.Организация" вернет "Организация", для "Основание.Контрагент" вернет "ОснованиеКонтрагент"
// Параметры:
// ИмяПоля - Строка
Функция ПолучитьИмяКолонкиРезультатаПоИмениПоляЛкс(Знач ИмяПоля) Экспорт
Начало = "Ссылка.";
ДлинаНачала = СтрДлина(Начало);
Если СтрокиРавныЛкс(Лев(ИмяПоля, ДлинаНачала), Начало) Тогда
ИмяПоля = Сред(ИмяПоля, ДлинаНачала + 1);
КонецЕсли;
ИмяПоля = СтрЗаменить(ИмяПоля, ".", "");
Возврат ИмяПоля;
КонецФункции
Процедура ДобавитьМногострочнуюСтрокуВТекстЛкс(СобираемыйТекст, Выражение, Смещение, СНовойСтроки = Ложь) Экспорт
Если СНовойСтроки Тогда
СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение;
КонецЕсли;
СобираемыйТекст = СобираемыйТекст + СтрПолучитьСтроку(Выражение, 1);
Для Счетчик = 2 По СтрЧислоСтрок(Выражение) Цикл
СобираемыйТекст = СобираемыйТекст + Символы.ПС + Смещение + СтрПолучитьСтроку(Выражение, Счетчик);
КонецЦикла;
КонецПроцедуры
Функция ПолучитьИндексКартинкиТипаЛкс(ОписаниеТипов) Экспорт
Если ОписаниеТипов = Неопределено Тогда
Возврат 14;
КонецЕсли;
Типы = ОписаниеТипов.Типы();
Если Типы.Количество() = 1 Тогда
КорневойТип = ПолучитьКорневойТипКонфигурацииЛкс(Типы[0]);
Если Типы[0] = Тип("Число") Тогда
ИндексКартинки = 0;
ИначеЕсли Типы[0] = Тип("Строка") Тогда
ИндексКартинки = 1;
ИначеЕсли Типы[0] = Тип("Дата") Тогда
ИндексКартинки = 2;
ИначеЕсли Типы[0] = Тип("Булево") Тогда
ИндексКартинки = 3;
ИначеЕсли Типы[0] = Тип("ТаблицаЗначений") Тогда
ИндексКартинки = 19;
ИначеЕсли КорневойТип = "Справочник" Тогда
ИндексКартинки = 7;
ИначеЕсли КорневойТип = "Документ" Тогда
ИндексКартинки = 8;
ИначеЕсли КорневойТип = "Перечисление" Тогда
ИндексКартинки = 9;
ИначеЕсли КорневойТип = "ПланВидовХарактеристик" Тогда
ИндексКартинки = 10;
ИначеЕсли КорневойТип = "ПланСчетов" Тогда
ИндексКартинки = 11;
ИначеЕсли КорневойТип = "ПланВидовРасчета" Тогда
ИндексКартинки = 12;
ИначеЕсли КорневойТип = "БизнесПроцесс" Тогда
ИндексКартинки = 13;
ИначеЕсли КорневойТип = "ТочкаМаршрута" Тогда
ИндексКартинки = 14;
ИначеЕсли КорневойТип = "Задача" Тогда
ИндексКартинки = 15;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Иначе
ИндексКартинки = 16;
КонецЕсли;
Возврат ИндексКартинки;
КонецФункции
// Получает строку для установки порядка компоновки.
//
// Параметры:
// ПорядокКомпоновки ПорядокКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - для установки порядка.
//
Функция ПолучитьВыражениеПорядкаКомпоновкиНаЯзыкеЛкс(ПорядокКомпоновки, ИсключаемоеПоле = "", СимволЗаменыТочки = Неопределено, ДиалектSQL = "1C") Экспорт
Строка = "";
Если СтрокиРавныЛкс(ДиалектSQL, "1С") Тогда
СтрокаВозр = "Возр";
СтрокаУбыв = "Убыв";
Иначе
СтрокаВозр = "Asc";
СтрокаУбыв = "Desc";
КонецЕсли;
Для Каждого ЭлементПорядка Из ПорядокКомпоновки.Элементы Цикл
Если Ложь
Или Не ЭлементПорядка.Использование
Или ТипЗнч(ЭлементПорядка) = Тип("АвтоЭлементПорядкаКомпоновкиДанных")
Или ИсключаемоеПоле = "" + ЭлементПорядка.Поле
Тогда
Продолжить;
КонецЕсли;
ИмяПоля = "" + ЭлементПорядка.Поле;
Если СимволЗаменыТочки <> Неопределено Тогда
ИмяПоля = СтрЗаменить(ИмяПоля, ".", СимволЗаменыТочки);
КонецЕсли;
Строка = Строка + ", " + ИмяПоля + " ";
Если ЭлементПорядка.ТипУпорядочивания = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда
Строка = Строка + СтрокаВозр;
Иначе
Строка = Строка + СтрокаУбыв;
КонецЕсли;
КонецЦикла;
Возврат Сред(Строка, 3);
КонецФункции // ПолучитьСтрокуПорядкаКомпоновкиЛкс()
Функция ПолучитьПреставлениеСочетанияКлавишЛкс(СочетаниеКлавиш) Экспорт
Представление = "";
Если СочетаниеКлавиш.Alt Тогда
Представление = Представление + "Alt+";
КонецЕсли;
Если СочетаниеКлавиш.Ctrl Тогда
Представление = Представление + "Ctrl+";
КонецЕсли;
Если СочетаниеКлавиш.Shift Тогда
Представление = Представление + "Shift+";
КонецЕсли;
Представление = Представление + СочетаниеКлавиш.Клавиша;
Возврат Представление;
КонецФункции
////////////////////////////////
// ФОРМЫ
Процедура ИнициализироватьФормуЛкс(ЭтаФорма, ПолноеИмяФормы) Экспорт
// Проверяем режим модальности
Список = Новый СписокЗначений;
Попытка
Список.ВыбратьЭлемент();
Исключение
ВызватьИсключение "При запуске приложения из конфигуратора автоматически включается контроль модальности.
|Запустите приложение другим способом, чтобы разрешить модальность.";
КонецПопытки;
ВстроитьКнопкиСтруктурыКоманднойПанелиЛкс(ЭтаФорма);
Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма);
мСвойстваФормы = ПолучитьДопСвойстваФормыЛкс(ЭтаФорма);
мСвойстваФормы.Вставить("ИмяФормы", ПолноеИмяФормы);
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Контейнер = Новый Структура();
Оповестить("ирПолучитьБазовуюФорму", Контейнер);
Если Не Контейнер.Свойство("ирПортативный") Тогда
БазоваяФорма = ирПортативный.ПолучитьФорму();
БазоваяФорма.Открыть();
КонецЕсли;
мПлатформа = ирКэш.Получить();
#Если _ Тогда
мПлатформа = Обработки.ирПлатформа.Создать();
#КонецЕсли
СтрокаВызова = "ирПортативный.ИнициализироватьФорму_" + мПлатформа.ПолучитьИдентификаторИзПредставления(ПолноеИмяФормы) + "(ЭтаФорма)";
Выполнить(СтрокаВызова);
Иначе
МетаФорма = Метаданные.НайтиПоПолномуИмени(ПолноеИмяФормы);
Если МетаФорма = Неопределено Тогда
Сообщить("Метаформа не найдена по полному имени """ + ПолноеИмяФормы + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция ПолучитьДопСвойстваФормыЛкс(ЭтаФорма)
СвойстваФормы = ЭтаФорма.Панель.Страницы[0].Значение;
Если СвойстваФормы = Неопределено Тогда
СвойстваФормы = Новый Структура();
ЭтаФорма.Панель.Страницы[0].Значение = СвойстваФормы;
КонецЕсли;
Возврат СвойстваФормы;
КонецФункции
Процедура ВстроитьКнопкиСтруктурыКоманднойПанелиЛкс(ЭтаФорма) Экспорт
мСвойстваФормы = ПолучитьДопСвойстваФормыЛкс(ЭтаФорма);
КнопкиВсехДействийКомандныхПанелей = Новый Соответствие;
ИмяКнопки = "СтруктураКоманднойПанели";
Для Каждого ЭлементФормы Из ЭтаФорма.ЭлементыФормы Цикл
КоманднаяПанель = Неопределено;
Если ТипЗнч(ЭлементФормы) = Тип("КоманднаяПанель") Тогда
КоманднаяПанель = ЭлементФормы;
Иначе
Попытка
//КоманднаяПанель = ЭлементФормы.КонтекстноеМеню; // В контекстных меню функция будет маловостребована, т.к. они имеют обычно более простую структуру и там сразу виден текст всех кнопок
Исключение
КонецПопытки;
КонецЕсли;
Если Истина
И КоманднаяПанель <> Неопределено
И КоманднаяПанель.Кнопки.Найти(ИмяКнопки) = Неопределено
Тогда
КоличествоКнопок = 0;
Для Каждого Кнопка Из КоманднаяПанель.Кнопки Цикл
Если Кнопка.ТипКнопки <> ТипКнопкиКоманднойПанели.Разделитель Тогда
КоличествоКнопок = КоличествоКнопок + 1;
КонецЕсли;
КонецЦикла;
Если КоличествоКнопок > 4 Тогда
КнопкаСтруктураКоманднойПанели = КоманднаяПанель.Кнопки.Вставить(0);
КнопкаСтруктураКоманднойПанели.Имя = ИмяКнопки;
КнопкаСтруктураКоманднойПанели.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаСтруктураКоманднойПанели.Картинка = ПолучитьОбщуюКартинкуЛкс("ирКоманднаяПанель");
КнопкаСтруктураКоманднойПанели.Отображение = ОтображениеКнопкиКоманднойПанели.Авто;
КнопкаСтруктураКоманднойПанели.Текст = "Структура командной панели";
КнопкаСтруктураКоманднойПанели.Подсказка = "Открыть структуру командной панели";
Попытка
КнопкаСтруктураКоманднойПанели.Действие = Новый Действие("СтруктураКоманднойПанелиНажатие");
Исключение
// В этой форме нет обработчика
Возврат;
КонецПопытки;
КнопкиВсехДействийКомандныхПанелей.Вставить(КнопкаСтруктураКоманднойПанели, КоманднаяПанель);
КонецЕсли;
КонецЕсли;
КонецЦикла;
мСвойстваФормы.Вставить("КнопкиВсехДействийКомандныхПанелей", КнопкиВсехДействийКомандныхПанелей);
КонецПроцедуры
Процедура ОткрытьСтруктуруКоманднойПанелиЛкс(ЭтаФорма, Знач Кнопка = Неопределено) Экспорт
мСвойстваФормы = ПолучитьДопСвойстваФормыЛкс(ЭтаФорма);
КоманднаяПанель = мСвойстваФормы.КнопкиВсехДействийКомандныхПанелей[Кнопка];
Если Кнопка <> Неопределено Тогда
Если КоманднаяПанель.Кнопки.Индекс(Кнопка) = -1 Тогда
// Для контекстных меню
КоманднаяПанель = КоманднаяПанель.Кнопки[0];
КонецЕсли;
КонецЕсли;
ФормаСтруктуры = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.СтруктураФормы");
ФормаСтруктуры.ПараметрЭлементФормы = КоманднаяПанель;
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
Процедура ОткрытьСтруктуруФормыЛкс(ЭтаФорма) Экспорт
ФормаСтруктуры = ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.СтруктураФормы");
ФормаСтруктуры.Форма = ЭтаФорма;
ФормаСтруктуры.ОткрытьМодально();
КонецПроцедуры
#КонецЕсли
Функция ЛиПустаяПодгруппаRegExpЛкс(Подгруппа) Экспорт
Результат = Ложь
Или Подгруппа = Неопределено
Или Подгруппа = "";
Возврат Результат;
КонецФункции
Процедура ОбновитьКопиюСвойстваВНижнемРегистреЛкс(Объект, ИмяСвойства = "Имя") Экспорт
Объект["Н" + ИмяСвойства] = НРег(Объект[ИмяСвойства]);
КонецПроцедуры
Функция ПолучитьСхемуКолонокМакетаКомпоновкиДанныхЛкс(МакетКомпоновки) Экспорт
#Если _ Тогда
МакетКомпоновки = Новый МакетКомпоновкиДанных;
#КонецЕсли
СхемаКолонок = Новый Структура;
// Схема колонок строится негарантировано, т.к. платформа не предоставляет нужных данных
ОписанияМакетовОбластей = МакетКомпоновки.Макеты;
Если ОписанияМакетовОбластей.Количество() > 0 Тогда
ЯчейкиЗаголовка = ОписанияМакетовОбластей[0].Макет.Ячейки;
Если ЯчейкиЗаголовка <> Неопределено Тогда
КоличествоЯчеекЗаголовка = ЯчейкиЗаголовка.Количество();
Для Индекс = 0 По КоличествоЯчеекЗаголовка - 1 Цикл
Для Каждого ОписаниеМакетаОбласти Из ОписанияМакетовОбластей Цикл
// Здесь подсказка криво работает из-за кривого синтакс-помощника 8.2.13.205
// http://partners.v8.1c.ru/forum/thread.jsp?id=898023#898023
ЯчейкаМакетаОбласти = ОписаниеМакетаОбласти.Макет.Ячейки[Индекс];
Если ТипЗнч(ЯчейкаМакетаОбласти) <> Тип("ЯчейкаМакетаКоллекцииЗначенийОбластиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
ПараметрЯчейки = ЯчейкаМакетаОбласти.Значение;
Если ПараметрЯчейки = Неопределено Тогда
Продолжить;
КонецЕсли;
Выражение = ОписаниеМакетаОбласти.Параметры["" + ПараметрЯчейки].Выражение;
ПозицияТочки = Найти(Выражение, ".");
Если Ложь
Или ПозицияТочки = 0
Или Найти(Выражение, " ") > 0
Или Найти(Выражение, "(") > 0
Тогда
//ИмяПоля = "";
Продолжить;
Иначе
ИмяПоля = Сред(Выражение, ПозицияТочки + 1);
КонецЕсли;
СхемаКолонок.Вставить(ЯчейкиЗаголовка[Индекс].Имя, ИмяПоля);
Прервать;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Возврат СхемаКолонок;
КонецФункции
Функция ПолучитьТекущуюДатуЛкс(НаСервере = Ложь) Экспорт
Если НаСервере Тогда
Результат = ирСервер.ПолучитьТекущуюДатуЛкс();
Иначе
Результат = ТекущаяДата();
КонецЕсли;
Возврат Результат;
КонецФункции
Функция СтрокиРавныЛкс(Знач Строка1, Знач Строка2, СУчетомРегистра = Ложь, БезПравыхНепечатныхСимволов = Ложь) Экспорт
Если Не СУчетомРегистра Тогда
Строка1 = НРег(Строка1);
Строка2 = НРег(Строка2);
КонецЕсли;
Если БезПравыхНепечатныхСимволов Тогда
Строка1 = СокрП(Строка1);
Строка2 = СокрП(Строка2);
КонецЕсли;
Результат = Строка1 = Строка2;
Возврат Результат;
КонецФункции
// Поиск числа в строке
//
// Параметры:
// ИсходнаяСтрока - Строка, строка в которой ищется число
// ПозицияЧисла - Число, позиция начала числа
// КоличествоСимволов - Число, количество символов числа
//
// Возвращаемое значение:
// Булево - Истина, число найдено
//
Функция НайтиЧислоВСтрокеЛкс(ИсходнаяСтрока, ПозицияЧисла, КоличествоСимволов) Экспорт
ПозицияЧисла = 0;
КоличествоСимволов = 0;
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
Для Сч = 1 По ДлинаСтроки Цикл
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
Если ПозицияЧисла = 0 Тогда
ПозицияЧисла = Сч;
КоличествоСимволов = 1;
Иначе
КоличествоСимволов = КоличествоСимволов + 1;
КонецЕсли;
Иначе
Если ПозицияЧисла <> 0 Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат ПозицияЧисла > 0;
КонецФункции // НайтиЧислоВСтроке()
Процедура ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, НаСервере = Ложь, ВыводитьПредупрежденияИСообщения = Истина) Экспорт
#Если Клиент Тогда
Если ВыводитьПредупрежденияИСообщения Тогда
Ответ = КодВозвратаДиалога.ОК;
Если НаСервере Тогда
ОбщийРазмер = ирСервер.ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
Иначе
ОбщийРазмер = ВычислитьРазмерКаталогаЛкс(КаталогЖурнала);
КонецЕсли;
Если ОбщийРазмер > 0 Тогда
Ответ = Вопрос("Действительно удалить рекурсивно все файлы (" + Формат(Цел(ОбщийРазмер/1000000), "ЧН=") + "МБ) в каталоге журнала?", РежимДиалогаВопрос.ОКОтмена);
КонецЕсли;
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Если НаСервере Тогда
ирСервер.ОчиститьКаталогТехножурналаЛкс(КаталогЖурнала, ВыводитьПредупрежденияИСообщения);
Возврат;
КонецЕсли;
#КонецЕсли
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.*", Истина);
Если ФайлыЖурнала.Количество() > 0 Тогда
СчетчикНеудаленных = 0;
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
Попытка
УдалитьФайлы(ФайлЖурнала.ПолноеИмя);
Исключение
СчетчикНеудаленных = СчетчикНеудаленных + 1;
КонецПопытки;
КонецЦикла;
Если ВыводитьПредупрежденияИСообщения Тогда
Если СчетчикНеудаленных > 0 Тогда
Сообщить("" + СчетчикНеудаленных + " файлов техножурнала удалить не удалось");
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ОчиститьКаталогТехножурналаЛкс()
Функция ВычислитьРазмерКаталогаЛкс(Каталог, ВключаяПодкаталоги = Истина) Экспорт
Файлы = НайтиФайлы(Каталог, "*.*", ВключаяПодкаталоги);
ОбщийРазмер = 0;
Для Каждого Файл Из Файлы Цикл
Если Файл.ЭтоКаталог() Тогда
Продолжить;
КонецЕсли;
ОбщийРазмер = ОбщийРазмер + Файл.Размер();
КонецЦикла;
Возврат ОбщийРазмер;
КонецФункции
Процедура УстановитьПометкиРодителейЛкс(Знач Родитель, Знач ИмяДанныхФлажка = "Пометка") Экспорт
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ТекСостояние = Родитель[ИмяДанныхФлажка];
НайденыВключенные = Ложь;
НайденыВыключенные = Ложь;
Для каждого Строка из Родитель.Строки Цикл
ЗначениеФлажка = Строка[ИмяДанныхФлажка];
Если ЗначениеФлажка = 0 Тогда
НайденыВыключенные = Истина;
ИначеЕсли ЗначениеФлажка = 1 Тогда
НайденыВключенные = Истина;
ИначеЕсли ЗначениеФлажка = 2 Тогда
НайденыВключенные = Истина;
НайденыВыключенные = Истина;
Прервать;
КонецЕсли;
Если НайденыВключенные И НайденыВыключенные Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если НайденыВключенные И НайденыВыключенные Тогда
Включить = 2;
ИначеЕсли НайденыВключенные И (Не НайденыВыключенные) Тогда
Включить = 1;
ИначеЕсли (Не НайденыВключенные) И НайденыВыключенные Тогда
Включить = 0;
ИначеЕсли (Не НайденыВключенные) И (Не НайденыВыключенные) Тогда
Включить = 2;
КонецЕсли;
Если Включить = ТекСостояние Тогда
Возврат;
Иначе
Родитель[ИмяДанныхФлажка] = Включить;
УстановитьПометкиРодителейЛкс(Родитель.Родитель, ИмяДанныхФлажка);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьПометкиПодчиненныхЛкс(Знач ТекСтрока, Знач ИмяДанныхФлажка = "Пометка") Экспорт
ТекСостояние = ТекСтрока[ИмяДанныхФлажка];
Подчиненные = ТекСтрока.Строки;
Если ТекСостояние = 2 Тогда
ТекСтрока[ИмяДанныхФлажка] = 0;
КонецЕсли;
Если Подчиненные.Количество() > 0 Тогда
Для каждого Строка из Подчиненные Цикл
Строка[ИмяДанныхФлажка] = ТекСостояние;
УстановитьПометкиПодчиненныхЛкс(Строка, ИмяДанныхФлажка);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Разбирает строку на две части: до подстроки разделителя и после
//
// Параметры:
// Стр - разбираемая строка
// Разделитель - подстрока-разделитель
// Режим - 0 - разделитель в возвращаемые подстроки не включается
// 1 - разделитель включается в левую подстроку
// 2 - разделитель включается в правую подстроку
//
// Возвращаемое значение:
// Правая часть строки - до символа-разделителя
//
Функция ОтделитьРазделителемЛкс(Знач Стр, Знач Разделитель = ".", Режим = 0) Экспорт
ПраваяЧасть = "";
ПозРазделителя = Найти(Стр, Разделитель);
ДлинаРазделителя = СтрДлина(Разделитель);
Если ПозРазделителя > 0 Тогда
ПраваяЧасть = Сред(Стр, ПозРазделителя + ?(Режим=2, 0, ДлинаРазделителя));
Стр = СокрЛП(Лев(Стр, ПозРазделителя - ?(Режим=1, -ДлинаРазделителя+1, 1)));
КонецЕсли;
Возврат(ПраваяЧасть);
КонецФункции // вОтделитьРазделителем()
// Проверяет попадание даты внутрь интервала всключая границы
Функция ЛиДатаВИнтервалеСГраницамиЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И ЗначениеЗаполнено(НачалоПериода)
И ПроверяемаяДата < НачалоПериода)
Или (Истина
И ЗначениеЗаполнено(КонецПериода)
И ПроверяемаяДата > КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
// Проверяет попадание даты внутрь интервала исключая границы
Функция ЛиДатаВИнтервалеБезГраницЛкс(ПроверяемаяДата, НачалоПериода, КонецПериода) Экспорт
ПустаяДата = Дата("00010101");
ЛиДатаВНеИнтервале = Ложь
Или (Истина
И НачалоПериода <> ПустаяДата
И ПроверяемаяДата <= НачалоПериода)
Или (Истина
И КонецПериода <> ПустаяДата
И ПроверяемаяДата >= КонецПериода);
Возврат Не ЛиДатаВНеИнтервале;
КонецФункции
Функция ЛиКаталогДоступенЛкс(Каталог, ВыводитьСообщения = Истина) Экспорт
ПроверочныйФайл = Новый Файл(Каталог);
Попытка
ЭтоКаталог = ПроверочныйФайл.ЭтоКаталог();
Исключение
Если ВыводитьСообщения Тогда
Сообщить("Указанный путь """ + Каталог + """ не доступен: " + ОписаниеОшибки());
КонецЕсли;
Возврат Ложь;
КонецПопытки;
Если Не ЭтоКаталог Тогда
Если ВыводитьСообщения Тогда
Сообщить("Указанный путь """ + Каталог + """ не является каталогом");
КонецЕсли;
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции // ЛиКаталогДоступен()
Функция ПолучитьСтрокуФильтраДляВыбораФайлаЛкс(Расширение, ОписаниеФормата = "", РазрешитьВсеФайлы = Истина) Экспорт
Результат = "(*." + Расширение + ")|*." + Расширение;
Если ЗначениеЗаполнено(ОписаниеФормата) Тогда
Результат = ОписаниеФормата + " " + Результат;
КонецЕсли;
Если РазрешитьВсеФайлы Тогда
Результат = Результат + "|Все файлы (*.*)|*.*";
КонецЕсли;
Возврат Результат;
КонецФункции
// Копирует все элементы переданного массива, структуры, соответствия, списка значений или коллекции объектов метаданных
// в однотипную коллекцию приемник (для метаданных в массив). Если коллекция приемник не указана, она будет создана.
// Фиксированные коллекции превращаются в нефиксированные.
//
// Параметры:
// КоллекцияИсходная - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - исходная коллекция;
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных, *Неопределено - коллекция приемник.
//
// Возвращаемое значение:
// КоллекцияПриемник - Массив, Структура, Соответствие, СписокЗначений, КоллекцияОбъектовМетаданных - коллекция приемник.
//
Функция СкопироватьУниверсальнуюКоллекциюЛкс(КоллекцияИсточник, КоллекцияПриемник = Неопределено) Экспорт
ТипКоллекции = ТипЗнч(КоллекцияИсточник);
Если Ложь
Или ТипКоллекции = Тип("Массив")
Или ТипКоллекции = Тип("ФиксированныйМассив")
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
Или ТипКоллекции = Тип("КоллекцияОбъектовМетаданных")
#КонецЕсли
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Массив;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Добавить(Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Структура")
Или ТипКоллекции = Тип("ФиксированнаяСтруктура")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Структура;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли Ложь
Или ТипКоллекции = Тип("Соответствие")
Или ТипКоллекции = Тип("ФиксированноеСоответствие")
Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый Соответствие;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
КоллекцияПриемник.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;
Возврат КоллекцияПриемник;
ИначеЕсли ТипКоллекции = Тип("СписокЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = Новый СписокЗначений;
КонецЕсли;
Для Каждого Элемент Из КоллекцияИсточник Цикл
ЗаполнитьЗначенияСвойств(КоллекцияПриемник.Добавить(), Элемент);
КонецЦикла;
Возврат КоллекцияПриемник;
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
ИначеЕсли ТипКоллекции = Тип("ТаблицаЗначений") Тогда
Если КоллекцияПриемник = Неопределено Тогда
КоллекцияПриемник = КоллекцияИсточник.СкопироватьКолонки();
КонецЕсли;
ЗагрузитьВТаблицуЗначенийЛкс(КоллекцияИсточник, КоллекцияПриемник);
Возврат КоллекцияПриемник;
#КонецЕсли
Иначе
Сообщить("Неверный тип универсальной коллекции для копирования """ + ТипКоллекции + """");
Возврат Неопределено;
КонецЕсли;
КонецФункции // СкопироватьУниверсальнуюКоллекциюЛкс()
////////////////////////////////////////////////////////////////////////////////
// ОТЛАДКА
#Если Не ТонкийКлиент И Не ВебКлиент Тогда
// Присваивает первому параметру второй.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
//
// Параметры:
// П1 Произвольный параметр1;
// П2 Произвольный параметр2;
//
// Возвращаемое значение:
// П2 Не используется.
//
Функция ПрЛкс(п1, п2 = Неопределено) Экспорт
п1 = п2;
Возврат п1;
КонецФункции // Присвоить()
// Выполняет программный код, переданный как параметр.
// Остальные Параметры могут участвовать в теле этого кода.
// Удобно использовать в отладчике.
//
// Параметры:
// П1 Произвольный параметр1;
// П2 Произвольный параметр2;
// П3 Произвольный параметр3;
// П4 Произвольный параметр4;
//
// Возвращаемое значение:
// Неопределено Не используется.
//
Функция ДуЛкс(Знач ТекстПрограммы, п1 = 0, п2 = 0, п3 = 0, п4 = 0) Экспорт
Перем Р;
Попытка
Выполнить(ТекстПрограммы);
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;
Возврат Р;
КонецФункции // Ду()
// На клиенте открывает консоль кода с передачей туда всех своих параметров. На сервере сразу выполняет код.
// Изменения параметров возвращаются в вызывающий контекст в модальном режиме.
//
// Параметры:
// ТекстПрограммы - Строка - программный код для передачи в консоль кода или выполнения;
// РежимОперации Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
// СтрокаИменПараметров Строка - имена параметров для консоли кода через запятую, если не указаны, то будут оригинальные П*;
// П* Произвольный - параметры для использования при выполнении программного кода;
//
// Возвращаемое значение:
// Строка - описание ошибок.
//
Функция ОперироватьЛкс(Знач ТекстПрограммы = "", Знач РежимОперации = 0, СтрокаИменПараметров= "",
П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
#Если Сервер И Не Клиент Тогда
РежимОперации = 2;
#КонецЕсли
МассивИмен = ПолучитьМассивИзСтрокиСРазделителемЛкс(СтрокаИменПараметров, ",", Истина);
Если МассивИмен.Количество() > 0 Тогда
Если МассивИмен[0] = "" Тогда
МассивИмен.Удалить(0);
КонецЕсли;
КонецЕсли;
ЧислоПараметров = 9;
ПереданныеПараметры = Новый СписокЗначений;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
ЗначениеПараметра = Вычислить(ИмяПараметра);
Если Ложь
Или ЗначениеПараметра <> Null // Опасный трюк в интерактивном режиме. Отрезает параметры, переданные, но имеющие значение Null.
Или РежимОперации = 2
Тогда
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ПереданныеПараметры.Добавить(ЗначениеПараметра, ПсевдонимПараметра);
КонецЕсли;
КонецЦикла;
Если РежимОперации < 2 Тогда
#Если Клиент Тогда
ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма", , , Новый УникальныйИдентификатор);
ФормаОтладки.мСписокВнешнихПараметров = ПереданныеПараметры;
ФормаОтладки.Текст = ТекстПрограммы;
Если РежимОперации = 0 Тогда
ФормаОтладки.Открыть();
Возврат Неопределено;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
#КонецЕсли
Иначе
ТекстПрограммы = ТекстПрограммы + ";";
Для Индекс = 0 По ПереданныеПараметры.Количество() - 1 Цикл
ВнешнийПараметр = ПереданныеПараметры[Индекс];
ТекстПрограммы = ВнешнийПараметр.Представление + "=" + "_АлгоритмОбъект[" + Индекс + "].Значение;" + Символы.ПС + ТекстПрограммы;
ТекстПрограммы = ТекстПрограммы + Символы.ПС + "_АлгоритмОбъект[" + Индекс + "].Значение = " + ВнешнийПараметр.Представление + ";";
КонецЦикла;
ВыполнитьАлгоритм(ТекстПрограммы, ПереданныеПараметры);
ПолученныеПараметры = ПереданныеПараметры;
КонецЕсли;
ОписаниеОшибок = "";
НовоеЗначение = Неопределено;
Для Счетчик = 1 По ЧислоПараметров Цикл
ИмяПараметра = "П" + Счетчик;
НовоеЗначение = Неопределено;
Если ПолученныеПараметры.Количество() > Счетчик - 1 Тогда
НовоеЗначение = ПолученныеПараметры[Счетчик - 1].Значение;
КонецЕсли;
Если Вычислить(ИмяПараметра) <> НовоеЗначение Тогда
Попытка
Выполнить(ИмяПараметра + " = НовоеЗначение");
Исключение
ПсевдонимПараметра = ИмяПараметра;
Если МассивИмен.Количество() > Счетчик - 1 Тогда
ПсевдонимПараметра = МассивИмен[Счетчик - 1];
КонецЕсли;
ОписаниеОшибки = "Ошибка возвращения параметра " + ПсевдонимПараметра + ": " + ОписаниеОшибки();
ОписаниеОшибок = ОписаниеОшибок + ОписаниеОшибки;
Сообщить(ОписаниеОшибки);
КонецПопытки;
КонецЕсли;
КонецЦикла;
Возврат ОписаниеОшибок;
КонецФункции // РП()
// Подготавливает строку для помещения всех переменных в структуру с целью ее дальнейшего вычисления в отладчике "Вычислить(Пер())".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для анализа, берется из буфера обмена если пустой.
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция ПерЛкс(Знач ТекстПрограммы = "") Экспорт
Параметры = ПолучитьПеременныеТекстаВстроенногоЯзыкаЛкс(ТекстПрограммы);
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Новый Структура(""" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Функция получает таблицу значений из указанной временной таблицы из менеджера временных таблиц,
// либо структуру из всех входящих в запрос временных таблиц.
// Используется для просмотра временных таблиц серверного менеджера временных таблиц в отладчике.
// Параметры:
// ЗапросИлиМенеджерВременныхТаблиц - Запрос, МенеджерВременныхТаблиц
// ИменаВременныхТаблиц - Строка, *"" - имена существующих, но возможно не используемых в тексте запроса временных таблиц через запятую
// ДопустимоеЧислоСтрок - Число, *500000 - выбирать из временной таблицы не более этого числа строк
//
// Результат - ТаблицаЗначений, Структура
//
Функция ПолВТЛкс(ЗапросИлиМенеджерВременныхТаблиц, Знач ИменаВременныхТаблиц = "", ДопустимоеЧислоСтрок = 500000) Экспорт
Результат = Новый Структура();
Запрос = Новый Запрос;
Если ТипЗнч(ЗапросИлиМенеджерВременныхТаблиц) = Тип("Запрос") Тогда
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц.МенеджерВременныхТаблиц;
Иначе
Запрос.МенеджерВременныхТаблиц = ЗапросИлиМенеджерВременныхТаблиц;
КонецЕсли;
ТекстЗапроса = "
|ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(ДопустимоеЧислоСтрок) + "
| *
|ИЗ
| ИмяВременнойТаблицы
|";
Платформа = ирКэш.Получить();
МассивИмен = ПолучитьМассивИзСтрокиСРазделителемЛкс(ИменаВременныхТаблиц, ",", Истина, Ложь);
ИменаИспользуемыхВременныхТаблиц = Платформа.НайтиВозможныеИменаВременныхТаблиц(ЗапросИлиМенеджерВременныхТаблиц.Текст);
Для Каждого ИмяИспользуемойВременнойТаблицы Из ИменаИспользуемыхВременныхТаблиц Цикл
МассивИмен.Добавить(ИмяИспользуемойВременнойТаблицы);
КонецЦикла;
Для Каждого ИмяВременнойТаблицы Из МассивИмен Цикл
Если Результат.Свойство(ИмяВременнойТаблицы) Тогда
Продолжить;
КонецЕсли;
Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяВременнойТаблицы", ИмяВременнойТаблицы);
Попытка
РезультатЗапроса = Запрос.Выполнить();
Исключение
Продолжить;
КонецПопытки;
Результат.Вставить(ИмяВременнойТаблицы, РезультатЗапроса.Выгрузить());
КонецЦикла;
Возврат Результат;
КонецФункции // ПолВТ()
// Начать трассу в технологическом журнале. Сам технологический журнал надо заранее включить.
Функция ТехНЛкс() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.НачатьТрассу("Отладчик") Тогда
Возврат "Трасса техножурнала начата";
Иначе
Возврат "Техножурнал не включен. Невозможно начать трассу.";
КонецЕсли;
КонецФункции
#Если Клиент Тогда
// Кончить трассу в технологическом журнале и показать ее анализ
Функция ТехКЛкс() Экспорт
АнализТехножурнала = ирКэш.ПолучитьАнализТехножурналаЛкс();
Если АнализТехножурнала.КончитьТрассу() Тогда
//АнализТехножурнала.ПоказатьТрассу();
Возврат "Трасса техножурнала кончена. Для ее анализа откройте в режиме предприятия ""Анализ техножурнала""";
Иначе
Возврат "Трасса техножурнала не была начата ранее.";
КонецЕсли;
КонецФункции
// Подготавливает строку для вызова Оперировать() в отладчике. Вызвается путем вычисления "Вычислить(Поп())".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка, *"" - программный код для передачи в консоль кода или выполнения, берется из буфера обмена если пустой;
// РежимОперации Число - 0 - немодально, 1 - модально, 2 - неинтерактивно (на сервере всегда);
//
// Возвращаемое значение:
// Строка для вычисления в отладчике.
//
Функция ПопЛкс(Знач ТекстПрограммы = "", РежимОперации = 1) Экспорт
Если ПустаяСтрока(ТекстПрограммы) Тогда
ТекстПрограммы = ПолучитьТекстИзБуфераОбменаОСЛкс();
КонецЕсли;
Параметры = Новый Структура();
ПолеВстроенногоЯзыка = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой");
#Если _ Тогда
ПолеВстроенногоЯзыка = Обработки.ирКлсПолеТекстовогоДокументаСКонтекстнойПодсказкой.Создать();
#КонецЕсли
ПолеВстроенногоЯзыка.ИнициализироватьНеинтерактивно();
Пока Истина Цикл
ИнформацияОбОшибке = ПолеВстроенногоЯзыка.ПолучитьИнформациюОбОшибке(ТекстПрограммы);
Если ИнформацияОбОшибке = Неопределено Тогда
Прервать;
КонецЕсли;
НеопределеннаяПеременная = ирКэш.Получить().ПолучитьИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке);
Если Не ЗначениеЗаполнено(НеопределеннаяПеременная) Тогда
Возврат ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
Если Не Параметры.Свойство(НеопределеннаяПеременная) Тогда
Параметры.Вставить(НеопределеннаяПеременная);
ПолеВстроенногоЯзыка.ДобавитьСловоЛокальногоКонтекста(НеопределеннаяПеременная);
КонецЕсли;
КонецЦикла;
СтрокаИменПараметров = "";
Для Каждого КлючИЗначение Из Параметры Цикл
Если СтрокаИменПараметров <> "" Тогда
СтрокаИменПараметров = СтрокаИменПараметров + ", ";
КонецЕсли;
СтрокаИменПараметров = СтрокаИменПараметров + КлючИЗначение.Ключ;
КонецЦикла;
НовыйТекст = ПолучитьСтроковыйЛитералИзМногострочногоТекстаЛкс(ТекстПрограммы);
СтрокаРезультата = "Оперировать(" + НовыйТекст + ", " + РежимОперации + ", " + """" + СтрокаИменПараметров + """, " + СтрокаИменПараметров + ")";
Возврат СтрокаРезультата;
КонецФункции
// Обертка Оперировать. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в вызывающий контекст.
//
// Параметры:
// П* Произвольный;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОпЛкс(П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null) Экспорт
Возврат ОперироватьЛкс(, Истина, , П1, П2, П3, П4, П5);
КонецФункции // Оп()
// Открывает консоль кода с передачей туда структуры параметров.
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// ТекстПрограммы - Строка;
// Модально Булево - открывать окно модально;
// СтруктураПараметров Структура - ключи соответсвуют именам параметов, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОперироватьСтруктуройЛкс(Знач ТекстПрограммы = "", Модально = Ложь, СтруктураПараметров = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольКода) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
Если Истина
И ПустаяСтрока(ТекстПрограммы)
И СтруктураПараметров <> Неопределено
И СтруктураПараметров.Количество() = 1
Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ТекстПрограммы = КлючИЗначение.Ключ;
КонецЦикла;
КонецЕсли;
ФормаОтладки = ПолучитьФормуЛкс("Обработка.ирКонсольКода.Форма",,, Новый УникальныйИдентификатор);
//ФормаОтладки.мСписокВнешнихПараметров = СкопироватьУниверсальнуюКоллекциюЛкс(СтруктураПараметров);
ПередаваемыеПараметры = Новый СписокЗначений;
Если СтруктураПараметров <> Неопределено Тогда
Для Каждого КлючИЗначение Из СтруктураПараметров Цикл
ПередаваемыеПараметры.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ);
КонецЦикла;
ФормаОтладки.мСписокВнешнихПараметров = ПередаваемыеПараметры;
КонецЕсли;
ФормаОтладки.Текст = ТекстПрограммы;
Если Не Модально Тогда
ФормаОтладки.Открыть();
Возврат ФормаОтладки;
КонецЕсли;
ПолученныеПараметры = ФормаОтладки.ОткрытьМодально();
Если ПолученныеПараметры = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если СтруктураПараметров <> Неопределено Тогда
//ЗаполнитьЗначенияСвойств(СтруктураПараметров, ПолученныеПараметры);
Для Каждого ПолученныйПараметр Из ПолученныеПараметры Цикл
СтруктураПараметров.Вставить(ПолученныйПараметр.Представление, ПолученныйПараметр.Значение);
КонецЦикла;
КонецЕсли;
Возврат Неопределено;
КонецФункции // РП()
// Обертка ОперироватьСтруктурой. Модально открывает консоль кода с передачей туда всех своих параметров.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
// Изменения параметров возвращаются в структуру, но не в вызывающий контекст.
//
// Параметры:
// СтруктураПараметров Структура - ключи соответсвуют именам параметов, а значения их значениям.
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОпсЛкс(СтруктураПараметров) Экспорт
Возврат ОперироватьСтруктуройЛкс(, Истина, СтруктураПараметров);
КонецФункции // Опс()
// Выводит в окно сообщений переданное значение вместе с типом и заданным представлением.
//
// Параметры:
// Значение - Произвольный;
// *Представление Строка, *"" - представление наблюдаемого значения.
//
Процедура НаблюдатьЛкс(Значение, Представление = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат;
КонецЕсли;
КонецЕсли;
Строка = Представление + " = " + "<" + ТипЗнч(Значение) + ">" + "[" + Значение + "]";
Сообщить(Строка);
КонецПроцедуры // Наблюдать()
#КонецЕсли
Процедура ЗаблокироватьНаборЗаписейПоОтборуЛкс(НаборЗаписей, НичегоНеДелатьБезТранзакции = Ложь) Экспорт
Если НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна() Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = НаборЗаписей.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ТипТаблицы = ПолучитьПервыйФрагментЛкс(ПространствоБлокировок);
Если Ложь
Или Не ЛиКорневойТипРегистраСведенийЛкс(ТипТаблицы)
Или ОбъектМД.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору
Тогда
ПространствоБлокировок = ПространствоБлокировок + ".НаборЗаписей";
КонецЕсли;
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ЭлементБлокировки.УстановитьЗначение(ЭлементОтбора.Имя, ЭлементОтбора.Значение);
КонецЕсли;
КонецЦикла;
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьСсылкуВТранзакцииЛкс(СсылочныйОбъект, НичегоНеДелатьБезТранзакции = Ложь) Экспорт
Если НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна() Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = СсылочныйОбъект.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
ЭлементБлокировки.УстановитьЗначение("Ссылка", СсылочныйОбъект.Ссылка);
Блокировка.Заблокировать();
КонецПроцедуры
Процедура ЗаблокироватьКонстантуЛкс(КонстантаМенеджерЗначения, НичегоНеДелатьБезТранзакции = Ложь) Экспорт
Если НичегоНеДелатьБезТранзакции И Не ТранзакцияАктивна() Тогда
Возврат;
КонецЕсли;
Блокировка = Новый БлокировкаДанных;
ОбъектМД = КонстантаМенеджерЗначения.Метаданные();
ПространствоБлокировок = ОбъектМД.ПолноеИмя();
ЭлементБлокировки = Блокировка.Добавить(ПространствоБлокировок);
Блокировка.Заблокировать();
КонецПроцедуры
Функция ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиИменаБД = Ложь, ЭтоТабличнаяЧасть = Ложь, ИспользоватьИмяПоляВместоПустогоПредставления = Ложь) Экспорт
ПредставлениеПоля = СтрокаПоля.ИмяПоля;
Если ПустаяСтрока(ПредставлениеПоля) Тогда
Если ЛиИменаБД Тогда
// Антибаг платформы. У некоторых полей почему то пустое имя, а должно быть непустое. https://partners.v8.1c.ru/forum/topic/1275356#m_1275356
Если ЭтоТабличнаяЧасть Тогда
Если ирОбщий.СтрокиРавныЛкс(СтрокаПоля.ИмяПоляХранения, "_KeyField") Тогда
ПредставлениеПоля = "НомерСтроки";
ИначеЕсли Найти(СтрокаПоля.ИмяПоляХранения, "IDRRef") > 0 Тогда
ПредставлениеПоля = "Ссылка";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(ПредставлениеПоля) Тогда
Если ЛиИменаБД Тогда
НИмяПоляХранения = НРег(СтрокаПоля.ИмяПоляХранения);
НМаркерПоляТипаЗначения = НРег("TYPE");
НМаркерПоляТипаСсылки = НРег("TRef");
//МаркерПоляЗначенияСсылки = НРег("RRef");
Если Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаСсылки)) = НМаркерПоляТипаСсылки Тогда
ПредставлениеПоля = ПредставлениеПоля + "_ТипСсылки";
ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляТипаЗначения)) = НМаркерПоляТипаЗначения Тогда
ПредставлениеПоля = ПредставлениеПоля + "_ТипЗначения";
//ИначеЕсли Прав(НИмяПоляХранения, СтрДлина(НМаркерПоляЗначенияСсылки)) = НМаркерПоляЗначенияСсылки Тогда
// ПредставлениеПоля = ПредставлениеПоля + "_Ссылка";
КонецЕсли;
КонецЕсли;
ИначеЕсли ИспользоватьИмяПоляВместоПустогоПредставления Тогда
ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения;
КонецЕсли;
Возврат ПредставлениеПоля;
КонецФункции
Функция ПолучитьПредставлениеСтруктурыЛкс(Структура) Экспорт
#Если _ Тогда
Структура = Новый Структура;
#КонецЕсли
ПредставлениеСтруктуры = "";
Для Каждого КлючИЗначение Из Структура Цикл
Если ПредставлениеСтруктуры <> "" Тогда
ПредставлениеСтруктуры = ПредставлениеСтруктуры + ", ";
КонецЕсли;
ПредставлениеСтруктуры = ПредставлениеСтруктуры + КлючИЗначение.Ключ + " = " + КлючИЗначение.Значение;
КонецЦикла;
Возврат ПредставлениеСтруктуры;
КонецФункции
Функция ПолучитьПредставлениеИндексаХраненияЛкс(СтрокаИндексаСтруктурыБД, ЛиСтруктураДанныхВИменахБД = Ложь, СтрокаТаблицыХранения, ЛиПредставлениеВИменахБД = Ложь) Экспорт
ЭтоТабличнаяЧасть = СтрокаТаблицыХранения.Назначение = "ТабличнаяЧасть";
ПредставлениеИндекса = "";
Разделитель = "";
Для каждого СтрокаПоля Из СтрокаИндексаСтруктурыБД.Поля Цикл
Если ЛиПредставлениеВИменахБД Тогда
ПредставлениеПоля = СтрокаПоля.ИмяПоляХранения;
Иначе
ПредставлениеПоля = ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ЛиСтруктураДанныхВИменахБД, ЭтоТабличнаяЧасть, Истина);
КонецЕсли;
ПредставлениеИндекса = ПредставлениеИндекса + Разделитель + ПредставлениеПоля;
Разделитель = ", ";
КонецЦикла;
Возврат ПредставлениеИндекса;
КонецФункции
Функция ПолучитьСовместимоеЗначениеПараметраЛкс(Знач ЗначениеПараметра, ИмяПараметра, ОписаниеТиповЭлементаУправленияПараметра = Неопределено) Экспорт
Результат = ЗначениеПараметра;
ТипЗначенияПараметра = ТипЗнч(Результат);
Если Истина
И ТипЗначенияПараметра = Тип("Массив")
И ОписаниеТиповЭлементаУправленияПараметра <> Неопределено
Тогда
СписокЗначений = Новый СписокЗначений;
ПреобразованиеУспешно = Истина;
Для Каждого ЭлементМассива Из ЗначениеПараметра Цикл
Если ОписаниеТиповЭлементаУправленияПараметра.СодержитТип(ТипЗнч(ЭлементМассива)) Тогда
СписокЗначений.Добавить(ЭлементМассива);
Иначе
ПреобразованиеУспешно = Ложь;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПреобразованиеУспешно Тогда
Результат = СписокЗначений;
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из массива в список значений", СтатусСообщения.Внимание);
КонецЕсли;
Иначе
МетаданныеТипаЗначения = Метаданные.НайтиПоТипу(ТипЗначенияПараметра);
Если МетаданныеТипаЗначения <> Неопределено Тогда
ТипТаблицы = ПолучитьТипТаблицыБДЛкс(МетаданныеТипаЗначения.ПолноеИмя());
Если ЛиТипВложеннойТаблицыБДЛкс(ТипТаблицы) Тогда
Результат = ЗначениеПараметра.Выгрузить();
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано из табличной части в таблицу значений", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
Если ОписаниеТиповЭлементаУправленияПараметра <> Неопределено Тогда
#Если _ Тогда
ОписаниеТиповЭлементаУправленияПараметра = Новый ОписаниеТипов;
#КонецЕсли
Результат = ОписаниеТиповЭлементаУправленияПараметра.ПривестиЗначение(ЗначениеПараметра);
Если Результат <> ЗначениеПараметра Тогда
Сообщить("Значение параметра """ + ИмяПараметра + """ было преобразовано """ + ЗначениеПараметра + """->""" + Результат + """", СтатусСообщения.Внимание);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Открывает нужную консоль для редактирования сложного объекта.
// Варианты использования в зависимости от типа параметра Объект:
// Запрос, COMОбъект - открывает Запрос или ADODB.Command или ADODB.Connection в консоли запросов
// ПостроительЗапроса - открывает результирующий запрос построителя запросов в консоли запросов
// ПостроительОтчета - открывает построитель отчета в консоли построителей отчетов, откуда можно открыть результирующий запрос построителя отчета в консоли запросов
// СхемаКомпоновки - открывает схему компоновки в консоли компоновки данных, откуда можно открыть результирующие (из макета компоновки) запросы в консоли запросов
//
// Параметры:
// Объект Запрос, ПостроительЗапроса, ПостроительОтчета, СхемаКомпоновкиДанных, COMОбъект.ADODB.Command - исследуемый объект;
// Модально Булево - открывать окно модально, должно быть Истина для использования функции в отладчике;
// НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц - НастройкиКомпоновкиДанных, Строка, *Неопределено -
// если первый параметр СхемаКомпоновкиДанных, то настройки компоновки,
// если первый параметр WMI или ADODB.Connection, то текст запроса,
// если первый параметр Запрос, имена временных таблиц разделенных запятыми;
// ВнешниеНаборыДанных - Структура, *Неопределено - внешние наборы данных для схемы компоновки;
// ОтложеннаяОтладка - Булево - на сервере игнорируется (равно Истина), вместо открытия инструмента отладки сразу выполняется помещение
// объектов отладки во временное хранилище;
// ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки - Число, *500000 - допустимое количество строк во всех временных таблицах запроса
// для отложенной отладки, больше этого количества строки не сохраняются, о чем сообщается в результате;
// Наименование - Строка - наименование сохраняемого объекта отложенной отладки;
//
// Возвращаемое значение:
// Неопределено.
//
Функция ОтладитьЛкс(Объект, Модально = Ложь, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, ВнешниеНаборыДанных = Неопределено,
ОтложенноеВыполнение = Ложь, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки = 500000, выхОбъектДляОтладки = Неопределено, Наименование = "") Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирКонсольЗапросов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
Если ТипЗнч(Модально) <> Тип("Булево") Тогда
ВызватьИсключение "Неправильный тип второго параметра (Модально) метода Отладить. Должен быть Булево";
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
Если Ложь
Или ТипЗнч(Объект) = Тип("Запрос")
Или ТипЗнч(Объект) = Тип("COMОбъект")
Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если _ Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект, , , Модально, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если _ Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьДляОтладки(Объект.ПолучитьЗапрос(), , , Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
КонсольЗапросов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов");
#Если _ Тогда
КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать();
#КонецЕсли
Результат = КонсольЗапросов.ОткрытьПоМакетуКомпоновки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
КонсольПостроителейОтчетов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКонсольПостроителейОтчетов");
#Если _ Тогда
КонсольПостроителейОтчетов = Обработки.ирКонсольПостроителейОтчетов.Создать();
#КонецЕсли
Результат = КонсольПостроителейОтчетов.ОткрытьДляОтладки(Объект, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
КонсольКомпоновокДанных = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Отчет.ирКонсольКомпоновокДанных");
#Если _ Тогда
КонсольКомпоновокДанных = Отчеты.ирКонсольКомпоновокДанных.Создать();
#КонецЕсли
Результат = КонсольКомпоновокДанных.ОткрытьДляОтладки(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, Модально);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
Возврат "Отладка динамического списка доступна только на сервере";
Иначе
Возврат "Не поддерживаемый тип " + ТипЗнч(Объект) + " первого параметра";
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, НастройкаКомпоновки, ВнешниеНаборыДанных", , Модально);
Результат = Неопределено;
Если ТипЗнч(Объект) = Тип("Запрос") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
ВременныеТаблицы = Неопределено;
Если Объект.МенеджерВременныхТаблиц <> Неопределено Тогда
ВременныеТаблицы = ПолВТЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
Результат = "";
Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
Если Результат <> "" Тогда
Результат = Результат + ", ";
КонецЕсли;
Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
Результат = Результат + КлючИЗначение.Ключ;
КонецЕсли;
КонецЦикла;
Если Результат <> "" Тогда
Результат = "Временные таблицы " + Результат + " были сохранены частично!";
КонецЕсли;
СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
КонецЕсли;
СтруктураЗапроса.Текст = Объект.Текст;
СтруктураЗапроса.ТипЗапроса = "Обычный";
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Объект.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("COMОбъект") Тогда
Попытка
Пустышка = Объект.CommandText;
ЭтоКомандаADO = Истина;
Исключение
ЭтоКомандаADO = Ложь;
Попытка
Пустышка = Объект.ConnectionString;
ЭтоСоединениеADO = Истина;
Исключение
ЭтоСоединениеADO = Ложь;
КонецПопытки;
КонецПопытки;
СтруктураЗапроса = Новый Структура("Текст, Параметры, ВременныеТаблицы, ТипЗапроса");
Если Ложь
Или ЭтоКомандаADO
Или ЭтоСоединениеADO
Тогда
Если ЭтоСоединениеADO Тогда
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц;
Иначе
СтруктураЗапроса.Текст = Объект.CommandText;
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ПолучитьКопиюОбъектаЛкс(Объект.Параметры);
СтруктураЗапроса.Параметры = Новый Структура();
Для Каждого Parameter Из Объект.Parameters Цикл
КлючПараметра = Parameter.Name;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = "_" + КлючПараметра;
КонецЕсли;
Если Не ЛиИмяПеременнойЛкс(КлючПараметра) Тогда
КлючПараметра = КлючПараметра + XMLСтрока(СтруктураЗапроса.Параметры.Количество());
КонецЕсли;
Если СтруктураЗапроса.Параметры.Свойство(КлючПараметра) Тогда
ВызватьИсключение "Не удалось назначить параметру уникальное имя";
КонецЕсли;
СтруктураЗапроса.Параметры.Вставить(КлючПараметра, ЗначениеВСтрокуВнутр(Parameter.Value));
КонецЦикла;
КонецЕсли;
СтруктураЗапроса.ТипЗапроса = "ADO";
//ВременныеТаблицы = Неопределено;
//ВременныеТаблицы = ПолВТ(Объект, ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки);
//Результат = "";
//Для Каждого КлючИЗначение Из ВременныеТаблицы Цикл
// Если Результат <> "" Тогда
// Результат = Результат + ", ";
// КонецЕсли;
// Если КлючИЗначение.Значение.Количество() = ДопустимоеЧислоСтрокВоВременнойТаблицеОтложеннойОтладки Тогда
// Результат = Результат + КлючИЗначение.Ключ;
// КонецЕсли;
//КонецЦикла;
//Если Результат <> "" Тогда
// Результат = Результат + Символы.ПС + "Временные таблицы " + Результат + " были сохранены частично!";
//КонецЕсли;
//СтруктураЗапроса.ВременныеТаблицы = ВременныеТаблицы;
СтруктураПараметров.Объект = СтруктураЗапроса;
Иначе
СтруктураЗапроса.ТипЗапроса = "WQL";
СтруктураЗапроса.Текст = НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц;
КонецЕсли;
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительЗапроса") Тогда
СтруктураЗапроса = Новый Структура("Текст, Параметры");
ЗаполнитьЗначенияСвойств(СтруктураЗапроса, Объект.ПолучитьЗапрос());
СтруктураЗапроса.Параметры = ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(СтруктураЗапроса.Параметры);
СтруктураПараметров.Объект = СтруктураЗапроса;
ИначеЕсли ТипЗнч(Объект) = Тип("МакетКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
ИначеЕсли ТипЗнч(Объект) = Тип("ПостроительОтчета") Тогда
Результат = "Отложенная отладка построителя отчета не поддерживается";
ИначеЕсли ТипЗнч(Объект) = Тип("СхемаКомпоновкиДанных") Тогда
СтруктураПараметров.Вставить("Объект", Объект);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц);
СтруктураПараметров.Вставить("ВнешниеНаборыДанных", ВнешниеНаборыДанных);
ИначеЕсли ТипЗнч(Объект) = Тип("ДинамическийСписок") Тогда
#Если Не Сервер Тогда
Возврат "Отладка динамического списка доступна только на сервере";
#КонецЕсли
НастройкаКомпоновки = Неопределено;
Схема = Неопределено;
ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Объект, НастройкаКомпоновки, Схема);
СтруктураПараметров.Вставить("Объект", Схема);
СтруктураПараметров.Вставить("НастройкаКомпоновки", НастройкаКомпоновки);
КонецЕсли;
Если СтруктураПараметров.Объект <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Отладить");
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки, Наименование);
Иначе
Если Результат = Неопределено Тогда
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПолучитьСхемуИНастройкиКомпоновкиДинамическогоСпискаЛкс(Знач ДинамическийСписок, выхНастройкаКомпоновки, выхСхема) Экспорт
ТекстЗапроса = ДинамическийСписок.ТекстЗапроса;
Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда
ТекстЗапроса = "ВЫБРАТЬ * ИЗ " + ДинамическийСписок.ОсновнаяТаблица;
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
выхНастройкаКомпоновки = Новый НастройкиКомпоновкиДанных;
ТекущаяГруппировка = выхНастройкаКомпоновки;
Для Каждого ПолеГруппировки Из ДинамическийСписок.Группировка.Элементы Цикл
Если ПолеГруппировки.Использование Тогда
ТекущаяГруппировка = НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура, ПолеГруппировки.Поле);
КонецЕсли;
КонецЦикла;
НайтиДобавитьЭлементСтруктурыГруппировкаКомпоновкиЛкс(ТекущаяГруппировка.Структура);
Для Каждого ДоступноеПоле Из ДинамическийСписок.УсловноеОформление.ДоступныеПоляПолей.Элементы Цикл
Если ДоступноеПоле.Папка Тогда
Продолжить;
КонецЕсли;
НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс(выхНастройкаКомпоновки.Выбор, ДоступноеПоле.Поле);
КонецЦикла;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(выхНастройкаКомпоновки);
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Отбор);
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Параметры);
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.Порядок);
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(ДинамическийСписок.УсловноеОформление);
выхНастройкаКомпоновки = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
выхСхема = ПолучитьСхемуКомпоновкиПоЗапросуЛкс(Запрос);
КонецПроцедуры
// Если передана НастройкаКомпоновкиПриемник, то в качестве результата вернется ее копия!
Функция СкопироватьНастройкиКомпоновкиЛкс(НастройкаКомпоновкиИлиДинамическийСписокИсточник, Знач НастройкаКомпоновкиПриемник = Неопределено, КопироватьОтбор = Ложь,
КопироватьПараметры = Ложь, КопироватьПорядок = Ложь, КопироватьУсловноеОформление = Ложь) Экспорт
#Если _ Тогда
НастройкаКомпоновкиИсточник = Новый НастройкиКомпоновкиДанных;
#КонецЕсли
Если НастройкаКомпоновкиПриемник = Неопределено Тогда
НастройкаКомпоновкиПриемник = Новый НастройкиКомпоновкиДанных;
КонецЕсли;
Если ТипЗнч(НастройкаКомпоновкиИлиДинамическийСписокИсточник) = Тип("НастройкиКомпоновкиДанных") Тогда
Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор;
Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.ПараметрыДанных;
УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление;
Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок;
Иначе // ДинамическийСписок
Отбор = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Отбор;
Параметры = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Параметры;
УсловноеОформление = НастройкаКомпоновкиИлиДинамическийСписокИсточник.УсловноеОформление;
Порядок = НастройкаКомпоновкиИлиДинамическийСписокИсточник.Порядок;
КонецЕсли;
НастройкаXDTO = СериализаторXDTO.ЗаписатьXDTO(НастройкаКомпоновкиПриемник);
Если КопироватьОтбор Тогда
НастройкаXDTO.Filter = СериализаторXDTO.ЗаписатьXDTO(Отбор);
КонецЕсли;
Если КопироватьПараметры Тогда
НастройкаXDTO.DataParameters = СериализаторXDTO.ЗаписатьXDTO(Параметры);
КонецЕсли;
Если КопироватьПорядок Тогда
НастройкаXDTO.Order = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
Если КопироватьУсловноеОформление Тогда
НастройкаXDTO.ConditionalAppearance = СериализаторXDTO.ЗаписатьXDTO(УсловноеОформление);
КонецЕсли;
НастройкаКомпоновкиПриемник = СериализаторXDTO.ПрочитатьXDTO(НастройкаXDTO);
Возврат НастройкаКомпоновкиПриемник;
КонецФункции // СкопироватьОтборКомпоновкиЛкс()
Функция ПолучитьРасширениеФайловДляОтладкиЛкс() Экспорт
Результат = "deb";
Возврат Результат;
КонецФункции
Функция ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки = Неопределено, Наименование = "")
Если Не ЗначениеЗаполнено(Наименование) Тогда
Наименование = "" + ТекущаяДата() + " " + СтруктураПараметров.ТипОперации + " " + СтруктураПараметров.Объект;
КонецЕсли;
Если Истина
И Не ирКэш.ЛиПортативныйРежимЛкс()
И Не (Истина
И ТранзакцияАктивна()
И ирКэш.ЭтоФайловаяБазаЛкс())
Тогда
ХранимоеЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров);
ОбъектДляОтладки = Справочники.ирОбъектыДляОтладки.СоздатьЭлемент();
ОбъектДляОтладки.Наименование = Наименование;
ОбъектДляОтладки.XML = ХранимоеЗначение;
выхОбъектДляОтладки = ЗаписатьОбъектДляОтладкиЛкс(ОбъектДляОтладки);
Результат = "Данные помещены в справочник ""Объекты для отладки"". Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Объект """ + ОбъектДляОтладки + """(" + выхОбъектДляОтладки.УникальныйИдентификатор() + ")";
Иначе
//выхОбъектДляОтладки = ПоместитьВоВременноеХранилище(ХранимоеЗначение, Новый УникальныйИдентификатор);
//Результат = "Данные помещены в хранилище ДО КОНЦА СЕАНСА. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
//+ " Адрес """ + выхОбъектДляОтладки + """";
РасширениеФайловДляОтладки = ПолучитьРасширениеФайловДляОтладкиЛкс();
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ПутьДляФайловОбъектовДляОтладки = ирПортативный.ПолучитьКаталогОбъектовДляОтладкиЛкс();
Платформа = ирКэш.Получить();
Наименование = Платформа.ПолучитьИдентификаторИзПредставления(Наименование);
ИмяФайла = ПутьДляФайловОбъектовДляОтладки + Наименование + "." + РасширениеФайловДляОтладки;
Иначе
ИмяФайла = ПолучитьИмяВременногоФайла(РасширениеФайловДляОтладки);
КонецЕсли;
ФайлОбъектаДляОтладки = Новый Файл(ИмяФайла);
СохранитьОбъектВВидеСтрокиXMLЛкс(СтруктураПараметров, , ФайлОбъектаДляОтладки.ПолноеИмя);
выхОбъектДляОтладки = ФайлОбъектаДляОтладки.ПолноеИмя;
Результат = "Данные помещены в файл. Скопируйте эту строку и используйте команду ""Отладить отложенный объект""."
+ " Файл """ + выхОбъектДляОтладки + """";
КонецЕсли;
Возврат Результат;
КонецФункции
// Обертка ОтладитьЛкс(). Модально открывает нужную консоль для редактирования объекта.
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ОтЛкс(Объект, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц = Неопределено, ВнешниеНаборыДанных = Неопределено, ОтложеннаяОтладка = Ложь, Наименование = "") Экспорт
Результат = ОтладитьЛкс(Объект, Истина, НастройкаКомпоновкиИлиТекстЗапросаИлиИменаВременныхТаблиц, ВнешниеНаборыДанных, ОтложеннаяОтладка,,, Наименование);
Возврат Результат;
КонецФункции // ОО()
// Открывает исследователь объектов.
//
// Параметры:
// Объект Произвольный, *Неопределено - объект, который будет исследован;
// Модально Булево - открывать окно модально;
// КакКоллекцию Булево, *Ложь - исследовать как коллекцию вместо объекта.
//
// Возвращаемое значение:
// Сам объект.
//
Функция ИсследоватьЛкс(Объект = Неопределено, Модально = Ложь, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПравоДоступа("Использование", Метаданные.Обработки.ирИсследовательОбъектов) Тогда
Возврат "Нет права использования функции";
КонецЕсли;
КонецЕсли;
#Если Не Клиент Тогда
ОтложенноеВыполнение = Истина;
#КонецЕсли
#Если ТолстыйКлиентУправляемоеПриложение Тогда
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
ОтложенноеВыполнение = Истина;
КонецЕсли;
#КонецЕсли
Если Не ОтложенноеВыполнение Тогда
ИсследовательОбъектов = ПолучитьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирИсследовательОбъектов");
#Если _ Тогда
ИсследовательОбъектов = Обработки.ирИсследовательОбъектов.Создать();
#КонецЕсли
Если КакКоллекцию Тогда
Результат = ИсследовательОбъектов.ИсследоватьКоллекцию(Объект, Модально);
Иначе
Результат = ИсследовательОбъектов.ИсследоватьОбъект(Объект, Модально);
КонецЕсли;
Если Результат <> Неопределено Тогда
Объект = Результат;
КонецЕсли;
Иначе
СтруктураПараметров = Новый Структура("Объект, Модально, КакКоллекцию", Объект, Модально, КакКоллекцию);
Попытка
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(СтруктураПараметров);
Исключение
ОбъектXDTO = Неопределено;
КонецПопытки;
Если ОбъектXDTO <> Неопределено Тогда
СтруктураПараметров.Вставить("ТипОперации", "Исследовать");
выхОбъектДляОтладки = Неопределено;
Результат = ОтложитьУпакованныйОбъектДляОтладкиЛкс(СтруктураПараметров, выхОбъектДляОтладки);
Иначе
Результат = "Отложенная отладка объекта такого типа не поддерживается";
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // Исследовать()
// Обертка Исследовать. Модально открывает объект в исследователе объектов
// Удобно вызывать из отладчика через диалог "Вычислить выражение".
Функция ИсЛкс(Объект = Неопределено, КакКоллекцию = Ложь, ОтложенноеВыполнение = Ложь) Экспорт
Возврат ИсследоватьЛкс(Объект, Истина, КакКоллекцию, ОтложенноеВыполнение);
КонецФункции // Ис()
Функция ПреобразоватьПараметрыЗапросаДляСериализацииЛкс(Параметры) Экспорт
// Антибаг платформы 8.2.18. Некорректная серилизация моментов времени http://partners.v8.1c.ru/forum/thread.jsp?id=1159525#1159525
//СтруктураЗапроса.Параметры = ПолучитьКопиюОбъектаЛкс(Объект.Параметры);
Структура = Новый Структура();
Для Каждого КлючИЗначение Из Параметры Цикл
ЗначениеПараметра = ПолучитьСовместимоеЗначениеПараметраЛкс(КлючИЗначение.Значение, КлючИЗначение.Ключ);
Структура.Вставить(КлючИЗначение.Ключ, ЗначениеВСтрокуВнутр(ЗначениеПараметра));
КонецЦикла;
Возврат Структура;
КонецФункции
Функция СкопироватьЗапросЛкс(ЗапросИсточник, ЗапросПриемник = Неопределено) Экспорт
Если ЗапросПриемник = Неопределено Тогда
ЗапросПриемник = Новый Запрос;
КонецЕсли;
ЗапросПриемник.Текст = ЗапросИсточник.Текст;
ирОбщий.СкопироватьУниверсальнуюКоллекциюЛкс(ЗапросИсточник.Параметры, ЗапросПриемник.Параметры);
Возврат ЗапросПриемник;
КонецФункции // СкопироватьЗапросЛкс()
Функция ПолучитьТекстЗапросаВсехТиповСсылокЛкс(ИмяВременнойТаблицы = "ВсеТипыСсылок", Знач ОписаниеТипов = Неопределено) Экспорт
Если ОписаниеТипов = Неопределено Тогда
ОписаниеТипов = ПолучитьОписаниеТиповВсеСсылкиЛкс();
КонецЕсли;
#Если _ Тогда
ОписаниеВсехТипов = Новый ОписаниеТипов;
#КонецЕсли
ТекстТаблицыТипов = "";
Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
ПолноеИмя = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
НоваяСтрока = "ВЫБРАТЬ ТИП(" + ПолноеИмя + ") КАК Тип, """ + ПолноеИмя + """ КАК Имя" + Символы.ПС;
Если ТекстТаблицыТипов <> "" Тогда
ТекстТаблицыТипов = ТекстТаблицыТипов + "ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС;
Иначе
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
НоваяСтрока = НоваяСтрока + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
КонецЕсли;
ТекстТаблицыТипов = ТекстТаблицыТипов + НоваяСтрока;
КонецЦикла;
//ТекстТаблицыТипов = ТекстТаблицыТипов + " ИНДЕКСИРОВАТЬ ПО Тип"; // По такому типу поля нельзя индексировать
Возврат ТекстТаблицыТипов;
КонецФункции
Функция ПолучитьТекстЗапросаДатВДиапазонеЛкс(ИмяВременнойТаблицы = "ДатыДиапазона") Экспорт
Текст = "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d) КАК Период
|";
Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда
Текст = Текст + "ПОМЕСТИТЬ " + ИмяВременнойТаблицы + Символы.ПС;
КонецЕсли;
Текст = Текст +
"ИЗ
| (ВЫБРАТЬ 0 КАК a
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК aa
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК b
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК bb
| ПО (ИСТИНА)
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 0 КАК c
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК cc
| ПО (ИСТИНА)
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| 0 КАК d
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 1
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 2
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 3
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 4
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 5
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 6
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 7
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 8
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ 9) КАК dd
| ПО (ИСТИНА)
|ГДЕ
| aa.a * 1000 + bb.b * 100 + cc.c * 10 + dd.d <= РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ)";
Возврат Текст;
КонецФункции
Функция ПолучитьСобственноеВнешнееСоединениеЛкс(ИнициализироватьИнтерфейсИР = Ложь, выхИнтерфейсИР = Неопределено) Экспорт
ИмяПользователяВнешнегоСоединения = "";
ПарольПользователяВнешнегоСоединения = "";
Если ПользователиИнформационнойБазы.ПолучитьПользователей().Количество() > 0 Тогда
ИмяПользователяВнешнегоСоединения = ИмяПользователя() + "_ВнешнееСоединение";
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователяВнешнегоСоединения);
Если ПользовательИБ = Неопределено Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
ПользовательИБ.Имя = ИмяПользователяВнешнегоСоединения;
ПользовательИБ.ПолноеИмя = ИмяПользователяВнешнегоСоединения;
Сообщить("Создан служебный пользователь ИБ с именем """ + ИмяПользователяВнешнегоСоединения + """");
КонецЕсли;
ТекущийПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ЗаполнитьЗначенияСвойств(ПользовательИБ, ТекущийПользовательИБ,, "Имя, ПолноеИмя");
ПользовательИБ.Роли.Очистить();
Для Каждого Роль Из ТекущийПользовательИБ.Роли Цикл
ПользовательИБ.Роли.Добавить(Роль);
КонецЦикла;
ПарольПользователяВнешнегоСоединения = "" + Новый УникальныйИдентификатор;
ПользовательИБ.ПоказыватьВСпискеВыбора = Ложь;
ПользовательИБ.АутентификацияОС = Ложь;
ПользовательИБ.АутентификацияСтандартная = Истина;
ПользовательИБ.Пароль = ПарольПользователяВнешнегоСоединения;
ПользовательИБ.Записать();
КонецЕсли;
Результат = ЗапуститьСеансПодПользователемЛкс(ИмяПользователяВнешнегоСоединения, ПарольПользователяВнешнегоСоединения, "ComConnector");
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
выхИнтерфейсИР = Результат.ВнешниеОбработки.Создать(ирПортативный.ИспользуемоеИмяФайла, Ложь);
Иначе
выхИнтерфейсИР = Результат;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент
// ДанныеРасшифровки - ДанныеРасшифровкиКомпоновкиДанных
// Поля - Строка(0,П), Массив - Если строка, то через запятую перечисленные имена полей.
// Область - ВыделенныеОбластиТабличногоДокумента, Массив, ОбластьЯчеекТабличногоДокумента - Если не указано, используются выделенные области
//
Функция ПолучитьТаблицуКлючейИзСкомпонованногоТабличногоДокументаЛкс(Знач ТабличныйДокумент, Знач ДанныеРасшифровки, Знач Поля = "", Знач Область = Неопределено) Экспорт
Перем ЭтотОбъект, Результат;
//НАЧАЛО.СЕРВИС
Если Истина
И ТипЗнч(Поля) = Тип("Строка")
И Не ПустаяСтрока(Поля)
Тогда
МассивИменПолей = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Поля, ",", Истина);
ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда
МассивИменПолей = Поля;
Иначе
МассивИменПолей = Новый Массив;
КонецЕсли;
ТаблицаРезультата = Неопределено;
МассивСсылок = Новый Массив;
АвтоПоля = МассивИменПолей.Количество() = 0;
Если ТипЗнч(Область) = Тип("Неопределено") Тогда
КоллекцияОбластей = ТабличныйДокумент.ВыделенныеОбласти;
ИначеЕсли ТипЗнч(Область) = Тип("Массив") Тогда
КоллекцияОбластей = Область;
ИначеЕсли ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента") Тогда
КоллекцияОбластей = Новый Массив;
КоллекцияОбластей.Добавить(Область);
КонецЕсли;
ЭлементыРасшифровки = ДанныеРасшифровки.Элементы;
НачальноеКоличество = КоллекцияОбластей.Количество();
Для СчетчикВыделенныеОбласти = 1 По НачальноеКоличество Цикл
Область = КоллекцияОбластей[НачальноеКоличество - СчетчикВыделенныеОбласти];
Если Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Колонки Тогда
Лево = Область.Лево;
Право = Область.Право;
Верх = 1;
Низ = ТабличныйДокумент.ВысотаТаблицы;
ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Строки Тогда
Лево = 1;
Право = ТабличныйДокумент.ШиринаТаблицы;
Верх = Область.Верх;
Низ = Область.Низ;
ИначеЕсли Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник Тогда
Лево = Область.Лево;
Право = Область.Право;
Верх = Область.Верх;
Низ = Область.Низ;
Иначе
Продолжить;
КонецЕсли;
Для НомерСтроки = Верх по Низ Цикл
КлючПолучен = Ложь;
СтруктураПолей = Новый Структура;
Для НомерКолонки = Лево по Право Цикл
ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
Если ОбластьЯчейки.Лево <> НомерКолонки Или ОбластьЯчейки.Верх <> НомерСтроки Тогда
// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
Продолжить;
КонецЕсли;
Расшифровка = ОбластьЯчейки.Расшифровка;
Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ЭлементРасшифровкиПоля = ЭлементыРасшифровки[Расшифровка];
Если НомерСтроки = Верх Тогда
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ТаблицаРезультата.Колонки.Добавить(ИмяПоля);
КонецЦикла;
КонецЕсли;
Если АвтоПоля Тогда
ИмяПоля = ЭлементРасшифровкиПоля.ПолучитьПоля()[0].Поле;
МассивИменПолей.Добавить(ИмяПоля);
ИмяКолонки = СтрЗаменить(ИмяПоля, ".", "");
Если ТаблицаРезультата.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
ТаблицаРезультата.Колонки.Добавить(ИмяКолонки);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КлючПолучен = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(ЭлементРасшифровкиПоля, МассивИменПолей, СтруктураПолей);
Если Истина
И КлючПолучен
И (Ложь
Или НомерКолонки = Право
Или Не АвтоПоля)
Тогда
Прервать;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если КлючПолучен Тогда
Если ТаблицаРезультата.НайтиСтроки(СтруктураПолей).Количество() = 0 Тогда
ЗаполнитьЗначенияСвойств(ТаблицаРезультата.Добавить(), СтруктураПолей);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если ТаблицаРезультата = Неопределено Тогда
ТаблицаРезультата = Новый ТаблицаЗначений;
КонецЕсли;
Результат = ТаблицаРезультата;
Возврат Результат;
КонецФункции
// Извлекаемые значения помещаются в структуру
// Параметры:
// ЭлементРасшифровкиПоля - ЭлементРасшифровкиКомпоновкиДанныхГруппировка, ЭлементРасшифровкиКомпоновкиДанныхПоля
// Поля - Строка(0,П), Массив
// СтруктураПолей - Структура
//
Функция ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(Знач ЭлементРасшифровкиПоля, Знач Поля = "", Знач СтруктураПолей = Неопределено) Экспорт
Если СтруктураПолей = Неопределено Тогда
СтруктураПолей = Новый Структура;
КонецЕсли;
Если Истина
И ТипЗнч(Поля) = Тип("Строка")
И Не ПустаяСтрока(Поля)
Тогда
МассивИменПолей = ирОбщий.ПолучитьМассивИзСтрокиСРазделителемЛкс(Поля, ",", Истина);
ИначеЕсли ТипЗнч(Поля) = Тип("Массив") Тогда
МассивИменПолей = Поля;
Иначе
МассивИменПолей = Новый Массив;
КонецЕсли;
Результат = Ложь;
Если ТипЗнч(ЭлементРасшифровкиПоля) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
ТекущиеЗначенияПолей = ЭлементРасшифровкиПоля.ПолучитьПоля();
Если ТекущиеЗначенияПолей.Количество() > 0 Тогда
//ЗначениеПоля = ТекущиеЗначенияПолей[0];
Для Каждого ИмяПоля Из МассивИменПолей Цикл
ЗначениеПоля = ТекущиеЗначенияПолей.Найти(ИмяПоля);
ИмяСвойства = СтрЗаменить(ИмяПоля, ".", "");
Если Истина
И ЗначениеПоля <> Неопределено
И Не СтруктураПолей.Свойство(ИмяСвойства)
Тогда
СтруктураПолей.Вставить(ИмяСвойства, ЗначениеПоля.Значение);
Если СтруктураПолей.Количество() = МассивИменПолей.Количество() Тогда
Результат = Истина;
Прервать
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Если Не Результат Тогда
РодительскиеЭлементыРасшифровки = ЭлементРасшифровкиПоля.ПолучитьРодителей();
Для Каждого РодительскийЭлементРасшифровки Из РодительскиеЭлементыРасшифровки Цикл
Результат = ИзвлечьКлючИзЭлементаРасшифровкиКомпоновкиЛкс(РодительскийЭлементРасшифровки, МассивИменПолей, СтруктураПолей);
Если Результат Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
#КонецЕсли
#Если Клиент И Не ТонкийКлиент И Не ВебКлиент Тогда
Процедура НастроитьАвтоТабличноеПолеДинамическогоСписка(ОсновнойЭУ) Экспорт
// Антибаг платформы 8.2-8.3 для регистра бухгалтерии https://partners.v8.1c.ru/forum/t/1372055/m/1372055
ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(ОсновнойЭУ.Значение));
ПолноеИмяМД = ОбъектМД.ПолноеИмя();
КорневойТип = ирОбщий.ПолучитьПервыйФрагментЛкс(ПолноеИмяМД);
Если КорневойТип <> "РегистрБухгалтерии" Тогда
ОсновнойЭУ.СоздатьКолонки();
КонецЕсли;
//СтруктураХраненияПолей = ирКэш.ПолучитьСтруктуруХраненияБДЛкс().НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля;
ФильтрМетаданных = Новый Массив;
ФильтрМетаданных.Добавить(ПолноеИмяМД);
СтруктураХраненияПолей = ПолучитьСтруктуруХраненияБазыДанных(ФильтрМетаданных).НайтиСтроки(Новый Структура("Назначение, Метаданные", "Основная", ПолноеИмяМД))[0].Поля;
Попытка
КолонкиСписка = ОсновнойЭУ.Значение.Колонки;
Исключение
КонецПопытки;
КолонкиТП = ОсновнойЭУ.Колонки;
Колонка = КолонкиТП.Найти("Картинка");
Если Колонка = Неопределено Тогда
КолонкаКартинки = КолонкиТП.Добавить("Картинка");
КолонкаКартинки.ОтображатьСтандартнуюКартинку = Истина;
КолонкаКартинки.Ширина = 3;
КолонкаКартинки.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КолонкаКартинки.ТекстШапки = "";
КонецЕсли;
Для Каждого ЭлементОтбора Из ОсновнойЭУ.Значение.Отбор Цикл
Колонка = ОсновнойЭУ.Колонки.Найти(ЭлементОтбора.Имя);
Если Колонка = Неопределено Тогда
// Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1002521#1002521
Если Ложь
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоДт") = 1
Или Найти(ЭлементОтбора.Имя, "ВидСубконтоКт") = 1
Тогда
Продолжить;
КонецЕсли;
Попытка
КолонкиСписка.Добавить(ЭлементОтбора.Имя, Ложь);
Исключение
// Сюда попадает например элемент отбора от критерия отбора
Продолжить;
КонецПопытки;
Колонка = ОсновнойЭУ.Колонки.Добавить();
Колонка.ТекстШапки = ЭлементОтбора.Представление;
Если Истина
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("Булево"))
И ЭлементОтбора.ТипЗначения.Типы().Количество() = 1
Тогда
Колонка.УстановитьЭлементУправления(Тип("Флажок"));
Попытка
Колонка.ДанныеФлажка = ЭлементОтбора.Имя;
Исключение
Колонка.Видимость = Ложь;
КонецПопытки;
Иначе
Колонка.УстановитьЭлементУправления(Тип("ПолеВвода"));
Попытка
Колонка.Данные = ЭлементОтбора.Имя;
Исключение
Колонка.Видимость = Ложь;
КонецПопытки;
КонецЕсли;
// Закомментировал 13.02.2011
//Если ЗначениеЗаполнено(Колонка.Данные) Тогда
// Колонка.Имя = Колонка.Данные;
//КонецЕсли;
Колонка.Имя = ЭлементОтбора.Имя;
СтрокаСтрукутрыПоля = СтруктураХраненияПолей.Найти(ЭлементОтбора.Имя, "ИмяПоля");
Если СтрокаСтрукутрыПоля <> Неопределено Тогда
МетаданныеПоля = СтрокаСтрукутрыПоля.Метаданные;
Если ЗначениеЗаполнено(МетаданныеПоля) Тогда
МетаданныеПоля = Метаданные.НайтиПоПолномуИмени(МетаданныеПоля);
Иначе
МетаданныеПоля = Неопределено;
КонецЕсли;
Если МетаданныеПоля <> Неопределено Тогда
Колонка.ПодсказкаВШапке = МетаданныеПоля.Подсказка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Антибаг платформы 8.2-8.3.6 https://partners.v8.1c.ru/forum/t/1337995/m/1337995
Если Истина
И ЭлементОтбора.ТипЗначения.СодержитТип(Тип("УникальныйИдентификатор"))
Тогда
Сообщить("Колонка """ + ЭлементОтбора.Имя + """ типа УникальныйИдентификатор не будет отображаться из-за ошибки платформы");
ОсновнойЭУ.Колонки.Удалить(Колонка);
Продолжить;
КонецЕсли;
КонецЦикла;
Если КолонкиСписка <> Неопределено Тогда
Для Каждого ЭлементНастройкиОтбора Из ОсновнойЭУ.НастройкаОтбора Цикл
ЭлементНастройкиОтбора.Доступность = Истина;
КонецЦикла;
ОбъектМД = Метаданные.НайтиПоТипу(ОсновнойЭУ.ТипЗначения.Типы()[0]);
НастройкаПорядка = ОсновнойЭУ.НастройкаПорядка;
ПредопределенныеПоля = Новый Массив();
Если КорневойТип = "ПланСчетов" Тогда
ПредопределенныеПоля.Добавить("Код");
КонецЕсли;
ПредопределенныеПоля.Добавить("Наименование");
ПредопределенныеПоля.Добавить("Дата");
ПредопределенныеПоля.Добавить("Период");
ПредопределенныеПоля.Добавить("ДатаИзменения");
ПредопределенныеПоля.Добавить("ДатаСоздания");
ПорядокУстановлен = Ложь;
Для Каждого ПредопределенноеПоле Из ПредопределенныеПоля Цикл
ЭлементПорядка = НастройкаПорядка.Найти(ПредопределенноеПоле);
Если ЭлементПорядка <> Неопределено Тогда
ЭлементПорядка.Доступность = Истина;
Если Не ПорядокУстановлен Тогда
Если ОсновнойЭУ.Значение.Порядок.Найти(ПредопределенноеПоле) = Неопределено Тогда
НовыйПорядок = ирОбщий.ПолучитьСтрокуПорядкаЛкс(ОсновнойЭУ.Значение.Порядок);
Если ЗначениеЗаполнено(НовыйПорядок) Тогда
НовыйПорядок = НовыйПорядок + ",";
КонецЕсли;
ОсновнойЭУ.Значение.Порядок.Установить(НовыйПорядок + ПредопределенноеПоле);
КонецЕсли;
ПорядокУстановлен = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Компоновщик = ирКэш.ПолучитьКомпоновщикТаблицыМетаданныхЛкс(ОбъектМД.ПолноеИмя());
//#Если _ Тогда
// Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
//#КонецЕсли
//Для Каждого ПолеВыбора Из Компоновщик.Настройки.ДоступныеПоляВыбора.Элементы Цикл
// Если ПолеВыбора.Папка Тогда
// Продолжить;
// КонецЕсли;
//КонецЦикла;
КолонкаСсылка = КолонкиСписка.Найти("Ссылка");
Если КолонкаСсылка <> Неопределено Тогда
КолонкаИдентификатора = ОсновнойЭУ.Колонки.Добавить("ИдентификаторЛкс");
КолонкаИдентификатора.ТекстШапки = "Идентификатор ссылки";
КонецЕсли;
КонецЕсли;
КонецПроцедуры // НастроитьАвтоТабличноеПолеДинамическогоСписка()
Процедура НастроитьДобавленныеКолонкиТабличногоПоляЛкс(Знач ТабличноеПоле, ОписанияТиповКолонок = Неопределено, ПодсказкиКолонок = Неопределено, ДоступныеПоляВыбора = Неопределено) Экспорт
Если ОписанияТиповКолонок = Неопределено Тогда
ОписанияТиповКолонок = ТабличноеПоле.Значение.Колонки;
КонецЕсли;
Для Каждого КолонкаТаблицы Из ОписанияТиповКолонок Цикл
КолонкаТабличногоПоля = ТабличноеПоле.Колонки[КолонкаТаблицы.Имя];
ТипыРеквизита = КолонкаТаблицы.ТипЗначения.Типы();
Если ТипыРеквизита.Количество() = 1 И ТипыРеквизита[0] = Тип("Булево") Тогда
КолонкаТабличногоПоля.Данные = "";
КолонкаТабличногоПоля.ДанныеФлажка = КолонкаТаблицы.Имя;
КолонкаТабличногоПоля.РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
КолонкаТабличногоПоля.Ширина = 3;
КонецЕсли;
Если ПодсказкиКолонок <> Неопределено Тогда
Метареквизит = ПодсказкиКолонок.Найти(КолонкаТаблицы.Имя);
Если Метареквизит <> Неопределено Тогда
КолонкаТабличногоПоля.ПодсказкаВШапке = Метареквизит.Подсказка;
КонецЕсли;
КонецЕсли;
Если ДоступныеПоляВыбора <> Неопределено Тогда
ДоступноеПоле = ДоступныеПоляВыбора.НайтиПоле(Новый ПолеКомпоновкиДанных(КолонкаТаблицы.Имя));
Если ДоступноеПоле <> Неопределено Тогда
КолонкаТабличногоПоля.ТекстШапки = ДоступноеПоле.Заголовок;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры // ДобавитьСтраницуТЧ()
Процедура ФормаОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник) Экспорт
Если ИмяСобытия = "ЗакрытьВсеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
ЭтаФорма.Закрыть();
Если ЭтаФорма.Открыта() Тогда
Параметр.Отказ = Истина;
КонецЕсли;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ЕстьОткрытыеФормыИнструментовРазработчика" Тогда
Если ЭтаФорма.Открыта() Тогда
Параметр.Ответ = Истина;
КонецЕсли;
ИначеЕсли ИмяСобытия = "ОбнаружитьСебя" Тогда
Попытка
Сообщить(ЭтаФорма.Имя);
Исключение
Попытка
Сообщить(ЭтаФорма.ЭтотОбъект.Метаданные().ПолноеИмя());
Исключение
Сообщить("Неизвестная форма");
КонецПопытки;
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьФайлСПредупреждениемЛкс(ИмяФайла, СтандартнаяОбработка = Неопределено) Экспорт
СтандартнаяОбработка = Ложь;
Ответ = Вопрос("Вы уверены, что хотите открыть """ + ИмяФайла + """?", РежимДиалогаВопрос.ОКОтмена);
Если Ответ = КодВозвратаДиалога.ОК Тогда
ЗапуститьПриложение(ИмяФайла);
КонецЕсли;
КонецПроцедуры
Процедура ОткрытьНастройкиАлгоритмовЛкс() Экспорт
ОткрытьФормуЛкс("Обработка.ирПлатформа.Форма.НастройкиАлгоритмов");
КонецПроцедуры
Процедура ОткрытьАдминистративнаяРегистрацияCOMЛкс() Экспорт
ОткрытьФормуЛкс("Обработка.ирПлатформа.Форма.АдминистративнаяРегистрацияCOM");
КонецПроцедуры
// Создает новый экземпляр обработки и открывает его форму.
//
// Параметры:
// Объект - ОбработкаОбъект, ОтчетОбъект.
//
// Возвращаемое значение:
// Форма.
//
Функция ОткрытьНовоеОкноОбработкиЛкс(ЭтотОбъект) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
НовыйОбъект = ПолучитьМенеджерЛкс(ЭтотОбъект).Создать();
Иначе
ПолноеИмяОбъекта = ЭтотОбъект.Метаданные().ПолноеИмя();
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяОбъекта);
ТипМетаданных = Фрагменты[0];
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных);
НовыйОбъект = Менеджер.Создать(ЭтотОбъект.ИспользуемоеИмяФайла);
КонецЕсли;
Результат = НовыйОбъект.ПолучитьФорму();
Результат.Открыть();
Возврат Результат;
КонецФункции // ОткрытьНовоеОкноОбработкиЛкс()
Функция ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
//ирПортативный #Если _ Тогда
// Такой прием нужен для обхода ошибка компиляции в портативном режиме
Результат = ПолучитьФорму(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
//ирПортативный #КонецЕсли
Иначе
Фрагменты = ПолучитьМассивИзСтрокиСРазделителемЛкс(ПолноеИмяФормы);
ОбъектМД = Метаданные.НайтиПоПолномуИмени(Фрагменты[0] + "." + Фрагменты[1]);
Если ОбъектМД = Неопределено Тогда
ТипМетаданных = Фрагменты[0];
Менеджер = ирПортативный.ПолучитьМенеджерТипаМетаданныхЛкс(ТипМетаданных);
ПолноеИмяФайла = ирПортативный.ПолучитьПолноеИмяФайлаПортативногоОбъектаМетаданныхЛкс(Фрагменты[1], ТипМетаданных);
Если Истина
И СтрокиРавныЛкс(Фрагменты[2], "Форма")
И Фрагменты.Количество() = 4
Тогда
ИмяФормы = Фрагменты[3];
Иначе
ИмяФормы = Неопределено;
КонецЕсли;
Результат = Менеджер.ПолучитьФорму(ПолноеИмяФайла, ИмяФормы, Владелец, Уникальность);
Иначе
Результат = ирПортативный.ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОткрытьФормуЛкс(ПолноеИмяФормы, Параметры = Неопределено, Владелец = Неопределено, Уникальность = Неопределено, Окно = Неопределено) Экспорт
Форма = ПолучитьФормуЛкс(ПолноеИмяФормы, Параметры, Владелец, Уникальность, Окно);
Форма.Открыть();
КонецФункции
Функция ПолучитьОбщуюКартинкуЛкс(Имя) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Результат = ирПортативный.ПолучитьОбщуюКартинкуЛкс(Имя);
Иначе
Результат = БиблиотекаКартинок[Имя];
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПолучитьЦветСтиляЛкс(Имя) Экспорт
Если ирКэш.ЛиПортативныйРежимЛкс() Тогда
Результат = ирПортативный.ПолучитьЦветСтиляЛкс(Имя);
Иначе
Результат = ЦветаСтиля[Имя];
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// Значение -
// ОчиститьПередУстановкой - Булево
// УстановитьТекст - Булево
// УстановитьЗначение - Булево
//
Функция БуферОбмена_УстановитьЗначениеЛкс(Знач Значение = "", Знач ОчиститьПередУстановкой = Истина, Знач УстановитьТекст = Истина, Знач УстановитьЗначение = Истина) Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
Если ОчиститьПередУстановкой Тогда
WinAPI.OpenClipboard(0);
WinAPI.EmptyClipboard();
WinAPI.CloseClipboard();
КонецЕсли;
CF_TEXT = 1;
CF_UNICODETEXT = 13;
CF_OEMTEXT = 7;
Если УстановитьЗначение Тогда
ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс();
ВнутреннееЗначение = СохранитьОбъектВВидеСтрокиXMLЛкс(Значение,,, Ложь);
БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, ФорматБуфераОбмена1С);
КонецЕсли;
Если УстановитьТекст Тогда
ВнутреннееЗначение = "" + Значение; // Может тормозить из-за обращений к БД
Если ВнутреннееЗначение <> "" Тогда
БуферОбмена_УстановитьДанныеПоФорматуЛкс(ВнутреннееЗначение, CF_UNICODETEXT);
КонецЕсли;
КонецЕсли;
КонецФункции
// Параметры:
// ВнутреннееЗначение -
// ФорматЗначения - Число(0,0) - CF_TEXT = 1;
// ПомещатьВКодировкеUTF8 - Булево - Иначе используется UNICODE
//
Функция БуферОбмена_УстановитьДанныеПоФорматуЛкс(Знач ВнутреннееЗначение, Знач ФорматЗначения = 1, Знач ПомещатьВКодировкеUTF8 = Ложь) Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
ВнутреннееЗначение = "" + ВнутреннееЗначение;
КоличествоСимволов = СтрДлина(ВнутреннееЗначение);
ПромежуточныйТекст = WinAPI.StrPtr(ВнутреннееЗначение, "s");
GMEM_DDESHARE = 8192; // &H2000;
Дескриптор = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 2);
Указатель = WinAPI.GlobalLock(Дескриптор);
WinAPI.MultiByteToWideChar(0, 0, ПромежуточныйТекст, -1, Указатель, КоличествоСимволов + 1);
Если ПомещатьВКодировкеUTF8 Тогда
Дескриптор2 = WinAPI.GlobalAlloc(GMEM_DDESHARE, (КоличествоСимволов + 1) * 1);
Указатель2 = WinAPI.GlobalLock(Дескриптор2);
CP_UTF8 = 65001; // UTF-8 translation
WinAPI.WideCharToMultiByte(CP_UTF8, 0, Указатель, -1, Указатель2, КоличествоСимволов + 1);
WinAPI.GlobalUnlock(Дескриптор);
Указатель = Указатель2;
Дескриптор = Указатель2;
КонецЕсли;
WinAPI.OpenClipboard(0);
WinAPI.SetClipboardData(ФорматЗначения, Дескриптор);
WinAPI.CloseClipboard();
WinAPI.GlobalUnlock(Дескриптор);
КонецФункции
// Параметры:
// ФорматЗначения - Число(0,0) - CF_TEXT = 1;
// Кодировка - Строка(0,П) - w (по умолчанию), s, z. Значения s и z нужны для чтения строки в ANSI- или OEM-кодировке, при этом она конвертируется в Юникод
//
Функция БуферОбменаолучитьДанныеПоФорматуЛкс(Знач ФорматЗначения = 1, Знач Кодировка = "w") Экспорт
WinAPI = ирКэш.ПолучитьWinAPI();
WinAPI.OpenClipboard(0);
Дескриптор = WinAPI.GetClipboardData(ФорматЗначения);
Если Дескриптор <> 0 Тогда
Указатель = WinAPI.GlobalLock(Дескриптор);
Результат = WinAPI.StrGet(Указатель, Кодировка);
WinAPI.GlobalUnlock(Дескриптор);
Иначе
Результат = "";
КонецЕсли;
WinAPI.CloseClipboard();
Возврат Результат;
КонецФункции
Функция БуферОбменаолучитьЗначениеЛкс() Экспорт
ФорматБуфераОбмена1С = ирКэш.ПолучитьФорматБуфераОбмена1СЛкс();
СтрокаXML = БуферОбменаолучитьДанныеПоФорматуЛксорматБуфераОбмена1С);
Результат = ВосстановитьОбъектИзСтрокиXMLЛкс(СтрокаXML,,, Ложь);
Возврат Результат;
КонецФункции
Функция БуферОбменаолучитьТекстЛкс() Экспорт
CF_UNICODETEXT = 13;
Результат = БуферОбменаолучитьДанныеПоФорматуЛкс(CF_UNICODETEXT);
Возврат Результат;
КонецФункции
// Параметры:
// ПолеВвода - ПолеВвода
// Значение -
// Текст - Строка(0,П)
//
Функция ВставитьЗначениеВПолеВводаЛкс(Знач ПолеВвода, Знач Значение, Знач Текст = "") Экспорт
Результат = Ложь;
Если Истина
И Значение <> Неопределено
И Не ПолеВвода.ТолькоПросмотр
Тогда
ТипНовогоЗначения = ТипЗнч(Значение);
Если Ложь
Или ТипЗнч(ПолеВвода.Значение) = ТипНовогоЗначения
Или ПолеВвода.ОграничениеТипа.Типы().Количество() = 0
Или ПолеВвода.ОграничениеТипа.СодержитТип(ТипНовогоЗначения)
Тогда
ИнтерактивноЗаписатьВЭлементУправленияЛкс(ПолеВвода, Значение);
КонецЕсли;
Если Значение = ПолеВвода.Значение Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
// Параметры:
// НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка
// Кнопка - КнопкаКоманднойПанели
// СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром.
// ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма
//
Функция БуферОбмена_ВставитьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Текст = БуферОбменаолучитьТекстЛкс();
Значение = БуферОбменаолучитьЗначениеЛкс();
ПродолжитьОбработку = Истина;
ТипЗначения = ТипЗнч(Значение);
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Если Не ЭтаФорма.ТолькоПросмотр Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ТекущийЭлементФормы, Значение, Текст);
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
Попытка
РедактированиеВДиалоге = ТекущийЭлементФормы.СпособРедактирования = СпособРедактированияСписка.ВДиалоге;
Исключение
РедактированиеВДиалоге = Ложь;
КонецПопытки;
Если Истина
И Не РедактированиеВДиалоге
И Не ЭтаФорма.ТолькоПросмотр
И Не ТекущийЭлементФормы.ТолькоПросмотр
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
ДобавитьСтроку = Истина
И ТекущийЭлементФормы.ТекущиеДанные = Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок;
Если Истина
И Значение <> Неопределено
И ТекущийЭлементФормы.ИзменятьСоставСтрок
И Не ДобавитьСтроку
Тогда
Ответ = Вопрос("Выполнить вставку значения в новую строку (иначе будет выполнена вставка в текущую)?", РежимДиалогаВопрос.ДаНет,
, КодВозвратаДиалога.Нет);
ДобавитьСтроку = Ответ = КодВозвратаДиалога.Да;
КонецЕсли;
Если ДобавитьСтроку Тогда
ИмяТекущейКолонки = ТекущийЭлементФормы.ТекущаяКолонка.Имя;
ТекущийЭлементФормы.ДобавитьСтроку();
ТекущийЭлементФормы.ТекущаяКолонка = ТекущийЭлементФормы.Колонки[ИмяТекущейКолонки];
ИначеЕсли ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено Тогда
ТекущийЭлементФормы.ИзменитьСтроку(); // Нужно делать, т.к. табличное поле выходит из режима редактирования строку при вызове команды
КонецЕсли;
Если ТекущийЭлементФормы.ТекущиеДанные <> Неопределено Тогда
ПолеВвода = ТекущийЭлементФормы.ТекущаяКолонка.ЭлементУправления;
Если ТипЗнч(ПолеВвода) = Тип("ПолеВвода") Тогда
Если ТипЗначения = Тип("Массив") Тогда
Значение = Значение[0];
КонецЕсли;
ПродолжитьОбработку = Не ВставитьЗначениеВПолеВводаЛкс(ПолеВвода, Значение, Текст);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если ПродолжитьОбработку Тогда
мПлатформа = ирКэш.Получить();
мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш);
Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
//ирПлатформа.WshShell.SendKeys("^v^м", 20); //англ.v,русс
WinAPI = ирКэш.ПолучитьWinAPI();
ДескрипторОкнаФокуса = WinAPI.GetActiveWindow();
WinAPI.EnableWindow(ДескрипторОкнаФокуса);
WM_KEYDOWN = 256; //0x0100
WM_KEYUP = 257; //0x0101
WM_COPY = 757; //0x0301
WM_CHAR = 258; //0x0102
WM_PASTE = 758; //0x0302
WM_GETTEXT = 13; //0x000D
VK_CONTROL = 17; // CTRL
KEY_V = 86; // V
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1);
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_V, 1);
Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1);
КонецЕсли;
Если WinAPI.GetAsyncKeyState(KEY_V) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_V, 1);
КонецЕсли;
ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина);
КонецЕсли;
КонецФункции
// Параметры:
// ЭтаФорма - Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма, Форма
// НастройкаДействия - СправочникСсылка.ЭлементыКомандныхПанелей2iS - Для команд-списков содержит ссылку элемента списка
// Кнопка - КнопкаКоманднойПанели
// СтандартнаяОбработка - Булево - Используется в случае связи кнопки с параметром.
// ИсточникДействий - ПолеHTMLДокумента, ПолеВвода, ПолеТабличногоДокумента, ПолеТекстовогоДокумента, ТабличноеПоле, Форма
//
Функция БуферОбмена_КопироватьЛкс(Знач ЭтаФорма, Знач Кнопка) Экспорт
ТекущийЭлементФормы = ЭтаФорма.ТекущийЭлемент;
Если ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеВвода") Тогда
Значение = ТекущийЭлементФормы.Значение;
//Текст = "" + ТекущийЭлементФормы.ВыделенныйТекст;
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = Неопределено;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ТабличноеПоле") Тогда
//:ТекущийЭлементФормы = Новый ("ТабличноеПоле")
Если Истина
И ТекущийЭлементФормы.ТекущаяСтрока <> Неопределено
И ТекущийЭлементФормы.ТекущаяКолонка <> Неопределено
Тогда
Ячейка = ТекущийЭлементФормы.ОформлениеСтроки(ТекущийЭлементФормы.ТекущаяСтрока).Ячейки[ТекущийЭлементФормы.ТекущаяКолонка.Имя];
Значение = Ячейка.Значение;
//Если ТипЗнч(Значение) = Тип("Строка") Тогда
////Если ПолучитьОписаниеТиповВсеРедактируемыеТипыЛкс().СодержитТип(ТипЗнч(Значение)) Тогда
// ОбъектМДСписка = Метаданные.НайтиПоТипу(ТипЗнч(ТекущийЭлементФормы.Значение));
// Если ОбъектМДСписка <> Неопределено Тогда
// Если ЛиКорневойТипСсылкиЛкс(ПолучитьПервыйФрагментЛкс(ОбъектМДСписка.ПолноеИмя())) Тогда
// КлючеваяКолонкаДанных = "Ссылка";
// КонецЕсли;
// КонецЕсли;
// ТипСтроки = ТипЗнч(ТекущийЭлементФормы.ТекущаяСтрока);
// Если КлючеваяКолонкаДанных <> Неопределено Тогда
// Значение = Новый Массив;
// Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл
// Значение.Добавить(ВыделеннаяСтрока[КлючеваяКолонкаДанных]);
// КонецЦикла;
// ИначеЕсли ТипСтроки = Тип("ДоступноеПолеКомпоновкиДанных") Тогда
// Значение = Новый Массив;
// Для Каждого ВыделеннаяСтрока Из ТекущийЭлементФормы.ВыделенныеСтроки Цикл
// Значение.Добавить(ВыделеннаяСтрока);
// КонецЦикла;
// Иначе
// Значение = Неопределено;
// КонецЕсли;
//КонецЕсли;
КонецЕсли;
ИначеЕсли ТипЗнч(ТекущийЭлементФормы) = Тип("ПолеТабличногоДокумента") Тогда
#Если _ Тогда
ТекущийЭлементФормы = Новый ТабличныйДокумент;
#КонецЕсли
Попытка
ДанныеРасшифровки = ЭтаФорма.ДанныеРасшифровки;
Исключение
ДанныеРасшифровки = Неопределено;
КонецПопытки;
Если Истина
И ДанныеРасшифровки <> Неопределено
И ТекущийЭлементФормы.ТекущаяОбласть <> Неопределено
И ТипЗнч(ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных")
Тогда
ЭлементРасшифровки = ДанныеРасшифровки.Элементы[ТекущийЭлементФормы.ТекущаяОбласть.Расшифровка];
Для каждого ЗначениеПоля Из ЭлементРасшифровки.ПолучитьПоля() Цикл
Если Не ЛиСсылкаНаОбъектБДЛкс(ЗначениеПоля.Значение) Тогда
Продолжить;
КонецЕсли;
Значение = ЗначениеПоля.Значение;
Прервать;
КонецЦикла;
КонецЕсли;
КонецЕсли;
мПлатформа = ирКэш.Получить();
мПлатформа.ПараметрыОбработчикаОжидания = Новый Структура("ИмяМетода, Кнопка, СочетаниеКлавиш", "УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс", Кнопка, Кнопка.СочетаниеКлавиш);
Если Значение <> Неопределено Тогда
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ИмяМетода", "БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс");
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("Значение", Значение);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("ОчиститьПередУстановкой", Ложь);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьТекст", Ложь);
мПлатформа.ПараметрыОбработчикаОжидания.Вставить("УстановитьЗначение", Истина);
КонецЕсли;
Кнопка.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.Нет);
//ирПлатформа.WshShell.SendKeys("^c^с"); //англ.C,русс.С
WinAPI = ирКэш.ПолучитьWinAPI();
ДескрипторОкнаФокуса = WinAPI.GetActiveWindow();
WinAPI.EnableWindow(ДескрипторОкнаФокуса);
WM_KEYDOWN = 256; //0x0100
WM_KEYUP = 257; //0x0101
WM_COPY = 757; //0x0301
WM_CHAR = 258; //0x0102
WM_PASTE = 758; //0x0302
WM_GETTEXT = 13; //0x000D
VK_CONTROL = 17; // CTRL
KEY_C = 67; // С
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, VK_CONTROL, 1);
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYDOWN, KEY_C, 1);
Если WinAPI.GetAsyncKeyState(VK_CONTROL) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, VK_CONTROL, 1);
КонецЕсли;
Если WinAPI.GetAsyncKeyState(KEY_C) = 0 Тогда
WinAPI.PostMessage(ДескрипторОкнаФокуса, WM_KEYUP, KEY_C, 1);
КонецЕсли;
ЭтаФорма.ПодключитьОбработчикОжидания("ОбработчикОжиданияСПараметрамиЛкс", 0.1, Истина);
КонецФункции
Функция ОткрытьРазличныеЗначенияКолонкиЛкс(Знач ТабличноеПоле) Экспорт
ирОбщий.ПолучитьФормуЛкс("Обработка.ирРазличныеЗначенияКолонки.Форма",, ТабличноеПоле).ОткрытьМодально();
КонецФункции
Процедура Форма_ВставитьСкрытуюКоманднуюПанельДляРаботыСБуферомОбменаЛкс(ЭтаФорма) Экспорт
ЭлементыФормы = ЭтаФорма.ЭлементыФормы;
ИмяКоманднойПанели = "КП_ПолеВвода";
КонтекстноеМенюФормы = ЭлементыФормы.Найти(ИмяКоманднойПанели);
Если КонтекстноеМенюФормы = Неопределено Тогда
КонтекстноеМенюФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), ИмяКоманднойПанели);
КонтекстноеМенюФормы.Видимость = Ложь;
КонецЕсли;
//лПлатформа = ирКэш.Получить();
//МакетФормы = лПлатформа.ПолучитьФорму("УниверсальныеКоманды");
//КонтекстноеМенюМакета = МакетФормы.ЭлементыФормы.КоманднаяПанель.Кнопки.ПолеВвода;
//ДобавитьКнопкиКоманднойПанелиКомпонентыЛкс(МакетФормы, КонтекстноеМенюМакета.Кнопки, КонтекстноеМенюФормы);
КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(КонтекстноеМенюФормы);
Для Каждого ЭлементФормы Из ЭлементыФормы Цикл
Если ТипЗнч(ЭлементФормы) = Тип("ПолеВвода") Тогда
Попытка
КонтекстноеМеню = ЭлементФормы.КонтекстноеМеню;
Исключение
// Поле ввода принадлежит не панели, поэтому у него нет свойства
Продолжить;
КонецПопытки;
Если КонтекстноеМеню = Неопределено Тогда
//ЭлементФормы.АвтоКонтекстноеМеню = Ложь;
ЭлементФормы.КонтекстноеМеню = КонтекстноеМенюФормы;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ДействияФормы = ЭлементыФормы.Найти("ДействияФормы");
Если ТипЗнч(ДействияФормы) <> Тип("КоманднаяПанель") Тогда
ПанельФормы = ЭтаФорма.Панель;
Если ПанельФормы.КонтекстноеМеню = Неопределено Тогда
ДействияФормы = ЭлементыФормы.Добавить(Тип("КоманднаяПанель"), "ДействияФормыАвто", Ложь);
ДействияФормы.ИсточникДействий = ЭтаФорма;
ПанельФормы.КонтекстноеМеню = ДействияФормы;
Иначе
ДействияФормы = ПанельФормы.КонтекстноеМеню;
КонецЕсли;
КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(ДействияФормы);
КонецЕсли;
КонецПроцедуры
Процедура ФормариЗакрытииЛкс(ЭтаФорма) Экспорт
ПодключитьГлобальныйОбработчикОжиданияЛкс("СохранитьНастройкиПользователяОтложенноЛкс");
КонецПроцедуры
Процедура КоманднаяПанельВставитьКнопкиБуфераОбменаЛкс(Знач КоманднаяПанельПолеВвода)
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить("МакетФормы");
КнопкаКопировать.Имя = "БуферОбмена_Копировать";
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаКопировать.Текст = "Копировать значение";
КнопкаКопировать.Картинка = ПолучитьОбщуюКартинкуЛкс("ирКопировать");
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.C, Истина, , Истина);
Попытка
КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие");
Исключение
КоманднаяПанельПолеВвода.Кнопки.Удалить(КнопкаКопировать);
Возврат;
КонецПопытки;
КнопкаКопировать = КоманднаяПанельПолеВвода.Кнопки.Добавить();
КнопкаКопировать.Имя = "БуферОбмена_Вставить";
КнопкаКопировать.ТипКнопки = ТипКнопкиКоманднойПанели.Действие;
КнопкаКопировать.Текст = "Вставить значение";
КнопкаКопировать.Картинка = ПолучитьОбщуюКартинкуЛкс("ирВставить");
КнопкаКопировать.СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша.V, Истина, , Истина);
КнопкаКопировать.Действие = Новый Действие("КлсУниверсальнаяКомандаНажатие");
КонецПроцедуры
Процедура УниверсальнаяКомандаФормыЛкс(ЭтаФОрма, Кнопка) Экспорт
Если Кнопка.Имя = "БуферОбмена_Копировать" Тогда
БуферОбмена_КопироватьЛкс(ЭтаФорма, Кнопка);
ИначеЕсли Кнопка.Имя = "БуферОбмена_Вставить" Тогда
БуферОбмена_ВставитьЛкс(ЭтаФорма, Кнопка);
КонецЕсли;
КонецПроцедуры
Процедура УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры) Экспорт
Параметры.Кнопка.СочетаниеКлавиш = Параметры.СочетаниеКлавиш;
КонецПроцедуры
Процедура БуферОбмена_УстановитьЗначениеИУстановитьСочетаниеКлавишОтложенноЛкс(Параметры) Экспорт
БуферОбмена_УстановитьЗначениеЛкс(Параметры.Значение, Параметры.ОчиститьПередУстановкой, Параметры.УстановитьТекст, Параметры.УстановитьЗначение);
УстановитьСочетаниеКлавишЭлементуФормыОтложенноЛкс(Параметры);
КонецПроцедуры
Процедура ОбработчикОжиданияСПараметрамиЛкс() Экспорт
мПлатформа = ирКэш.Получить();
ПараметрыОбработчикаОжидания = мПлатформа.ПараметрыОбработчикаОжидания;
Выполнить(ПараметрыОбработчикаОжидания.ИмяМетода + "(ПараметрыОбработчикаОжидания)");
мПлатформа.ПараметрыОбработчикаОжидания = Неопределено;
КонецПроцедуры
// Родственник ВернутьПостоянныйПарольПользователяЛкс
// Пароль устанавливается временный и опционально роль ирРазработчик
Функция УстановитьВременныеСвойстваПользователюИБЛкс(ПользовательИБ, ПодменитьПарольНаВремяЗапуска = Истина, ВременноПредоставитьПравоРазработчикИР = Истина) Экспорт
#Если _ Тогда
ПользовательИБ = ПользователиИнформационнойБазы.СоздатьПользователя();
#КонецЕсли
НужноВернутьДомен = Ложь;
НужноВыставитьПароль = Ложь;
УдалитьРольРазработчикИР = Ложь;
Если ПодменитьПарольНаВремяЗапуска Тогда
Если СтрокиРавныЛкс(ПользовательИБ.Имя, ИмяПользователя()) Тогда
Сообщить("Назначение временного пароля собственному пользователю не допускается");
Возврат Неопределено;
КонецЕсли;
мhash = ПользовательИБ.СохраняемоеЗначениеПароля;
Если ПользовательИБ.АутентификацияОС = Истина Тогда
ПользовательИБ.АутентификацияОС = Ложь;
НужноВернутьДомен = Истина;
КонецЕсли;
Если ПользовательИБ.АутентификацияСтандартная = Ложь Тогда
ПользовательИБ.АутентификацияСтандартная = Истина;
НужноВыставитьПароль = Истина;
КонецЕсли;
Пароль = Формат(ТекущаяДата(), "ДФ=HHmmss") + XMLСтрока(НомерСеансаИнформационнойБазы()) + "!_qQ";
ПользовательИБ.Пароль = Пароль;
КонецЕсли;
Если ВременноПредоставитьПравоРазработчикИР И Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
Если Не ПользовательИБ.Роли.Содержит(Метаданные.Роли.ирРазработчик) Тогда
УдалитьРольРазработчикИР = Истина;
ПользовательИБ.Роли.Добавить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
КонецЕсли;
ПользовательИБ.Записать();
НаборПараметров = Новый Структура();
НаборПараметров.Вставить("mHash", мhash);
НаборПараметров.Вставить("НужноВыставитьПароль", НужноВыставитьПароль);
НаборПараметров.Вставить("НужноВернутьДомен", НужноВернутьДомен);
НаборПараметров.Вставить("ПользовательИБ", ПользовательИБ);
НаборПараметров.Вставить("УдалитьРольРазработчикИР", УдалитьРольРазработчикИР);
НаборПараметров.Вставить("Имя", ПользовательИБ.Имя);
НаборПараметров.Вставить("Пароль", Пароль);
Возврат НаборПараметров;
КонецФункции
// Родственник УстановитьВременныеСвойстваПользователюИБЛкс
Процедура ВернутьПостоянныеСвойстваПользователюИБЛкс(НаборПараметров = Неопределено) Экспорт;
//УстановитьПривилегированныйРежим(Истина);
Если НЕ НаборПараметров = Неопределено Тогда
мhash = НаборПараметров.mhash;
НужноВыставитьПароль = НаборПараметров.НужноВыставитьПароль;
НужноВернутьДомен = НаборПараметров.НужноВернутьДомен;
ПользовательИБ = НаборПараметров.ПользовательИБ;
УдалитьРольРазработчикИР = НаборПараметров.УдалитьРольРазработчикИР;
Иначе
Возврат;
КонецЕсли;
ПользовательИБ.СохраняемоеЗначениеПароля = мHash;
Если НужноВыставитьПароль Тогда
Пользовательиб.АутентификацияСтандартная = Ложь;
КонецЕсли;
Если НужноВернутьДомен Тогда
Пользовательиб.АутентификацияОС = Истина;
КонецЕсли;
Если УдалитьРольРазработчикИР Тогда
ПользовательИБ.Роли.Удалить(Метаданные.Роли.ирРазработчик);
КонецЕсли;
ПользовательИБ.Записать();
КонецПроцедуры
Процедура ОткрытьСписокИнструментовЛкс() Экспорт
ФормаСпискаИнструментов = ПолучитьФорму("Обработка.ирПортативный.Форма");
ФормаСпискаИнструментов.ПараметрТолькоОткрытьНастройки = Истина;
ФормаСпискаИнструментов.Открыть();
КонецПроцедуры
Процедура ОткрытьМенеджерТабличногоПоляЛкс(ТабличноеПоле, ЭтаФорма) Экспорт
ирОбщий.ПолучитьФормуЛкс("Обработка.ирПлатформа.Форма.МенеджерТабличногоПоля", , ЭтаФорма).УстановитьСвязь(ТабличноеПоле);
КонецПроцедуры
Функция РежимСовместимостиМеньше8_3_4Лкс() Экспорт
Возврат Ложь
Или ирКэш.Получить().ВерсияПлатформы < 803004
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_3
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_2
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_3_1
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_2_16
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_2_13
Или Метаданные.РежимСовместимости = Метаданные.СвойстваОбъектов.РежимСовместимости.Версия8_1;
КонецФункции
#КонецЕсли
// Проверяет, отвечает ли строка правилам формирования имен переменных встроенного языка.
//
// Параметры:
// Строка Строка.
//
// Возвращаемое значение:
// Булево.
//
Функция ЛиИмяПеременнойЛкс(Строка) Экспорт
Если ПустаяСтрока(Строка) Тогда
Возврат Ложь;
КонецЕсли;
Пустышка = Новый Структура;
Попытка
Пустышка.Вставить(Строка);
Возврат Истина;
Исключение
Возврат Ложь;
КонецПопытки;
КонецФункции // ЛиИмяПеременнойЛкс()
// Пространство имен текущей конфигурации иис Возвращаемое значение:
//
Функция ПространствоИменТекущейКонфигурацииЛкс() Экспорт
Возврат "http://v8.1c.ru/8.1/data/enterprise/current-config";
КонецФункции
Функция БезопасноПолучитьЗначениеСвойстваЛкс(ЭлементФормы, Знач ИмяСвойстваЗаголовка) Экспорт
СтруктураЗначений = Новый Структура(ИмяСвойстваЗаголовка);
ЗаполнитьЗначенияСвойств(СтруктураЗначений, ЭлементФормы);
ЗаголовокЭлемента = СтруктураЗначений[ИмяСвойстваЗаголовка];
Возврат ЗаголовокЭлемента;
КонецФункции
Функция ВосстановитьТекущуюСтрокуТаблицыФормыЛкс(ТаблицаФормы, Знач КлючТекущейСтроки, ДанныеТаблицы = Неопределено, ИмяКлючевойКолонки = "Ссылка") Экспорт
Если КлючТекущейСтроки <> Неопределено Тогда
Если ДанныеТаблицы = Неопределено Тогда
ДанныеТаблицы = ТаблицаФормы.Значение;
КонецЕсли;
Если ТипЗнч(КлючТекущейСтроки) <> Тип("Структура") Тогда
КлючТекущейСтроки = Новый Структура(ИмяКлючевойКолонки, КлючТекущейСтроки);
КонецЕсли;
НайденныеСтроки = ДанныеТаблицы.НайтиСтроки(КлючТекущейСтроки);
Если НайденныеСтроки.Количество() > 0 Тогда
Строка = НайденныеСтроки[0];
Попытка
ИдентификаторСтроки = Строка.ПолучитьИдентификатор();
Исключение
ИдентификаторСтроки = Строка;
КонецПопытки;
ТаблицаФормы.ТекущаяСтрока = ИдентификаторСтроки;
Возврат Истина;
КонецЕсли;
КонецЕсли;
Возврат Ложь;
КонецФункции
Функция ПолучитьКлючТекущейСтрокиЛкс(ТаблицаФормы, ИмяКлючевойКолонки = "Ссылка") Экспорт
ТекущиеДанные = ТаблицаФормы.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
КлючТекущейСтроки = ТекущиеДанные[ИмяКлючевойКолонки];
КонецЕсли;
Возврат КлючТекущейСтроки;
КонецФункции