//ирПортативный Перем ирПортативный Экспорт; //ирПортативный Перем ирОбщий Экспорт; //ирПортативный Перем ирСервер Экспорт; //ирПортативный Перем ирКэш Экспорт; //ирПортативный Перем ирКлиент Экспорт; Перем ЧистыйКонтекст; Перем ФиксироватьВнешниеИсключенияАлгоритмов Экспорт; Перем ВерсияПлатформы Экспорт; Перем ЭтоФайловаяБаза Экспорт; Перем мМетаданные Экспорт; Перем мПустойМодуль; Перем ЭтоИнтеграция Экспорт; Перем СоответствиеВидовСравнения Экспорт; Перем МаркерНачалаАлгоритма Экспорт; Перем МаркерКонцаАлгоритма Экспорт; Перем МакетыКомпонент Экспорт; Перем мКэшПустыхЗначений Экспорт; Перем ВложенностьИндикации Экспорт; Перем КэшОбъектов Экспорт; Перем ВремяОбъект Экспорт; Перем СловарьПеревода Экспорт; Перем АрхитектураПроцессора Экспорт; Перем ВыполнятьАлгоритмыЧерезВнешниеОбработки Экспорт; Перем ВнешняяОбработкаСервисы Экспорт; Перем ФайловыйКэшАлгоритмовДопускаетРедактирование Экспорт; Перем ФормаПустышка Экспорт; Перем КешАлгоритмов; Перем СубПутьКФайлуПотокаМодуляВнешнейОбработки; Перем СубПутьКФайлуПотокаМакетаВнешнейОбработки; Перем СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки; Перем СубПутьККонтрольномуФайлуВнешнейОбработки; Перем ПутьККаталогуСлужебныхВременныхФайлов; Перем мЕстьАдминистративныеПраваУУчетнойЗаписиОС; Перем СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось; Перем ПапкаКешаВнешнихОбработокАлгоритмов Экспорт; Перем ПапкаВнешнихКомпонент Экспорт; Перем ПапкаКэшаМодулей Экспорт; Перем ПапкаКэшаРолей Экспорт; Перем КаталогФайловогоКэша Экспорт; Перем СтруктураПодкаталоговФайловогоКэша Экспорт; Перем ИмяФайлаПакера Экспорт; Перем ШаблоныВнешнейОбработки; Перем ШаблоныВнешнейОбработкиСМакетом; Перем ФайлРегистратораКомпонентCU; Перем ФайлРегистратораNetКомпонент; Перем МассивСравненияТекстов Экспорт; Перем мВопросОтключенияПроверкиМодальностиЗадавался Экспорт; Перем мПроверкаСовместимостиКонфигурацииВыполнялась Экспорт; Перем мПроверкаЗащитыОтОпасныхДействийВыполнялась Экспорт; Перем мПроверкаСоединенияADOЭтойБДВыполнялась Экспорт; Перем мПерехватКлавиатуры; Перем АсинхронностьЗапрещена Экспорт; Перем РежимОтладки Экспорт; // Отключает использование однострочных сверток кода. Снижает скорость, но облегчает отладку. Перем НастройкиКомпьютера Экспорт; Перем мДиалектыSQL Экспорт; // Используется в Обработка.ирКлсПолеТекстаПрограммы Перем WScriptShell; Перем RegExp Экспорт; // ОбработкаОбъект.ирОболочкаРегВыражение Перем RegExp2 Экспорт; // ОбработкаОбъект.ирОболочкаРегВыражение Перем шЛюбой Экспорт; Перем шБуква Экспорт; Перем шБукваЦифра Экспорт; Перем шИмя Экспорт; Перем шЧисло Экспорт; Перем шИндекс Экспорт; Перем шСкобки Экспорт; Перем шGUID Экспорт; Перем шКомментарий Экспорт; Перем шРазделитель Экспорт; Перем шПустоеНачалоСтроки Экспорт; Перем шСтрокаПрограммы Экспорт; Перем шСтрокаПростая Экспорт; Перем шСтрокаЗапроса Экспорт; Перем шИмяВременнойТаблицы Экспорт; Перем шГиперСсылка Экспорт; Перем МаркерОбъектаМетаданных; Перем МаркерКоллекцииОбъектовМетаданных; //#Если Клиент Или ВнешнееСоединение Тогда Перем ИдентификаторПроцессаОС Экспорт; Перем VBScript Экспорт; Перем JavaScript Экспорт; Перем ДеревоТипов Экспорт; Перем ТаблицаОбщихТипов Экспорт; Перем ТаблицаИменЭлементовКоллекций Экспорт; Перем ТаблицаРасширенийТипов Экспорт; Перем ТаблицаШаблоновКонтекстов Экспорт; Перем ТаблицаТиповМетаОбъектов Экспорт; Перем ТаблицаПараметров Экспорт; Перем СлужебноеПолеТекста Экспорт; Перем СлужебноеПолеТекста2 Экспорт; //Перем СлужебноеПолеHtmlДокумента Экспорт; Перем МассивОбычныхЭлементовУправления Экспорт; Перем МассивУправляемыхЭлементовУправления Экспорт; Перем мМассивТиповЭлементовОбычнойФормы Экспорт; Перем ТаблицаСтатистикиВыбора Экспорт; Перем мМассивТиповСМетаданными Экспорт; Перем мТаблицаТипов; // см. НоваяТаблицаТипов Перем мТаблицаСоответствияВидов; Перем мТаблицаЗамеров Экспорт; Перем мТаблицаИндикаторов Экспорт; Перем мИменаОсновныхКлассовБиблиотекCOM; // Кэш имен классов, например Exel - Application Перем мОбразцыCOMОбъектов; // Для вычисления свойств Перем мADOUtils; // GameWithFire.ADOUtils Перем мКэшСловГлобальногоКонтекста; Перем мКолонкиБД Экспорт; Перем мСтруктураХраненияБДСРазмерами Экспорт; Перем мТаблицаРедактируемыхТипов; Перем мОписаниеТипаМДТабличнаяЧасть; Перем мОписаниеТипаМДВнешнийИсточникДанных; Перем мДеревоОбъектовМД; Перем мТаблицаВсехТаблицБД; Перем мПоляТекстаПрограммы; Перем мШаблоныДляАнализаВстроенногоЯзыка; Перем мСлужебнаяФорма; Перем COMНавигатор Экспорт; Перем ТаблицаШаблоновТекста Экспорт; Перем мКартинкиТипов; Перем мМассивИсключенийИменКоллекций; Перем мПассивныеФормы; Перем мИменаТиповМетаданныхСМенеджерами; Перем мКэшРазбораВыражений Экспорт; Перем ФайлЗапаковщика1С Экспорт; Перем ФайлБиблиотекиЗапаковщика; Перем ФайлОткрывателя1С Экспорт; Перем ФайлФорматераЗапросовБД Экспорт; Перем ФайлРаспаковщикаZIP Экспорт; Перем СинтаксПомощник; Перем Парсеры Экспорт; Перем БуферыСравнения Экспорт; Перем ПараметрыОбработчикаОжидания Экспорт; Перем БазовыйФайлРедактораJSON; Перем БазовыйФайлРедактораКода; Перем мМаркерИмениЗапросаПакета Экспорт; Перем мМаркерИмениЧастиОбъединения Экспорт; Перем ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов Экспорт; Перем СинтаксическийКонтрольПередЗаписью Экспорт; Перем ОтложенноеОткрытиеИсточникаОшибки Экспорт; Перем АвторегистрацияComКомпонент Экспорт; Перем ЛиКомпонентаFormsTextBoxДоступна; Перем МодальныеГруппы Экспорт; Перем мМодулиМетаданных; Перем мВызовыВсехСловПоМодулям; Перем ОткрытыеФормыПодсистемы Экспорт; Перем ОтслеживаемыеФормы Экспорт; Перем ПерехватКлавиатурногоВводаВОбычномПриложении Экспорт; Перем ОтмененныеФоновыеЗадания Экспорт; Перем ВнутреннийБуферОбмена Экспорт; Перем ПроверочноеСоединениеЭтойСУБД Экспорт; Перем ИспользоватьЭмуляциюНажатияКлавиш Экспорт; Перем ВыделениеРезультатовПоиска Экспорт; Перем НеИспользоватьУправляемыеФормыИнструментов Экспорт; Перем мСвязанныйКонфигуратор Экспорт; Перем мДатаОбновленияКэшаМодулей; Перем мДобавленныеОбщиеМодули; // Инициализирует, если необходимо, большие таблицы платформы. // К ним относятся таблицы методов и свойств. // // Параметры: // Нет. // Процедура ИнициацияОписанияМетодовИСвойств() Экспорт Если ТаблицаКонтекстов.Количество() > 0 Тогда Возврат; КонецЕсли; #Если Клиент Тогда Состояние("Инициализация таблицы методов и свойств..."); #КонецЕсли МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаМетодовИСвойств").ПолучитьТекст()); ТаблицаКонтекстов = МассивТаблиц.ТаблицаКонтекстов; // ТаблицаЗначений //! ТаблицаКонтекстов.Колонки.Добавить("ТипКонтекста"); //! ТаблицаКонтекстов.Колонки.Добавить("ЯзыкПрограммы"); //! ТаблицаКонтекстов.Колонки.Добавить("ТипЯзыка"); //! ТаблицаКонтекстов.Колонки.Добавить("Слово"); //! ТаблицаКонтекстов.Колонки.Добавить("НСлово"); //! ТаблицаКонтекстов.Колонки.Добавить("ТипСлова"); //! ТаблицаКонтекстов.Колонки.Добавить("НомерВерсииПлатформы"); ТаблицаКонтекстов.Колонки.Добавить("Описание"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова"); ТаблицаШаблоновКонтекстов = МассивТаблиц.ТаблицаШаблоновКонтекстов; // ТаблицаЗначений //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("ТипКонтекста"); //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("ЯзыкПрограммы"); //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("ТипЯзыка"); //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("Слово"); //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("НСлово"); //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("ТипСлова"); //! ТаблицаШаблоновКонтекстов.Колонки.Добавить("НомерВерсииПлатформы"); ТаблицаШаблоновКонтекстов.Колонки.Добавить("Описание"); // Нужно для вирт. таблицы КритерийОтбора.<Имя критерия отбора>() ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста"); ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка"); ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова"); ТаблицаПараметров = МассивТаблиц.ТаблицаПараметров; // ТаблицаЗначений - Теперь на старте пустая //! ТаблицаПараметров.Колонки.Добавить("ТипКонтекста"); //! ТаблицаПараметров.Колонки.Добавить("ЯзыкПрограммы"); //! ТаблицаПараметров.Колонки.Добавить("Слово"); //! ТаблицаПараметров.Колонки.Добавить("Номер"); ТаблицаПараметров.Колонки.Добавить("Описание"); ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово"); //ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово, Номер"); #Если Клиент Тогда Состояние(""); #КонецЕсли КонецПроцедуры // Инициализирует, если необходимо, малые таблицы платформы. // К ним относятся таблицы типов и коллекций. // // Параметры: // Нет. // Процедура ИнициализацияОписанияОбщихТипов() Экспорт Если ТипЗнч(ТаблицаОбщихТипов) = Тип("ТаблицаЗначений") Тогда Возврат; КонецЕсли; МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаИменЭлементовКоллекций").ПолучитьТекст()); ТаблицаИменЭлементовКоллекций = МассивТаблиц.ТаблицаИменЭлементовКоллекций; #Если Сервер И Не Сервер Тогда ТаблицаИменЭлементовКоллекций = НОвый ТаблицаЗначений; #КонецЕсли ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяКоллекции"); ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяЭлементаКоллекции"); ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяОбщегоТипа, ИмяЭлементаКоллекции"); ТаблицаРасширенийТипов = МассивТаблиц.ТаблицаРасширений; #Если Сервер И Не Сервер Тогда ТаблицаРасширенийТипов = НОвый ТаблицаЗначений; #КонецЕсли ТаблицаРасширенийТипов.Индексы.Добавить("Расширение"); МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаОбщихТипов").ПолучитьТекст()); ТаблицаОбщихТипов = МассивТаблиц.ТаблицаОбщихТипов; #Если Сервер И Не Сервер Тогда ТаблицаОбщихТипов = НОвый ТаблицаЗначений; #КонецЕсли //! ТаблицаОбщихТипов.Колонки.Добавить("БазовыйТип"); //! ТаблицаОбщихТипов.Колонки.Добавить("ЕстьКонструктор"); //! ТаблицаОбщихТипов.Колонки.Добавить("ТипТипа"); //! ТаблицаОбщихТипов.Колонки.Добавить("ЯзыкПрограммы"); //! ТаблицаОбщихТипов.Колонки.Добавить("Слово"); //! ТаблицаОбщихТипов.Колонки.Добавить("НСлово"); ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы"); ТаблицаОбщихТипов.Индексы.Добавить("Слово, ТипТипа"); //ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы, ТипТипа"); ТаблицаОбщихТипов.Индексы.Добавить("НСлово, ЯзыкПрограммы, ЕстьКонструктор"); ТаблицаОбщихТипов.Индексы.Добавить("Представление, ТипТипа"); ТаблицаОбщихТипов.Индексы.Добавить("ИД"); ТаблицаОбщихТипов.Индексы.Добавить("БазовыйТип, ЯзыкПрограммы"); КонецПроцедуры // Добавляет дополнительные Свойства для типов контекстов платформы. Процедура ДобавитьСловоВОписаниеТипаКонтекста(ТипКонтекста, Слово, ТипСлова, ТипЗначения) Экспорт ИнициацияОписанияМетодовИСвойств(); НоваяСтрока = ТаблицаКонтекстов.Добавить(); НоваяСтрока.ТипКонтекста = ТипКонтекста; НоваяСтрока.Слово = Слово; НоваяСтрока.НСлово = НРег(Слово); НоваяСтрока.ТипСлова = ТипСлова; НоваяСтрока.ТипЗначения = ТипЗначения; КонецПроцедуры // Добавляет в список значений коллекцию объектов метаданных. // // Параметры: // пСписокМетаданных - СписокЗначений - куда добавляем объекты; // пИмяМетаданных - Строка - имя коллекции объектов метаданных или имя корневого типа; // *ЛиПолноеИмя - Булево, *Истина - добавлять полные имена, иначе краткие; // *ЛиДобавлятьКартинки - Булево, *Истина - добавлять картинки; // *ОтборПоПраву - Строка, *Неопределено - проверять перед добавлением право текущего пользователя. // Процедура ДобавитьВСписокКоллекциюМетаданных(пСписокМетаданных, пИмяМетаданных, ЛиПолноеИмя = Истина, ЛиДобавлятьКартинки = Истина, ОтборПоПраву = Неопределено) Экспорт Картинка = Неопределено; СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(пИмяМетаданных, , 0); Если СтрокаКорневогоТипа <> Неопределено Тогда ИмяКоллекцииМетаданных = СтрокаКорневогоТипа.Множественное; #Если Клиент Тогда Если ЛиДобавлятьКартинки Тогда КорневойТип = пИмяМетаданных; Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип); КонецЕсли; #КонецЕсли Иначе ИмяКоллекцииМетаданных = пИмяМетаданных; #Если Клиент Тогда Если ЛиДобавлятьКартинки Тогда КорневойТип = ОписаниеТипаМетаОбъектов(, пИмяМетаданных, 0).Единственное; Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип); КонецЕсли; #КонецЕсли КонецЕсли; Для Каждого Объект ИЗ мМетаданные[ИмяКоллекцииМетаданных] Цикл Если Истина И ОтборПоПраву <> Неопределено И Не ПравоДоступа(ОтборПоПраву, Объект) Тогда Продолжить; КонецЕсли; Если ЛиПолноеИмя Тогда ИмяМетаОбъекта = Объект.ПолноеИмя(); Иначе ИмяМетаОбъекта = Объект.Имя; КонецЕсли; пСписокМетаданных.Добавить(ИмяМетаОбъекта, Объект.Представление(), , Картинка); КонецЦикла; КонецПроцедуры // Получает список ключевых слов языка запросов. // // Параметры: // *Расширение - Тип, *Неопределено - для определения расширения языка запросов. // // Возвращаемое значение: // СписокЗначений - где значение содержит слово. // Функция КлючевыеСловаЯзыкаЗапросов(РежимКомпоновкиДанных = Ложь, Русские = Истина, Английские = Ложь) Экспорт Список = Новый СписокЗначений; Если Русские Тогда Список.Добавить("АВТОУПОРЯДОЧИВАНИЕ"); Список.Добавить("ВНУТРЕННЕЕ"); Список.Добавить("ВОЗР"); Список.Добавить("ВСЕ"); Список.Добавить("ВЫБРАТЬ"); Список.Добавить("ГДЕ"); Список.Добавить("ДЛЯ"); Список.Добавить("ИЗ"); Список.Добавить("ИЗМЕНЕНИЯ"); Список.Добавить("ИМЕЮЩИЕ"); Список.Добавить("ИНДЕКСИРОВАТЬ"); Список.Добавить("ИТОГИ"); Список.Добавить("КАК"); Список.Добавить("ЛЕВОЕ"); Список.Добавить("ОБЩИЕ"); Список.Добавить("ОБЪЕДИНИТЬ"); Список.Добавить("ПЕРВЫЕ"); Список.Добавить("ПО"); Список.Добавить("ПОЛНОЕ"); Список.Добавить("ПОМЕСТИТЬ"); Список.Добавить("ПРАВОЕ"); Список.Добавить("РАЗЛИЧНЫЕ"); Список.Добавить("РАЗРЕШЕННЫЕ"); Список.Добавить("СГРУППИРОВАТЬ"); Список.Добавить("СОЕДИНЕНИЕ"); Список.Добавить("УБЫВ"); Список.Добавить("УНИЧТОЖИТЬ"); Список.Добавить("УПОРЯДОЧИТЬ"); Список.Добавить("НЕ"); Список.Добавить("И"); Список.Добавить("ИЛИ"); Список.Добавить("ВЫБОР"); Список.Добавить("КОГДА"); Список.Добавить("ТОГДА"); Список.Добавить("ИНАЧЕ"); Список.Добавить("КОНЕЦ"); Список.Добавить("ЕСТЬ"); Список.Добавить("NULL"); Список.Добавить("МЕЖДУ"); Список.Добавить("В"); Список.Добавить("ПОДОБНО"); Список.Добавить("СПЕЦСИМВОЛ"); Список.Добавить("ИЕРАРХИЯ"); Список.Добавить("ИЕРАРХИИ"); Список.Добавить("ССЫЛКА"); Если РежимКомпоновкиДанных Тогда // Видимо это устаревшие слова Список.Добавить("ЗНАЧЕНИЕ"); Список.Добавить("ЗНАЧЕНИЯ"); Список.Добавить("ИДЕНТИФИКАТОР"); Список.Добавить("ИМЯ"); Список.Добавить("ОБЪЕКТ"); Список.Добавить("СПИСОК"); Список.Добавить("ТИПЗНАЧЕНИЯ"); Список.Добавить("ХАРАКТЕРИСТИКА"); // Это новые слова Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК"); Список.Добавить("ПОЛЕИМЕНИ"); Список.Добавить("ПОЛЕКЛЮЧА"); Список.Добавить("ПОЛЕЗНАЧЕНИЯ"); Список.Добавить("ПОЛЕВИДА"); Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ"); Список.Добавить("ПОЛЕОБЪЕКТА"); Список.Добавить("ВИДЫХАРАКТЕРИСТИК"); КонецЕсли; КонецЕсли; Если Английские Тогда Список.Добавить("AUTOORDER"); Список.Добавить("INNER"); Список.Добавить("ASC"); Список.Добавить("ALL"); Список.Добавить("SELECT"); Список.Добавить("WHERE"); Список.Добавить("FOR"); Список.Добавить("FROM"); Список.Добавить("UPDATE"); Список.Добавить("HAVING"); Список.Добавить("INDEX"); Список.Добавить("TOTALS"); Список.Добавить("AS"); Список.Добавить("LEFT"); //Список.Добавить("ОБЩИЕ"); // ЗАБЫЛ перевод Список.Добавить("UNION"); Список.Добавить("FIRST"); Список.Добавить("BY"); Список.Добавить("ON"); Список.Добавить("FULL"); Список.Добавить("INTO"); Список.Добавить("RIGHT"); Список.Добавить("DISTINCT"); Список.Добавить("ALLOWED"); Список.Добавить("GROUP"); Список.Добавить("JOIN"); Список.Добавить("DESC"); Список.Добавить("DROP"); Список.Добавить("ORDER"); Список.Добавить("NOT"); Список.Добавить("AND"); Список.Добавить("OR"); Список.Добавить("CASE"); Список.Добавить("WHEN"); Список.Добавить("THEN"); Список.Добавить("ELSE"); Список.Добавить("END"); Список.Добавить("IS"); Список.Добавить("NULL"); Список.Добавить("BETWEEN"); Список.Добавить("IN"); Список.Добавить("LIKE"); Список.Добавить("СПЕЦСИМВОЛ"); Список.Добавить("HIERARCHY"); Список.Добавить("REFS"); //Если РежимКомпоновкиДанных Тогда // // Видимо это устаревшие слова // Список.Добавить("VALUE"); // Список.Добавить("VALUES"); // Список.Добавить("IDENTIFICATOR"); // Список.Добавить("NAME"); // Список.Добавить("OBJECT"); // Список.Добавить("LIST"); // Список.Добавить("VALUETYPE"); // Список.Добавить("CHARACTERISTIC"); // // Это новые слова // Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК"); // Список.Добавить("ПОЛЕИМЕНИ"); // Список.Добавить("ПОЛЕКЛЮЧА"); // Список.Добавить("ПОЛЕЗНАЧЕНИЯ"); // Список.Добавить("ПОЛЕВИДА"); // Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ"); // Список.Добавить("ПОЛЕОБЪЕКТА"); // Список.Добавить("ВИДЫХАРАКТЕРИСТИК"); //КонецЕсли; КонецЕсли; Возврат Список; КонецФункции // ПолучитьСписокСловЯзыкаЗапросов() // Получает список ключевых встроенного языка. // // Параметры: // Нет. // // Возвращаемое значение: // СписокЗначений - где значение содержит слово. // Функция КлючевыеСловаВстроенногоЯзыка() Экспорт Список = Новый СписокЗначений; Список.Добавить("Знач"); Список.Добавить("Val"); Список.Добавить("Возврат"); Список.Добавить("Return"); Список.Добавить("ВызватьИсключение"); Список.Добавить("Raise"); Список.Добавить("Выполнить"); Список.Добавить("Execute"); Список.Добавить("Для"); Список.Добавить("For"); Список.Добавить("Если"); Список.Добавить("If"); Список.Добавить("И"); Список.Добавить("And"); Список.Добавить("Из"); Список.Добавить("In"); // аналог В (запрос) и ИЗ (встроенный) Список.Добавить("Или"); Список.Добавить("Or"); Список.Добавить("Иначе"); Список.Добавить("Else"); Список.Добавить("ИначеЕсли"); Список.Добавить("ElsIf"); Список.Добавить("Исключение"); Список.Добавить("Except"); Список.Добавить("Каждого"); Список.Добавить("Each"); Список.Добавить("КонецЕсли"); Список.Добавить("EndIf"); Список.Добавить("КонецПопытки"); Список.Добавить("EndTry"); Список.Добавить("КонецПроцедуры"); Список.Добавить("EndProcedure"); Список.Добавить("КонецФункции"); Список.Добавить("EndFunction"); Список.Добавить("КонецЦикла"); Список.Добавить("EndDo"); Список.Добавить("Не"); Список.Добавить("Not"); Список.Добавить("Новый"); Список.Добавить("New"); Список.Добавить("Перейти"); Список.Добавить("Goto"); Список.Добавить("Перем"); Список.Добавить("Var"); Список.Добавить("По"); Список.Добавить("To"); Список.Добавить("Пока"); Список.Добавить("While"); Список.Добавить("Попытка"); Список.Добавить("Try"); Список.Добавить("Прервать"); Список.Добавить("Break"); Список.Добавить("Продолжить"); Список.Добавить("Continue"); Список.Добавить("Процедура"); Список.Добавить("Procedure"); Список.Добавить("Тогда"); Список.Добавить("Then"); Список.Добавить("Функция"); Список.Добавить("Function"); Список.Добавить("Цикл"); Список.Добавить("Do"); Список.Добавить("Экспорт"); Список.Добавить("Export"); // 8.3 Список.Добавить("Ждать"); Список.Добавить("Await"); Список.Добавить("Асинх"); Список.Добавить("Async"); //// Инструкции препроцессора. Добавлено 28.01.2012 //// Здесь им не место, т.к. по этому списку проверяется валидность имен переменных //Список.Добавить("Клиент"); //Список.Добавить("Сервер"); //Список.Добавить("ВнешнееСоединение"); //Список.Добавить("ТолстыйКлиентУправляемоеПриложение"); //Список.Добавить("ТолстыйКлиентОбычноеПриложение"); //Список.Добавить("ТонкийКлиент"); //Список.Добавить("ВебКлиент"); Возврат Список; КонецФункции Функция ЛитералыЗначенияВсехЯзыков1С() Экспорт Список = Новый СписокЗначений; Список.Добавить("Истина", "Истина"); Список.Добавить("True", "Истина"); Список.Добавить("Ложь", "Ложь"); Список.Добавить("False", "Ложь"); Список.Добавить("Неопределено", "Неопределено"); Список.Добавить("Undefined", "Неопределено"); Список.Добавить("Null", "Null"); Возврат Список; КонецФункции // Размаскирует обращения к временным таблицам в тексте запроса. // // Параметры: // ТекстЗапроса - Строка; // МассивВременныхТаблиц - Массив - элементами являются имена временных таблиц, замаскированных ранее. // // Возвращаемое значение: // Строка - новые текст запроса. // Функция РазмаскироватьВременныеТаблицы(ТекстЗапроса, МассивВременныхТаблиц, выхВсеРазмаскировано = Ложь) Экспорт Если МассивВременныхТаблиц.Количество() = 0 Тогда Возврат ТекстЗапроса; КонецЕсли; // Допустимы 2 уровня скобок внутри имитатора временной таблицы. RegExp.Global = Истина; RegExp.MultiLine = Ложь; RegExp.IgnoreCase = Истина; ИмяВременнойТаблицы = ""; Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл ИмяВременнойТаблицы = ИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица; КонецЦикла; ИмяВременнойТаблицы = Сред(ИмяВременнойТаблицы, 2); НовыйТекстЗапроса = ТекстЗапроса; // Сначала делаем красивые замены - подзапрос на имя временной таблицы //RegExp.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")""\)"; RegExp.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")""\s*\)"; НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "$2"); выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0; Если Не выхВсеРазмаскировано Тогда // А теперь делаем некрасивые замены - оставляем подзапросы но заменяем в них имена полей и временной таблицы RegExp.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")"""; НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "(ВЫБРАТЬ Т.* ИЗ $2 КАК Т ГДЕ ИСТИНА"); // и0ие90цаун787 RegExp.Pattern = "ВЫБОР\s+КОГДА\s+""!ИмяПоля!""\s+=\s+""(.+?)""\s+ТОГДА\s+.+?\n\s*(?:КОГДА\s+ЛОЖЬ\s+ТОГДА\s+.+?\n)*\s*КОНЕЦ"; НовыйТекстЗапроса = RegExp.Заменить(НовыйТекстЗапроса, "Т.$1"); выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0; КонецЕсли; Если Не выхВсеРазмаскировано Тогда ВызватьИсключение "Не удалось размаскировать временные таблицы в тексте запроса. Возможно на них был наложен несовместимый с маскировкой отбор компоновки."; КонецЕсли; Возврат НовыйТекстЗапроса; КонецФункции // РазмаскироватьВременныеТаблицы() // Получает текст запроса, где каждая временная таблица заменена своим имитатором. // // Параметры: // ОбъектЗапроса - Запрос - // *ТекстЗапроса - Строка, *Неопределено - // *МассивВременныхТаблиц - Массив, *Неопределено - все подменяемые таблицы заносятся сюда. // // Возвращаемое значение: // Строка - новый текст запроса. // Функция ЗамаскироватьВременныеТаблицы(ОбъектЗапроса, Знач ТекстЗапроса = Неопределено, МассивВременныхТаблиц = Неопределено) Экспорт Если ТекстЗапроса = Неопределено Тогда ТекстЗапроса = ОбъектЗапроса.Текст; КонецЕсли; ВременныйЗапрос = Новый Запрос; ВременныйЗапрос.МенеджерВременныхТаблиц = ОбъектЗапроса.МенеджерВременныхТаблиц; ПроверочныйЗапрос = Новый ПостроительЗапроса; //// Исключительная ситуация должна быть обработана сверху //ПараметрыЗапроса = ВременныйЗапрос.НайтиПараметры(); Если ТипЗнч(МассивВременныхТаблиц) <> Тип("Массив") Тогда МассивВременныхТаблиц = Новый Массив; КонецЕсли; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстЗапроса); Пока Истина Цикл Попытка ПроверочныйЗапрос.Текст = ТекстЗапроса; //ПроверочныйЗапрос.НайтиПараметры(); Прервать; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); //ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, """", """"); ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Таблица не найдена """, """", Ложь); Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы; Попытка КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки; Исключение Прервать; КонецПопытки; КонецЕсли; // В 8.2.15 такой прием лишен смысла, т.к. движок запросов потом не сможет обработать обращения к дочерним полям //Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда // ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Неверные параметры """, """", Ложь); // Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда // Попытка // КолонкиВременнойТаблицы = ОбъектЗапроса.Параметры[ИмяВременнойТаблицы].Колонки; // Исключение // Попытка // КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки; // Исключение // Прервать; // КонецПопытки; // КонецПопытки; // ИмяВременнойТаблицы = "&" + ИмяВременнойТаблицы; // КонецЕсли; //КонецЕсли; Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда Прервать; КонецЕсли; ИмитаторВременнойТаблицы = ирОбщий.ЗапросИмитаторКоллекцииПолейЛкс(КолонкиВременнойТаблицы) + " ГДЕ ""ВременнаяТаблица"" = """ + ИмяВременнойТаблицы + """"; КоординатыОбращения = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{(", ")}"); НомерСтроки = Число(ирОбщий.ПервыйФрагментЛкс(КоординатыОбращения, ", ")); НомерКолонки = Число(ирОбщий.ПоследнийФрагментЛкс(КоординатыОбращения, ",")); СтрокаЗапроса = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки); ТекстПосле = Сред(СтрокаЗапроса, НомерКолонки + СтрДлина(ИмяВременнойТаблицы)); СтрокаКАК = "КАК"; Если Не ирОбщий.СтрокиРавныЛкс(Лев(СокрЛ(ТекстПосле), СтрДлина(СтрокаКАК)), СтрокаКАК) Тогда ТекстПосле = " КАК " + ИмяВременнойТаблицы + " " + ТекстПосле; КонецЕсли; НоваяСтрока = Лев(СтрокаЗапроса, НомерКолонки - 1) + "(" + ИмитаторВременнойТаблицы + ")" + ТекстПосле; ТекстовыйДокумент.ЗаменитьСтроку(НомерСтроки, НоваяСтрока); ТекстЗапроса = ТекстовыйДокумент.ПолучитьТекст(); МассивВременныхТаблиц.Добавить(ИмяВременнойТаблицы); КонецПопытки; КонецЦикла; Возврат ТекстЗапроса; КонецФункции // Результат - Массив Функция НайтиВозможныеИменаВременныхТаблиц(ТекстЗапроса, ЛиДиалект1С = Истина) Экспорт Имена = Новый Соответствие; RegExp.Global = Истина; RegExp.pattern = "(?:ИЗ|FROM|СОЕДИНЕНИЕ|JOIN|УНИЧТОЖИТЬ|DROP|,)\s+(" + шИмяВременнойТаблицы + ")(?:\s|$|[^\(\._\d" + шБуква + "])"; РезультатПоиска = RegExp.НайтиВхождения(ТекстЗапроса); Для Каждого Вхождение Из РезультатПоиска Цикл Имена.Вставить(Нрег(Вхождение.SubMatches(0)), Вхождение.SubMatches(0)); КонецЦикла; Результат = Новый Массив(); Для Каждого КлючИЗначение Из Имена Цикл Если Истина И ЛиДиалект1С И (Ложь Или ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Значение, "Константы") Или Найти(КлючИЗначение.Значение, ".") > 0) Тогда Продолжить; КонецЕсли; Результат.Добавить(КлючИЗначение.Значение); КонецЦикла; Возврат Результат; КонецФункции Функция РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(Знач ТекстПакета, Знач ПозицияКурсора = Неопределено, выхПозиции0 = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда RegExp = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли МассивТекстовЗапросов = Новый Массив; Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда Схема = Вычислить("Новый СхемаЗапроса"); #Если Сервер И Не Сервер Тогда Схема = Новый СхемаЗапроса; #КонецЕсли Попытка Схема.УстановитьТекстЗапроса(ТекстПакета); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки Возврат МассивТекстовЗапросов; КонецПопытки; Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл МассивТекстовЗапросов.Добавить(ЗапросПакета.ПолучитьТекстЗапроса()); КонецЦикла; КонецЕсли; Возврат МассивТекстовЗапросов; КонецЕсли; RegExp.Global = Истина; RegExp.Multiline = Ложь; //RegExp.Pattern = "(?:" + шСтрокаЗапроса + ")|" + шКомментарий + "|;(?:\s*\n)*|$"; RegExp.Pattern = "(?:" + шСтрокаЗапроса + ")|" + шКомментарий + "|;|$"; Результат = RegExp.НайтиВхождения(ТекстПакета,, Истина); НачалоЗапроса = 1; ОстальнойТекст = ТекстПакета; ДлинаТекстаПакета = СтрДлина(ТекстПакета); выхПозиции0 = Новый Массив; выхПозиции0.Добавить(0); Для Каждого Match Из Результат Цикл ПозицияВхождения = Match.FirstIndex; Если Истина И Не ирОбщий.СтрНачинаетсяСЛкс(Match.Value, ";") И ПозицияВхождения <> ДлинаТекстаПакета Тогда Продолжить; КонецЕсли; ИмяВременнойТаблицы = ""; ДлинаТекстаЗапроса = ПозицияВхождения + Match.Length; ТекстЗапроса = Сред(ТекстПакета, НачалоЗапроса, ДлинаТекстаЗапроса - НачалоЗапроса + 1); Если ПустаяСтрока(ТекстЗапроса) Тогда Продолжить; КонецЕсли; //Если ТекстЗапроса = ";" Тогда // Продолжить; //КонецЕсли; ОстальнойТекст = Сред(ОстальнойТекст, ДлинаТекстаЗапроса + 1); НачалоЗапроса = НачалоЗапроса + СтрДлина(ТекстЗапроса); МассивТекстовЗапросов.Добавить(ТекстЗапроса); выхПозиции0.Добавить(ПозицияВхождения + 1); Если ПозицияКурсора <> Неопределено И ПозицияКурсора < ПозицияВхождения Тогда Прервать; КонецЕсли; КонецЦикла; Если МассивТекстовЗапросов.Количество() = 0 Тогда МассивТекстовЗапросов.Добавить(ТекстПакета); КонецЕсли; Возврат МассивТекстовЗапросов; КонецФункции // Структура результата пакетного запроса на основе разметки в комментариях. // // Параметры: // ТекстПакетаИлиМассивТекстовЗапросов - - // ПрефиксКомментария - - // // Возвращаемое значение: // - // Функция СтруктураРезультатаПакетногоЗапроса(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ПрефиксКомментария = "//") Экспорт Результат = Новый Структура; Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда Возврат Результат; КонецЕсли; Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Строка") Тогда МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов); Иначе МассивТекстовЗапросов = ТекстПакетаИлиМассивТекстовЗапросов; КонецЕсли; RegExp.Global = Ложь; RegExp.Multiline = Ложь; RegExp.Pattern = ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс(ПрефиксКомментария + мМаркерИмениЗапросаПакета) + "(" + шИмя + ")(?: |\n|\r)"; Индекс = -1; Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл Индекс = Индекс + 1; Вхождения = RegExp.НайтиВхождения(ТекстЗапроса); Если Вхождения.Количество() = 0 Тогда Продолжить; КонецЕсли; ИмяЗапроса = Вхождения[0].SubMatches(0); Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапроса) Тогда Результат.Вставить(ИмяЗапроса, Индекс); КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ПреобразоватьЗапросВПодзапрос(Текст, ТекстВыбранныхПолей = "*", ПсевдонимВложенногоЗапроса = "ВложенныйЗапрос", ОбрезатьНачинаяСУпорядочивания = Ложь, ЭтоРусскийЯзык = Истина, Знач Смещение = "") Экспорт //ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса); RegExp.Pattern = "^(?:\s|(" + шКомментарий + "))*((?:ВЫБРАТЬ|SELECT)\s+((?:РАЗРЕШЕННЫЕ|ALLOWED)\s+)?)((?:(?:.|\r|\n)*\s((?:УПОРЯДОЧИТЬ|ORDER)\s+(?:ПО|BY)\s+" + шИмя + "(?:\s*,\s*" + шИмя + ")*(?:\s+(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER))?|(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER)))*)((?:.|\r|\n)*)$"; РезультатПоиска = RegExp.НайтиВхождения(Текст)[0]; Если ЭтоРусскийЯзык Тогда Результат = "ВЫБРАТЬ"; Иначе Результат = "SELECT"; КонецЕсли; Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(РезультатПоиска.SubMatches(2)) Тогда Если ЭтоРусскийЯзык Тогда Результат = Результат + " РАЗРЕШЕННЫЕ"; Иначе Результат = Результат + " ALLOWED"; КонецЕсли; КонецЕсли; Смещение = Смещение + Символы.Таб; Если ЭтоРусскийЯзык Тогда Результат = Результат + " " + ТекстВыбранныхПолей + " ИЗ ("; Иначе Результат = Результат + " " + ТекстВыбранныхПолей + " FROM ("; КонецЕсли; НачальныйКомментарий = РезультатПоиска.SubMatches(0); Если ЗначениеЗаполнено(НачальныйКомментарий) Тогда Результат = Результат + Символы.ПС + Смещение + НачальныйКомментарий; Иначе Результат = Результат + Символы.ПС; КонецЕсли; Если ЭтоРусскийЯзык Тогда Результат = Результат + Смещение + "ВЫБРАТЬ "; Иначе Результат = Результат + Смещение + "SELECT "; КонецЕсли; ТекстДоПоследнегоУПОРЯДОЧИТЬ = РезультатПоиска.SubMatches(3); Если ЗначениеЗаполнено(ТекстДоПоследнегоУПОРЯДОЧИТЬ) Тогда ТекстДоПоследнегоУПОРЯДОЧИТЬ = ирОбщий.СтрокаБезКонцаЛкс(ТекстДоПоследнегоУПОРЯДОЧИТЬ, СтрДлина(РезультатПоиска.SubMatches(4))); ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, ТекстДоПоследнегоУПОРЯДОЧИТЬ, Смещение); Иначе ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, РезультатПоиска.SubMatches(5), Смещение); КонецЕсли; Если ЭтоРусскийЯзык Тогда Результат = Результат + ") КАК "; Иначе Результат = Результат + ") AS "; КонецЕсли; Результат = Результат + ПсевдонимВложенногоЗапроса; Если Истина //И ТекстДоПоследнегоУПОРЯДОЧИТЬ <> Неопределено И Не ПустаяСтрока(ТекстДоПоследнегоУПОРЯДОЧИТЬ) И Не ОбрезатьНачинаяСУпорядочивания Тогда Результат = Результат + Символы.ПС + РезультатПоиска.SubMatches(4) + РезультатПоиска.SubMatches(5); КонецЕсли; Возврат Результат; КонецФункции // ПолучитьТекстЗапросаДоУпорядочивания() Функция СоздаваемыеВременныеТаблицыПакетаЗапросов(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ТолькоТребующиеУничтоженияНаВходе = Ложь, Знач ВместеСУничтожениями = Ложь) Экспорт #Если Сервер И Не Сервер Тогда RegExp2 = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли СозданныеТаблицы = Новый СписокЗначений; Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Массив") Тогда ТекстыЗапросовПакета = ТекстПакетаИлиМассивТекстовЗапросов; Иначе Если Не ирКэш.ДоступныРегВыраженияЛкс() Тогда Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда Схема = Вычислить("Новый СхемаЗапроса"); #Если Сервер И Не Сервер Тогда Схема = Новый СхемаЗапроса; #КонецЕсли Попытка Схема.УстановитьТекстЗапроса(ТекстПакетаИлиМассивТекстовЗапросов); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки Возврат СозданныеТаблицы; КонецПопытки; Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл ИмяСоздаваемойТаблицы = Неопределено; Если Истина И ТипЗнч(ЗапросПакета) = Тип("ЗапросВыбораСхемыЗапроса") И ЗначениеЗаполнено(ЗапросПакета.ТаблицаДляПомещения) Тогда ИмяСоздаваемойТаблицы = ЗапросПакета.ТаблицаДляПомещения; КонецЕсли; СозданныеТаблицы.Добавить(НРег(ИмяСоздаваемойТаблицы), ИмяСоздаваемойТаблицы); КонецЦикла; КонецЕсли; Возврат СозданныеТаблицы; КонецЕсли; ТекстыЗапросовПакета = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов); КонецЕсли; RegExp2.Global = Истина; // Ищем в каждом запросе пакета предложение ПОМЕСТИТЬ/УНИЧТОЖИТЬ ШаблонПОМЕСТИТЬИЗ = "(?:" + шСтрокаЗапроса + ")|(?:(?:" + шРазделитель + "|\|)(?:(ПОМЕСТИТЬ|INTO\s+TABLE|INTO)|(УНИЧТОЖИТЬ|DROP|DROP\s+TABLE))" + шРазделитель //+ "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;|')|(?:" + шРазделитель + "))|.+?"; + "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;|')|\s)|" + шРазделитель + "|.+?"; RegExp2.Pattern = ШаблонПОМЕСТИТЬИЗ; СозданныеТаблицыНрег = Новый Массив; СначалаУничтоженныеТаблицы = Новый Массив; Для Каждого ТекстЗапроса Из ТекстыЗапросовПакета Цикл ИмяСозданнойВременнойТаблицы = Неопределено; СозданиеВременнойТаблицы = RegExp2.Заменить(ТекстЗапроса, "$1"); ИмяВременнойТаблицы = RegExp2.Заменить(ТекстЗапроса, "$3"); Если ЗначениеЗаполнено(СозданиеВременнойТаблицы) Тогда Если Ложь Или Не ТолькоТребующиеУничтоженияНаВходе Или СначалаУничтоженныеТаблицы.Найти(НРег(ИмяВременнойТаблицы)) = Неопределено Тогда ИмяСозданнойВременнойТаблицы = ИмяВременнойТаблицы; Если ИмяСозданнойВременнойТаблицы <> Неопределено Тогда СозданныеТаблицыНрег.Добавить(НРег(ИмяСозданнойВременнойТаблицы)); КонецЕсли; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда Если ВместеСУничтожениями Тогда ИмяСозданнойВременнойТаблицы = "-" + ИмяВременнойТаблицы; КонецЕсли; ИмяВременнойТаблицы = НРег(ИмяВременнойТаблицы); Если ТолькоТребующиеУничтоженияНаВходе Тогда Если СозданныеТаблицыНрег.Найти(ИмяВременнойТаблицы) = Неопределено Тогда СначалаУничтоженныеТаблицы.Добавить(ИмяВременнойТаблицы); КонецЕсли; КонецЕсли; КонецЕсли; СозданныеТаблицы.Добавить(НРег(ИмяСозданнойВременнойТаблицы), ИмяСозданнойВременнойТаблицы); КонецЦикла; Возврат СозданныеТаблицы; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ТИПАМИ // Получает чистую внутреннюю таблицу предопределенных слов. // // Параметры: // Нет. // // Возвращаемое значение: // ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов". // Функция НоваяТаблицаСвойствТипа() Экспорт ВнутрТаблицаСлов = Новый ТаблицаЗначений; ВнутрТаблицаСлов.Колонки.Добавить("Слово"); ВнутрТаблицаСлов.Колонки.Добавить("ТипСлова"); ВнутрТаблицаСлов.Колонки.Добавить("ТаблицаТипов"); ВнутрТаблицаСлов.Колонки.Добавить("ТипЗначения"); ВнутрТаблицаСлов.Колонки.Добавить("Определение"); ВнутрТаблицаСлов.Колонки.Добавить("МожноУточнитьТип"); ВнутрТаблицаСлов.Индексы.Добавить("Слово, ТипСлова"); Возврат ВнутрТаблицаСлов; КонецФункции // Функция - Подобрать вариант синтаксиса метода // // Параметры: // ТаблицаВариантов - - содержимое будет утеряно! // // Возвращаемое значение: // строка - название варианта синтаксиса // Функция ПодобратьВариантСинтаксисаМетода(Знач ТаблицаВариантов, Знач КоличествоФактПараметровМетода = 0, Знач ТекущийВариант = "", Знач ТекущийВариантУстановленВручную = Ложь, выхНомер = 0) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаВариантов = Новый ТаблицаЗначений; #КонецЕсли ТаблицаВариантов.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число")); ТаблицаВариантов.ЗаполнитьЗначения(1, "Количество"); ТаблицаВариантов.Свернуть("ВариантСинтаксиса", "Количество"); //ТаблицаВариантов.Сортировать("Количество"); // Если закомментировано, то ОткрытьФорму("") правильно показывает и ближе к поведению конфигуратора НовыйТекущийВариант = ""; Если ТаблицаВариантов.Количество() > 0 Тогда Для Каждого СтрокаВарианта Из ТаблицаВариантов Цикл Если ТекущийВариантУстановленВручную И СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда НовыйТекущийВариант = ТекущийВариант; выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта); Прервать; КонецЕсли; Если СтрокаВарианта.Количество >= КоличествоФактПараметровМетода Тогда НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса; выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта); Если Не ТекущийВариантУстановленВручную Тогда Прервать; КонецЕсли; КонецЕсли; КонецЦикла; Если СтрокаВарианта.Количество < КоличествоФактПараметровМетода Тогда НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса; выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта); КонецЕсли; КонецЕсли; выхНомер = выхНомер + 1; Возврат НовыйТекущийВариант; КонецФункции Функция СинтаксПомощник() Экспорт Если СинтаксПомощник = Неопределено Тогда СинтаксПомощник = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирСинтаксПомощник"); КонецЕсли; Возврат СинтаксПомощник; КонецФункции Функция ДоступныеЗначенияТипа(Знач ИмяТипаИлиТипЗначения) Экспорт ИнициацияОписанияМетодовИСвойств(); Если ТипЗнч(ИмяТипаИлиТипЗначения) = Тип("Тип") Тогда ИмяТипаИлиТипЗначения = СтруктураТипаИзКонкретногоТипа(ИмяТипаИлиТипЗначения).ИмяОбщегоТипа; КонецЕсли; //Пустышка = Вычислить("Метаданные.СвойстваОбъектов." + ИмяТипаЗначения); СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", "ПеречислениеМетаданных" + ИмяТипаИлиТипЗначения, "Свойство")); Если СтрокиЗначений.Количество() = 0 Тогда ИмяТипаПеречисления = ИмяТипаИлиТипЗначения; Если Не ирОбщий.СтрНачинаетсяСЛкс(ИмяТипаИлиТипЗначения, "Перечисление") Тогда ИмяТипаПеречисления = "Перечисление" + ИмяТипаПеречисления; КонецЕсли; СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", ИмяТипаПеречисления, "Свойство")); КонецЕсли; СтрокиЗначений = ТаблицаКонтекстов.Скопировать(СтрокиЗначений); СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(СтрокиЗначений.ВыгрузитьКолонку("Слово")); Возврат СписокЗначений; КонецФункции // Формирует построитель запроса по структуре типа. // // Параметры: // СтруктураТипа - Структура - описатель типа. // // Возвращаемое значение: // ПостроительЗапроса. // Функция ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, ВиртуальнаяТаблица = Неопределено) МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда ПолноеИмя = МетаданныеРодителя.ПолноеИмя(); Иначе ПолноеИмя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя); КонецЕсли; МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя); КорневойТипРодителя = МассивФрагментов[0]; Если ОписаниеТипаМетаОбъектов(КорневойТипРодителя, , 0) <> Неопределено Тогда Если Ложь Или (Истина И МассивФрагментов.Количество() = 2 И МассивФрагментов[0] <> "ВнешнийИсточникДанных") Или (Истина И МассивФрагментов.Количество() = 4 И МассивФрагментов[2] = "ТабличнаяЧасть") Тогда ПостроительЗапроса = Новый Структура("ДоступныеПоля", Новый Массив); Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда ИмяТаблицы = "Константы." + МассивФрагментов[1]; Иначе ИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмя, Ложь, ВиртуальнаяТаблица = Неопределено); КонецЕсли; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Если Ложь Или ВиртуальнаяТаблица = Неопределено Или Найти(ВиртуальнаяТаблица.Выражение, "(") = 0 Тогда ТаблицаРезультата = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы + ВиртуальнаяТаблица.Выражение); #Если Сервер И Не Сервер Тогда ТаблицаРезультата = Новый ТаблицаЗначений; #КонецЕсли ТаблицаРезультата = ТаблицаРезультата.Скопировать(, "Имя, ТипЗначения"); // Делаем копию, т.к. будем ее модифицировать ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата); Иначе Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда ОпределениеТаблицы = "ВЫБРАТЬ " + ИмяТаблицы; Иначе УникальноеИмяТаблицы = "______________________"; ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ; Если ВиртуальнаяТаблица <> Неопределено Тогда ОпределениеТаблицы = ОпределениеТаблицы + ВиртуальнаяТаблица.Выражение; КонецЕсли; ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы; КонецЕсли; Попытка //ПостроительЗапроса.Текст = ОпределениеТаблицы; ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы,,, Ложь); Исключение Успех = Ложь; Если ВиртуальнаяТаблица <> Неопределено Тогда ПозицияСкобки = Найти(ВиртуальнаяТаблица.Выражение, "("); Если ПозицияСкобки > 0 Тогда ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ; ОпределениеТаблицы = ОпределениеТаблицы + Лев(ВиртуальнаяТаблица.Выражение, ПозицияСкобки - 1); ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы; Попытка //ПостроительЗапроса.Текст = ОпределениеТаблицы; ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы); Успех = Истина; Исключение КонецПопытки; КонецЕсли; КонецЕсли; Если Не Успех Тогда ВызватьИсключение "ОшибкаВычисленияВиртуальнойТаблицы"; КонецЕсли; КонецПопытки; ТаблицаРезультата = ирОбщий.ТаблицаЗначенийВТаблицуПолейБДЛкс(ТаблицаРезультата); ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата); КонецЕсли; ТаблицаРезультата.Колонки.Добавить("НИмя"); ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаРезультата); ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ПостроительЗапроса.ДоступныеПоля, ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы)); Иначе // Внешние метаданные ПостроительЗапроса = Новый ПостроительЗапроса; ЗапросРеквизитов = Новый Запрос("ВЫБРАТЬ Имя, ТипыСтрокой ИЗ Справочник.СвойстваМетаданных ГДЕ Владелец = &СсылкаМД"); ЗапросРеквизитов.УстановитьПараметр("СсылкаМД", МетаданныеРодителя); ТаблицаРеквизитов = ЗапросРеквизитов.Выполнить().Выгрузить(); Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Добавить(СтрокаРеквизита.Имя); Для Каждого СтрокаТипа Из СтрокаРеквизита.Типы Цикл МассивТипов = Новый Массив; ОбъектМД = КэшОбъект(СтрокаТипа.Объект); МассивТипов.Добавить(Тип(ОбъектМД.Наименование)); КонецЦикла; ДоступноеПоле.ТипЗначения = Новый ОписаниеТипов(МассивТипов); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ПостроительЗапроса; КонецФункции // Получает массив общих типов, дополняя исходный тип расширениями. // // Параметры: // СтруктураТипа - Структура. // // Возвращаемое значение: // Массив - структур типа. // Функция ТаблицаОбщихТиповИзСтруктурыТипа(Знач СтруктураТипа, Знач ЭтоЛокальныйКонтекст) Экспорт МассивОбщихТипов = НоваяТаблицаДополнительныхТипов(); Если СтруктураТипа.ТипЯзыка <> "" Тогда ЗаполнитьЗначенияСвойств(МассивОбщихТипов.Добавить(), СтруктураТипа); Возврат МассивОбщихТипов; КонецЕсли; Если Ложь Или (Истина И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("COMОбъект") И (Ложь Или СтруктураТипа.ИмяОбщегоТипа = "Локальный" // Для подстраховки Или ЭтоЛокальныйКонтекст И СтруктураТипа.ИмяОбщегоТипа <> "Глобальный")) Или СтруктураТипа.ИмяОбщегоТипа = "Automation сервер" Или СтруктураТипа.ИмяОбщегоТипа = "Внешнее соединение" Тогда // Должен идти первым в списке! НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа,, "ИмяОбщегоТипа, Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "Глобальный"; НоваяСтрока.Метаданные = Метаданные; КонецЕсли; СтрокаТаблицы = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаТаблицы, СтруктураТипа); Если СтрокаТаблицы.ИмяОбщегоТипа = "УправляемаяФорма" Тогда СтрокаТаблицы.ИмяОбщегоТипа = "ФормаКлиентскогоПриложения"; КонецЕсли; Если Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "ТабличнаяЧасть"; ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧастьСтрока.") > 0 Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "СтрокаТабличнойЧасти"; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТекстовогоДокумента" Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "ТекстовыйДокумент"; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеГрафическойСхемы" Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "ГрафическаяСхема"; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТабличногоДокумента" Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "ТабличныйДокумент"; ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "КоллекцияМетаданных") > 0 Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "КоллекцияОбъектовМетаданных"; //ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "РасширениеФормы") > 0 Тогда // НоваяСтрока = МассивОбщихТипов.Добавить(); // ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); // НоваяСтрока.ИмяОбщегоТипа = "Форма"; Иначе ОбщийТипМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипа.ИмяОбщегоТипа, , ": ", Ложь); //Если ОбщийТипМетаданных <> "" Тогда Если ЗначениеЗаполнено(ОбщийТипМетаданных) Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = ОбщийТипМетаданных; КонецЕсли; КонецЕсли; // TODO добавить расширения управляемой формы Мультиметка638663811 // Расширения, образованные элементом управления и типом связанных с ним данных СтрокаРасширения = ТаблицаРасширенийТипов.Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение"); Если Истина И СтрокаРасширения <> Неопределено И ЗначениеЗаполнено(СтрокаРасширения.ОсновнойТип) Тогда Если Истина И СтрокаРасширения.ОсновнойТип = "Форма" И СтруктураТипа.ДополнительныеТипы = Неопределено Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип; #Если Клиент Тогда Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("Форма") Тогда ОсновнойРеквизитФормы = ИмяОсновногоРеквизитаФормы(СтруктураТипа.Метаданные); РасширяющийОбъект = СтруктураТипа.Метаданные[ОсновнойРеквизитФормы]; СтруктураТипаОбъекта = СтруктураТипаИзЗначения(РасширяющийОбъект); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипаОбъекта); //НоваяСтрока.Метаданные = ирОбщий.ПолучитьМетаданныеЛкс(РасширяющийОбъект); КонецЕсли; #КонецЕсли КонецЕсли; НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.ОсновнойТип; КонецЕсли; // Общие расширения элементов управления Для Счетчик = 1 По Мин(2, МассивОбщихТипов.Количество()) Цикл // Для поля табличного документа будет 2 типа https://www.hostedredmine.com/issues/956247 лИмяОбщегоТипа = МассивОбщихТипов[МассивОбщихТипов.Количество() - Счетчик].ИмяОбщегоТипа; Если МассивОбычныхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхВФорме"; НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхНаПанели"; //ИначеЕсли МассивУправляемыхЭлементовУправления.Найти(лИмяОбщегоТипа) <> Неопределено Тогда // // http://www.hostedredmine.com/issues/882998 // НоваяСтрока = МассивОбщихТипов.Добавить(); // ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); // НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхВФорме"; КонецЕсли; КонецЦикла; Если СтруктураТипа.ДополнительныеТипы <> Неопределено Тогда ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтруктураТипа.ДополнительныеТипы, МассивОбщихТипов); КонецЕсли; Возврат МассивОбщихТипов; КонецФункции Процедура ОчиститьКэшАнализатораЯзыка() Экспорт мМодулиМетаданных = Неопределено; мВызовыВсехМетодовПоМодулям = Неопределено; мКэшСловГлобальногоКонтекста = Неопределено; мПассивныеФормы.Очистить(); КонецПроцедуры Процедура ПроверитьОбновитьКэш() Экспорт НоваяДатаОбновленияКэшаМодулей = ирОбщий.ДатаОбновленияКэшаМодулейЛкс(); Если мДатаОбновленияКэшаМодулей <> НоваяДатаОбновленияКэшаМодулей Тогда ОчиститьКэшАнализатораЯзыка(); мДатаОбновленияКэшаМодулей = НоваяДатаОбновленияКэшаМодулей; КонецЕсли; КонецПроцедуры // Получает внутреннюю таблицу предопределенных слов заданного родительского типа. // // Параметры: // РодительскаяСтруктураТипа - Структура; // *Слово - Строка, *Неопределено - для отбора; // *ТипСлова - Строка, *Неопределено - для отбора; // *ВиртуальнаяТаблица - Структура, *Неопределено - описание виртуальной таблицы; // *ЯзыкПрограммы - *Число, 0; // // Возвращаемое значение: // ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов". // Функция СловаКонтекстаПредопределенные(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВиртуальнаяТаблица = Неопределено, Знач ЯзыкПрограммы = 0, Знач Конфигурация = Неопределено, Знач ВычислятьТипы = Истина, Знач ФлагиКомпиляции = Неопределено, Знач ТаблицаСлов = Неопределено, Знач ЭтоЛокальныйКонтекст = Ложь, Знач НаборыСлов = Неопределено, Знач БазовоеРасширениеКонфигурации = "") Экспорт Если Истина И Не РодительскаяСтруктураТипа.Конструктор И Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа) И РодительскаяСтруктураТипа.ТипЯзыка = "" Тогда // родительский контекст является Процедурой Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСвойствТипа(); КонецЕсли; Возврат ТаблицаСлов; КонецЕсли; КлючПоискаКонструктора = Новый Структура; Если РодительскаяСтруктураТипа.Конструктор Тогда КлючПоискаКонструктора = Новый Структура("ЕстьКонструктор, ЯзыкПрограммы, НСлово", Истина, ЯзыкПрограммы); КонецЕсли; ИмяОбщегоТипаРодителяБезДеталей = РодительскаяСтруктураТипа.ИмяОбщегоТипа; Если Найти(ИмяОбщегоТипаРодителяБезДеталей, " {V") > 0 Тогда ЧистоеИмяТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипаРодителяБезДеталей, " "); Если Найти(ЧистоеИмяТипа, "IV8COMConnector") = 1 Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Менеджер COM-соединений"; ИначеЕсли Найти(ЧистоеИмяТипа, "IServerAgentConnection") = 1 Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с агентом сервера"; ИначеЕсли Найти(ИмяОбщегоТипаРодителяБезДеталей, "IWorkingProcessConnection") Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с рабочим процессом"; ИначеЕсли Найти(ИмяОбщегоТипаРодителяБезДеталей, "Application") Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Automation сервер"; КонецЕсли; КонецЕсли; МассивОбщихТипов = ТаблицаОбщихТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст); #Если Сервер И Не Сервер Тогда МассивОбщихТипов = Новый ТаблицаЗначений; ТаблицаСлов = Новый ТаблицаЗначений; #КонецЕсли НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс(); Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл ИмяОбщегоТипаРодителяБезДеталей = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "["); ИспользоватьКэширование = Истина И Слово = Неопределено И (Ложь Или ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Или ИмяОбщегоТипаРодителяБезДеталей = "" // ИмяТипа ); Если ИспользоватьКэширование Тогда // Мультиметка3398476724 ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс(); НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина); КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП); КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП); КлючКэширования = "" + ЯзыкПрограммы + ";" + Конфигурация + ";" + ВычислятьТипы + ";" + ТипСлова + ";" + НаСервере + ";" + КлиентОбычноеПриложение + ";" + КлиентУправляемоеПриложение + ";" + РодительскаяСтруктураТипа.ТипЯзыка + ";" + БазовоеРасширениеКонфигурации; Если мКэшСловГлобальногоКонтекста = Неопределено Тогда мКэшСловГлобальногоКонтекста = Новый Соответствие; КонецЕсли; ТаблицаСловИзКэша = мКэшСловГлобальногоКонтекста[КлючКэширования]; #Если Сервер И Не Сервер Тогда ТаблицаСловИзКэша = Новый ТаблицаЗначений; #КонецЕсли Если ТаблицаСловИзКэша <> Неопределено Тогда Если ТаблицаСлов <> Неопределено Тогда ВызватьИсключение "Для глобального контекста нельзя передавать таблицу-приемник"; КонецЕсли; Если НаборыСлов <> Неопределено Тогда НаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша); ТаблицаСлов = НоваяТаблицаСвойствТипа(); Иначе ТаблицаСлов = ТаблицаСловИзКэша.Скопировать(); КонецЕсли; Продолжить; КонецЕсли; КонецЕсли; Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСвойствТипа(); КонецЕсли; Если Истина И ИмяОбщегоТипаРодителяБезДеталей <> "Глобальный" И ФлагиКомпиляции <> Неопределено И ФлагиКомпиляции.БезКонтекста И ЭтоЛокальныйКонтекст Тогда Продолжить; КонецЕсли; МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные; Если Истина И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Форма") <> Неопределено Тогда МетаданныеРодителя = МетаданныеРодителя.Форма; КонецЕсли; КорневойТипРодителя = Неопределено; ПостроительЗапросаРодителя = Неопределено; ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя); Если Истина И ТипМетаданныхРодителя = Тип("ОбъектМетаданных") И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя); Иначе КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя); КонецЕсли; ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица); КонецЕсли; Если ИмяОбщегоТипаРодителяБезДеталей = "Локальный" Тогда НайденныеСтроки = Новый Массив; ИначеЕсли ТипСлова = "Конструктор" Тогда НайденныеСтроки = Новый Массив; Если ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Тогда СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова", Слово, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка, ТипСлова); НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча); КонецЕсли; Иначе // Состав полей совпадает с индексом СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипаРодителяБезДеталей, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка); Если Слово <> Неопределено Тогда СтруктураКлюча.Вставить("НСлово", НРег(Слово)); Если Истина И ЯзыкПрограммы = 0 // В языке запросов может быть неоднозначность между типами слов Таблица и Поле. Поэтому для них жертвуем попаданием в индекс И ТипСлова = Неопределено Тогда //ирОбщий.СообщитьЛкс("Использован медленный поиск по таблице контекстов"); ТипСлова = "Свойство"; // Так будем всегда попадать в индекс КонецЕсли; КонецЕсли; Если ТипСлова <> Неопределено Тогда СтруктураКлюча.Вставить("ТипСлова", ТипСлова); КонецЕсли; Если ЯзыкПрограммы <> 0 Тогда ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаКонтекстов, СтруктураКлюча); // спасает в случае языка запросов, где ТипСлова не используется КонецЕсли; НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча); КонецЕсли; ПредыдущаяСтрокаСлова = Неопределено; // Для регистра бухгалтерии ВычислятьТипыЦикл = ВычислятьТипы Или НайденныеСтроки.Количество() < 100; Для Каждого СтрокаСлова Из НайденныеСтроки Цикл Если Истина И ПредыдущаяСтрокаСлова <> Неопределено И ПредыдущаяСтрокаСлова.НСлово = СтрокаСлова.НСлово И ПредыдущаяСтрокаСлова.ТипСлова = СтрокаСлова.ТипСлова Тогда Продолжить; КонецЕсли; ПредыдущаяСтрокаСлова = СтрокаСлова; Если СтрокаСлова.НомерВерсииПлатформы > НомерВерсииПлатформы Тогда Продолжить; КонецЕсли; Если Истина И СтрокаСлова.ТипСлова = "Метод" И СтрокаОбщегоТипа.НеВключатьМетоды Тогда Продолжить; КонецЕсли; Если Истина И ТипСлова = Неопределено И (Ложь Или СтрокаСлова.ТипСлова = "Событие" Или СтрокаСлова.ТипСлова = "Параметр" Или СтрокаСлова.ТипСлова = "Конструктор") Тогда Продолжить; КонецЕсли; Если РодительскаяСтруктураТипа.Конструктор Тогда КлючПоискаКонструктора.НСлово = НРег(СтрокаСлова.Слово); Если ТаблицаОбщихТипов.НайтиСтроки(КлючПоискаКонструктора).Количество() = 0 Тогда Продолжить; КонецЕсли; КонецЕсли; ЛиТипСКвалификаторами = Истина И (Ложь Или СтрокаСлова.ТипСлова = "Свойство" Или СтрокаСлова.ТипСлова = "Поле") И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаСлова.ТипЗначения) И Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ОбъектМетаданных"); ТаблицаТипов = Неопределено; Если ВычислятьТипыЦикл Тогда ТаблицаТипов = НоваяТаблицаТипов(); ЛиДобавляемСлово = Истина; Если Найти(СтрокаСлова.ТипЗначения, "[") > 0 Тогда МассивТиповЗначения = ирОбщий.ЗначенияВМассивЛкс(СтрокаСлова.ТипЗначения); Иначе МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.ТипЗначения, ", "); КонецЕсли; Для Каждого ИмяОбщегоТипаСлова Из МассивТиповЗначения Цикл СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.СтрокаОписания = СтрокаСлова; ЗаполнитьЗначенияСвойств(СтруктураТипа, РодительскаяСтруктураТипа, , "ИмяОбщегоТипа, СтрокаОписания, Метаданные"); Если Истина //И ТипЗнч(МетаданныеРодителя) <> Тип("COMОбъект") //И ИмяОбщегоТипаСлова <> //И СтрокаСлова.ТипСлова = "Свойство" Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа, СтрокаОбщегоТипа, "Метаданные"); КонецЕсли; Если ИмяОбщегоТипаСлова = "ОбъектМетаданныхКонфигурация" Тогда //СтруктураТипа.Метаданные = Конфигурация; Если Конфигурация <> Неопределено Тогда СтруктураТипа.Метаданные = Конфигурация; Иначе СтруктураТипа.Метаданные = мМетаданные; КонецЕсли; ИначеЕсли ИмяОбщегоТипаСлова = "Отбор" Тогда Если Истина И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных") И (Ложь //Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "объект.") > 0 Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "наборзаписей.") > 0) Тогда ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()); СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыБД); СтруктураТипа.Метаданные = СтруктураОбъекта.Методы; ИначеЕсли СтрокаОбщегоТипа.ИмяОбщегоТипа = "РасширениеТабличногоПоляТабличнойЧасти" Тогда Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ТабличноеПоле") Тогда СтруктураТипа.Метаданные = Метаданные.НайтиПоТипу(ТипЗнч(СтрокаОбщегоТипа.Метаданные.Значение)); КонецЕсли; Иначе КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа); Если Истина И Найти(КонкретныйТип, "<") = 0 И ТипЗнч(СтруктураТипа.Метаданные) <> Тип(КонкретныйТип) Тогда Попытка Образователь = Новый (КонкретныйТип); СтруктураТипа.Метаданные = Образователь; Исключение // Срабатывает для табличных полей КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаСлова; Если ВиртуальнаяТаблица <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа.ВиртуальнаяТаблица, ВиртуальнаяТаблица); КонецЕсли; Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.Слово; Если СтрокаСлова.ТипКонтекста <> "" Тогда СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипа.ИмяОбщегоТипа; КонецЕсли; КонецЕсли; Если Истина И Найти(СтруктураТипа.ИмяОбщегоТипа, "СтрокаТабличнойЧасти") > 0 И Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда ИмяТипаСтрокиТЧ = СтрЗаменить(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.", "ТабличнаяЧастьСтрока."); СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, "СтрокаТабличнойЧасти", ИмяТипаСтрокиТЧ); КонецЕсли; Если Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") И ИмяОбщегоТипаСлова = "КолонкаТабличногоПоля" Тогда ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипаСлова, МетаданныеРодителя); Если ИмяОбщегоТипаРасширения <> Неопределено Тогда СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения; КонецЕсли; КонецЕсли; МаркерРасширений = "Расширение"; Если Истина И Лев(РодительскаяСтруктураТипа.ИмяОбщегоТипа, СтрДлина(МаркерРасширений)) = МаркерРасширений И СтрокаСлова.Слово = "Значение" Тогда Если РодительскаяСтруктураТипа.Метаданные <> Неопределено Тогда ЭлементФормы = РодительскаяСтруктураТипа.Метаданные; // ПолеВвода СтруктураТипа = СтруктураТипаИзЗначения(ЭлементФормы.Значение); Иначе СтрокаРасширения = ТаблицаРасширенийТипов.Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение"); //Если СтрокаРасширения <> Неопределено Тогда СтруктураТипа.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип; //КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И МетаданныеРодителя <> Неопределено И СтрокаСлова.ТипСлова = "Свойство" Тогда Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") Или (Истина // Нельзя допускать неявного выполнения запроса при обращении к свойству "Результат" построителя И СтруктураТипа.ИмяОбщегоТипа = "РезультатЗапроса" И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")) Или (Истина // Здесь свойство есть у объекта метаданных, но имеет другой смысл И СтрокаСлова.Слово = "ВидыСубконто" И СтруктураТипа.ИмяОбщегоТипа = "ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда ЗначениеСвойства = МетаданныеРодителя; Иначе Если Истина #Если Клиент Тогда И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") #Иначе И Ложь #КонецЕсли И СтрокаСлова.Слово = "ТекущийРодитель" Тогда // Антибаг платформы 8.2.16. Вывести в чистом виде не удалось. Падает при вычислении свойства ТекущийРодитель в форме списка РС.ООП_ВаучерыТез ЗначениеСвойства = Неопределено; Иначе Попытка ЗначениеСвойства = МетаданныеРодителя[СтрокаСлова.Слово]; Исключение ЗначениеСвойства = Неопределено; КонецПопытки; КонецЕсли; КонецЕсли; Если ЗначениеСвойства <> Неопределено Тогда Если мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда Если СтрокаСлова.ТипЗначения = "ВсеЭлементыФормы" Тогда // Для имитатора формы Иначе СтруктураТипа.Метаданные = ЗначениеСвойства; КонецЕсли; Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь) Тогда СтруктураТипа.ДержательМетаданных = МетаданныеРодителя; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; // Для методов метаданных нужна специфическая обработка для усечения типов Если Истина И СтрокаСлова.ТипСлова = "Метод" И Лев(ИмяОбщегоТипаСлова, СтрДлина(МаркерОбъектаМетаданных)) = МаркерОбъектаМетаданных И СтрокаСлова.Слово = "Родитель" Тогда Родитель = Неопределено; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Родитель = МетаданныеРодителя.Родитель(); КонецЕсли; Если Родитель <> Неопределено Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(Родитель.ПолноеИмя()); СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 1]; Иначе СтруктураТипа.ИмяОбщегоТипа = "Неопределено"; КонецЕсли; СтруктураТипа.Метаданные = Родитель; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И СтрокаСлова.ТипСлова = "Метод" И Лев(ИмяОбщегоТипаСлова, СтрДлина(МаркерКоллекцииОбъектовМетаданных)) = МаркерКоллекцииОбъектовМетаданных И (Ложь Или СтрокаСлова.Слово = "Найти" Или СтрокаСлова.Слово = "Получить") Тогда СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", ИмяОбщегоТипаСлова, ЯзыкПрограммы); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча); СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].ТипЭлементаКоллекции; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ОписаниеТипов") И СтрокаСлова.ТипКонтекста = "ОписаниеТипов" И СтрокаСлова.Слово = "ПривестиЗначение" Тогда Если МетаданныеРодителя.Типы().Количество() = 1 Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, МетаданныеРодителя); КонецЕсли; Прервать; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТекстовыйДокумент") И ИмяОбщегоТипаРодителяБезДеталей = "ТекстовыйДокумент" И СтрокаСлова.Слово = "ПолучитьТекст" Тогда СтруктураТипа = НоваяСтруктураТипа("Строка"); СтруктураТипа.Метаданные = МетаданныеРодителя.ПолучитьТекст(); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И (Ложь Или ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение" Или ИмяОбщегоТипаРодителяБезДеталей = "ЭлементСпискаЗначений") И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Свойство(СтрокаСлова.Слово) Тогда ТаблицаТипов = МетаданныеРодителя[СтрокаСлова.Слово]; Если ТаблицаТипов <> Неопределено Тогда Прервать; КонецЕсли; ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "Соответствие" И СтрокаСлова.Слово = "Получить" И ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда ТаблицаТипов = МетаданныеРодителя.Значение; Если ТаблицаТипов <> Неопределено Тогда Прервать; КонецЕсли; ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "Запрос" И ИмяОбщегоТипаСлова = "МенеджерВременныхТаблиц" Тогда МенеджерВременныхТаблиц = РодительскаяСтруктураТипа.ДержательМетаданных; Если Истина И ТипЗнч(МенеджерВременныхТаблиц) = Тип("Структура") //И МенеджерВременныхТаблиц.Тип = Тип("МенеджерВременныхТаблиц") И МенеджерВременныхТаблиц.Активен Тогда СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип("МенеджерВременныхТаблиц")); СтруктураТипа.Метаданные = МенеджерВременныхТаблиц; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Продолжить; Иначе СтруктураТипа.Метаданные = Неопределено; КонецЕсли; ИначеЕсли Истина И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Массив[РезультатЗапроса]" И СтрокаСлова.ТипСлова = "Метод" И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И (Ложь Или СтрокаСлова.Слово = "Количество" Или СтрокаСлова.Слово = "ВГраница") Тогда КоличествоЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(МетаданныеРодителя.Текст).Количество(); Если СтрокаСлова.Слово = "Количество" Тогда СтруктураТипа.Метаданные = КоличествоЗапросов; Иначе СтруктураТипа.Метаданные = КоличествоЗапросов - 1; КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И СтрокаСлова.Слово = "ИсходныйКлючЗаписи" И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") Тогда ЛиДобавляемСлово = ЗначениеСвойства <> Неопределено; Если ЛиДобавляемСлово Тогда СтруктураТипа = СтруктураТипаИзЗначения(ЗначениеСвойства, СтруктураТипа); КонецЕсли; Прервать; #Если Клиент Тогда ИначеЕсли Ложь Или (Истина И СтрокаСлова.ТипСлова = "Метод" И СтрокаСлова.Слово = "ДанныеСтроки" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы") Или ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы"))) Или (Истина И СтрокаСлова.ТипСлова = "Свойство" И (Ложь Или (Истина И (Ложь Или СтрокаСлова.Слово = "ТекущиеДанные" Или СтрокаСлова.Слово = "ОформленияЯчеекДинамическогоСписка") И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы"))) Или (Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") И (Ложь Или СтрокаСлова.Слово = "ДанныеСтроки" Или СтрокаСлова.Слово = "ТекущаяСтрока" Или СтрокаСлова.Слово = "ТекущиеДанные")))) Тогда ИмяРеквизитаФормы = ""; Форма = РодительскаяСтруктураТипа.ДержательМетаданных; ДанныеЭлементаФормы = ирОбщий.ДанныеЭлементаФормыЛкс(МетаданныеРодителя, ИмяРеквизитаФормы, Форма); ТаблицаТипов = Неопределено; Если ДанныеЭлементаФормы <> Неопределено Тогда Если Форма = Неопределено Тогда Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(МетаданныеРодителя); КонецЕсли; Если ТипЗнч(ДанныеЭлементаФормы) = Тип("НастройкиКомпоновкиДанных") Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы.Структура)); ИначеЕсли ТипЗнч(ДанныеЭлементаФормы) = Тип("ДинамическийСписок") Тогда СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыСтруктура"); СтруктураТипа.Метаданные = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы).Все; Иначе ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы)); Если ТаблицаТипов.Количество() = 0 Тогда // Деревья #Если Клиент Тогда ТаблицаЗначений = ирКлиент.ТаблицаИлиДеревоЗначенийИзТаблицыФормыСКоллекциейЛкс(МетаданныеРодителя, Новый Массив); Если ТаблицаЗначений <> Неопределено Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ТаблицаЗначений)); ТаблицаТипов[0].ИмяОбщегоТипа = "СтрокаДереваЗначений"; КонецЕсли; #КонецЕсли КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда ОписаниеТипов = МетаданныеРодителя.ОписаниеТипов; //ОписаниеТипов Если ОписаниеТипов <> Неопределено Тогда Если ОписаниеТипов.СодержитТип(Тип("ДинамическийСписок")) Тогда СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыСтруктура"); СтруктураТипа.Метаданные = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы).Все; Иначе ТаблицаТиповКоллекции = ТаблицаТиповИзОписанияТипов(ОписаниеТипов); ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(ТаблицаТиповКоллекции[0]); КонецЕсли; Иначе СтруктураТипа.Метаданные = Неопределено; КонецЕсли; КонецЕсли; Если ТаблицаТипов <> Неопределено Тогда ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); Если Форма <> Неопределено Тогда ТаблицаТипов.ЗаполнитьЗначения(Форма, "ДержательМетаданных"); КонецЕсли; Прервать; КонецЕсли; #КонецЕсли ИначеЕсли Истина // Опасно широкое условие. Не подходит для Соответствие И КорневойТипРодителя = Неопределено И СтрокаСлова.ТипСлова = "Метод" И СтрокаСлова.Слово = "Получить" И СтрокаСлова.ТипЗначения = "Произвольный" Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа,, ЯзыкПрограммы); Прервать; КонецЕсли; Если КорневойТипРодителя <> Неопределено Тогда ДоступноеПолеСлова = Неопределено; Если ПостроительЗапросаРодителя <> Неопределено Тогда ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(СтрокаСлова.Слово)); КонецЕсли; // Частные случаи Если Истина И ПостроительЗапросаРодителя <> Неопределено И (Ложь Или СтрокаСлова.ТипСлова = "Поле" Или СтрокаСлова.Слово = "Активность" Или СтрокаСлова.Слово = "Владелец" Или СтрокаСлова.Слово = "ВидДвижения" Или СтрокаСлова.Слово = "Код" Или СтрокаСлова.Слово = "МоментВремени" Или СтрокаСлова.Слово = "НомерСтроки" Или СтрокаСлова.Слово = "Период" Или СтрокаСлова.Слово = "Регистратор" //Или СтрокаСлова.Слово = "СубконтоДт" // Закомментировано 14.04.2012 //Или СтрокаСлова.Слово = "СубконтоКт" // Закомментировано 14.04.2012 Или СтрокаСлова.Слово = "СчетДт" Или СтрокаСлова.Слово = "СчетКт" Или ЛиТипСКвалификаторами И ДоступноеПолеСлова <> Неопределено) Тогда Если ДоступноеПолеСлова = Неопределено Тогда ЛиДобавляемСлово = Ложь; Иначе ОписаниеТиповСлова = ДоступноеПолеСлова.ТипЗначения; // Мультиметка73777324 Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы"); ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова; ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова; ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка"); СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЦикла; КонецЕсли; Прервать; ИначеЕсли Ложь Или (Истина И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджер.<Имя константы>" И СтрокаСлова.Слово = "Получить") Или (Истина И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджерЗначения.<Имя константы>" И СтрокаСлова.Слово = "Значение") Тогда ОписаниеТиповСлова = МетаданныеРодителя.Тип; // Мультиметка73777324 Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы"); ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова; ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова; ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка"); СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЦикла; ИначеЕсли Истина И СтрокаСлова.ТипСлова = "Метод" И (Ложь Или СтрокаСлова.Слово = "Выгрузить" Или СтрокаСлова.Слово = "ВыгрузитьКолонки") И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа); Образователь = Неопределено; Если НРег(КонкретныйТип) = Нрег("ТабличнаяЧасть") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()); Если МассивФрагментов[1] = Метаданные().Имя Тогда Если Метаданные().ТабличныеЧасти.Найти(МассивФрагментов[3]) <> Неопределено Тогда Образователь = ЭтотОбъект[МассивФрагментов[3]]; КонецЕсли; ИначеЕсли Ложь Или МассивФрагментов[0] = "Обработка" Или МассивФрагментов[0] = "Отчет" Тогда Образователь = Новый (МассивФрагментов[0] + "Объект." + МассивФрагментов[1]); // Опасно. Можно быть долго. Могут быть ошибки на толстом клиенте. Образователь = Образователь[МассивФрагментов[3]]; Иначе СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]); Образователь = СтруктураОбъекта.Данные[МассивФрагментов[3]]; КонецЕсли; ИначеЕсли НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()); СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]); Образователь = СтруктураОбъекта.Данные.ВидыСубконто; ИначеЕсли Ложь Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ВытесняющиеВидыРасчета.<Имя плана видов расчета>") Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("БазовыеВидыРасчета.<Имя плана видов расчета>") Или НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа) = Нрег("ВедущиеВидыРасчета.<Имя плана видов расчета>") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()); СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]); ИмяТЧ = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа); Попытка Образователь = СтруктураОбъекта.Данные[ИмяТЧ]; Исключение КонецПопытки; ИначеЕсли Найти(КонкретныйТип, "<") = 0 Тогда СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя())); Образователь = СтруктураОбъекта.Данные; КонецЕсли; Если Образователь <> Неопределено Тогда Если ТипЗнч(Образователь) <> Тип("ТаблицаЗначений") Тогда //! Образователь = 0; // ТабличнаяЧасть Образователь = Образователь.ВыгрузитьКолонки(); КонецЕсли; СтруктураТипа.Метаданные = Образователь; КонецЕсли; ИначеЕсли Истина И (Ложь Или СтрокаСлова.Слово = "СрезПервых" Или СтрокаСлова.Слово = "СрезПоследних") И КорневойТипРодителя = "РегистрСведений" И МетаданныеРодителя.ПериодичностьРегистраСведений = мМетаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда ЛиДобавляемСлово = Ложь; Прервать; ИначеЕсли Истина И (Ложь Или СтрокаСлова.Слово = "Остатки" Или СтрокаСлова.Слово = "ОстаткиИОбороты") И КорневойТипРодителя = "РегистрНакопления" И МетаданныеРодителя.ВидРегистра = мМетаданные.СвойстваОбъектов.ВидРегистраНакопления.Обороты Тогда ЛиДобавляемСлово = Ложь; Прервать; ИначеЕсли Истина И (Ложь Или СтрокаСлова.Слово = "ОборотыДтКт") И КорневойТипРодителя = "РегистрБухгалтерии" И Не МетаданныеРодителя.Корреспонденция Тогда ЛиДобавляемСлово = Ложь; Прервать; Иначе ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЕсли; ИначеЕсли Истина И СтрокаСлова.Слово = "Выполнить" И СтрокаСлова.ТипСлова = "Метод" И ТипЗнч(МетаданныеРодителя) = Тип("Запрос") Тогда ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(МетаданныеРодителя.Текст); СтруктураТипа.Метаданные = ПостроительЗапроса; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); ИначеЕсли Истина И СтрокаСлова.Слово = "Выгрузить" И СтрокаСлова.ТипСлова = "Метод" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("Запрос") Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")) Тогда ПостроительЗапроса = МетаданныеРодителя; Если ТипЗнч(ПостроительЗапроса) = Тип("Запрос") Тогда ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(ПостроительЗапроса.Текст); КонецЕсли; ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса, РодительскаяСтруктураТипа.ДержательМетаданных); СтруктураТипа.Метаданные = ПустаяТаблицаЗначенийИзПостроителя(ПостроительЗапроса); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); ИначеЕсли Истина И СтрокаСлова.Слово = "Выгрузить" И СтрокаСлова.ТипСлова = "Метод" И (Ложь Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыКоллекция") Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыСтруктураСКоллекцией")) Тогда #Если Клиент Тогда ТаблицаЗначений = Новый ТаблицаЗначений; Для Каждого КлючИЗначение Из ДочерниеСвойстваДанныхФормы(МетаданныеРодителя,, РодительскаяСтруктураТипа.ДержательМетаданных, Слово) Цикл ТаблицаЗначений.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; СтруктураТипа.Метаданные = ТаблицаЗначений; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); #КонецЕсли ИначеЕсли Истина И СтрокаСлова.Слово = "Значение" И СтрокаСлова.ТипСлова = "Свойство" И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("СписокЗначений") И СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы().Количество() = 1 Тогда СтруктураТипа = СтруктураТипаИзКонкретногоТипа(СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы()[0]); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); Иначе Если Истина И ИмяОбщегоТипаСлова = "Форма" // TODO возможно нужно заменить на ирОбщий.ЛиИмяТипаФормыЛкс() И СтрокаСлова.Слово = "ЭтаФорма" Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, РодительскаяСтруктураТипа, Истина); Иначе ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); КонецЕсли; КонецЕсли; КонецЦикла; Если Не ЛиДобавляемСлово Тогда Продолжить; КонецЕсли; Если ТаблицаТипов.Количество() = 0 Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЕсли; КонецЕсли; ТипЗначения = СтрокаСлова.ТипЗначения; Если ЛиТипСКвалификаторами Тогда ТипЗначения = "??," + ТипЗначения; КонецЕсли; ДобавитьВТаблицуСлов(ТаблицаСлов, СтрокаСлова.Слово, СтрокаСлова.ТипСлова, ТаблицаТипов, ТипЗначения, "Предопределенный"); КонецЦикла; Если ИспользоватьКэширование Тогда СтруктураТипаГлобальный = НоваяСтруктураТипа("Глобальный"); СтруктураТипаГлобальный.Метаданные = Метаданные; СтруктураТипаГлобальный.Конструктор = РодительскаяСтруктураТипа.Конструктор; СтруктураТипаГлобальный.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка; СловаКонтекстаМетаданные(СтруктураТипаГлобальный,, ТипСлова,, ЯзыкПрограммы,,, ВычислятьТипы, ФлагиКомпиляции,, ТаблицаСлов,,,, БазовоеРасширениеКонфигурации); ТаблицаСловИзКэша = ТаблицаСлов.Скопировать(); мКэшСловГлобальногоКонтекста[КлючКэширования] = ТаблицаСловИзКэша; Если НаборыСлов <> Неопределено Тогда НаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша); ТаблицаСлов.Очистить(); КонецЕсли; КонецЕсли; КонецЦикла; Возврат ТаблицаСлов; КонецФункции //. // Параметры: // ПостроительЗапроса - ПостроительЗапроса - // Возвращаемое значение: // ТаблицаЗначений, Неопределено - Функция ПустаяТаблицаЗначенийИзПостроителя(Знач ПостроительЗапроса) Экспорт ТаблицаЗначений = Новый ТаблицаЗначений; Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл ТаблицаЗначений.Колонки.Добавить(ВыбранноеПоле.Имя, ПостроительЗапроса.ДоступныеПоля[ВыбранноеПоле.Имя].ТипЗначения); КонецЦикла; Возврат ТаблицаЗначений; КонецФункции // Получает внутреннюю таблицу метаданных слов заданного родительского типа. // // Параметры: // РодительскаяСтруктураТипа - - Структура; // Слово - - Строка, *Неопределено - для отбора; // ТипСлова - - Строка, *Неопределено - для отбора; // ВнутриГруппыОбщихМодулей - Булево - ; // ЯзыкПрограммы - - *Число, 0; // ТекущийИндекс - Строка - выражение в квадратных скобках. // ВнешниеФункцииКомпоновкиДанных - - // ВычислятьТипы - - // ФлагиКомпиляции - см. НовыеФлагиКомпиляции() - // МодульМетаданныхДинамический - - // ТаблицаСлов - - // ВычислятьТипыМетодовМодулей - Булево - // ЭтоЛокальныйКонтекст - Булево - // БазовоеРасширениеКонфигурации - Строка - "" - основная конфигурация, "*" - все расширения // // Возвращаемое значение: // ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов". // Функция СловаКонтекстаМетаданные(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВнутриГруппыОбщихМодулей = Ложь, Знач ЯзыкПрограммы = 0, Знач ТекущийИндекс = Неопределено, Знач ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина, Знач ФлагиКомпиляции = Неопределено, Знач МодульМетаданныхДинамический = Неопределено, Знач ТаблицаСлов = Неопределено, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ЭтоЛокальныйКонтекст = Ложь, Знач ЛиВместеСЛокальнымКонтекстом = Ложь, Знач БазовоеРасширениеКонфигурации = "") Экспорт Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСвойствТипа(); КонецЕсли; Если Ложь Или ТипСлова = "Конструктор" Или РодительскаяСтруктураТипа.Конструктор Или Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа) // родительский контекст является процедурой Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Произвольный" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Неопределено" Тогда Возврат ТаблицаСлов; КонецЕсли; // Мультиметка3398476724 ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс(); НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина); КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП); КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП); БезКонтекста = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "БезКонтекста", ЛиСеансТолстогоКлиентаУП); ПредставлениеМетаданных = ирОбщий.ПредставлениеЗначенияЛкс(РодительскаяСтруктураТипа.Метаданные); ЭтоМетаданныеТабличнойЧастиВнешнейОбработки = ирОбщий.ПервыйФрагментЛкс(ПредставлениеМетаданных) = "ВнешняяОбработкаТабличнаяЧасть"; Если Не ирОбщий.СтрНачинаетсяСЛкс(ПредставлениеМетаданных, "Внешн") Тогда КонкретныйТип = ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа); Если Найти(ирОбщий.ПервыйФрагментЛкс(КонкретныйТип, "["), "<") > 0 Тогда // Такой конкретный тип не разрешен Возврат ТаблицаСлов; КонецЕсли; КонецЕсли; Если Слово <> Неопределено Тогда ВычислятьТипыМетодовМодулей = Истина; КонецЕсли; Если Слово <> Неопределено И ТекущийИндекс <> Неопределено Тогда Если Ложь Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соответствие" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ФиксированноеСоответствие" Тогда Если Истина И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Структура") И РодительскаяСтруктураТипа.Метаданные.Значение <> Неопределено Тогда ТаблицаТипов = ДобавитьВТаблицуТипов(, РодительскаяСтруктураТипа.Метаданные.Значение); ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1"); Возврат ТаблицаСлов; КонецЕсли; Иначе ЛиИндексИдентификатор = Ложь; RegExp.Pattern = "^""(" + шИмя + ")""$"; РезультатСтроковойКонстанты = RegExp.НайтиВхождения(Слово); Если РезультатСтроковойКонстанты.Количество() > 0 Тогда Слово = РезультатСтроковойКонстанты[0].SubMatches(0); ЛиИндексИдентификатор = Истина; КонецЕсли; Если Ложь Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Структура" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ФиксированнаяСтруктура" Тогда // у них значениями именованных свойств являются произвольные типы Иначе Если Не ЛиИндексИдентификатор Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа, Слово, ЯзыкПрограммы); ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1"); Возврат ТаблицаСлов; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; ЭтоГруппаОбщихМодулей = Ложь; ПолноеИмяПодсистемыИР = ирОбщий.ИмяПродуктаЛкс(); МаксЧислоТиповДляАнализа = МаксЧислоТиповДляАнализа(); ТаблицаОбщихТиповСтруктурыТипа = ТаблицаОбщихТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст); НомерВерсииПлатформы = ирКэш.НомерВерсииПлатформыЛкс(); Для Каждого СтрокаОбщегоТипа Из ТаблицаОбщихТиповСтруктурыТипа Цикл ИмяОбщегоТипаРодителя = СтрокаОбщегоТипа.ИмяОбщегоТипа; Если Истина И ИмяОбщегоТипаРодителя = "Глобальный" И РодительскаяСтруктураТипа.ИмяОбщегоТипа <> "Глобальный" // пропускаем вызов для заполнения кэша И Слово = Неопределено И ТекущийИндекс = Неопределено Тогда // Подразумеваем, что в ТаблицаСлов уже помещен кэш Предопределенные+Метаданные Продолжить; КонецЕсли; Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипаРодителя, "ISWbemObject {WbemScripting.SwbemLocator}") Тогда Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("COMОбъект") Тогда СтруктураЦикла = Новый Структура(); Попытка СтруктураЦикла.Вставить("Свойство", СтрокаОбщегоТипа.Метаданные.Properties_); СтруктураЦикла.Вставить("Метод", СтрокаОбщегоТипа.Метаданные.Methods_); Исключение КонецПопытки; Для Каждого КлючИЗначение Из СтруктураЦикла Цикл КоллекцияСвойств = КлючИЗначение.Значение; лТипСлова = КлючИЗначение.Ключ; Если Истина И ТипСлова <> Неопределено И Не ирОбщий.СтрокиРавныЛкс(лТипСлова, ТипСлова) Тогда Продолжить; КонецЕсли; Для Каждого Свойство Из КоллекцияСвойств Цикл ИмяСвойства = Свойство.Name; Если Истина И Слово <> Неопределено И Не ирОбщий.СтрокиРавныЛкс(ИмяСвойства, Слово) Тогда Продолжить; КонецЕсли; ТаблицаТипов = НоваяТаблицаТипов(); СтруктураТипа = ТаблицаТипов.Добавить(); СтруктураТипа.СтрокаОписания = Свойство; СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство); СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные; ДобавитьВТаблицуСлов(ТаблицаСлов, ИмяСвойства, лТипСлова, ТаблицаТипов,, "Метаданные"); КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные; Если Ложь Или ИмяОбщегоТипаРодителя = "Локальный" Или (Истина И ИмяОбщегоТипаРодителя <> "Глобальный" И ФлагиКомпиляции <> Неопределено И ФлагиКомпиляции.БезКонтекста И ЭтоЛокальныйКонтекст) Тогда НайденныеСтроки = Новый Массив; Иначе КорневойТипРодителя = Неопределено; ПостроительЗапросаРодителя = Неопределено; Если РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя); Если Ложь Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Или (Истина И ЭтоИнтеграция И (Ложь Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис") Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис"))) Тогда Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя); Иначе КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя); КонецЕсли; ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица); КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 2 И ИмяОбщегоТипаРодителя = "Глобальный" И ВнешниеФункцииКомпоновкиДанных Тогда СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово", ИмяОбщегоТипаРодителя, 0, РодительскаяСтруктураТипа.ТипЯзыка, НРег("<Имя общего модуля>")); Иначе СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипаРодителя, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка); КонецЕсли; Если ТипСлова <> Неопределено Тогда СтруктураКлюча.Вставить("ТипСлова", ТипСлова); КонецЕсли; НайденныеСтроки = ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча); КонецЕсли; ПредыдущаяСтрокаВида = Неопределено; // Для регистра бухгалтерии Для Каждого СтрокаВида Из НайденныеСтроки Цикл Если Ложь Или (Истина И ПредыдущаяСтрокаВида <> Неопределено И ПредыдущаяСтрокаВида.НСлово = СтрокаВида.НСлово И ПредыдущаяСтрокаВида.ТипСлова = СтрокаВида.ТипСлова) Или СтрокаВида.НомерВерсииПлатформы > НомерВерсииПлатформы Или СтрокаВида.ТипСлова = "Событие" Тогда Продолжить; КонецЕсли; ПредыдущаяСтрокаВида = СтрокаВида; ЛиТипСКвалификаторами = ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаВида.ТипЗначения); СхемаКоллекции = Новый Соответствие; МетаданныеЭлементов = Новый Соответствие; КоллекцияЗначений = Неопределено; ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаВида.Слово, "<", ">", Ложь, Истина); КлючПоиска = Новый Структура("ИмяОбщегоТипа, ИмяЭлементаКоллекции", ИмяОбщегоТипаРодителя, ИмяЭлементаКоллекции); СтрокаОписанияВида = Неопределено; НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска); Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда СтрокаОписанияВида = НайденныеСтрокиКоллекций[0]; Если НайденныеСтрокиКоллекций.Количество() > 1 Тогда #Если Клиент Тогда Если Истина И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы" И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Форма") Тогда // Устранение неоднозначности одноименных типов "ЭлементыФормы" обычной и упрвляемой формы СтрокаОписанияВида = НайденныеСтрокиКоллекций[1]; КонецЕсли; #КонецЕсли КонецЕсли; КонецЕсли; Если СтрокаОписанияВида = Неопределено Тогда КлючПоиска.Удалить("ИмяОбщегоТипа"); НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска); Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда СтрокаОписанияВида = НайденныеСтрокиКоллекций[0]; КонецЕсли; КонецЕсли; //// Исправление кривоты платформенной справки (неуникальные имена шаблона элемента коллекции между разными типами коллекций) //Если ИмяЭлементаКоллекции = "<Имя элемента управления>" Тогда // СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции); // Если ИмяОбщегоТипа = "ВсеЭлементыФормы" Тогда // СтруктураОтбора.ИмяКоллекции = "Элементы"; // Иначе//Если ИмяОбщегоТипа = "ЭлементыФормы" Тогда // СтруктураОтбора.ИмяКоллекции = "ЭлементыФормы"; // КонецЕсли; // СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0]; //ИначеЕсли ИмяЭлементаКоллекции = "<Имя колонки>" Тогда // СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции); // Если ИмяОбщегоТипа = "Ячейки" Тогда // СтруктураОтбора.ИмяКоллекции = "ОформленияЯчеек"; // Иначе//Если ИмяОбщегоТипа = "СтрокаТаблицыЗначений" Тогда // СтруктураОтбора.ИмяКоллекции = "Колонки"; // КонецЕсли; // СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0]; //КонецЕсли; Если Слово <> Неопределено Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаВида.Слово, ИмяЭлементаКоллекции); НачалоТекущегоСлова = Лев(Слово, СтрДлина(МассивФрагментов[0])); КонецТекущегоСлова = Прав(Слово, СтрДлина(МассивФрагментов[1])); ИмяТекущегоСлова = Сред(Слово, СтрДлина(НачалоТекущегоСлова) + 1, СтрДлина(Слово) - СтрДлина(КонецТекущегоСлова)); Если НачалоТекущегоСлова + ИмяЭлементаКоллекции + КонецТекущегоСлова <> СтрокаВида.Слово Тогда Продолжить; КонецЕсли; КонецЕсли; Если СтрокаОписанияВида = Неопределено Тогда // Имя элемента коллекции не внесено в служебную таблицу Продолжить; КонецЕсли; Если Истина И СтрокаОписанияВида.ИмяКоллекции = "Предопределенные" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") // Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ Т.Ссылка ИЗ " + МетаданныеРодителя.ПолноеИмя() + " КАК Т |ГДЕ Т.Предопределенный |"; Результат = Запрос.Выполнить().Выгрузить(); МенеджерТипа = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя); Для Каждого СтрокаРезультата Из Результат Цикл СхемаКоллекции.Вставить(МенеджерТипа.ПолучитьИмяПредопределенного(СтрокаРезультата.Ссылка), Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(СтрокаРезультата.Ссылка)))); КонецЦикла; ИначеЕсли Ложь Или (Истина И (Ложь Или СтрокаОписанияВида.ИмяКоллекции = "Колонки" Или СтрокаОписанияВида.ИмяКоллекции = "Поля") И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") Или ТипЗнч(МетаданныеРодителя) = Тип("РезультатЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений") )) Или (Истина И СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>" И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")) Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда КоллекцияЗначений = МетаданныеРодителя; ИначеЕсли Найти(ИмяОбщегоТипаРодителя, "Колон") = 0 Тогда // %%%% Некрасиво, но работает Если СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>" Тогда ДинамическийСписок = МетаданныеРодителя.Значение; ПостроительСписка = ПостроительЗапросаПоСтруктуреТипа(СтруктураТипаИзЗначения(ДинамическийСписок)); КоллекцияКолонок = ДинамическийСписок.Колонки; Для Каждого Колонка Из КоллекцияКолонок Цикл Если Колонка.Имя = "" Тогда // Антибаг платформы 8.2.16 Продолжить; КонецЕсли; СхемаКоллекции.Вставить(Колонка.Имя, ПостроительСписка.ДоступныеПоля[Колонка.Имя].ТипЗначения); КонецЦикла; Иначе Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений") Тогда Попытка МетаОбъект = МетаданныеРодителя.Владелец(); Исключение // Строка была удалена МетаОбъект = Неопределено; КонецПопытки; Если МетаОбъект <> Неопределено Тогда Для Каждого Колонка Из МетаОбъект.Колонки Цикл Если Колонка.Имя = "" Тогда // Строка таблицы/дерева при перетаскивании имеет такую колонку (вероятно ошибка платформы) Продолжить; КонецЕсли; СхемаКоллекции.Вставить(Колонка.Имя, МетаданныеРодителя[Колонка.Имя]); КонецЦикла; КонецЕсли; Иначе Для Каждого Колонка Из МетаданныеРодителя.Колонки Цикл СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения); КонецЦикла; КонецЕсли; КонецЕсли; Иначе Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений") Тогда КоллекцияЗначений = МетаданныеРодителя.Владелец().Колонки; Иначе КоллекцияЗначений = МетаданныеРодителя.Колонки; КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И ЭтоМетаданныеТабличнойЧастиВнешнейОбработки Тогда Для Каждого Колонка Из МетаданныеРодителя.ВыгрузитьКолонки().Колонки Цикл Если Колонка.Имя = "НомерСтроки" Тогда Продолжить; КонецЕсли; СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения); КонецЦикла; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И СтрокаОписанияВида.ИмяКоллекции = "Колонки" Тогда ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя); Если СтрокаВида.ТипЗначения <> "Произвольный" Тогда Попытка ОписаниеТиповЭлемента = Новый ОписаниеТипов(СтрокаВида.ТипЗначения); Исключение ОписаниеТиповЭлемента = Неопределено; КонецПопытки; КонецЕсли; Для Каждого ВыбранноеПоле Из МетаданныеРодителя.ВыбранныеПоля Цикл лДоступноеПоле = МетаданныеРодителя.ДоступныеПоля.Найти(ВыбранноеПоле.Имя); Если СтрокаВида.ТипЗначения = "Произвольный" Тогда ОписаниеТиповЭлемента = лДоступноеПоле.ТипЗначения; КонецЕсли; СхемаКоллекции.Вставить(ВыбранноеПоле.Имя, ОписаниеТиповЭлемента); КонецЦикла; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И СтрокаОписанияВида.ИмяКоллекции = "Поля" Тогда ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя); Для Каждого ДоступноеПоле Из МетаданныеРодителя.ДоступныеПоля Цикл СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ДоступноеПоле.ТипЗначения); КонецЦикла; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И СтрокаОписанияВида.ИмяКоллекции = "Структура" Тогда // Вроде бы мертвая ветка, т.к. для свойства "Параметры" всегда передается готовая структура вместо построителя Для Каждого КлючИЗначение Из МетаданныеРодителя.Параметры Цикл СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ДоступноеПоле.ТипЗначения); КонецЦикла; ИначеЕсли Ложь Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "ФиксированнаяСтруктура" И ТипЗнч(МетаданныеРодителя) = Тип("ФиксированнаяСтруктура")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "НастройкаОформления" И ТипЗнч(МетаданныеРодителя) = Тип("НастройкаОформления")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Отбор" И ТипЗнч(МетаданныеРодителя) = Тип("Отбор")) Тогда КоллекцияЗначений = МетаданныеРодителя; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеКомпоновкиДанных") Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")) Тогда Для Каждого ДоступноеПоле Из МетаданныеРодителя.Элементы Цикл СхемаКоллекции.Вставить(ирОбщий.ПоследнийФрагментЛкс("" + ДоступноеПоле.Поле), ДоступноеПоле.ТипЗначения); КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеРеквизиты" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Попытка ОбщиеРеквизиты = Метаданные.ОбщиеРеквизиты; Исключение // Платформа 8.2.13 и ниже ОбщиеРеквизиты = Новый Массив; КонецПопытки; СхемаКоллекции = Новый Массив(); Для Каждого ОбщийРеквизит Из ОбщиеРеквизиты Цикл Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаданныеРодителя) Тогда СхемаКоллекции.Добавить(ОбщийРеквизит); КонецЕсли; КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Картинки" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") Тогда Если ЗначениеЗаполнено(Слово) Тогда МетаКартинка = Метаданные.ОбщиеКартинки.Найти(Слово); Если МетаКартинка <> Неопределено Тогда СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка); КонецЕсли; Иначе // Долго СхемаКоллекции = Новый Структура; Для Каждого МетаКартинка Из Метаданные.ОбщиеКартинки Цикл СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка); КонецЦикла; КонецЕсли; ИначеЕсли Истина // И СтрокаОписанияВида.ИмяКоллекции = "Свойства" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектXDTO") Тогда КоллекцияЗначений = Новый Структура; ОбъектXDTO = МетаданныеРодителя; Для Каждого Свойство Из ОбъектXDTO.Свойства() Цикл Если Истина И ЗначениеЗаполнено(Свойство.Имя) //И ОбъектXDTO.Установлено(Свойство.Имя) Тогда Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя); Иначе ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя); КонецЕсли; КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства); КонецЕсли; КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" И ТипЗнч(МетаданныеРодителя) = Тип("СвойствоXDTO") Тогда КоллекцияЗначений = Новый Структура; ОбъектXDTO = МетаданныеРодителя.ОбъектВладелец; Свойство = МетаданныеРодителя; Если ОбъектXDTO.Установлено(Свойство.Имя) Тогда Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя); Иначе ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя); КонецЕсли; КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства); КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Параметры" И ТипЗнч(МетаданныеРодителя) = Тип("ТабличныйДокумент") И МетаданныеРодителя.ВысотаТаблицы * МетаданныеРодителя.ШиринаТаблицы < 20000 Тогда КоллекцияЗначений = Новый Структура; СписокПараметров = ирОбщий.ПараметрыТабличногоДокументаЛкс(МетаданныеРодителя); Для Каждого ЭлементСписка Из СписокПараметров Цикл Попытка КоллекцияЗначений.Вставить(ЭлементСписка.Значение); Исключение // Имена параметров могут содержать запрещенные символы КонецПопытки; КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений")) Тогда СхемаКоллекции = МетаданныеРодителя.Колонки; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда СхемаКоллекции = ирКэш.ПоляТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(МетаданныеРодителя.ПолноеИмя()), Истина); ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Тип") <> ирОбщий.ТипУправляемаяФормаЛкс() Тогда СхемаКоллекции = МетаданныеРодителя; #Если Клиент Тогда ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Форма") Тогда КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово]; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты" И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя) Тогда Если ЗначениеЗаполнено(Слово) Тогда ИмитаторФормы = МетаданныеРодителя; Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда Попытка ЗначениеРеквизита = МетаданныеРодителя[Слово]; Исключение ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя); КонецПопытки; КонецЕсли; Если ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда СтруктураИмен = ИменаРеквизитовФормы(ИмитаторФормы, "").Все; Если СтруктураИмен.Свойство(Слово) Тогда ЗначениеСлова = СтруктураИмен[Слово]; СхемаКоллекции.Вставить(Слово, ЗначениеСлова); ИначеЕсли Не ЛиВместеСЛокальнымКонтекстом Тогда ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Реквизит:" + Слово); КонецЕсли; Иначе // Для ускорения особенно для управляемой формы КоллекцияЗначений = Новый Структура; Попытка ЗначениеРеквизита = МетаданныеРодителя[Слово]; Исключение ЗначениеРеквизита = Null; КонецПопытки; Если ЗначениеРеквизита <> Null Тогда КоллекцияЗначений.Вставить(Слово, ЗначениеРеквизита); КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(МетаданныеРодителя) = Тип("Форма") Тогда ПутьКРодителю = Неопределено; Иначе ПутьКРодителю = ""; КонецЕсли; СтруктураИмен = ИменаРеквизитовФормы(МетаданныеРодителя, ПутьКРодителю).Все; Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда СхемаКоллекции = СтруктураИмен; Иначе КоллекцияЗначений = Новый Структура; Для Каждого КлючИЗначение Из СтруктураИмен Цикл Попытка ЗначениеРеквизита = МетаданныеРодителя[КлючИЗначение.Ключ]; Исключение Если КлючИЗначение.Значение <> Неопределено Тогда // Добавленный реквизит был получен через буфер обмена, но пока отсутствует в натуральной форме ЗначениеРеквизита = ТаблицаТиповИзОписанияТипов(КлючИЗначение.Значение); Иначе ЗначениеРеквизита = Неопределено; КонецЕсли; КонецПопытки; КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеРеквизита); КонецЦикла; КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Команды" И ирОбщий.ЛиФормаИлиИмитаторЛкс(РодительскаяСтруктураТипа.ДержательМетаданных, Ложь) Тогда Форма = РодительскаяСтруктураТипа.ДержательМетаданных; СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Если СлужебныеДанные <> Неопределено Тогда СхемаКоллекции = СлужебныеДанные.Команды; Если ЗначениеЗаполнено(Слово) И Не СхемаКоллекции.Свойство(Слово) Тогда ДобавитьОтсутствиеЭлементаФормы(Форма, "Команда:" + Слово); КонецЕсли; Иначе Если ТипЗнч(Форма) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда СхемаКоллекции = Форма.Команды; КонецЕсли; КонецЕсли; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") И РодительскаяСтруктураТипа.СтрокаОписания.Слово = "Параметры" Тогда Форма = РодительскаяСтруктураТипа.ДержательМетаданных; СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Если СлужебныеДанные <> Неопределено Тогда СхемаКоллекции = СлужебныеДанные.Параметры; // Параметры часто не описаны в структуре формы //Если ЗначениеЗаполнено(Слово) И Не СхемаКоллекции.Свойство(Слово) Тогда // ДобавитьОтсутствиеЭлементаФормы(Форма, "Параметр:" + Слово); //КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ДинамическийСписок") Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыДерево") Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктураСКоллекцией") Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыКоллекция") Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыКоллекцияЭлементовДерева") // Для следующих сериализация вызывает ошибку //Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыЭлементДерева") //Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыЭлементКоллекции") Тогда Форма = РодительскаяСтруктураТипа.ДержательМетаданных; ЛиКоллекция = Ложь Или ирОбщий.ЛиКоллекцияЛкс(МетаданныеРодителя) Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыДерево"); СтруктураИмен = ДочерниеСвойстваДанныхФормы(МетаданныеРодителя, ЛиКоллекция, Форма, Слово); СхемаКоллекции = СтруктураИмен; Если Не ЛиКоллекция Тогда Для Каждого КлючИЗначение Из СтруктураИмен Цикл ЗначениеСвойства = КлючИЗначение.Значение; // ОписаниеТипов Если Ложь Или ЗначениеСвойства = Неопределено Или ЗначениеСвойства.Типы().Количество() = 0 Тогда ЗначениеСвойства = ТаблицаТиповИзЗначения(МетаданныеРодителя[КлючИЗначение.Ключ]); Иначе ЗначениеСвойства = ТаблицаТиповИзОписанияТипов(ЗначениеСвойства); КонецЕсли; ЗначениеСвойства.ЗаполнитьЗначения(Форма, "ДержательМетаданных"); Если КоллекцияЗначений = Неопределено Тогда КоллекцияЗначений = Новый Структура; КонецЕсли; КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеСвойства); КонецЦикла; КонецЕсли; ИначеЕсли Ложь Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "ЭлементыФормы" И ТипЗнч(МетаданныеРодителя) = Тип("Форма")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Элементы" И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь)) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Страницы" И ТипЗнч(МетаданныеРодителя) = Тип("Панель")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Кнопки" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкаКоманднойПанели") Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкиКоманднойПанели"))) Тогда ДочерниеЭлементы = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции]; Если ИмяОбщегоТипаРодителя = "ОформленияЯчеек" Тогда СхемаКоллекции = ДочерниеЭлементы; Иначе ИмитаторФормы = МетаданныеРодителя; Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда КоллекцияЗначений = Новый Соответствие; Для Каждого ЭлементФормы Из ДочерниеЭлементы Цикл КоллекцияЗначений.Вставить(ЭлементФормы.Имя, ЭлементФормы); КонецЦикла; ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя); ИначеЕсли ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда КоллекцияЗначений = Новый Соответствие; Иначе КоллекцияЗначений = ДочерниеЭлементы; КонецЕсли; Если Истина И ТипЗнч(ИмитаторФормы) = Тип("Структура") И ИмитаторФормы.Свойство(СтрокаОписанияВида.ИмяКоллекции) Тогда // имитатор формы Для Каждого КлючИЗначение Из ИмитаторФормы[СтрокаОписанияВида.ИмяКоллекции] Цикл Если ЗначениеЗаполнено(Слово) И Не ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Ключ, Слово) Тогда Продолжить; КонецЕсли; Если КоллекцияЗначений[КлючИЗначение.Ключ] <> Неопределено Тогда Продолжить; КонецЕсли; СтруктураЭлемента = КлючИЗначение.Значение; ЗначениеЭлемента = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(СтруктураЭлемента.Тип)); // Если ЗначениеЗаполнено(Слово) Тогда ЗначениеЭлемента = ТаблицаТиповИзОписанияТипов(ЗначениеЭлемента); ЗначениеЭлемента[0].Метаданные = СтруктураЭлемента; ЗначениеЭлемента[0].ДержательМетаданных = ИмитаторФормы; ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ЗначениеЭлемента[0].ИмяОбщегоТипа, СтруктураЭлемента); Если ИмяОбщегоТипаРасширения <> Неопределено Тогда ЗначениеЭлемента[0].ИмяОбщегоТипа = ИмяОбщегоТипаРасширения; КонецЕсли; КонецЕсли; КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеЭлемента); КонецЦикла; Если ЗначениеЗаполнено(Слово) И КоллекцияЗначений[Слово] = Неопределено Тогда ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Элемент:" + Слово); КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы" И (Ложь Или ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы") Или ТипЗнч(МетаданныеРодителя) = Тип("ГруппаФормы")) Тогда КоллекцияЗначений = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции]; #КонецЕсли ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда КоллекцияЗначений = МетаданныеРодителя; //ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Оформление" Тогда // Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл // Если МетаОбщийМодуль.Глобальный Тогда // Продолжить; // КонецЕсли; // СхемаКоллекции.Вставить(МетаОбщийМодуль.Имя); // КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеМодули" И ИмяОбщегоТипаРодителя = "Глобальный" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") // Тогда СхемаКоллекции = ирКэш.ДоступныеОбщиеМодулиЛкс(НаСервере, КлиентОбычноеПриложение, КлиентУправляемоеПриложение); Если мДобавленныеОбщиеМодули.Количество() > 0 Тогда ирОбщий.СкопироватьКоллекциюЛкс(мДобавленныеОбщиеМодули, СхемаКоллекции); КонецЕсли; Если Прав(Слово, 1) = "_" Тогда ЭтоГруппаОбщихМодулей = Истина; НачальныйФрагмент = НРег(ирОбщий.СтрокаБезКонцаЛкс(Слово)); Слово = Неопределено; ТаблицаСлов.Очистить(); НоваяСхема = Новый Структура; Для Каждого КлючИЗначение Из СхемаКоллекции Цикл Если ирОбщий.СтрНачинаетсяСЛкс(КлючИЗначение.Ключ, НачальныйФрагмент) Тогда НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЕсли; КонецЦикла; СхемаКоллекции = НоваяСхема; ИначеЕсли Не ЗначениеЗаполнено(Слово) Тогда СписокЗначений = Новый СписокЗначений; НоваяСхема = Новый Структура; Для Каждого КлючИЗначение Из СхемаКоллекции Цикл СписокЗначений.Добавить(КлючИЗначение.Ключ); НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; СписокЗначений.СортироватьПоЗначению(); СхемаКоллекции = НоваяСхема; ИмяГруппы = Неопределено; ЧленыГруппы = Новый Массив; Для Каждого ИмяМодуляЦикл Из СписокЗначений.ВыгрузитьЗначения() Цикл Если Истина И ИмяГруппы <> Неопределено И ирОбщий.СтрНачинаетсяСЛкс(ИмяМодуляЦикл, ИмяГруппы, Истина) Тогда ЧленыГруппы.Добавить(ИмяМодуляЦикл); Иначе Если ЧленыГруппы.Количество() > 2 Тогда СхемаКоллекции.Вставить(ИмяГруппы + "_"); КонецЕсли; ИмяГруппы = ИмяМодуляЦикл; ЧленыГруппы.Очистить(); КонецЕсли; КонецЦикла; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ВидыСубконто" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда //! МетаданныеРодителя = 0; // ОбъектМетаданныхРегистрБухгалтерии Для Счетчик = 1 По МетаданныеРодителя.ПланСчетов.МаксКоличествоСубконто Цикл СхемаКоллекции.Вставить(Строка(Счетчик), МетаданныеРодителя.ПланСчетов.ВидыСубконто); КонецЦикла; ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Движения" Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда //! МетаданныеРодителя = 0; // ОбъектМетаданныхДокумент Для Каждого МетаРегистр Из МетаданныеРодителя.Движения Цикл МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаРегистр.ПолноеИмя()); СхемаКоллекции.Вставить(МетаРегистр.Имя, Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1])); КонецЦикла; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияДвижений") Тогда Для Каждого НаборЗаписейРегистра Из МетаданныеРодителя Цикл // РегистрСведенийНаборЗаписей.КурсыВалют СхемаКоллекции.Вставить(НаборЗаписейРегистра.Метаданные().Имя, НаборЗаписейРегистра); КонецЦикла; ИначеЕсли Истина И Слово <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") // Тогда МетаданныеРегистра = Метаданные.РегистрыСведений.Найти(Слово); Если МетаданныеРегистра = Неопределено Тогда МетаданныеРегистра = Метаданные.РегистрыНакопления.Найти(Слово); КонецЕсли; Если МетаданныеРегистра = Неопределено Тогда МетаданныеРегистра = Метаданные.РегистрыБухгалтерии.Найти(Слово); КонецЕсли; Если МетаданныеРегистра = Неопределено Тогда МетаданныеРегистра = Метаданные.РегистрыРасчета.Найти(Слово); КонецЕсли; Если МетаданныеРегистра <> Неопределено Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаданныеРегистра.ПолноеИмя()); СхемаКоллекции.Вставить(МассивФрагментов[1], Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1])); КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ТочкиМаршрута" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда КоллекцияЗначений = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя)[СтрокаОписанияВида.ИмяКоллекции]; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Или ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация")) Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Тогда КоллекцияЗначений = МетаданныеРодителя; Иначе ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь); Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных); Если СтрокаКорневогоТипа <> Неопределено Тогда //КоллекцияЗначений = МетаданныеРодителя[ИмяКоллекцииОбъектовМетаданных]; Попытка КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово]; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); // Для отладки КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли Истина //И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" И ЭтоИнтеграция И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданныхИис") Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.МетаданныеИис")) Тогда Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииОбъектовМетаданных + ": ", , Ложь); Иначе ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции; КонецЕсли; Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных); Запрос = Новый Запрос; Если СтрокаКорневогоТипа <> Неопределено Тогда //лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово; Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданныхИис |ГДЕ КонфигурацияМетаданных = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойствМетаданныхИис.Свойство)"; Запрос.Текст = ТекстЗапроса; Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип"); КонецЦикла; Иначе ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.МетаданныеИис |ГДЕ КонфигурацияМетаданных = &Владелец И ТипМетаданных.ИмяМножественное = &ИмяРодителя"; Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных); Запрос.Текст = ТекстЗапроса; Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл СхемаКоллекции[Выборка.Имя] = Выборка.Значение; КонецЦикла; КонецЕсли; КонецЕсли; Иначе //КоллекцияЗначений = МетаданныеРодителя; КонецЕсли; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ОбщийМодуль") Тогда // Платформа пока не дает узнать имя модуля Иначе Если мМассивИсключенийИменКоллекций.НайтиПоЗначению(СтрокаОписанияВида.ИмяКоллекции) <> Неопределено Тогда Продолжить; КонецЕсли; СхемаКоллекции = МетаданныеРодителя; Если ТипЗнч(МетаданныеРодителя) <> Тип("КоллекцияОбъектовМетаданных") Тогда ЦелевойТип = Неопределено; Если Найти(СтрокаОбщегоТипа.ИмяОбщегоТипа, "<") = 0 Тогда Попытка ЦелевойТип = Тип(СтрокаОбщегоТипа.ИмяОбщегоТипа); Исключение КонецПопытки; КонецЕсли; Попытка Если ТипЗнч(МетаданныеРодителя) = ЦелевойТип Тогда СхемаКоллекции = МетаданныеРодителя; Иначе СхемаКоллекции = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции]; КонецЕсли; Исключение Продолжить; КонецПопытки; КонецЕсли; КонецЕсли; Если КоллекцияЗначений = Неопределено Тогда КоллекцияЗначений = СхемаКоллекции; Если Слово <> Неопределено Тогда ЭлементСхемы = Неопределено; Если Ложь Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированнаяСтруктура") Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированноеСоответствие") Или ТипЗнч(КоллекцияЗначений) = Тип("Структура") Или ТипЗнч(КоллекцияЗначений) = Тип("Соответствие") Тогда //Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл // Если ЭлементКоллекции.Ключ = ИмяТекущегоСлова Тогда // ЭлементСхемы = ЭлементКоллекции.Значение; // Прервать; // КонецЕсли; //КонецЦикла; Попытка ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова]; Исключение КонецПопытки; Иначе ЭлементСхемы = Null; Если ТипЗнч(КоллекцияЗначений) <> Тип("Массив") Тогда Попытка ЭлементСхемы = КоллекцияЗначений.Найти(ИмяТекущегоСлова); Исключение КонецПопытки; КонецЕсли; Если ЭлементСхемы = Null Тогда ЭлементСхемы = Неопределено; Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл Если ЭлементКоллекции.Имя = ИмяТекущегоСлова Тогда ЭлементСхемы = ЭлементКоллекции; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; КоллекцияЗначений = Новый Соответствие; Если ЭлементСхемы <> Неопределено Тогда КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы); КонецЕсли; КонецЕсли; Иначе Если Слово <> Неопределено Тогда Попытка ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова]; Исключение ЭлементСхемы = Null; КонецПопытки; КоллекцияЗначений = Новый Соответствие; Если ЭлементСхемы <> Null Тогда КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы); КонецЕсли; КонецЕсли; КонецЕсли; Если КоллекцияЗначений = Неопределено Тогда КоллекцияЗначений = Новый Массив(); КонецЕсли; ЭтоСубконто = Найти(СтрокаВида.Слово, "Субконто") = 1; ПредыдущаяТаблицаТипов = Неопределено; ВычислятьТипыЦикл = ВычислятьТипы Или КоллекцияЗначений.Количество() < 100; ИмяКолонкиФлага = ИмяКолонкиФлагаВнутриТаблицы(); Если ЗначениеЗаполнено(СтрокаВида.ТипЗначения) Тогда ТипЗначенияСлова = "," + СтрокаВида.ТипЗначения; ТипЗначенияСлова = СтрЗаменить(ТипЗначенияСлова, ",Произвольный", ""); Иначе ТипЗначенияСлова = ""; КонецЕсли; Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл Если ЭлементКоллекции = Неопределено Тогда // ПараметрыМакетаТабличногоДокумента Продолжить; КонецЕсли; Если ТипЗнч(ЭлементКоллекции) = Тип("КлючИЗначение") Тогда ИмяСвойства = ЭлементКоллекции.Ключ; ЗначениеСвойства = ЭлементКоллекции.Значение; Иначе ИмяСвойства = ЭлементКоллекции.Имя; ЗначениеСвойства = ЭлементКоллекции; КонецЕсли; КонечноеСлово = СтрЗаменить(СтрокаВида.Слово, ИмяЭлементаКоллекции, ИмяСвойства); ТаблицаТипов = Неопределено; Если ВычислятьТипыЦикл Тогда Если ЭтоСубконто И ПредыдущаяТаблицаТипов <> Неопределено Тогда ТаблицаТипов = ПредыдущаяТаблицаТипов; ИначеЕсли Истина И ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений") И ЗначениеСвойства.Количество() > 0 И ЗначениеСвойства.Колонки.Найти(ИмяКолонкиФлага) <> Неопределено //И ЗначениеСвойства.Колонки.Найти("ИмяОбщегоТипа") <> Неопределено Тогда ТаблицаТипов = ЗначениеСвойства; Иначе ТаблицаТипов = НоваяТаблицаТипов(); ПредыдущаяТаблицаТипов = ТаблицаТипов; МассивТипов = Новый Массив; Квалификаторы = Неопределено; ОписаниеТиповЗначения = Неопределено; Если СхемаКоллекции.Количество() > 0 Тогда Если Ложь Или СтрокаВида.ТипЗначения = "" Или СтрокаВида.ТипЗначения = "Произвольный" Или СтрокаВида.ТипЗначения = "Набор записей регистра" Или Найти(СтрокаВида.ТипЗначения, "<") > 0 Или ЛиТипСКвалификаторами Тогда Если ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") Тогда ОписаниеТиповЗначения = ЗначениеСвойства; КонецЕсли; Если Истина И ЯзыкПрограммы = 1 И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе" //И КорневойТипРодителя <> Неопределено //И КорневойТипРодителя <> "ВнешнийИсточникДанных" И ПостроительЗапросаРодителя <> Неопределено Тогда ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(КонечноеСлово)); Если ДоступноеПолеСлова = Неопределено Тогда Продолжить; КонецЕсли; Если ДоступноеПолеСлова.ТипЗначения <> Новый ОписаниеТипов("ТаблицаЗначений") Тогда ОписаниеТиповЗначения = ДоступноеПолеСлова.ТипЗначения; КонецЕсли; КонецЕсли; Если Истина И ОписаниеТиповЗначения = Неопределено И СтрокаОписанияВида.ИмяКоллекции <> "КритерииОтбора" И СтрокаОписанияВида.ИмяКоллекции <> "ПланыВидовХарактеристик" И ИмяОбщегоТипаРодителя <> "Константа" Тогда Попытка ОписаниеТиповЗначения = ЗначениеСвойства.Тип; Исключение Попытка ОписаниеТиповЗначения = ЗначениеСвойства.ТипЗначения; Исключение КонецПопытки; КонецПопытки; Если ТипЗнч(ОписаниеТиповЗначения) <> Тип("ОписаниеТипов") Тогда ОписаниеТиповЗначения = Неопределено; КонецЕсли; КонецЕсли; Если ТипЗнч(ОписаниеТиповЗначения) = Тип("ОписаниеТипов") Тогда МассивТипов = ОписаниеТиповЗначения.Типы(); Квалификаторы = ОписаниеТиповЗначения; ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") Тогда МассивТипов = ЗначениеСвойства; КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И МассивТипов.Количество() = 0 И (Ложь Или СхемаКоллекции.Количество() = 0 //Или ОписаниеТиповЗначения = Неопределено И СтрокаВида.ТипЗначения = "Произвольный" ) Тогда МассивТипов.Добавить(ТипЗнч(ЗначениеСвойства)); КонецЕсли; Если Истина //И ОписаниеТиповЗначения <> Неопределено И МассивТипов.Количество() > 0 И СтрокаОписанияВида.ИмяКоллекции <> "<Имя коллекции метаданных>" И (Ложь Или СтрокаОписанияВида.ИмяКоллекции <> "Константы" Или ЯзыкПрограммы = 1) Тогда ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Метаданные, ДержательМетаданных, Квалификаторы"); ШаблонСтруктурыТипа.СтрокаОписания = СтрокаВида; ШаблонСтруктурыТипа.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка; Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда ШаблонСтруктурыТипа.ДержательМетаданных = МетаданныеРодителя; Иначе ШаблонСтруктурыТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; КонецЕсли; ШаблонСтруктурыТипа.Квалификаторы = Квалификаторы; //ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя; ПередаватьЗначениеСвойства = ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных"); ПередаватьМетаданныеРодителя = НЕ (ИмяОбщегоТипаРодителя = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура")); Если МассивТипов.Количество() > МаксЧислоТиповДляАнализа Тогда СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(МассивТипов[0], ЯзыкПрограммы, ШаблонСтруктурыТипа); СтруктураОбщегоТипа = НоваяСтруктураТипа(СтруктураТипаСвойства.ИмяОбщегоТипа); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураОбщегоТипа); Иначе МассивНакопления = Новый Массив; Для Каждого Тип Из МассивТипов Цикл Если Истина И Тип = ТипЗнч(ЗначениеСвойства) //И (Ложь // Или мМассивТиповСМетаданными.Найти(Тип) <> Неопределено // Или мМассивТиповЭлементовОбычнойФормы.Найти(Тип) <> Неопределено) Тогда МетаданныеЭлемента = МетаданныеЭлементов[ИмяСвойства]; Если МетаданныеЭлемента = Неопределено Тогда МетаданныеЭлемента = ЗначениеСвойства; КонецЕсли; ШаблонСтруктурыТипа.Метаданные = МетаданныеЭлемента; СтруктураТипаСвойства = СтруктураТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа); Иначе Если ПередаватьЗначениеСвойства Тогда ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства; ИначеЕсли ПередаватьМетаданныеРодителя Тогда ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя; КонецЕсли; СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа); КонецЕсли; МассивНакопления.Добавить(СтруктураТипаСвойства); КонецЦикла; ДобавитьВТаблицуТипов(ТаблицаТипов, МассивНакопления); КонецЕсли; Иначе СтруктураТипаСвойства = НоваяСтруктураТипа(); ЗаполнитьЗначенияСвойств(СтруктураТипаСвойства, РодительскаяСтруктураТипа, "ТипЯзыка"); Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда СтруктураТипаСвойства.ДержательМетаданных = МетаданныеРодителя; Иначе СтруктураТипаСвойства.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; КонецЕсли; Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.Слово; Если СтрокаВида.ТипКонтекста <> "" Тогда СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипКонтекста + "." + СтруктураТипаСвойства.ИмяОбщегоТипа; КонецЕсли; Иначе СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаВида.ТипЗначения; СтруктураТипаСвойства.СтрокаОписания = СтрокаВида; КонецЕсли; СтруктураТипаСвойства.Метаданные = ЗначениеСвойства; //Если ПустаяСтрока(СтруктураТипаСвойства.ИмяОбщегоТипа) Тогда //КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаСвойства); КонецЕсли; КонецЕсли; Иначе // КонецЕсли; ДобавитьВТаблицуСлов(ТаблицаСлов, КонечноеСлово, СтрокаВида.ТипСлова, ТаблицаТипов, "??" + ТипЗначенияСлова, "Метаданные"); КонецЦикла; Если ЭтоГруппаОбщихМодулей Тогда Прервать; КонецЕсли; КонецЦикла; Если ЭтоГруппаОбщихМодулей Тогда Прервать; КонецЕсли; // Модуль Если Истина И (Ложь Или РодительскаяСтруктураТипа.ТипЯзыка = "" Или СтрокаОбщегоТипа.ИмяОбщегоТипа <> "Глобальный") И (Ложь Или ЯзыкПрограммы = 0 Или ЯзыкПрограммы = 2) Тогда Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Глобальный" Тогда ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(СтрокаОбщегоТипа, Слово, ТипСлова, ВычислятьТипы, ВычислятьТипыМетодовМодулей, Не ЭтоЛокальныйКонтекст, КлиентОбычноеПриложение, КлиентУправляемоеПриложение, НаСервере, ТаблицаСлов); Иначе МодульМетаданныхКомпонента = МодульМетаданныхДинамический; Если МодульМетаданныхКомпонента = Неопределено И ИмяОбщегоТипаРодителя <> "НеизвестныйКонтекст" Тогда СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя); СтруктураТипаМодуля.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; // Имя расширения конфигурации СтруктураТипаМодуля.Метаданные = МетаданныеРодителя; МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля); КонецЕсли; Если МодульМетаданныхКомпонента <> Неопределено Тогда РасширениеМодуля = ""; Если Истина И МодульМетаданныхКомпонента.СтруктураТипа <> Неопределено И ТипЗнч(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных) = Тип("Строка") И ЗначениеЗаполнено(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных) Тогда РасширениеМодуля = МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных; КонецЕсли; Если Ложь Или Не ЗначениеЗаполнено(РасширениеМодуля) // методы конфигурации всегда видны расширению Или БазовоеРасширениеКонфигурации = "*" // методы конфигурации всегда видны внешнему модулю Или РасширениеМодуля = БазовоеРасширениеКонфигурации Или РасширениеМодуля = ПолноеИмяПодсистемыИР // расширение ИР видно всем Тогда ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, Не ЭтоЛокальныйКонтекст, ФлагиКомпиляции, ВнутриГруппыОбщихМодулей); КонецЕсли; ВидимыеРасширения = Новый Массив; Если Истина И ТипЗнч(РасширениеМодуля) = Тип("Строка") И ЗначениеЗаполнено(РасширениеМодуля) И (Ложь Или ТипЗнч(МетаданныеРодителя) <> Тип("ОбъектМетаданных") Или МетаданныеРодителя.РасширениеКонфигурации() = Неопределено) Тогда // Для расширения модуля добавляем базовый модуль ВидимыеРасширения.Добавить(Неопределено); ИначеЕсли БазовоеРасширениеКонфигурации = "*" Тогда // При вызове из внешнего модуля, добавляем расширение модуля этого расширения Для Каждого РасширениеКонфигурации Из ирКэш.РасширенияКонфигурацииЛкс() Цикл ВидимыеРасширения.Добавить(РасширениеКонфигурации.Ключ.Имя); КонецЦикла; ИначеЕсли ЗначениеЗаполнено(БазовоеРасширениеКонфигурации) Тогда // При вызове из модулях расширения, добавляем расширение модуля этого расширения ВидимыеРасширения.Добавить(БазовоеРасширениеКонфигурации); КонецЕсли; Для Каждого ВидимоеРасширение Из ВидимыеРасширения Цикл СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя); СтруктураТипаМодуля.ДержательМетаданных = ВидимоеРасширение; СтруктураТипаМодуля.Метаданные = МетаданныеРодителя; МодульМетаданныхРасширение = ПодготовитьМодульМетаданных(СтруктураТипаМодуля); Если МодульМетаданныхРасширение <> Неопределено Тогда ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхРасширение, ВычислятьТипыМетодовМодулей, ВычислятьТипы, Не ЭтоЛокальныйКонтекст, ФлагиКомпиляции, ВнутриГруппыОбщихМодулей); КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; #Если Клиент Тогда Если Истина И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("COMОбъект") Или ТипЗнч(МетаданныеРодителя) = Тип("ВнешнийОбъект")) И ЛиИмяТипаComОбъекта(ИмяОбщегоТипаРодителя) Тогда ИмяБиблиотеки = ""; ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеРодителя, ИмяОбщегоТипаРодителя, ИмяБиблиотеки); Если ИнфоТипа <> Неопределено Тогда МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипаРодителя); Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл Для Каждого Член Из ИнфоТипа.Members Цикл Если Член.AttributeMask = 1 Тогда // Это члены IDispatch Продолжить; КонецЕсли; ИмяЧлена = Член.Name; Если Член.InvokeKind = 1 Или Член.Parameters.Count > 0 Тогда лТипСлова = "Метод"; Иначе лТипСлова = "Свойство"; КонецЕсли; Если Слово <> Неопределено Тогда Если Не ирОбщий.СтрокиРавныЛкс(Слово, ИмяЧлена) Тогда Продолжить; КонецЕсли; Если Не ирОбщий.СтрокиРавныЛкс(ТипСлова, лТипСлова) Тогда Продолжить; КонецЕсли; КонецЕсли; СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(Член.ReturnType, ИмяБиблиотеки, ИнфоТипа.Parent); СтруктураТипа.СтрокаОписания = Член; СтруктураТипа.Метаданные = МетаданныеРодителя; ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); ДобавитьВТаблицуСлов(ТаблицаСлов, ИмяЧлена, лТипСлова, ТаблицаТипов,, "Метаданные"); КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; #КонецЕсли КонецЕсли; КонецЦикла; Если Истина И Слово <> Неопределено И ИмяОбщегоТипаРодителя <> "Глобальный" // Для того, чтобы постоянно не присваивался тип <ОбщийМодуль> И ТаблицаСлов.Количество() = 0 И НайденныеСтроки.Количество() = 1 И ТаблицаОбщихТиповСтруктурыТипа.Количество() = 1 Тогда // Шаблон только один. Берем его даже если имя элемента коллекции не подошло. СтрокаВида = НайденныеСтроки[0]; Если Истина // Иначе при вычислении результата метода модуля менеджера все локальные переменные будут срабатывать И Найти(СтрокаВида.Слово, "<Имя предопределенного") = 0 И Найти(СтрокаВида.Слово, "<Имя значения перечисления") = 0 Тогда СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = СтрокаВида.ТипЗначения; СтруктураТипа.СтрокаОписания = СтрокаВида; СтруктураТипа.Метаданные = МетаданныеРодителя; ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); ДобавитьВТаблицуСлов(ТаблицаСлов, СтрокаВида.Слово, СтрокаВида.ТипСлова, ТаблицаТипов,, "Метаданные"); КонецЕсли; КонецЕсли; Возврат ТаблицаСлов; КонецФункции // Функция - Добавить в таблицу слов элементы глобальных модулей // // Параметры: // СтрокаОбщегоТипа - см. ТаблицаОбщихТиповИзСтруктурыТипа()[0] - // Функция ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(Знач СтрокаОбщегоТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВычислятьТипы = Истина, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ТолькоЭкспорт = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач НаСервере = Ложь, Знач ТаблицаСлов = Неопределено) Экспорт Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСвойствТипа(); КонецЕсли; Если ПустаяСтрока(ТипСлова) Или ТипСлова = "Метод" Тогда // Глобальные общие модули СтруктураТипаМодуля = НоваяСтруктураТипа(); СтруктураТипаМодуля.ИмяОбщегоТипа = "ОбщийМодуль"; Для Каждого ОбщийМодульМД Из Метаданные.ОбщиеМодули Цикл #Если Сервер И Не Сервер Тогда ОбщийМодульМД = Метаданные.ОбщиеМодули.ирОбщий; #КонецЕсли Если Ложь Или Не ОбщийМодульМД.Глобальный Или (Истина И НаСервере И Не ОбщийМодульМД.Сервер) Или (Истина И КлиентОбычноеПриложение И Не ОбщийМодульМД.КлиентОбычноеПриложение) Или (Истина И КлиентУправляемоеПриложение И Не ОбщийМодульМД.КлиентУправляемоеПриложение) Или (Истина И Не НаСервере И Не ОбщийМодульМД.ВызовСервера И Не (Ложь Или (Истина И КлиентОбычноеПриложение И ОбщийМодульМД.КлиентОбычноеПриложение) Или (Истина И КлиентУправляемоеПриложение И ОбщийМодульМД.КлиентУправляемоеПриложение) ) ) Тогда Продолжить; КонецЕсли; СтруктураТипаМодуля.Метаданные = ОбщийМодульМД; МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля); ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, "Метод", ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт); КонецЦикла; КонецЕсли; СтруктураТипаМодуля = НоваяСтруктураТипа(СтрокаОбщегоТипа.ИмяОбщегоТипа); СтруктураТипаМодуля.Метаданные = СтрокаОбщегоТипа.Метаданные; Если КлиентОбычноеПриложение Тогда МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульОбычногоПриложения"); ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт); КонецЕсли; Если КлиентУправляемоеПриложение Тогда МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульУправляемогоПриложения"); ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт); КонецЕсли; Возврат ТаблицаСлов; КонецФункции //. // Параметры: // ИмяОбщегоТипаРодителя - Неопределено - // Возвращаемое значение: // Массив[Неопределено] - Функция ИнтерфейсыCOMОбъекта(Знач ИнфоТипа, Знач ИмяОбщегоТипаРодителя) Экспорт Если Найти(ИмяОбщегоТипаРодителя, " {") > 0 Тогда ИнфоТипа = ИнфоТипа.Parent.TypeInfos.NamedItem(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипаРодителя, " {")); КонецЕсли; //Если ИмяCOMКласса = "" Тогда // Если Описатель.Parent.Name = "V" + ирКэш.НомерИзданияПлатформыЛкс() Тогда // ИмяОбщегоТипа = "COM-соединитель"; // КонецЕсли; //КонецЕсли; Если НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда МассивИнфоТипа = ИнфоТипа.Interfaces; Иначе МассивИнфоТипа = Новый Массив; МассивИнфоТипа.Добавить(ИнфоТипа); Для Каждого ИнтерфейсОбъекта Из ИнфоТипа.ImpliedInterfaces Цикл МассивИнфоТипа.Добавить(ИнтерфейсОбъекта); КонецЦикла; КонецЕсли; Возврат МассивИнфоТипа; КонецФункции // Помогает обновлять кэш управляемой формы из конфигуратора при следующем вызове автодополнения // Параметры: // ФормаИлиСтруктура - Форма, Структура - // Ключ - Строка - Процедура ДобавитьОтсутствиеЭлементаФормы(Знач ФормаИлиСтруктура, Знач Ключ) Экспорт СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиСтруктура); ОтсутствуютЭлементы = Неопределено; Если Не СлужебныеДанные.Свойство("ОтсутствуютЭлементы", ОтсутствуютЭлементы) Тогда ОтсутствуютЭлементы = Новый Соответствие; СлужебныеДанные.Вставить("ОтсутствуютЭлементы", ОтсутствуютЭлементы); КонецЕсли; Если ОтсутствуютЭлементы[Ключ] = Неопределено Тогда ОтсутствуютЭлементы[Ключ] = 1; СлужебныеДанные.Вставить("ДатаОбновления", Дата(1,1,1)); КонецЕсли; КонецПроцедуры Функция ТаблицаТиповЭлементовКоллекции(Знач РодительскаяСтруктураТипа, Знач ТекстИндексаЭлемента = "", Знач ЯзыкПрограммы = 0, Знач ТаблицаТипов = Неопределено) Экспорт НужнаПроверкаТипов = Истина; МетаданныеКоллекции = РодительскаяСтруктураТипа.Метаданные; // Массив Если Истина И ТипЗнч(МетаданныеКоллекции) = Тип("Массив") И МетаданныеКоллекции.Количество() > 0 И (Ложь Или ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[") = "Массив" Или ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[") = "ФиксированныйМассив") Тогда ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаИзЗначения(МетаданныеКоллекции[0])); ИначеЕсли Истина И (Ложь Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "СписокЗначений" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соответствие") И ТипЗнч(МетаданныеКоллекции) = Тип(РодительскаяСтруктураТипа.ИмяОбщегоТипа) И МетаданныеКоллекции.Количество() > 0 Тогда СтруктураТипаЭлемента = Новый Структура("Значение"); ЗаполнитьЗначенияСвойств(СтруктураТипаЭлемента, МетаданныеКоллекции[0]); ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаИзЗначения(СтруктураТипаЭлемента)); Иначе ТипыЭлементовКоллекции = ТипыЭлементовКоллекции(РодительскаяСтруктураТипа, ЯзыкПрограммы, НужнаПроверкаТипов); Если ТипыЭлементовКоллекции.Количество() > 0 Тогда Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; ТипТип = Тип("Тип"); Для Каждого БазовыйТипЭлемента Из ТипыЭлементовКоллекции Цикл Если ТипЗнч(БазовыйТипЭлемента) = ТипТип Тогда КонкретныйТип = БазовыйТипЭлемента; Иначе Попытка КонкретныйТип = Тип(БазовыйТипЭлемента); Исключение КонкретныйТип = Неопределено; КонецПопытки; КонецЕсли; Если КонкретныйТип <> Неопределено Тогда СтруктураТипаЭлемента = СтруктураТипаИзКонкретногоТипа(КонкретныйТип); Иначе СтруктураТипаЭлемента = НоваяСтруктураТипа(); СтруктураТипаЭлемента.ИмяОбщегоТипа = БазовыйТипЭлемента; СтруктураТипаЭлемента.Метаданные = мМетаданные; КонецЕсли; Если ТипЗнч(СтруктураТипаЭлемента.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") Тогда СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции; КонецЕсли; СтруктураТипаЭлемента.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; Если КонкретныйТип = Неопределено И НужнаПроверкаТипов Тогда СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТипЭлемента, ЯзыкПрограммы); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча); Если НайденныеСтроки.Количество() > 0 Тогда СтруктураТипаЭлемента.СтрокаОписания = НайденныеСтроки[0]; СтруктураТипаЭлемента.ИмяОбщегоТипа = НайденныеСтроки[0].Слово; Если ТипЗнч(МетаданныеКоллекции) <> Тип("КоллекцияОбъектовМетаданных") Тогда СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции; КонецЕсли; КонецЕсли; КонецЕсли; Если ТипЗнч(МетаданныеКоллекции) = Тип("ПостроительЗапроса") Тогда ПостроительЗапроса = МетаданныеКоллекции; Попытка ИндексВПакете = Число(ТекстИндексаЭлемента); Исключение ИндексВПакете = Неопределено; КонецПопытки; Если ИндексВПакете <> Неопределено Тогда ТекстыЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(МетаданныеКоллекции.Текст); #Если Сервер И Не Сервер Тогда ТекстыЗапросов = Новый Массив; #КонецЕсли ПостроительЗапроса = ПостроительПакетаЗапросовДоИндекса(ТекстыЗапросов, ИндексВПакете); Если ПостроительЗапроса <> Неопределено Тогда СтруктураТипаЭлемента.Метаданные = ПостроительЗапроса; МенеджерВременныхТаблиц = РодительскаяСтруктураТипа.ДержательМетаданных; // см. Обработки.ирКлсПолеТекстаПрограммы.Создать().НовыйМенеджерВременныхТаблиц() ПоследнийПакетЗапросов = МенеджерВременныхТаблиц.ПакетыЗапросов[МенеджерВременныхТаблиц.ПакетыЗапросов.ВГраница()]; // см. Обработки.ирКлсПолеТекстаПрограммы.Создать().НовыйПакетЗапросов() ПоследнийПакетЗапросов = ирОбщий.СкопироватьКоллекциюЛкс(ПоследнийПакетЗапросов); ПоследнийПакетЗапросов.Вставить("ИндексВПакете", ИндексВПакете); СтруктураТипаЭлемента.ДержательМетаданных = ПоследнийПакетЗапросов; КонецЕсли; КонецЕсли; КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); КонецЦикла; Иначе ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа()); КонецЕсли; КонецЕсли; Возврат ТаблицаТипов; КонецФункции Функция ПараметрыИзТекстаЗапроса(Знач ТекстЗапроса, Знач ВВидеСтруктуры = Ложь, Знач СтруктураПриемник = Неопределено) Экспорт Запрос = Новый Запрос(ТекстЗапроса); Попытка ПараметрыЗапроса = Запрос.НайтиПараметры(); Исключение ПараметрыЗапроса = Новый Массив; КонецПопытки; Если ВВидеСтруктуры Тогда Результат = СтруктураПриемник; Если СтруктураПриемник = Неопределено Тогда Результат = Новый Структура; КонецЕсли; Если ПараметрыЗапроса <> Неопределено Тогда Для Каждого ОписаниеПараметра Из ПараметрыЗапроса Цикл Результат.Вставить(ОписаниеПараметра.Имя); КонецЦикла; КонецЕсли; Иначе Результат = ПараметрыЗапроса; КонецЕсли; Возврат Результат; КонецФункции //. // Параметры: // ТекстЗапроса - Строка - // Возвращаемое значение: // ПостроительЗапроса - Функция ПостроительЗапросаИзТекстаДляТипа(Знач ТекстЗапроса, Знач ПостроительЗапроса = Неопределено) Экспорт Если ПостроительЗапроса = Неопределено Тогда ПостроительЗапроса = Новый ПостроительЗапроса; КонецЕсли; Попытка ПостроительЗапроса.Текст = ТекстЗапроса; Исключение // Даже если текст некорректный, он сохраняется в свойстве КонецПопытки; ПараметрыИзТекстаЗапроса(ТекстЗапроса, Истина, ПостроительЗапроса.Параметры); Возврат ПостроительЗапроса; КонецФункции // Функция - Построитель пакета запросов до индекса включительно // // Параметры: // ТекстыЗапросов - - // ИндексЭлемента - - // // Возвращаемое значение: // - // Функция ПостроительПакетаЗапросовДоИндекса(Знач ТекстыЗапросов, Знач ИндексЭлемента) Экспорт ТекстЗапроса = ""; Если ТекстыЗапросов.Количество() > ИндексЭлемента Тогда ТекстЗапроса = ирОбщий.СтрСоединитьЛкс(ТекстыЗапросов, Символы.ПС, ИндексЭлемента + 1); Если Лев(ТекстЗапроса, 1) = """" Тогда ТекстЗапроса = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ТекстЗапроса); КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(ТекстЗапроса) Тогда ПостроительЗапроса = Новый ПостроительЗапроса; Попытка ПостроительЗапроса.Текст = ТекстЗапроса; //ПостроительЗапроса.ЗаполнитьНастройки(); Исключение КонецПопытки; ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса); КонецЕсли; Возврат ПостроительЗапроса; КонецФункции // Процедура - Подготовить выбранные поля построителя // // Параметры: // ПостроительЗапроса - ПостроительЗапроса - // ДержательМетаданных - см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() - // Процедура ПодготовитьМетаданныеПостроителяЗапроса(Знач ПостроительЗапроса, Знач ДержательМетаданных = Неопределено) Экспорт Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 Тогда Попытка ПостроительЗапроса.ЗаполнитьНастройки(); Исключение КонецПопытки; КонецЕсли; Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 И ирКэш.ДоступноСхемаЗапросаЛкс() Тогда Текст = ПостроительЗапроса.Текст; Если Истина И ДержательМетаданных <> Неопределено И ДержательМетаданных.Тип = Тип("МенеджерВременныхТаблиц") //И ДержательМетаданных.Активен Тогда ТекстыПакетов = Новый Массив; Для Индекс = 0 По ДержательМетаданных.ПакетыЗапросов.ВГраница() - 1 Цикл ТекстыПакетов.Добавить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ДержательМетаданных.ПакетыЗапросов[Индекс].Текст)); КонецЦикла; ТекстыПакетов.Добавить(Текст); Текст = ирОбщий.СтрСоединитьЛкс(ТекстыПакетов, ";" + Символы.ПС); КонецЕсли; Попытка ПустаяТаблица = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(Текст,, Истина); Исключение Возврат; КонецПопытки; ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ПустаяТаблица); ПостроительЗапроса.ЗаполнитьНастройки(); КонецЕсли; КонецПроцедуры Функция ЛиИмяТипаComОбъекта(ИмяОбщегоТипа) Экспорт Результат = Ложь Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Или Найти(ИмяОбщегоТипа, " {") > 0; Возврат Результат; КонецФункции Функция ДобавитьВТаблицуСловЭлементыМодуляМетаданных(Знач СтруктураТипаМини, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВнутренняяТаблицаСлов = Неопределено, Знач МодульМетаданных, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ВычислятьТипы = Истина, Знач ТолькоЭкспорт = Истина, Знач ФлагиКомпиляции = Неопределено, Знач ВнутриГруппыОбщихМодулей = Ложь) Экспорт Если ВнутренняяТаблицаСлов = Неопределено Тогда ВнутренняяТаблицаСлов = НоваяТаблицаСвойствТипа(); КонецЕсли; МетаданныеРодителя = СтруктураТипаМини.Метаданные; // см. Метаданные.ОбщиеМодули[0] ОтборСловМодуля = Новый Структура; Если ТолькоЭкспорт Тогда ОтборСловМодуля.Вставить("ЛиЭкспорт", Истина); КонецЕсли; Если ЗначениеЗаполнено(Слово) Тогда ОтборСловМодуля.Вставить("НИмя", НРег(Слово)); КонецЕсли; Если Истина И (Ложь Или ФлагиКомпиляции = Неопределено Или Не ФлагиКомпиляции.БезКонтекста) И (Ложь Или ТипСлова = Неопределено Или ТипСлова = "Свойство") Тогда ПеременныеМодуля = МодульМетаданных.Переменные; #Если Сервер И Не Сервер Тогда ПеременныеМодуля = Новый ТаблицаЗначений; #КонецЕсли Если ОтборСловМодуля.Количество() > 0 Тогда ПодходящиеПеременные = ПеременныеМодуля.НайтиСтроки(ОтборСловМодуля); Иначе ПодходящиеПеременные = ПеременныеМодуля; КонецЕсли; КомпонентаПодсказки = Неопределено; ТаблицаТипов = Неопределено; Для Каждого ПеременнаяМодуля Из ПодходящиеПеременные Цикл Если ВычислятьТипы Тогда Если ВычислятьТипыМетодовМодулей Тогда ПодготовитьТипЗначенияПеременнойМодуля(ПеременнаяМодуля, МодульМетаданных, КомпонентаПодсказки); КонецЕсли; ТаблицаТипов = ТаблицаТиповСловаМодуля(ПеременнаяМодуля, МодульМетаданных); КонецЕсли; ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, ПеременнаяМодуля.Имя, "Свойство", ТаблицаТипов,, "Метаданные"); КонецЦикла; КонецЕсли; Если Истина И Не ТолькоЭкспорт И ФлагиКомпиляции <> Неопределено И ирОбщий.СтрКончаетсяНаЛкс(МодульМетаданных.Имя, ".Форма.Модуль") Тогда //Если ФлагиКомпиляции.Сервер Тогда // ОтборСловМодуля.Вставить("Сервер", Истина); //КонецЕсли; //Если ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение Тогда // ОтборСловМодуля.Вставить("Клиент", Истина); //КонецЕсли; Если Не (ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение) Тогда ОтборСловМодуля.Вставить("Клиент", Ложь); КонецЕсли; Если ФлагиКомпиляции.БезКонтекста Тогда ОтборСловМодуля.Вставить("БезКонтекста", Истина); КонецЕсли; КонецЕсли; Если Ложь Или ТипСлова = Неопределено Или ТипСлова = "Метод" Тогда МетодыМодуля = МодульМетаданных.Методы; #Если Сервер И Не Сервер Тогда МетодыМодуля = Новый ТаблицаЗначений; #КонецЕсли Если ОтборСловМодуля.Количество() > 0 Тогда ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля); Если Истина И ПодходящиеМетоды.Количество() = 0 И ЗначениеЗаполнено(Слово) И СтруктураТипаМини.ИмяОбщегоТипа <> "Глобальный" Тогда ОтборСловМодуля.Вставить("НИмя", "<>"); ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля); КонецЕсли; Иначе ПодходящиеМетоды = МетодыМодуля; КонецЕсли; ВычислятьТипы = Ложь Или ЗначениеЗаполнено(Слово) Или ВычислятьТипы; Если ЗначениеЗаполнено(Слово) Тогда ВычислятьТипыМетодовМодулей = Истина; КонецЕсли; Если ВычислятьТипыМетодовМодулей И ПодходящиеМетоды.Количество() > 100 Тогда Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПодходящиеМетоды.Количество(), "Вычисление типов функций"); Иначе Индикатор = Неопределено; КонецЕсли; ТаблицаТипов = Неопределено; РазделительВариантаКонтекста = РазделительВариантаКонтекста(); Для Каждого МетодМодуля Из ПодходящиеМетоды Цикл Если Индикатор <> Неопределено Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонецЕсли; ИмяМетода = МетодМодуля.Имя; Если ИмяМетода = "<>" И Не ЗначениеЗаполнено(Слово) Тогда Продолжить; КонецЕсли; Если ВычислятьТипы Тогда Если ВычислятьТипыМетодовМодулей Тогда ПодготовитьТипРезультатаМетода(МетодМодуля, МодульМетаданных); КонецЕсли; ТаблицаТипов = ТаблицаТиповСловаМодуля(МетодМодуля, МодульМетаданных); КонецЕсли; Если ВнутриГруппыОбщихМодулей Тогда ИмяМетода = ИмяМетода + " - " + МетаданныеРодителя.Имя; КонецЕсли; ДобавитьВТаблицуСлов(ВнутренняяТаблицаСлов, ИмяМетода, "Метод", ТаблицаТипов, МетодМодуля.ТипЗначения, "Метаданные"); КонецЦикла; Если Индикатор <> Неопределено Тогда ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; КонецЕсли; Возврат ВнутренняяТаблицаСлов; КонецФункции Функция РазделительВариантаКонтекста() Экспорт Возврат " - "; КонецФункции //. // Параметры: // МетодМодуля - СтрокаТаблицыЗначений - // Возвращаемое значение: // ТаблицаЗначений - Функция ТаблицаТиповСловаМодуля(СловоМодуля, МодульМетаданных) Экспорт Если СловоМодуля.ТаблицаТипов <> Неопределено Тогда ТаблицаТипов = СловоМодуля.ТаблицаТипов.Скопировать(); // Мультиметка4529884 против циклической ссылки #Если Сервер И Не Сервер Тогда ТаблицаТипов = Новый ТаблицаЗначений; #КонецЕсли Иначе ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; Если ТаблицаТипов.Количество() = 0 Тогда СтруктураТипа = ТаблицаТипов.Добавить(); Если ЗначениеЗаполнено(СловоМодуля.ТипЗначения) Тогда Если СловоМодуля.Имя = "<>" Тогда СтруктураТипа.ИмяОбщегоТипа = СловоМодуля.ТипЗначения; Иначе СтруктураТипа.ИмяОбщегоТипа = "??"; // в этом варианте некрасиво выглядит тип результата ирОбщий.НайтиДобавитьЭлементНастроекКомпоновкиПоПолюЛкс() //СтруктураТипа.ИмяОбщегоТипа = "?"; // так сломается вычисление типов методов в Обработка.ирКлсПолеТекстаПрограммы.Форма.МетодыМодулей КонецЕсли; КонецЕсли; ОбновитьДетальностьСтруктурыТипа(СтруктураТипа); КонецЕсли; ТаблицаТипов.ЗаполнитьЗначения(СловоМодуля, "СтрокаОписания"); // Мультиметка4529884 против циклической ссылки СловоМодуля.ИмяМодуля = МодульМетаданных.Имя; Возврат ТаблицаТипов; КонецФункции Функция ПодготовитьМодульМетаданных(Знач СтруктураТипа, Знач ТипМодуля = "", выхИмяМодуля = "", Знач НовыйТекст = Неопределено, Знач ТекущаяПозиция = Неопределено) Экспорт ВерсияФормата = ВерсияФорматаКэшаМодулей(); СтрокаСозданияРодителя = ""; ФлагиКомпиляции = Неопределено; // см. НовыеФлагиКомпиляции() выхИмяМодуля = ИмяМодуляИзСтруктурыТипа(СтруктураТипа, ТипМодуля, СтрокаСозданияРодителя, ФлагиКомпиляции); Если ЗначениеЗаполнено(выхИмяМодуля) Тогда Если мМодулиМетаданных = Неопределено Тогда мМодулиМетаданных = Новый Соответствие; КонецЕсли; МодульМетаданных = МодульМетаданныхИзКэша(выхИмяМодуля); // см. МодульМетаданных() Если Ложь Или МодульМетаданных = Неопределено Или НовыйТекст <> Неопределено И МодульМетаданных.Текст <> НовыйТекст Тогда //ПроверитьСтруктуруФайловогоКэша(); #Если Сервер И Не Сервер Тогда ПапкаКэшаМодулей = Новый Файл; #КонецЕсли ФайлМодуля = ФайлМодуляИзИмениМодуля(выхИмяМодуля); ТекстовыйДокумент = Новый ТекстовыйДокумент; СтарыйТекст = Неопределено; Если НовыйТекст <> Неопределено Тогда Если МодульМетаданных <> Неопределено Тогда СтарыйТекст = МодульМетаданных.Текст; КонецЕсли; Если СтарыйТекст = Неопределено И ФайлМодуля.Существует() Тогда ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя); СтарыйТекст = ТекстовыйДокумент.ПолучитьТекст(); КонецЕсли; Если СтарыйТекст <> НовыйТекст Тогда ТекстовыйДокумент.УстановитьТекст(НовыйТекст); Для Счетчик = 1 По 2 Цикл Попытка Если ирКэш.НомерРежимаСовместимостиЛкс() > 803018 Тогда ТекстовыйДокумент.ЗаписатьАсинх(ФайлМодуля.ПолноеИмя); Иначе ТекстовыйДокумент.Записать(ФайлМодуля.ПолноеИмя); КонецЕсли; Прервать; Исключение Если Счетчик = 2 Тогда ВызватьИсключение; КонецЕсли; СоздатьКаталог(ФайлМодуля.Путь); // Нужно для подкаталогов расширений 23мс КонецПопытки; КонецЦикла; КонецЕсли; КонецЕсли; ФайлОписанияМодуля = ФайлМодуляИзИмениМодуля(выхИмяМодуля, "ixd"); ОбновитьФайлОписания = Истина; Если ФайлОписанияМодуля.Существует() Тогда МодульМетаданных = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлОписанияМодуля.ПолноеИмя); // см. МодульМетаданных() ОбновитьФайлОписания = Ложь Или СтарыйТекст <> НовыйТекст Или (Истина И ФайлМодуля.Существует() И ФайлМодуля.ПолучитьВремяИзменения() > ФайлОписанияМодуля.ПолучитьВремяИзменения()); Если Ложь Или ТипЗнч(МодульМетаданных) <> Тип("Структура") Или ирОбщий.СвойствоСтруктурыЛкс(МодульМетаданных, "ВерсияФормата") <> ВерсияФормата Или МодульМетаданных.Имя <> выхИмяМодуля // Антибаг ИР. В старых версиях где то писалось пустое имя в кэш Тогда // Старый формат кэша ОбновитьФайлОписания = Истина; МодульМетаданных = Неопределено; Иначе МодульМетаданных.Текст = СтарыйТекст; // Может установиться Неопределено КонецЕсли; КонецЕсли; СтарыйМодуль = Неопределено; Если ОбновитьФайлОписания Тогда Если Не ФайлМодуля.Существует() Тогда Если СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось <> Истина Тогда // Может выводиться неоправданно, если модуль пуст. В этом случае конфигуратор не выгружает файл. Поэтому уведомляем только о полной пустоте кэша ФайлыМодулей = НайтиФайлы(ПапкаКэшаМодулей.ПолноеИмя, ИмяКонтрольногоФайлаКэшаМодулей()); Если ФайлыМодулей.Количество() = 0 Тогда #Если Клиент Тогда ирКлиент.ОткрытьНастройкиПоляТекстаПрограммыНаЗаднемПланеЛкс(); #КонецЕсли КонецЕсли; СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось = Истина; КонецЕсли; МодульМетаданных = МодульМетаданных("", СтруктураТипа, выхИмяМодуля); Иначе Если НовыйТекст = Неопределено Тогда ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя); НовыйТекст = ТекстовыйДокумент.ПолучитьТекст(); МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяМодуля); ЗаписатьМодульВКэш(МодульМетаданных); Иначе СтарыйМодуль = МодульМетаданных; МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяМодуля, Ложь, МодульМетаданных, ТекущаяПозиция); // Т.к. в этом сценарии часто будет обновление текста модуля происходить, то не будем тратить время на обновление индекса в файле, но удалим его чтобы потом дату изменения не сверять УдалитьФайлы(ПапкаКэшаМодулей.ПолноеИмя, выхИмяМодуля + ".i*"); // Все расширения файлов индексов начинаются с "i" Если мВызовыВсехСловПоМодулям <> Неопределено Тогда мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяМодуля, Истина)] = Неопределено; мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяМодуля, Ложь)] = Неопределено; КонецЕсли; КонецЕсли; //ирОбщий.СообщитьЛкс(ФайлМодуля.ПолноеИмя); // Отладка //УдалитьФайлы(ФайлМодуля.ПолноеИмя); КонецЕсли; КонецЕсли; мМодулиМетаданных[НРег(выхИмяМодуля)] = МодульМетаданных; МодульМетаданных.СтруктураТипа = СтруктураТипа; МодульМетаданных.ФлагиКомпиляции = ФлагиКомпиляции; МодульМетаданных.Вставить("СтрокаСоздания", СтрокаСозданияРодителя); МодульМетаданных.Вставить("ТипМодуля", ТипМодуля); МодульМетаданных.Вставить("ВерсияФормата", ВерсияФормата); Если МодульМетаданных <> Неопределено И СтарыйМодуль <> МодульМетаданных Тогда #Если Сервер И Не Сервер Тогда МетодыМодуля = Новый ТаблицаЗначений; #КонецЕсли БазовыйТип = ирОбщий.ПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа); Если Истина И МодульМетаданных <> мПустойМодуль И (Ложь Или ирОбщий.СтрКончаетсяНаЛкс(БазовыйТип, "Объект") Или ирОбщий.ЛиИмяТипаФормыЛкс(БазовыйТип, Истина)) Тогда // Добавим в переменные модуля реквизиты объекта с изменяемыми метаданными, чтобы уточнять их тип по коду МодульВременный = МодульМетаданных("",, "кэш"); МодульВременный.Переменные.Очистить(); // Иногда там остаются какие то переменные //ТаблицаСлов = ТаблицаСловИзСтруктурыТипа(СтруктураТипа,,,, Ложь,, "Свойство",,, МодульВременный); ИнициацияОписанияМетодовИСвойств(); ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа,, "Свойство",,,,,,, МодульВременный); Для Каждого СтрокаСлова Из ТаблицаСлов Цикл // TODO добавить фильтр по типу Если ЛиДетальностьТиповДостаточна(СтрокаСлова.ТаблицаТипов) Тогда Продолжить; КонецЕсли; СтрокаПеременной = МодульМетаданных.Переменные.Добавить(); СтрокаПеременной.Имя = СтрокаСлова.Слово; СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя); СтрокаПеременной.ЛиЭкспорт = Истина; КонецЦикла; КонецЕсли; КонецЕсли; Иначе МодульМетаданных.Имя = выхИмяМодуля; // Нужно для единого пустого модуля, чтобы виртуальные методы в нем имели правильное имя модуля КонецЕсли; КонецЕсли; Возврат МодульМетаданных; КонецФункции //. // Возвращаемое значение: // Число - Функция ВерсияФорматаКэшаМодулей() Экспорт ВерсияФормата = 14; // Метка91237881041 Каждый раз при изменении структуры увеличиваем на 1 Возврат ВерсияФормата; КонецФункции Функция ПеречислениеТипСлова() Экспорт Структура = Новый Структура("Свойство, Метод, Конструктор"); Возврат ирОбщий.ЗаполнитьЗначенияКлючамиВСтруктуреЛкс(Структура); КонецФункции // Возращает таблицу вызовов слова через точку. // Параметры: // ИмяМодуля - Строка - // ТекстовыйДокумент - ТекстовыйДокумент - // Файл - Файл - // ПолеТекстаПрограммы - ОбработкаОбъект.ирКлсПолеТекстаПрограммы // Возвращаемое значение: // ТаблицаЗначений - Функция НепрямыеВызовыСловаВМодуле(Знач ИмяМодуля, Знач ТекстовыйДокумент, Знач Файл, Знач ПолеТекстаПрограммы, Знач ИскатьСлово, Знач ЛиМетод = Истина) Экспорт _РежимОтладки = Ложь; Если ЛиМетод Тогда ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками+"\.)("+шИмя+")\s*\((?:(?:"+ПолеТекстаПрограммы.шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*\)"; Расширение = "icl"; Иначе ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками+"\.)("+шИмя+")(?!\s*[\(])"+ПолеТекстаПрограммы.шПостИмяСвойства; Расширение = "ipr"; КонецЕсли; Если мВызовыВсехСловПоМодулям = Неопределено Тогда мВызовыВсехСловПоМодулям = Новый Соответствие; КонецЕсли; КлючКэша = КлючКэшаВызововСловаПоМодулю(ИмяМодуля, ЛиМетод); ИндексВызововМодуля = мВызовыВсехСловПоМодулям[КлючКэша]; Если ИндексВызововМодуля = Неопределено Тогда ВерсияФорматаИндекса = 6; ФайлИндекса = ФайлМодуляИзИмениМодуля(ИмяМодуля, Расширение); ОбновитьИндекс = Не ФайлИндекса.Существует(); Если Не ОбновитьИндекс Тогда ИндексВызововМодуля = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлИндекса.ПолноеИмя); // см. ирОбщий.НайтиРегВыражениеЛкс Если Ложь Или ТипЗнч(ИндексВызововМодуля) <> Тип("Структура") Или ИндексВызововМодуля.ВерсияФормата <> ВерсияФорматаИндекса Тогда // Старый формат кэша ОбновитьИндекс = Истина; ИндексВызововМодуля = Неопределено; КонецЕсли; КонецЕсли; Если ОбновитьИндекс Тогда ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст(); //ТаблицаВызовов = ирОбщий.НайтиРегВыражениеЛкс(ТекстМодуля, ШаблонВнешнегоВызова,,,,,, Истина); //ТаблицаВызовов.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка")); //Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. // Для Каждого СтрокаВызова Из ТаблицаВызовов Цикл // СтрокаВызова.Слово = СтрокаВызова.Подгруппы.SubMatches(0); // КонецЦикла; //Иначе // // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" // Для Каждого СтрокаВызова Из ТаблицаВызовов Цикл   СтрокаВызова.Слово = НРег(СтрокаВызова.Подгруппы.SubMatches(0));   КонецЦикла;   //КонецЕсли; //ТаблицаВызовов.Колонки.Удалить("Подгруппы"); //ТаблицаВызовов.Колонки.Удалить("ТекстВхождения"); // РегВыражение = ирКэш.ВычислительРегВыраженийЛкс(); РегВыражение.IgnoreCase = Истина; РегВыражение.Global = Истина; РегВыражение.Pattern = ШаблонВнешнегоВызова; Вхождения = РегВыражение.НайтиВхождения(ТекстМодуля); ТаблицаВызовов = Новый ТаблицаЗначений; ТаблицаВызовов.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число")); ТаблицаВызовов.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число")); ТаблицаВызовов.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка")); Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого Вхождение Из Вхождения Цикл СтрокаРезультата = ТаблицаВызовов.Добавить(); СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex; СтрокаРезультата.ДлинаВхождения = Вхождение.Length; СтрокаРезультата.Слово = Вхождение.SubMatches(0); КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для Каждого Вхождение Из Вхождения Цикл   СтрокаРезультата = ТаблицаВызовов.Добавить();   СтрокаРезультата.ПозицияВхождения = Вхождение.FirstIndex;   СтрокаРезультата.ДлинаВхождения = Вхождение.Length;   СтрокаРезультата.Слово = Вхождение.SubMatches(0);   КонецЦикла;   КонецЕсли; ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаВызовов, "Слово"); МассивСлов = ирОбщий.РазличныеЗначенияКолонкиТаблицыЛкс(ТаблицаВызовов, "Слово"); НомерСлова = 1; СтруктураСлов = Новый Структура; ТаблицаВызовов.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число")); Для Каждого Слово Из МассивСлов Цикл СтруктураСлов.Вставить(Слово, НомерСлова); ВызовыСлова = ТаблицаВызовов.НайтиСтроки(Новый Структура("Слово", Слово)); Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого СтрокаВызова Из ВызовыСлова Цикл СтрокаВызова.НомерСлова = НомерСлова; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для Каждого СтрокаВызова Из ВызовыСлова Цикл   СтрокаВызова.НомерСлова = НомерСлова;   КонецЦикла;   КонецЕсли; НомерСлова = НомерСлова + 1; КонецЦикла; ТаблицаВызовов.Колонки.Удалить("Слово"); ИндексВызововМодуля = Новый Структура; ИндексВызововМодуля.Вставить("ВерсияФормата", ВерсияФорматаИндекса); ИндексВызововМодуля.Вставить("Вызовы", ТаблицаВызовов); ИндексВызововМодуля.Вставить("СтруктураСлов", СтруктураСлов); ирОбщий.СохранитьЗначениеВФайлЛкс(ИндексВызововМодуля, ФайлИндекса.ПолноеИмя); КонецЕсли; ирОбщий.ДобавитьИндексВТаблицуЛкс(ИндексВызововМодуля.Вызовы, "НомерСлова"); мВызовыВсехСловПоМодулям[КлючКэша] = ИндексВызововМодуля; КонецЕсли; НомерСлова = 0; Результат = Новый Массив; Если ИндексВызововМодуля.СтруктураСлов.Свойство(ИскатьСлово, НомерСлова) Тогда Результат = ИндексВызововМодуля.Вызовы.НайтиСтроки(Новый Структура("НомерСлова", НомерСлова)); КонецЕсли; Возврат Результат; КонецФункции Функция КлючКэшаВызововСловаПоМодулю(Знач Модуль, Знач ЛиМетод) Экспорт Возврат НРег(Модуль) + "." + ЛиМетод; КонецФункции // Возвращаемое значение: // Строка - Функция ИмяКонтрольногоФайлаКэшаМодулей() Экспорт Возврат "КонтрольныйФайл.ixd"; КонецФункции Функция ИмяДинамическогоМодуля() Экспорт Возврат "Динамический.Модуль"; КонецФункции Функция ИмяМетодаИнициация() Экспорт Возврат "<Инициация>"; КонецФункции //. // Параметры: // МодульМетаданных - Структура - // ОбнулятьВычисляемое - Булево - немного дольше, но гарантирует успех Процедура ЗаписатьМодульВКэш(Знач МодульМетаданных, Знач ЧерезКопию = Ложь) Экспорт Если МодульМетаданных = мПустойМодуль Тогда Возврат; КонецЕсли; ФайлОписанияМодуля = ФайлМодуляИзИмениМодуля(МодульМетаданных.Имя, "ixd"); Если ЧерезКопию Тогда КопияМодуля = ирОбщий.СкопироватьКоллекциюЛкс(МодульМетаданных); КопияМодуля.Текст = Неопределено; КопияМодуля.СтруктураТипа = Неопределено; КопияМодуля.ТекущийМетод = Неопределено; Если Не ЛиСохранятьОшибкиМодуля(КопияМодуля) Тогда КопияМодуля.Ошибки = Неопределено; КонецЕсли; КопияМодуля.Переменные = КопияМодуля.Переменные.Скопировать(); КопияМодуля.Методы = КопияМодуля.Методы.Скопировать(); КопияМодуля.Методы.ЗаполнитьЗначения(Неопределено, "КэшПоиска, ТелоБезВозвратов"); СброситьКэшТиповВыраженийМодуля(КопияМодуля); МодульМетаданных = КопияМодуля; КонецЕсли; МодульМетаданных.Вставить("ВерсияФормата", ВерсияФорматаКэшаМодулей()); Текст = МодульМетаданных.Текст; СтруктураТипа = МодульМетаданных.СтруктураТипа; МодульМетаданных.Текст = Неопределено; МодульМетаданных.СтруктураТипа = Неопределено; ирОбщий.СохранитьЗначениеВФайлЛкс(МодульМетаданных, ФайлОписанияМодуля.ПолноеИмя); МодульМетаданных.Текст = Текст; МодульМетаданных.СтруктураТипа = СтруктураТипа; КонецПроцедуры //. // Параметры: // Модуль - Структура - // Возвращаемое значение: // Булево - Функция ЛиСохранятьОшибкиМодуля(Модуль) Экспорт Результат = Истина И Модуль.Ошибки <> Неопределено И Модуль.Ошибки.Количество() < 50; Возврат Результат; КонецФункции //. // Параметры: // ИмяМодуля - Строка - // Возвращаемое значение: // см. ПодготовитьМодульМетаданных() - Функция МодульМетаданныхИзКэша(Знач ИмяМодуля) Экспорт МодульМетаданных = мМодулиМетаданных[НРег(ИмяМодуля)]; Возврат МодульМетаданных; КонецФункции Процедура СброситьКэшиТиповВыраженийМодулей(Знач КромеМодуля = "") Экспорт Для Каждого КлючИЗначение Из мМодулиМетаданных Цикл Если КлючИЗначение.Ключ = НРег(КромеМодуля) Тогда Продолжить; КонецЕсли; СброситьКэшТиповВыраженийМодуля(КлючИЗначение.Значение); КонецЦикла; КонецПроцедуры //. // Параметры: // Модуль - см. МодульМетаданных() - Процедура СброситьКэшТиповВыраженийМодуля(Знач Модуль) Экспорт Переменные = Модуль.Переменные; Переменные.ЗаполнитьЗначения(Ложь, "Вычислено"); // Чтобы не отслеживать зависимости Переменные.ЗаполнитьЗначения(, "ТаблицаТипов"); // Чтобы не отслеживать зависимости Методы = Модуль.Методы; Методы.ЗаполнитьЗначения(Ложь, "Вычислено"); // Чтобы не отслеживать зависимости Методы.ЗаполнитьЗначения(, "ТаблицаТипов, ТипыВыражений"); // Чтобы не отслеживать зависимости. ТипыВыражений - самые тяжелые _РежимОтладки = Ложь; Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого СтрокаМетода Из Методы Цикл Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов"); КонецЕсли; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для Каждого СтрокаМетода Из Методы Цикл   Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда   СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов");   КонецЕсли;   КонецЦикла;   КонецЕсли; //Для Каждого СтрокаМетода Из Методы Цикл // Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда // СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов"); // КонецЕсли; // Если СтрокаМетода.ТаблицаТипов <> Неопределено Тогда // СтрокаМетода.ТаблицаТипов = Неопределено; // КонецЕсли; // Если СтрокаМетода.ТипыВыражений <> Неопределено Тогда // СтрокаМетода.ТипыВыражений = Неопределено; // КонецЕсли; //КонецЦикла; КонецПроцедуры //. // Параметры: // ИмяМодуля - Строка - например "ИнструментыРазработчикаTormozit ОбщийМодуль.ирОбщий.Модуль" // Возвращаемое значение: // Файл - Функция ФайлМодуляИзИмениМодуля(Знач ИмяМодуля, Знач Расширение = "txt", Знач ЗаменитьНедопустимыеСимволы = Ложь) Экспорт ИмяМодуля = СтрЗаменить(ИмяМодуля, " ", "\"); Если ЗаменитьНедопустимыеСимволы Тогда ИмяМодуля = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(ИмяМодуля, "_"); КонецЕсли; ФайлМодуля = Новый Файл(ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМодуля + "." + Расширение); Возврат ФайлМодуля; КонецФункции // Функция - Имя файла модуля без расширения // // Параметры: // СтруктураТипа - см. НоваяСтруктураТипа() - // ТипМодуля - Строка - входное значение имеет смысл только для модулей приложения (безобъектных) // СтрокаСозданияРодителя - Строка - // ФлагиКомпиляции - Структура - выход, заполняется если ТипМодуля на входе пустой // // Возвращаемое значение: // Строка - // Функция ИмяМодуляИзСтруктурыТипа(Знач СтруктураТипа, ТипМодуля = "", СтрокаСозданияРодителя = "", ФлагиКомпиляции = Неопределено) Экспорт ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; МетаданныеРодителя = СтруктураТипа.Метаданные; ТипыМетаОбъектов = ирКэш.ТипыМетаОбъектов(); Результат = ""; ФлагиКомпиляции = НовыеФлагиКомпиляции(Ложь, Ложь, Ложь); Если ТипМодуля = "МодульОбычногоПриложения" Тогда ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", Истина); ИначеЕсли ТипМодуля = "МодульУправляемогоПриложения" Тогда ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", Истина); ИначеЕсли ТипМодуля = "МодульСеанса" Тогда ФлагиКомпиляции.Вставить("Сервер", Истина); Иначе ФлагиКомпиляции = НовыеФлагиКомпиляции(); КонецЕсли; Если ИмяОбщегоТипа = "Глобальный" Тогда //Если ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда //#Если ТолстыйКлиентОбычноеПриложение Тогда // ТипМодуля = "МодульОбычногоПриложения"; //#Иначе // ТипМодуля = "МодульУправляемогоПриложения"; //#КонецЕсли Если Не ЗначениеЗаполнено(ТипМодуля) Тогда ВызватьИсключение "Требуется передача типа модуля конфигурации"; КонецЕсли; ИначеЕсли Ложь Или ИмяОбщегоТипа = "Команда" Или ИмяОбщегоТипа = "ОбщаяКоманда" Тогда ТипМодуля = "МодульКоманды"; ИначеЕсли Ложь Или ИмяОбщегоТипа = "WebСервис" Или ИмяОбщегоТипа = "HttpСервис" Или ИмяОбщегоТипа = "ОбщийМодуль" Тогда ТипМодуля = "Модуль"; Если ИмяОбщегоТипа = "ОбщийМодуль" Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда // Добавленный/переименованный объект метаданных Фрагменты = ирОбщий.СтрРазделитьЛкс(МетаданныеРодителя); МетаданныеРодителя = Новый Структура; МетаданныеРодителя.Вставить("ВызовСервера", Истина); МетаданныеРодителя.Вставить("Сервер", Истина); МетаданныеРодителя.Вставить("КлиентУправляемоеПриложение", Истина); МетаданныеРодителя.Вставить("КлиентОбычноеПриложение", Истина); МетаданныеРодителя.Вставить("Имя", Фрагменты[1]); //МетаданныеРодителя.Вставить("ИмяРасширения", СтруктураТипа.ДержательМетаданных); мДобавленныеОбщиеМодули.Вставить(Фрагменты[1], МетаданныеРодителя); КонецЕсли; Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда ФлагиКомпиляции.Сервер = МетаданныеРодителя.Сервер; ФлагиКомпиляции.КлиентОбычноеПриложение = МетаданныеРодителя.КлиентОбычноеПриложение; ФлагиКомпиляции.КлиентУправляемоеПриложение = МетаданныеРодителя.КлиентУправляемоеПриложение; СтрокаСозданияРодителя = МетаданныеРодителя.Имя; Результат = ИмяОбщегоТипа + "." + МетаданныеРодителя.Имя + "." + ТипМодуля; Иначе // Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") Тогда // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.СтруктураТипаМодуля КонецЕсли; Иначе ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь; ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь; КонецЕсли; ИначеЕсли ирОбщий.ЛиИмяТипаФормыЛкс(ИмяОбщегоТипа, Истина) Тогда Если Ложь #Если Клиент Тогда Или ТипЗнч(МетаданныеРодителя) = Тип("Форма") #КонецЕсли Тогда СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя); Если СлужебныеДанныеФормы.Свойство("ИмяФормы") Тогда МетаданныеРодителя = СлужебныеДанныеФормы.ИмяФормы; КонецЕсли; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя(); ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь) Тогда МетаданныеРодителя = МетаданныеРодителя.ИмяФормы; КонецЕсли; ТипМодуля = "Модуль"; Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда МетаданныеРодителя = МетаданныеРодителя + ".Форма"; КонецЕсли; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И (Ложь Или ИмяОбщегоТипа = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Или ИмяОбщегоТипа = "ВнешнийОтчетОбъект.<Имя внешнего отчета>") Тогда // Нужно для некомпилируемых внешних объектов МетаданныеРодителя = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь) + "." + МетаданныеРодителя.Имя; ТипМодуля = "МодульОбъекта"; Иначе КорневойТипОбъекта = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь); Если ЗначениеЗаполнено(КорневойТипОбъекта) Тогда ТипМодуля = "МодульОбъекта"; СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТипОбъекта, "Единственное"); Если Истина И СтрокаТипаМетаОбъекта <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Множественное = СтрокаТипаМетаОбъекта.Множественное; Если СтрокаТипаМетаОбъекта.Категория = 1 Тогда СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".Создать()"; ИначеЕсли СтрокаТипаМетаОбъекта.Категория = 0 Тогда СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".ПустаяСсылка().ПолучитьОбъект()"; КонецЕсли; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей.", Ложь)) Тогда ТипМодуля = "МодульНабораЗаписей"; КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей"); СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное"); Если Истина И СтрокаТипаМетаОбъекта <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Множественное = СтрокаТипаМетаОбъекта.Множественное; СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".СоздатьНаборЗаписей()"; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "МенеджерЗначения.", Ложь)) Тогда ТипМодуля = "МодульМенеджераЗначения"; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда СтрокаСозданияРодителя = "Константы." + МетаданныеРодителя.Имя + ".СоздатьМенеджерЗначения()"; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер.", Ложь)) Тогда ТипМодуля = "МодульМенеджера"; КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер"); СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное"); Если Истина И СтрокаТипаМетаОбъекта <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Множественное = СтрокаТипаМетаОбъекта.Множественное; СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя; КонецЕсли; Иначе // Тип объекта не имеет модуля ТипМодуля = Неопределено; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(Результат) Тогда Если ЗначениеЗаполнено(ТипМодуля) Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданныхКонфигурация") Тогда Результат = "Конфигурация" + "." + ТипМодуля; Иначе Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя(); КонецЕсли; Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда Результат = МетаданныеРодителя + "." + ТипМодуля; КонецЕсли; КонецЕсли; Если Найти(Результат, ":") > 0 Тогда // для ускорения Результат = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(Результат, "_"); КонецЕсли; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда Результат = МетаданныеРодителя; КонецЕсли; КонецЕсли; Если Истина И ирКэш.НомерВерсииПлатформыЛкс() >= 803008 И СтруктураТипа.ДержательМетаданных = Неопределено Тогда Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда МетаданныеРасширения = СтруктураТипа.Метаданные.РасширениеКонфигурации(); ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда МетаданныеРасширения = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные)); Если МетаданныеРасширения <> Неопределено Тогда МетаданныеРасширения = МетаданныеРасширения.РасширениеКонфигурации(); КонецЕсли; КонецЕсли; Если МетаданныеРасширения <> Неопределено Тогда СтруктураТипа.ДержательМетаданных = МетаданныеРасширения.Имя; КонецЕсли; КонецЕсли; Если ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Строка") Тогда Результат = СтруктураТипа.ДержательМетаданных + " " + Результат; КонецЕсли; Возврат Результат; КонецФункции // Функция - Обновить кэш структуры формы из буфера // // Параметры: // СлужебныеДанные - см. ирОбщий.СлужебныеДанныеФормыЛкс() - // ТекстБуфераОбмена - - // Форма - - // // Возвращаемое значение: // - // Функция ОбновитьКэшСтруктурыФормыИзБуфера(Знач СлужебныеДанные, Знач ТекстБуфераОбмена, Знач Форма = Неопределено) Экспорт Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда СлужебныеДанные.Удалить("КорневыеИменаРеквизитов"); КонецЕсли; ИмитаторФормы = Новый Структура("ВерсияФормата, Элементы, Параметры, Команды, ДинамическиеСписки, ИменаОбработчиков, Реквизиты", ВерсияФорматаСтруктурыФормы(), Новый Структура, Новый Структура, Новый Структура, Новый Структура, Новый Массив); ЛиОбычнаяФорма = Ложь; Попытка ДвоичныеДанные = Base64Значение(ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстБуфераОбмена, "#base64:", "}")); Текст = Новый ТекстовыйДокумент; Текст.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения()); ТекстФайла = Текст.ПолучитьТекст(); ЛиОбычнаяФорма = Лев(ТекстФайла, 1) <> "{"; Если ЛиОбычнаяФорма Тогда СлужебныеДанные.Тип = Тип("Форма"); // Обычная форма ВызватьИсключение "ОбычнаяФорма"; КонецЕсли; XMLСтрока = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(ТекстФайла); // Если ошибка, то обычная форма ДокументDOM = ирОбщий.ТекстВДокументDOMЛкс(XMLСтрока); // Если ошибка, то не поддерживаемый формат управляемой формы. Например Обработка.упРМПланированиеРейсов.ФормаРедактированияРейса Исключение ОписаниеОшибки = ОписаниеОшибки(); ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата()); Если Не ЛиОбычнаяФорма И ЗначениеЗаполнено(ТекстБуфераОбмена) Тогда ирОбщий.СообщитьЛкс("Ошибка разбора буферного описания формы " + ирОбщий.ПолноеИмяФормыЛкс(СлужебныеДанные) + ": " + ОписаниеОшибки); КонецЕсли; Возврат Ложь; КонецПопытки; Разыменователь = Новый РазыменовательПространствИменDOM(Новый Соответствие); ШаблонУровня = ""; Для Счетчик = 0 По 8 Цикл Выражение = "/e/e[1]/e/" + ШаблонУровня + "d[text()='02023637-7868-4a5f-8576-835a76e0c9ba']"; ШаблонУровня = ШаблонУровня + "*/"; НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь); УзелDOM = НаборУзлов.ПолучитьСледующий(); Если УзелDOM <> Неопределено Тогда ИмитаторФормы.ИменаОбработчиков = ИменаОбработчиковИзУзлаФормы(ДокументDOM, УзелDOM.РодительскийУзел.РодительскийУзел.ПредыдущийСоседний.ПредыдущийСоседний.ПредыдущийСоседний, Разыменователь); Прервать; КонецЕсли; КонецЦикла; // реквизиты Выражение = "/e/e[2]/e/d[3]/text()"; НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка); УзелDOM = НаборУзлов.ПолучитьСледующий(); ИмитаторФормы.Реквизиты = НоваяТаблицаРеквизитовФормы(); Пока УзелDOM <> Неопределено Цикл ИмяРеквизита = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое); ОписаниеРеквизита = Новый Структура; РеквизитыКоллекции = НоваяТаблицаРеквизитовФормы(); НомерУзлаВложенных = 13; ОписаниеТипов = ТипЗначенияИзУзлаФормы(УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[5]); Если ОписаниеТипов = Новый ОписаниеТипов("ДинамическийСписок") Тогда ДинамическийСписок = Новый Структура("ОсновнаяТаблица, ТекстЗапроса"); УзелДинамическийСписок = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[14]; //ДинамическийСписок.ОсновнаяТаблица = УзелДинамическийСписок.ДочерниеУзлы[5].ТекстовоеСодержимое; УзелДинамическийСписок.ДочерниеУзлы[3].УдалитьДочерний(УзелДинамическийСписок.ДочерниеУзлы[3].ПервыйДочерний); ДинамическийСписок.ТекстЗапроса = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелДинамическийСписок.ДочерниеУзлы[3].ТекстовоеСодержимое); ИмитаторФормы.ДинамическиеСписки.Вставить(ИмяРеквизита, ДинамическийСписок); Для Каждого ДочернийУзел Из УзелДинамическийСписок.ДочерниеУзлы Цикл ТекстУзла = ДочернийУзел.ПоследнийДочерний.ТекстовоеСодержимое; Если Ложь Или ирОбщий.СтрНачинаетсяСЛкс(ТекстУзла, """FieldsMapItemName") Или ирОбщий.СтрНачинаетсяСЛкс(ТекстУзла, """FieldsMapItemSecondaryName") Тогда ИмяДочернегоРеквизита = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ДочернийУзел.СледующийСоседний.ПоследнийДочерний.ТекстовоеСодержимое); Если Найти(ИмяДочернегоРеквизита, ".") = 0 Тогда ОписаниеРеквизита = РеквизитыКоллекции.Добавить(); ОписаниеРеквизита.Имя = ИмяДочернегоРеквизита; ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ОписаниеРеквизита); ОписаниеРеквизита.ОписаниеТипов = ТипЗначенияИзУзлаФормы(ДочернийУзел.СледующийСоседний.ПервыйДочерний); КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; ЗначениеРеквизита = Неопределено; КоличествоРеквизитовКоллекции = Число(УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[НомерУзлаВложенных].ТекстовоеСодержимое); Если КоличествоРеквизитовКоллекции > 0 Тогда Если Ложь Или ОписаниеТипов = Новый ОписаниеТипов("ТаблицаЗначений") Или ОписаниеТипов = Новый ОписаниеТипов("ДеревоЗначений") Тогда ЗначениеРеквизита = Новый (ОписаниеТипов.Типы()[0]); // ТаблицаЗначений Иначе ЗначениеРеквизита = Новый Структура; // Мультиметка7726614 КонецЕсли; Для НомерРеквизита = 1 По КоличествоРеквизитовКоллекции Цикл УзелДочерний = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[НомерУзлаВложенных + НомерРеквизита].ДочерниеУзлы[3]; ОписаниеРеквизита = РеквизитыКоллекции.Добавить(); ОписаниеРеквизита.Имя = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелДочерний.ТекстовоеСодержимое); ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ОписаниеРеквизита); ОписаниеРеквизита.Индекс = УзелДочерний.РодительскийУзел.ДочерниеУзлы[1].ПервыйДочерний.ТекстовоеСодержимое; ОписаниеРеквизита.ОписаниеТипов = ТипЗначенияИзУзлаФормы(УзелДочерний.СледующийСоседний.СледующийСоседний); Если ТипЗнч(ЗначениеРеквизита) = Тип("Структура") Тогда ЗначениеРеквизита.Вставить(ОписаниеРеквизита.Имя, ОписаниеРеквизита.ОписаниеТипов); Иначе ЗначениеРеквизита.Колонки.Добавить(ОписаниеРеквизита.Имя, ОписаниеРеквизита.ОписаниеТипов); КонецЕсли; КонецЦикла; КонецЕсли; ОписаниеРеквизита = ИмитаторФормы.Реквизиты.Добавить(); ОписаниеРеквизита.Имя = ИмяРеквизита; ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(ОписаниеРеквизита); ОписаниеРеквизита.Индекс = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[1].ПервыйДочерний.ТекстовоеСодержимое; ОписаниеРеквизита.ОписаниеТипов = ОписаниеТипов; ОписаниеРеквизита.Реквизиты = РеквизитыКоллекции; ОписаниеРеквизита.Значение = ЗначениеРеквизита; УзелDOM = НаборУзлов.ПолучитьСледующий(); КонецЦикла; // Элементы ВсеТипыЭлементов = Новый Соответствие; ВсеТипыЭлементов.Вставить("1", Тип("ДополнениеЭлементаФормы")); ВсеТипыЭлементов.Вставить("cd5394d0-7dda-4b56-8927-93ccbe967a01", Тип("ГруппаФормы")); ВсеТипыЭлементов.Вставить("77ffcc29-7f2d-4223-b22f-19666e7250ba", Тип("ПолеФормы")); ВсеТипыЭлементов.Вставить("143c00f7-a42d-4cd7-9189-88e4467dc768", Тип("ТаблицаФормы")); ВсеТипыЭлементов.Вставить("a9f3b1ac-f51b-431e-b102-55a69acdecad", Тип("КнопкаФормы")); ВсеТипыЭлементов.Вставить("3d3cb80c-508b-41fa-8a18-680cdf5f1712", Тип("ДекорацияФормы")); ВидыЭлементовПоля = Новый Соответствие; ВидыЭлементовПоля.Вставить("1", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеНадписи)); ВидыЭлементовПоля.Вставить("2", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеВвода)); ВидыЭлементовПоля.Вставить("3", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеФлажка)); ВидыЭлементовПоля.Вставить("4", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеКартинки)); ВидыЭлементовПоля.Вставить("5", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПереключателя)); ВидыЭлементовПоля.Вставить("6", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеТабличногоДокумента)); ВидыЭлементовПоля.Вставить("7", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеТекстовогоДокумента)); ВидыЭлементовПоля.Вставить("8", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеКалендаря)); ВидыЭлементовПоля.Вставить("9", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеИндикатора)); ВидыЭлементовПоля.Вставить("10", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПолосыРегулирования)); ВидыЭлементовПоля.Вставить("11", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеДиаграммы)); ВидыЭлементовПоля.Вставить("12", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеДиаграммыГанта)); ВидыЭлементовПоля.Вставить("14", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеГрафическойСхемы)); ВидыЭлементовПоля.Вставить("15", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеHTMLДокумента)); ВидыЭлементовПоля.Вставить("17", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеФорматированногоДокумента)); ВидыЭлементовПоля.Вставить("18", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПериода)); ВидыЭлементовПоля.Вставить("19", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПланировщика)); ПутиКРодителям = Новый Соответствие; //Выражение = "/e/e[1]/e/d[6]/text()"; // Корневые элементы // Антибаг платформы 8.3.23. Просмотр поддерева "//" работает крайне медленно https://www.hostedredmine.com/issues/977092 //Выражение = "/e/e[1]/e//d[(position()=5 or position()=6) and starts-with(text(), '""') and text()!='""""']/text()"; // Все элементы ШаблонУровня = ""; Для Счетчик = 0 По 8 Цикл Выражение = "/e/e[1]/e/" + ШаблонУровня + "d[(position()=5 or position()=6) and starts-with(text(), '""') and text()!='""""']/text()"; // Все элементы ШаблонУровня = ШаблонУровня + "*/"; НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка); УзелDOM = НаборУзлов.ПолучитьСледующий(); Пока УзелDOM <> Неопределено Цикл ИмяЭлемента = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое); Если Ложь Или Не ирОбщий.ЛиИмяПеременнойЛкс(ИмяЭлемента) Или ирОбщий.СтрНачинаетсяСЛкс(ИмяЭлемента, "Navigator") Тогда Перейти ~СледующийЭлемент; КонецЕсли; ПутьКДанным = Новый Массив; Если УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы.Количество() <= 12 Тогда УзлыПутиКДанным = Новый Массив; Иначе УзлыПутиКДанным = УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[12].ДочерниеУзлы; КонецЕсли; Если УзлыПутиКДанным.Количество() > 1 Тогда ГлубинаПутиКДанным = Число(УзлыПутиКДанным[0].ТекстовоеСодержимое); Если ГлубинаПутиКДанным > 0 Тогда ИдентификаторыРеквизитов = Новый Соответствие; РеквизитыРодителя = ИмитаторФормы.Реквизиты; Для Индекс = 1 По ГлубинаПутиКДанным Цикл ИндексРеквизита = УзлыПутиКДанным[Индекс].ТекстовоеСодержимое; СтрокаРеквизита = РеквизитыРодителя.Найти(ИндексРеквизита, "Индекс"); Если СтрокаРеквизита <> Неопределено Тогда ИмяРеквизита = СтрокаРеквизита.Имя; Иначе ИмяРеквизита = ИндексРеквизита; #Если Клиент Тогда Если Форма <> Неопределено И Найти(ИмяРеквизита, "-") > 0 Тогда ПутьКРодителю = ирОбщий.СтрСоединитьЛкс(ПутьКДанным, "."); ИдентификаторыРеквизитов = ПутиКРодителям[ПутьКРодителю]; Если ИдентификаторыРеквизитов = Неопределено Тогда ИменаРеквизитовФормы(Форма, ПутьКРодителю,, ИдентификаторыРеквизитов); ПутиКРодителям[ПутьКРодителю] = ИдентификаторыРеквизитов; КонецЕсли; Идентификатор = ирОбщий.СтрСоединитьЛкс(ирОбщий.ВыгрузитьСвойствоЛкс(УзлыПутиКДанным[Индекс].ДочерниеУзлы, "текстовоеСодержимое"), ":"); ИмяРеквизита = ИдентификаторыРеквизитов[Идентификатор]; КонецЕсли; #КонецЕсли КонецЕсли; ПутьКДанным.Добавить(ИмяРеквизита); Если Ложь Или СтрокаРеквизита = Неопределено Или СтрокаРеквизита.Реквизиты = Неопределено Тогда Прервать; КонецЕсли; РеквизитыРодителя = СтрокаРеквизита.Реквизиты; КонецЦикла; КонецЕсли; КонецЕсли; ПутьКДанным = ирОбщий.СтрСоединитьЛкс(ПутьКДанным, "."); ТипЭлемента = ВсеТипыЭлементов[УзелDOM.РодительскийУзел.РодительскийУзел.ПредыдущийСоседний.ТекстовоеСодержимое]; ВидЭлемента = Неопределено; ВидЭлементаИмя = ""; ОписаниеЭлемента = Новый Структура; Если ТипЭлемента = Неопределено Тогда Если ирОбщий.СтрКончаетсяНаЛкс(ИмяЭлемента, "РасширеннаяПодсказка") Тогда ТипЭлемента = Тип("ДекорацияФормы"); ИначеЕсли ирОбщий.СтрКончаетсяНаЛкс(ИмяЭлемента, "КонтекстноеМеню") Тогда ТипЭлемента = Тип("ГруппаФормы"); ВидЭлемента = ВидГруппыФормы.КонтекстноеМеню; ИначеЕсли ирОбщий.СтрКончаетсяНаЛкс(ИмяЭлемента, "КоманднаяПанель") Тогда ТипЭлемента = Тип("ГруппаФормы"); ВидЭлемента = ВидГруппыФормы.КоманднаяПанель; Иначе // Опасно. Можно отсечь что то полезное Перейти ~СледующийЭлемент; КонецЕсли; Если ВидЭлемента <> Неопределено Тогда ВидЭлементаИмя = ПолучитьПолноеИмяПредопределенногоЗначения(ВидЭлемента); КонецЕсли; ИначеЕсли ТипЭлемента = Тип("ПолеФормы") Тогда ВидЭлементаИмя = ВидыЭлементовПоля[УзелDOM.РодительскийУзел.ПредыдущийСоседний.ТекстовоеСодержимое]; КонецЕсли; Если Ложь Или ВидЭлемента = ВидГруппыФормы.КоманднаяПанель Или ВидЭлемента = ВидГруппыФормы.КонтекстноеМеню Тогда // Иначе ИменаОбработчиков = ИменаОбработчиковИзУзлаФормы(ДокументDOM, УзелDOM.РодительскийУзел.РодительскийУзел, Разыменователь); ОписаниеЭлемента.Вставить("ИменаОбработчиков", ИменаОбработчиков); КонецЕсли; ОписаниеЭлемента.Вставить("ПутьКДанным", ПутьКДанным); ОписаниеЭлемента.Вставить("Тип", ТипЭлемента); ОписаниеЭлемента.Вставить("Вид", ВидЭлементаИмя); ИмитаторФормы.Элементы.Вставить(ИмяЭлемента, ОписаниеЭлемента); ~СледующийЭлемент: УзелDOM = НаборУзлов.ПолучитьСледующий(); КонецЦикла; КонецЦикла; // параметры Выражение = "/e/e[3]/e/d[2]/text()"; // Все параметры НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка); УзелDOM = НаборУзлов.ПолучитьСледующий(); Пока УзелDOM <> Неопределено Цикл ИмитаторФормы.Параметры.Вставить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое), ТипЗначенияИзУзлаФормы(УзелDOM.РодительскийУзел.СледующийСоседний)); УзелDOM = НаборУзлов.ПолучитьСледующий(); КонецЦикла; // команды Выражение = "/e/e[4]/e/d[2]/text()"; // Все команды НаборУзлов = ДокументDOM.ВычислитьВыражениеXPath(Выражение, ДокументDOM, Разыменователь, ТипРезультатаDOMXPath.Строка); УзелDOM = НаборУзлов.ПолучитьСледующий(); Пока УзелDOM <> Неопределено Цикл ИмитаторФормы.Команды.Вставить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелDOM.ТекстовоеСодержимое)); УзелDOM = НаборУзлов.ПолучитьСледующий(); КонецЦикла; ФайлФормы = ФайлМодуляИзИмениМодуля(СлужебныеДанные.ИмяФормы, "xml", Истина); ирОбщий.СохранитьЗначениеВФайлЛкс(ИмитаторФормы, ФайлФормы.ПолноеИмя); ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата()); Возврат Истина; КонецФункции Функция ВерсияФорматаСтруктурыФормы() Возврат 3; // Каждый раз при изменении структуры увеличиваем на 1 КонецФункции Процедура ДополнитьСлужебныеДанныеИзКэшаФормы(Знач СлужебныеДанные, Знач ИмитаторФормы, Знач ДатаОбновления) Экспорт Если Ложь Или Не СлужебныеДанные.Свойство("Элементы") Или ИмитаторФормы.Элементы.Количество() > 0 Тогда ирОбщий.СкопироватьКоллекциюЛкс(ИмитаторФормы, СлужебныеДанные); Для Каждого СтрокаЭлемента Из СлужебныеДанные.Элементы Цикл Если ЗначениеЗаполнено(СтрокаЭлемента.Значение.Вид) Тогда СтрокаЭлемента.Значение.Вид = ПредопределенноеЗначение(СтрокаЭлемента.Значение.Вид); КонецЕсли; ЗначениеРеквизита = Неопределено; ПутьКДанным = СтрокаЭлемента.Значение.ПутьКДанным; Если ЗначениеЗаполнено(ПутьКДанным) Тогда СтрокаРеквизита = ИмитаторФормы.Реквизиты.Найти(ПутьКДанным, "Имя"); Если СтрокаРеквизита <> Неопределено Тогда ЗначениеРеквизита = СтрокаРеквизита.Значение; ОписаниеТипов = СтрокаРеквизита.ОписаниеТипов; КонецЕсли; КонецЕсли; СтрокаЭлемента.Значение.Вставить("ОписаниеТипов", ОписаниеТипов); СтрокаЭлемента.Значение.Вставить("Значение", ЗначениеРеквизита); КонецЦикла; КонецЕсли; //СлужебныеДанные.Вставить("ПутиКДанным", ИмитаторФормы.Элементы); СлужебныеДанные.Вставить("ДатаОбновления", ДатаОбновления); СлужебныеДанные.Вставить("Тип", ирОбщий.ТипУправляемаяФормаЛкс()); КонецПроцедуры //. // Параметры: // ДокументDOM - ДокументDOM, ДокументHTML - // УзелDOM - АтрибутDOM, ДокументDOM, КомментарийDOM, НотацияDOM, ОпределениеТипаДокументаDOM, СекцияCDATADOM, СущностьDOM, ТекстDOM, ФрагментДокументаDOM, ЭлементDOM, ... - // Разыменователь - РазыменовательПространствИменDOM - // Возвращаемое значение: // Массив - Функция ИменаОбработчиковИзУзлаФормы(Знач ДокументDOM, Знач УзелDOM, Знач Разыменователь) ОбработчикиСобытий = Новый Массив; // Тут цикл поиска по глубине давал замедление! ВыражениеОбработчиков = ".//d[contains(text(),'-') and not(starts-with(text(),'-') or text()='00000000-0000-0000-0000-000000000000')]/following-sibling::d[1][not(text()='0' or contains(text(),'""""') or contains(text(),'-'))]/text()"; НаборУзловОбработчиков = ДокументDOM.ВычислитьВыражениеXPath(ВыражениеОбработчиков, УзелDOM, Разыменователь, ТипРезультатаDOMXPath.Строка); // Долго! УзелОбработчика = НаборУзловОбработчиков.ПолучитьСледующий(); Пока УзелОбработчика <> Неопределено Цикл ОбработчикиСобытий.Добавить(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(УзелОбработчика.ТекстовоеСодержимое)); УзелОбработчика = НаборУзловОбработчиков.ПолучитьСледующий(); КонецЦикла; Возврат ОбработчикиСобытий; КонецФункции // . // Возвращаемое значение: // ТаблицаЗначений - Функция НоваяТаблицаРеквизитовФормы() Реквизиты = Новый ТаблицаЗначений; Реквизиты.Колонки.Добавить("Индекс"); Реквизиты.Колонки.Добавить("Имя"); Реквизиты.Колонки.Добавить("НИмя"); Реквизиты.Колонки.Добавить("ОписаниеТипов"); Реквизиты.Колонки.Добавить("Реквизиты"); Реквизиты.Колонки.Добавить("Значение"); //Реквизиты.Колонки.Добавить("ЛиДляКоллекции", Новый ОписаниеТипов("Булево")); Возврат Реквизиты; КонецФункции //. // Параметры: // УзелТипа - ЭлементDOM - // Возвращаемое значение: // ОписаниеТипов - Функция ТипЗначенияИзУзлаФормы(Знач УзелТипа) Тип = Неопределено; Если УзелТипа.ДочерниеУзлы.Количество() > 1 Тогда РодТипа = УзелТипа.ДочерниеУзлы[1].ДочерниеУзлы[0].ДочерниеУзлы[0]; Если РодТипа.ТекстовоеСодержимое = """S""" Тогда Тип = Тип("Строка"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """B""" Тогда Тип = Тип("Булево"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """N""" Тогда Тип = Тип("Число"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """D""" Тогда Тип = Тип("Число"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """#""" Тогда ИДТипа = УзелТипа.ДочерниеУзлы[1].ДочерниеУзлы[1].ТекстовоеСодержимое; Попытка Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}"); Исключение КонецПопытки; Иначе Пустышка = 0; КонецЕсли; КонецЕсли; Возврат новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(Тип)); КонецФункции // Возвращаемое значение: // Структура - Функция НовыеФлагиКомпиляции(Знач Сервер = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач БезКонтекста = Ложь) Экспорт ФлагиКомпиляции = Новый Структура; ФлагиКомпиляции.Вставить("Сервер", Сервер); ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", КлиентОбычноеПриложение); ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", КлиентУправляемоеПриложение); ФлагиКомпиляции.Вставить("БезКонтекста", БезКонтекста); Возврат ФлагиКомпиляции; КонецФункции Функция ОписаниеМетодаМодуля(ПолноеИмяМетода) Экспорт СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль"; СтруктураТипа.Метаданные = Метаданные.ОбщиеМодули[ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМетода)]; МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа); Если МодульМетаданных = Неопределено Тогда Возврат Неопределено; КонецЕсли; МетодыМодуля = МодульМетаданных.Методы; #Если Сервер И Не Сервер Тогда МетодыМодуля = Новый ТаблицаЗначений; #КонецЕсли ОписаниеМетода = МетодыМодуля.Найти(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяМетода), "Имя"); Возврат ОписаниеМетода; КонецФункции Функция ПолучитьРазделыМодуля1С(Знач ТекстМодуля = "") Экспорт #Если Сервер И Не Сервер Тогда RegExp = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); RegExp.IgnoreCase = Истина; RegExp.MultiLine = Ложь; RegExp.Global = Истина; RegExp.Pattern = Шаблоны.ЭлементОбластиМетодов; ВхожденияМетодов = RegExp.НайтиВхождения(ТекстМодуля); ПозицияНачалаПервогоМетода = 1; ПозицияКонцаПоследнегоМетода = 1; Для Индекс = 0 По ВхожденияМетодов.Количество() - 1 Цикл Вхождение = ВхожденияМетодов[Индекс]; Если Вхождение.SubMatches(1) <> Неопределено Тогда ПозицияНачалаПервогоМетода = Вхождение.FirstIndex + 1; Прервать; КонецЕсли; КонецЦикла; Для Индекс = 1 - ВхожденияМетодов.Количество() По 0 Цикл // Обратный обход Вхождение = ВхожденияМетодов[-Индекс]; Если Вхождение.SubMatches(1) <> Неопределено Тогда ПозицияКонцаПоследнегоМетода = Вхождение.FirstIndex + Вхождение.Length + 1; Прервать; КонецЕсли; КонецЦикла; Если ПозицияКонцаПоследнегоМетода = 1 Тогда RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных; ВхожденияПеременных = RegExp.НайтиВхождения(ТекстМодуля); Для Индекс = 1 - ВхожденияПеременных.Количество() По 0 Цикл // Обратный обход Вхождение = ВхожденияПеременных[-Индекс]; ПозицияНачалаПервогоМетода = Вхождение.FirstIndex + Вхождение.Length + 1; ПозицияКонцаПоследнегоМетода = ПозицияНачалаПервогоМетода; Прервать; КонецЦикла; КонецЕсли; Результат = Новый Структура; Результат.Вставить("ПеременныеТекст", Сред(ТекстМодуля, 1, ПозицияНачалаПервогоМетода - 1)); Результат.Вставить("МетодыТекст", Сред(ТекстМодуля, ПозицияНачалаПервогоМетода, ПозицияКонцаПоследнегоМетода - ПозицияНачалаПервогоМетода)); Если ПозицияНачалаПервогоМетода < ПозицияКонцаПоследнегоМетода Тогда ПозицияКонцаПоследнегоМетода = ПозицияКонцаПоследнегоМетода + 1; КонецЕсли; Результат.Вставить("ПозицияМетодов", ПозицияНачалаПервогоМетода); // начиная с 1 Результат.Вставить("ПозицияПрограммы", ПозицияКонцаПоследнегоМетода); // начиная с 1 Результат.Вставить("Программа", Сред(ТекстМодуля, Результат.ПозицияПрограммы)); Результат.Вставить("ВхожденияМетодов", ВхожденияМетодов); Возврат Результат; КонецФункции Функция ШаблоныДляАнализаВстроенногоЯзыка() Экспорт Перем шИмя, шПустоеНачалоСтроки, шКомментарий, шРазделитель, шСтруктураКомментаПарам, шСтруктураКомментаВозвр, шВозврат, шСтруктураКомментаОписаниеПараметров, шКомментМетода, шОписаниеПеременной, шСтрокаПеременныхБезКомментов, шСтрокаПеременных, шСтрокаПрограммы, шПараметрыМетода, шДирективаПрепроцессора, шБлокКомментов, шМетодЧистый, шМетод1, шМетодСПредКомментом, шСтруктураМодуля, шЭлементОбластиМетодов; Если мШаблоныДляАнализаВстроенногоЯзыка <> Неопределено Тогда Возврат мШаблоныДляАнализаВстроенногоЯзыка; КонецЕсли; // {ОписаниеРегулярногоВыражения.Начало} конструктор из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) // {Шаблон.Начало} // + <шИмя> = [_ЁА-ЯA-Z][_ЁА-ЯA-Z\d]* // + <шПустоеНачалоСтроки> = (?:\n|^)(?:\t| )* // + <шКомментарий> = //[^\n]*(?=(?:\n|$)) // + <шРазделитель> = (?:<шКомментарий>|\s|\xa0|$) // + <шСтруктураКомментаПарам> = Параметры(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?:\n\s*Возвращаемое значение\s*\:?\s*\n|$) // + <шСтруктураКомментаВозвр> = Возвращаемое значение(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?:\n\s*Параметры\s*\:?\s*\n|$) // + <шВозврат> = Возврат\s+(?:Неопределено|Undefined|Null|(<шИмя>))(?:;|\n|\r|$) // + <шСтруктураКомментаОписаниеПараметров> = (<шИмя>)(?:\s*[-–])([^\n]*(?:\n|$)(\s{4}[^\n]*(?:\n|$))*) // + <шКомментМетода> = ((?:[\f\r\t\v]*//[^\n]*\n)+)(?:Функция|Процедура)<шРазделитель>*(<шИмя>) // + <шОписаниеПеременной> = (<шИмя>)(<шРазделитель>+Экспорт)? // + <шСтрокаПеременныхБезКомментов> = <шПустоеНачалоСтроки>Перем((?:<шРазделитель>*<шОписаниеПеременной><шРазделитель>*[;,])+) // + <шСтрокаПеременных> = <шСтрокаПеременныхБезКомментов>([^\n\S]*//[^\n]*)? // + <шСтрокаПрограммы> = "(?:(?:"")|[^"\n])*(?:<шРазделитель>*\|(?:(?:"")|[^"\n])*)*(?:"|$) // + <шПараметрыМетода> = <шРазделитель>*(Знач\s)?<шРазделитель>*(<шИмя>)<шРазделитель>*=?((?:<шРазделитель>*|(<шСтрокаПрограммы>)|(?:[^,\n]*))+)(?:,|$) // + <шДирективаПрепроцессора> = (?:\n\s*)?<шПустоеНачалоСтроки>[#&][^\n]*(?=\n|$) // + <шБлокКомментов> = <шКомментарий>(?:<шПустоеНачалоСтроки><шКомментарий>)*(?=(?:\n|$)) // + <шМетодЧистый> = ([\t ]*(?:Асинх\s+)?(Процедура|Функция)<шРазделитель>*(<шИмя>)<шРазделитель>*\(([^\)]*)\)(<шРазделитель>*Экспорт)?(?:\s*?(?=\n))?(?:\n\s*Перем .*(?=\n))*)((?:<шСтрокаПрограммы>|<шБлокКомментов>|\.Конец(?:Процедуры|Функции)|(?:\r|\n|.)(?!Конец(?:Процедуры|Функции)))*)(?:$|[^а-яё_a-z0-9\."]Конец(?:Процедуры|Функции)(?=(?:<шКомментарий>|[^а-яё_a-z0-9\."]|$))) // + <шМетодСПредКомментом> = (?:(<шБлокКомментов>\n)|\n|^)[\t ]*<шМетодЧистый> // + <шЭлементОбластиМетодов> = <шМетодСПредКомментом>|(<шБлокКомментов>)|(<шДирективаПрепроцессора>) // {Шаблон.Конец} шИмя = ЭтотОбъект.шИмя; шПустоеНачалоСтроки = ЭтотОбъект.шПустоеНачалоСтроки; шКомментарий = ЭтотОбъект.шКомментарий; шРазделитель = ЭтотОбъект.шРазделитель; шСтрокаПрограммы = ЭтотОбъект.шСтрокаПрограммы; шСтруктураКомментаПарам = "Параметры(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?=\n\s*Возвращаемое значение\s*\:?\s*\n|$)"; // Всегда захватывает блок возвращаемого значения шСтруктураКомментаВозвр = "Возвращаемое значение(?:\s*:\s*)?((([^\n]\n)*|.|\n)*)(?:\n\s*Параметры\s*\:?\s*\n|$)"; //шВозврат = "Возврат\s+(?:Неопределено|Undefined|Null|(" + шИмя + "))(?:;|\n|\r|$)"; шВозврат = "Возврат\s+(.+?)(?:;| КонецЕсли|\n|\r|$)"; шСтруктураКомментаОписаниеПараметров = "(" + шИмя + ")(?:\s*[-–])([^\n]*(?:\n|$)(\s{4}[^\n]*(?:\n|$))*)"; шКомментМетода = "((?:[\f\r\t\v]*//[^\n]*\n)+)(?:Функция|Процедура)" + шРазделитель + "+(" + шИмя + ")"; шОписаниеПеременной = "(" + шИмя + ")(" + шРазделитель + "+Экспорт)?"; шСтрокаПеременныхБезКомментов = "Перем((?:" + шРазделитель + "*" + шОписаниеПеременной + "" + шРазделитель + "*[;,])+)"; шСтрокаПеременных = "" + шПустоеНачалоСтроки + шСтрокаПеременныхБезКомментов + "([^\n\S]*//[^\n]*)?"; шПараметрыМетода = "" + шРазделитель + "*(Знач\s)?" + шРазделитель + "*(" + шИмя + ")" + шРазделитель + "*=?((?:" + шРазделитель + "*|(" + шСтрокаПрограммы + ")|(?:[^,\n]*))+)(?:,|$)"; шДирективаПрепроцессора = "(?:\n\s*)?" + шПустоеНачалоСтроки + "[#&][^\n]*(?=\n|$)"; шБлокКомментов = "" + шКомментарий + "(?:" + шПустоеНачалоСтроки + "" + шКомментарий + ")*(?=(?:\n|$))"; шМетодЧистый = "([\t ]*(?:Асинх\s+)?(Процедура|Функция)" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*Экспорт)?(?:\s*?(?=\n))?(?:\n\s*Перем .*(?=\n))*)" + "((?:" + шСтрокаПрограммы + "|" + шБлокКомментов + "|\.Конец(?:Процедуры|Функции)|(?:\r|\n|.)(?!Конец(?:Процедуры|Функции)))*)(?:$|[^а-яё_a-z0-9\.""]Конец(?:Процедуры|Функции)(?=(?:" + шКомментарий + "|[^а-яё_a-z0-9\.""]|$)))"; шМетодСПредКомментом = "(?:(" + шБлокКомментов + "\n)|\n|^)" + шМетодЧистый + ""; шЭлементОбластиМетодов = "" + шМетодСПредКомментом + "|(" + шБлокКомментов + ")|(" + шДирективаПрепроцессора + ")"; // {ОписаниеРегулярногоВыражения.Конец} Результат = Новый Структура; Результат.Вставить("СтрокаПрограммы", шСтрокаПрограммы); Результат.Вставить("ДирективаПрепроцессора", шДирективаПрепроцессора); Результат.Вставить("БлокКомментариев", шБлокКомментов); Результат.Вставить("ОписаниеМетодаСКомментарием", шМетодСПредКомментом); Результат.Вставить("ОписаниеМетодаЧистое", шМетодЧистый); Результат.Вставить("ЭлементОбластиМетодов", шЭлементОбластиМетодов); Результат.Вставить("ОписаниеПеременной", шОписаниеПеременной); Результат.Вставить("ОписаниеСтрокиПеременных", шСтрокаПеременных); Результат.Вставить("ОписаниеСтрокиПеременныхБезКомментов", шСтрокаПеременныхБезКомментов); Результат.Вставить("КомментарийОписаниеМетода", шКомментМетода); Результат.Вставить("ПараметрыМетода", шПараметрыМетода); Результат.Вставить("СтруктураКомментарияВозвр", шСтруктураКомментаВозвр); Результат.Вставить("СтруктураКомментарияПарам", шСтруктураКомментаПарам); Результат.Вставить("СтруктураКомментарияОписаниеПараметров", шСтруктураКомментаОписаниеПараметров); Результат.Вставить("Возврат", шВозврат); Результат.Вставить("ОписаниеПараметра", ".*(?:\n(?://)?(?:[\t ]{5,}|[\t ]+\*).*)*"); мШаблоныДляАнализаВстроенногоЯзыка = Результат; Возврат Результат; КонецФункции // Функция - Модуль метаданных. Для пустого текста и НЕ пустого имени возращает единый модуль с именем "<Пустой>"! // // Параметры: // ТекстМодуля - Строка - // СтруктураТипа - см. НоваяСтруктураТипа() - // ИмяМодуля - Строка - // ПодготовитьОписанияРезультатовМетодов - Булево - // СтарыйМодуль - см. МодульМетаданных() - // ТекущийМетод - см. НоваяТаблицаМетодовМодуля()[0] - // // Возвращаемое значение: // Структура - // Функция МодульМетаданных(Знач ТекстМодуля, Знач СтруктураТипа = Неопределено, Знач ИмяМодуля = "", Знач ПодготовитьОписанияРезультатовМетодов = Истина, Знач СтарыйМодуль = Неопределено, Знач ТекущаяПозиция = 0) Экспорт РазрешитьЕдиныйПустойМодуль = Истина И ПустаяСтрока(ТекстМодуля) И ИмяМодуля <> ИмяДинамическогоМодуля() И ЗначениеЗаполнено(ИмяМодуля); Если РазрешитьЕдиныйПустойМодуль И мПустойМодуль <> Неопределено Тогда // Для ускорения заполнения списка в Обработка.ирКлсПолеТекстаПрограммы.Форма.МетодыМодулей Возврат мПустойМодуль; КонецЕсли; ЛиНачальныйДиапазонСовпал = Ложь; ЛиКонечныйДиапазонСовпал = Ложь; Если Истина И СтарыйМодуль <> Неопределено //И СтарыйМодуль.Свойство("Текст") И ЗначениеЗаполнено(ТекущаяПозиция) И ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 // СтрНайти() Тогда МетодыСтарые = СтарыйМодуль.Методы; ТекущийМетод = СтарыйМодуль.ТекущийМетод; // см. МетодыСтарые.Добавить() Если ТекущийМетод <> Неопределено Тогда Если Ложь Или МетодыСтарые.Индекс(ТекущийМетод) = -1 Или ТекущийМетод.ПозицияСОписанием - ТекущаяПозиция > 1000 Или ТекущаяПозиция - (ТекущийМетод.ПозицияСОписанием + ТекущийМетод.ДлинаСОписанием) > 1000 Тогда ТекущийМетод = Неопределено; КонецЕсли; КонецЕсли; ИндексТекущегоМетода = -1; Если ТекущийМетод <> Неопределено Тогда ИндексТекущегоМетода = МетодыСтарые.Индекс(ТекущийМетод); КонецЕсли; Если ИндексТекущегоМетода = -1 Тогда ИндексТекущегоМетода = МетодыСтарые.Количество(); Для Каждого Метод Из МетодыСтарые Цикл Если Метод.ПозицияСОписанием = 0 Тогда Продолжить; КонецЕсли; Если Метод.ПозицияСОписанием + Метод.ДлинаСОписанием + 100 > ТекущаяПозиция Тогда ИндексТекущегоМетода = МетодыСтарые.Индекс(Метод); ТекущийМетод = Метод; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если ТекущийМетод <> Неопределено Тогда ПозицияНачалаСтарая = ТекущийМетод.ПозицияСОписанием; ПозицияКонцаСтарая = ПозицияНачалаСтарая + ТекущийМетод.ДлинаСОписанием; Иначе ПозицияНачалаСтарая = СтарыйМодуль.ПозицияПрограммы; ПозицияКонцаСтарая = СтрДлина(СтарыйМодуль.Текст); КонецЕсли; ЧастьДоМетодаСтарая = Лев(СтарыйМодуль.Текст, ПозицияНачалаСтарая); ЧастьДоМетодаНовая = Лев(ТекстМодуля, ПозицияНачалаСтарая); Если ЧастьДоМетодаСтарая = ЧастьДоМетодаНовая Тогда ЛиНачальныйДиапазонСовпал = Истина; Если ТекущийМетод <> Неопределено Тогда Если ТекущийМетод.ТипЗначения = Неопределено Тогда МаркерКонца = Символы.ПС + "КонецПроцедуры"; Иначе МаркерКонца = Символы.ПС + "КонецФункции"; КонецЕсли; ПозицияКонцаНовая = ирОбщий.СтрНайтиЛкс(ТекстМодуля, МаркерКонца,, ПозицияНачалаСтарая) + СтрДлина(МаркерКонца); Иначе ПозицияКонцаНовая = СтрДлина(ТекстМодуля); КонецЕсли; ЧастьПослеМетодаНовая = Сред(ТекстМодуля, ПозицияКонцаНовая); ЧастьПослеМетодаСтарая = Сред(СтарыйМодуль.Текст, ПозицияКонцаСтарая); ЛиКонечныйДиапазонСовпал = ЧастьПослеМетодаНовая = ЧастьПослеМетодаСтарая; СмещениеКонечногоДиапазона = ПозицияКонцаНовая - ПозицияКонцаСтарая; КонецЕсли; КонецЕсли; НачальнаяПозицияДиапазона = 0; Если ЛиНачальныйДиапазонСовпал Тогда Модуль = СтарыйМодуль; СброситьКэшТиповВыраженийМодуля(Модуль); Методы = Модуль.Методы; Ошибки = Модуль.Ошибки; // ОбработкаТабличнаяЧасть.ирКлсПолеТекстаПрограммы.ОшибкиМодуля Если Ошибки <> Неопределено Тогда УдалитьОшибкиМетода(ТекущийМетод, Ошибки); КонецЕсли; НачальнаяПозицияДиапазона = ПозицияНачалаСтарая - 1; Если ЛиКонечныйДиапазонСовпал Тогда Если ТекущийМетод = Неопределено Тогда Модуль.Программа = Сред(ТекстМодуля, ПозицияНачалаСтарая); ВхожденияМетодов = Новый Массив; Иначе ТекущийМетод.КэшПоиска = Неопределено; ОпределениеСОписанием = Сред(ТекстМодуля, ПозицияНачалаСтарая, ТекущийМетод.ДлинаСОписанием + СмещениеКонечногоДиапазона); ВхожденияМетодов = ПолучитьРазделыМодуля1С(ОпределениеСОписанием).ВхожденияМетодов; Для ИндексМетодаЦикл = ИндексТекущегоМетода + 1 По Методы.Количество() - 1 Цикл СтрокаМетода = Методы[ИндексМетодаЦикл]; Если СтрокаМетода.ПозицияСОписанием = 0 Тогда Продолжить; // Возможно даже Прервать КонецЕсли; СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием + СмещениеКонечногоДиапазона; СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияОпределения + СмещениеКонечногоДиапазона; СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияТела + СмещениеКонечногоДиапазона; Если Ошибки <> Неопределено И СтрокаМетода.РассчитаныОшибки Тогда Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", СтрокаМетода.Имя)) Цикл СтрокаОшибки.Позиция = СтрокаОшибки.Позиция + СмещениеКонечногоДиапазона; КонецЦикла; КонецЕсли; КонецЦикла; Модуль.ПозицияПрограммы = Модуль.ПозицияПрограммы + СмещениеКонечногоДиапазона; КонецЕсли; Иначе КонечныйДиапазон = Сред(ТекстМодуля, ПозицияНачалаСтарая); РазделыМодуля = ПолучитьРазделыМодуля1С(КонечныйДиапазон); Модуль.Программа = РазделыМодуля.Программа; Модуль.ПозицияПрограммы = ПозицияНачалаСтарая + РазделыМодуля.ПозицияПрограммы; ВхожденияМетодов = РазделыМодуля.ВхожденияМетодов; Пока Методы.Количество() > ИндексТекущегоМетода Цикл Если Ошибки <> Неопределено Тогда УдалитьОшибкиМетода(Методы[ИндексТекущегоМетода], Ошибки); КонецЕсли; Методы.Удалить(ИндексТекущегоМетода); КонецЦикла; ТекущийМетод = Неопределено; КонецЕсли; Модуль.Текст = ТекстМодуля; Иначе ТекущийМетод = Неопределено; Ошибки = Неопределено; Модуль = ПолучитьРазделыМодуля1С(ТекстМодуля); Модуль.Вставить("СтруктураТипа", СтруктураТипа); Модуль.Вставить("Имя", ИмяМодуля); Модуль.Вставить("ФлагиКомпиляции"); Модуль.Вставить("ТекущийМетод"); Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); RegExp.IgnoreCase = Истина; RegExp.Multiline = Ложь; // При добавлении колонок нужно увеличивать версию формата Метка91237881041 Переменные = Новый ТаблицаЗначений; Переменные.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево")); Переменные.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // вычислено по коду Переменные.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1. Переменные.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1. Переменные.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("ТаблицаТипов"); //RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")"; RegExp.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")"; Вхождения = RegExp.НайтиВхождения(Модуль.ПеременныеТекст); Для Каждого Вхождение Из Вхождения Цикл Если Вхождение.SubMatches(0) <> Неопределено Тогда ТекстСтроки = Вхождение.SubMatches(0); ОписаниеСтроки = ОчиститьТекстМодуляОтПрефиксаКомментария(Вхождение.SubMatches(3)); ПозицияСОписанием = Вхождение.FirstIndex + 2; Если Найти(ТекстСтроки, ",") = 0 Тогда // Одна переменная в строке ИмяПеременной = ирОбщий.ПервыйФрагментЛкс(Вхождение.SubMatches(1)); ЭкспортПеременной = ?(Вхождение.SubMatches(2) = Неопределено, Ложь, Истина); ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием); Иначе // Несколько переменных в строке RegExp2.Pattern = Шаблоны.ОписаниеПеременной + "|\s*(?:;|,)"; Результат2 = RegExp2.НайтиВхождения(ТекстСтроки); // тяжелая операция Для Каждого Вхождение2 Из Результат2 Цикл Если Вхождение2.SubMatches(0) <> Неопределено Тогда ИмяПеременной = Вхождение2.SubMatches(0); ЭкспортПеременной = ?(Вхождение2.SubMatches(1) = Неопределено, Ложь, Истина); ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием); КонецЕсли; КонецЦикла; КонецЕсли; //ИначеЕсли Вхождение.SubMatches(4) <> Неопределено Тогда // СтрокаПеременной.Тип = "Комментарий"; //ИначеЕсли Вхождение.SubMatches(5) <> Неопределено Тогда // СтрокаПеременной.Тип = "Директива"; КонецЕсли; КонецЦикла; Модуль.Удалить("ПеременныеТекст"); Модуль.Вставить("Переменные", Переменные); Методы = НоваяТаблицаМетодовМодуля(); ВхожденияМетодов = Модуль.ВхожденияМетодов; Если СтруктураТипа <> Неопределено Тогда СтрокаМетода = Методы.Добавить(); СтрокаМетода.Сервер = Истина; СтрокаМетода.Клиент = Истина; СтрокаМетода.ЛиЭкспорт = Истина; СтрокаМетода.РассчитаныОшибки = Истина; СтрокаМетода.Имя = "<>"; СтрокаМетода.ТипЗначения = "НеизвестныйКонтекст"; ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаМетода); КонецЕсли; КонецЕсли; ПоследняяАннотация = ""; ПоследнееОписание = ""; ПорогДлиныМаркераТела = 20; Для Каждого Вхождение Из ВхожденияМетодов Цикл ПозицияВхождения = Вхождение.FirstIndex + 1 + НачальнаяПозицияДиапазона; Заголовок = Вхождение.SubMatches(1); Если Заголовок <> Неопределено Тогда Если ТекущийМетод <> Неопределено Тогда СтрокаМетода = ТекущийМетод; СтрокаМетода.ОписаниеРезультата = Неопределено; СтрокаМетода.ТелоБезВозвратов = Неопределено; Иначе СтрокаМетода = Методы.Добавить(); КонецЕсли; ОписаниеМетода = Вхождение.SubMatches(0); ДлинаОписания = СтрДлина(ОписаниеМетода); ОпределениеБезОписания = Сред(Вхождение.Value, ДлинаОписания + 1); Если Лев(ОпределениеБезОписания, 1) = Символы.ПС Тогда ОпределениеБезОписания = Сред(ОпределениеБезОписания, 2); ДлинаОписания = ДлинаОписания + 1; КонецЕсли; СтрокаМетода.ПозицияСОписанием = ПозицияВхождения; СтрокаМетода.ДлинаСОписанием = Вхождение.Length; СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияСОписанием + ДлинаОписания; СтрокаМетода.ДлинаОпределения = СтрДлина(ОпределениеБезОписания); //СтрокаМетода.Индекс = Вхождение.FirstIndex + Смещение; СтрокаМетода.Имя = Вхождение.SubMatches(3); СтрокаМетода.НИмя = Нрег(СтрокаМетода.Имя); ТекстПараметров = Вхождение.SubMatches(4); ТекстЭкспорта = Вхождение.SubMatches(5); ЛиЭкспорт = ?(ТекстЭкспорта = Неопределено, Ложь, Истина); Тело = Вхождение.SubMatches(6); ПерваяСтрокаТела = ирОбщий.ПервыйФрагментЛкс(Тело, Символы.ПС); ПозицияЭкспортаВТеле = Найти(ПерваяСтрокаТела, ") Экспорт"); ДлинаЗаголовка = СтрДлина(Заголовок); Если ПозицияЭкспортаВТеле > 0 Тогда // Сработал ложный конец секции параметров из-за ")" в значении по умолчанию ДобавкаЗаголовка = ")" + Лев(ПерваяСтрокаТела, ПозицияЭкспортаВТеле - 1); ТекстПараметров = ТекстПараметров + ДобавкаЗаголовка; ДлинаЗаголовка = ДлинаЗаголовка + СтрДлина(ДобавкаЗаголовка); ЛиЭкспорт = Истина; КонецЕсли; СтрокаМетода.ЛиЭкспорт = ЛиЭкспорт; Тело = Сред(Тело, 2); // Мультиметка38422941 Сдвиг добавлен после вынужденного переноса символа "переноса строки" из заголовка в тело СтрокаМетода.ДлинаТела = СтрДлина(Тело); Если СтрокаМетода.ДлинаТела = 0 Тогда // TODO надо полностью перейти на этот способ СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + ДлинаЗаголовка; Иначе МаркерНачалаТела = Тело; //Если СтрДлина(МаркерНачалаТела) < ПорогДлиныМаркераТела Тогда // МаркерНачалаТела = МаркерНачалаТела + Символы.ПС; //КонецЕсли; МаркерНачалаТела = Лев(МаркерНачалаТела, ПорогДлиныМаркераТела); СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + Найти(ОпределениеБезОписания, МаркерНачалаТела) - 2; // Мультиметка38422941 КонецЕсли; Если ЗначениеЗаполнено(ПоследняяАннотация) И Не ЗначениеЗаполнено(ОписаниеМетода) Тогда ОписаниеМетода = ПоследнееОписание; КонецЕсли; ПоследнееОписание = ""; СтрокаМетода.Описание = ОписаниеМетода; СтрокаМетода.Аннотация = ПоследняяАннотация; Если НРег(Вхождение.SubMatches(2)) = "функция" Тогда СтрокаМетода.ТипЗначения = "??"; КонецЕсли; СтрокаМетода.Параметры = ТекстПараметров; // Сначала тип "Строка". Позже разбираем их в ПараметрыМетодаМодуля() Если ПодготовитьОписанияРезультатовМетодов Тогда // очень небольшая экономия времени ПодготовитьОписаниеРезультатаМетода(СтрокаМетода); КонецЕсли; Если ЗначениеЗаполнено(ПоследняяАннотация) Тогда СтрокаМетода.РасширяемыйМетод = ирОбщий.ТекстМеждуМаркерамиЛкс(ПоследняяАннотация, "(""", """)", Ложь); КонецЕсли; ПоследняяАннотация = НРег(ПоследняяАннотация); СтрокаМетода.Сервер = ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "насервере") > 0; СтрокаМетода.Клиент = ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "наклиенте") > 0; СтрокаМетода.БезКонтекста = Найти(ПоследняяАннотация, "безконтекста") > 0; СтрокаМетода.ЛиАсинх = НРег(Лев(Заголовок, 1)) = "а"; Если СтарыйМодуль <> Неопределено Тогда //СтарыйМетод = СтарыйМодуль.Методы.Найти(СтрокаМетода.НИмя, "НИмя"); //Если Истина // //И СтарыйМетод.Вычислено // И ТипЗнч(СтарыйМетод.Параметры) <> Тип("Строка") // И Сред(СтарыйМодуль.Текст, СтарыйМетод.ПозицияСОписанием, СтарыйМетод.ДлинаСОписанием) = Вхождение.Value // И СтарыйМетод.Аннотация = СтрокаМетода.Аннотация //Тогда // СтрокаМетода.Параметры = СтарыйМетод.Параметры; // СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов"); // СтрокаМетода.ОписаниеРезультата = СтарыйМетод.ОписаниеРезультата; // СтрокаМетода.ТипЗначения = СтарыйМетод.ТипЗначения; //КонецЕсли; КонецЕсли; ПоследняяАннотация = ""; ИначеЕсли Вхождение.SubMatches(7) <> Неопределено Тогда Если Модуль.ПозицияМетодов > ПозицияВхождения Тогда Продолжить; КонецЕсли; ПоследнееОписание = Вхождение.SubMatches(7); ИначеЕсли Вхождение.SubMatches(8) <> Неопределено Тогда НоваяАннотация = Вхождение.SubMatches(8); Если СтрЧислоСтрок(НоваяАннотация) = 3 Тогда ПоследнееОписание = ""; КонецЕсли; НоваяАннотация = СокрЛП(НоваяАннотация); Если Лев(НоваяАннотация, 1) = "&" Тогда ПоследняяАннотация = НоваяАннотация; КонецЕсли; КонецЕсли; КонецЦикла; Модуль.Удалить("МетодыТекст"); Модуль.Удалить("ВхожденияМетодов"); Модуль.Вставить("Методы", Методы); Модуль.Вставить("Текст", ТекстМодуля); Модуль.Вставить("Ошибки", Ошибки); Методы.Индексы.Добавить("ЛиЭкспорт"); Методы.Индексы.Добавить("ЛиЭкспорт, НИмя"); Методы.Индексы.Добавить("НИмя"); Если РазрешитьЕдиныйПустойМодуль Тогда Модуль.Имя = "<Пустой>"; мПустойМодуль = Модуль; КонецЕсли; Возврат Модуль; КонецФункции //. // Параметры: // СтрокаМетода - СтрокаТаблицыЗначений - // Ошибки - ОбработкаТабличнаяЧасть.ирКлсПолеТекстаПрограммы.ОшибкиМодуля - Процедура УдалитьОшибкиМетода(Знач СтрокаМетода, Знач Ошибки) Экспорт Если СтрокаМетода = Неопределено Тогда ИмяМетода = "<Инициация>"; Иначе Если Не СтрокаМетода.РассчитаныОшибки Тогда Возврат; Иначе СтрокаМетода.РассчитаныОшибки = Ложь; ИмяМетода = СтрокаМетода.Имя; КонецЕсли; КонецЕсли; Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", ИмяМетода)) Цикл Ошибки.Удалить(СтрокаОшибки); КонецЦикла; КонецПроцедуры // Функция - Новая таблица методов модуля // // Возвращаемое значение: // ТаблицаЗначений - : // * Параметры - Строка, см. НоваяТаблицаПараметровМетодаМодуля // * ТаблицаТипов - см. НоваяТаблицаТипов // * КлючевыеПараметры - Структура // Функция НоваяТаблицаМетодовМодуля() Экспорт // При добавлении колонок нужно увеличивать версию формата Метка91237881041 Методы = Новый ТаблицаЗначений; Методы.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); //Методы.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка")); //Методы.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("Аннотация", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("РасширяемыйМетод", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("Параметры"); Методы.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1. Методы.Колонки.Добавить("ДлинаСОписанием", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1. Может содержать непечатное смещение от начала строки Методы.Колонки.Добавить("ДлинаОпределения", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("ПозицияТела", Новый ОписаниеТипов("Число")); // Начиная с 1 Методы.Колонки.Добавить("ДлинаТела", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("ТелоБезВозвратов"); Методы.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("ОписаниеРезультата"); Методы.Колонки.Добавить("ТипЗначения"); Методы.Колонки.Добавить("ТаблицаТипов"); Методы.Колонки.Добавить("Сервер", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("Клиент", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("БезКонтекста", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("ЛиАсинх", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // тип значения вычислен по коду Методы.Колонки.Добавить("РассчитаныОшибки", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("КлючевыеПараметры"); Методы.Колонки.Добавить("КэшПоиска"); Методы.Колонки.Добавить("ТипыВыражений"); Возврат Методы; КонецФункции //. // Параметры: // Переменные - ТаблицаЗначений - // ИмяПеременной - ? - // ЭкспортПеременной - ? - // ОписаниеСтроки - Строка - // ПозицияСОписанием - ? - Процедура ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, Знач ОписаниеСтроки, Знач ПозицияСОписанием) Экспорт СтрокаПеременной = Переменные.Добавить(); СтрокаПеременной.Имя = ИмяПеременной; СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя); СтрокаПеременной.ЛиЭкспорт = ЭкспортПеременной; СтрокаПеременной.ПозицияСОписанием = ПозицияСОписанием; СтрокаПеременной.ПозицияОпределения = ПозицияСОписанием; СтрокаПеременной.Описание = ОписаниеСтроки; КонецПроцедуры //. // Параметры: // СтрокаМетода - см. НоваяТаблицаМетодовМодуля()[0] - // выхБылиИзменения - Булево - // Возвращаемое значение: // ТаблицаЗначений - Функция ПараметрыМетодаМодуля(СтрокаМетода, выхБылиИзменения = Ложь) Экспорт Если СтрокаМетода = Неопределено Тогда Возврат Неопределено; КонецЕсли; Результат = СтрокаМетода.Параметры; Если ТипЗнч(Результат) = Тип("Строка") Тогда выхБылиИзменения = Истина; СтрокаМетода.Описание = ОчиститьТекстМодуляОтПрефиксаКомментария(СтрокаМетода.Описание); Если Не ЗначениеЗаполнено(СтрокаМетода.Параметры) Тогда Результат = Неопределено; Иначе Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); RegExp2.Global = Истина; RegExp2.Pattern = Шаблоны.ПараметрыМетода; РезультатПараметров = RegExp2.НайтиВхождения(СтрокаМетода.Параметры); Если РезультатПараметров.Количество() > 0 Тогда Результат = НоваяТаблицаПараметровМетодаМодуля(); Для Каждого ВхождениеПараметра Из РезультатПараметров Цикл СтрокаПраметра = Результат.Добавить(); СтрокаПраметра.Имя = ВхождениеПараметра.SubMatches(1); СтрокаПраметра.НИмя = НРег(СтрокаПраметра.Имя); СтрокаПраметра.Знач = ?(ВхождениеПараметра.SubMatches(0) = Неопределено, Ложь, Истина); СтрокаПраметра.Значение = ВхождениеПараметра.SubMatches(2); КонецЦикла; Если ЗначениеЗаполнено(СтрокаМетода.Описание) Тогда ОписанияПараметровЗагружены = Ложь; Если СтрЧислоСтрок(СтрокаМетода.Описание) = 1 Тогда СсылкаНаОписание = СтрокаМетода.Описание; Если УдалитьПрефиксИзТекстаТипов(СсылкаНаОписание) Тогда // Ссылка на описание друго метода. Параметры сопоставляются по позиции. //СтрокаМетода.Описание = СтрокаБазовогоМетода.Описание; Методы = Неопределено; Если Найти(СсылкаНаОписание, ".") = 0 Тогда Методы = СтрокаМетода.Владелец(); Иначе Если Прав(СсылкаНаОписание, 1) = "." Тогда СсылкаНаОписание = СокрП(ирОбщий.СтрокаБезКонцаЛкс(СсылкаНаОписание)); КонецЕсли; КраткоеИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(СсылкаНаОписание); Анализатор = ирКэш.ПолеТекстаМодуляБезСтруктурыТипаЛкс(""); ТаблицаТиповМодуля = Анализатор.ВычислитьТипЗначенияВыражения(КраткоеИмяМодуля,,,,,, Ложь); Если ТаблицаТиповМодуля.Количество() > 0 Тогда Модуль = ПодготовитьМодульМетаданных(ТаблицаТиповМодуля[0]); Если Модуль <> Неопределено Тогда Методы = Модуль.Методы; КонецЕсли; КонецЕсли; КонецЕсли; Если Методы <> Неопределено Тогда ИмяБазовогоМетода = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПоследнийФрагментЛкс(СсылкаНаОписание), "("); СтрокаБазовогоМетода = Методы.Найти(НРег(ИмяБазовогоМетода), "НИмя"); Если СтрокаБазовогоМетода <> Неопределено Тогда ПараметрыБазовогоМетода = ПараметрыМетодаМодуля(СтрокаБазовогоМетода); Если ПараметрыБазовогоМетода <> Неопределено Тогда Для Индекс = 0 По Мин(ПараметрыБазовогоМетода.Количество(), Результат.Количество()) - 1 Цикл Результат[Индекс].Описание = ПараметрыБазовогоМетода[Индекс].Описание; Результат[Индекс].ТипЗначения = ПараметрыБазовогоМетода[Индекс].ТипЗначения; КонецЦикла; КонецЕсли; ОписанияПараметровЗагружены = Истина; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ОписанияПараметровЗагружены Тогда ВхожденияОписаний = ПараметрыМетодаИзКомментария(СтрокаМетода.Описание, Шаблоны); Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл СтрокаПараметра = Результат.Найти(НРег(ВхождениеОписания.Имя)); Если СтрокаПараметра <> Неопределено Тогда Если ВхождениеОписания.ТипЗначения = Неопределено Тогда ИмяТипа = СокрЛП(ВхождениеОписания.Описание); Попытка Пустышка = Тип(ИмяТипа); ЭтоТип = Истина; Исключение ЭтоТип = Ложь; КонецПопытки; Если ЭтоТип Тогда СтрокаПараметра.ТипЗначения = ИмяТипа; Иначе СтрокаПараметра.Описание = ВхождениеОписания.Описание; КонецЕсли; Иначе СтрокаПараметра.Описание = ВхождениеОписания.Описание; СтрокаПараметра.ТипЗначения = ВхождениеОписания.ТипЗначения; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; СтрокаМетода.Параметры = Результат; КонецЕсли; Возврат Результат; КонецФункции //. // Возвращаемое значение: // ТаблицаЗначений - Функция НоваяТаблицаПараметровМетодаМодуля() Экспорт Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Значение"); Результат.Колонки.Добавить("Знач", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("ТаблицаТипов"); Возврат Результат; КонецФункции // Вызывается из других конфигураций! // Параметры: // ОписаниеМетода - Строка - // Шаблоны - Структура - для ускорения // Возвращаемое значение: // ТаблицаЗначений - Функция ПараметрыМетодаИзКомментария(Знач ОписаниеМетода, Шаблоны = Неопределено) Экспорт Если Шаблоны = Неопределено Тогда Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); КонецЕсли; шРазделительВнутриСтроки = "[-–]"; // Здесь 2 разных символа шОписаниеПараметра = "\n\s{0,8}(" + шИмя + ")\*?\s*(?:" + шРазделительВнутриСтроки + "\s*([^-–\n]*)\s*)?" + шРазделительВнутриСтроки + "\s*?(" + Шаблоны.ОписаниеПараметра + ")[\.;]?"; ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(ОписаниеМетода, шОписаниеПараметра, "Имя, ТипЗначения, Описание",,, Ложь, Ложь); Возврат ВхожденияОписаний; КонецФункции Функция ОчиститьТекстМодуляОтПрефиксаКомментария(Знач ТекстМодуля) Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда Возврат ""; КонецЕсли; RegExp.Global = Истина; RegExp.Pattern = шПустоеНачалоСтроки + "(?:/){2,}"; Результат = RegExp.Заменить(ТекстМодуля, Символы.ПС); Если Лев(Результат, 1) = Символы.ПС Тогда Результат = Сред(Результат, 2); // Отрезаем начальный перенос строки КонецЕсли; Возврат Результат; КонецФункции Функция ПодготовитьТипРезультатаМетода(МетодМодуля, ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено, Знач СФактическимиПараметрами = Ложь, Знач ДляСвойства = "") Экспорт Если МетодМодуля.ТипЗначения = Неопределено Тогда // тип метода - "процедура" Возврат Неопределено; КонецЕсли; Если МетодМодуля.ТаблицаТипов = Неопределено Тогда МетодМодуля.ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; ПодготовитьОписаниеРезультатаМетода(МетодМодуля); ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш); ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(МетодМодуля, Истина); ТаблицаТипов = ПодготовитьТипЗначенияСловаМодуля(ПолеТекстаМодуляКэш.ИмяПеременнойВозвращаемогоЗначения(), ПолеТекстаМодуляКэш, МетодМодуля, ИмяИлиМодуль, МетодМодуля, МетодМодуля.ОписаниеРезультата, СФактическимиПараметрами, Истина, ДляСвойства); Возврат ТаблицаТипов; КонецФункции //. // Параметры: // СтрокаОпределения - СтрокаТаблицыЗначений - Процедура ПодготовитьОписаниеРезультатаМетода(СтрокаОпределения) Экспорт Если Истина И ЗначениеЗаполнено(СтрокаОпределения.Описание) И СтрокаОпределения.ОписаниеРезультата = Неопределено И СтрокаОпределения.ТипЗначения <> Неопределено Тогда Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); ШаблонОписанияРезультата = "(?:Возвращаемое\s+значение|Результат)[:-]\s*(?:([^-–:\n]+)\s*(?=[-–:\n]))?\s*(" + Шаблоны.ОписаниеПараметра + ")"; ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(СтрокаОпределения.Описание, ШаблонОписанияРезультата, "ТипЗначения, Описание", Ложь,, Ложь, Ложь); Если ВхожденияОписаний.Количество() > 0 Тогда ВхождениеОписания = ВхожденияОписаний[ВхожденияОписаний.Количество() - 1]; ТекстТипаЗначения = СокрЛ(СтрЗаменить(ВхождениеОписания.ТипЗначения, "//", "")); КопияТекстТипаЗначения = ТекстТипаЗначения; Если УдалитьПрефиксИзТекстаТипов(КопияТекстТипаЗначения) Тогда СтрокаОпределения.ТипЗначения = ТекстТипаЗначения; ИначеЕсли ЗначениеЗаполнено(ТекстТипаЗначения) Тогда СтрокаОпределения.ТипЗначения = СтрокаОпределения.ТипЗначения + ", " + ТекстТипаЗначения; // TODO удаление дублей КонецЕсли; ОписаниеРезультата = СокрЛП(ВхождениеОписания.Описание); СтрокаОпределения.ОписаниеРезультата = ОчиститьТекстМодуляОтПрефиксаКомментария(ОписаниеРезультата); Иначе СтрокаОпределения.ОписаниеРезультата = ""; КонецЕсли; КонецЕсли; КонецПроцедуры // Функция - Удалить префикс из текста типов // // Параметры: // Текст - - // // Возвращаемое значение: // Булево - является ли именем типа // Функция УдалитьПрефиксИзТекстаТипов(Текст) Экспорт Текст = СокрЛП(Текст); МаркерСм = "см."; Если ирОбщий.СтрНачинаетсяСЛкс(Текст, МаркерСм) Тогда Текст = СокрЛ(Сред(Текст, СтрДлина(МаркерСм) + 1)); Возврат Истина; КонецЕсли; Если Найти(Текст, "(") > 0 И Найти(Текст, " ") = 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ПодготовитьТипЗначенияПеременнойМодуля(СтрокаОпределения, ИмяИлиМодуль, Знач ПолеТекстаМодуляКэш = Неопределено) Экспорт Если Не СтрокаОпределения.Вычислено Тогда Если СтрокаОпределения.ТаблицаТипов = Неопределено Тогда СтрокаОпределения.ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; Если Истина И ЗначениеЗаполнено(СтрокаОпределения.Описание) И Не ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения) Тогда ТипЗначения = ирОбщий.ПервыйФрагментЛкс(СтрокаОпределения.Описание, "-"); СтрокаОпределения.Описание = Сред(СтрокаОпределения.Описание, СтрДлина(ТипЗначения) + 1); СтрокаОпределения.ТипЗначения = СокрЛ(ТипЗначения); КонецЕсли; ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш); ПодготовитьТипЗначенияСловаМодуля(СтрокаОпределения.Имя, ПолеТекстаМодуляКэш,, ИмяИлиМодуль, СтрокаОпределения, СтрокаОпределения.Описание); КонецЕсли; КонецФункции Функция ПодготовитьТипЗначенияСловаМодуля(Знач ИмяПеременной, Знач ПолеТекстаМодуляКэш, Знач МетодМодуля, Знач ИмяИлиМодуль, Знач СтрокаОпределения, Знач ОписаниеТипа = "", Знач СФактическимиПараметрами = Ложь, Знач ЭтоПрисвоенноеВыражение = Ложь, Знач ДляСвойства = "") Если ПустаяСтрока(ИмяПеременной) Тогда ВызватьИсключение "Э"; КонецЕсли; Если СФактическимиПараметрами Тогда //ЭлементыКлюча = Новый СписокЗначений; //Для Каждого КлючИЗначение Из СтрокаОпределения.КлючевыеПараметры Цикл // КлючЗначения = КлючИЗначение.Значение[0].Метаданные; // КлючЗначения = XMLСтрока(КлючЗначения); // ЭлементыКлюча.Добавить(КлючИЗначение.Ключ + "=" + КлючЗначения); //КонецЦикла; //ЭлементыКлюча.СортироватьПоЗначению(); //ДопКлючКэша = ирОбщий.СтрСоединитьЛкс(ЭлементыКлюча, ";"); ДопКлючКэша = Неопределено; ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,, ДопКлючКэша, ДляСвойства); Иначе Если Не СтрокаОпределения.Вычислено И СтрокаОпределения.Имя <> "<>" Тогда Если Не ЗначениеЗаполнено(ДляСвойства) Тогда СтрокаОпределения.Вычислено = Истина; КонецЕсли; // Обогащаем таблицу структур типов из текстового описания типа Если Истина И ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения) И СтрокаОпределения.ТипЗначения <> "??" И СтрокаОпределения.ТипЗначения <> "?" Тогда ТаблицаТипов = ПолеТекстаМодуляКэш.ТаблицаТиповИзТекста(СтрокаОпределения.ТипЗначения, ОписаниеТипа); ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТипов); КонецЕсли; УказанКонструктор = Найти(НРег(СтрокаОпределения.ТипЗначения), "см.") > 0; Если Ложь Или (Истина И УказанКонструктор И ЛиДетальностьТиповДостаточна(ТаблицаТипов)) Или (Истина И МетодМодуля = Неопределено // только для переменных И ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения) И Не УказанКонструктор И ЛиДетальностьТиповДостаточна(ТаблицаТипов, 4)) Тогда // Считаем что тип в комментарии описан достаточно подробно Иначе ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,,, ДляСвойства); Если ТаблицаТипов.Количество() > 0 Тогда // Мультиметка4529884 против циклической ссылки Для Каждого СтрокаТипа Из ТаблицаТипов.НайтиСтроки(Новый Структура("СтрокаОписания", СтрокаОпределения)) Цикл Если СтрокаТипа.Метаданные = Неопределено Тогда ТаблицаТипов.Удалить(СтрокаТипа); Иначе СтрокаТипа.СтрокаОписания = Неопределено; КонецЕсли; КонецЦикла; ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТипов); Иначе СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = "Произвольный"; ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, СтруктураТипа); КонецЕсли; //СтрокаОпределения.ТаблицаТипов.ЗаполнитьЗначения(СтрокаОпределения, "СтрокаОписания"); // Мультиметка4529884 Была циклическая ссылка ! Теперь заполняем ссылку позже уже в копии таблицы Если Не ЗначениеЗаполнено(ДляСвойства) Тогда СтрокаОпределения.ТипЗначения = ПредставлениеМассиваСтруктурТипов(СтрокаОпределения.ТаблицаТипов); КонецЕсли; КонецЕсли; КонецЕсли; ТаблицаТипов = СтрокаОпределения.ТаблицаТипов; КонецЕсли; Возврат ТаблицаТипов; КонецФункции //. // Параметры: // ИмяИлиМодуль - Структура - // ПолеТекстаМодуляКэш - ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено - // Возвращаемое значение: // ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено - Функция ПолеТекстаМодуля(Знач ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено) Экспорт Если ПолеТекстаМодуляКэш = Неопределено Тогда Если ТипЗнч(ИмяИлиМодуль) = Тип("Строка") Тогда ИмяМодуля = ИмяИлиМодуль; Иначе ИмяМодуля = ИмяИлиМодуль.Имя КонецЕсли; ПолеТекстаМодуляКэш = ирКэш.ПолеТекстаМодуляЛкс(ИмяМодуля); Если ТипЗнч(ИмяИлиМодуль) = Тип("Структура") Тогда НовыйМодуль = ИмяИлиМодуль; // Точно из кэша Иначе НовыйМодуль = МодульМетаданныхИзКэша(ИмяМодуля); КонецЕсли; Если НовыйМодуль <> Неопределено Тогда ПолеТекстаМодуляКэш.ЗагрузитьМодульМетаданных(НовыйМодуль); КонецЕсли; ПолеТекстаМодуляКэш = ПолеТекстаМодуляКэш.КопияКомпоненты(); // Иначе при вызовах в рамках одного модуля будет переиспользоваться один объект и портиться контекст КонецЕсли; Возврат ПолеТекстаМодуляКэш; КонецФункции // Получает представление массива типов. // // Параметры: // ТаблицаТиповКонтекста - ТаблицаЗначений. // // Возвращаемое значение: // Строка - представление массива типов. // Функция ПредставлениеМассиваСтруктурТипов(ТаблицаТиповКонтекста, БезДублей = Ложь, МаксКоличествоТипов = 10) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаТиповКонтекста = Новый ТаблицаЗначений; #КонецЕсли ПредставлениеТипаКонтекста = ""; Если ТаблицаТиповКонтекста <> Неопределено Тогда Если ТаблицаТиповКонтекста.Количество() = 0 Тогда ИначеЕсли ТаблицаТиповКонтекста.Количество() = 1 Тогда ПредставлениеТипаКонтекста = ИмяТипаИзСтруктурыТипа(ТаблицаТиповКонтекста[0]); Иначе СписокОбрезан = Неопределено; СписокИменТипов = ТаблицаТиповДляПользователя(ТаблицаТиповКонтекста, БезДублей, МаксКоличествоТипов, СписокОбрезан); Если СписокОбрезан Тогда СписокИменТипов.Добавить().Имя = "..."; КонецЕсли; ПредставлениеТипаКонтекста = ирОбщий.СтрСоединитьЛкс(СписокИменТипов.ВыгрузитьКолонку("Имя"), ", "); ПредставлениеТипаКонтекста = СтрЗаменить(ПредставлениеТипаКонтекста, "?, ", ""); КонецЕсли; КонецЕсли; Возврат ПредставлениеТипаКонтекста; КонецФункции Функция ТаблицаТиповДляПользователя(Знач ТаблицаТиповКонтекста, Знач БезДублей = Истина, Знач МаксКоличествоТипов = 0, выхСписокОбрезан = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаТиповКонтекста = Новый ТаблицаЗначений; #КонецЕсли Счетчик = 0; выхСписокОбрезан = Ложь; СписокИменТипов = Новый ТаблицаЗначений; СписокИменТипов.Колонки.Добавить("Имя"); СписокИменТипов.Колонки.Добавить("СтруктураТипа"); СтруктураТипаНеопределено = Неопределено; Для Каждого СтруктураТипаКонтекста Из ТаблицаТиповКонтекста Цикл Счетчик = Счетчик + 1; Если МаксКоличествоТипов > 0 И Счетчик > МаксКоличествоТипов Тогда выхСписокОбрезан = Истина; Прервать; КонецЕсли; ИмяТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста); Если Не ЗначениеЗаполнено(ИмяТипа) Тогда Продолжить; КонецЕсли; Если ИмяТипа = "Неопределено" Тогда СтруктураТипаНеопределено = СтруктураТипаКонтекста; Продолжить; КонецЕсли; СтрокаИменТипов = СписокИменТипов.Добавить(); СтрокаИменТипов.Имя = ИмяТипа; СтрокаИменТипов.СтруктураТипа = СтруктураТипаКонтекста; КонецЦикла; Если БезДублей Тогда СписокИменТипов.Свернуть("Имя"); КонецЕсли; СписокИменТипов.Сортировать("Имя"); Если СтруктураТипаНеопределено <> Неопределено Тогда // Чтобы Неопределено всегда шло последним СтрокаИменТипов = СписокИменТипов.Добавить(); СтрокаИменТипов.Имя = "Неопределено"; СтрокаИменТипов.СтруктураТипа = СтруктураТипаНеопределено; КонецЕсли; Возврат СписокИменТипов; КонецФункции // Функция - Отбор параметров метода // // Параметры: // СтрокаОписания - СтрокаТаблицыЗначений - строка таблицы ТаблицаКонтекстов // // Возвращаемое значение: // - // Функция ОтборПараметровМетода(Знач СтрокаОписания) Экспорт ОтборПараметров = Новый Структура; ОтборПараметров.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста); Если СтрокаОписания.ТипСлова = "Конструктор" Тогда ОтборПараметров.Вставить("Слово", "<Новый>"); Иначе ОтборПараметров.Вставить("Слово", СтрокаОписания.Слово); КонецЕсли; ОтборПараметров.Вставить("ЯзыкПрограммы", СтрокаОписания.ЯзыкПрограммы); Возврат ОтборПараметров; КонецФункции // Функция - Таблица параметров метода для всех вариантов синтаксиса // // Параметры: // СтрокаОписания - СтрокаТаблицыЗначений - строка глобальной таблицы ТаблицаКонтекстов // ОтборПараметров - - // // Возвращаемое значение: // - // Функция ПараметрыМетодаПлатформы(Знач СтрокаОписания) Экспорт ОтборПараметров = ОтборПараметровМетода(СтрокаОписания); КоличествоПараметров = 0; Если Не ЗначениеЗаполнено(СтрокаОписания.Описание) Тогда // Мультиметка443985642 СинтаксПомощник = СинтаксПомощник(); #Если Сервер И Не Сервер Тогда СинтаксПомощник = Обработки.ирСинтаксПомощник.Создать(); #КонецЕсли МассивВариантов = Новый Массив; Если СтрокаОписания.ТипСлова = "Конструктор" Тогда Отбор = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка"); // индекс ЗаполнитьЗначенияСвойств(Отбор, СтрокаОписания); Для Каждого СтрокаВарианта Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл МассивВариантов.Добавить(СтрокаВарианта); КонецЦикла; Иначе МассивВариантов.Добавить(СтрокаОписания); КонецЕсли; Для Каждого ВариантМетода Из МассивВариантов Цикл ПутьКЭлементуАрхива = ВариантМетода.ПутьКОписанию; НовыйАдрес = СинтаксПомощник.РаспаковатьФайлАрхиваСинтаксПомощника(ПутьКЭлементуАрхива); КоличествоПараметров = 100; Если НовыйАдрес <> Неопределено Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ирОбщий.ПервыйФрагментЛкс(НовыйАдрес, "#")); ТекстДокумента = ТекстовыйДокумент.ПолучитьТекст(); КоличествоПараметров = СинтаксПомощник.ЗагрузитьОписаниеМетода(ВариантМетода.ТипКонтекста, ВариантМетода.Слово, ТекстДокумента, ВариантМетода.ТипСлова, ВариантМетода.ЯзыкПрограммы,,, ВариантМетода); КонецЕсли; КонецЦикла; КонецЕсли; СтрокиПараметров = ТаблицаПараметров.Скопировать(ОтборПараметров); Пока Истина И КоличествоПараметров > 0 И КоличествоПараметров < СтрокиПараметров.Количество() И СтрокиПараметров[0].ВариантСинтаксиса = СтрокиПараметров[КоличествоПараметров].ВариантСинтаксиса Цикл // Удаляем дубли параметров виртуальных таблиц регистра бухгалтерии https://www.hostedredmine.com/issues/952173 СтрокиПараметров.Удалить(КоличествоПараметров); КонецЦикла; Возврат СтрокиПараметров; КонецФункции Функция ПолучитьТипЗначенияЧленаИнтерфейса(ОписаниеРезультата, ИмяБиблиотеки = "", _БиблиотекаТипов = Неопределено) Экспорт //Тест = ПолучитьИмяТипаCOMVariant(Член); ИнфоТипаРезультата = ОписаниеРезультата.TypeInfo; Если ИнфоТипаРезультата <> Неопределено Тогда ТипЗначенияРезультата = ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоТипаРезультата, ИмяБиблиотеки); Иначе НомерТипа = ОписаниеРезультата.VarType; ТипЗначенияРезультата = "Произвольный" + ", " + НомерТипа; Если НомерТипа = 0 Тогда ТипЗначенияРезультата = Неопределено; ИначеЕсли НомерТипа = 1 Тогда ТипЗначенияРезультата = Null; ИначеЕсли НомерТипа >= 2 И НомерТипа <= 5 Тогда ТипЗначенияРезультата = "Число"; ИначеЕсли НомерТипа = 7 Тогда ТипЗначенияРезультата = "Дата"; ИначеЕсли НомерТипа = 8 Тогда ТипЗначенияРезультата = "Строка"; ИначеЕсли НомерТипа = 11 Тогда ТипЗначенияРезультата = "Булево"; ИначеЕсли НомерТипа = 12 Тогда ТипЗначенияРезультата = "Строка"; ИначеЕсли НомерТипа >= 14 И НомерТипа <= 23 Тогда ТипЗначенияРезультата = "Число"; ИначеЕсли НомерТипа = 24 Тогда // Метод не возвращает значение - Процедура ТипЗначенияРезультата = ""; ИначеЕсли НомерТипа = 9 Тогда // Тип этого значения станет известен только при его появлении //ТипЗначенияРезультата = ПолучитьИмяТипаCOMVariant(ОписаниеРезультата); // Тоже не дает результат ТипЗначенияРезультата = "Произвольный"; КонецЕсли; КонецЕсли; Возврат ТипЗначенияРезультата; //'OLE Automation VARIANT types // Enum TliVarType // VT_EMPTY = 0 '&H0 // VT_NULL = 1 '&H1 // VT_I2 = 2 '&H2 // VT_I4 = 3 '&H3 // VT_R4 = 4 '&H4 // VT_R8 = 5 '&H5 // VT_CY = 6 '&H6 // VT_DATE = 7 '&H7 // VT_BSTR = 8 '&H8 // VT_DISPATCH = 9 '&H9 // VT_ERROR = 10 '&HA // VT_BOOL = 11 '&HB // VT_VARIANT = 12 '&HC // VT_UNKNOWN = 13 '&HD // VT_DECIMAL = 14 '&HE // VT_I1 = 16 '&H10 // VT_UI1 = 17 '&H11 // VT_UI2 = 18 '&H12 // VT_UI4 = 19 '&H13 // VT_I8 = 20 '&H14 // VT_UI8 = 21 '&H15 // VT_INT = 22 '&H16 // VT_UINT = 23 '&H17 // VT_VOID = 24 '&H18 // VT_HRESULT = 25 '&H19 // VT_PTR = 26 '&H1A // VT_SAFEARRAY = 27 '&H1B // VT_CARRAY = 28 '&H1C // VT_USERDEFINED = 29 '&H1D // VT_LPSTR = 30 '&H1E // VT_LPWSTR = 31 '&H1F // VT_RECORD = 36 '&H24 // VT_FILETIME = 64 '&H40 // VT_BLOB = 65 '&H41 // VT_STREAM = 66 '&H42 // VT_STORAGE = 67 '&H43 // VT_STREAMED_OBJECT = 68 '&H44 // VT_STORED_OBJECT = 69 '&H45 // VT_BLOB_OBJECT = 70 '&H46 // VT_CF = 71 '&H47 // VT_CLSID = 72 '&H48 // VT_VECTOR = 4096 '&H1000 // VT_ARRAY = 8192 '&H2000 // VT_BYREF = 16384 '&H4000 // VT_RESERVED = 32768 '&H8000 КонецФункции Функция ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоИнтерфейса, Знач ИмяБиблиотеки = "") Экспорт Если Не ЗначениеЗаполнено(ИмяБиблиотеки) Тогда ИмяБиблиотеки = "COMОбъект"; КонецЕсли; Результат = ИнфоИнтерфейса.Name + " {" + ИмяБиблиотеки + "}"; Возврат Результат; КонецФункции Функция ПолноеИмяТипаCOMОбъекта(COMОбъект, Знач ПолноеИмяОсновногоКласса = "") Экспорт ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(COMОбъект, , ПолноеИмяОсновногоКласса); Если ИнфоИнтерфейса <> Неопределено Тогда Результат = ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоИнтерфейса, ПолноеИмяОсновногоКласса); Иначе Результат = "COMОбъект"; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьИнфоТипаCOMОбъекта(выхCOMОбъект, Знач ИмяОбщегоТипа = Неопределено, выхПолноеИмяОсновногоКласса = "") Экспорт ПолучитьCOMНавигатор(); Если COMНавигатор = "Отказ" Тогда Возврат Неопределено; КонецЕсли; Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда Попытка COMНавигатор.ResolveAliases = Ложь; // Тут бывает кривой объект без свойств и методов и при выводе строки эта ошибка очень раздражает //ИнфоКласса = COMНавигатор.ClassInfoFromObject(выхCOMОбъект); // Этот способ не поддерживается в большинстве классов ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект); // // Тут возникает ошибка для некоторых объектов, например V83.Application, ADODB.Recorset.Fields(*).Precision Исключение ОписаниеОшибки = ОписаниеОшибки(); //ирОбщий.СообщитьЛкс(ОписаниеОшибки); Возврат Неопределено; КонецПопытки; КонецЕсли; Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда выхПолноеИмяОсновногоКласса = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь); ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, " "); КонецЕсли; Если Не ЗначениеЗаполнено(выхПолноеИмяОсновногоКласса) Тогда Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда ИмяБиблиотеки = ИнфоИнтерфейса.Parent.Name; ИмяОсновногоКласса = мИменаОсновныхКлассовБиблиотекCOM[ИмяБиблиотеки]; Если ИмяОсновногоКласса = Неопределено Тогда //КаталогПриложений = Новый COMОбъект("COMAdmin.COMAdminCatalog"); //КаталогПриложений.Connect("localhost"); //Компоненты = КаталогПриложений.GetCollection("InprocServers"); //Компоненты.PopulateByKey("" + ИнфоИнтерфейса.Parent.GUID); //Компоненты.PopulateByKey("{F935DC26-1CF0-11D0-ADB9-00C04FD58A0B}"); //Если Компоненты.Count > 0 Тогда // ИмяОсновногоКласса = Компоненты.Item(0).Name; //Иначе ПробныйОбъект = Неопределено; Для Каждого Претендент Из ИнфоИнтерфейса.Parent.CoClasses Цикл Попытка ПробныйОбъект = Новый COMОбъект(ИмяБиблиотеки + "." + Претендент.Name); Исключение Продолжить; КонецПопытки; Прервать; КонецЦикла; Если ПробныйОбъект <> Неопределено Тогда ИмяОсновногоКласса = Претендент.Name; Иначе ИмяОсновногоКласса = "?"; КонецЕсли; мИменаОсновныхКлассовБиблиотекCOM[ИмяБиблиотеки] = ИмяОсновногоКласса; //КонецЕсли; КонецЕсли; выхПолноеИмяОсновногоКласса = ИмяБиблиотеки + "." + ИмяОсновногоКласса; Иначе Возврат Неопределено; КонецЕсли; КонецЕсли; Если ИнфоИнтерфейса = Неопределено Тогда выхCOMОбъект = ПолучитьОбразецCOMОбъекта(выхПолноеИмяОсновногоКласса); Попытка ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект); Исключение //ирОбщий.СообщитьЛкс(ОписаниеОшибки()); Возврат Неопределено; КонецПопытки; лИнфоИнтерфейса = ИнфоИнтерфейса.Parent.TypeInfos.NamedItem(ИмяОбщегоТипа); Если лИнфоИнтерфейса <> Неопределено Тогда ИнфоИнтерфейса = лИнфоИнтерфейса; Иначе // Например для Shell.Application выполняется КонецЕсли; КонецЕсли; Возврат ИнфоИнтерфейса; КонецФункции Функция ПолучитьОбразецCOMОбъекта(ПолноеИмяОсновногоКлассаCOM) Экспорт КлючКэша = НРег(ПолноеИмяОсновногоКлассаCOM); Результат = мОбразцыCOMОбъектов[КлючКэша]; // Закомментировал т.к. замедляет работу анализатора кода например для V83.Application //Если Результат <> Неопределено Тогда // ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(Результат,, ПолноеИмяОсновногоКлассаCOM); // Если ИнфоИнтерфейса = Неопределено Тогда // // Объект испорчен // Результат = Неопределено; // КонецЕсли; //КонецЕсли; Если Результат = Неопределено Тогда Попытка Результат = Новый COMОбъект(ПолноеИмяОсновногоКлассаCOM); Исключение Возврат Неопределено; КонецПопытки; мОбразцыCOMОбъектов[КлючКэша] = Результат; КонецЕсли; Возврат Результат; КонецФункции // Получает новый экземпляр ком-объекта парсера. // // Параметры: // Нет. // // Возвращаемое значение: // Com-объект, Неопределено. // Функция ПолучитьCOMНавигатор() Экспорт Если COMНавигатор = "НеИнициализирован" Тогда COMНавигатор = ПолучитьCOMОбъектИзМакета("TLBINF32", "TLI.TLIApplication"); //! COMНавигатор = Новый COMОбъект("TLI.TLIApplication"); КонецЕсли; Возврат COMНавигатор; КонецФункции Функция ТипыЭлементовКоллекции(Знач СтруктураТипаКоллекции, Знач ЯзыкПрограммы = 0, выхНужнаПроверкаТипов = Истина) Экспорт выхНужнаПроверкаТипов = Истина; ТипыЭлементовКоллекции = Новый Массив(); ИмяОбщегоТипаКоллекции = ирОбщий.ПервыйФрагментЛкс(СтруктураТипаКоллекции.ИмяОбщегоТипа, "["); Если Ложь Или ИмяОбщегоТипаКоллекции = "Массив" Или ИмяОбщегоТипаКоллекции = "ФиксированныйМассив" Тогда выхНужнаПроверкаТипов = Ложь; ТекстТипыЭлементов = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипаКоллекции.ИмяОбщегоТипа, "[", "]", Ложь); Если ЗначениеЗаполнено(ТекстТипыЭлементов) Тогда ТипыЭлементовКоллекции = ирОбщий.СтрРазделитьЛкс(ТекстТипыЭлементов, ", "); КонецЕсли; ИначеЕсли ЛиИмяТипаComОбъекта(СтруктураТипаКоллекции.ИмяОбщегоТипа) Тогда ИмяОбщегоТипа = СтруктураТипаКоллекции.ИмяОбщегоТипа; ТаблицаСтруктурТипаЭлемента = НоваяТаблицаТипов(); ИмяБиблиотеки = ""; МетаданныеОбъекта = СтруктураТипаКоллекции.Метаданные; ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеОбъекта, ИмяОбщегоТипа, ИмяБиблиотеки); Если ИнфоТипа = Неопределено Тогда Возврат ТаблицаСтруктурТипаЭлемента; КонецЕсли; МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипа); Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл Для Каждого Член Из ИнфоТипа.Members Цикл Если Истина //И Член.InvokeKind = 1 // метод // почему то иногда у него стоит 2 (например ADODB.Fields) И ирОбщий.СтрокиРавныЛкс(Член.Name, "Item") Тогда ИнфоТипаЭлемента = Член.ReturnType.TypeInfo; ИмяОбщегоТипаЭлемента = ПолучитьТипЗначенияЧленаИнтерфейса(Член.ReturnType, ИмяБиблиотеки, ИнфоТипа.Parent); ТипыЭлементовКоллекции.Добавить(ИмяОбщегоТипаЭлемента); Прервать; КонецЕсли; КонецЦикла; КонецЦикла; ИначеЕсли Истина И СтруктураТипаКоллекции.ИмяОбщегоТипа = "ЭлементыФормы" И ТипЗнч(СтруктураТипаКоллекции.Метаданные) = Тип("Форма") Тогда ТипыЭлементовКоллекции = мМассивТиповЭлементовОбычнойФормы; Иначе СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча); Если НайденныеСтроки.Количество() > 0 Тогда Если НайденныеСтроки[0].ТипЭлементаКоллекции <> "" Тогда ТипыЭлементовКоллекции = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ТипыЭлементовКоллекции; КонецФункции // Добавляет и заполяет строку в таблицу слов при условии отсутствия там строк по ключу (Слово, ТипСлова) // // Параметры: // ТаблицаСлов - ТаблицаЗначений - НоваяТаблицаСвойствТипа(); // Слово - Строка; // ТипСлова - Строка; // ТаблицаТипов - ТаблицаЗначений. // Функция ДобавитьВТаблицуСлов(Знач ТаблицаСлов, Знач Слово, Знач ТипСлова, Знач ТаблицаТипов = Неопределено, Знач ТипЗначения = "??", Знач Определение = "") Экспорт #Если Сервер И Не Сервер Тогда ТаблицаСлов = Новый ТаблицаЗначений #КонецЕсли КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова); Если ТипСлова <> "Метод" Тогда // Для ускорения, т.к. платформа не позволяет перегружать методы НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда Если ТаблицаТипов <> Неопределено Тогда ДобавитьВТаблицуТипов(НайденныеСтроки[0].ТаблицаТипов, ТаблицаТипов); КонецЕсли; Возврат НайденныеСтроки[0]; КонецЕсли; КонецЕсли; СтрокаСлова = ТаблицаСлов.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаСлова, КлючПоиска); СтрокаСлова.ТипЗначения = ТипЗначения; СтрокаСлова.Определение = Определение; Если ТаблицаТипов <> Неопределено Тогда СтрокаСлова.ТаблицаТипов = ТаблицаТипов; Попытка ТипЗначенияВложенный = ТаблицаТипов[0].СтрокаОписания.ТипЗначения; Исключение ТипЗначенияВложенный = Неопределено; КонецПопытки; Если Ложь //Или ТипЗначенияВложенный = Неопределено // Отключил, чтобы вычисление представлений примитивных типов не откладывалось //Или ТипЗначенияВложенный = "Произвольный" Тогда ТипЗначенияВложенный = "??"; КонецЕсли; СтрокаСлова.МожноУточнитьТип = Ложь Или (Истина И ТипЗначенияВложенный <> "??" // Нужно чтобы вычисляемые по коду свойства и функции не вычислялись сразу при заполнении списка автодополнения И Лев(ТипЗначения, 2) = "??") Или Найти(ТипЗначения, "<") > 0; КонецЕсли; Возврат СтрокаСлова; КонецФункции // Получает таблицу слов указанной структуры типа. // // Параметры: // СтруктураТипа - Структура - описание типа. // БазовоеРасширениеКонфигурации - Строка - "" - основная конфигурация, "*" - все расширения // // Возвращаемое значение: // ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов", "Определение". // Функция ТаблицаСловИзСтруктурыТипа(СтруктураТипа, ЯзыкПрограммы = 0, Конфигурация = Неопределено, ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина, Знач ВнутриГруппыОбщихМодулей = Ложь, ТипСлова = Неопределено, Знач ФлагиКомпиляции = Неопределено, Знач Слово = Неопределено, Знач МодульМетаданных = Неопределено, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ТаблицаСвойств = Неопределено, Знач ЭтоЛокальныйКонтекст = Ложь, Знач НаборыСлов = Неопределено, Знач БазовоеРасширениеКонфигурации = "") Экспорт ИнициацияОписанияМетодовИСвойств(); Если ФлагиКомпиляции = Неопределено Тогда ФлагиКомпиляции = НовыеФлагиКомпиляции(); КонецЕсли; Если Не ВнутриГруппыОбщихМодулей Тогда ТаблицаСвойств = СловаКонтекстаПредопределенные(СтруктураТипа, Слово, ТипСлова,, ЯзыкПрограммы, Конфигурация, ВычислятьТипы, ФлагиКомпиляции, ТаблицаСвойств, ЭтоЛокальныйКонтекст, НаборыСлов, БазовоеРасширениеКонфигурации); КонецЕсли; ТаблицаСвойств = СловаКонтекстаМетаданные(СтруктураТипа, Слово, ТипСлова, ВнутриГруппыОбщихМодулей, ЯзыкПрограммы,, ВнешниеФункцииКомпоновкиДанных, ВычислятьТипы, ФлагиКомпиляции, МодульМетаданных, ТаблицаСвойств, ВычислятьТипыМетодовМодулей, ЭтоЛокальныйКонтекст,, БазовоеРасширениеКонфигурации); Возврат ТаблицаСвойств; КонецФункции Функция ИмяКолонкиФлагаВнутриТаблицы() Экспорт Возврат "ДержательМетаданных"; КонецФункции // Получает новую структуру типа. // // Параметры: // Нет. // // Возвращаемое значение: // Структура - "ИмяОбщегоТипа", "Метаданные", "СтрокаОписания", "ТипЯзыка", "ВиртуальнаяТаблица". // Функция НоваяТаблицаДополнительныхТипов() Экспорт ТаблицаСтруктурТипа = Новый ТаблицаЗначений; ТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка")); ТаблицаСтруктурТипа.Колонки.Добавить("Метаданные"); //ТаблицаСтруктурТипа.Колонки.Добавить("ВключатьСвойства", Новый ОписаниеТипов("Булево")); ТаблицаСтруктурТипа.Колонки.Добавить("НеВключатьМетоды", Новый ОписаниеТипов("Булево")); Возврат ТаблицаСтруктурТипа; КонецФункции // Получает допустимые типы (строку) из таблицы структур типа. // // Параметры: // ТаблицаТипов - ТаблицаЗначений. // // Возвращаемое значение: // Строка. // Функция ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов) Экспорт СтрокаСериализованныхТипов = ""; Для Каждого СтруктураТипа Из ТаблицаТипов Цикл СтрокаСериализованныхТипов = СтрокаСериализованныхТипов + ";" + СтруктураТипаВСтрокуВнутр(СтруктураТипа); КонецЦикла; СтрокаСериализованныхТипов = Сред(СтрокаСериализованныхТипов, 2); Возврат СтрокаСериализованныхТипов; КонецФункции Функция ДопустимыеТипыИзОписанияТипов(ОписаниеТипов) Экспорт ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов); ДопустимыеТипы = ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов); Возврат ДопустимыеТипы; КонецФункции // Получает представление допустимых типов. // // Параметры: // ДопустимыеТипы - Строка. // // Возвращаемое значение: // СтрокаПредставления - Строка. // Функция ПредставлениеДопустимыхТипов(ДопустимыеТипы) Экспорт ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы); СтрокаПредставления = ""; Для Каждого СтруктураТипа Из ТаблицаТипов Цикл СтрокаПредставления = СтрокаПредставления + ", " + ИмяТипаИзСтруктурыТипа(СтруктураТипа); ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); Если ТипМетаданных = Тип("КвалификаторыДаты") Тогда Квалификаторы = СтруктураТипа.Метаданные; Если Квалификаторы.ЧастиДаты = ЧастиДаты.Время Тогда ПредставлениеСоставаДаты = "В"; ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.Дата Тогда ПредставлениеСоставаДаты = "Д"; ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда ПредставлениеСоставаДаты = "ДВ"; КонецЕсли; СтрокаПредставления = СтрокаПредставления + "(" + ПредставлениеСоставаДаты + ")"; ИначеЕсли ТипМетаданных = Тип("КвалификаторыСтроки") Тогда Квалификаторы = СтруктураТипа.Метаданные; СтрокаПредставления = СтрокаПредставления + "(" + Квалификаторы.Длина + "," + ?(Квалификаторы.ДопустимаяДлина = ДопустимаяДлина.Фиксированная, "Ф", "П") + ")"; ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда Квалификаторы = СтруктураТипа.Метаданные; СтрокаПредставления = СтрокаПредставления + "(" + ?(Квалификаторы.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, "Н", "") + Квалификаторы.Разрядность + "," + Квалификаторы.РазрядностьДробнойЧасти + ")"; КонецЕсли; КонецЦикла; СтрокаПредставления = Сред(СтрокаПредставления, 3); Возврат СтрокаПредставления; КонецФункции // ПредставлениеДопустимыхТипов() // Получает структуру типа из значения. // // Параметры: // Значение - Произвольный; // *ЯзыкПрограммы - Число, *0; // *ШаблонСтруктурыТипа - Структура, СтрокаТаблицыЗначений, *Неопределено - содержит значения по умолчанию для новой структуры типа. // // Возвращаемое значение: // см. НоваяСтруктураТипа() - // Функция СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт Если мМассивТиповСМетаданными.Найти(ТипЗнч(Значение)) <> Неопределено Тогда Если ШаблонСтруктурыТипа = Неопределено Тогда ШаблонСтруктурыТипа = Новый Структура; КонецЕсли; Если ТипЗнч(ШаблонСтруктурыТипа) = Тип("Структура") Тогда Если Ложь Или Не ШаблонСтруктурыТипа.Свойство("Метаданные") Или ШаблонСтруктурыТипа.Метаданные = Неопределено Тогда ШаблонСтруктурыТипа.Вставить("Метаданные", Значение); КонецЕсли; КонецЕсли; КонецЕсли; СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗнч(Значение), ЯзыкПрограммы, ШаблонСтруктурыТипа); Если СтруктураТипа.ИмяОбщегоТипа = "COMОбъект" Тогда СтруктураТипа.ИмяОбщегоТипа = ПолноеИмяТипаCOMОбъекта(Значение); //ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПеречислимоеСвойствоОбъектовМетаданных" Тогда // // Не работает. Оказывается одно ПеречислимоеСвойствоОбъектовМетаданных может иметь много экземпляров // СтрокиСвойствПеречислений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "ПеречислимыеСвойстваОбъектовМетаданных")); // Для Каждого СтрокиСвойстваПеречисления Из СтрокиСвойствПеречислений Цикл // Если Метаданные.СвойстваОбъектов[СтрокиСвойстваПеречисления.Слово] = Значение Тогда // СтруктураТипа.ИмяОбщегоТипа = "ПеречислениеМетаданных" + СтрокиСвойстваПеречисления.Слово; // Прервать; // КонецЕсли; // КонецЦикла; КонецЕсли; ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; //Если Ложь // Или (Истина // И ИмяОбщегоТипа = "СтрокаТаблицыЗначений" // И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ТаблицаЗначений")) // Или (Истина // И ИмяОбщегоТипа = "СтрокаДереваЗначений" // И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ДеревоЗначений")) // Или (Истина // И ИмяОбщегоТипа = "ВыборкаИзРезультатаЗапроса" // И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("РезультатЗапроса")) //Тогда // Попытка // СтруктураТипа.Метаданные = Значение.Владелец(); // Исключение // // Строка была удалена из коллекции // КонецПопытки; //КонецЕсли; Если Ложь Или ИмяОбщегоТипа = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Или ИмяОбщегоТипа = "ВнешнийОтчетОбъект.<Имя внешнего отчета>" Тогда МетаданныеЗначения = Значение.Метаданные(); ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"; ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(ТипЗнч(Значение), МетаданныеЗначения, ЛиНеУчитыватьПодтип); СтруктураТипа.Метаданные = МетаданныеЗначения; КлючПоиска = Новый Структура("Слово", ИмяОбщегоТипа); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово; Если СтруктураТипа.СтрокаОписания = Неопределено Тогда СтруктураТипа.СтрокаОписания = НайденныеСтроки[0]; КонецЕсли; КонецЕсли; КонецЕсли; Если Ложь Или ИмяОбщегоТипа = "Форма" Или ИмяОбщегоТипа = "ПолеВвода" //Или ИмяОбщегоТипа = "КолонкаТабличногоПоля" // в другом месте делаем Или ИмяОбщегоТипа = "ТабличноеПоле" Или ИмяОбщегоТипа = "УправляемаяФорма" Или ИмяОбщегоТипа = "ФормаКлиентскогоПриложения" Или ИмяОбщегоТипа = "ДекорацияФормы" Или ИмяОбщегоТипа = "ПолеФормы" Или ИмяОбщегоТипа = "ГруппаФормы" Или ИмяОбщегоТипа = "ТаблицаФормы" Тогда ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипа, Значение); Если ИмяОбщегоТипаРасширения <> Неопределено Тогда СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения; КонецЕсли; КонецЕсли; Если ИмяОбщегоТипа = "Форма" Тогда СтруктураТипа.ДержательМетаданных = Значение; КонецЕсли; Возврат СтруктураТипа; КонецФункции //. Мультиметка638663811 // Параметры: // Значение - ? - // ИмяОбщегоТипа - Строка, Строка - // Возвращаемое значение: // ? - Функция ИмяТипаРасширенияЭлементаФормы(БазовоеИмяОбщегоТипа, ЭлементИлиФорма = Неопределено) Экспорт ИмяОбщегоТипаРасширения = Неопределено; РасширяющийТип = Неопределено; Если Ложь Или БазовоеИмяОбщегоТипа = "УправляемаяФорма" Или БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения" Тогда БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения"; КлючОсновногоОбъекта = ирОбщий.КлючОсновногоОбъектаФормыЛкс(ЭлементИлиФорма); Если КлючОсновногоОбъекта <> Неопределено Тогда СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(КлючОсновногоОбъекта); ИмяОбщегоТипаОбъекта = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; Если Найти(ИмяОбщегоТипаОбъекта, "Ссылка.") > 0 Тогда Если Ложь Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Справочник") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Документ") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "ПланВидовХарактеристик") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Задача") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "БизнесПроцесс") Тогда РасширяющийТип = СтрЗаменить(ИмяОбщегоТипаОбъекта, "Ссылка.", "Объект."); Иначе РасширяющийТип = "СсылочныйОбъект"; КонецЕсли; Иначе РасширяющийТип = СтрЗаменить(СтруктураРасширяющегоТипа.ИмяОбщегоТипа, "КлючЗаписи.", "Запись."); КонецЕсли; Иначе Попытка Пустышка = ЭлементИлиФорма.Параметры.РежимВыбора; ЭтоФормаДинамическогоСписка = ТипЗнч(ЭлементИлиФорма.Список) = Тип("ДинамическийСписок"); Исключение ЭтоФормаДинамическогоСписка = Ложь; КонецПопытки; Если ЭтоФормаДинамическогоСписка Тогда РасширяющийТип = "ДинамическийСписок"; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или БазовоеИмяОбщегоТипа = "ДекорацияФормы" Или БазовоеИмяОбщегоТипа = "ПолеФормы" Или БазовоеИмяОбщегоТипа = "ГруппаФормы" Тогда Если ТипЗнч(ЭлементИлиФорма.Вид) <> Тип("Строка") Тогда ИмяВида = ПолучитьПолноеИмяПредопределенногоЗначения(ЭлементИлиФорма.Вид); Иначе ИмяВида = ЭлементИлиФорма.Вид; КонецЕсли; РасширяющийТип = ирОбщий.ПоследнийФрагментЛкс(ИмяВида); ИначеЕсли БазовоеИмяОбщегоТипа = "ТаблицаФормы" Тогда РасширяющийТип = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ЭлементИлиФорма); Если РасширяющийТип = "Список" Тогда РасширяющийТип = "ДинамическийСписок"; КонецЕсли; ИначеЕсли БазовоеИмяОбщегоТипа = "Форма" Тогда #Если Клиент Тогда ОсновнойРеквизитФормы = ИмяОсновногоРеквизитаФормы(ЭлементИлиФорма); Если ЗначениеЗаполнено(ОсновнойРеквизитФормы) Тогда СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(ЭлементИлиФорма[ОсновнойРеквизитФормы]); РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; КонецЕсли; #КонецЕсли Иначе Попытка ДанныеЭлементаФормы = ЭлементИлиФорма.Значение; Исключение // Случается из-за особенностей платформы. Иногда она убирает это свойство из элемента управления. КонецПопытки; СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(ДанныеЭлементаФормы); РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; Если ирОбщий.СтрКончаетсяНаЛкс(РасширяющийТип, ".<Имя табличной части>") Тогда РасширяющийТип = "ТабличнаяЧасть"; КонецЕсли; Попытка Пустышка = Тип("Перечисление" + СтруктураРасширяющегоТипа.ИмяОбщегоТипа); РасширяющийТип = "Системное перечисление"; Исключение КонецПопытки; КонецЕсли; Если РасширяющийТип <> Неопределено Тогда Если РасширяющийТип = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Тогда РасширяющийТип = "ОбработкаОбъект.<Имя обработки>"; ИначеЕсли РасширяющийТип = "ВнешнийОтчетОбъект.<Имя внешнего отчета>" Тогда РасширяющийТип = "ОтчетОбъект.<Имя отчета>"; КонецЕсли; СтруктураКлюча = Новый Структура("РасширяющийТип, ОсновнойТип", РасширяющийТип, БазовоеИмяОбщегоТипа); МассивНайденных = ТаблицаРасширенийТипов.НайтиСтроки(СтруктураКлюча); Если МассивНайденных.Количество() > 0 Тогда ИмяОбщегоТипаРасширения = МассивНайденных[0].Расширение; КонецЕсли; КонецЕсли; Возврат ИмяОбщегоТипаРасширения; КонецФункции // <Описание функции> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция УникальныйИдентификаторИзСтроки(Текст) Экспорт Цифра = "[a-fA-F0-9]"; RegExp.Pattern = "(" + ирОбщий.СтрокаПовторомЛкс(Цифра, 32) + ")|(" + ирОбщий.СтрокаПовторомЛкс(Цифра, 8) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 12) + ")"; Вхождения = RegExp.НайтиВхождения(Текст); Если Вхождения.Количество() > 0 Тогда Вхождение = Вхождения[0]; Если Не ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Вхождение.SubMatches(1)) Тогда УникальныйИдентификатор = Новый УникальныйИдентификатор(Вхождение.SubMatches(1)); Иначе УникальныйИдентификатор = Новый УникальныйИдентификатор(ирОбщий.ПолучитьГУИДПрямойИзИнверсногоЛкс(Вхождение.SubMatches(0))); КонецЕсли; КонецЕсли; Возврат УникальныйИдентификатор; КонецФункции // Неполный сериализатор структуры типа. // // Параметры: // СтруктураТипа - Структура. // // Возвращаемое значение: // Строка. // Функция СтруктураТипаВСтрокуВнутр(СтруктураТипа) Экспорт ОписательТипа = Новый Структура("ИмяОбщегоТипа, Метаданные"); ЗаполнитьЗначенияСвойств(ОписательТипа, СтруктураТипа, "ИмяОбщегоТипа"); ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); Если ТипМетаданных = Тип("ОбъектМетаданныхКонфигурация") Тогда //ОписательТипа.Метаданные = СтруктураТипа.Метаданные.ПолноеИмя(); ИначеЕсли ТипМетаданных = Тип("ОбъектМетаданных") Тогда ОписательТипа.Метаданные = СтруктураТипа.Метаданные.ПолноеИмя(); ИначеЕсли Ложь Или ТипМетаданных = Тип("КвалификаторыДаты") Или ТипМетаданных = Тип("КвалификаторыСтроки") Или ТипМетаданных = Тип("КвалификаторыЧисла") Тогда Поток = Новый ЗаписьXML; Поток.УстановитьСтроку(); СериализаторXDTO.ЗаписатьXML(Поток, СтруктураТипа.Метаданные); ОписательТипа.Метаданные = Новый ХранилищеЗначения(Поток.Закрыть()); Иначе //ОписательТипа.Метаданные = СтруктураТипа.Метаданные; КонецЕсли; Результат = ЗначениеВСтрокуВнутр(ОписательТипа); Возврат Результат; КонецФункции // СтруктураТипаВСтрокуВнутр() // Зависит от текущего языка системы. Поддерживаются Рус и Анг языки. // // Параметры: // КонкрентыйТип - Тип - // МетаданныеТипа - ОбъектМетаданных - // ЛиНеУчитыватьПодтип - Булево - // // Возвращаемое значение: // Строка - // Функция ИмяОбщегоТипаИзТипаЗначенияСМетаданными(Знач КонкрентыйТип, Знач МетаданныеТипа, Знач ЛиНеУчитыватьПодтип) КонкрентыйТип = НРег(КонкрентыйТип); Если Ложь Или Найти(КонкрентыйТип, "(точка маршрута)") > 0 Или Найти(КонкрентыйТип, "(route point)") > 0 Тогда ИмяОбщегоТипа = "ТочкаМаршрутаБизнесПроцессаСсылка.<Имя бизнес-процесса>"; Возврат ИмяОбщегоТипа; КонецЕсли; ИмяОбщегоТипа = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеТипа); Подтип = ""; ИмяЭлементаПодтипа = ""; Если ЛиНеУчитыватьПодтип Тогда Подтип = ""; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "объект:") > 0 Или Найти(КонкрентыйТип, "object:") > 0 Тогда //Если Истина // И Не ИмяОбщегоТипа = "ВнешняяОбработка" // И Не ИмяОбщегоТипа = "ВнешнийОтчет" //Тогда Подтип = "Объект"; //КонецЕсли; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "выборка:") > 0 Или Найти(КонкрентыйТип, "selection:") > 0 Тогда Подтип = "Выборка"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "список:") > 0 Или Найти(КонкрентыйТип, "list:") > 0 Тогда Подтип = "Список"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "менеджер:") > 0 Или Найти(КонкрентыйТип, "manager:") > 0 Тогда Подтип = "Менеджер"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "менеджер значения:") > 0 Или Найти(КонкрентыйТип, "value manager:") > 0 Тогда Подтип = "МенеджерЗначения"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "менеджер ws-ссылки:") > 0 Или Найти(КонкрентыйТип, "ws-reference manager:") > 0 Тогда Подтип = "Менеджер"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "табличная часть:") > 0 Или Найти(КонкрентыйТип, "tabular section:") > 0 Тогда Подтип = "ТабличнаяЧасть"; ИмяЭлементаПодтипа = "<Имя табличной части>"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "табличная часть строка:") > 0 Или Найти(КонкрентыйТип, "tabular section row:") > 0 Тогда Подтип = "ТабличнаяЧастьСтрока"; ИмяЭлементаПодтипа = "<Имя табличной части>"; ИначеЕсли Ложь // Связано со следующим условием! Или Найти(КонкрентыйТип, "виды субконто:") > 0 Или Найти(КонкрентыйТип, "ext dimension types:") > 0 Тогда Подтип = "ВидыСубконто"; ИначеЕсли Ложь // Связано со следующим условием! Или Найти(КонкрентыйТип, "ext dimensions:") > 0 Или Найти(КонкрентыйТип, "субконто:") > 0 Тогда Подтип = "Субконто"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "виды субконто строка:") > 0 Или Найти(КонкрентыйТип, "ext dimension types row:") > 0 Тогда Подтип = "ВидыСубконтоСтрока"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "набор записей:") > 0 Или Найти(КонкрентыйТип, "record set:") > 0 Тогда Подтип = "НаборЗаписей"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "ключ записи:") > 0 Или Найти(КонкрентыйТип, "record key:") > 0 Тогда Подтип = "КлючЗаписи"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "запись:") > 0 Или Найти(КонкрентыйТип, "record:") > 0 Тогда Подтип = "Запись"; ИначеЕсли Ложь Или Найти(КонкрентыйТип, "менеджер записи:") > 0 Или Найти(КонкрентыйТип, "record manager:") > 0 Тогда Подтип = "МенеджерЗаписи"; // Пришлось сделать так из-за изменения представления ссылочных типов в 8.2 http://partners.v8.1c.ru/forum/thread.jsp?id=830683#830683 //ИначеЕсли Найти(КонкрентыйТип, "ссылка:") > 0 Тогда Иначе//Если Найти(КонкрентыйТип, ":") = 0 Тогда Подтип = "Ссылка"; КонецЕсли; СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(ИмяОбщегоТипа); СтрокаВида = ТаблицаИменЭлементовКоллекций.Найти(СтрокаКорневогоТипа.Множественное, "ИмяКоллекции"); Если СтрокаВида <> Неопределено Тогда Если ИмяОбщегоТипа = "ВнешнийИсточникДанных" Тогда ИмяОбщегоТипа = ИмяОбщегоТипа + "Таблица" + Подтип + "." + СтрокаВида.ИмяЭлементаКоллекции; СтрокаВида = ТаблицаИменЭлементовКоллекций.Найти("Таблицы", "ИмяКоллекции"); ИмяОбщегоТипа = ИмяОбщегоТипа + "." + СтрокаВида.ИмяЭлементаКоллекции; Иначе ИмяОбщегоТипа = ИмяОбщегоТипа + Подтип + "." + СтрокаВида.ИмяЭлементаКоллекции; КонецЕсли; КонецЕсли; Если ИмяЭлементаПодтипа <> "" Тогда ИмяОбщегоТипа = ИмяОбщегоТипа + "." + ИмяЭлементаПодтипа; КонецЕсли; Возврат ИмяОбщегоТипа; КонецФункции //. // Возвращаемое значение: // Структура - Функция ИменаТиповМетаданныхСМенеджерами() Экспорт Если мИменаТиповМетаданныхСМенеджерами <> Неопределено Тогда Возврат мИменаТиповМетаданныхСМенеджерами; КонецЕсли; мИменаТиповМетаданныхСМенеджерами = Новый Структура; ИмяДочернегоТипаМД = "МодульМенеджера"; Для Каждого СтрокаТипаМетаОбъекта Из ирКэш.ТипыМетаОбъектов(Истина, Ложь) Цикл ОтборСвойств = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова", "ОбъектМетаданных" + СтрокаТипаМетаОбъекта.Единственное, 0, "", НРег(ИмяДочернегоТипаМД), "Свойство"); Если ТаблицаКонтекстов.НайтиСтроки(ОтборСвойств).Количество() = 0 Тогда Продолжить; КонецЕсли; мИменаТиповМетаданныхСМенеджерами.Вставить(СтрокаТипаМетаОбъекта.Множественное); КонецЦикла; Возврат мИменаТиповМетаданныхСМенеджерами; КонецФункции // Получает структуру типа из конкретного типа. // // Параметры: // КонкрентыйТип - Тип, Строка - тип либо его представление (для неметаданных типов); // *ЯзыкПрограммы - Число, *0; // *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа. // // Возвращаемое значение: // см. НоваяСтруктураТипа() - // Функция СтруктураТипаИзКонкретногоТипа(КонкрентыйТип, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено) Экспорт СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.Метаданные = мМетаданные; Если ШаблонСтруктурыТипа <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа); КонецЕсли; Если ЯзыкПрограммы = 1 И КонкрентыйТип = Тип("ТаблицаЗначений") Тогда СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица"; // Для ускорения ИначеЕсли КонкрентыйТип = Тип("Число") Тогда СтруктураТипа.ИмяОбщегоТипа = "Число"; ИначеЕсли КонкрентыйТип = Тип("Строка") Тогда СтруктураТипа.ИмяОбщегоТипа = "Строка"; ИначеЕсли КонкрентыйТип = Тип("Булево") Тогда СтруктураТипа.ИмяОбщегоТипа = "Булево"; ИначеЕсли КонкрентыйТип = Тип("ОписаниеТипов") Тогда СтруктураТипа.ИмяОбщегоТипа = "ОписаниеТипов"; ИначеЕсли КонкрентыйТип = Тип("Массив") Тогда СтруктураТипа.ИмяОбщегоТипа = "Массив"; ИначеЕсли КонкрентыйТип = Тип("Структура") Тогда СтруктураТипа.ИмяОбщегоТипа = "Структура"; ИначеЕсли КонкрентыйТип = Тип("ОбъектМетаданных") Тогда Если Истина И ШаблонСтруктурыТипа <> Неопределено // было закомментировано И ТипЗнч(ШаблонСтруктурыТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ШаблонСтруктурыТипа.Метаданные.ПолноеИмя()); // Исключения из общего правила Если МассивФрагментов[0] = "ОбщаяФорма" Тогда МассивФрагментов[0] = "Форма"; ИначеЕсли МассивФрагментов[0] = "ОбщийМакет" Тогда МассивФрагментов[0] = "Макет"; КонецЕсли; СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + ": " + МассивФрагментов[МассивФрагментов.ВГраница() - 1]; Иначе СтруктураТипа.ИмяОбщегоТипа = "ОбъектМетаданных"; КонецЕсли; ИначеЕсли Истина И КонкрентыйТип = Тип("КоллекцияОбъектовМетаданных") И ШаблонСтруктурыТипа <> Неопределено И СтруктураТипа.ИмяОбщегоТипа <> "НеизвестныйКонтекст" Тогда // Иначе Если Истина И ТипЗнч(КонкрентыйТип) = Тип("Тип") И КонкрентыйТип <> Тип("КонстантыНабор") // Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=876094#876094 Тогда МетаданныеТипа = мМетаданные.НайтиПоТипу(КонкрентыйТип); КонецЕсли; Если МетаданныеТипа = Неопределено Тогда ПредставлениеТипа = Строка(КонкрентыйТип); Если Найти(ПредставлениеТипа, ":") = 0 Тогда ИдентификаторТипа = ирОбщий.ИдентификаторТипаЛкс(КонкрентыйТип); Иначе // Внешние метаданные ИдентификаторТипа = ""; ПредставлениеТипа = ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"); Если НРег(ПредставлениеТипа) = Нрег("External data processor") Тогда ПредставлениеТипа = "Внешняя обработка"; ИначеЕсли НРег(ПредставлениеТипа) = Нрег("External data processor tabular section") Тогда ПредставлениеТипа = "Внешняя обработка табличная часть"; КонецЕсли; КонецЕсли; Если ИдентификаторТипа <> "" Тогда КлючПоиска = Новый Структура("ИД", ИдентификаторТипа); Иначе //КлючПоиска = Новый Структура("Представление, ТипТипа", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"), "Основной"); КлючПоиска = Новый Структура("Представление", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":")); КонецЕсли; Иначе ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"; ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(КонкрентыйТип, МетаданныеТипа, ЛиНеУчитыватьПодтип); СтруктураТипа.Метаданные = МетаданныеТипа; КлючПоиска = Новый Структура("Слово, ТипТипа", ИмяОбщегоТипа, "Основной"); КонецЕсли; НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово; Если СтруктураТипа.СтрокаОписания = Неопределено Тогда СтруктураТипа.СтрокаОписания = НайденныеСтроки[0]; КонецЕсли; ИначеЕсли Найти(КонкрентыйТип, " ") = 0 Тогда СтруктураТипа.ИмяОбщегоТипа = Строка(КонкрентыйТип); Иначе //ирОбщий.СообщитьЛкс("Невозможно восстановить имя типа """ + КонкрентыйТип + """", СтатусСообщения.Важное); КонецЕсли; КонецЕсли; Возврат СтруктураТипа; КонецФункции // Получает таблицу структур типов из описания типов. // // Параметры: // ОписаниеТипов - ОписаниеТипов - // *ТаблицаТипов - ТаблицаЗначений, *Неопределено - существующая таблица. // // Возвращаемое значение: // ТаблицаЗначений - структур типов. // Функция ТаблицаТиповИзОписанияТипов(ОписаниеТипов, ТаблицаТипов = Неопределено) Экспорт Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; Типы = ОписаниеТипов.Типы(); СлишкомМногоТипов = Типы.Количество() > МаксЧислоТиповДляАнализа(); Для Каждого Тип Из Типы Цикл СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип); СтруктураТипа.Квалификаторы = ОписаниеТипов; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Если СлишкомМногоТипов Тогда Прервать; КонецЕсли; КонецЦикла; Возврат ТаблицаТипов; КонецФункции Функция МаксЧислоТиповДляАнализа() Экспорт Возврат 100; КонецФункции Функция ТаблицаТиповИзЗначения(Значение, ТаблицаТипов = Неопределено, ЯзыкПрограммы = 0) Экспорт Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; СтруктураТипа = СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Возврат ТаблицаТипов; КонецФункции // Получает объект по ссылке, кэшируя результат в соответствии. // // Параметры: // Ссылка - Ссылка; // ПринудительноОбновить - Булево, *Ложь. // // Возвращаемое значение: // Объект. // Функция КэшОбъект(Ссылка, ПринудительноОбновить = Ложь) Экспорт ТипСсылки = ТипЗнч(Ссылка); Кэш = КэшОбъектов[ТипСсылки]; Если Кэш = Неопределено Тогда Кэш = Новый Соответствие; КэшОбъектов[ТипСсылки] = Кэш; КонецЕсли; Если Не ПринудительноОбновить Тогда Результат = Кэш[Ссылка]; КонецЕсли; Если Результат = Неопределено Тогда Результат = Ссылка.ПолучитьОбъект(); Кэш[Ссылка] = Результат; КонецЕсли; Возврат Результат; КонецФункции // Получает строку конкретного типа. // // Параметры: // СтруктураТипа - Структура - описание типа. // // Возвращаемое значение: // Строка - конкрентого типа. // Функция ИмяТипаИзСтруктурыТипа(Знач СтруктураТипа, Знач Подробное = Истина) Экспорт КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа; МаркерРасширенияФормы = "РасширениеФормы"; Если Лев(КонкретныйТип, СтрДлина(МаркерРасширенияФормы)) = МаркерРасширенияФормы Тогда КонкретныйТип = "Форма"; КонецЕсли; Если Подробное Тогда Если КонкретныйТип = "Форма" И ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда КонкретныйТип = КонкретныйТип + "[" + ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные) + "]"; ИначеЕсли КонкретныйТип = "ОбщийМодуль" И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда КонкретныйТип = КонкретныйТип + "[" + СтруктураТипа.Метаданные.Имя + "]"; КонецЕсли; КонецЕсли; //Если Лев(КонкретныйТип, СтрДлина(МаркерКоллекцииМетаданных)) = МаркерКоллекцииМетаданных Тогда // КонкретныйТип = МаркерКоллекцииМетаданных; //КонецЕсли; ОбъектМД = СтруктураТипа.Метаданные; Если Истина И ТипЗнч(ОбъектМД) = Тип("КоллекцияОбъектовМетаданных") И ОбъектМД.Количество() > 0 Тогда ОбъектМД = ОбъектМД[0].Родитель(); КонецЕсли; ТипМетаданных = ТипЗнч(ОбъектМД); Если ТипМетаданных = Тип("ОбъектМетаданных") Тогда ПолноеИмя = ОбъектМД.ПолноеИмя(); МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя); Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда // Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект МассивФрагментов.Вставить(0, "Имя"); МассивФрагментов.Вставить(0, ""); КонецЕсли; Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина); КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]); КонецЦикла; ИначеЕсли Истина И ЭтоИнтеграция И (Ложь Или ТипМетаданных = Тип("СправочникСсылка.ОбъектыМетаданных2iS") Или ТипМетаданных = Тип("СправочникСсылка.СвойстваМетаданных2iS")) Тогда ОбъектМД = КэшОбъект(ОбъектМД); ПолноеИмя = ОбъектМД.ПолноеИмя; МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя); Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда // Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект МассивФрагментов.Вставить(0, "Имя"); МассивФрагментов.Вставить(0, ""); КонецЕсли; Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина); КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]); КонецЦикла; //ИначеЕсли ТипЗнч(СтруктураТипа.Метаданные) = Тип("Соответствие") Тогда // Для Каждого ЭлементВида Из СтруктураТипа.Метаданные Цикл // КонкретныйТип = СтрЗаменить(КонкретныйТип, ЭлементВида.Ключ, ЭлементВида.Значение); // КонецЦикла; ИначеЕсли Ложь Или КонкретныйТип = "НеизвестныйКонтекст" Или КонкретныйТип = "Произвольный" Тогда КонкретныйТип = "?"; КонецЕсли; Попытка Квалификаторы = СтруктураТипа.Квалификаторы; Исключение Квалификаторы = Неопределено; КонецПопытки; Если Истина И Квалификаторы <> Неопределено И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(КонкретныйТип) Тогда ирОбщий.ДобавитьКвалификаторыВПредставлениеТипаЛкс(КонкретныйТип, Тип(КонкретныйТип), СтруктураТипа.Квалификаторы); КонецЕсли; Возврат КонкретныйТип; КонецФункции // Десериализатор структуры типа из неполной сериализации. // // Параметры: // СтрокаСтруктурыТипа - Строка. // // Возвращаемое значение: // СтруктураТипа - Структура. // Функция СтруктураТипаИзСтрокиВнутр(СтрокаСтруктурыТипа) Экспорт СтруктураТипа = НоваяСтруктураТипа(); Если ПустаяСтрока(СтрокаСтруктурыТипа) Тогда Возврат СтруктураТипа; КонецЕсли; Успех = Ложь; Попытка ОписательТипа = ЗначениеИзСтрокиВнутр(СтрокаСтруктурыТипа); Успех = Истина; Исключение ОписательТипа = НоваяСтруктураТипа(); ОписательТипа.ИмяОбщегоТипа = "<Ошибка преобразования>"; КонецПопытки; Если Успех Тогда СтруктураТипа.ИмяОбщегоТипа = ОписательТипа.ИмяОбщегоТипа; Если ТипЗнч(ОписательТипа.Метаданные) = Тип("Строка") Тогда СтруктураТипа.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ОписательТипа.Метаданные); ИначеЕсли ТипЗнч(ОписательТипа.Метаданные) = Тип("ХранилищеЗначения") Тогда Поток = Новый ЧтениеXML; Поток.УстановитьСтроку(ОписательТипа.Метаданные.Получить()); // Тут тормоз СтруктураТипа.Метаданные = СериализаторXDTO.ПрочитатьXML(Поток); Иначе СтруктураТипа.Метаданные = ОписательТипа.Метаданные; КонецЕсли; КонецЕсли; Возврат СтруктураТипа; КонецФункции // СтруктураТипаВСтрокуВнутр() // Получает новую структуру типа. // // Параметры: // ИмяОбщегоТипа - Строка - // // Возвращаемое значение: // Структура - : // *ИмяОбщегоТипа - Строка // *Метаданные // *СтрокаОписания - СтрокаТаблицыЗначений // *ТипЯзыка - Строка // *ВиртуальнаяТаблица - Структура // Функция НоваяСтруктураТипа(ИмяОбщегоТипа = "НеизвестныйКонтекст") Экспорт // Мультиметка73327878378078 Возврат Новый Структура("ИмяОбщегоТипа, Метаданные, СтрокаОписания, ТипЯзыка, Конструктор, ВиртуальнаяТаблица, ДополнительныеТипы, ДержательМетаданных, Квалификаторы", ИмяОбщегоТипа, Неопределено, Неопределено, "", Ложь, Новый Структура("Выражение, НомерСтроки", "", 0)); КонецФункции Функция НоваяТаблицаТипов() Экспорт Если мТаблицаТипов = Неопределено Тогда // Мультиметка73327878378078 мТаблицаТипов = Новый ТаблицаЗначений; мТаблицаТипов.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка")); мТаблицаТипов.Колонки.Добавить("Метаданные"); мТаблицаТипов.Колонки.Добавить("СтрокаОписания"); // СтрокаТаблицыЗначений мТаблицаТипов.Колонки.Добавить("ТипЯзыка", Новый ОписаниеТипов("Строка")); мТаблицаТипов.Колонки.Добавить("ВиртуальнаяТаблица"); мТаблицаТипов.Колонки.Добавить("Конструктор", Новый ОписаниеТипов("Булево")); мТаблицаТипов.Колонки.Добавить("ДополнительныеТипы"); мТаблицаТипов.Колонки.Добавить("ДержательМетаданных"); мТаблицаТипов.Колонки.Добавить("Квалификаторы"); мТаблицаТипов.Колонки.Добавить("Детальность"); КонецЕсли; Возврат мТаблицаТипов.Скопировать(); КонецФункции // Добавляет структуру типа в таблицу структур типов с поглощением. // // Параметры: // ТаблицаПриемник - ТаблицаЗначений - ; // ОписаниеТипов - Структура, ТаблицаЗначений, ОписаниеТипов, Массив[Структура] - считаем что внутри этой коллекции типы не пересекаются. // Функция ДобавитьВТаблицуТипов(ТаблицаПриемник = Неопределено, Знач ОписаниеТипов, Знач ПередаватьДополнительныеТипы = Ложь) Экспорт Если ТаблицаПриемник = Неопределено Тогда ТаблицаПриемник = НоваяТаблицаТипов(); КонецЕсли; ТипОписания = ТипЗнч(ОписаниеТипов); Если ТипОписания = Тип("ОписаниеТипов") Тогда //! ОписаниеТипов=0 // ОписаниеТипов ТаблицаИсточник = Новый Массив; Для Каждого Тип Из ОписаниеТипов.Типы() Цикл СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип); // Циклическая ссылка СтрокаОписания СтруктураТипа.Вставить("Детальность"); ТаблицаИсточник.Добавить(СтруктураТипа); КонецЦикла; ИначеЕсли Истина И ТипОписания <> Тип("ТаблицаЗначений") И ТипОписания <> Тип("Массив") Тогда ТаблицаИсточник = Новый Массив; ТаблицаИсточник.Добавить(ОписаниеТипов); Иначе ТаблицаИсточник = ОписаниеТипов; // см. НоваяТаблицаТипов() КонецЕсли; КоличествоТипов = ТаблицаИсточник.Количество(); Если КоличествоТипов > МаксЧислоТиповДляАнализа() Тогда // Для подстраховки. Нужно в вызывающем контексте это контролировать Возврат ТаблицаПриемник; КонецЕсли; НужноВытеснять = КоличествоТипов > 0; Детальность = Неопределено; ИсключаемыеСвойства = Неопределено; Если Не ПередаватьДополнительныеТипы Тогда ИсключаемыеСвойства = "ДополнительныеТипы"; КонецЕсли; Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл Если Истина //И НужноВытеснять И СтрокаИсточника.ИмяОбщегоТипа = "НеизвестныйКонтекст" И СтрокаИсточника.СтрокаОписания = Неопределено Тогда Продолжить; КонецЕсли; Если Истина И ТипЗнч(СтрокаИсточника) = Тип("Структура") И Не СтрокаИсточника.Свойство("Детальность", Детальность) Тогда СтрокаИсточника.Вставить("Детальность", Неопределено); Иначе Детальность = СтрокаИсточника.Детальность; КонецЕсли; Если Детальность = Неопределено Тогда ОбновитьДетальностьСтруктурыТипа(СтрокаИсточника); КонецЕсли; Если НужноВытеснять Тогда Если Найти(СтрокаИсточника.ИмяОбщегоТипа, "Массив") = 1 Тогда ДобавлятьТип = Истина; Для Каждого СтрокаПриемника Из ТаблицаПриемник Цикл Если Найти(СтрокаПриемника.ИмяОбщегоТипа, "Массив") = 1 Тогда ЕстьВложенныеИсточника = Найти(СтрокаИсточника.ИмяОбщегоТипа, "[") > 0; ЕстьВложенныеПриемника = Найти(СтрокаПриемника.ИмяОбщегоТипа, "[") > 0; Если Истина И ЕстьВложенныеИсточника И ЕстьВложенныеПриемника Тогда ТипыЭлементовИсточника = ТипыЭлементовКоллекции(СтрокаИсточника,, Ложь); СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(ТипыЭлементовИсточника); ТипыЭлементовПриемника = ТипыЭлементовКоллекции(СтрокаПриемника,, Ложь); Для Каждого ИмяТипа Из ТипыЭлементовПриемника Цикл Если СписокЗначений.НайтиПоЗначению(ИмяТипа) = Неопределено Тогда СписокЗначений.Добавить(ИмяТипа); КонецЕсли; КонецЦикла; СписокЗначений.СортироватьПоЗначению(); СтрокаПриемника.ИмяОбщегоТипа = "Массив[" + ирОбщий.СтрСоединитьЛкс(СписокЗначений.ВыгрузитьЗначения()) + "]"; ИначеЕсли ЕстьВложенныеИсточника Тогда СтрокаПриемника.ИмяОбщегоТипа = СтрокаИсточника.ИмяОбщегоТипа; КонецЕсли; ДобавлятьТип = Ложь; Прервать; КонецЕсли; КонецЦикла; Если Не ДобавлятьТип Тогда Прервать; КонецЕсли; Иначе ИменаПоиска = "ИмяОбщегоТипа"; КлючПоиска = Новый Структура(ИменаПоиска); ЗаполнитьЗначенияСвойств(КлючПоиска, СтрокаИсточника, ИменаПоиска); Найденные = ТаблицаПриемник.НайтиСтроки(КлючПоиска); Если СтрокаИсточника.Детальность > 0 Тогда Для Каждого СтрокаПриемника Из ТаблицаПриемник.НайтиСтроки(Новый Структура("Детальность", 0)) Цикл ТаблицаПриемник.Удалить(СтрокаПриемника); КонецЦикла; Если ирОбщий.СтрНачинаетсяСЛкс(СтрокаИсточника.ИмяОбщегоТипа, "РасширениеФормы", Истина) Тогда // Учитывам регистр для ускорения НайденныеФормы = ТаблицаПриемник.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", "Форма")); ирОбщий.ДополнитьМассивЛкс(Найденные, НайденныеФормы); КонецЕсли; КонецЕсли; Если Найденные.Количество() > 0 Тогда СтрокаПриемника = Найденные[0]; // Считаем что "Найденные" всегда содержит не более одной строки Если Ложь Или СтрокаПриемника.Метаданные = СтрокаИсточника.Метаданные Или ТипЗнч(СтрокаПриемника.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ОбъектМетаданныхКонфигурация") // Почему то часто равенство значений не выполняется Или СтрокаПриемника.Детальность > СтрокаИсточника.Детальность Тогда Продолжить; КонецЕсли; Если СтрокаПриемника.Детальность < СтрокаИсточника.Детальность Тогда ТаблицаПриемник.Удалить(СтрокаПриемника); Иначе // Далее детальности равны Если Ложь Или ТаблицаПриемник.Количество() > 10 Или СтрокаПриемника.ИмяОбщегоТипа = "Строка" // Для ускорения вычисления типа результата ИмяМодуляИзСтруктурыТипа() Или СтрокаПриемника.ИмяОбщегоТипа = "Число" Или СтрокаПриемника.ИмяОбщегоТипа = "Булево" Или СтрокаПриемника.ИмяОбщегоТипа = "Тип" Тогда Продолжить; КонецЕсли; Если Ложь Или (Истина И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ТаблицаЗначений") И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("ТаблицаЗначений")) Или (Истина И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ДеревоЗначений") И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("ДеревоЗначений")) Тогда ирОбщий.СкопироватьКолонкиКоллекцииЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные); Продолжить; КонецЕсли; Если Истина И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("ТаблицаЗначений") И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("Структура") Тогда Для Каждого Колонка Из СтрокаИсточника.Метаданные.Колонки Цикл Если Не СтрокаПриемника.Метаданные.Свойство(Колонка.Имя) Тогда СтрокаПриемника.Метаданные.Вставить(Колонка.Имя, ТаблицаТиповИзОписанияТипов(Колонка.ТипЗначения)); КонецЕсли; КонецЦикла; Продолжить; КонецЕсли; Если Ложь Или (Истина И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("Структура") И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("Структура")) Или (Истина И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("Массив") И ТипЗнч(СтрокаПриемника.Метаданные) = Тип("Массив")) Тогда ирОбщий.СкопироватьКоллекциюЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные); Продолжить; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника, , ИсключаемыеСвойства); КонецЦикла; Возврат ТаблицаПриемник; КонецФункции Функция ОбновитьДетальностьСтруктурыТипа(СтруктураТипа) Экспорт ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; Если Ложь Или ИмяОбщегоТипа = "??" Или ИмяОбщегоТипа = "НеизвестныйКонтекст" Тогда Результат = 0; ИначеЕсли Ложь Или ИмяОбщегоТипа = "" // Процедура Или ИмяОбщегоТипа = "Произвольный" Или ИмяОбщегоТипа = "Неопределено" Тогда Результат = 1; Если ИмяОбщегоТипа = "Неопределено" Тогда СтруктураТипа.Метаданные = Неопределено; // Чтобы раньше склеивались типы в ДобавитьВТаблицуТипов КонецЕсли; ИначеЕсли Ложь Или ИмяОбщегоТипа = "Строка" Или ИмяОбщегоТипа = "Число" Или ИмяОбщегоТипа = "Булево" Или ИмяОбщегоТипа = "Дата" Или ИмяОбщегоТипа = "Null" Или ИмяОбщегоТипа = "Тип" //Или ИмяОбщегоТипа = "Примитивный" Тогда Если ТипМетаданных = Тип(ИмяОбщегоТипа) Тогда Результат = 3; Иначе Результат = 2; Если Истина И ИмяОбщегоТипа = "Строка" И ТипМетаданных = Тип("ТаблицаЗначений") Тогда Результат = 5; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипМетаданных = Тип("Неопределено") Или ТипМетаданных = Тип("ОбъектМетаданныхКонфигурация") Или ТипМетаданных = Тип("КоллекцияОбъектовМетаданных") Или ТипМетаданных = Тип("ОбщийМодуль") // Пока платформа не позволяет узнать его имя Тогда Результат = 3; ИначеЕсли ТипМетаданных = Тип("ОбъектМетаданных") Тогда Результат = 4; ИначеЕсли Ложь #Если Клиент Тогда Или ТипМетаданных = Тип("Форма") Или ТипМетаданных = Тип("УправляемаяФорма") #КонецЕсли Тогда Результат = 6; ИначеЕсли ТипМетаданных = Тип("ПостроительЗапроса") Тогда Результат = 7; Иначе Результат = 5; КонецЕсли; СтруктураТипа.Детальность = Результат; Возврат Результат; КонецФункции //. // Параметры: // ТаблицаТипов - ТаблицаЗначений - // МинДетальность - Число - минимальное достаточное значение детальности // Возвращаемое значение: // Булево - Функция ЛиДетальностьТиповДостаточна(ТаблицаТипов, Знач МинДетальность = 3, Знач ВыбратьЛучшийТип = Ложь, выхЛучшийТип = Неопределено, Знач УчитыватьПримитивные = Истина) Экспорт Если Ложь Или ТаблицаТипов = Неопределено Или ТаблицаТипов.Количество() = 0 Тогда Возврат Ложь; КонецЕсли; Счетчик = 1; МинДетальность = МинДетальность - 1; Для Индекс = 1 - ТаблицаТипов.Количество() По 0 Цикл // Обратный обход СтрокаТипа = ТаблицаТипов[-Индекс]; Если Ложь Или СтрокаТипа.Детальность > МинДетальность Или (Истина И УчитыватьПримитивные И (Ложь Или СтрокаТипа.ИмяОбщегоТипа = "Строка" Или СтрокаТипа.ИмяОбщегоТипа = "Число" Или СтрокаТипа.ИмяОбщегоТипа = "Булево" // почему закомментировал? )) Тогда выхЛучшийТип = СтрокаТипа; МинДетальность = СтрокаТипа.Детальность; Если Не ВыбратьЛучшийТип Тогда Прервать; КонецЕсли; КонецЕсли; Если Счетчик = 3 Тогда // Проверяем не больше 3-х, т.к. бесполезных типов обычно очень мало указывают в описании, например Неопределено, Null Прервать; КонецЕсли; Счетчик = Счетчик + 1; КонецЦикла; Возврат выхЛучшийТип <> Неопределено; КонецФункции // Получает массив структур типов из строки допустимых типов. // // Параметры: // ДопустимыеТипы - Строка; // *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа. // // Возвращаемое значение: // Структура - структура типа. // Функция ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы, ШаблонСтруктурыТипа = Неопределено) Экспорт ТаблицаТипов = НоваяТаблицаТипов(); Если ПустаяСтрока(ДопустимыеТипы) Тогда Возврат ТаблицаТипов; КонецЕсли; МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";"); Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл СтруктураТипа = СтруктураТипаИзСтрокиВнутр(СериализованныйТип); Если ШаблонСтруктурыТипа <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа); КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЦикла; Возврат ТаблицаТипов; КонецФункции // Получает описание типов из допустимых типов. // // Параметры: // ДопустимыеТипы - Строка; // ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления. // // Возвращаемое значение: // ОписаниеТипов. // Функция ОписаниеТиповИзДопустимыхТипов(ДопустимыеТипы, ТипЗначенияЭУ = Неопределено) Экспорт ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы); ОписаниеТипов = ОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаТипов, ТипЗначенияЭУ); Возврат ОписаниеТипов; КонецФункции // Получает описание типов из таблицы структур типов. // // Параметры: // ДопустимыеТипы - Строка; // ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления. // // Возвращаемое значение: // ОписаниеТипов. // Функция ОписаниеТиповИзТаблицыСтруктурТипов(ТаблицаТипов, ТипЗначенияЭУ = Неопределено) Экспорт Если ТаблицаТипов = Неопределено Тогда Возврат Новый ОписаниеТипов; КонецЕсли; МассивТипов = Новый Массив; Для Каждого СтруктураТипа Из ТаблицаТипов Цикл СтрокаКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа); Попытка ТекущийТип = Тип(СтрокаКонкретногоТипа); Исключение Продолжить; КонецПопытки; ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); Если ТипМетаданных = Тип("КвалификаторыСтроки") Тогда КвалификаторыСтроки = СтруктураТипа.Метаданные; ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда КвалификаторыЧисла = СтруктураТипа.Метаданные; ИначеЕсли ТипМетаданных = Тип("КвалификаторыДаты") Тогда КвалификаторыДаты = СтруктураТипа.Метаданные; КонецЕсли; Если ТипЗначенияЭУ <> Неопределено Тогда Если Не ТипЗначенияЭУ.СодержитТип(ТекущийТип) Тогда Продолжить; КонецЕсли; КонецЕсли; МассивТипов.Добавить(ТекущийТип); КонецЦикла; ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыСтроки); Возврат ОписаниеТипов; КонецФункции // Получает строку типа метаобъектов по единственному или множественному числу. // // Параметры: // *Единственное - Строка, *Неопределено - единственное число типа; // *Множественное - Строка, *Неопределено - множественное число типа. // *Категория - Число, *Неопределено. // // Возвращаемое значение: // СтрокаТаблицыЗначений - найденная строка типа; // Неопределено - корневой тип не найден. // Функция ОписаниеТипаМетаОбъектов(Знач Единственное = Неопределено, Знач Множественное = Неопределено, Категория = Неопределено) Экспорт СтруктураПоиска = Новый Структура; Если Категория <> Неопределено Тогда СтруктураПоиска.Вставить("Категория", Категория); КонецЕсли; Если Единственное <> Неопределено Тогда СтруктураПоиска.Вставить("НЕдинственное", НРег(Единственное)); КонецЕсли; Если Множественное <> Неопределено Тогда СтруктураПоиска.Вставить("НМножественное", НРег(Множественное)); КонецЕсли; НайденныеСтроки = ТаблицаТиповМетаОбъектов.НайтиСтроки(СтруктураПоиска); Если НайденныеСтроки.Количество() = 0 Тогда Результат = Неопределено; Иначе Результат = НайденныеСтроки[0]; КонецЕсли; Возврат Результат; КонецФункции Процедура ПроверитьЗагрузитьКэшМДСеанса() ПереданныйКэш = ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш; КэшМДСеанса = Неопределено; Если ЗначениеЗаполнено(ПереданныйКэш) Тогда КэшМДСеанса = ПолучитьИзВременногоХранилища(ПереданныйКэш); КонецЕсли; Если КэшМДСеанса = Неопределено Тогда СостояниеРасчета = ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс(); Если СостояниеРасчета <> Неопределено Тогда ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(СостояниеРасчета.ИдентификаторЗадания); КонецЕсли; Если ФоновоеЗадание <> Неопределено Тогда Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда ирОбщий.ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание); КонецЕсли; Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда КэшМДСеанса = ирОбщий.ПрочитатьРезультатФоновогоЗаданияЛкс(СостояниеРасчета.АдресРезультата, СостояниеРасчета.ФормаРезультата); Если КэшМДСеанса = Null Тогда КэшМДСеанса = Неопределено; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если КэшМДСеанса <> Неопределено Тогда #Если Сервер И Не Сервер Тогда КэшМДСеанса = Новый Структура; #КонецЕсли мТаблицаВсехТаблицБД = КэшМДСеанса.ТаблицаВсехТаблицБД; Если КэшМДСеанса.Свойство("ДеревоОбъектовМД") Тогда мДеревоОбъектовМД = КэшМДСеанса.ДеревоОбъектовМД; КонецЕсли; Возврат; КонецЕсли; КонецПроцедуры Функция ДеревоОбъектовМД() Экспорт ПроверитьЗагрузитьКэшМДСеанса(); Если мДеревоОбъектовМД <> Неопределено Тогда #Если Сервер И Не Сервер Тогда мДеревоОбъектовМД = Новый ДеревоЗначений; #КонецЕсли #Если Клиент Тогда Если мДеревоОбъектовМД.Колонки.Найти("КоличествоСтрок") = Неопределено Тогда мДеревоОбъектовМД.Колонки.Добавить("КоличествоСтрок", Новый ОписаниеТипов("Строка, Число")); КонецЕсли; #КонецЕсли Возврат мДеревоОбъектовМД; КонецЕсли; ДеревоОбъектовМД = Новый ДеревоЗначений; ДеревоОбъектовМД.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); ДеревоОбъектовМД.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); ДеревоОбъектовМД.Колонки.Добавить("ПолноеИмяОбъекта", Новый ОписаниеТипов("Строка")); ДеревоОбъектовМД.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число")); ДеревоОбъектовМД.Колонки.Добавить("ЕстьДоступ", Новый ОписаниеТипов("Булево")); ДеревоОбъектовМД.Колонки.Добавить("ПравоПросмотр", Новый ОписаниеТипов("Булево")); ДеревоОбъектовМД.Колонки.Добавить("ТипТаблицы", Новый ОписаниеТипов("Строка")); АнализаторКода = ирОбщий.НовыйАнализаторКодаЛкс(); #Если Сервер И Не Сервер Тогда АнализаторКода = Обработки.ирКлсПолеТекстаПрограммы.Создать(); #КонецЕсли мТаблицаВсехТаблицБД = АнализаторКода.ДоступныеТаблицы.ВыгрузитьКолонки(); мТаблицаВсехТаблицБД.Колонки.Удалить("ПородившийЗапрос"); // Для экономии памяти мТаблицаВсехТаблицБД.Колонки.Добавить("ТипСсылки"); //ТаблицаВсехТаблицБД.Колонки.Добавить("СтруктураКлюча"); Если Метаданные.Константы.Количество() > 0 Тогда ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ирОбщий.ПеревестиСтроку("Константы"),, "Константы"); // Мультиметка0012741388 опираемся на то, что эта таблица БД идет первой в списке КонецЕсли; КоллекцияКорневыхТипов = Новый Массив; СтрокиМетаОбъектов = ТаблицаТиповМетаОбъектов.НайтиСтроки(Новый Структура("Категория", 0)); Для Каждого СтрокаТаблицыМетаОбъектов Из СтрокиМетаОбъектов Цикл КоллекцияКорневыхТипов.Добавить(СтрокаТаблицыМетаОбъектов.Единственное); КонецЦикла; Если ирКэш.ДоступныВнешниеИсточникДанныхЛкс() Тогда Для Каждого МетаВнешнийИсточникДанных Из Метаданные.ВнешниеИсточникиДанных Цикл КоллекцияКорневыхТипов.Добавить(МетаВнешнийИсточникДанных.ПолноеИмя()); КонецЦикла; КонецЕсли; КоллекцияКорневыхТипов.Добавить("Отчет"); КоллекцияКорневыхТипов.Добавить("Обработка"); КоллекцияКорневыхТипов.Добавить("Роль"); КоллекцияКорневыхТипов.Добавить("Подсистема"); КоллекцияКорневыхТипов.Добавить("РегламентноеЗадание"); КоллекцияКорневыхТипов.Добавить("HTTPСервис"); КоллекцияКорневыхТипов.Добавить("WebСервис"); КоллекцияКорневыхТипов.Добавить("ОбщаяКоманда"); ИмяДвиженияССубконто = ирОбщий.ПеревестиСтроку("ДвиженияССубконто"); ИмяГраницы = ирОбщий.ПеревестиСтроку("Границы"); ИмяЗадачиПоИсполнителю = ирОбщий.ПеревестиСтроку("ЗадачиПоИсполнителю"); ИмяКонстанта = ирОбщий.ПеревестиСтроку("Константа"); ИмяОбороты = ирОбщий.ПеревестиСтроку("Обороты"); ИмяОборотыДтКт = ирОбщий.ПеревестиСтроку("ОборотыДтКт"); ИмяОстатки = ирОбщий.ПеревестиСтроку("Остатки"); ИмяОстаткиИОбороты = ирОбщий.ПеревестиСтроку("ОстаткиИОбороты"); ИмяСрезПервых = ирОбщий.ПеревестиСтроку("СрезПервых"); ИмяСрезПоследних = ирОбщий.ПеревестиСтроку("СрезПоследних"); ИмяСубконто = ирОбщий.ПеревестиСтроку("Субконто"); ИмяТабличнаяЧасть = ирОбщий.ПеревестиСтроку("ТабличнаяЧасть"); ИмяТочки = ирОбщий.ПеревестиСтроку("Точки"); ИндексКартинкиТЧ = мОписаниеТипаМДТабличнаяЧасть.ИндексКартинкиЕдинственное; ИндикаторТиповМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКорневыхТипов.Количество(), "Анализ конфигурации"); Для Каждого КорневойТип Из КоллекцияКорневыхТипов Цикл ирОбщий.ОбработатьИндикаторЛкс(ИндикаторТиповМД); ОписаниеКорневогоТипа = ОписаниеТипаМетаОбъектов(КорневойТип); Если ОписаниеКорневогоТипа = Неопределено Тогда Если Найти(КорневойТип, ".") = 0 Тогда // В текущей версии платформы нет поддержки такого типа метаданных Продолжить; КонецЕсли; // Внешний источник данных ОписаниеКорневогоТипа = мОписаниеТипаМДВнешнийИсточникДанных; ОбъектМДКорневогоТипа = ирКэш.ОбъектМДПоПолномуИмениЛкс(КорневойТип); МножественноеКорневогоТипа = КорневойТип; ЕдинственноеКорневогоТипа = ОбъектМДКорневогоТипа.Имя; ПредставлениеКатегории = ОбъектМДКорневогоТипа.Представление(); ЕстьДоступ = ПравоДоступа("Использование", ОбъектМДКорневогоТипа); СхемаТаблиц = ОбъектМДКорневогоТипа.Имя; ТипТаблицы = "Внешняя"; КоллекцияМетаОбъектов = ОбъектМДКорневогоТипа.Таблицы; ЕстьТаблицаБД = Истина; Иначе МножественноеКорневогоТипа = ОписаниеКорневогоТипа.Множественное; ЕдинственноеКорневогоТипа = ОписаниеКорневогоТипа.Единственное; ПредставлениеКатегории = ирОбщий.ПредставлениеИзИдентификатораЛкс(МножественноеКорневогоТипа); ЕстьДоступ = Истина; СхемаТаблиц = ""; //Если КорневойТип = "КритерийОтбора" Тогда // ТипТаблицы = "ВиртуальнаяТаблица"; //Иначе ТипТаблицы = КорневойТип; //КонецЕсли; Если КорневойТип = "Перерасчет" Тогда КоллекцияМетаОбъектов = Новый Массив; Для Каждого МетаРегистрРасчета Из Метаданные.РегистрыРасчета Цикл Для Каждого Перерасчет Из МетаРегистрРасчета.Перерасчеты Цикл КоллекцияМетаОбъектов.Добавить(Перерасчет); КонецЦикла; КонецЦикла; Иначе КоллекцияМетаОбъектов = Метаданные[МножественноеКорневогоТипа]; КонецЕсли; ЕстьТаблицаБД = Истина И (Ложь Или КорневойТип <> "Константа" Или ирКэш.ДоступныТаблицыКонстантЛкс()) И (Ложь Или КорневойТип = "Константа" Или КорневойТип = "КритерийОтбора" Или КорневойТип = "ЖурналДокументов" Или ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип) Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип)); КонецЕсли; Если КоллекцияМетаОбъектов.Количество() = 0 Тогда Продолжить; КонецЕсли; СтрокаТипаМетаданных = ДеревоОбъектовМД.Строки.Добавить(); СтрокаТипаМетаданных.Представление = ПредставлениеКатегории; СтрокаТипаМетаданных.Имя = ЕдинственноеКорневогоТипа; СтрокаТипаМетаданных.ПолноеИмяОбъекта = МножественноеКорневогоТипа; СтрокаТипаМетаданных.ИндексКартинки = ОписаниеКорневогоТипа.ИндексКартинкиМножественное; СтрокаТипаМетаданных.ЕстьДоступ = ЕстьДоступ; ЛиКорневойТипОбъектаСТабличнымиЧастями = ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип); ИндикаторОбъектовМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияМетаОбъектов.Количество(), "Анализ " + КорневойТип); Для Каждого ОбъектМД Из КоллекцияМетаОбъектов Цикл #Если Сервер И Не Сервер Тогда ОбъектМД = Метаданные.Справочники.ирАлгоритмы; #КонецЕсли ирОбщий.ОбработатьИндикаторЛкс(ИндикаторОбъектовМД); ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ПредставлениеМД = ОбъектМД.Представление(); ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); ФрагментыИмениТаблицы = ирОбщий.СтрРазделитьЛкс(ПолноеИмяТаблицыБД); ИмяОбъектаМД = ОбъектМД.Имя; Если КорневойТип = "Перерасчет" Тогда МетаРегистрРасчета = ОбъектМД.Родитель(); ИмяОбъектаМД = МетаРегистрРасчета.Имя + "." + ИмяОбъектаМД; ПредставлениеМД = МетаРегистрРасчета.Представление() + "." + ПредставлениеМД; КонецЕсли; СтрокаОбъектаМД = ДобавитьСтрокуДереваМД(СтрокаТипаМетаданных, ПолноеИмяТаблицыБД, ИмяОбъектаМД, ПредставлениеМД, ТипТаблицы, ОписаниеКорневогоТипа.ИндексКартинкиЕдинственное, ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД, ОбъектМД.Имя, ПредставлениеМД, СхемаТаблиц, ОбъектМД,, ФрагментыИмениТаблицы); Попытка СтрокаОбъектаМД.ПравоПросмотр = ПравоДоступа("Просмотр", ОбъектМД); Исключение СтрокаОбъектаМД.ПравоПросмотр = Истина; КонецПопытки; Если ЛиКорневойТипОбъектаСТабличнымиЧастями Тогда СтруктураТЧ = ирОбщий.ТабличныеЧастиОбъектаЛкс(ОбъектМД, ФрагментыИмениТаблицы); Для Каждого КлючИЗначение Из СтруктураТЧ Цикл СтрокаТЧВДереве = ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + КлючИЗначение.Ключ, КлючИЗначение.Ключ, КлючИЗначение.Значение, "ТабличнаяЧасть", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД + "." + ИмяТабличнаяЧасть + "." + КлючИЗначение.Ключ,, ПредставлениеМД + "." + КлючИЗначение.Значение,, ОбъектМД); МетаТЧ = ОбъектМД.ТабличныеЧасти.Найти(КлючИЗначение.Ключ); Если МетаТЧ <> Неопределено Тогда СтрокаТЧВДереве.ПравоПросмотр = ПравоДоступа("Просмотр", МетаТЧ); КонецЕсли; КонецЦикла; Если КорневойТип = "БизнесПроцесс" Тогда //! ОбъектМД = Метаданные.БизнесПроцессы[0] ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяТочки, "Точки", "Точки", "Точки", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Точки",, ОбъектМД); КонецЕсли; Если КорневойТип = "Задача" Тогда //! ОбъектМД = Метаданные.Задачи[0] Если ОбъектМД.Адресация <> Неопределено Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяЗадачиПоИсполнителю, "ЗадачиПоИсполнителю", "Задачи по исполнителю", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Задачи по исполнителю",, ОбъектМД, 1); КонецЕсли; КонецЕсли; КонецЕсли; Если КорневойТип = "РегистрСведений" Тогда //! ОбъектМД = Метаданные.РегистрыСведений[0] Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПоследних, "СрезПоследних", "срез последних", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез последних",, ОбъектМД, 1); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПервых, "СрезПервых", "срез первых", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез первых",, ОбъектМД, 1); КонецЕсли; ИначеЕсли КорневойТип = "РегистрНакопления" Тогда //! ОбъектМД = Метаданные.РегистрыНакопления[0] ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 3); Если ОбъектМД.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 1); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 4); КонецЕсли; ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда //! ОбъектМД = Метаданные.РегистрыБухгалтерии[0] ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 5); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 3); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 6); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДвиженияССубконто, "ДвиженияССубконто", "Движения с субконто", "ДвиженияССубконто", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Движения с субконто",, ОбъектМД, 2); Если ОбъектМД.ПланСчетов.МаксКоличествоСубконто > 0 Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСубконто, "Субконто", "Субконто", "Субконто", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Субконто",, ОбъектМД); КонецЕсли; Если ОбъектМД.Корреспонденция Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОборотыДтКт, "ОборотыДтКт", "Обороты Дт Кт", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты Дт Кт",, ОбъектМД, 7); КонецЕсли; ИначеЕсли КорневойТип = "Последовательность" Тогда //! ОбъектМД = Метаданные.Последовательности[0] ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяГраницы, "Границы", "Границы", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Границы",, ОбъектМД); КонецЕсли; Если ирОбщий.ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМД) Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД, Истина, Ложь), "Изменения", "Изменения", "Изменения", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Изменения",, ОбъектМД); КонецЕсли; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если СтрокаТипаМетаданных.Строки.Количество() = 0 Тогда ДеревоОбъектовМД.Строки.Удалить(СтрокаТипаМетаданных); КонецЕсли; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); мТаблицаВсехТаблицБД.Индексы.Добавить("НПолноеИмя"); //мТаблицаВсехТаблицБД.Сортировать("НПолноеИмя"); // Вроде бы сортировка хранения уже не используется мДеревоОбъектовМД = ДеревоОбъектовМД; Возврат мДеревоОбъектовМД; КонецФункции Функция ДобавитьСтрокуДереваМД(СтрокаРодителяМД, ПолноеИмяТаблицы, Имя, Представление, ТипТаблицы = "", ИндексКартинки = 0, ЕстьТаблицаБД = Ложь, мТаблицаВсехТаблицБД = Неопределено, ПолноеИмяМД ="", ИмяТаблицы = "", ПредставлениеТаблицы = "", СхемаТаблицы = "", ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено, ФрагментыИмениТаблицы = Неопределено) ДочерняяТаблица = СтрокаРодителяМД.Строки.Добавить(); ДочерняяТаблица.Имя = Имя; ДочерняяТаблица.Представление = Представление; ДочерняяТаблица.ПолноеИмяОбъекта = ПолноеИмяТаблицы; ДочерняяТаблица.ИндексКартинки = ИндексКартинки; ДочерняяТаблица.ПравоПросмотр = СтрокаРодителяМД.ПравоПросмотр; ДочерняяТаблица.ТипТаблицы = ТипТаблицы; Если ЕстьТаблицаБД Тогда ОписаниеТаблицы = ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ПолноеИмяТаблицы, ПолноеИмяМД, ТипТаблицы, ИмяТаблицы, ПредставлениеТаблицы, СхемаТаблицы,, ОбъектМД, ИндексПараметраОтбора, ФрагментыИмениТаблицы); ДочерняяТаблица.ЕстьДоступ = ОписаниеТаблицы.ЕстьДоступ; Иначе ДочерняяТаблица.ЕстьДоступ = СтрокаРодителяМД.ЕстьДоступ; КонецЕсли; Возврат ДочерняяТаблица; КонецФункции Функция ТаблицаВсехТаблицБД() Экспорт ПроверитьЗагрузитьКэшМДСеанса(); Если мТаблицаВсехТаблицБД <> Неопределено Тогда Возврат мТаблицаВсехТаблицБД; КонецЕсли; ДеревоОбъектовМД(); Возврат мТаблицаВсехТаблицБД; КонецФункции // Проверяет общий тип на агрегатность. // // Параметры: // ИмяОбщегоТипа - Строка; // *ЯзыкПрограммы - *Число, 0. // // Возвращаемое значение: // Булево. // Функция ЭтоАгрегатныйОбщийТип(Знач ИмяОбщегоТипа, Знач ЯзыкПрограммы = 0) Экспорт Если ИмяОбщегоТипа = "" Тогда Возврат Ложь; КонецЕсли; ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "["); СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипа, ЯзыкПрограммы, ""); // 2021 добавил ТипЯзыка для попадания в индекс Если Ложь Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Или (Истина И ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0 И ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0 //И Не ЛиИмяТипаComОбъекта(ИмяОбщегоТипа) ) Тогда Результат = Ложь; Иначе Результат = Истина; КонецЕсли; Возврат Результат; КонецФункции Функция БазовыйФайлРедактораJSON() Экспорт Если БазовыйФайлРедактораJSON = Неопределено Тогда БазовыйКаталог = КаталогВременныхФайлов(); КаталогКомпоненты = "JSONEditor"; ДвоичныеДанные = ПолучитьМакет("JSONEditor"); Чтение = Вычислить("Новый ЧтениеДанных(ДвоичныеДанные)"); // 8.3.9+ Файл = Новый ЧтениеZipФайла(Чтение.ИсходныйПоток()); Файл.ИзвлечьВсе(БазовыйКаталог + КаталогКомпоненты); БазовыйФайлРедактораJSON = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "index.html"; КонецЕсли; Возврат БазовыйФайлРедактораJSON; КонецФункции Функция БазовыйФайлРедактораКода() Экспорт Если БазовыйФайлРедактораКода = Неопределено Тогда БазовыйКаталог = КаталогВременныхФайлов(); КаталогКомпоненты = "MonacoEditor"; ДвоичныеДанные = ПолучитьМакет("MonacoEditor"); Чтение = Вычислить("Новый ЧтениеДанных(ДвоичныеДанные)"); // 8.3.9+ Файл = Новый ЧтениеZipФайла(Чтение.ИсходныйПоток()); Файл.ИзвлечьВсе(БазовыйКаталог + КаталогКомпоненты); ИмяФайла = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "editor.js"; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ИмяФайла, КодировкаТекста.UTF8); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ТекстФайла = ирОбщий.СтрЗаменитьЛкс(ТекстФайла, "customOptions: true", ", lineHeight: 15" ", suggestFontSize: 13, suggestLineHeight: 15" , Истина); ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ИмяФайла); //ИмяФайла = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "decorations.css"; //ТекстовыйДокумент = Новый ТекстовыйДокумент; //ТекстовыйДокумент.Прочитать(ИмяФайла); //ТекстовыйДокумент.ДобавитьСтроку("body {overflow: hidden;}"); //// Цвета статусной строки //ТекстовыйДокумент.ДобавитьСтроку(" //|.statusbar-widget { //| background: #c2dfef; //| color: #000; //|}"); //// Ширина списка автодополнения //ТекстовыйДокумент.ДобавитьСтроку(" //|.monaco-editor .suggest-widget { //| width: 500px; //|}"); //// Ширина списка автодополнения вместе с окном детальной инфы //ТекстовыйДокумент.ДобавитьСтроку(" //|.monaco-editor .suggest-widget.docs-side { //| width: 1000px; //|}"); //ТекстовыйДокумент.Записать(ИмяФайла); БазовыйФайлРедактораКода = БазовыйКаталог + КаталогКомпоненты + ирОбщий.РазделительПутиКФайлуЛкс() + "index.html"; КонецЕсли; Возврат БазовыйФайлРедактораКода; КонецФункции //. // Параметры: // МодульМетаданных - см. МодульМетаданных() - // ИмяМетода - ? - // Возвращаемое значение: // СтрокаТаблицыЗначений, Неопределено - Функция СтрокаМетодаМодуляПоИмени(Знач МодульМетаданных, Знач ИмяМетода) Экспорт Если Ложь Или Не ЗначениеЗаполнено(ИмяМетода) Или ИмяМетода = ИмяМетодаИнициация() Тогда Возврат Неопределено; КонецЕсли; СтрокаМетода = МодульМетаданных.Методы.Найти(НРег(ИмяМетода), "НИмя"); Если Истина И СтрокаМетода <> Неопределено И Не ЗначениеЗаполнено(СтрокаМетода.ИмяМодуля) Тогда СтрокаМетода.ИмяМодуля = МодульМетаданных.Имя; КонецЕсли; Возврат СтрокаМетода; КонецФункции #Если Клиент Тогда // Не применяется для имитаторов. // Параметры: // ДанныеФормы - ДанныеФормы - // ЛиКоллекция - Булево, Неопределено - // Форма - УправляемаяФорма - // Возвращаемое значение: // Структура - "Ключ" содержит имя реквизита, а "Значение" содержит описание типов реквизита Функция ДочерниеСвойстваДанныхФормы(ДанныеФормы, Знач ЛиДляКоллекции = Неопределено, Знач Форма, Знач ИмяСвойства = "") Экспорт Если ЛиДляКоллекции = Неопределено Тогда ЛиДляКоллекции = ирОбщий.ЛиКоллекцияЛкс(ДанныеФормы); КонецЕсли; ДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ДанныеФормы)); СоответствиеПИ = Новый Соответствие; СоответствиеПИ.Вставить("t", "http://v8.1c.ru/8.2/uobjects"); СоответствиеПИ.Вставить("xs", "http://www.w3.org/2001/XMLSchema"); СоответствиеПИ.Вставить("xsi", "http://www.w3.org/2001/XMLSchema-instance"); Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПИ); Выражение = "/*[last()]/t:type[1]/text()"; ПутьКРодителю = ДокументДОМ.ВычислитьВыражениеXPath(Выражение, ДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение; СтруктураИмен = Новый Структура; Если Найти(ПутьКРодителю, "root.") = 1 Тогда ПутьКРодителю = Сред(ПутьКРодителю, СтрДлина("root.") + 1); СтруктураИмен = ИменаРеквизитовФормы(Форма, ПутьКРодителю, ЛиДляКоллекции,, ДокументДОМ).Все; Если ЗначениеЗаполнено(ИмяСвойства) И Не СтруктураИмен.Свойство(ИмяСвойства) Тогда ДобавитьОтсутствиеЭлементаФормы(Форма, "Реквизит:" + ПутьКРодителю + "." + ИмяСвойства); КонецЕсли; Иначе // parameters - там почему то всегда пусто КонецЕсли; Возврат СтруктураИмен; КонецФункции // Позволяет пользователю выбрать один из возможных вариантов описания слова. // // Параметры: // СтруктураЦикла - Соответствие - где ключи - имена ветвей дерева, а значения - таблицы структур типов; // *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова. // // Возвращаемое значение: // СтрокаТаблицыЗначений, Структура - описание слова. // Функция ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения = Ложь, ВладелецФормы = Неопределено, Слово = "", НомерПараметраМетода = 0, БезусловнаяАктивизацияРезультатов = Истина, выхФормаВыбора = Неопределено, КоличествоФактПараметровМетода = 0) Экспорт ДеревоВыбора = Новый ДеревоЗначений; ДеревоВыбора.Колонки.Добавить("Ключ"); ДеревоВыбора.Колонки.Добавить("Представление"); ДеревоВыбора.Колонки.Добавить("ТипСлова"); СчетчикСтрокВторогоУровня = 0; НачальнаяСтрокаВыбора = Неопределено; Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл СтрокаЭлементаЦикла = ДеревоВыбора.Строки.Добавить(); СтрокаЭлементаЦикла.Представление = ЭлементЦикла.Ключ; КонецЦикла; ДеревоВыбора.Строки.Сортировать("Представление"); Для Каждого СтрокаЭлементаЦикла Из ДеревоВыбора.Строки Цикл Для Каждого СтруктураТипаКонтекста Из СтруктураЦикла[СтрокаЭлементаЦикла.Представление] Цикл //Если СтруктураТипаКонтекста.СтрокаОписания = Неопределено Тогда // Продолжить; //КонецЕсли; Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "НеизвестныйКонтекст" Тогда Продолжить; КонецЕсли; СтрокаОписания = СтруктураТипаКонтекста.СтрокаОписания; // Ранее среди параметров были: ПутьКСлову = "", ТекущееСлово = "", //// Добавим строку описания слова //ЭтоИмяТипа = Ложь; //Попытка // Если СтрокаОписания.ТипЯзыка = "ИмяТипа" Тогда // ЭтоИмяТипа = Истина; // КонецЕсли; //Исключение //КонецПопытки; // //Если ЭтоИмяТипа Тогда // // Если Прав(ПутьКСлову, 1) = "(" Тогда // ЧистыйПутьКСлову = Лев(ПутьКСлову, СтрДлина(ПутьКСлову) - 1); // Иначе // ЧистыйПутьКСлову = ТекущееСлово; // КонецЕсли; // // БазовыйТип = ирОбщий.ПервыйФрагментЛкс(ЧистыйПутьКСлову); // Если БазовыйТип = "" Тогда // // НеизвестныйКонтекст // СтрокаОписания = Неопределено; // Иначе // СтрокаОписания = ТаблицаОбщихТипов.Найти(БазовыйТип, "БазовыйТип"); // КонецЕсли; //КонецЕсли; Если Истина И СтрокаОписания <> Неопределено И ТипЗнч(СтрокаОписания) <> Тип("COMОбъект") И СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписания, "Ключ") = Неопределено И СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено И (Ложь Или СтрокаОписания.Владелец().Колонки.Найти("ТипЯзыка") = Неопределено Или СтрокаОписания.ТипЯзыка <> "ИмяТипа") Тогда ПредставлениеТипа = СтрокаОписания.Слово; Если Истина И СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено И ЗначениеЗаполнено(СтрокаОписания.ТипКонтекста) Тогда ПредставлениеТипа = СтрокаОписания.ТипКонтекста + "." + ПредставлениеТипа; КонецЕсли; СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить(); СтрокаДереваВыбора.Ключ = СтрокаОписания; Попытка СтрокаДереваВыбора.ТипСлова = СтрокаОписания.ТипСлова; Исключение СтрокаДереваВыбора.ТипСлова = "Тип"; КонецПопытки; СтрокаДереваВыбора.Представление = ПредставлениеТипа; КонецЕсли; Если ВключатьПутьКОписаниюТипаЗначения Тогда // Добавим строку описания типа значения СтрокаОписанияТипаЗначения = ТаблицаОбщихТипов.Найти(НРег(СтруктураТипаКонтекста.ИмяОбщегоТипа), "НСлово"); Если СтрокаОписанияТипаЗначения <> Неопределено Тогда Если СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписанияТипаЗначения, "Ключ") = Неопределено Тогда ПредставлениеТипа = СтрокаОписанияТипаЗначения.Слово; СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить(); СтрокаДереваВыбора.Ключ = СтрокаОписанияТипаЗначения; СтрокаДереваВыбора.ТипСлова = "Тип"; СтрокаДереваВыбора.Представление = ПредставлениеТипа; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; СчетчикСтрокВторогоУровня = СчетчикСтрокВторогоУровня + СтрокаЭлементаЦикла.Строки.Количество(); Если Истина И НачальнаяСтрокаВыбора = Неопределено И СтрокаЭлементаЦикла.Строки.Количество() > 0 Тогда Если СтрокаДереваВыбора.ТипСлова = "Конструктор" Тогда Отбор = Новый Структура; Отбор.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста); Отбор.Вставить("Слово", "<Новый>"); Отбор.Вставить("ЯзыкПрограммы", 0); ТаблицаВариантов = ТаблицаПараметров.Скопировать(Отбор); НовыйТекущийВариант = ПодобратьВариантСинтаксисаМетода(ТаблицаВариантов, КоличествоФактПараметровМетода); Для Каждого СтрокаВарианта Из СтрокаЭлементаЦикла.Строки Цикл Если НовыйТекущийВариант = СтрокаВарианта.Ключ.Слово Тогда НачальнаяСтрокаВыбора = СтрокаВарианта; Прервать; КонецЕсли; КонецЦикла; Иначе НачальнаяСтрокаВыбора = СтрокаЭлементаЦикла.Строки[0]; КонецЕсли; КонецЕсли; СтрокаЭлементаЦикла.Строки.Сортировать("Представление"); КонецЦикла; Если выхФормаВыбора = Неопределено Тогда выхФормаВыбора = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма"); КонецЕсли; Если СчетчикСтрокВторогоУровня > 0 Или выхФормаВыбора.Открыта() Тогда выхФормаВыбора.ДеревоТиповСлова = ДеревоВыбора; выхФормаВыбора.ИскомоеСлово = Слово; выхФормаВыбора.ПоискСУчетомТипаСлова = Истина; выхФормаВыбора.НомерИскомогоПараметра = НомерПараметраМетода; выхФормаВыбора.ВладелецФормы = ВладелецФормы; выхФормаВыбора.ЗакрыватьПриЗакрытииВладельца = Ложь; Если НачальнаяСтрокаВыбора <> Неопределено Тогда выхФормаВыбора.ВыбратьИскомуюСтроку(НачальнаяСтрокаВыбора, БезусловнаяАктивизацияРезультатов); КонецЕсли; выхФормаВыбора.ВладелецФормы = Неопределено; // Перенес в саму форму КонецЕсли; Если Ложь Или СчетчикСтрокВторогоУровня = 1 Или (Истина И СчетчикСтрокВторогоУровня = 2 И ДеревоВыбора.Строки[0].Строки.Количество() = 1 И НачальнаяСтрокаВыбора.Ключ = ДеревоВыбора.Строки[1].Строки[0].Ключ) Тогда ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора; ИначеЕсли СчетчикСтрокВторогоУровня > 1 Тогда //ФормаВыбора = ПолучитьФорму("ФормаВыбораСправкиПоСлову"); //ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора; //ФормаВыбора.НачальноеЗначениеВыбора = НачальнаяСтрокаВыбора; //ВыбранныйЭлементТипа = ФормаВыбора.ОткрытьМодально(); ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора; Иначе ВыбранныйЭлементТипа = Неопределено; КонецЕсли; Если ВыбранныйЭлементТипа = Неопределено Тогда СтрокаОписания = Неопределено; Иначе СтрокаОписания = ВыбранныйЭлементТипа.Ключ; КонецЕсли; Возврат СтрокаОписания; КонецФункции Функция НайтиИмяМетодаСтрокиМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "", Знач ЧислоСтрокДляПоискаИмениМетода = 1000) Экспорт Если Не ЗначениеЗаполнено(ИмяМодуля) Тогда // Динамический код Возврат ""; КонецЕсли; ОписаниеМодуля = ирКлиент.ОписаниеМодуляПоСжатомуИмениЛкс(ИмяМодуля); ИмяМетода = НайтиИмяМетодаСтрокиФайлаМодуля(ОписаниеМодуля.ИмяМодуля, НомерСтроки, СодержаниеСтроки, ТекстыМодулей, СтароеИмяФайлаМодуляБезРасширения, ЧислоСтрокДляПоискаИмениМетода); Возврат ИмяМетода; КонецФункции Функция НайтиИмяМетодаСтрокиФайлаМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "", Знач ЧислоСтрокДляПоискаИмениМетода = 2000, выхСмещениеСтрокиМетода = 0, Знач ПолеТекстаМодуля = Неопределено) Экспорт Если ПолеТекстаМодуля = Неопределено Тогда ПолеТекстаМодуля = ирКлиент.ПолеТекстаМодуляБезСтруктурыТипаЛкс(ИмяМодуля); КонецЕсли; Если ПолеТекстаМодуля = Неопределено Тогда Возврат Неопределено; КонецЕсли; Если Ложь Или СодержаниеСтроки = Неопределено Или СокрЛП(ПолеТекстаМодуля.ПолеТекста.ПолучитьСтроку(НомерСтроки)) = СодержаниеСтроки Тогда Если ТекстыМодулей = Неопределено Тогда ТекстыМодулей = Новый Соответствие; КонецЕсли; КэшРазметкиМодулей = ТекстыМодулей[ИмяМодуля]; Если КэшРазметкиМодулей = Неопределено Тогда Методы = Новый ТаблицаЗначений; Методы.Колонки.Добавить("Метод"); Методы.Индексы.Добавить("Метод"); Методы.Колонки.Добавить("НачальнаяСтрока"); Методы.Колонки.Добавить("КонечнаяСтрока", Новый ОписаниеТипов("Число")); КэшРазметкиМодулей = Новый Структура("Методы", Методы); ТекстыМодулей[ИмяМодуля] = КэшРазметкиМодулей; Методы = Неопределено; КонецЕсли; НужноеОписаниеМетода = Неопределено; Если ирКэш.РежимОтладкиЛкс() Тогда // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого ОписаниеМетода Из КэшРазметкиМодулей.Методы Цикл Если Истина И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки Тогда НужноеОписаниеМетода = ОписаниеМетода; Прервать; КонецЕсли; КонецЦикла; Иначе // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru) Для Каждого ОписаниеМетода Из КэшРазметкиМодулей.Методы Цикл   Если Истина   И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки   И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки   Тогда   НужноеОписаниеМетода = ОписаниеМетода;   Прервать;   КонецЕсли;   КонецЦикла;   КонецЕсли; Если НужноеОписаниеМетода = Неопределено Тогда РегВыражение = ирКэш.ВычислительРегВыраженийЛкс(); #Если Сервер И Не Сервер Тогда РегВыражение = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли РегВыражение.Global = Истина; РегВыражение.Pattern = "(?:" + шПустоеНачалоСтроки + "(?:Процедура|Функция)" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\()" + "|(?:" + шПустоеНачалоСтроки + "(?:КонецПроцедуры|КонецФункции)" + шРазделитель + "+?(?=\n))"; НачальнаяСтрокаДиапазона = Макс(1, НомерСтроки - ЧислоСтрокДляПоискаИмениМетода); ПолеТекстаМодуля.ПолеТекста.УстановитьГраницыВыделения(НомерСтроки + 1, 1, НачальнаяСтрокаДиапазона, 1); Вхождения = РегВыражение.НайтиВхождения(ПолеТекстаМодуля.ВыделенныйТекст(), Истина); Если Вхождения.Количество() > 0 Тогда Вхождение = Вхождения[Вхождения.Количество() - 1]; ИмяМетода = Вхождение.SubMatches(0); Если ИмяМетода = Неопределено Тогда ИмяМетода = ИмяМетодаИнициация(); КонецЕсли; НужноеОписаниеМетода = КэшРазметкиМодулей.Методы.Найти(ИмяМетода, "Метод"); Если НужноеОписаниеМетода = Неопределено Тогда НужноеОписаниеМетода = КэшРазметкиМодулей.Методы.Вставить(0); НужноеОписаниеМетода.Метод = ИмяМетода; НужноеОписаниеМетода.НачальнаяСтрока = НачальнаяСтрокаДиапазона + СтрЧислоСтрок(Лев(ПолеТекстаМодуля.ВыделенныйТекст(), Вхождение.FirstIndex + Вхождение.Length)) - 1; Если ИмяМетода = ИмяМетодаИнициация() Тогда НужноеОписаниеМетода.КонечнаяСтрока = 100000000; КонецЕсли; КонецЕсли; Иначе Пустышка = 0; // Для отладки КонецЕсли; Иначе ИмяМетода = НужноеОписаниеМетода.Метод; КонецЕсли; Если НужноеОписаниеМетода <> Неопределено Тогда выхСмещениеСтрокиМетода = НомерСтроки - НужноеОписаниеМетода.НачальнаяСтрока; Если НомерСтроки > НужноеОписаниеМетода.КонечнаяСтрока Тогда НужноеОписаниеМетода.КонечнаяСтрока = НомерСтроки; КонецЕсли; КонецЕсли; Иначе Пустышка = 0; // Для отладки КонецЕсли; Возврат ИмяМетода; КонецФункции Функция ЗаполнитьСписокИнструментов() Экспорт Если СписокИнструментов.Количество() = 0 Тогда ТабличныйДокумент = ПолучитьМакет("СписокИнструментов"); СписокИнструментов.Загрузить(ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ТабличныйДокумент,,,, Истина)); КонецЕсли; Возврат СписокИнструментов; КонецФункции // Инициализирует полное дерево типов платформы. // // Параметры: // Нет. // Процедура ИнициироватьДеревоТипов() Экспорт ИнициацияОписанияМетодовИСвойств(); Состояние("Инициализация дерева типов..."); Если ДеревоТипов <> Неопределено Тогда Возврат; КонецЕсли; ДеревоТипов = Новый ДеревоЗначений; ДеревоТипов.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево")); ДеревоТипов.Колонки.Добавить("Имя"); ДеревоТипов.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число")); ДеревоТипов.Колонки.Добавить("СтруктураТипа"); лТаблицаТипов = ТаблицаОбщихТипов.Скопировать(Новый Структура("ЯзыкПрограммы", 0), "Слово"); лТаблицаТипов.Колонки.Слово.Имя = "Имя"; Для Каждого СтрокаТипа Из лТаблицаТипов Цикл ЗаполнитьЗначенияСвойств(ДеревоТипов.Строки.Добавить(), СтрокаТипа); КонецЦикла; СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.Метаданные = мМетаданные; СтруктураТипа.ТипЯзыка = "ИмяТипа"; СтруктураТипа.ИмяОбщегоТипа = ""; ОбработатьСтрокиДереваТипов(ДеревоТипов.Строки, СтруктураТипа); ДеревоТипов.Строки.Сортировать("Имя", Истина); ВсеТипы.Сортировать("Имя"); МассивВажныхТипов = Новый Массив; // Порядок обратный МассивВажныхТипов.Добавить("Массив"); МассивВажныхТипов.Добавить("Булево"); МассивВажныхТипов.Добавить("Дата"); МассивВажныхТипов.Добавить("Строка"); МассивВажныхТипов.Добавить("Число"); Для Каждого ВажныйТип Из МассивВажныхТипов Цикл СтрокаТипа = ВсеТипы.Найти(ВажныйТип, "Имя"); ВсеТипы.Сдвинуть(СтрокаТипа, -ВсеТипы.Индекс(СтрокаТипа)); СтрокаТипа = ДеревоТипов.Строки.Найти(ВажныйТип, "Имя"); ДеревоТипов.Строки.Сдвинуть(СтрокаТипа, -ДеревоТипов.Строки.Индекс(СтрокаТипа)); КонецЦикла; Состояние(""); КонецПроцедуры Процедура ОбработатьСтрокиДереваТипов(Строки, КорневаяСтруктураТипа = Неопределено, ОкончаниеСтрокиТипа = "", _МетаданныеТипа = Неопределено) Экспорт МассивСтрокКУдалению = Новый Массив; Для Каждого СтрокаТипа Из Строки Цикл ТекущееИмяТипа = СтрокаТипа.Имя; СтрокаТипа.Имя = СтрокаТипа.Имя + ОкончаниеСтрокиТипа; Уровень = СтрокаТипа.Уровень(); ФрагментыОбщегоТипа = Неопределено; Если Уровень = 0 Тогда Если Найти(ТекущееИмяТипа, ".") > 0 Тогда ФрагментыОбщегоТипа = ирОбщий.СтрРазделитьЛкс(ТекущееИмяТипа); ТекущееИмяТипа = ФрагментыОбщегоТипа[0]; КонецЕсли; СтрокаТипаМетаОбъектов = ОписаниеТипаМетаОбъектов(ТекущееИмяТипа); Если СтрокаТипаМетаОбъектов <> Неопределено Тогда СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное; КонецЕсли; Уровень = 0; //СтрокаТипа.ИмяОбщегоТипа = ТекущееИмяТипа; Иначе Если КорневаяСтруктураТипа <> Неопределено Тогда КорневаяСтруктураТипа.Свойство("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа); КонецЕсли; СтрокаТипа.ИндексКартинки = Строки.Родитель.ИндексКартинки; КонецЕсли; Если ФрагментыОбщегоТипа <> Неопределено Тогда Если ФрагментыОбщегоТипа.ВГраница() > Уровень Тогда ТекущийФрагмент = ФрагментыОбщегоТипа[Уровень + 1]; КонецЕсли; Если Найти(ТекущийФрагмент, "<") > 0 Тогда Если Истина И КорневаяСтруктураТипа = Неопределено Тогда КорневаяСтруктураТипа = НоваяСтруктураТипа(); КорневаяСтруктураТипа.Метаданные = мМетаданные; КорневаяСтруктураТипа.ТипЯзыка = "ИмяТипа"; КорневаяСтруктураТипа.ИмяОбщегоТипа = СтрокаТипа.Имя; КонецЕсли; Если Уровень = 0 Тогда КорневаяСтруктураТипа.Вставить("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа); СтруктураТипа = НоваяСтруктураТипа(); ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа); СтруктураТипа.ИмяОбщегоТипа = ТекущееИмяТипа; Иначе СтруктураТипа = СтрокаТипа.СтруктураТипа; КонецЕсли; Попытка ВнутренняяТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, , "Свойство"); Исключение ВнутренняяТаблицаСлов = Новый ТаблицаЗначений; КонецПопытки; Если Истина И Уровень > 0 И ВнутренняяТаблицаСлов.Количество() = 0 Тогда МассивСтрокКУдалению.Добавить(СтрокаТипа); Продолжить; Иначе ОкончаниеСтрокиТипаВниз = ""; Для Счетчик = Уровень + 2 По ФрагментыОбщегоТипа.ВГраница() Цикл Фрагмент = ФрагментыОбщегоТипа[Счетчик]; ОкончаниеСтрокиТипаВниз = ОкончаниеСтрокиТипаВниз + "." + Фрагмент; КонецЦикла; Для Каждого СтрокаСлова Из ВнутренняяТаблицаСлов Цикл НоваяСтрока = СтрокаТипа.Строки.Добавить(); СтруктураТипаВниз = СтрокаСлова.ТаблицаТипов[0]; НоваяСтрока.СтруктураТипа = СтруктураТипаВниз; //НоваяСтрока.Имя = ИмяТипаИзСтруктурыТипа(СтруктураТипаВниз); НоваяСтрока.Имя = ТекущееИмяТипа + "." + СтруктураТипаВниз.Метаданные.Имя; КонецЦикла; ОбработатьСтрокиДереваТипов(СтрокаТипа.Строки, КорневаяСтруктураТипа, ОкончаниеСтрокиТипаВниз); КонецЕсли; КонецЕсли; КонецЕсли; //ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа, "ИмяОбщегоТипа"); ЗаполнитьЗначенияСвойств(ВсеТипы.Добавить(), СтрокаТипа); КонецЦикла; РодительСтрок = Строки.Родитель; Для Каждого СтрокаКУдалению Из МассивСтрокКУдалению Цикл РодительСтрок.Строки.Удалить(СтрокаКУдалению); КонецЦикла; КонецПроцедуры // Открыть диалог для редактирования допустимых типов. // // Параметры: // ДопустимыеТипы - Строка - сериализованные допустимые типы; // *ТолькоПросмотр - Булево, *Истина - открыть только для просмотра. // // Возвращаемое значение: // Строка - сериализованных допустимых типов; // Неопределено - отмена. // Функция РедактироватьДопустимыеТипы(ДопустимыеТипы, ТолькоПросмотр = Ложь) Экспорт ФормаВыбора = ПолучитьФорму("ВыборДопустимыхТипов"); ФормаВыбора.ДопустимыеТипы = ДопустимыеТипы; ФормаВыбора.ТолькоПросмотр = ТолькоПросмотр; Если ФормаВыбора.ОткрытьМодально() = Истина Тогда Возврат ФормаВыбора.ДопустимыеТипы; Иначе Возврат Неопределено; КонецЕсли; КонецФункции // Убирает из строки лишние кавычки. // // Параметры: // ПервичнаяСтрока - Строка. // // Возвращаемое значение: // Строка. // Функция ИзвлечьСтрокуШаблонаТекста(ПервичнаяСтрока) RegExp.Global = Истина; СтрокаБезГраниц = Сред(ПервичнаяСтрока, 2, СтрДлина(ПервичнаяСтрока) - 2); RegExp.Pattern = "([^""]*"")"""; Результат = RegExp.Заменить(СтрокаБезГраниц, "$1"); Возврат Результат; КонецФункции // ИзвлечьСтрокуШаблонаТекста () // Загружает шаблоны текста из файла. // // Параметры: // Нет. // // Возвращаемое значение: // Булево - успешность операции. // Функция ПолучитьТаблицуШаблоновТекста(ИмяКласса, _мСообщенияЧерезПредупреждения = Ложь, ПринудительноОбновить = Ложь) Экспорт Если Истина И Не ПринудительноОбновить И ТаблицаШаблоновТекста <> Неопределено Тогда Возврат ТаблицаШаблоновТекста; КонецЕсли; ТаблицаШаблоновТекста = Новый ТаблицаЗначений; ТаблицаШаблоновТекста.Колонки.Добавить("Шаблон"); ТаблицаШаблоновТекста.Колонки.Добавить("Замена"); ТаблицаШаблоновТекста.Индексы.Добавить("Шаблон"); ФайлШаблонов = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста"); Файл = Новый Файл(ФайлШаблонов); Если Не Файл.Существует() Тогда Если ЗначениеЗаполнено(ФайлШаблонов) Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Не обнаружен файл шаблонов текста """ + ФайлШаблонов + """, указанный в настройках компоненты ""Контекстная подсказка"""); КонецЕсли; Возврат Неопределено; КонецЕсли; Парсер = мПолучитьПарсер("ГрамматикаФайлаШаблоновТекста"); Если Парсер = Неопределено Тогда Возврат Неопределено; КонецЕсли; ТекстовыйДокументФайла = Новый ТекстовыйДокумент; ТекстовыйДокументФайла.Прочитать(ФайлШаблонов); Состояние("Идет загрузка файла шаблонов текста..."); gpMsgReduction = 2; gpMsgAccept = 3; gpMsgNotLoadedError = 4; gpMsgLexicalError = 5; gpMsgSyntaxError = 6; gpMsgInternalError = 8; Парсер.OpenTextString(ТекстовыйДокументФайла.ПолучитьТекст()); Закончили = Ложь; ТекущаяСтрокаТаблицыШаблоновТекста = Неопределено; Пока Не Закончили Цикл Ответ = Парсер.Parse(); Если Ложь Или Ответ = gpMsgLexicalError Или Ответ = gpMsgSyntaxError Или Ответ = gpMsgInternalError Или Ответ = gpMsgNotLoadedError Или Ответ = gpMsgAccept Тогда Закончили = Истина; ИначеЕсли Ответ = gpMsgReduction Тогда ИмяПравила = Парсер.CurrentReduction.ParentRule.RuleNonterminal.Text; Если ИмяПравила = "" Тогда СтартовыйТокен = Парсер.CurrentReduction.Tokens(0); ТекущаяСтрокаТаблицыШаблоновТекста = ТаблицаШаблоновТекста.Добавить(); ТекущаяСтрокаТаблицыШаблоновТекста.Шаблон = Нрег(ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data)); ИначеЕсли ИмяПравила = "" Тогда СтартовыйТокен = Парсер.CurrentReduction.Tokens(0); ТекущаяСтрокаТаблицыШаблоновТекста.Замена = ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data); КонецЕсли; КонецЕсли; КонецЦикла; Состояние(); Если Ответ <> gpMsgAccept Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Указан неправильный файл шаблонов """ + ФайлШаблонов + """"); ТаблицаШаблоновТекста = Неопределено; КонецЕсли; Возврат ТаблицаШаблоновТекста; КонецФункции // ЗагрузитьШаблоныТекста() // . // Параметры: // Параметры - ТаблицаЗначений - колонки "ИмяПараметра, ЗначениеПараметра" // ТипЗапроса - Строка, *"Построитель" - "Обычный", "Компоновка", "Построитель" Функция РедактироватьЗапрос(Текст, Параметры = Неопределено, Знач ТипЗапроса = "Построитель", ПараметрыADO = Неопределено, ПараметрыWMI = Неопределено, ВыделениеДвумерное = Неопределено) Экспорт СтруктураЗапроса = Новый Структура; СтруктураЗапроса.Вставить("ТекстЗапроса", Текст); СтруктураЗапроса.Вставить("Параметры", Параметры); Если ПараметрыADO <> Неопределено Тогда СтруктураЗапроса.Вставить("ПараметрыADO", ПараметрыADO); КонецЕсли; Если ПараметрыWMI <> Неопределено Тогда СтруктураЗапроса.Вставить("ПараметрыWMI", ПараметрыWMI); КонецЕсли; СтруктураЗапроса.Вставить("ТипЗапроса", ТипЗапроса); СтруктураЗапроса.Вставить("Имя", "Запрос"); СтруктураЗапроса.Вставить("ВыделениеДвумерное", ВыделениеДвумерное); КонсольЗапросов = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли РезультатФормы = КонсольЗапросов.РедактироватьСтруктуруЗапроса(, СтруктураЗапроса); Результат = РезультатФормы <> Неопределено; Если Результат Тогда Текст = РезультатФормы.ТекстЗапроса; Параметры = РезультатФормы.Параметры; ПараметрыADO = РезультатФормы.ПараметрыADO; ПараметрыWMI = РезультатФормы.ПараметрыWMI; ВыделениеДвумерное = РезультатФормы.ВыделениеДвумерное; КонецЕсли; Возврат Результат; КонецФункции #КонецЕсли //////////////////////////////////////////////////////////////////////////////// // РАБОТА С АЛГОРИТМАМИ // Выполняет текст программы. // // Параметры: // ТекстДляВыполнения - Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Функция ВыполнитьЛокально(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Если ЛиСинтаксическийКонтроль Тогда ирОбщий.ВыполнитьАлгоритмБезРезультата(ТекстДляВыполнения); Иначе Результат = ирОбщий.ВыполнитьАлгоритм(ТекстДляВыполнения); КонецЕсли; Возврат Результат; КонецФункции // Выполняет программный код в контексте. // // Параметры: // ТекстДляВыполнения - Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Функция ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения = "ВыполнитьЛокально", ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Если ПустаяСтрока(МетодВыполнения) Тогда ВызватьИсключение "Не указан метод выполнения"; КонецЕсли; Если КонтекстВыполнения = Неопределено Тогда ИнформацияОбОшибке = Вычислить(МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)"); Иначе ИнформацияОбОшибке = Вычислить("КонтекстВыполнения." + МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)"); КонецЕсли; Возврат ИнформацияОбОшибке; КонецФункции // Получает новый экземпляр ком-объекта парсера. // // Параметры: // Нет. // // Возвращаемое значение: // Com-объект, Неопределено. // Функция ПолучитьADOUtils(_ПытатьсяУстанавливать = Ложь, Знач СмещениеГодаADO = Неопределено, Знач Типизировать1С = Ложь, Знач БинарныеВСтроку = Ложь) Экспорт Если мADOUtils = Неопределено Тогда ИдентификаторКласса = "GameWithFire.ADOUtils"; ИмяОбъекта = "ADOUtils"; ПодключитьВнешнююКомпоненту(ИдентификаторКласса); Попытка мADOUtils = Новый ("AddIn." + ИмяОбъекта); мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки Исключение мADOUtils = Неопределено; КонецПопытки; Если Истина И мADOUtils = Неопределено //И ПытатьсяУстанавливать И Ложь Тогда ИмяМакетаДополнительнойБиблиотеки = "Zlib1"; ИмяМакетаКомпоненты = "GameWithFire"; ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки, ИмяОбъекта); ПодключитьВнешнююКомпоненту(ИдентификаторКласса); Попытка мADOUtils = Новый ("AddIn." + ИмяОбъекта); мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки Исключение КонецПопытки; КонецЕсли; // такой способ почему то не работает //мADOUtils = ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, , ИдентификаторКласса, ТипВнешнейКомпоненты.COM, ИмяМакетаДополнительнойБиблиотеки); КонецЕсли; Если мADOUtils <> Неопределено Тогда мADOUtils.BinaryDataAsStrings = БинарныеВСтроку; мADOUtils.BinaryDataAs1C = Типизировать1С; мADOUtils.YearOffset = СмещениеГодаADO; КонецЕсли; Возврат мADOUtils; КонецФункции //#КонецЕсли Функция ИдентификаторыПроцессовОтладчиков() Экспорт Перем Результат; ПортДляПодключенияОтладчика(Результат); Возврат Результат; КонецФункции Функция ПортДляПодключенияОтладчика(выхИдентификаторыОтладчиков = Неопределено, выхПротокол = "") Экспорт Результат = ""; ирОбщий.ПараметрыЗапускаСеансаТекущиеЛкс(Результат); ИдентификаторЭтогоПроцесса = ирКэш.ИдентификаторПроцессаОСЛкс(); ТекстРезультата = ТекстРезультатаКомандыСистемы("netstat -n -a -o"); выхИдентификаторыОтладчиков = Новый Массив; шАдресIP4 = "(?:[0-9]{1,3}\.){3}[0-9]{1,3}"; Результат = ирОбщий.ТекстМеждуМаркерамиЛкс(Результат, "/DEBUGGERURL""", """"); Если Истина И ЗначениеЗаполнено(Результат) И ирОбщий.СтрокиРавныЛкс(ирОбщий.ПервыйФрагментЛкс(Результат, ":"), "http") Тогда // http://CORTEX:1550 выхПротокол = "http"; ПортСервераОтладки = ирОбщий.ПоследнийФрагментЛкс(Результат, ":", Ложь); Если ПортСервераОтладки = "" Тогда ПортСервераОтладки = Неопределено; КонецЕсли; RegExp.Global = Истина; шСоединениеССерверомОтладки = "TCP(?:\s+)(" + шАдресIP4 +"):(?:\d+)(?:\s+)" + шАдресIP4 + ":" + ПортСервераОтладки +"(?:\s+)ESTABLISHED(?:\s+)"; RegExp.Pattern = шСоединениеССерверомОтладки + Формат(ИдентификаторЭтогоПроцесса, "ЧГ="); Вхождения = RegExp.НайтиВхождения(ТекстРезультата); Для Каждого Вхождение Из Вхождения Цикл ЛокальныйАдрес4 = Вхождение.SubMatches(0); Прервать; КонецЦикла; RegExp.Pattern = шСоединениеССерверомОтладки + "(\d+)"; Вхождения = RegExp.НайтиВхождения(ТекстРезультата); Для Каждого Вхождение Из Вхождения Цикл ИдентификаторОтладчика = Вхождение.SubMatches(1); Если Истина И ИдентификаторОтладчика <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=") И выхИдентификаторыОтладчиков.Найти(ИдентификаторОтладчика) = Неопределено Тогда ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(ИдентификаторОтладчика); Если Истина И ирОбщий.СтрокиРавныЛкс(ПроцессОС.Name, ирОбщий.ИмяИсполняемогоФайлаКлиентаПлатформыЛкс(Ложь)) И ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС) Тогда выхИдентификаторыОтладчиков.Добавить(ИдентификаторОтладчика); КонецЕсли; КонецЕсли; КонецЦикла; выхИдентификаторыОтладчиков.Добавить("0"); // Чтобы неоднозначность сохранялась и с одним найденным отладчиком Иначе выхПротокол = "tcp"; RegExp.Global = Истина; RegExp.Pattern = "TCP(?:\s+)0\.0\.0\.0:(\d+)(?:\s+)" + шАдресIP4 + ":(\d+)(?:\s+)LISTENING(?:\s+)" + Формат(ИдентификаторЭтогоПроцесса, "ЧГ="); Вхождения = RegExp.НайтиВхождения(ТекстРезультата); МассивСлушающихПортов = Новый Массив; СтрокаПоиска = ""; // Т.к. неясно какой из портов для отладки, используем все Для Каждого Вхождение Из Вхождения Цикл МассивСлушающихПортов.Добавить(Вхождение.SubMatches(0)); СтрокаПоиска = СтрокаПоиска + "|" + Вхождение.SubMatches(0); КонецЦикла; Если МассивСлушающихПортов.Количество() = 0 Тогда Результат = Неопределено; Возврат Результат; КонецЕсли; СтрокаПоиска = Сред(СтрокаПоиска, 2); ЛокальныйАдрес = ирОбщий.ПодготовитьТекстДляРегВыраженияЛкс("127.0.0.1"); RegExp.Pattern = "TCP(?:\s+)" + ЛокальныйАдрес + ":(?:\d+)(?:\s+)" + ЛокальныйАдрес + ":(" + СтрокаПоиска + ")(?:\s+)ESTABLISHED(?:\s+)(\d+)"; Вхождения = RegExp.НайтиВхождения(ТекстРезультата); Для Каждого Вхождение Из Вхождения Цикл ИдентификаторКорреспондента = Вхождение.SubMatches(1); Если ИдентификаторКорреспондента <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=") Тогда выхИдентификаторыОтладчиков.Добавить(ИдентификаторКорреспондента); Иначе МассивСлушающихПортов.Удалить(МассивСлушающихПортов.Найти(Вхождение.SubMatches(0))); КонецЕсли; КонецЦикла; Если МассивСлушающихПортов.Количество() > 0 Тогда Результат = "tcp://127.0.0.1:" + МассивСлушающихПортов[0]; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции #Если Клиент Тогда //. // Параметры: // ИмяФормы - Строка - // Возвращаемое значение: // Форма - Функция ПассивнаяФормаПоИмениКэш(Знач ИмяФормы) Экспорт Результат = мПассивныеФормы[НРег(ИмяФормы)]; Если Результат = Неопределено Тогда Попытка ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ИмяФормы); Если ОбъектМД <> Неопределено Тогда ИмяФормы = ОбъектМД.ПолноеИмя(); // Нормализуем имя, чтобы файл в кэше модулей имел оригинальные регистры букв КонецЕсли; Форма = ирКлиент.ПассивнаяФормаПоИмениЛкс(ИмяФормы); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки КонецПопытки; Если Форма <> Неопределено Тогда СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Результат = Форма; Иначе СлужебныеДанные = Новый Структура; Результат = СлужебныеДанные; КонецЕсли; Если Не СлужебныеДанные.Свойство("ИмяФормы") Тогда СлужебныеДанные.Вставить("ИмяФормы", ИмяФормы); КонецЕсли; ФайлФормы = ирКэш.Получить().ФайлМодуляИзИмениМодуля(СлужебныеДанные.ИмяФормы, "xml", Истина); Если ФайлФормы.Существует() Тогда ИмитаторФормы = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлФормы.ПолноеИмя); // Структура Если ИмитаторФормы.ВерсияФормата = ВерсияФорматаСтруктурыФормы() Тогда //ДатаОбновления = ФайлФормы.ПолучитьВремяИзменения(); ДатаОбновления = Дата(1,1,1); ирКэш.Получить().ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ДатаОбновления); КонецЕсли; КонецЕсли; Если Результат = СлужебныеДанные И Не СлужебныеДанные.Свойство("Тип") Тогда СлужебныеДанные.Вставить("Тип", ирОбщий.ТипУправляемаяФормаЛкс()); КонецЕсли; мПассивныеФормы[НРег(ИмяФормы)] = Результат; КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьДокументDOMФормы(Форма) Экспорт СтрокаФормы = ЗначениеВСтрокуВнутр(Форма); XMLСтрокаФормы = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(СтрокаФормы); ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.УстановитьСтроку(XMLСтрокаФормы); ПостроительDOM = Новый ПостроительDOM; ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML); Возврат ДокументDOM; КонецФункции Функция ПолучитьXPathИмениРеквизитаВОписанииРеквизита() ИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс(); Если ИДВерсииПлатформы = "81" Тогда Результат = "/d[3]"; ИначеЕсли Ложь Или ИДВерсииПлатформы = "82" Или ИДВерсииПлатформы = "83" Тогда Результат = "/d[4]"; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьXPathИмениРеквизитаВОписанииРеквизита() Функция ИмяОсновногоРеквизитаФормы(Знач ФормаИлиДокументDOM) Экспорт Возврат ИменаРеквизитовФормы(ФормаИлиДокументDOM).Основной; КонецФункции // Функция - Имена реквизитов формы // // Параметры: // ФормаИлиДокументDOM - - // ПутьКРодителю - Строка, Неопределено - если тип "Строка", то подразумевается управляемая форма, иначе - обычная форма // ЛиДляЭлементаКоллекции - Булево - пока не используем это разделение в имитаторе // // Возвращаемое значение: // - // Функция ИменаРеквизитовФормы(Знач ФормаИлиДокументDOM, Знач ПутьКРодителю = Неопределено, Знач ЛиДляКоллекции = Ложь, выхИдентификаторыРеквизитов = Неопределено, ДокументДОМ = Неопределено) Экспорт Если ПутьКРодителю <> Неопределено Тогда // Управляемая форма ИменаРеквизитов = Неопределено; КорневыеИменаРеквизитов = Неопределено; выхИдентификаторыРеквизитов = Новый Соответствие; ИмяОсновногоРеквизита = ""; ТипУправляемаяФорма = ирОбщий.ТипУправляемаяФормаЛкс(); Форма = ФормаИлиДокументDOM; Если Форма <> Неопределено Тогда СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Иначе Пустышка = 0; // Для отладки. Желательно чтобы сюда не было приходов КонецЕсли; Если СлужебныеДанные = Неопределено Тогда // Редко. Открытая форма. Фактически не используем кэш СлужебныеДанные = Новый Структура; КонецЕсли; Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда КорневыеИменаРеквизитов = СлужебныеДанные.КорневыеИменаРеквизитов.Все; КонецЕсли; Если ДокументДОМ = Неопределено И СлужебныеДанные.Свойство("ДокументДОМ") Тогда ДокументДОМ = СлужебныеДанные.ДокументДОМ; КонецЕсли; Если ТипЗнч(Форма) = ТипУправляемаяФорма И ДокументДОМ = Неопределено Тогда СтруктураТипа = НоваяСтруктураТипа("ФормаКлиентскогоПриложения"); СтруктураТипа.Метаданные = Форма; //МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипа); // Раньше кэш ДокументДОМ хранился тут ЛюбыеДанныеФормы = Неопределено; КорневыеИменаРеквизитов = Новый Структура; ИмяМодуля = ИмяМодуляИзСтруктурыТипа(СтруктураТипа); КандидатыИменРеквизитов = ирОбщий.КандидатыИменОбъектныхРеквизитовФормыЛкс(Форма); ПолеТекстаПрограммы = Неопределено; МодульПроанализирован = Ложь; Пока Истина Цикл Для Каждого ИмяРеквизита Из КандидатыИменРеквизитов Цикл Попытка ЗначениеРеквизита = Форма[ИмяРеквизита]; Исключение Продолжить; КонецПопытки; КорневыеИменаРеквизитов.Вставить(ИмяРеквизита); Если Истина И ТипЗнч(ЗначениеРеквизита) <> Тип("СписокЗначений") И мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеРеквизита)) <> Неопределено Тогда ЛюбыеДанныеФормы = ЗначениеРеквизита; Перейти ~Конец; КонецЕсли; КонецЦикла; Если МодульПроанализирован Тогда Прервать; КонецЕсли; Для Каждого ЭлементФормы Из Форма.Элементы Цикл ИмяРеквизита = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПутьКДаннымЭлементаУправляемойФормыЛкс(ЭлементФормы,, Форма)); Если Истина И ЗначениеЗаполнено(ИмяРеквизита) И Не КорневыеИменаРеквизитов.Свойство(ИмяРеквизита) Тогда КорневыеИменаРеквизитов.Вставить(ИмяРеквизита); ЗначениеРеквизита = Форма[ИмяРеквизита]; ТипЗначения = ТипЗнч(ЗначениеРеквизита); Если мМассивТиповСМетаданными.Найти(ТипЗначения) <> Неопределено Тогда ИмяТипа = ирОбщий.ИмяТипаЛкс(ТипЗначения); Если МассивУправляемыхЭлементовУправления.Найти(ИмяТипа) = Неопределено Тогда ЛюбыеДанныеФормы = ЗначениеРеквизита; Перейти ~Конец; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Если ЛюбыеДанныеФормы = Неопределено Тогда // Самый долгий способ ПолеТекстаМодуля = ПолеТекстаМодуля(ИмяМодуля); #Если Сервер И Не Сервер Тогда ПолеТекстаМодуля = Обработки.ирКлсПолеТекстаПрограммы.Создать(); #КонецЕсли ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипаИзКонкретногоТипа(ирОбщий.ТипУправляемаяФормаЛкс())); ПолеТекстаМодуля.ЗаполнитьТаблицуСлов(ТаблицаТипов,,, Ложь, Ложь); ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь,,,,,, Истина); ПолеТекстаМодуля.мРодительскийКонтекст = "ЭтаФорма"; // TODO добавить слова от ЭтотОбъект ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь, Истина, Ложь,,,, Истина); КандидатыИменРеквизитов = ПолеТекстаМодуля.ТаблицаСлов.Выгрузить(Новый Структура("Определение", "Статистический")).ВыгрузитьКолонку("НСлово"); ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтаФорма")); Если ВредныйКандидат <> Неопределено Тогда КандидатыИменРеквизитов.Удалить(ВредныйКандидат); КонецЕсли; ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтотОбъект")); Если ВредныйКандидат <> Неопределено Тогда КандидатыИменРеквизитов.Удалить(ВредныйКандидат); КонецЕсли; КонецЕсли; МодульПроанализирован = Истина; КонецЦикла; ~Конец: Если ЛюбыеДанныеФормы <> Неопределено Тогда ДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ЛюбыеДанныеФормы)); // Обычно выполняется достаточно быстро КонецЕсли; КонецЕсли; Если ПутьКРодителю = "" И Не ЛиДляКоллекции Тогда ИменаРеквизитов = КорневыеИменаРеквизитов; КонецЕсли; Если ИменаРеквизитов = Неопределено Тогда ИменаРеквизитов = Новый Структура; КонецЕсли; Если СлужебныеДанные.Свойство("Реквизиты") Тогда ТаблицаРеквизитов = СлужебныеДанные.Реквизиты; // см. НоваяТаблицаРеквизитовФормы Если ТаблицаРеквизитов <> Неопределено Тогда УспехРеквизита = Истина; Для Каждого ИмяРодителя Из ирОбщий.СтрРазделитьЛкс(НРег(ПутьКРодителю),,, Ложь) Цикл СтрокаРодителя = ТаблицаРеквизитов.Найти(ИмяРодителя, "НИмя"); Если СтрокаРодителя = Неопределено Тогда УспехРеквизита = Ложь; Прервать; КонецЕсли; ТаблицаРеквизитов = СтрокаРодителя.Реквизиты; КонецЦикла; ЭтоКоллекция = Истина И СтрокаРодителя <> Неопределено И ТипЗнч(СтрокаРодителя.Значение) <> Тип("Структура"); // Мультиметка7726614 Если Истина И УспехРеквизита И (Ложь Или ЛиДляКоллекции И ЭтоКоллекция Или Не ЛиДляКоллекции И Не ЭтоКоллекция) Тогда Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл ОписаниеТипов = СтрокаРеквизита.ОписаниеТипов; // ОписаниеТипов Если СтрокаРеквизита.Значение = Неопределено Тогда Если ОписаниеТипов = Неопределено Тогда //ОписаниеТипов = Новый ОписаниеТипов; Иначе Типы = ОписаниеТипов.Типы(); Если Типы.Количество() > 0 Тогда ТипЗначения = Типы[0]; Если Ложь Или ирОбщий.ЛиНаборЗаписейРегистраЛкс(ТипЗначения) //Или ирОбщий.ЛиТипОбъектаБДЛкс(ТипЗначения) // TODO сделать для объектов генерацию структуры их свойств Тогда ОписаниеТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов); ОписаниеТипов[0].ИмяОбщегоТипа = "ДанныеФормыСтруктураСКоллекцией"; КонецЕсли; КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(СтрокаРеквизита.Значение) = Тип("ТаблицаЗначений") Тогда СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыКоллекция"); ИначеЕсли ТипЗнч(СтрокаРеквизита.Значение) = Тип("ДеревоЗначений") Тогда СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыДерево"); Иначе СтруктураТипа = СтруктураТипаИзЗначения(СтрокаРеквизита.Значение); КонецЕсли; СтруктураТипа.Метаданные = СтрокаРеквизита.Значение; ОписаниеТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); КонецЕсли; ИменаРеквизитов.Вставить(СтрокаРеквизита.Имя, ОписаниеТипов); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; Если ДокументДОМ <> Неопределено Тогда Если ЗначениеЗаполнено(ПутьКРодителю) Тогда ПутьКРодителю = "." + ПутьКРодителю; КонецЕсли; СоответствиеПИ = Новый Соответствие; СоответствиеПИ.Вставить("t", "http://v8.1c.ru/8.2/uobjects"); СоответствиеПИ.Вставить("xs", "http://www.w3.org/2001/XMLSchema"); СоответствиеПИ.Вставить("xsi", "http://www.w3.org/2001/XMLSchema-instance"); Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПИ); Если ЛиДляКоллекции Тогда ПутьКРодителю = ПутьКРодителю + ".item"; КонецЕсли; Выражение = "/*/*/*[@name=""root" + ПутьКРодителю + """]/*"; НаборУзлов = ДокументДОМ.ВычислитьВыражениеXPath(Выражение, ДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Любой); УзелDOM = НаборУзлов.ПолучитьСледующий(); Пока УзелDOM <> Неопределено Цикл ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("nameRu"); Если ИмяРеквизита = Неопределено Тогда ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("name"); КонецЕсли; Если ИмяРеквизита <> Неопределено Тогда ИмяРеквизита = ИмяРеквизита.ТекстовоеСодержимое; Если Истина И Найти(ИмяРеквизита, ".") = 0 // Защита от нахождения "root" + ПутьКРодителю И УзелDOM.ПервыйДочерний <> Неопределено Тогда Типы = Новый Массив; УзелТипаЗначения = УзелDOM.ПервыйДочерний.ПервыйДочерний; Если УзелТипаЗначения <> Неопределено Тогда ИменаТипов = ирОбщий.СтрРазделитьЛкс(УзелТипаЗначения.ТекстовоеСодержимое, " "); Если ИменаТипов.Количество() < 11 Тогда Для Каждого ИДТипа Из ИменаТипов Цикл Попытка Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}"); Исключение Тип = Неопределено; КонецПопытки; Если Тип <> Неопределено Тогда Типы.Добавить(Тип); КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если Истина И ПутьКРодителю = "" И Типы.Количество() = 0 И ТипЗнч(Форма) = ТипУправляемаяФорма Тогда Типы.Добавить(ТипЗнч(Форма[ИмяРеквизита])); КонецЕсли; ИменаРеквизитов.Вставить(ИмяРеквизита, Новый ОписаниеТипов(Типы)); выхИдентификаторыРеквизитов.Вставить(УзелDOM.Атрибуты[0].ТекстовоеСодержимое, ИмяРеквизита); КонецЕсли; КонецЕсли; УзелDOM = НаборУзлов.ПолучитьСледующий(); КонецЦикла; КонецЕсли; Если ТипЗнч(Форма) = ТипУправляемаяФорма И Форма.Открыта() Тогда // Нельзя размещать ДокументДОМ, т.к. он не сериализуется Иначе СлужебныеДанные.Вставить("ДокументДОМ", ДокументДОМ); КонецЕсли; Иначе // Обычная форма ИменаРеквизитов = Новый Структура; ДокументДОМ = ФормаИлиДокументDOM; Если ТипЗнч(ФормаИлиДокументDOM) <> Тип("ДокументDOM") Тогда СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиДокументDOM); Если СлужебныеДанные <> Неопределено Тогда Результат = Неопределено; Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов", Результат) Тогда Возврат Результат; КонецЕсли; КонецЕсли; ДокументДОМ = ПолучитьДокументDOMФормы(ФормаИлиДокументDOM); КонецЕсли; РазыменовательПИ = Новый РазыменовательПространствИменDOM(ДокументДОМ); СтрокаXPath = "/e[1]/e[1]/e[2]/e[2]/e" + ПолучитьXPathИмениРеквизитаВОписанииРеквизита() + "/text()"; РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(СтрокаXPath, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.НеупорядоченныйИтераторУзлов); Пока Истина Цикл Узел = РезультатXPath.ПолучитьСледующий(); Если Узел = Неопределено Тогда Прервать; КонецЕсли; ИмяРеквизита = Узел.ТекстовоеСодержимое; Длина = СтрДлина(ИмяРеквизита); ИмяРеквизита = Сред(ИмяРеквизита, 2, Длина - 2); ИменаРеквизитов.Вставить(ИмяРеквизита); КонецЦикла; ИмяЭлемента = "/e[1]/e[1]/e[2]/e[1]/d[1]/text()"; РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.Строка); КлючОсновногоРеквизита = РезультатXPath.СтроковоеЗначение; ИмяЭлемента = "/e[1]/e[1]/e[2]/e[2]/e/e[1]/d[1]/text()"; РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(ИмяЭлемента, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.УпорядоченныйИтераторУзлов); Счетчик = 1; Пока 1 = 1 Цикл Узел = РезультатXPath.ПолучитьСледующий(); Если Узел = Неопределено Тогда Прервать; КонецЕсли; Если Узел.ТекстовоеСодержимое = КлючОсновногоРеквизита Тогда Прервать; КонецЕсли; Счетчик = Счетчик + 1; КонецЦикла; Если Узел <> Неопределено Тогда СтрокаXPath = "/e[1]/e[1]/e[2]/e[2]/e[" + Счетчик + "]" + ПолучитьXPathИмениРеквизитаВОписанииРеквизита() + "/text()"; РезультатXPath = ДокументДОМ.ВычислитьВыражениеXPath(СтрокаXPath, ДокументДОМ, РазыменовательПИ, ТипРезультатаDOMXPath.Строка); Длина = СтрДлина(РезультатXPath.СтроковоеЗначение); ИмяОсновногоРеквизита = Сред(РезультатXPath.СтроковоеЗначение, 2, Длина - 2); КонецЕсли; КонецЕсли; Результат = Новый Структура; Результат.Вставить("Основной", ИмяОсновногоРеквизита); Результат.Вставить("Все", ИменаРеквизитов); Если СлужебныеДанные <> Неопределено И Не ЗначениеЗаполнено(ПутьКРодителю) Тогда СлужебныеДанные.Вставить("КорневыеИменаРеквизитов", Результат); КонецЕсли; Возврат Результат; КонецФункции // Функция - Получить макет компоненты // // Параметры: // Компонента - ОбработкаОбъект, ОбработкаОбъект.ирКлсПолеТекстаПрограммы - // // Возвращаемое значение: // Форма - // Функция ПолучитьМакетКомпоненты(Компонента) Экспорт Макет = 0; Если Не МакетыКомпонент.Свойство(Компонента.ИмяКласса, Макет) Тогда Макет = Компонента.ПолучитьФорму("ФормаМакет"); Попытка Пустышка = Макет.мПлатформа; Успех = Истина; Исключение Успех = Ложь; КонецПопытки; Если Успех Тогда ирОбщий.СообщитьЛкс("Образована циклическая ссылка на ирПлатформа", СтатусСообщения.Внимание); КонецЕсли; МакетыКомпонент.Вставить(Компонента.ИмяКласса, Макет); КонецЕсли; Возврат Макет; КонецФункции // <Описание функции> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция ПолучитьТекстМодуляВнешнейОбработкиАлгоритма(ФайлВнешнейОбработки) Экспорт Если Не ФайлВнешнейОбработки.Существует() Тогда Возврат Неопределено; КонецЕсли; ТекстМодуля = ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки); Если ТекстМодуля = Неопределено Тогда Возврат Неопределено; КонецЕсли; ТекстАлгоритма = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстМодуля, МаркерНачалаАлгоритма, МаркерКонцаАлгоритма); Результат = ""; ТекстАлгоритмаТД = Новый ТекстовыйДокумент; ТекстАлгоритмаТД.УстановитьТекст(ТекстАлгоритма); Для Счетчик = 1 По ТекстАлгоритмаТД.КоличествоСтрок() Цикл СтрокаАлгоритма = ТекстАлгоритмаТД.ПолучитьСтроку(Счетчик); Если Лев(СтрокаАлгоритма, 1) = Символы.Таб Тогда СтрокаАлгоритма = Сред(СтрокаАлгоритма, 2); КонецЕсли; Результат = Результат + СтрокаАлгоритма + Символы.ПС; КонецЦикла; Возврат Результат; КонецФункции // ПолучитьТекстМодуляВнешнейОбработкиАлгоритма() // <Описание функции> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки) Экспорт #Если Сервер И Не Сервер Тогда ФайлВнешнейОбработки = Новый Файл; #КонецЕсли ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки(); Если Не ИспользоватьБыструюРаспаковку Тогда // Штатный способ платформы, но работает только на 8.3.8+ ТекстЛога = Неопределено; ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ИмяВременногоФайла + """ """ + ФайлВнешнейОбработки.ПолноеИмя + """",, ТекстЛога, Истина) Тогда УдалитьФайлы(ИмяВременногоФайла); ирОбщий.СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; Файлы = НайтиФайлы(ИмяВременногоФайла, "ObjectModule.bsl", Истина); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(Файлы[0].ПолноеИмя); ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст(); Иначе КаталогРаспаковки = ПолучитьИмяВременногоФайла(); СоздатьКаталог(КаталогРаспаковки); РаспаковатьФайлВнешнейОбработки(ФайлВнешнейОбработки.ПолноеИмя, КаталогРаспаковки); ФайлТекстаМодуляОбработки = Новый Файл(КаталогРаспаковки + ирОбщий.РазделительПутиКФайлуЛкс() + СубПутьКФайлуПотокаМодуляВнешнейОбработки); ТекстовыйДокументМодуля = Новый ТекстовыйДокумент(); ТекстовыйДокументМодуля.Прочитать(ФайлТекстаМодуляОбработки.ПолноеИмя); ТекстМодуля = ТекстовыйДокументМодуля.ПолучитьТекст(); УдалитьФайлы(КаталогРаспаковки); КонецЕсли; Возврат ТекстМодуля; КонецФункции // Открывает модуль внешней обработки алгоритма в конфигураторе. // // Параметры: // АлгоритмОбъект - СправочникОбъект.Сервисы2iS; // *НомерСтрокиВМодуле - Число, *0 - если указана, устанавливает текущую строку в модуле; // *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе; // *Переоткрыть - Булево, *Истина - переоткрыть, если уже открыт // Процедура ОткрытьАлгоритмВОтладчике(АлгоритмОбъект, НомерСтрокиВМодуле = 0, ИдентификаторПроцесса = 0, Переоткрыть = Истина) Экспорт Если Не ВыполнятьАлгоритмыЧерезВнешниеОбработки Тогда ирОбщий.СообщитьЛкс("Данная функция доступна только в режиме выполнения сервисов через внешние обработки", СтатусСообщения.Информация); Возврат; КонецЕсли; Если Не ФайловыйКэшАлгоритмовДопускаетРедактирование Тогда ирОбщий.СообщитьЛкс("Изменения файла будут игнорироваться, т.к. в настройках алгоритмов не включено разрешение редактирования файлового кэша", СтатусСообщения.Информация); КонецЕсли; ПолучитьФайлОткрывателя1С(); ФайлВнешнейОбработки = ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект); Если ФайлВнешнейОбработки <> Неопределено Тогда СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """"; Если ЗначениеЗаполнено(НомерСтрокиВМодуле) Тогда СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ="); КонецЕсли; Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ="); КонецЕсли; Если Переоткрыть Тогда СтрокаЗапуска = СтрокаЗапуска + " -reopen"; КонецЕсли; WshShell().Run(СтрокаЗапуска, 0, Ложь); КонецЕсли; КонецПроцедуры Функция ПодключитьПерехватКлавиатуры(_НовоеЗначение = Неопределено) Экспорт Если мПерехватКлавиатуры = Неопределено Тогда Попытка мПерехватКлавиатуры = Вычислить("ирПерехватКлавиатуры"); Исключение КонецПопытки; КонецЕсли; Если мПерехватКлавиатуры <> Неопределено Тогда Попытка Пустышка = мПерехватКлавиатуры.ЗахватРазрешен; Исключение // Антибаг платформы 8.3.21 https://www.hostedredmine.com/issues/956250 мПерехватКлавиатуры = Неопределено; КонецПопытки; КонецЕсли; Если мПерехватКлавиатуры = Неопределено Тогда Если Не ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс() Тогда мПерехватКлавиатуры = Новый Структура("ЗахватПервым,СобытиеПриНажатии,ЗахватРазрешен"); ПерехватКлавиатурногоВводаВОбычномПриложении = Ложь; Иначе мПерехватКлавиатуры = ПолучитьОбъектВнешнейКомпонентыИзМакета("KeyboardHook", "AddIn.ПерехватКлавиатуры.KeyboardHook", "ПерехватКлавиатуры", ТипВнешнейКомпоненты.Native); КонецЕсли; Если мПерехватКлавиатуры = Неопределено Тогда ирОбщий.СообщитьЛкс("Не удалось подключить внешнюю компоненту ПерехватКлавиатуры. Поэтому некоторые функции инструментов отключены.", СтатусСообщения.Внимание); Возврат Неопределено; КонецЕсли; мПерехватКлавиатуры.СобытиеПриНажатии = Истина; Попытка Выполнить("ирПерехватКлавиатуры = мПерехватКлавиатуры"); Исключение КонецПопытки; КонецЕсли; мПерехватКлавиатуры.ЗахватРазрешен = ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс(); Возврат мПерехватКлавиатуры; КонецФункции Функция ИспользоватьЭмуляциюНажатияКлавиш(Обновить = Ложь) Экспорт Если ИспользоватьЭмуляциюНажатияКлавиш = Неопределено Или Обновить Тогда ИспользоватьЭмуляциюНажатияКлавиш = ирОбщий.ВосстановитьЗначениеЛкс("ИспользоватьЭмуляциюНажатияКлавиш") <> Ложь; КонецЕсли; Возврат ИспользоватьЭмуляциюНажатияКлавиш; КонецФункции // Открывает модуль внешней обработки в конфигураторе. // // Параметры: // ПолноеИмяФайла - Строка; // *НомерСтрокиВМодуле - Число, *0 - если указана, устанавливает текущую строку в модуле; // *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе; // *Переоткрыть - Булево, *Истина - переоткрыть, если уже открыт // Процедура ОткрытьМодульВнешнейОбработкиВКонфигураторе(ПолноеИмяФайла, НомерСтрокиВМодуле = 0, ИдентификаторПроцесса = 0, _Переоткрыть = Истина, ВнутреннееИмя = "") Экспорт ФайлВнешнейОбработки = Новый Файл(ПолноеИмяФайла); Если Ложь Или ирКэш.НомерВерсииПлатформыЛкс() >= 803008 И ирКэш.НомерВерсииPowerShellЛкс() >= 3 Тогда Если Не ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда ИдентификаторПроцесса = ВыбратьПроцессКонфигуратора(); Если ИдентификаторПроцесса = Неопределено Тогда Возврат; КонецЕсли; КонецЕсли; ТекстСкрипта = ПолучитьМакет("СкриптОткрытьМодульВнешнейОбработки"); ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1")); ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя); СтрокаЗапуска = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя + " -processID " + ИдентификаторПроцесса + " -file """ + ПолноеИмяФайла + """"); Если НомерСтрокиВМодуле > 0 Тогда СтрокаЗапуска = СтрокаЗапуска + " -line " + Формат(НомерСтрокиВМодуле, "ЧГ="); КонецЕсли; Если ЗначениеЗаполнено(ВнутреннееИмя) Тогда СтрокаЗапуска = СтрокаЗапуска + " -internalName """ + ВнутреннееИмя + """"; КонецЕсли; //РезультатКоманды = ирОбщий.ВыполнитьКомандуОСЛкс(СтрокаЗапуска); // Так возникает 20с ожидание на инструкции $mainWindow = $rootElement.FindFirst(...) ЗапуститьПриложение(СтрокаЗапуска, КаталогВременныхФайлов()); Иначе ПолучитьФайлОткрывателя1С(); СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """"; Если НомерСтрокиВМодуле > 0 Тогда СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ="); КонецЕсли; Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ="); КонецЕсли; //Если Переоткрыть Тогда СтрокаЗапуска = СтрокаЗапуска + " -reopen"; //КонецЕсли; WshShell().Run(СтрокаЗапуска, 0, Ложь); КонецЕсли; КонецПроцедуры Функция ВыбратьПроцессКонфигуратора(Знач ИдентификаторыОтладчиков = Неопределено) Экспорт Если ИдентификаторыОтладчиков = Неопределено Тогда ИдентификаторыОтладчиков = ИдентификаторыПроцессовОтладчиков(); #Если Сервер И Не Сервер Тогда ИдентификаторыОтладчиков = Новый Массив; #КонецЕсли КонецЕсли; ТекстСкрипта = ПолучитьМакет("СкриптОткрытыеПриложения1С"); ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1")); ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя); КомандаСистемыЗапускаСкрипта = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя); РезультатСкрипта = ирОбщий.ВыполнитьКомандуОСЛкс(КомандаСистемыЗапускаСкрипта); ТаблицаКонфигураторов = ирОбщий.ТаблицаИзСтрокиСРазделителемЛкс(РезультатСкрипта,,, Истина); НачальноеЗначениеВыбора = Неопределено; СписокКонфигураторов = Новый СписокЗначений; Для Каждого СтрокаКонфигуратора Из ТаблицаКонфигураторов Цикл ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(СтрокаКонфигуратора.Id); Если Не ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС) Тогда Продолжить; КонецЕсли; ПредставлениеПроцесса = СтрокаКонфигуратора.MainWindowTitle; ЛиОтладчик = ИдентификаторыОтладчиков.Найти(СтрокаКонфигуратора.Id) <> Неопределено; Если ЛиОтладчик Тогда ПредставлениеПроцесса = "<Отладчик>" + ПредставлениеПроцесса; КонецЕсли; НовыйЭлемент = СписокКонфигураторов.Добавить(СтрокаКонфигуратора.Id, ПредставлениеПроцесса); Если ЛиОтладчик Тогда НачальноеЗначениеВыбора = НовыйЭлемент; КонецЕсли; КонецЦикла; Если СписокКонфигураторов.Количество() = 1 Тогда РезультатВыбора = СписокКонфигураторов[0]; ИначеЕсли СписокКонфигураторов.Количество() > 1 Тогда РезультатВыбора = СписокКонфигураторов.ВыбратьЭлемент("Выберите окно конфигуратора", НачальноеЗначениеВыбора); Иначе РезультатВыбора = Неопределено; КонецЕсли; Если РезультатВыбора <> Неопределено Тогда РезультатВыбора = РезультатВыбора.Значение; КонецЕсли; Возврат РезультатВыбора; КонецФункции // Открывает файл в конфигураторе. // // Параметры: // ПолноеИмя - Строка; // *ЭлементОбработки - "Форма", "Модуль", *Неопределено$ // *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе. // Процедура ОткрытьФайлВКонфигураторе(ПолноеИмя, ЭлементОбработки = "", ИдентификаторПроцесса = 0) Экспорт ПолучитьФайлОткрывателя1С(); ФайлВнешнейОбработки = Новый Файл(ПолноеИмя); Если ФайлВнешнейОбработки.Существует() Тогда СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """"; Если ЭлементОбработки = "Форма" Тогда СтрокаЗапуска = СтрокаЗапуска + " -cof"; ИначеЕсли ЭлементОбработки = "Модуль" Тогда СтрокаЗапуска = СтрокаЗапуска + " -com"; Иначе СтрокаЗапуска = СтрокаЗапуска + " -coa"; КонецЕсли; СтрокаЗапуска = СтрокаЗапуска + " -ob1""" + ПолноеИмя + """"; Если ИдентификаторПроцесса > 0 Тогда СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ="); КонецЕсли; WshShell().Run(СтрокаЗапуска, 0, Ложь); КонецЕсли; КонецПроцедуры // Открывает диалог глобального поиска в конфигураторе и устанавливает каталог файлов. // // Параметры: // КаталогРасположения - Строка; // *ИдентификаторПроцесса - Число, *0 - если указан, будет открываться только в заданном процессе. // Процедура ОткрытьДиалогГлобальногоПоискаВКонфигураторе(КаталогРасположения, ИдентификаторПроцесса = 0) Экспорт ПолучитьФайлОткрывателя1С(); СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """"; СтрокаЗапуска = СтрокаЗапуска + " -cgf"; СтрокаЗапуска = СтрокаЗапуска + " -ob1""" + КаталогРасположения + """"; Если ИдентификаторПроцесса > 0 Тогда СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ="); КонецЕсли; WshShell().Run(СтрокаЗапуска, 0, Ложь); КонецПроцедуры // ОткрытьДиалогГлобальногоПоискаВКонфигураторе() // Активизирует главное окно процесса по PID. // // Параметры: // *ИдентификаторПроцесса - Число. // Процедура АктивизироватьОкноПроцесса1С8(ИдентификаторПроцесса = 0) Экспорт ПолучитьФайлОткрывателя1С(); СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """"; СтрокаЗапуска = СтрокаЗапуска + " -aaa -pid" + Формат(ИдентификаторПроцесса, "ЧГ="); WshShell().Run(СтрокаЗапуска, 0, Ложь); КонецПроцедуры Процедура ПодключитьСвязанныйКонфигуратор(Знач ИД, Знач ИмяФайлаБуфера) Экспорт мСвязанныйКонфигуратор = Новый Структура("ИД, ИмяФайлаБуфера", ИД, ИмяФайлаБуфера); КонецПроцедуры Процедура АктивизироватьОкноКонфигуратора(Знач ПередаваемыйТекст = "") Экспорт АктивизироватьОкноПроцесса1С8(мСвязанныйКонфигуратор.ИД); ТекстДок = Новый ТекстовыйДокумент; ТекстДок.УстановитьТекст(ПередаваемыйТекст); ТекстДок.Записать(мСвязанныйКонфигуратор.ИмяФайлаБуфера); КонецПроцедуры // <Описание процедуры> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // Процедура СохранитьНастройкиАлгоритмов() Экспорт //ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ФиксироватьВнешниеИсключенияАлгоритмов", ФиксироватьВнешниеИсключенияАлгоритмов); ирОбщий.СохранитьЗначениеЛкс("ФиксироватьВнешниеИсключенияАлгоритмов", ФиксироватьВнешниеИсключенияАлгоритмов); //ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью); ирОбщий.СохранитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью); //ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки); ирОбщий.СохранитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки); ирОбщий.СохранитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование); //ирОбщий.СохранитьЗначениеЛкс("ирПлатформа.ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов", ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов); ирОбщий.СохранитьЗначениеЛкс("ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов", ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов); КонецПроцедуры // СохранитьНастройкиАлгоритмов() Функция ТаблицаРедактируемыхТиповИзОписанияТипов(ОписаниеТипов = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов = Новый ОписаниеТипов; #КонецЕсли ПоляКлюча = "Имя, URIПространстваИмен"; Если мТаблицаРедактируемыхТипов = Неопределено Тогда мТаблицаРедактируемыхТипов = РедактируемыеТипы.ВыгрузитьКолонки(); мТаблицаРедактируемыхТипов.Индексы.Добавить(ПоляКлюча); Для Каждого Тип Из ирОбщий.ОписаниеТиповВсеРедактируемыеТипыЛкс().Типы() Цикл СтрокаТипа = мТаблицаРедактируемыхТипов.Добавить(); //СтрокаТипа.Представление = "" + Тип; ТипXML = СериализаторXDTO.XMLТип(Тип); Если Тип = Тип("Число") Тогда СтрокаТипа.Порядок = -4; ИначеЕсли Тип = Тип("Строка") Тогда СтрокаТипа.Порядок = -3; ИначеЕсли Тип = Тип("Дата") Тогда СтрокаТипа.Порядок = -2; ИначеЕсли Тип = Тип("Булево") Тогда СтрокаТипа.Порядок = -1; ИначеЕсли Найти(ТипXML.ИмяТипа, ".") > 0 Тогда СтрокаТипа.Порядок = 100; ОбъектМД = Метаданные.НайтиПоТипу(Тип); ТекущееИмяТипа = ОбъектМД.ПолноеИмя(); ИмяТипаМетаданных = ирОбщий.ПервыйФрагментЛкс(ТекущееИмяТипа); СтрокаТипаМетаОбъектов = ОписаниеТипаМетаОбъектов(ИмяТипаМетаданных); Если СтрокаТипаМетаОбъектов <> Неопределено Тогда СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное; СтрокаТипа.Порядок = СтрокаТипаМетаОбъектов.Владелец().Индекс(СтрокаТипаМетаОбъектов); КонецЕсли; КонецЕсли; СтрокаТипа.Имя = ТипXML.ИмяТипа; СтрокаТипа.URIПространстваИмен = ТипXML.URIПространстваИмен; СтрокаТипа.Представление = "" + Тип; КонецЦикла; КонецЕсли; Если Ложь Или ОписаниеТипов = Неопределено Или ОписаниеТипов.Типы().Количество() = 0 Тогда НоваяТаблица = мТаблицаРедактируемыхТипов; Иначе СтрокиДляКопирования = Новый Массив; КлючПоиска = Новый Структура(ПоляКлюча); Для Каждого Тип Из ОписаниеТипов.Типы() Цикл ТипXML = СериализаторXDTO.XMLТип(Тип); Если ТипXML = Неопределено Тогда // Экзотические типы - Например НаправлениеСортировки Продолжить; КонецЕсли; КлючПоиска.Имя = ТипXML.ИмяТипа; КлючПоиска.URIПространстваИмен = ТипXML.URIПространстваИмен; Найденные = мТаблицаРедактируемыхТипов.НайтиСтроки(КлючПоиска); Если Найденные.Количество() = 0 Тогда // Экзотические типы - например ТипИзмеренияПостроителяОтчета Продолжить; КонецЕсли; СтрокиДляКопирования.Добавить(Найденные[0]); КонецЦикла; НоваяТаблица = мТаблицаРедактируемыхТипов.Скопировать(СтрокиДляКопирования); КонецЕсли; НоваяТаблица.Сортировать("Порядок, Представление"); Возврат НоваяТаблица; КонецФункции Функция ЛиКомпонентаFormsTextBoxДоступна() Экспорт Если ЛиКомпонентаFormsTextBoxДоступна = Неопределено Тогда ЛиКомпонентаFormsTextBoxДоступна = Истина; ИдентификаторКласса = "Forms.TextBox.1"; Попытка Пустышка = Новый COMОбъект(ИдентификаторКласса); Исключение ИмяМакетаДополнительнойБиблиотеки = "FM20ENU"; ИмяМакетаКомпоненты = "FM20"; Пустышка = ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки); Если Пустышка = Неопределено Тогда ТекстСообщения = "Для полной функциональности контекстной подсказки нужно выполнить одно из условий:"; #Если ТолстыйКлиентОбычноеПриложение Тогда Если Не ирКлиент.ЛиПерехватКлавиатурногоВводаВОбычномПриложенииЛкс() Тогда ТекстСообщения = ТекстСообщения + " |- Включить флажок ""Перехват клавиатурного ввода в обычном приложении"" в окне ""Список инструментов и общие настройки"""; КонецЕсли; #КонецЕсли ТекстСообщения = ТекстСообщения + " |- Использовать 32б приложение и зарегистрировать библиотеки FM20.dll и FM20ENU.dll из состава MS Office 97-2007. Это можно сделать с помощью формы ""Регистрация COM-компонент"" из состава подсистемы"; ирОбщий.СообщитьЛкс(ТекстСообщения); ЛиКомпонентаFormsTextBoxДоступна = Ложь; КонецЕсли; КонецПопытки; КонецЕсли; Возврат ЛиКомпонентаFormsTextBoxДоступна; КонецФункции #КонецЕсли //////////////////////////////////////////////////////////////////////////////////////////////////// // Получает новый экземпляр ком-объекта парсера. // // Параметры: // Нет. // // Возвращаемое значение: // Com-объект, Неопределено. // Функция мПолучитьПарсер(ИмяГрамматики, Кэшировать = Истина, СообщениеПользователюПриНеудаче = "") Экспорт Если Кэшировать Тогда Если Парсеры.Свойство(ИмяГрамматики) Тогда Парсер = Парсеры[ИмяГрамматики]; Если Парсер <> Неопределено Тогда Парсер.Restart(); // Без этого что то не очищается и приводит к зависанию парсинга. КонецЕсли; Возврат Парсер; КонецЕсли; КонецЕсли; Парсер = ПолучитьCOMОбъектИзМакета("GoldParser", "GoldParserForNet.Parser"); // Новый Parser Если Парсер <> Неопределено Тогда Парсер.TrimReductions = Истина; МакетГрамматики = ПолучитьМакет(ИмяГрамматики); ФайлСкомпилированнойГрамматики = ПолучитьИмяВременногоФайла("cgt"); МакетГрамматики.Записать(ФайлСкомпилированнойГрамматики); Если Не Парсер.LoadCompiledGrammar(ФайлСкомпилированнойГрамматики) Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Не удалось загрузить файл грамматики """ + ФайлСкомпилированнойГрамматики + """", Истина, СтатусСообщения.Важное); Парсер = Неопределено; КонецЕсли; УдалитьФайлы(ФайлСкомпилированнойГрамматики); Иначе ирОбщий.СообщитьЛкс(СообщениеПользователюПриНеудаче, СтатусСообщения.Внимание); КонецЕсли; Если Кэшировать Тогда Парсеры.Вставить(ИмяГрамматики, Парсер); КонецЕсли; Возврат Парсер; КонецФункции // <Описание процедуры> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // Процедура ПроверитьСтруктуруФайловогоКэша() Экспорт ПроверитьКаталогФайловогоКэша(); СтруктураПодкаталоговФайловогоКэша = Новый Структура; СтруктураПодкаталоговФайловогоКэша.Вставить("a"); // Внешние обработки алгоритмов //СтруктураПодкаталоговФайловогоКэша.Вставить("b"); // Внешние обработки архива 2iS СтруктураПодкаталоговФайловогоКэша.Вставить("c"); // Внешние компоненты СтруктураПодкаталоговФайловогоКэша.Вставить("КэшМодулей"); СтруктураПодкаталоговФайловогоКэша.Вставить("КэшРолей"); Разделитель = ирОбщий.РазделительПутиКФайлуЛкс(); Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл ПолныйПутьКаталога = КаталогФайловогоКэша + Разделитель + ЭлементПодкаталога.Ключ; ФайлКаталога = Новый Файл(ПолныйПутьКаталога); Если Не ФайлКаталога.Существует() Тогда Попытка СоздатьКаталог(ФайлКаталога.ПолноеИмя); ПробныйФайл = Новый ТекстовыйДокумент; ПробныйФайл.Записать(ФайлКаталога.ПолноеИмя + Разделитель + "1.txt"); Исключение ОписаниеОшибки = ОписаниеОшибки(); Сообщить("Файловый кэш """ + ЭлементПодкаталога.Ключ + """ отключен из-за ошибки: " + ОписаниеОшибки, СтатусСообщения.Важное); // При использовании ирОбщий.СообщитьЛкс() может происходить переполнение стека Продолжить; КонецПопытки; КонецЕсли; СтруктураПодкаталоговФайловогоКэша[ЭлементПодкаталога.Ключ] = ФайлКаталога; Если ЭлементПодкаталога.Ключ = "a" Тогда //КаталогДинамическихВнешнихОбработок = ПолныйПутьКаталога; ПапкаКешаВнешнихОбработокАлгоритмов = ФайлКаталога; ТекущаяДатаДвижка = Дата("20100927"); // Здесь меняем редко. Будет приводить к разовой очистке кэша перед началом его использования ФайлКэшаДвижка = Новый Файл(ПолныйПутьКаталога + Разделитель + "_EngineTimeStamp.mll"); ДатаКэшаДвижка = Неопределено; Если ФайлКэшаДвижка.Существует() Тогда Попытка ДатаКэшаДвижка = ЗначениеИзФайла(ФайлКэшаДвижка.ПолноеИмя); Исключение КонецПопытки; КонецЕсли; Если ДатаКэшаДвижка <> ТекущаяДатаДвижка Тогда Попытка УдалитьФайлы(ПолныйПутьКаталога + Разделитель, "*.*"); Исключение Неудача = Истина; КонецПопытки; Если Неудача <> Истина Тогда ЗначениеВФайл(ФайлКэшаДвижка.ПолноеИмя, ТекущаяДатаДвижка); КонецЕсли; КонецЕсли; //ИначеЕсли ЭлементПодкаталога.Ключ = "b" Тогда // ПапкаКешаВнешнихОбработокАрхива = ФайлКаталога; ИначеЕсли ЭлементПодкаталога.Ключ = "c" Тогда ПапкаВнешнихКомпонент = ФайлКаталога; ИначеЕсли ЭлементПодкаталога.Ключ = "КэшМодулей" Тогда ПапкаКэшаМодулей = ФайлКаталога; ИначеЕсли ЭлементПодкаталога.Ключ = "КэшРолей" Тогда ПапкаКэшаРолей = ФайлКаталога; КонецЕсли; КонецЦикла; ПутьККаталогуСлужебныхВременныхФайлов = КаталогВременныхФайлов() + "temp1template\"; СоздатьКаталог(ПутьККаталогуСлужебныхВременныхФайлов); МассивЗамков = НайтиФайлы(ПутьККаталогуСлужебныхВременныхФайлов, "*.lck"); Для Каждого Замок Из МассивЗамков Цикл Попытка УдалитьФайлы(Замок.ПолноеИмя); УдалитьФайлы(Замок.Путь + Замок.ИмяБезРасширения); Исключение КонецПопытки; КонецЦикла; НастройкиКомпьютера(); КонецПроцедуры Функция ФайлРоли(Знач ИмяРоли) Экспорт ФайлРоли = Новый Файл("" + ПапкаКэшаРолей.ПолноеИмя + "\Role." + ИмяРоли + ".Rights.xml"); Возврат ФайлРоли; КонецФункции Функция СловарьПеревода() Экспорт Если СловарьПеревода = Неопределено Тогда Результат = ПолучитьМакет("РусскийАнглийский"); СловарьПеревода = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(Результат,,,,,,, Истина); ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(СловарьПеревода, "Русский"); ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(СловарьПеревода, "Английский"); КонецЕсли; Возврат СловарьПеревода; КонецФункции Функция ПеревестиСтроку(РусскаяСтрока, Принудительно = Ложь) Экспорт Если Не Принудительно И Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда Возврат РусскаяСтрока; Иначе Словарь = СловарьПеревода(); СтрокаПеревода = Словарь.Найти(НРег(РусскаяСтрока), "НРусский"); Если СтрокаПеревода = Неопределено Тогда Английский = РусскаяСтрока; Иначе Английский = СтрокаПеревода.Английский; КонецЕсли; Возврат Английский; КонецЕсли; КонецФункции Функция ПеревестиВРусский(ЛокальнаяСтрока, Принудительно = Ложь) Экспорт Если Не Принудительно И Метаданные.ВариантВстроенногоЯзыка = Метаданные.СвойстваОбъектов.ВариантВстроенногоЯзыка.Русский Тогда Возврат ЛокальнаяСтрока; Иначе Словарь = СловарьПеревода(); СтрокаПеревода = Словарь.НайтиСтроки(Новый Структура("НАнглийский", НРег(ЛокальнаяСтрока))); КоличествоПереводов = СтрокаПеревода.Количество(); Если КоличествоПереводов = 0 Тогда Русский = ЛокальнаяСтрока; Иначе Русский = СтрокаПеревода[0].Русский; Если КоличествоПереводов > 1 Тогда ирОбщий.СообщитьЛкс("Неоднозначный перевод на русский идентификатора """ + ЛокальнаяСтрока + """", СтатусСообщения.Внимание); КонецЕсли; КонецЕсли; Возврат Русский; КонецЕсли; КонецФункции Функция ТекстРезультатаКомандыСистемы(Знач Команда = "", Знач ИмяСервера = "", Элевация = Ложь) Экспорт Если Не ЗначениеЗаполнено(ИмяСервера) Тогда ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла()); СтрокаЗапуска = Команда; ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(СтрокаЗапуска, ФайлРезультата.Путь, ФайлРезультата.Имя, , Элевация); Если ФайлРезультата.Существует() Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя, КодировкаТекста.OEM); УдалитьФайлы(ФайлРезультата.ПолноеИмя); Результат = ТекстовыйДокумент.ПолучитьТекст(); Иначе Результат = "Файл результата команды системы не найден! Попробуйте отключить антивирусное ПО."; КонецЕсли; Иначе ВызватьИсключение "Получение результата команды системы на удаленном сервере не реализовано"; КонецЕсли; Возврат Результат; КонецФункции Функция ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ПолноеИмяDll, Административная = Ложь, ИмяТипаВК = Ложь, ИмяМакетаКомпоненты = "", Знач Зарегистрировать = Истина) Экспорт Если ирКэш.Это64битныйПроцессЛкс() Тогда ТипПроцесса = "64"; Иначе ТипПроцесса = "32"; КонецЕсли; Если Найти(КлассКомпоненты, "ForNet") > 0 Тогда ТипCOMКомпоненты = "-Net"; Иначе ТипCOMКомпоненты = ""; КонецЕсли; Если Зарегистрировать Тогда ПрефикДействия = "За"; Иначе ПрефикДействия = "Раз"; КонецЕсли; Если Истина И Не Административная И Зарегистрировать И ЗначениеЗаполнено(ИмяМакетаКомпоненты) Тогда Если Метаданные().Макеты.Найти(ИмяМакетаКомпоненты + "Reg") <> Неопределено Тогда // http://stackoverflow.com/questions/37193356/registering-net-com-dlls-without-admin-rights-regasm // http://stackoverflow.com/questions/35782404/registering-a-com-without-admin-rights СкриптРегистрации = ПолучитьМакет(ИмяМакетаКомпоненты + "Reg").ПолучитьТекст(); СкриптРегистрации = ирОбщий.СтрЗаменитьЛкс(СкриптРегистрации, "HKEY_CLASSES_ROOT", "HKEY_CURRENT_USER\Software\Classes"); РезультатКоманды = ВнестиФайлCOMКомпонентыВРеестр(СкриптРегистрации, СтрЗаменить(ПолноеИмяDll, "\", "/")); Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК); Если Компонента <> Неопределено Тогда ирОбщий.СообщитьЛкс(ПрефикДействия + "регистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; Иначе ирОбщий.СообщитьЛкс(РезультатКоманды); КонецЕсли; КонецЕсли; КонецЕсли; Если ТипCOMКомпоненты = "-Net" Тогда Если Административная Тогда Если ФайлРегистратораNetКомпонент = Неопределено Тогда ФайлРегистратораNetКомпонент = ПроверитьЗаписатьКомпонентуИзМакетаВФайл("RegasmExeWin" + ТипПроцесса, , "exe"); КонецЕсли; КоманднаяСтрока = """" + ФайлРегистратораNetКомпонент.ПолноеИмя + """ """ + ПолноеИмяDll + """ /unregister"; // сначала надо отменить регистрацию, иначе новая может не выполниться ИмяФайлаРезультата = ""; РезультатКоманды = ТекстРезультатаКомандыСистемы(КоманднаяСтрока,, Административная); Если Зарегистрировать Тогда КоманднаяСтрока = """" + ФайлРегистратораNetКомпонент.ПолноеИмя + """ """ + ПолноеИмяDll + """ /codebase"; ИмяФайлаРезультата = ""; РезультатКоманды = ТекстРезультатаКомандыСистемы(КоманднаяСтрока,, Административная); Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК); КонецЕсли; Если Компонента <> Неопределено Тогда ирОбщий.СообщитьЛкс(ПрефикДействия + "регистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; Иначе ирОбщий.СообщитьЛкс(РезультатКоманды); КонецЕсли; КонецЕсли; Иначе Если Административная Тогда // HKLM КоманднаяСтрока = "regsvr32 /s """ + ПолноеИмяDll + """"; Если Не Зарегистрировать Тогда КоманднаяСтрока = КоманднаяСтрока + " /u"; КонецЕсли; //ТекстРезультата = ТекстРезультатаКомандыСистемы(КоманднаяСтрока); ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(КоманднаяСтрока,,,, Административная); Компонента = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК); Если Компонента <> Неопределено Тогда ирОбщий.СообщитьЛкс(ПрефикДействия + "регистрирована COM" + ТипCOMКомпоненты + "-компонента " + КлассКомпоненты, СтатусСообщения.Информация); Возврат Компонента; КонецЕсли; КонецЕсли; КонецЕсли; //Если ирКэш.Это64битныйПроцессЛкс() Тогда // ирОбщий.СообщитьЛкс("Невозможно загрузить 32-битную COM" + ТипCOMКомпоненты + "-компоненту " + КлассКомпоненты + " в 64-битном приложении. Запустите 32-битное приложение.", СтатусСообщения.Внимание); //Иначе ТекстСообщения = "Не удалось " + ПрефикДействия + "регистрировать COM" + ТипCOMКомпоненты + "-компоненту " + КлассКомпоненты; Если Истина И Административная И (Ложь Или ирОбщий.ВКОбщаяЛкс().IsAdmin() //Или ЕстьАдминистративныеПраваУУчетнойЗаписиОС() ) Тогда ТекстСообщения = ТекстСообщения + " от имени администратора!" Иначе ТекстСообщения = ТекстСообщения + ". Запустите приложение от имени администратора или используйте инструмент ""Регистрация COM-компонент"", чтобы ее " + ПрефикДействия + "регистрировать" КонецЕсли; //КонецЕсли; ирОбщий.СообщитьЛкс(ТекстСообщения, СтатусСообщения.Внимание); Возврат Неопределено; КонецФункции Функция ВнестиФайлCOMКомпонентыВРеестр(Знач СкриптРегистрации, Знач ПолноеИмяDll, Знач ИдентификаторКласса = "", Знач x64 = Неопределено) Экспорт Если x64 = Неопределено Тогда x64 = ирКэш.Это64битныйПроцессЛкс(); КонецЕсли; СкриптРегистрации = ирОбщий.СтрЗаменитьЛкс(СкриптРегистрации, "%ComDllFilename%", ПолноеИмяDll); Если ЗначениеЗаполнено(ИдентификаторКласса) Тогда СкриптРегистрации = ирОбщий.СтрЗаменитьЛкс(СкриптРегистрации, "%ComDllCLSID%", ИдентификаторКласса); КонецЕсли; ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("reg"); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(СкриптРегистрации); ТекстовыйДокумент.Записать(ИмяФайлаСкрипта, КодировкаТекста.ANSI); //РезультатКоманды = ТекстРезультатаКомандыСистемы("regedit /s """ + ИмяФайлаСкрипта + """); // Поддержка Windows XP РезультатКоманды = ТекстРезультатаКомандыСистемы("reg import """ + ИмяФайлаСкрипта + """ /reg:" + ?(x64, "64", "32")); // Windows Vista и выше Возврат РезультатКоманды; КонецФункции Функция ПолучитьПроверитьCOMОбъект(Знач КлассКомпоненты, ИмяТипаВК = "") Экспорт Если ЗначениеЗаполнено(ИмяТипаВК) Тогда ПодключитьВнешнююКомпоненту(КлассКомпоненты); Попытка Компонента = Новый ("AddIn." + ИмяТипаВК); Исключение КонецПопытки; Возврат Компонента; Иначе Попытка Компонента = Новый COMОбъект(КлассКомпоненты); Если КлассКомпоненты = "GoldParserForNet.Parser" Тогда Попытка Если Компонента.Version = "5.08" Тогда Возврат Компонента; КонецЕсли; Исключение Компонента = Неопределено; КонецПопытки; Иначе Возврат Компонента; КонецЕсли; Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки КонецПопытки; КонецЕсли; Возврат Неопределено; КонецФункции // Возвращает нужный com-объект. Если компонента не зарегистрирована, то пытается ее сохранить из макета и зарегистрировать. // // Параметры: // Нет. // // Возвращаемое значение: // COM-объект, Неопределено. // Функция ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, КлассКомпоненты, КаталогУстановки = "авто", ИмяМакетаДополнительнойБиблиотеки = "", ИмяТипаВК = "") Экспорт Результат = ПолучитьПроверитьCOMОбъект(КлассКомпоненты, ИмяТипаВК); Если Результат = Неопределено И АвторегистрацияComКомпонент Тогда Если Нрег(КаталогУстановки) = Нрег("авто") Тогда КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя; КонецЕсли; #Если Клиент Тогда Если КаталогУстановки = "" Тогда Ответ = Вопрос("Для работы данной функции необходимо зарегистрировать //|(необходимы права локального администратора) | COM-компоненту """ + ИмяМакетаКомпоненты + """. Выполнить регистрацию?", РежимДиалогаВопрос.ОКОтмена, 30, КодВозвратаДиалога.Отмена); Если Ответ = КодВозвратаДиалога.Отмена Тогда Возврат Неопределено; КонецЕсли; ВыборФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); ВыборФайла.Заголовок = "Укажите папку, куда установить компоненту."; Если Не ВыборФайла.Выбрать() Тогда Возврат Неопределено; КонецЕсли; КаталогУстановки = ВыборФайла.Каталог; КонецЕсли; #КонецЕсли ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты, КаталогУстановки); Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки, КаталогУстановки); КонецЕсли; Результат = ЗарегистрироватьПолучитьCOMОбъект(КлассКомпоненты, ФайлКомпоненты.ПолноеИмя, , ИмяТипаВК, ИмяМакетаКомпоненты); КонецЕсли; Возврат Результат; КонецФункции // Параметры: // ИмяКомпоненты - Строка - имя макета компоненты // КлассКомпоненты - Строка - имя // ТипВнешнейКомпоненты - ТипВнешнейКомпоненты, * - по умолчанию Native Функция ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, ИмяОбъекта, ИмяКомпоненты = Неопределено, Знач ТипКомпоненты = Неопределено, ИмяМакетаДополнительнойБиблиотеки = "") Экспорт Если ТипКомпоненты = Неопределено Тогда ТипКомпоненты = ТипВнешнейКомпоненты.Native; КонецЕсли; Попытка Результат = Новый (ИмяОбъекта); Исключение Если ИмяКомпоненты = Неопределено Тогда ИмяКомпоненты = ИмяМакетаКомпоненты; КонецЕсли; Если КодСимвола(ИмяМакетаКомпоненты, 1) >= 128 Тогда // https://www.hostedredmine.com/issues/890335 ВызватьИсключение "Нельзя использовать кириллические буквы в именах файлов внешних компонент"; КонецЕсли; ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты); Местоположение = ФайлКомпоненты.ПолноеИмя; Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда ФайлДополнительнойБиблиотеки = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки); КонецЕсли; Успех = ПодключитьВнешнююКомпоненту(Местоположение, ИмяКомпоненты, ТипКомпоненты); ПодключитьВнешнююКомпоненту(ИмяОбъекта); Попытка Результат = Новый (ИмяОбъекта); Исключение КонецПопытки; КонецПопытки; Возврат Результат; КонецФункции Функция ПроверитьЗаписатьКомпонентуИзМакетаВФайл(Знач ИмяМакетаКомпоненты, КаталогУстановки = "", Расширение = "dll") Экспорт Если Не ЗначениеЗаполнено(КаталогУстановки) Тогда КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя; КонецЕсли; ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты); ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "." + Расширение); ВременныйФайл = Новый Файл(ПолучитьИмяВременногоФайла()); Попытка ДвоичныеДанныеМакета.Записать(ВременныйФайл.ПолноеИмя); Исключение ирОбщий.СообщитьЛкс("Не удалось создать временный файл компоненты """ + ИмяМакетаКомпоненты + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат Неопределено; КонецПопытки; Счетчик = 1; ФайлПодходит = Ложь; Пока ФайлКомпоненты.Существует() Цикл #Если Клиент Тогда СравнениеФайлов = Новый СравнениеФайлов; СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное; СравнениеФайлов.ПервыйФайл = ВременныйФайл.ПолноеИмя; СравнениеФайлов.ВторойФайл = ФайлКомпоненты.ПолноеИмя; Если СравнениеФайлов.Сравнить() Тогда ФайлПодходит = Истина; Прервать; КонецЕсли; #Иначе // Внешняя компонента может собираться с одинаковым размером (сборщик ее дополняет пустотой до нужного размера) //Если ВременныйФайл.Размер() = ФайлКомпоненты.Размер() Тогда // Опасно. Переделать на Хэш // ФайлПодходит = Истина; // Прервать; //КонецЕсли; #КонецЕсли Попытка УдалитьФайлы(ФайлКомпоненты.ПолноеИмя); Исключение ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "_" + Формат(Счетчик, "ЧГ=") + "." + Расширение); Счетчик = Счетчик + 1; КонецПопытки; КонецЦикла; Если Не ФайлПодходит Тогда Попытка ПереместитьФайлКакАдминистратор(ВременныйФайл.ПолноеИмя, ФайлКомпоненты.ПолноеИмя); Исключение УдалитьФайлы(ВременныйФайл.ПолноеИмя); ирОбщий.СообщитьЛкс("Файл """ + ФайлКомпоненты.ПолноеИмя + """ недоступен для изменения и не был перезаписан.", СтатусСообщения.Внимание); Возврат Неопределено; КонецПопытки; КонецЕсли; Возврат ФайлКомпоненты; КонецФункции // Способ через ZIP архив (32+64) появился только в 8.3 Функция ПолучитьДвоичныеДанныеКомпоненты(БазовоеИмяМакетаКомпоненты) Экспорт Если Метаданные().Макеты.Найти(БазовоеИмяМакетаКомпоненты) = Неопределено Тогда Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Win"; Иначе БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Lin"; КонецЕсли; Если ирКэш.Это64битныйПроцессЛкс() Тогда БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "64"; Иначе БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "32"; КонецЕсли; КонецЕсли; ДвоичныеДанныеМакета = ПолучитьМакет(БазовоеИмяМакетаКомпоненты); Возврат ДвоичныеДанныеМакета; КонецФункции // <Описание функции> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция СоздатьОбъектВнешнихМетаданных(ПолноеИмяФайла, МенеджерВнешнихОбъектов = Неопределено, Конвертировать = Истина) Экспорт Если МенеджерВнешнихОбъектов = Неопределено Тогда МенеджерВнешнихОбъектов = ВнешниеОбработки; КонецЕсли; Попытка ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь); Исключение #Если Клиент Тогда ОписаниеОшибки = ОписаниеОшибки(); Если Истина И Конвертировать И Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитан")) > 0 //И ирКэш.НомерВерсииПлатформыЛкс() <> 802015 // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164 Тогда СтрокаЗапуска = "DESIGNER /ConvertFiles""" + ПолноеИмяФайла + """"; ЗапуститьСистему(СтрокаЗапуска, Истина); ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь); Иначе #КонецЕсли ВызватьИсключение; #Если Клиент Тогда КонецЕсли; #КонецЕсли КонецПопытки; Возврат ВнешнийОбъект; КонецФункции // <Описание функции> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция СоздатьВнешнююОбработкуАлгоритма(АлгоритмОбъект, ПолноеИмя) Экспорт Попытка ВнешняяОбработка = СоздатьОбъектВнешнихМетаданных(ПолноеИмя); Результат = ВнешняяОбработка; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке); Если Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитана текущей версией")) > 0 Тогда УдалитьФайлы(ПолноеИмя); КонецЕсли; СобытиеОшибки = "Ошибка создания внешнего объекта"; ОписаниеОшибки = "Загрузка сервиса """ + АлгоритмОбъект.Наименование + """"; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + " |" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина); КонецЕсли; ОписаниеОшибки = СобытиеОшибки + ": " + ОписаниеОшибки; ОписаниеОшибки = ОписаниеОшибки + ": " + ИнформацияОбОшибке.Описание + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока; ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Важное); ЗаписьЖурналаРегистрации(СобытиеОшибки, УровеньЖурналаРегистрации.Ошибка, Метаданные.НайтиПоТипу(ТипЗнч(АлгоритмОбъект.Ссылка)), АлгоритмОбъект.Ссылка, ОписаниеОшибки); Результат = Неопределено; КонецПопытки; Возврат Результат; КонецФункции // СоздатьВнешнююОбработкуАлгоритма() // Проверяет актуальность кэша. Вызывается когда кэш в памяти уже точно не соотвествует объекту БД. // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта, КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшДопускаетРедактирование) Экспорт Попытка ДатаИзмененияФайла = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс(); ФайлВнешнейОбработкиСуществует = Истина; Исключение ФайлВнешнейОбработкиСуществует = Ложь; КонецПопытки; Если ФайлВнешнейОбработкиСуществует Тогда Если Истина И ЭлементКэша <> Неопределено И ЭлементКэша.ДатаИзменения >= ДатаИзмененияФайла И ЭлементКэша.ДатаИзменения >= ДатаИзмененияОбъекта Тогда КэшВнешнейОбработкиАктуален = Истина; ИначеЕсли Ложь Или (Истина И ЭлементКэша = Неопределено И ДатаИзмененияФайла = ДатаИзмененияОбъекта) Или (Истина И ЭлементКэша <> Неопределено И ДатаИзмененияФайла = ЭлементКэша.ДатаИзменения И ДатаИзмененияФайла = ДатаИзмененияОбъекта) Или (Истина И ФайловыйКэшДопускаетРедактирование И (Ложь Или (Истина И ЭлементКэша = Неопределено И ДатаИзмененияФайла >= ДатаИзмененияОбъекта) Или (Истина И ЭлементКэша <> Неопределено И ДатаИзмененияФайла >= ЭлементКэша.ДатаИзменения И ДатаИзмененияФайла >= ДатаИзмененияОбъекта))) Тогда ФайлВнешнейОбработкиАктуален = Истина; ДатаИзмененияКэша = ДатаИзмененияФайла; КонецЕсли; КонецЕсли; КонецФункции // ПроверитьАктуальностьКэшаВнешнейОбработки() // <Описание процедуры> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // Функция РазвернутьНовыйШаблонВнешнейОбработки(СМакетом = Ложь, ГлобальныйКлюч = Неопределено, ФайлСИменем, ТекстПотокаСИменем, Знач ДляИДВерсииПлатформы = "") Экспорт Если ПустаяСтрока(ДляИДВерсииПлатформы) Тогда ДляИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс(); КонецЕсли; Если ДляИДВерсииПлатформы = "83" Тогда ДляИДВерсииПлатформы = "82"; КонецЕсли; Если ГлобальныйКлюч = Неопределено Тогда ГлобальныйКлюч = "" + Новый УникальныйИдентификатор; КонецЕсли; лПутьКШаблонуВнешнейОбработки = ПутьККаталогуСлужебныхВременныхФайлов + ГлобальныйКлюч; Файл = Новый Файл(ПолучитьИмяВременногоФайла()); //ПолучитьМакет("ВнешняяОбработка").Записать(Файл.ПолноеИмя); Если СМакетом Тогда ИмяМакета = "ШаблонВнешнейОбработкиСМакетом"; Иначе ИмяМакета = "ШаблонВнешнейОбработкиСервиса"; КонецЕсли; ИмяМакета = ИмяМакета + ДляИДВерсииПлатформы; ПолучитьМакет(ИмяМакета).Записать(Файл.ПолноеИмя); ЧтениеZip = Новый ЧтениеZipФайла(Файл.ПолноеИмя); ЧтениеZip.ИзвлечьВсе(лПутьКШаблонуВнешнейОбработки); ФайлСИменем = Новый Файл(лПутьКШаблонуВнешнейОбработки + ирОбщий.РазделительПутиКФайлуЛкс() + СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки); ПотокСИменемОбработки = Новый ТекстовыйДокумент; ПотокСИменемОбработки.Прочитать(ФайлСИменем.ПолноеИмя); ТекстПотокаСИменем = ПотокСИменемОбработки.ПолучитьТекст(); СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(лПутьКШаблонуВнешнейОбработки); Возврат лПутьКШаблонуВнешнейОбработки; КонецФункции Процедура СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(Каталог, выхИмяКомандногоФайла = "") Экспорт Если Не ЗначениеЗаполнено(выхИмяКомандногоФайла) Тогда выхИмяКомандногоФайла = "pack.bat"; КонецЕсли; Разделитель = ирОбщий.РазделительПутиКФайлуЛкс(); ПодготовитьПакер(Каталог); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(" |FOR /D %%I IN (*.unp) DO " + ИмяФайлаПакера + " -pack %%I %%~nI |FOR %%I IN (*.und) DO " + ИмяФайлаПакера + " -deflate %%I %%~nI |" + ИмяФайлаПакера + " -pack .\ %1"); ТекстовыйДокумент.Записать(Каталог + Разделитель + выхИмяКомандногоФайла, КодировкаТекста.ANSI); КонецПроцедуры Процедура ПодготовитьПакер(Знач Каталог) Разделитель = ирОбщий.РазделительПутиКФайлуЛкс(); Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда ДвоичныеДанны = ПолучитьМакет("V8unpackExeWin"); ПолучитьМакет("Zlib1").Записать(Каталог + Разделитель + "Zlib1.dll"); Иначе //Если ирКэш.Это64битнаяОСЛкс() Тогда // Зависит от COM Если ирКэш.Это64битныйПроцессЛкс() Тогда // В Linux равнозначно ирКэш.Это64битнаяОСЛкс() ДвоичныеДанны = ПолучитьМакет("V8unpackExeLinux64"); Иначе ирОбщий.СообщитьЛкс("Механизм распаковки файлов платформы 1С для Linux не поддерживает 32-разрядные ОС"); Возврат; КонецЕсли; КонецЕсли; ПолноеИмяФайла = Каталог + ?(Прав(Каталог, 1) = Разделитель, "", Разделитель) + ИмяФайлаПакера; ДвоичныеДанны.Записать(ПолноеИмяФайла); Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда ирОбщий.ВыполнитьКомандуОСЛкс("chmod +x " + ПолноеИмяФайла); // Установим признак "Исполняемый файл" КонецЕсли; КонецПроцедуры Процедура УпаковатьФайлВнешнейОбработки(КаталогРаспаковки, ПолноеИмяФайлаВнешнейОбработки) Экспорт Если ирОбщий.ПроверитьПлатформаНеWindowsЛкс() Тогда Возврат; КонецЕсли; ИмяКомандногоФайла = ""; СоздатьКомандныйФайлДляУпаковкиФайлаВнешнейОбработки(КаталогРаспаковки, ИмяКомандногоФайла); ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(ИмяКомандногоФайла + " """ + ПолноеИмяФайлаВнешнейОбработки + """", КаталогРаспаковки); КонецПроцедуры // ПолноеИмяФайла - не должно содержать не английских букв Процедура РаспаковатьФайлВнешнейОбработки(ПолноеИмяФайла, ПутьРаспаковки) Экспорт Разделитель = ирОбщий.РазделительПутиКФайлуЛкс(); ПодготовитьПакер(ПутьРаспаковки); ИмяФайлаЛога = "unpack.log"; Если Истина //И Ложь // Для отладки И ирКэш.ЛиПлатформаWindowsЛкс() И ирКэш.ЛиДоступноВыполнениеКомандныхФайловЛкс() Тогда ИмяКомандногоФайла = "unpack.bat"; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(" |" + ИмяФайлаПакера + " -unpack %1 .\ |FOR %%I IN (*.data) DO " + ИмяФайлаПакера + " -undeflate %%I %%~nI.data.und |FOR %%I IN (*.und) DO " + ИмяФайлаПакера + " -unpack %%I %%~nI.und.unp |"); ПолноеИмяКомандногоФайла = ПутьРаспаковки + Разделитель + ИмяКомандногоФайла; ТекстовыйДокумент.Записать(ПолноеИмяКомандногоФайла, КодировкаТекста.ANSI); ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(ИмяКомандногоФайла + " """ + ПолноеИмяФайла + """", ПутьРаспаковки, ИмяФайлаЛога); Иначе // Под Windows этот способ медленнее в 5 раз // У версии под Linux немного отличаются параметры запуска по сравнению с Windows https://github.com/e8tools/v8unpack ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("./" + ИмяФайлаПакера + " -unpack """ + ПолноеИмяФайла + """ ./", ПутьРаспаковки, ИмяФайлаЛога,,, Истина); Для Каждого Файл Из НайтиФайлы(ПутьРаспаковки, "*.data") Цикл #Если Сервер И Не Сервер Тогда Файл = Новый Файл; #КонецЕсли // Можно наверное ускорить созданием командного файла ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("./" + ИмяФайлаПакера + " -undeflate " + Файл.Имя + " " + Файл.Имя + ".und", ПутьРаспаковки, ИмяФайлаЛога,,, Истина); ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("./" + ИмяФайлаПакера + " -unpack " + Файл.Имя + ".und " + Файл.Имя + ".und.unp", ПутьРаспаковки, ИмяФайлаЛога,,, Истина); КонецЦикла; КонецЕсли; ЧитатьЛог = Ложь; // Для отладки Если ЧитатьЛог Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ПутьРаспаковки + Разделитель + ИмяФайлаЛога, ирОбщий.СистемнаяКодировкаТекстаОСЛкс()); ТекстЛога = ТекстовыйДокумент.ПолучитьТекст(); КонецЕсли; УдалитьФайлы(ИмяФайлаЛога); КонецПроцедуры Функция ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки() Экспорт ИспользоватьБыстрыйГенератор = Истина; Если ирОбщий.СтрокиРавныЛкс(ирКэш.ТекущийСеансЛкс().ИмяПриложения, "1cv8") Тогда // Антибаг 8.3.11-?. Testplatform@1c.ru - Support #17972. В обычном приложении на клиенте при повторном создании с одним именем файла и внутренней версией используются метаданные первой обработки в сеансе. // Начиная с 8.3.11 кэширование внешних обработок проверяет только Ид версии, которые в старом способе не меняются, поэтому на 8.3.11+ используется штатный долгий метод генерации внешней обработки ИспользоватьБыстрыйГенератор = ирКэш.НомерВерсииПлатформыЛкс() < 803011; КонецЕсли; Возврат ИспользоватьБыстрыйГенератор; КонецФункции // <Описание функции> // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция СформироватьВнешнююОбработку(Знач ФайлОбработки, Знач ИмяОбработки, Знач ТекстМодуля, Знач ТекстМакета = Неопределено, Знач ДляИДВерсииПлатформы = "", ИспользоватьБыструюРаспаковку = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ФайлОбработки = Новый файл; #КонецЕсли //Если ИспользоватьБыструюРаспаковку = Неопределено Тогда // ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки(); //КонецЕсли; ИспользоватьБыструюРаспаковку = Истина; // используется шаблон с макетом, то там надо добавить файл versions.data.und - https://github.com/e8tools/v8unpack/issues/69 Если Не ИспользоватьБыструюРаспаковку Тогда // Штатный способ платформы, но работает только на 8.3.8+ Если ТекстМакета <> Неопределено Тогда ВызватьИсключение "Парамер ТекстМакета для 8.3.11+ не поддерживается"; КонецЕсли; ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки["8"]; Если ШаблонВнешнейОбработки = Неопределено Тогда ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf"); ПолучитьМакет("ВнешняяОбработка").Записать(ИмяВременногоФайла); ШаблонВнешнейОбработки = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ШаблонВнешнейОбработки); ТекстЛога = Неопределено; Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ШаблонВнешнейОбработки + """ """ + ИмяВременногоФайла + """",, ТекстЛога, Истина,,,,,,, Ложь) Тогда УдалитьФайлы(ШаблонВнешнейОбработки); УдалитьФайлы(ИмяВременногоФайла); ирОбщий.СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; ШаблоныВнешнейОбработки["8"] = ШаблонВнешнейОбработки; КонецЕсли; Файлы = НайтиФайлы(ШаблонВнешнейОбработки, "ObjectModule.bsl", Истина); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстМодуля); ТекстовыйДокумент.Записать(Файлы[0].ПолноеИмя); ТекстЛога = Неопределено; ИмяКорневогоФайла = ШаблонВнешнейОбработки + ирОбщий.РазделительПутиКФайлуЛкс() + "ИмяВнешнейОбработки.xml"; Если ЗначениеЗаполнено(ИмяОбработки) Тогда ПотокСИменемОбработки = Новый ТекстовыйДокумент; ПотокСИменемОбработки.Прочитать(ИмяКорневогоФайла); ПотокСИменемОбработки.УстановитьТекст(СтрЗаменить(ПотокСИменемОбработки.ПолучитьТекст(), "ИмяВнешнейОбработки", ИмяОбработки)); ПотокСИменемОбработки.Записать(ИмяКорневогоФайла); КонецЕсли; Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadExternalDataProcessorOrReportFromFiles """ + ИмяКорневогоФайла + """ """ + ФайлОбработки.ПолноеИмя + """", , ТекстЛога, Истина,,,,,,, Ложь) Тогда УдалитьФайлы(ШаблонВнешнейОбработки); УдалитьФайлы(ИмяВременногоФайла); ирОбщий.СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; Результат = Истина; Иначе Если ПустаяСтрока(ДляИДВерсииПлатформы) Тогда ДляИДВерсииПлатформы = ирКэш.НомерИзданияПлатформыЛкс(); КонецЕсли; Если ДляИДВерсииПлатформы = "83" Тогда ДляИДВерсииПлатформы = "82"; КонецЕсли; Если ТекстМакета <> Неопределено Тогда ШаблонВнешнейОбработкиСМакетом = ШаблоныВнешнейОбработкиСМакетом[ДляИДВерсииПлатформы]; Если ШаблонВнешнейОбработкиСМакетом = Неопределено Тогда ШаблонВнешнейОбработкиСМакетом = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстПотокаСИменем"); ШаблонВнешнейОбработкиСМакетом.Путь = РазвернутьНовыйШаблонВнешнейОбработки(Истина,, ШаблонВнешнейОбработкиСМакетом.ФайлСИменем, ШаблонВнешнейОбработкиСМакетом.ТекстПотокаСИменем, ДляИДВерсииПлатформы); ФайлЗамокШаблонаСМакетом = Новый ЗаписьТекста; ФайлЗамокШаблонаСМакетом.Открыть(ШаблонВнешнейОбработкиСМакетом.Путь + ".lck"); ШаблонВнешнейОбработкиСМакетом.ФайлЗамок = ФайлЗамокШаблонаСМакетом; ШаблоныВнешнейОбработкиСМакетом[ДляИДВерсииПлатформы] = ШаблонВнешнейОбработкиСМакетом; КонецЕсли; ПутьКШаблону = ШаблонВнешнейОбработкиСМакетом.Путь; ФайлСИменем = ШаблонВнешнейОбработкиСМакетом.ФайлСИменем; ТекстПотокаСИменем = ШаблонВнешнейОбработкиСМакетом.ТекстПотокаСИменем; Иначе ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки[ДляИДВерсииПлатформы]; Если ШаблонВнешнейОбработки = Неопределено Тогда ШаблонВнешнейОбработки = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстПотокаСИменем"); ШаблонВнешнейОбработки.Путь = РазвернутьНовыйШаблонВнешнейОбработки(,, ШаблонВнешнейОбработки.ФайлСИменем, ШаблонВнешнейОбработки.ТекстПотокаСИменем, ДляИДВерсииПлатформы); ФайлЗамокШаблона = Новый ЗаписьТекста; ФайлЗамокШаблона.Открыть(ШаблонВнешнейОбработки.Путь + ".lck"); ШаблонВнешнейОбработки.ФайлЗамок = ФайлЗамокШаблона; ШаблоныВнешнейОбработки[ДляИДВерсииПлатформы] = ШаблонВнешнейОбработки; КонецЕсли; ПутьКШаблону = ШаблонВнешнейОбработки.Путь; ФайлСИменем = ШаблонВнешнейОбработки.ФайлСИменем; ТекстПотокаСИменем = ШаблонВнешнейОбработки.ТекстПотокаСИменем; КонецЕсли; ИмяФайлаВерсий = "versions.data.und"; ФайлЗаголовка = Новый Файл(ПутьКШаблону + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайлаВерсий); // ДвоичныеДанныеЗаголовка = Новый ДвоичныеДанные(ФайлЗаголовка.ПолноеИмя); // ПотокЗаписи = ФайловыеПотоки.ОткрытьДляЗаписи(ФайлЗаголовка.ПолноеИмя); // Читатель = Новый ЧтениеДанных(ДвоичныеДанныеЗаголовка); // Писатель = Новый ЗаписьДанных(ПотокЗаписи); // Счетчик = 1; // Пока Истина Цикл // Целое16 = Читатель.ПрочитатьЦелое16(); // Если Целое16 = Неопределено Тогда // Прервать; // КонецЕсли; // Если Ложь // Или Счетчик = 1 // Тогда // Целое16 = Целое16 + 1; // Увеличиваем номер версии содержимого // КонецЕсли; // Писатель.ЗаписатьЦелое16(Целое16); // Счетчик = Счетчик + 1; // КонецЦикла; // Писатель.Закрыть(); // ПотокЗаписи.Закрыть(); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлЗаголовка.ПолноеИмя); ТекстФайла = ТекстовыйДокумент.ПолучитьТекст(); ФрагментТекста = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстФайла, """4eb1cc18-835d-4f8c-a120-3f9d886d75d4""", """902f74d3-f929-4b0f-8719-4cbb655891aa""", Ложь, Истина); ТекстФайла = ирОбщий.СтрЗаменитьЛкс(ТекстФайла, ФрагментТекста, """4eb1cc18-835d-4f8c-a120-3f9d886d75d4""," + Новый УникальныйИдентификатор + ",""902f74d3-f929-4b0f-8719-4cbb655891aa"""); ТекстовыйДокумент.УстановитьТекст(ТекстФайла); ТекстовыйДокумент.Записать(ФайлЗаголовка.ПолноеИмя); ПутьКШаблону = ПутьКШаблону + ирОбщий.РазделительПутиКФайлуЛкс(); Если ЗначениеЗаполнено(ИмяОбработки) Тогда ТекстПотокаСИменем = СтрЗаменить(ТекстПотокаСИменем, "ИмяВнешнейОбработки", ИмяОбработки); КонецЕсли; ПотокСИменемОбработки = Новый ТекстовыйДокумент; ПотокСИменемОбработки.УстановитьТекст(ТекстПотокаСИменем); ПотокСИменемОбработки.Записать(ФайлСИменем.ПолноеИмя); ФайлТекстаМодуляОбработки = Новый Файл(ПутьКШаблону + СубПутьКФайлуПотокаМодуляВнешнейОбработки); ТекстовыйДокументМодуля = Новый ТекстовыйДокумент(); ТекстовыйДокументМодуля.УстановитьТекст(ТекстМодуля); ТекстовыйДокументМодуля.Записать(ФайлТекстаМодуляОбработки.ПолноеИмя); Если ТекстМакета <> Неопределено Тогда ФайлТекстаМакетаПараметров = Новый Файл(ПутьКШаблону + СубПутьКФайлуПотокаМакетаВнешнейОбработки); ТекстовыйДокументМакета = Новый ТекстовыйДокумент(); ТекстовыйДокументМакета.УстановитьТекст(ТекстМакета); ТекстовыйДокументМакета.Записать(ФайлТекстаМакетаПараметров.ПолноеИмя); КонецЕсли; Результат = УпаковатьВнешнююОбработку(ПутьКШаблону, ФайлОбработки.ПолноеИмя); КонецЕсли; Возврат Результат; КонецФункции // Файлы "Zlib1.dll" и "v8unpack.exe" должны быть в этом каталоге. Функция УпаковатьВнешнююОбработку(ПутьКШаблонуВнешнейОбработки, ИмяВыходногоФайла, СоздатьФайлыУпаковщика = Ложь) Экспорт // Небольшой накладной расход, но надежность повышаем УдалитьФайлы(ПутьКШаблонуВнешнейОбработки + СубПутьККонтрольномуФайлуВнешнейОбработки); Попытка УдалитьФайлы(ИмяВыходногоФайла); Исключение Событие = "Ошибка создания служебного объекта (1)"; //ирОбщий.СообщитьЛкс(Событие, СтатусСообщения.Важное); //ЗаписьЖурналаРегистрации(Событие, УровеньЖурналаРегистрации.Ошибка); //Возврат Неопределено; ВызватьИсключение Событие; КонецПопытки; Если СоздатьФайлыУпаковщика Тогда ПодготовитьПакер(ПутьКШаблонуВнешнейОбработки); КонецЕсли; ИмяКомандногоФайла = "pack.bat"; ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс(ИмяКомандногоФайла + " """ + ИмяВыходногоФайла + """", ПутьКШаблонуВнешнейОбработки); КонтрольныйФайл1 = Новый Файл(ПутьКШаблонуВнешнейОбработки + СубПутьККонтрольномуФайлуВнешнейОбработки); КонтрольныйФайл2 = Новый Файл(ИмяВыходногоФайла); Если Ложь Или Не КонтрольныйФайл1.Существует() //Или Не КонтрольныйФайл2.Существует() // Отключил для повышения скорости Тогда Если ирКэш.ЛиДоступноВыполнениеКомандныхФайловЛкс(Истина) Тогда ВызватьИсключение "Ошибка выполнения приложения V8unpack"; КонецЕсли; КонецЕсли; Возврат Истина; КонецФункции Функция ПолучитьФайлВнешнейОбработкиАлгоритма(АлгоритмОбъект) Экспорт Если Ложь Или СтрДлина(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя) + СтрДлина(АлгоритмОбъект.Наименование) > 250 Тогда // Ограничение WinAPI на путь к файлу КлючСервиса = "" + АлгоритмОбъект.Ссылка.УникальныйИдентификатор(); Иначе КлючСервиса = АлгоритмОбъект.Наименование; КонецЕсли; ИмяФайла = КлючСервиса + ".epf"; ФайлВнешнейОбработки = Новый Файл(ПапкаКешаВнешнихОбработокАлгоритмов.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяФайла); Возврат ФайлВнешнейОбработки; КонецФункции Функция ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша = Неопределено, ДатаИзмененияКэша = Неопределено) Экспорт ФайлВнешнейОбработкиАктуален = Ложь; КэшВнешнейОбработкиАктуален = Ложь; ФайлВнешнейОбработки = ПолучитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса); ДатаИзмененияОбъекта = ДескрипторСервиса.ДатаИзмененияКонтекста; //// Условие добавлено для мягкого перехода на новый кэш параметров сервисов 21.10.2010. Потом нужно убрать //Если ЗначениеЗаполнено(ДескрипторСервиса.ДатаИзмененияКэша) Тогда ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта, КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшАлгоритмовДопускаетРедактирование); //КонецЕсли; Если Истина И Не КэшВнешнейОбработкиАктуален И Не ФайлВнешнейОбработкиАктуален Тогда СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса); СервисОбъект.СобратьКонтекст(); СформироватьВнешнююОбработку(ФайлВнешнейОбработки, СервисОбъект.Наименование, СервисОбъект.ПолучитьТекстМодуляОбработки() //, СервисОбъект.ПолучитьТекстМакетаПараметров() ); Попытка ФайлВнешнейОбработки.УстановитьВремяИзменения(СервисОбъект.ДатаИзмененияКонтекста); Исключение Если Не ФайлВнешнейОбработки.Существует() Тогда ирОбщий.ПроверитьКодЯзыкаОСЛкс(); ВызватьИсключение "Файл внешней обработки сервиса """ + СервисОбъект.Наименование + """ не сформирован"; Иначе ВызватьИсключение; КонецЕсли; КонецПопытки; КонецЕсли; Если КэшВнешнейОбработкиАктуален Тогда Возврат Неопределено; Иначе Возврат ФайлВнешнейОбработки; КонецЕсли; КонецФункции Функция ПолучитьВнешнююОбработкуПоАлгоритму(ДескрипторСервиса) Экспорт // %%%% Здесь можно было бы структуру попробовать вместо ТЗ //ЭлементКэша = 0; //КешВнешнихОбработокАлгоритмов.Свойство(ДескрипторСервиса.Наименование, ЭлементКэша); ЭлементКэша = ДескрипторСервиса.мСтруктураВнешнейОбработки; Если Ложь Или ЭлементКэша = Неопределено Или ЭлементКэша.ДатаИзменения < ДескрипторСервиса.ДатаИзмененияКонтекста Или ФайловыйКэшАлгоритмовДопускаетРедактирование Тогда ДатаИзмененияКэша = ДескрипторСервиса.ДатаИзмененияКонтекста; // Для обхода бага платформы WshShell().Run(,,True) Для Счетчик = 1 По 3 Цикл ФайлВнешнейОбработки = ПолучитьОбновитьФайлВнешнейОбработкиАлгоритма(ДескрипторСервиса, ЭлементКэша, ДатаИзмененияКэша); Если ФайлВнешнейОбработки <> Неопределено Тогда ВнешняяОбработка = СоздатьВнешнююОбработкуАлгоритма(ДескрипторСервиса, ФайлВнешнейОбработки.ПолноеИмя); // Для обхода бага платформы. Если ВнешняяОбработка <> Неопределено Тогда ИмяАлгоритмаВнешнейОбработки = ВнешняяОбработка.Метаданные().Имя; Если ИмяАлгоритмаВнешнейОбработки <> ДескрипторСервиса.Наименование Тогда ЗаписьЖурналаРегистрации("Несоответствие внешней обработки и сервиса", УровеньЖурналаРегистрации.Ошибка, , ДескрипторСервиса.Ссылка, "Попытка №" + Счетчик + ". Внешняя обработка """ + ИмяАлгоритмаВнешнейОбработки + """"); УдалитьФайлы(ФайлВнешнейОбработки.ПолноеИмя); Продолжить; КонецЕсли; КонецЕсли; КонецЕсли; Прервать; КонецЦикла; Если ФайлВнешнейОбработки <> Неопределено Тогда Если ЭлементКэша = Неопределено Тогда ЭлементКэша = Новый Структура("ДатаИзменения, ВнешняяОбработка"); //КешВнешнихОбработокАлгоритмов.Вставить(ДескрипторСервиса.Наименование, ЭлементКэша); ДескрипторСервиса.мСтруктураВнешнейОбработки = ЭлементКэша; КонецЕсли; Если ВнешняяОбработка <> Неопределено Тогда ЭлементКэша.ДатаИзменения = ДатаИзмененияКэша; ЭлементКэша.ВнешняяОбработка = ВнешняяОбработка; Иначе ЭлементКэша.ДатаИзменения = Дата("00010101"); КонецЕсли; КонецЕсли; КонецЕсли; Если ЭлементКэша <> Неопределено Тогда Результат = ЭлементКэша.ВнешняяОбработка; Иначе Результат = Неопределено; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьВнешнююОбработкуПоАлгоритму() Функция ЕстьАдминистративныеПраваУУчетнойЗаписиОС() Экспорт Если мЕстьАдминистративныеПраваУУчетнойЗаписиОС <> Неопределено Тогда Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС; КонецЕсли; Попытка Network = Новый COMОбъект("WScript.Network"); Исключение // Например Linux ОписаниеОшибки = ОписаниеОшибки(); Возврат Ложь; КонецПопытки; //ПользовательОС = Network.UserDomain + "\" + Network.UserName; ПользовательОС = Network.UserName; КомандаСистемы = "Net user " + ПользовательОС; РезультатКоманды = ТекстРезультатаКомандыСистемы(КомандаСистемы); мЕстьАдминистративныеПраваУУчетнойЗаписиОС = Ложь Или Найти(РезультатКоманды, "Администраторы") > 0 Или Найти(РезультатКоманды, "Administrators") > 0; Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС; КонецФункции Функция ПереместитьФайлКакАдминистратор(ИмяИсточника, ИмяПриемника) Экспорт Успех = Истина; Попытка //ПереместитьФайл(ИмяИсточника, ИмяПриемника); // так не работает наследование прав от каталога-приемника! КопироватьФайл(ИмяИсточника, ИмяПриемника); Исключение ОписаниеОшибки = ОписаниеОшибки(); КонецПопытки; Если ОписаниеОшибки <> Неопределено Тогда //КомандаСистемы = "cmd.exe /c move """ + ИмяИсточника + """ """ + ИмяПриемника + """"; // так не работает наследование прав от каталога-приемника! КомандаСистемы = "cmd.exe /c copy """ + ИмяИсточника + """ """ + ИмяПриемника + """"; ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина); // При успехе возвращает: // Скопировано файлов: 1. Если Найти(ОписаниеОшибки, "1") = 0 Тогда ВызватьИсключение "Ошибка доступа к файлу """ + ИмяПриемника + """: " + ОписаниеОшибки; КонецЕсли; КонецЕсли; Если Успех Тогда Попытка УдалитьФайлы(ИмяИсточника); Исключение КомандаСистемы = "cmd.exe /c del """ + ИмяИсточника + """"; ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина); // При успехе возвращает пустую строку Если Не ПустаяСтрока(ОписаниеОшибки) Тогда ВызватьИсключение "Ошибка доступа к файлу """ + ИмяИсточника + """: " + ОписаниеОшибки; КонецЕсли; КонецПопытки; КонецЕсли; Возврат Успех; КонецФункции Функция ПолучитьПолноеИмяКомпьютераСетиПоЛюбомуИмени(ИмяКомпьютера) Экспорт ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла()); ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("nslookup " + ИмяКомпьютера, ФайлРезультата.Путь, ФайлРезультата.Имя); Если Не ФайлРезультата.Существует() Тогда ПолноеИмяКомпьютера = ""; Иначе ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя); УдалитьФайлы(ФайлРезультата.ПолноеИмя); ТекстРезультата = ТекстовыйДокумент.ПолучитьТекст(); RegExp.IgnoreCase = Истина; RegExp.Pattern = "(?:name|имя|╚ь ):\s*([-" + шБукваЦифра + "]+(\.([-" + шБукваЦифра + "]+))*)\s*"; Результат = RegExp.НайтиВхождения(ТекстРезультата); Если Результат.Количество() > 0 Тогда ПолноеИмяКомпьютера = Результат[0].SubMatches(0); Иначе ПолноеИмяКомпьютера = ""; КонецЕсли; КонецЕсли; //ASPDNS = ПолучитьCOMОбъектИзМакета("ASPDNS", "ASPDNS.DNSLookup"); //IP = ASPDNS.GetIPFromName(ИмяКомпьютера); //ПолноеИмяКомпьютера = ASPDNS.GetNameFromIP(IP); Возврат ПолноеИмяКомпьютера; КонецФункции Функция ПроверитьКаталогФайловогоКэша() Экспорт //http://www.hostedredmine.com/issues/851201 //СтрокаСоединения = ирКэш.СтрокаСоединенияСервераЛкс(); СтрокаСоединения = СтрокаСоединенияИнформационнойБазы(); КаталогВерсииПлатформыВПрофиле = ирКэш.КаталогИзданияПлатформыВПрофилеЛкс(); КаталогФайловогоКэша = КаталогВерсииПлатформыВПрофиле + ирОбщий.РазделительПутиКФайлуЛкс() + ирОбщий.ИдентификаторИзПредставленияЛкс(СтрокаСоединения); ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша); Если Не ПапкаФайловогоКэша.Существует() Тогда Попытка СоздатьКаталог(ПапкаФайловогоКэша.ПолноеИмя); ПробныйФайл = Новый ТекстовыйДокумент; ПробныйФайл.Записать(ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "1.txt"); Исключение ОписаниеОшибки = ОписаниеОшибки(); Сообщить("Файловые кэши отключены из-за ошибки: " + ОписаниеОшибки, СтатусСообщения.Важное); // При использовании ирОбщий.СообщитьЛкс() может происходить переполнение стека ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь; Возврат Ложь; КонецПопытки; КонецЕсли; Возврат Истина; КонецФункции Функция НастройкиКомпьютера() Экспорт Если НастройкиКомпьютера = Неопределено Тогда ФайлаНастроекКомпьютера = Новый Файл(ИмяФайлаНастроекКомпьютера()); Если ФайлаНастроекКомпьютера.Существует() Тогда НастройкиКомпьютера = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлаНастроекКомпьютера.ПолноеИмя); Если НастройкиКомпьютера <> Неопределено Тогда ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаМодулей"]; ЗначениеНастройки = Новый Файл(ЗначениеНастройки); Если ЗначениеНастройки.Существует() Тогда ПапкаКэшаМодулей = ЗначениеНастройки; КонецЕсли; ЗначениеНастройки = НастройкиКомпьютера["ПапкаКэшаРолей"]; ЗначениеНастройки = Новый Файл(ЗначениеНастройки); Если ЗначениеНастройки.Существует() Тогда ПапкаКэшаРолей = ЗначениеНастройки; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если НастройкиКомпьютера = Неопределено Тогда НастройкиКомпьютера = Новый Соответствие; КонецЕсли; Возврат НастройкиКомпьютера; КонецФункции Процедура СохранитьНастройкиКомпьтера() Экспорт ИмяФайлаНастроекКомпьютера = ИмяФайлаНастроекКомпьютера(); ирОбщий.СохранитьЗначениеВФайлЛкс(НастройкиКомпьютера, ИмяФайлаНастроекКомпьютера); КонецПроцедуры Функция ИмяФайлаНастроекКомпьютера() ПапкаФайловогоКэша = Новый Файл(КаталогФайловогоКэша); ИмяФайлаНастроекКомпьютера = ПапкаФайловогоКэша.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + "ComputerSettings.xml"; Возврат ИмяФайлаНастроекКомпьютера; КонецФункции Функция ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт Если ИнформацияОбОшибке <> Неопределено Тогда RegExp.Global = Ложь; //ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке); Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; ОписаниеОшибки = ИнформацияОбОшибке.Описание; RegExp.Pattern = "(?:Переменная не определена |Variable is not defined )\(([_0-9" + шБуква + "]+)\)"; Результат = RegExp.НайтиВхождения(ОписаниеОшибки); Если Результат.Количество() > 0 Тогда ИмяПеременнойРезультата = Результат[0].SubMatches(0); Иначе Если СообщитьНеобрабатываемуюОшибку Тогда ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИмяПеременнойРезультата; КонецФункции Функция ИмяНеопределенногоМетодаИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт Если ИнформацияОбОшибке <> Неопределено Тогда RegExp.Global = Ложь; //ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке); Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; ОписаниеОшибки = ИнформацияОбОшибке.Описание; RegExp.Pattern = "(?:Процедура или функция с указанным именем не определена |TODO_xxxx9469326459823 )\(([_0-9" + шБуква + "]+)\)"; Результат = RegExp.НайтиВхождения(ОписаниеОшибки); Если Результат.Количество() > 0 Тогда ИмяМетодаРезультата = Результат[0].SubMatches(0); Иначе Если СообщитьНеобрабатываемуюОшибку Тогда ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИмяМетодаРезультата; КонецФункции #Если Клиент Или ВнешнееСоединение Тогда // Выполняет алгоритм по ссылке. // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // // Возвращаемое значение: // - <Тип.Вид> - <описание значения> // <продолжение описания значения>; // <Значение2> - <Тип.Вид> - <описание значения> // <продолжение описания значения>. // Функция ВыполнитьАлгоритм(СсылкаАлгоритма, СтруктураПараметров = Неопределено) Экспорт Если СтруктураПараметров = Неопределено Тогда СтруктураПараметров = Новый Структура; КонецЕсли; АлгоритмОбъект = Неопределено; Если Не КешАлгоритмов.Свойство(СсылкаАлгоритма, АлгоритмОбъект) Тогда АлгоритмОбъект = СсылкаАлгоритма.ПолучитьОбъект(); КешАлгоритмов.Вставить(СсылкаАлгоритма, АлгоритмОбъект); КонецЕсли; Результат = ВыполнитьМетодАлгоритма(АлгоритмОбъект, 1, СтруктураПараметров); Возврат Результат; КонецФункции Процедура ОчиститьКешАлгоритмов(ОчиститьКэшНаДиске = Ложь) Экспорт КешАлгоритмов.Очистить(); //КешВнешнихОбработокАлгоритмов.Очистить(); Если ОчиститьКэшНаДиске Тогда //Для Каждого ЭлементПодкаталога Из СтруктураПодкаталоговФайловогоКэша Цикл // УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.dat"); // УдалитьФайлы(ЭлементПодкаталога.Значение.ПолноеИмя, "*.epf"); //КонецЦикла; ФайлПодкаталога = СтруктураПодкаталоговФайловогоКэша["a"]; УдалитьФайлы(ФайлПодкаталога.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс(), "*.*"); ПроверитьСтруктуруФайловогоКэша(); КонецЕсли; КонецПроцедуры // ОчиститьКешАлгоритмов() Процедура ОбновитьАлгоритмВКеше(АлгоритмОбъект) Экспорт КешАлгоритмов.Вставить(АлгоритмОбъект.Ссылка, АлгоритмОбъект); КонецПроцедуры // УдалитьАлгоритмИзКеша() Функция ПолучитьФайлОткрывателя1С(БыстраяПроверка = Истина) Экспорт Если Ложь Или Не БыстраяПроверка Или ФайлОткрывателя1С = Неопределено Тогда ФайлОткрывателя1С = Новый Файл(ПолучитьИмяВременногоФайла("exe")); ПолучитьМакет("OpenIn1Cv8ExeWin").Записать(ФайлОткрывателя1С.ПолноеИмя); КонецЕсли; Возврат ФайлОткрывателя1С; КонецФункции Функция ФайлФорматераЗапросовБД(БыстраяПроверка = Истина) Экспорт Если Ложь Или Не БыстраяПроверка Или ФайлФорматераЗапросовБД = Неопределено Тогда ФайлФорматераЗапросовБД = Новый Файл(ПолучитьИмяВременногоФайла("exe")); ПолучитьМакет("SqlFormatter").Записать(ФайлФорматераЗапросовБД.ПолноеИмя); КонецЕсли; Возврат ФайлФорматераЗапросовБД; КонецФункции Функция ПолучитьФайлРаспаковщикаZIP(БыстраяПроверка = Ложь) Экспорт Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда Если Ложь Или Не БыстраяПроверка Или ФайлРаспаковщикаZIP = Неопределено Тогда ФайлРаспаковщикаZIP = Новый Файл(ПолучитьИмяВременногоФайла("exe")); ПолучитьМакет("unzip").Записать(ФайлРаспаковщикаZIP.ПолноеИмя); КонецЕсли; Иначе // Может потребоваться установка - sudo apt install unzip ФайлРаспаковщикаZIP = Новый Файл("unzip"); КонецЕсли; Возврат ФайлРаспаковщикаZIP; КонецФункции // Получает из длинного пути к файлу короткий в формате DOS (8.3) // // Параметры: // ПолноеИмяФайла - Строка; // // Возвращаемое значение: // Строка; // Функция ПолучитьИмяФайлаВФорматеDOS(ПолноеИмяФайла) Экспорт Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда Возврат ПолноеИмяФайла; КонецЕсли; Если ирКэш.Это64битныйПроцессЛкс() Тогда ВызватьИсключение "Получение имени файла в формате ""8.3"" недоступно в 64б процессе"; КонецЕсли; Если VBScript = Неопределено Тогда VBScript = Новый COMОбъект("MSScriptControl.ScriptControl"); // Не работает в 64б процессе VBScript.language = "vbscript"; КонецЕсли; VBScript.addcode(" |Public Function GetShortPath() |Set fso = CreateObject(""scripting.filesystemobject"") |Set fsoFile = fso.GetFile(""" + ПолноеИмяФайла + """) |GetShortPath = fsoFile.ShortPath |End Function |"); DOSИмя = VBScript.Run("GetShortPath"); Возврат DOSИмя; КонецФункции Процедура УдалитьСлужебныеФайлы() Экспорт СтруктураЦикла = Новый Массив; СтруктураЦикла.Добавить(ШаблоныВнешнейОбработки); СтруктураЦикла.Добавить(ШаблоныВнешнейОбработкиСМакетом); Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл Для Каждого КлючИЗначение Из ЭлементЦикла Цикл ШаблонВнешнейОбработки = КлючИЗначение.Значение; Если ШаблонВнешнейОбработки.ФайлЗамок <> Неопределено Тогда ШаблонВнешнейОбработки.ФайлЗамок.Закрыть(); Попытка УдалитьФайлы(ШаблонВнешнейОбработки.Путь + ".lck"); УдалитьФайлы(ШаблонВнешнейОбработки.Путь); Исключение КонецПопытки; КонецЕсли; КонецЦикла; КонецЦикла; КонецПроцедуры // УдалитьСлужебныеФайлы() // Функция - Поле текста программы // // Параметры: // ЯзыкПрограммы - Число - // НачалоТекста - Строка - первые 1000 символов текста для определения его языка // // Возвращаемое значение: // - // Функция ПолеТекстаПрограммы(Знач ЯзыкПрограммы = 0, Знач НачалоТекста = "") Экспорт Если мПоляТекстаПрограммы = Неопределено Тогда мПоляТекстаПрограммы = Новый Соответствие; КонецЕсли; Если ЯзыкПрограммы = 0 И ирОбщий.ЛиТекстЯзыкаЗапросовЛкс(НачалоТекста) Тогда ЯзыкПрограммы = 1; КонецЕсли; ПолеТекстаПрограммы = мПоляТекстаПрограммы[ЯзыкПрограммы]; Если ПолеТекстаПрограммы = Неопределено Тогда ПолеТекстаПрограммы = ирОбщий.НовыйАнализаторКодаЛкс(); #Если Сервер И Не Сервер Тогда ПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать(); #КонецЕсли ПолеТекстаПрограммы.ИнициироватьНеинтерактивно(ЯзыкПрограммы); ПолеТекстаПрограммы.ЭтоМодуль = Истина; мПоляТекстаПрограммы[ЯзыкПрограммы] = ПолеТекстаПрограммы; КонецЕсли; Возврат ПолеТекстаПрограммы; КонецФункции #КонецЕсли Функция ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение) Экспорт Если ПустоеЗначение = Неопределено Тогда Результат = "<Неопределено>"; Иначе Результат = мКэшПустыхЗначений[ПустоеЗначение]; Если Результат = Неопределено Тогда Если ПустоеЗначение = Null Тогда Результат = ""; ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("Булево") И ПустоеЗначение = Ложь Тогда //Результат = "<Булево: Нет>"; Результат = "" + ПустоеЗначение; ИначеЕсли ПустоеЗначение = "" Тогда Результат = "<Строка>"; ИначеЕсли ПустоеЗначение = 0 Тогда //Результат = "<Пустое число>"; Результат = Формат(ПустоеЗначение, "ЧН="); ИначеЕсли ПустоеЗначение = Дата("00010101") Тогда Результат = "<Дата>"; ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("УникальныйИдентификатор") Тогда Результат = "<Идентификатор>"; ИначеЕсли ТипЗнч(ПустоеЗначение) = Тип("Картинка") Тогда Результат = "<Картинка>"; Иначе ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(ПустоеЗначение); Если ОбъектМД <> Неопределено Тогда Результат = "<" + ОбъектМД.ПолноеИмя() + ".Ссылка>"; КонецЕсли; КонецЕсли; мКэшПустыхЗначений[ПустоеЗначение] = Результат; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции // Возвращает текущее время в миллисекундах. // // Параметры: // Нет. // // Возвращаемое значение: // Число. // Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт Если ирКэш.НомерИзданияПлатформыЛкс() >= "83" Тогда Результат = Вычислить("ТекущаяУниверсальнаяДатаВМиллисекундах()"); КонецЕсли; Если Результат = Неопределено Тогда Если JavaScript = Неопределено Тогда Попытка JavaScript = Новый COMОбъект("MSScriptControl.ScriptControl"); Исключение ирОбщий.СообщитьЛкс("Ошибка создания MSScriptControl.ScriptControl: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат 0; КонецПопытки; JavaScript.Language = "javascript"; КонецЕсли; Результат = JavaScript.Eval("new Date().getTime()"); КонецЕсли; Возврат Результат; КонецФункции Функция ПроверитьПолучитьОбъектСервиса(Знач АлгоритмОбъект) Экспорт Если ТипЗнч(АлгоритмОбъект) = Тип("СтрокаТаблицыЗначений") Тогда лОбъект = АлгоритмОбъект.ЭтотОбъект; Если лОбъект = Неопределено Тогда лОбъект = АлгоритмОбъект.Ссылка.ПолучитьОбъект(); ЗаполнитьЗначенияСвойств(лОбъект, АлгоритмОбъект, , "ЭтотОбъект, Ссылка, мПолнаяТаблицаПараметров"); ////%!% АлгоритмОбъект.ЭтотОбъект = лОбъект; КонецЕсли; АлгоритмОбъект = лОбъект; КонецЕсли; Возврат АлгоритмОбъект; КонецФункции // ПроверитьПолучитьОбъектСервиса() Функция ПредставлениеИнформацииОбОшибке(Знач ИнформацияОбОшибке) Экспорт // Антибаг платформы. В описании повторяется причина и описание между уровнями. В общем бардак. ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда Пока Истина И ИнформацияОбОшибке.Причина <> Неопределено И ИнформацияОбОшибке.Описание = ОписаниеОшибки Цикл ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; Если ИнформацияОбОшибке.Описание <> ОписаниеОшибки Тогда ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке); КонецЕсли; Иначе Фрагмент = ирОбщий.ПоследнийФрагментЛкс(ОписаниеОшибки, "по причине:" + Символы.ПС); Позиция = Найти(ОписаниеОшибки, Фрагмент + Символы.ПС + "по причине:" + Символы.ПС + Фрагмент); Если Позиция > 0 Тогда ОписаниеОшибки = Лев(ОписаниеОшибки, Позиция) + Фрагмент; КонецЕсли; КонецЕсли; Возврат ОписаниеОшибки; КонецФункции // ПредставлениеИнформацииОбОшибке() Функция ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, РежимВыполненияАлгоритма, Интерактивно = Истина) Экспорт //СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса); // Такой прием применен для избежания обращения к БД внутри сломанной транзакции Если ТипЗнч(ДескрипторСервиса) = Тип("СтрокаТаблицыЗначений") Тогда лОбъект = ДескрипторСервиса.ЭтотОбъект; Если лОбъект = Неопределено Тогда //лОбъект = Справочники.Сервисы2iS.СоздатьЭлемент(); //ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, , "ЭтотОбъект, Ссылка, КэшПараметров"); лОбъект = Новый ("СправочникОбъект.Сервисы2iS"); ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, "мЗначенияПоУмолчанию, мВнешниеПараметры, мВнутренниеПараметры"); КонецЕсли; СервисОбъект = лОбъект; Иначе СервисОбъект = ДескрипторСервиса; КонецЕсли; Если РежимВыполненияАлгоритма = 3 Тогда Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуАлгоритмаВРежиме2(); ИмяМодуляСервиса = ""; ИначеЕсли РежимВыполненияАлгоритма = 2 Тогда Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуАлгоритмаВТексте(); ИмяМодуляСервиса = ""; ИначеЕсли Ложь Или РежимВыполненияАлгоритма = 1 Или РежимВыполненияАлгоритма = 0 Тогда Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуМетодаВМодуле(); ИмяМодуляСервиса = "ВнешняяОбработка." + ДескрипторСервиса.Наименование; Если Ложь Или ирКэш.НомерИзданияПлатформыЛкс() = "82" Или ирКэш.НомерИзданияПлатформыЛкс() = "83" Тогда ИмяМодуляСервиса = ИмяМодуляСервиса + ".МодульОбъекта"; КонецЕсли; КонецЕсли; ПрефиксСервиса = "Сервис "; Если ИмяМодуляСервиса = ИнформацияОбОшибке.ИмяМодуля Тогда НомерСтрокиАлгоритма = ИнформацияОбОшибке.НомерСтроки; НомерСтрокиАлгоритма = НомерСтрокиАлгоритма - Смещение; ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]{" + НомерСтрокиАлгоритма + "}:" + Символы.ПС + "==========================================================================" + Символы.ПС + ИнформацияОбОшибке.Описание + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока; Иначе ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]"; МаркерСлужебногоИсключения = "ВызватьИсключение Ошибка;//#Служебное"; Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда ОписаниеОшибки = ОписаниеОшибки + "{" + ИнформацияОбОшибке.ИмяМодуля + "(" + ИнформацияОбОшибке.НомерСтроки + ")}: "; КонецЕсли; ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.Описание; Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока; КонецЕсли; КонецЕсли; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + " |" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина); КонецЕсли; #Если Клиент Тогда Если Интерактивно И ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов Тогда Если Не ирКэш.ЛиПортативныйРежимЛкс() И ирКлиент.ЛиЕстьИнтерактивныйДоступКИнструментамЛкс() Тогда Если Истина И ОтложенноеОткрытиеИсточникаОшибки.Количество() > 0 И ОтложенноеОткрытиеИсточникаОшибки[0].АлгоритмОбъект = Неопределено // СтопСтрока Тогда // Не подключаем отложенное открытие, т.к. уже внутри него. Случается при ПолученииДанных Иначе СтрокаИсточникаОшибки = ОтложенноеОткрытиеИсточникаОшибки.Добавить(); СтрокаИсточникаОшибки.АлгоритмОбъект = ДескрипторСервиса.Ссылка; СтрокаИсточникаОшибки.ИнформацияОбОшибке = ИнформацияОбОшибке; СтрокаИсточникаОшибки.РежимВыполненияАлгоритма = РежимВыполненияАлгоритма; СтрокаИсточникаОшибки.Смещение = Смещение; ПодключитьОбработчикОжидания("ОтложенноеОткрытиеИсточникаОшибки", 0.1, Истина); КонецЕсли; //Возврат Символы.ПС + ОписаниеОшибки; Иначе ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Важное); КонецЕсли; КонецЕсли; #КонецЕсли Возврат ОписаниеОшибки; КонецФункции // ОбработатьВнешнееИсключениеАлгоритма() // Выполняет алгоритм по объекту. // // Параметры: // <Параметр1> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>; // <Параметр2> - <Тип.Вид> - <описание параметра> // <продолжение описания параметра>. // Функция ВыполнитьМетодАлгоритма(ДескрипторСервиса, Режим, П0 = Null, П1 = Null, П2 = Null, П3 = Null, П4 = Null, П5 = Null, П6 = Null, П7 = Null, П8 = Null, П9 = Null) Экспорт //#Если Клиент Тогда Если ВыполнятьАлгоритмыЧерезВнешниеОбработки Тогда Если Ложь Или ВнешняяОбработкаСервисы = Неопределено Или ДескрипторСервиса.ИндивидуальнаяВнешняяОбработка Тогда ВнешняяОбработкаАлгоритма = ПолучитьВнешнююОбработкуПоАлгоритму(ДескрипторСервиса); //Иначе // ВнешняяОбработкаАлгоритма = ДескрипторСервиса.мСтруктураВнешнейОбработки; // Если ВнешняяОбработкаАлгоритма = Неопределено Тогда // ВнешняяОбработкаАлгоритма = ВнешняяОбработкаСервисы.ПолучитьФорму(ДескрипторСервиса.Наименование); // ДескрипторСервиса.мСтруктураВнешнейОбработки = ВнешняяОбработкаАлгоритма; // КонецЕсли; //КонецЕсли; Если ВнешняяОбработкаАлгоритма <> Неопределено Тогда Если ФиксироватьВнешниеИсключенияАлгоритмов Тогда Попытка Результат = ВнешняяОбработкаАлгоритма.мМетод(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); Ошибка = ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, 0); ВызватьИсключение Ошибка;//#Служебное КонецПопытки; Иначе Результат = ВнешняяОбработкаАлгоритма.мМетод(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9); КонецЕсли; Иначе //ирОбщий.СообщитьЛкс("Ошибка компиляции сервиса """ + ДескрипторСервиса.Наименование + """. Сервис не выполнен.", СтатусСообщения.Внимание); ВызватьИсключение "Ошибка компиляции сервиса """ + ДескрипторСервиса.Наименование + """"; КонецЕсли; Иначе // Прямые вызовы Если ФиксироватьВнешниеИсключенияАлгоритмов Тогда Попытка Результат = Вычислить("ВнешняяОбработкаСервисы._" + ДескрипторСервиса.Наименование + "(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9)"); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); Ошибка = ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, 0); ВызватьИсключение Ошибка;//#Служебное КонецПопытки; Иначе Результат = Вычислить("ВнешняяОбработкаСервисы._" + ДескрипторСервиса.Наименование + "(ДескрипторСервиса, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9)"); КонецЕсли; КонецЕсли; Иначе //#КонецЕсли //#Если Не Клиент И Не ВнешнееСоединение Тогда //ДескрипторСервиса.ирПлатформа = ЭтотОбъект; //#КонецЕсли СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса); #Если Сервер И Не Сервер Тогда СервисОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать(); #КонецЕсли ТекстАлгоритмаСПараметрами = СервисОбъект.ПолучитьТелоМетода(); Если ФиксироватьВнешниеИсключенияАлгоритмов Тогда Попытка Результат = ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритмаСПараметрами, СервисОбъект, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9); Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); Ошибка = ОбработатьВнешнееИсключениеАлгоритма(СервисОбъект, ИнформацияОбОшибке, 2); ВызватьИсключение Ошибка;//#Служебное КонецПопытки; Иначе Результат = ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритмаСПараметрами, СервисОбъект, Режим, П0, П1, П2, П3, П4, П5, П6, П7, П8, П9); КонецЕсли; //#Если Клиент Тогда КонецЕсли; //#КонецЕсли Возврат Результат; КонецФункции // ВыполнитьМетодАлгоритма() Функция ПолучитьИмяТипаCOMVariant(ReturnType) Экспорт Перем ScrptCtrl; ТекстМодуля = " |Function getMemberReturn( ReturnType ) | Dim ret | On Error Resume Next | If ReturnType Is Nothing Then | ret = """" | ElseIf Not IsEmpty(ReturnType.TypedVariant) Then | ff = ReturnType.TypedVariant | ff.VariantInit() | ret = ff.Name | ElseIf Not ReturnType.TypeInfo Is Nothing Then | ret = ReturnType.TypeInfo.Name | Else | ret = """" | End If | getMemberReturn = ret |End Function"; ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl"); ScrptCtrl.Language = "vbscript"; Попытка ScrptCtrl.AddCode(ТекстМодуля); Исключение ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Description); ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Source); ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Text); ирОбщий.СообщитьЛкс(ScrptCtrl.Error.Line); КонецПопытки; Результат = ScrptCtrl.Run("getMemberReturn", ReturnType); Возврат Результат; КонецФункции Функция WshShell() Экспорт Если WScriptShell = Неопределено Тогда WScriptShell = Новый COMОбъект("WScript.Shell"); КонецЕсли; Возврат WScriptShell; КонецФункции Процедура ПрочитатьОбщиеНастройки() ОбщиеНастройки = ирОбщий.ВосстановитьЗначениеЛкс("ОбщиеНастройки"); Если ОбщиеНастройки = Неопределено Тогда // Старый формат настроек ФайловыйКэшАлгоритмовДопускаетРедактирование = ирОбщий.ВосстановитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование"); АвторегистрацияComКомпонент = ирОбщий.ВосстановитьЗначениеЛкс("АвторегистрацияComКомпонент"); ПерехватКлавиатурногоВводаВОбычномПриложении = ирОбщий.ВосстановитьЗначениеЛкс("ПерехватКлавиатурногоВводаВОбычномПриложении"); ВыделениеРезультатовПоиска = ирОбщий.ВосстановитьЗначениеЛкс("ВыделениеРезультатовПоиска"); НеИспользоватьУправляемыеФормыИнструментов = ирОбщий.ВосстановитьЗначениеЛкс("НеИспользоватьУправляемыеФормыИнструментов"); Иначе ФайловыйКэшАлгоритмовДопускаетРедактирование = ОбщиеНастройки.ФайловыйКэшАлгоритмовДопускаетРедактирование; АвторегистрацияComКомпонент = ОбщиеНастройки.АвторегистрацияComКомпонент; ПерехватКлавиатурногоВводаВОбычномПриложении = ОбщиеНастройки.ПерехватКлавиатурногоВводаВОбычномПриложении; ВыделениеРезультатовПоиска = ОбщиеНастройки.ВыделениеРезультатовПоиска; НеИспользоватьУправляемыеФормыИнструментов = ОбщиеНастройки.НеИспользоватьУправляемыеФормыИнструментов; КонецЕсли; // Фиксированные. Больше не меняем. ФиксироватьВнешниеИсключенияАлгоритмов = Истина; ВыполнятьАлгоритмыЧерезВнешниеОбработки = Ложь; ПоказыватьВнешниеИсключенияПриВыполненииАлгоритмов = Ложь; Если ФайловыйКэшАлгоритмовДопускаетРедактирование = Неопределено Тогда ФайловыйКэшАлгоритмовДопускаетРедактирование = Ложь; КонецЕсли; Если НеИспользоватьУправляемыеФормыИнструментов = Неопределено Тогда НеИспользоватьУправляемыеФормыИнструментов = Ложь; КонецЕсли; // Антибаг http://partners.v8.1c.ru/forum/thread.jsp?id=861032#861032 Если АвторегистрацияComКомпонент = Неопределено Тогда АвторегистрацияComКомпонент = Истина; КонецЕсли; #Если Клиент Тогда Если ПерехватКлавиатурногоВводаВОбычномПриложении = Неопределено Тогда ПерехватКлавиатурногоВводаВОбычномПриложении = Метаданные.ОсновнойРежимЗапуска = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение; КонецЕсли; //СинтаксическийКонтрольПередЗаписью = ирОбщий.ВосстановитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью"); //Если СинтаксическийКонтрольПередЗаписью = Неопределено Тогда СинтаксическийКонтрольПередЗаписью = Истина; //КонецЕсли; Если ВыделениеРезультатовПоиска = Неопределено Тогда ВыделениеРезультатовПоиска = "⧼⧽"; КонецЕсли; #КонецЕсли Если ОбщиеНастройки = Неопределено Тогда СохранитьОбщиеНастройки(); КонецЕсли; КонецПроцедуры Процедура СохранитьОбщиеНастройки() Экспорт ОбщиеНастройки = Новый Структура; ОбщиеНастройки.Вставить("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование); ОбщиеНастройки.Вставить("АвторегистрацияComКомпонент", АвторегистрацияComКомпонент); ОбщиеНастройки.Вставить("ПерехватКлавиатурногоВводаВОбычномПриложении", ПерехватКлавиатурногоВводаВОбычномПриложении); ОбщиеНастройки.Вставить("ВыделениеРезультатовПоиска", ВыделениеРезультатовПоиска); ОбщиеНастройки.Вставить("НеИспользоватьУправляемыеФормыИнструментов", НеИспользоватьУправляемыеФормыИнструментов); ирОбщий.СохранитьЗначениеЛкс("ОбщиеНастройки", ОбщиеНастройки); КонецПроцедуры Функция НовоеСлужебноеПолеТекста(Знач СлужебнаяФорма = Неопределено, Знач Суффикс = "") Экспорт Перем ПолеТекста; Если СлужебнаяФорма = Неопределено Тогда СлужебнаяФорма = мСлужебнаяФорма; КонецЕсли; ПолеТекста = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекста" + Суффикс, Ложь); Возврат ПолеТекста; КонецФункции //ирПортативный Контейнер = Новый Структура(); //ирПортативный #Если Клиент Тогда //ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер); //ирПортативный #КонецЕсли //ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда //ирПортативный Файл = Новый Файл(ИспользуемоеИмяФайла); //ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(Файл.Путь, СтрДлина(Файл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf"; //ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта //ирПортативный КонецЕсли; //ирПортативный ирОбщий = ирПортативный.ОбщийМодульЛкс("ирОбщий"); //ирПортативный ирКэш = ирПортативный.ОбщийМодульЛкс("ирКэш"); //ирПортативный ирСервер = ирПортативный.ОбщийМодульЛкс("ирСервер"); //ирПортативный ирКлиент = ирПортативный.ОбщийМодульЛкс("ирКлиент"); #Если Сервер И Не Сервер Тогда мТаблицаВсехТаблицБД = Обработки.ирКлсПолеТекстаПрограммы.Создать().ДоступныеТаблицы.ВыгрузитьКолонки(); #КонецЕсли ИнициализацияОписанияОбщихТипов(); мМетаданные = Метаданные; КэшОбъектов = Новый Соответствие; мКэшПустыхЗначений = Новый Соответствие; мПассивныеФормы = новый Соответствие; СисИнфо = Новый СистемнаяИнформация; Фрагменты = ирОбщий.СтрРазделитьЛкс(СисИнфо.ВерсияПриложения); ВерсияПлатформы = Число(Фрагменты[0]) * 100 * 1000 + Число(Фрагменты[1]) * 1000 + Число(Фрагменты[2]); ЭтоИнтеграция = Метаданные.Справочники.Найти("иисМетаданные") <> Неопределено; МаркерНачалаАлгоритма = "//НАЧАЛО.СЕРВИС" + Символы.ПС; МаркерКонцаАлгоритма = "//КОНЕЦ_.СЕРВИС" + Символы.ПС; мМаркерИмениЗапросаПакета = "{Запрос: "; мМаркерИмениЧастиОбъединения = "{Выборка: "; шЛюбой = "(?:.|\n|\r)"; шБуква = "_ЁА-ЯA-Z"; шБукваЦифра = "_ЁА-ЯA-Z0-9"; шБукваСРешеткой = "_ЁА-ЯA-Z#"; шКомментарий = "//[^\n]*(?=(?:\n|$))"; шРазделитель = "(?:" + шКомментарий + "|\s|\xa0|$)"; // Возможно стоит добавить |\n|\r . Пришлось явно добавить неразрывный пробел (\xa0), т.к. VBScript не находит его через \s шПустоеНачалоСтроки = "(?:\n|^)(?:\t| )*"; // Когда внутри шРазделитель был управляющий символ <начало строки>, то возникали зависания на больших литералах https://www.hostedredmine.com/issues/966307 //шСтрокаПрограммы = """(?:""""|[^""\n])*(?:" + шРазделитель + "*\|(?:""""|[^""\n])*)*(?:""|$)"; // шСтрокаПрограммы = """(?:""""|[^""\n\r])*(?:(?:\n|\r|^)(?:\t| )*(?:" + шКомментарий + "|\|(?:""""|[^""\n\r])*)|\s|\xa0)*(?:""|(?=\n|\r|$))"; // Так быстрее (меньше откатов) 14.08.2023 . \r добавил для защиты от зависаний на экзотических файлах с OD-OD-OA шСтрокаЗапроса = """(?:(?:"""")|[^""\n])*(?:""|\n|$)"; // Есть сильно связанный шаблон шНачалоСтрокиЗапроса в ирКлсПолеТекстаПрограммы шGUID = "[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}"; шЧисло = "\d+(\.\d+)?"; шИндекс = "(\[[^\]\[]+?(?:(?:\[[^\]]+?\][^\]\[]*?)*)*\])"; шСтрокаПростая = """[^""]*"""; шМеждуСкобок = "[^\(\);""]"; шСкобки = "(\(" + шМеждуСкобок + "*(?:(?:" + шСтрокаПростая + "|\((?:" + "[^\);""]" + "|" + шСтрокаПростая + ")*\))" + шМеждуСкобок + "*)*\))"; // МультиМетка82355611 шИмя = "[" + шБуква + "][" + шБуква + "\d]*"; шИмяСРешеткой = "[" + шБукваСРешеткой + "][" + шБукваСРешеткой + "\d]*"; шИмяВременнойТаблицы = шИмяСРешеткой + "(?:\." + шИмяСРешеткой + ")*"; шГиперСсылка = "(\b(?:[" + шБукваЦифра + "]+)://[" + шБукваЦифра + "-+&@#\\/%?=~_|!:,.;()]+)"; ВложенностьИндикации = 0; ИмяКластераСерверов = НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr"); ЭтоФайловаяБаза = ПустаяСтрока(ИмяКластераСерверов); ПрочитатьОбщиеНастройки(); Парсеры = Новый Структура; ШаблоныВнешнейОбработки = Новый Соответствие; ШаблоныВнешнейОбработкиСМакетом = Новый Соответствие; ПроверитьСтруктуруФайловогоКэша(); ИмяФайлаПакера = "v8unpack.exe"; МассивОбычныхЭлементовУправления = Новый Массив; РежимОтладки = Ложь; АсинхронностьЗапрещена = Ложь; #Если Клиент Тогда ТаблицаСтатистикиВыбора = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора"); Если ТаблицаСтатистикиВыбора <> Неопределено Тогда Если ТаблицаСтатистикиВыбора.Колонки.Найти("ЯзыкПрограммы") = Неопределено Тогда ТаблицаСтатистикиВыбора = Неопределено; КонецЕсли; КонецЕсли; Если ТаблицаСтатистикиВыбора = Неопределено Тогда ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений; ТаблицаСтатистикиВыбора.Колонки.Добавить("ТипКонтекста"); ТаблицаСтатистикиВыбора.Колонки.Добавить("Слово"); ТаблицаСтатистикиВыбора.Колонки.Добавить("ЯзыкПрограммы"); ТаблицаСтатистикиВыбора.Колонки.Добавить("Рейтинг", Новый ОписаниеТипов("Число")); КонецЕсли; РежимОтладки = Найти(НРег(ПараметрЗапуска), НРег("РежимОтладкиИР")) > 0; АсинхронностьЗапрещена = Найти(НРег(ПараметрЗапуска), НРег("ЗапретитьАсинхронностьИР")) > 0; COMНавигатор = "НеИнициализирован"; ОтложенноеОткрытиеИсточникаОшибки = Новый ТаблицаЗначений; ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("АлгоритмОбъект"); ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("ИнформацияОбОшибке"); ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("РежимВыполненияАлгоритма"); ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("Смещение", Новый ОписаниеТипов("Число")); мСлужебнаяФорма = ПолучитьФорму("Служебная"); Если мСлужебнаяФорма <> Неопределено Тогда // Для портативного режима управляемого приложения СлужебноеПолеТекста = НовоеСлужебноеПолеТекста(); СлужебноеПолеТекста2 = НовоеСлужебноеПолеТекста(, "2"); //СлужебноеПолеHtmlДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"), "СлужебноеПолеHTMLДокумента", Ложь); // Тяжелая операция КонецЕсли; МассивОбычныхЭлементовУправления.Добавить("Диаграмма"); МассивОбычныхЭлементовУправления.Добавить("ДиаграммаГанта"); МассивОбычныхЭлементовУправления.Добавить("Дендрограмма"); МассивОбычныхЭлементовУправления.Добавить("Индикатор"); МассивОбычныхЭлементовУправления.Добавить("ПолеКалендаря"); МассивОбычныхЭлементовУправления.Добавить("Кнопка"); МассивОбычныхЭлементовУправления.Добавить("КолонкаТабличногоПоля"); МассивОбычныхЭлементовУправления.Добавить("КоманднаяПанель"); МассивОбычныхЭлементовУправления.Добавить("Надпись"); МассивОбычныхЭлементовУправления.Добавить("Панель"); МассивОбычныхЭлементовУправления.Добавить("Переключатель"); МассивОбычныхЭлементовУправления.Добавить("ПолеГрафическойСхемы"); МассивОбычныхЭлементовУправления.Добавить("ПолеГеографическойСхемы"); МассивОбычныхЭлементовУправления.Добавить("ПолеТабличногоДокумента"); МассивОбычныхЭлементовУправления.Добавить("ПолеHTMLДокумента"); МассивОбычныхЭлементовУправления.Добавить("ПолеТекстовогоДокумента"); МассивОбычныхЭлементовУправления.Добавить("ПолеВвода"); МассивОбычныхЭлементовУправления.Добавить("ПолеВыбора"); МассивОбычныхЭлементовУправления.Добавить("ПолеСписка"); МассивОбычныхЭлементовУправления.Добавить("ПолеКартинки"); МассивОбычныхЭлементовУправления.Добавить("ПолосаРегулирования"); МассивОбычныхЭлементовУправления.Добавить("Разделитель"); МассивОбычныхЭлементовУправления.Добавить("РамкаГруппы"); МассивОбычныхЭлементовУправления.Добавить("СводнаяДиаграмма"); МассивОбычныхЭлементовУправления.Добавить("СтраницаПанели"); МассивОбычныхЭлементовУправления.Добавить("ТабличноеПоле"); МассивОбычныхЭлементовУправления.Добавить("Флажок"); мМассивТиповЭлементовОбычнойФормы = Новый Массив; Для Каждого ИмяТипа Из МассивОбычныхЭлементовУправления Цикл мМассивТиповЭлементовОбычнойФормы.Добавить(Тип(ИмяТипа)); КонецЦикла; #КонецЕсли МассивУправляемыхЭлементовУправления = Новый Массив; МассивУправляемыхЭлементовУправления.Добавить("ПолеФормы"); МассивУправляемыхЭлементовУправления.Добавить("КнопкаФормы"); МассивУправляемыхЭлементовУправления.Добавить("ТаблицаФормы"); МассивУправляемыхЭлементовУправления.Добавить("ГруппаФормы"); МассивУправляемыхЭлементовУправления.Добавить("ДекорацияФормы"); мМассивТиповСМетаданными = Новый Массив; мМассивТиповСМетаданными.Добавить(Тип("ОбъектМетаданных")); мМассивТиповСМетаданными.Добавить(Тип("КоллекцияОбъектовМетаданных")); мМассивТиповСМетаданными.Добавить(Тип("КоллекцияДвижений")); мМассивТиповСМетаданными.Добавить(Тип("ОписанияСтандартныхРеквизитов")); мМассивТиповСМетаданными.Добавить(Тип("СписокПолей")); мМассивТиповСМетаданными.Добавить(Тип("Структура")); мМассивТиповСМетаданными.Добавить(Тип("СписокЗначений")); мМассивТиповСМетаданными.Добавить(Тип("ФиксированнаяСтруктура")); мМассивТиповСМетаданными.Добавить(Тип("ТаблицаЗначений")); мМассивТиповСМетаданными.Добавить(Тип("ДеревоЗначений")); мМассивТиповСМетаданными.Добавить(Тип("СтрокаТаблицыЗначений")); мМассивТиповСМетаданными.Добавить(Тип("СтрокаДереваЗначений")); мМассивТиповСМетаданными.Добавить(Тип("ВыборкаИзРезультатаЗапроса")); мМассивТиповСМетаданными.Добавить(Тип("РезультатЗапроса")); мМассивТиповСМетаданными.Добавить(Тип("Отбор")); мМассивТиповСМетаданными.Добавить(Тип("НастройкаОформления")); мМассивТиповСМетаданными.Добавить(Тип("COMОбъект")); мМассивТиповСМетаданными.Добавить(Тип("ВнешнийОбъект")); мМассивТиповСМетаданными.Добавить(Тип("ОбъектXDTO")); мМассивТиповСМетаданными.Добавить(Тип("СвойствоXDTO")); //мМассивТиповСМетаданными.Добавить(Тип("ОбщийМодуль")); мМассивТиповСМетаданными.Добавить(Тип("ПостроительЗапроса")); мМассивТиповСМетаданными.Добавить(Тип("ПостроительОтчета")); мМассивТиповСМетаданными.Добавить(Тип("ПоляНастройки")); мМассивТиповСМетаданными.Добавить(Тип("СхемаКомпоновкиДанных")); мМассивТиповСМетаданными.Добавить(Тип("ТабличныйДокумент")); мМассивТиповСМетаданными.Добавить(Тип("ТекстовыйДокумент")); мМассивТиповСМетаданными.Добавить(Тип("НаборыДанныхСхемыКомпоновкиДанных")); мМассивТиповСМетаданными.Добавить(Тип("ПараметрыСхемыКомпоновкиДанных")); //мМассивТиповСМетаданными.Добавить(Тип("ДинамическийСписок")); // Будет давать ошибку сериализации мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыДерево")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекция")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекцияЭлементовДерева")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктура")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктураСКоллекцией")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементДерева")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементКоллекции")); мМассивТиповСМетаданными.Добавить(ирОбщий.ТипУправляемаяФормаЛкс()); мМассивТиповСМетаданными.Добавить(Тип("ПолеФормы")); мМассивТиповСМетаданными.Добавить(Тип("ГруппаФормы")); мМассивТиповСМетаданными.Добавить(Тип("ТаблицаФормы")); мМассивТиповСМетаданными.Добавить(Тип("КомандыФормы")); #Если Клиент Тогда мМассивТиповСМетаданными.Добавить(Тип("Форма")); мМассивТиповСМетаданными.Добавить(Тип("ТабличноеПоле")); мМассивТиповСМетаданными.Добавить(Тип("Панель")); мМассивТиповСМетаданными.Добавить(Тип("КнопкаКоманднойПанели")); мМассивТиповСМетаданными.Добавить(Тип("КоманднаяПанель")); мМассивТиповСМетаданными.Добавить(Тип("ПолеВвода")); #КонецЕсли //#Если Клиент Или ВнешнееСоединение Тогда СубПутьКФайлуПотокаМодуляВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data.und.unp\text.data"; СубПутьКФайлуПотокаМакетаВнешнейОбработки = "902f74d3-f929-4b0f-8719-4cbb655891aa.0.data.und"; СубПутьКФайлуПотокаЗаголовкаВнешнейОбработки = "4eb1cc18-835d-4f8c-a120-3f9d886d75d4.data.und"; СубПутьККонтрольномуФайлуВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data"; //КешВнешнихОбработокАлгоритмов = Новый Структура; КешАлгоритмов = Новый Структура; ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов(); МакетыКомпонент = Новый Структура; МаркерКоллекцииОбъектовМетаданных = "КоллекцияОбъектовМетаданных"; МаркерОбъектаМетаданных = "ОбъектМетаданных"; мМассивИсключенийИменКоллекций = Новый СписокЗначений; мМассивИсключенийИменКоллекций.Добавить("Свойства"); мМассивИсключенийИменКоллекций.Добавить("Методы"); мМассивИсключенийИменКоллекций.Добавить(""); СоответствиеВидовСравнения = Новый ТаблицаЗначений; СоответствиеВидовСравнения.Колонки.Добавить("Построитель"); СоответствиеВидовСравнения.Колонки.Добавить("Компоновка"); СоответствиеВидовСравнения.Колонки.Добавить("Имя"); СоответствиеВидовСравнения.Индексы.Добавить("Построитель"); СоответствиеВидовСравнения.Индексы.Добавить("Компоновка"); //Интервал //ИнтервалВключаяГраницы //ИнтервалВключаяНачало //ИнтервалВключаяОкончание СоответствиеВидовСравнения.Добавить().Имя = "Больше"; СоответствиеВидовСравнения.Добавить().Имя = "БольшеИлиРавно"; СоответствиеВидовСравнения.Добавить().Имя = "ВИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "ВСписке"; СоответствиеВидовСравнения.Добавить().Имя = "ВСпискеПоИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "Меньше"; СоответствиеВидовСравнения.Добавить().Имя = "МеньшеИлиРавно"; СоответствиеВидовСравнения.Добавить().Имя = "НеВИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "НеВСписке"; СоответствиеВидовСравнения.Добавить().Имя = "НеВСпискеПоИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "НеРавно"; СоответствиеВидовСравнения.Добавить().Имя = "НеСодержит"; СоответствиеВидовСравнения.Добавить().Имя = "Равно"; СоответствиеВидовСравнения.Добавить().Имя = "Содержит"; Для Каждого СтрокаСоответствия Из СоответствиеВидовСравнения Цикл СтрокаСоответствия.Построитель = Вычислить("ВидСравнения." + СтрокаСоответствия.Имя); СтрокаСоответствия.Компоновка = Вычислить("ВидСравненияКомпоновкиДанных." + СтрокаСоответствия.Имя); КонецЦикла; мТаблицаЗамеров = Новый ТаблицаЗначений; мТаблицаЗамеров.Колонки.Добавить("_0"); мТаблицаЗамеров.Колонки.Добавить("Ключ"); мТаблицаЗамеров.Колонки.Добавить("ДатаНачала"); мТаблицаЗамеров.Колонки.Добавить("ОтладкаРазрешена", Новый ОписаниеТипов("Булево")); мТаблицаЗамеров.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число")); мТаблицаИндикаторов = Новый ТаблицаЗначений; мТаблицаИндикаторов.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число")); мТаблицаИндикаторов.Колонки.Добавить("ПредставлениеПроцесса", Новый ОписаниеТипов("Строка")); мТаблицаИндикаторов.Колонки.Добавить("ЛиВыводитьВремя", Новый ОписаниеТипов("Булево")); мТаблицаИндикаторов.Колонки.Добавить("РазрешитьПрерывание", Новый ОписаниеТипов("Булево")); мТаблицаИндикаторов.Колонки.Добавить("ДатаНачалаПроцесса", Новый ОписаниеТипов("Дата")); мТаблицаИндикаторов.Колонки.Добавить("МинимальныйПериодОбновления", Новый ОписаниеТипов("Число")); мТаблицаИндикаторов.Колонки.Добавить("СледующееОбновление", Новый ОписаниеТипов("Дата")); мТаблицаИндикаторов.Колонки.Добавить("Шаг", Новый ОписаниеТипов("Число")); мТаблицаИндикаторов.Колонки.Добавить("ТекстСостояния", Новый ОписаниеТипов("Строка")); мТаблицаИндикаторов.Колонки.Добавить("СледующийСчетчик", Новый ОписаниеТипов("Число")); мТаблицаИндикаторов.Колонки.Добавить("Счетчик", Новый ОписаниеТипов("Число")); мТаблицаИндикаторов.Колонки.Добавить("РежимОтладки", Новый ОписаниеТипов("Булево")); // Для ускорения мТаблицаИндикаторов.Колонки.Добавить("СледующаяПроверкаПрерывания", Новый ОписаниеТипов("Дата")); //#КонецЕсли RegExp = ирОбщий.НовоеРегВыражениеЛкс(); RegExp.IgnoreCase = Истина; RegExp.MultiLine = Ложь; RegExp2 = ирОбщий.НовоеРегВыражениеЛкс(); RegExp2.IgnoreCase = Истина; RegExp2.MultiLine = Ложь; мИменаОсновныхКлассовБиблиотекCOM = Новый Соответствие; мОбразцыCOMОбъектов = Новый Соответствие; БуферыСравнения = Новый Соответствие; МодальныеГруппы = Новый СписокЗначений; ОтмененныеФоновыеЗадания = Новый Массив; мДобавленныеОбщиеМодули = Новый Структура; мОписаниеТипаМДТабличнаяЧасть = ОписаниеТипаМетаОбъектов("ТабличнаяЧасть"); мОписаниеТипаМДВнешнийИсточникДанных = ОписаниеТипаМетаОбъектов("ВнешнийИсточникДанных");