//ирПортативный Перем ирПортативный Экспорт; //ирПортативный Перем ирОбщий Экспорт; //ирПортативный Перем ирСервер Экспорт; //ирПортативный Перем ирКэш Экспорт; //ирПортативный Перем ирКлиент Экспорт; Перем ВерсияПлатформы Экспорт; Перем ЭтоФайловаяБаза Экспорт; Перем мМетаданные Экспорт; Перем мПустойМодуль; // см. МодульМетаданных Перем ЭтоИнтеграция Экспорт; Перем СоответствиеВидовСравнения Экспорт; Перем МаркерНачалаАлгоритма Экспорт; Перем МаркерКонцаАлгоритма Экспорт; Перем МакетыКомпонент Экспорт; Перем мКэшПустыхЗначений Экспорт; Перем ВложенностьИндикации Экспорт; Перем КэшОбъектов Экспорт; Перем ВремяОбъект Экспорт; Перем мСловарьПеревода; Перем АрхитектураПроцессора Экспорт; Перем ВыполнятьАлгоритмыЧерезВнешниеОбработки Экспорт; Перем ВнешняяОбработкаСервисы Экспорт; Перем ФайловыйКэшАлгоритмовДопускаетРедактирование Экспорт; Перем ФормаПустышка Экспорт; Перем КешАлгоритмов; Перем СубПутьКФайлуМодуляВнешнейОбработки; Перем СубПутьКФайлуМодуляФормыВнешнейОбработки; Перем СубПутьКФайлуМакетаВнешнейОбработки; Перем СубПутьКФайлуЗаголовкаВнешнейОбработки; Перем СубПутьККонтрольномуФайлуВнешнейОбработки; Перем ПутьККаталогуСлужебныхВременныхФайлов; Перем мЕстьАдминистративныеПраваУУчетнойЗаписиОС; Перем СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось; Перем ПапкаКешаВнешнихОбработокАлгоритмов Экспорт; Перем ПапкаВнешнихКомпонент Экспорт; Перем ПапкаКэшаМодулей Экспорт; Перем ПапкаКэшаРолей Экспорт; Перем КаталогФайловогоКэша Экспорт; Перем СтруктураПодкаталоговФайловогоКэша Экспорт; Перем ИмяФайлаПакера Экспорт; Перем ШаблоныВнешнейОбработки; Перем ШаблоныВнешнейОбработкиСМакетом; Перем ФайлРегистратораКомпонентCU; Перем ФайлРегистратораNetКомпонент; Перем МассивСравненияТекстов Экспорт; Перем мВопросОтключенияПроверкиМодальностиЗадавался Экспорт; Перем мПроверкаСовместимостиКонфигурацииВыполнялась Экспорт; Перем мПроверкаЗащитыОтОпасныхДействийВыполнялась Экспорт; Перем мПроверкаСоединенияADOЭтойБДВыполнялась Экспорт; Перем мПерехватКлавиатуры; Перем мНомерВерсииПлатформы; Перем АсинхронностьЗапрещена Экспорт; Перем РежимОтладки Экспорт; // Отключает использование однострочных сверток кода. Снижает скорость, но облегчает отладку. Перем НастройкиКомпьютера Экспорт; Перем мДиалектыSQL Экспорт; // Используется в Обработка.ирКлсПолеёТекстаПрограммы Перем ЛиРежимСовместимости83 Экспорт; Перем WScriptShell; Перем мРегВыражение Экспорт; // ОбработкаОбъект.ирОболочкаРегВыражение Перем мРегВыражение2 Экспорт; // ОбработкаОбъект.ирОболочкаРегВыражение Перем мНечеткоеСравнениеСлов; Перем мТипыВыражений Экспорт; Перем мФайлОтменыВычислений Экспорт; // Файл, Неопределено Перем шЛюбой Экспорт; Перем шБуква Экспорт; Перем шБукваЦифра Экспорт; Перем шИмя Экспорт; Перем шЧисло Экспорт; Перем шИндекс Экспорт; Перем шСкобки Экспорт; Перем шGUID Экспорт; Перем шКомментарий Экспорт; Перем шРазделитель Экспорт; Перем шПустоеНачалоСтроки Экспорт; Перем шЛитералПрограммы Экспорт; Перем шЛитералПростой Экспорт; Перем шЛитералВЗапросе Экспорт; Перем шИмяВременнойТаблицы Экспорт; Перем шГиперСсылка Экспорт; Перем шИнструкцияПрепроцессора Экспорт; Перем шМетодНачало Экспорт; Перем шМетодКонец Экспорт; Перем МаркерОбъектаМетаданных; Перем МаркерКоллекцииМетаданных; //#Если Клиент Или ВнешнееСоединение Тогда Перем ИдентификаторПроцессаОС Экспорт; Перем VBScript Экспорт; Перем JavaScript Экспорт; Перем ДеревоТипов Экспорт; Перем ТаблицаКонтекстов Экспорт; Перем ТаблицаОбщихТипов Экспорт; Перем ТаблицаИменЭлементовКоллекций Экспорт; Перем ТаблицаРасширенийТипов Экспорт; Перем ТаблицаТиповМетаданных Экспорт; Перем ТаблицаСокращенияИменТипов Экспорт; Перем ТаблицаШаблоновКонтекстов Экспорт; Перем ТаблицаТиповМетаОбъектов Экспорт; Перем ТаблицаПараметров Экспорт; Перем СлужебноеПолеТекста Экспорт; Перем СлужебноеПолеТекста2 Экспорт; //Перем СлужебноеПолеHtmlДокумента Экспорт; Перем МассивОбычныхЭлементовУправления Экспорт; Перем МассивУправляемыхЭлементовУправления Экспорт; Перем мМассивТиповЭлементовОбычнойФормы Экспорт; Перем мМассивТиповЭлементовУправляемойФормы Экспорт; Перем ТаблицаСтатистикиВыбора Экспорт; Перем ДатаПоследнегоСохраненияСтатистикиВыбора Экспорт; Перем мМассивТиповСМетаданными Экспорт; Перем мТаблицаТипов; Перем мТаблицаСоответствияВидов; Перем мТаблицаЗамеров Экспорт; Перем мИндикаторы Экспорт; Перем мИменаОсновныхКлассовБиблиотекCOM; // Кэш имен классов, например Exel - Application Перем мОбразцыCOMОбъектов; // Для вычисления свойств Перем мADOUtils; // см. ПолучитьADOUtils() Перем мКэшСловГлобальногоКонтекста; Перем мКолонкиБД Экспорт; Перем мСтруктураХраненияБДСРазмерами Экспорт; Перем мТаблицаРедактируемыхТипов; Перем мОписаниеТипаМДТабличнаяЧасть; Перем мОписаниеТипаМДВнешнийИсточникДанных; Перем мДеревоОбъектовМД; Перем мТаблицаВсехТаблицБД; Перем мПоляТекстаПрограммы; Перем мШаблоныДляАнализаВстроенногоЯзыка; Перем мСлужебнаяФорма; Перем COMНавигатор Экспорт; // см. ПолучитьCOMНавигатор() Перем ТаблицаШаблоновТекста Экспорт; Перем мКартинкиТипов; Перем мМассивИсключенийИменКоллекций; Перем мПассивныеФормы; Перем мИменаТиповМетаданныхСМенеджерами; Перем мКэшРазбораВыражений Экспорт; Перем мПравилаВычисленияФункций Экспорт; Перем мВсеИменаСобытийЭлементовФормы; Перем ФайлЗапаковщика1С Экспорт; Перем ФайлБиблиотекиЗапаковщика; Перем ФайлОткрывателя1С Экспорт; Перем ФайлФорматераЗапросовБД Экспорт; Перем ФайлРаспаковщикаZIP Экспорт; Перем СинтаксПомощник; Перем Парсеры Экспорт; Перем БуферыСравнения Экспорт; Перем ПараметрыОбработчикаОжидания Экспорт; Перем БазовыйФайлРедактораJSON; Перем БазовыйФайлРедактораКода; Перем мМаркерИмениЗапросаПакета Экспорт; Перем мМаркерИмениЧастиОбъединения Экспорт; Перем СинтаксическийКонтрольПередЗаписью Экспорт; Перем ОтложенноеОткрытиеИсточникаОшибки Экспорт; Перем АвторегистрацияComКомпонент Экспорт; Перем ЛиКомпонентаFormsTextBoxДоступна; Перем МодальныеГруппы Экспорт; Перем мМодулиМетаданных; Перем мПрямыеВызовыМетодов; Перем мВызовыВсехСловПоМодулям; Перем ОткрытыеФормыПодсистемы Экспорт; Перем ОтслеживаемыеФормы Экспорт; Перем ПерехватКлавиатурногоВводаВОбычномПриложении Экспорт; Перем ОтмененныеФоновыеЗадания Экспорт; Перем ВнутреннийБуферОбмена Экспорт; Перем ПроверочноеСоединениеЭтойСУБД Экспорт; Перем ИспользоватьЭмуляциюНажатияКлавиш Экспорт; Перем ВыделениеРезультатовПоиска Экспорт; Перем НеИспользоватьУправляемыеФормыИнструментов Экспорт; Перем мСвязанныйКонфигуратор Экспорт; Перем мДатаОбновленияКэшаМодулей; Перем мДобавленныеОбщиеМодули; Перем мРежимПроверкиМодуля Экспорт; Перем мРежимПереходаКОпределению Экспорт; Перем мОчередьСообщенийВнешнемуКлиенту Экспорт; // см. НоваяОчередьСообщенийВнешнемуКлиенту, Неопределено - для накопления важных сообщений в режиме Automation-сервера Перем мТерминалыЯзыкаЗапросов; Перем мПроизвольныйКод Экспорт; // Для адаптера Перем ПеречТипСлова Экспорт; // см. ПеречТипСлова Перем ПеречИсточникСлова Экспорт; // см. ПеречИсточникСлова // Инициализирует, если необходимо, большие таблицы платформы. // К ним относятся таблицы методов и свойств. // // Параметры: // Нет. // Процедура ИнициацияОписанияМетодовИСвойств() Экспорт Если ТаблицаКонтекстов <> Неопределено Тогда Возврат; КонецЕсли; #Если Клиент Тогда Состояние("Инициализация таблицы методов и свойств..."); #КонецЕсли МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаМетодовИСвойств").ПолучитьТекст()); ТаблицаКонтекстов = МассивТаблиц.ТаблицаКонтекстов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаКонтекстов ТаблицаКонтекстов.Колонки.Добавить("Описание"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово"); ТаблицаКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово, ТипСлова"); ТаблицаШаблоновКонтекстов = МассивТаблиц.ТаблицаШаблоновКонтекстов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаШаблоновКонтекстов ТаблицаШаблоновКонтекстов.Колонки.Добавить("Описание"); // Нужно для вирт. таблицы КритерийОтбора.<Имя критерия отбора>() ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста"); ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка"); ТаблицаШаблоновКонтекстов.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова"); ТаблицаПараметров = МассивТаблиц.ТаблицаПараметров; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаПараметров ТаблицаПараметров.Колонки.Добавить("Описание"); ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово"); //ТаблицаПараметров.Индексы.Добавить("ТипКонтекста, ЯзыкПрограммы, Слово, Номер"); #Если Клиент Тогда Состояние(""); #КонецЕсли //мПравилаВычисленияФункций = ирОбщий.НоваяТаблицаЗначенийЛкс("Слово, нСлово, ТипКонтекста, Правило"); // Долго мПравилаВычисленияФункций = Новый ТаблицаЗначений; мПравилаВычисленияФункций.Колонки.Добавить("Слово"); мПравилаВычисленияФункций.Колонки.Добавить("нСлово"); мПравилаВычисленияФункций.Колонки.Добавить("ТипКонтекста"); мПравилаВычисленияФункций.Колонки.Добавить("Правило"); мПравилаВычисленияФункций.Индексы.Добавить("Слово, ТипКонтекста"); ТаблицаСтатистикиВыбора = ирОбщий.ВосстановитьЗначениеЛкс("ирПлатформа.ТаблицаСтатистикиВыбора"); ИмяКолонкиХраненияВерсии = "ЯзыкПрограммы"; ВерсияСтатистики = "2"; Если ТаблицаСтатистикиВыбора <> Неопределено Тогда Если Ложь Или ТаблицаСтатистикиВыбора.Колонки.Найти(ИмяКолонкиХраненияВерсии) = Неопределено Или ТаблицаСтатистикиВыбора.Колонки[ИмяКолонкиХраненияВерсии].Заголовок <> ВерсияСтатистики Тогда ТаблицаСтатистикиВыбора = Неопределено; КонецЕсли; КонецЕсли; Если ТаблицаСтатистикиВыбора = Неопределено Тогда ТаблицаСтатистикиВыбора = Новый ТаблицаЗначений; ТаблицаСтатистикиВыбора.Колонки.Добавить("ТипКонтекста", Новый ОписаниеТипов("Строка")); ТаблицаСтатистикиВыбора.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка")); ТаблицаСтатистикиВыбора.Колонки.Добавить("ЯзыкПрограммы", Новый ОписаниеТипов("Число")); ТаблицаСтатистикиВыбора.Колонки.Добавить("ЭтоМетод", Новый ОписаниеТипов("Булево")); ТаблицаСтатистикиВыбора.Колонки.Добавить("Рейтинг", Новый ОписаниеТипов("Число")); КонецЕсли; ТаблицаСтатистикиВыбора.Колонки[ИмяКолонкиХраненияВерсии].Заголовок = ВерсияСтатистики; Если ТаблицаСтатистикиВыбора.Индексы.Количество() > 2 Тогда ТаблицаСтатистикиВыбора.Индексы.Очистить(); КонецЕсли; ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаСтатистикиВыбора, "ТипКонтекста, ЯзыкПрограммы"); ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаСтатистикиВыбора, "ТипКонтекста, ЯзыкПрограммы, Слово, ЭтоМетод"); ДатаПоследнегоСохраненияСтатистикиВыбора = ТекущаяДата(); КонецПроцедуры // Инициализирует, если необходимо, малые таблицы платформы. // К ним относятся таблицы типов и коллекций. // // Параметры: // Нет. // Процедура ИнициализацияОписанияОбщихТипов() Экспорт Если ТипЗнч(ТаблицаОбщихТипов) = Тип("ТаблицаЗначений") Тогда Возврат; КонецЕсли; МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаИменЭлементовКоллекций").ПолучитьТекст()); // Структура ТаблицаИменЭлементовКоллекций = МассивТаблиц.ТаблицаИменЭлементовКоллекций; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаИменЭлементовКоллекций ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяКоллекции"); ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяЭлементаКоллекции"); ТаблицаИменЭлементовКоллекций.Индексы.Добавить("ИмяОбщегоТипа, ИмяЭлементаКоллекции"); ТаблицаРасширенийТипов = МассивТаблиц.ТаблицаРасширений; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаРасширений ТаблицаРасширенийТипов.Индексы.Добавить("Расширение"); ТаблицаРасширенийТипов.Индексы.Добавить("ОсновнойТип"); ТаблицаТиповМетаданных = МассивТаблиц.ТаблицаТиповМетаданных; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаТиповМетаданных Если МассивТаблиц.Свойство("ТаблицаСокращенияИменТипов") Тогда ТаблицаСокращенияИменТипов = МассивТаблиц.ТаблицаСокращенияИменТипов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаСокращенияИменТипов КонецЕсли; МассивТаблиц = ЗначениеИзСтрокиВнутр(ПолучитьМакет("ТаблицаОбщихТипов").ПолучитьТекст()); ТаблицаОбщихТипов = МассивТаблиц.ТаблицаОбщихТипов; // см. Обработка.ирПлатформа.Форма.ОписаниеПлатформы.ТаблицаОбщихТипов ТаблицаОбщихТипов.Колонки.Добавить("Описание"); ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы"); ТаблицаОбщихТипов.Индексы.Добавить("Слово, ТипТипа"); //ТаблицаОбщихТипов.Индексы.Добавить("Слово, ЯзыкПрограммы, ТипТипа"); ТаблицаОбщихТипов.Индексы.Добавить("НСлово, ЯзыкПрограммы, ЕстьКонструктор"); ТаблицаОбщихТипов.Индексы.Добавить("Представление, ТипТипа"); ТаблицаОбщихТипов.Индексы.Добавить("ИД"); ТаблицаОбщихТипов.Индексы.Добавить("БазовыйТип, ЯзыкПрограммы"); ПеречТипСлова(); ПеречИсточникСлова(); КонецПроцедуры // Добавляет дополнительные Свойства для типов контекстов платформы. Процедура ДобавитьСловоВОписаниеТипаКонтекста(ТипКонтекста, Слово, ТипСлова, ТипЗначения) Экспорт ИнициацияОписанияМетодовИСвойств(); НоваяСтрока = ТаблицаКонтекстов.Добавить(); НоваяСтрока.ТипКонтекста = ТипКонтекста; НоваяСтрока.Слово = Слово; НоваяСтрока.НСлово = НРег(Слово); НоваяСтрока.ТипСлова = ТипСлова; НоваяСтрока.ТипЗначения = ТипЗначения; КонецПроцедуры // Добавляет в список значений коллекцию объектов метаданных. // // Параметры: // пСписокМетаданных - СписокЗначений - куда добавляем объекты; // пИмяМетаданных - Строка - имя коллекции объектов метаданных или имя корневого типа; // *ЛиПолноеИмя - Булево, *Истина - добавлять полные имена, иначе краткие; // *ЛиДобавлятьКартинки - Булево, *Истина - добавлять картинки; // *ОтборПоПраву - Строка, *Неопределено - проверять перед добавлением право текущего пользователя. // Процедура ДобавитьВСписокКоллекциюМетаданных(пСписокМетаданных, пИмяМетаданных, ЛиПолноеИмя = Истина, ЛиДобавлятьКартинки = Истина, ОтборПоПраву = Неопределено) Экспорт Картинка = Неопределено; СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(пИмяМетаданных, , 0); Если СтрокаКорневогоТипа <> Неопределено Тогда ИмяКоллекцииМетаданных = СтрокаКорневогоТипа.Множественное; #Если Клиент Тогда Если ЛиДобавлятьКартинки Тогда КорневойТип = пИмяМетаданных; Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип); КонецЕсли; #КонецЕсли Иначе ИмяКоллекцииМетаданных = пИмяМетаданных; #Если Клиент Тогда Если ЛиДобавлятьКартинки Тогда КорневойТип = ОписаниеТипаМетаОбъектов(, пИмяМетаданных, 0).Единственное; Картинка = ирКлиент.КартинкаКорневогоТипаМДЛкс(КорневойТип); КонецЕсли; #КонецЕсли КонецЕсли; Для Каждого Объект ИЗ мМетаданные[ИмяКоллекцииМетаданных] Цикл Если Истина И ОтборПоПраву <> Неопределено И Не ПравоДоступа(ОтборПоПраву, Объект) Тогда Продолжить; КонецЕсли; Если ЛиПолноеИмя Тогда ИмяМетаОбъекта = Объект.ПолноеИмя(); Иначе ИмяМетаОбъекта = Объект.Имя; КонецЕсли; пСписокМетаданных.Добавить(ИмяМетаОбъекта, Объект.Представление(), , Картинка); КонецЦикла; КонецПроцедуры // Получает список ключевых слов языка запросов. // // Параметры: // *Расширение - Тип, *Неопределено - для определения расширения языка запросов. // // Возвращаемое значение: // СписокЗначений - где значение содержит слово. // Функция КлючевыеСловаЯзыкаЗапросов(Знач РежимКомпоновкиДанных = Ложь, Знач Русские = Истина, Знач Английские = Ложь) Экспорт Список = Новый СписокЗначений; Если Русские Тогда Список.Добавить("АВТОУПОРЯДОЧИВАНИЕ"); Список.Добавить("ВНУТРЕННЕЕ"); Список.Добавить("ВОЗР"); Список.Добавить("ВСЕ"); Список.Добавить("ВЫБРАТЬ"); Список.Добавить("ДОБАВИТЬ"); Список.Добавить("ГДЕ"); Список.Добавить("ДЛЯ"); Список.Добавить("ИЗ"); Список.Добавить("ИЗМЕНЕНИЯ"); Список.Добавить("ИМЕЮЩИЕ"); Список.Добавить("ИНДЕКСИРОВАТЬ"); Список.Добавить("ИТОГИ"); Список.Добавить("КАК"); Список.Добавить("ЛЕВОЕ"); Список.Добавить("НАБОРАМ"); Список.Добавить("ОБЩИЕ"); Список.Добавить("ОБЪЕДИНИТЬ"); Список.Добавить("ПЕРВЫЕ"); Список.Добавить("ПО"); Список.Добавить("ПОЛНОЕ"); Список.Добавить("ПОМЕСТИТЬ"); Список.Добавить("ПРАВОЕ"); Список.Добавить("РАЗЛИЧНЫЕ"); Список.Добавить("РАЗРЕШЕННЫЕ"); Список.Добавить("СГРУППИРОВАТЬ"); Список.Добавить("СОЕДИНЕНИЕ"); Список.Добавить("УБЫВ"); Список.Добавить("УНИКАЛЬНО"); Список.Добавить("УНИЧТОЖИТЬ"); Список.Добавить("УПОРЯДОЧИТЬ"); Список.Добавить("НЕ"); Список.Добавить("И"); Список.Добавить("ИЛИ"); Список.Добавить("ВЫБОР"); Список.Добавить("КОГДА"); Список.Добавить("ТОГДА"); Список.Добавить("ИНАЧЕ"); Список.Добавить("КОНЕЦ"); Список.Добавить("ЕСТЬ"); Список.Добавить("NULL"); Список.Добавить("МЕЖДУ"); Список.Добавить("В"); Список.Добавить("ПОДОБНО"); Список.Добавить("СПЕЦСИМВОЛ"); Список.Добавить("ИЕРАРХИЯ"); Список.Добавить("ИЕРАРХИИ"); Список.Добавить("ССЫЛКА"); Если РежимКомпоновкиДанных Тогда // Видимо это устаревшие слова Список.Добавить("ЗНАЧЕНИЕ"); Список.Добавить("ЗНАЧЕНИЯ"); Список.Добавить("ИДЕНТИФИКАТОР"); Список.Добавить("ИМЯ"); Список.Добавить("ОБЪЕКТ"); Список.Добавить("СПИСОК"); Список.Добавить("ТИПЗНАЧЕНИЯ"); Список.Добавить("ХАРАКТЕРИСТИКА"); // Это новые слова Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК"); Список.Добавить("ПОЛЕИМЕНИ"); Список.Добавить("ПОЛЕКЛЮЧА"); Список.Добавить("ПОЛЕЗНАЧЕНИЯ"); Список.Добавить("ПОЛЕВИДА"); Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ"); Список.Добавить("ПОЛЕОБЪЕКТА"); Список.Добавить("ВИДЫХАРАКТЕРИСТИК"); КонецЕсли; КонецЕсли; Если Английские Тогда Список.Добавить("AUTOORDER"); Список.Добавить("INNER"); Список.Добавить("ASC"); Список.Добавить("ALL"); Список.Добавить("SELECT"); Список.Добавить("WHERE"); Список.Добавить("FOR"); Список.Добавить("FROM"); Список.Добавить("UPDATE"); Список.Добавить("HAVING"); Список.Добавить("INDEX"); Список.Добавить("TOTALS"); Список.Добавить("AS"); Список.Добавить("LEFT"); Список.Добавить("SETS"); //Список.Добавить("ОБЩИЕ"); // ЗАБЫЛ перевод Список.Добавить("UNION"); Список.Добавить("FIRST"); Список.Добавить("BY"); Список.Добавить("ON"); Список.Добавить("FULL"); Список.Добавить("INTO"); Список.Добавить("RIGHT"); Список.Добавить("DISTINCT"); Список.Добавить("ALLOWED"); Список.Добавить("GROUP"); Список.Добавить("JOIN"); Список.Добавить("DESC"); Список.Добавить("UNIQUE"); Список.Добавить("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"); // // Это новые слова // Список.Добавить("ЗНАЧЕНИЯХАРАКТЕРИСТИК"); // Список.Добавить("ПОЛЕИМЕНИ"); // Список.Добавить("ПОЛЕКЛЮЧА"); // Список.Добавить("ПОЛЕЗНАЧЕНИЯ"); // Список.Добавить("ПОЛЕВИДА"); // Список.Добавить("ПОЛЕТИПАЗНАЧЕНИЯ"); // Список.Добавить("ПОЛЕОБЪЕКТА"); // Список.Добавить("ВИДЫХАРАКТЕРИСТИК"); //КонецЕсли; КонецЕсли; Возврат Список; КонецФункции // Получает список ключевых встроенного языка. // // Параметры: // Нет. // // Возвращаемое значение: // СписокЗначений - где значение содержит слово. // Функция КлючевыеСловаВстроенногоЯзыка(Знач Русские = Истина, Знач Английские = Ложь) Экспорт Список = Новый СписокЗначений; Если Русские Тогда Список.Добавить("Знач"); Список.Добавить("Процедура"); Список.Добавить("Функция"); Список.Добавить("Экспорт"); Список.Добавить("Возврат"); Список.Добавить("ВызватьИсключение"); Список.Добавить("Выполнить"); Список.Добавить("Для"); Список.Добавить("Если"); Список.Добавить("И"); Список.Добавить("Из"); Список.Добавить("Или"); Список.Добавить("Иначе"); Список.Добавить("ИначеЕсли"); Список.Добавить("Исключение"); Список.Добавить("Каждого"); Список.Добавить("КонецЕсли"); Список.Добавить("КонецПопытки"); Список.Добавить("КонецПроцедуры"); Список.Добавить("КонецФункции"); Список.Добавить("КонецЦикла"); Список.Добавить("Не"); Список.Добавить("Новый"); Список.Добавить("Перейти"); Список.Добавить("Перем"); Список.Добавить("По"); Список.Добавить("Пока"); Список.Добавить("Попытка"); Список.Добавить("Прервать"); Список.Добавить("Продолжить"); Список.Добавить("Тогда"); Список.Добавить("Цикл"); Список.Добавить("ДобавитьОбработчик"); Список.Добавить("УдалитьОбработчик"); // 8.3 Список.Добавить("Ждать"); Список.Добавить("Асинх"); КонецЕсли; Если Английские Тогда Список.Добавить("Val"); Список.Добавить("Procedure"); Список.Добавить("Function"); Список.Добавить("Export"); Список.Добавить("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"); Список.Добавить("Then"); Список.Добавить("Do"); Список.Добавить("AddHandler"); Список.Добавить("RemoveHandler"); // 8.3 Список.Добавить("Await"); Список.Добавить("Async"); КонецЕсли; Возврат Список; КонецФункции Функция ЛитералыЗначенияВсехЯзыков1С() Экспорт Список = Новый СписокЗначений; Список.Добавить("Истина", "Истина"); Список.Добавить("True", "Истина"); Список.Добавить("Ложь", "Ложь"); Список.Добавить("False", "Ложь"); Список.Добавить("Неопределено", "Неопределено"); Список.Добавить("Undefined", "Неопределено"); Список.Добавить("Null", "Null"); Возврат Список; КонецФункции // Размаскирует обращения к временным таблицам в тексте запроса. // // Параметры: // ТекстЗапроса - Строка; // МассивВременныхТаблиц - Массив - элементами являются имена временных таблиц, замаскированных ранее. // // Возвращаемое значение: // Строка - новые текст запроса. // Функция РазмаскироватьВременныеТаблицы(ТекстЗапроса, МассивВременныхТаблиц, выхВсеРазмаскировано = Ложь) Экспорт Если МассивВременныхТаблиц.Количество() = 0 Тогда Возврат ТекстЗапроса; КонецЕсли; // Допустимы 2 уровня скобок внутри имитатора временной таблицы. мРегВыражение.Global = Истина; мРегВыражение.MultiLine = Ложь; мРегВыражение.IgnoreCase = Истина; ИмяВременнойТаблицы = ""; Для Каждого ПодмененнаяВременнаяТаблица Из МассивВременныхТаблиц Цикл ИмяВременнойТаблицы = ИмяВременнойТаблицы + "|" + ПодмененнаяВременнаяТаблица; КонецЦикла; ИмяВременнойТаблицы = Сред(ИмяВременнойТаблицы, 2); НовыйТекстЗапроса = ТекстЗапроса; // Сначала делаем красивые замены - подзапрос на имя временной таблицы //мРегВыражение.Pattern = "\(ВЫБРАТЬ(?:" + шСкобки + "|[^$\(\)])*?""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")""\)"; мРегВыражение.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")""\s*\)"; НовыйТекстЗапроса = мРегВыражение.Заменить(НовыйТекстЗапроса, "$2"); выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0; Если Не выхВсеРазмаскировано Тогда // А теперь делаем некрасивые замены - оставляем подзапросы но заменяем в них имена полей и временной таблицы мРегВыражение.Pattern = "\(ВЫБРАТЬ(?:[^\(\)]*(?:" + шСкобки + "[^\(\)]*)*)""ВременнаяТаблица"" = ""(" + ИмяВременнойТаблицы + ")"""; НовыйТекстЗапроса = мРегВыражение.Заменить(НовыйТекстЗапроса, "(ВЫБРАТЬ Т.* ИЗ $2 КАК Т ГДЕ ИСТИНА"); // и0ие90цаун787 мРегВыражение.Pattern = "ВЫБОР\s+КОГДА\s+""!ИмяПоля!""\s+=\s+""(.+?)""\s+ТОГДА\s+.+?\n\s*(?:КОГДА\s+ЛОЖЬ\s+ТОГДА\s+.+?\n)*\s*КОНЕЦ"; НовыйТекстЗапроса = мРегВыражение.Заменить(НовыйТекстЗапроса, "Т.$1"); выхВсеРазмаскировано = Найти(НовыйТекстЗапроса, """ВременнаяТаблица"" = """) = 0; КонецЕсли; Если Не выхВсеРазмаскировано Тогда ВызватьИсключение "Не удалось размаскировать временные таблицы в тексте запроса. Возможно на них был наложен несовместимый с маскировкой отбор компоновки."; КонецЕсли; Возврат НовыйТекстЗапроса; КонецФункции // РазмаскироватьВременныеТаблицы() // Получает текст запроса, где каждая временная таблица заменена своим имитатором. // // Параметры: // ОбъектЗапроса - Запрос - // *ТекстЗапроса - Строка, *Неопределено - // *МассивВременныхТаблиц - Массив, *Неопределено - все подменяемые таблицы заносятся сюда. // // Возвращаемое значение: // Строка - новый текст запроса. // Функция ЗамаскироватьВременныеТаблицы(ОбъектЗапроса, Знач ТекстЗапроса = Неопределено, МассивВременныхТаблиц = Неопределено) Экспорт Если ТекстЗапроса = Неопределено Тогда ТекстЗапроса = ОбъектЗапроса.Текст; КонецЕсли; ВременныйЗапрос = Новый Запрос; ВременныйЗапрос.МенеджерВременныхТаблиц = ОбъектЗапроса.МенеджерВременныхТаблиц; ПроверочныйЗапрос = Новый ПостроительЗапроса; Если ТипЗнч(МассивВременныхТаблиц) <> Тип("Массив") Тогда МассивВременныхТаблиц = Новый Массив; КонецЕсли; ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстЗапроса); Пока Истина Цикл Попытка ПроверочныйЗапрос.Текст = ТекстЗапроса; Прервать; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); //ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, """", """"); ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Таблица не найдена """, """", Ложь); Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда ВременныйЗапрос.Текст = "ВЫБРАТЬ * ИЗ " + ИмяВременнойТаблицы; Попытка КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки; Исключение Прервать; КонецПопытки; КонецЕсли; // В 8.2.15 такой прием лишен смысла, т.к. движок запросов потом не сможет обработать обращения к дочерним полям //Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда // ИмяВременнойТаблицы = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "Неверные параметры """, """", Ложь); // Если ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда // Попытка // КолонкиВременнойТаблицы = ОбъектЗапроса.Параметры[ИмяВременнойТаблицы].Колонки; // Исключение // Попытка // КолонкиВременнойТаблицы = ВременныйЗапрос.Выполнить().Колонки; // Исключение // Прервать; // КонецПопытки; // КонецПопытки; // ИмяВременнойТаблицы = "&" + ИмяВременнойТаблицы; // КонецЕсли; //КонецЕсли; Если Не ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда Прервать; КонецЕсли; ИмитаторВременнойТаблицы = ирОбщий.ЗапросИмитаторКоллекцииПолейЛкс(КолонкиВременнойТаблицы) + " ГДЕ ""ВременнаяТаблица"" = """ + ИмяВременнойТаблицы + """"; КоординатыОбращения = ирОбщий.ТекстМеждуМаркерамиЛкс(ИнформацияОбОшибке.Причина.Описание, "{(", ")}"); НомерСтроки = Число(ирОбщий.ПервыйФрагментЛкс(КоординатыОбращения, ", ")); НомерКолонки = Число(ирОбщий.ПоследнийФрагментЛкс(КоординатыОбращения, ",")); СтрокаЗапроса = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки); ТекстПосле = Сред(СтрокаЗапроса, НомерКолонки + СтрДлина(ИмяВременнойТаблицы)); СтрокаКАК = "КАК"; Если Не ирОбщий.СтрокиРавныЛкс(Лев(СокрЛ(ТекстПосле), СтрДлина(СтрокаКАК)), СтрокаКАК) Тогда ТекстПосле = " КАК " + ИмяВременнойТаблицы + " " + ТекстПосле; КонецЕсли; НоваяСтрока = Лев(СтрокаЗапроса, НомерКолонки - 1) + "(" + ИмитаторВременнойТаблицы + ")" + ТекстПосле; ТекстовыйДокумент.ЗаменитьСтроку(НомерСтроки, НоваяСтрока); ТекстЗапроса = ТекстовыйДокумент.ПолучитьТекст(); МассивВременныхТаблиц.Добавить(ИмяВременнойТаблицы); КонецПопытки; КонецЦикла; Возврат ТекстЗапроса; КонецФункции // Результат - Массив Функция НайтиВозможныеИменаВременныхТаблиц(ТекстЗапроса, ЛиДиалект1С = Истина) Экспорт Имена = Новый Соответствие; мРегВыражение.Global = Истина; мРегВыражение.pattern = "(?:ИЗ|FROM|СОЕДИНЕНИЕ|JOIN|УНИЧТОЖИТЬ|DROP|,)\s+(" + шИмяВременнойТаблицы + ")(?:\s|$|[^\(\._\d" + шБуква + "])"; РезультатПоиска = мРегВыражение.НайтиВхождения(ТекстЗапроса); Для Каждого Вхождение Из РезультатПоиска Цикл Имена.Вставить(Нрег(Вхождение.SubMatches(0)), Вхождение.SubMatches(0)); КонецЦикла; Результат = Новый Массив(); Для Каждого КлючИЗначение Из Имена Цикл Если Истина И ЛиДиалект1С И (Ложь Или ирОбщий.СтрокиРавныЛкс(КлючИЗначение.Значение, "Константы") Или Найти(КлючИЗначение.Значение, ".") > 0) Тогда Продолжить; КонецЕсли; Результат.Добавить(КлючИЗначение.Значение); КонецЦикла; Возврат Результат; КонецФункции Функция РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(Знач ТекстПакета, Знач ПозицияКурсора = Неопределено, выхПозиции0 = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли МассивТекстовЗапросов = Новый Массив; Если Не ирКэш.ДоступноРегВыраженияЛкс() Тогда Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда Схема = Вычислить("Новый СхемаЗапроса"); #Если Сервер И Не Сервер Тогда Схема = Новый СхемаЗапроса; #КонецЕсли Попытка Схема.УстановитьТекстЗапроса(ТекстПакета); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки Возврат МассивТекстовЗапросов; КонецПопытки; Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл МассивТекстовЗапросов.Добавить(ЗапросПакета.ПолучитьТекстЗапроса()); КонецЦикла; КонецЕсли; Возврат МассивТекстовЗапросов; КонецЕсли; мРегВыражение.Global = Истина; мРегВыражение.Multiline = Ложь; //мРегВыражение.Pattern = "(?:" + шЛитералВЗапросе + ")|" + шКомментарий + "|;(?:\s*\n)*|$"; мРегВыражение.Pattern = "[^^](?:" + шЛитералВЗапросе + ")|" + шКомментарий + "|;|$"; Результат = мРегВыражение.НайтиВхождения(ТекстПакета,, Истина); НачалоЗапроса = 1; ОстальнойТекст = ТекстПакета; ДлинаТекстаПакета = СтрДлина(ТекстПакета); выхПозиции0 = Новый Массив; выхПозиции0.Добавить(0); Для Каждого Match Из Результат Цикл ПозицияВхождения = Match.FirstIndex; Если Истина И Не ирОбщий.СтрНачинаетсяСЛкс(Match.Value, ";") И ПозицияВхождения <> ДлинаТекстаПакета Тогда Продолжить; КонецЕсли; ДлинаТекстаЗапроса = ПозицияВхождения + Match.Length; ТекстЗапроса = Сред(ТекстПакета, НачалоЗапроса, ДлинаТекстаЗапроса - НачалоЗапроса + 1); Если ПустаяСтрока(ТекстЗапроса) Тогда Продолжить; КонецЕсли; //Если ТекстЗапроса = ";" Тогда // Продолжить; //КонецЕсли; ОстальнойТекст = Сред(ОстальнойТекст, ДлинаТекстаЗапроса + 1); НачалоЗапроса = НачалоЗапроса + СтрДлина(ТекстЗапроса); МассивТекстовЗапросов.Добавить(ТекстЗапроса); выхПозиции0.Добавить(ПозицияВхождения + 1); Если ПозицияКурсора <> Неопределено И ПозицияКурсора < ПозицияВхождения Тогда Прервать; КонецЕсли; КонецЦикла; Если МассивТекстовЗапросов.Количество() = 0 Тогда МассивТекстовЗапросов.Добавить(ТекстПакета); Иначе выхПозиции0.Удалить(выхПозиции0.ВГраница()); КонецЕсли; Возврат МассивТекстовЗапросов; КонецФункции // Структура результата пакетного запроса на основе разметки в комментариях. // // Параметры: // ТекстПакетаИлиМассивТекстовЗапросов - - // ПрефиксКомментария - - // // Возвращаемое значение: // - // Функция СтруктураРезультатаПакетногоЗапроса(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ПрефиксКомментария = "//") Экспорт Результат = Новый Структура; Если Не ирКэш.ДоступноРегВыраженияЛкс() Тогда Возврат Результат; КонецЕсли; Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Строка") Тогда МассивТекстовЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов); Иначе МассивТекстовЗапросов = ТекстПакетаИлиМассивТекстовЗапросов; КонецЕсли; мРегВыражение.Global = Ложь; мРегВыражение.Multiline = Ложь; мРегВыражение.Pattern = ирОбщий.ТекстДляРегВыраженияЛкс(ПрефиксКомментария + мМаркерИмениЗапросаПакета) + "(" + шИмя + ")(?: |\n|\r)"; Индекс = -1; Для Каждого ТекстЗапроса Из МассивТекстовЗапросов Цикл Индекс = Индекс + 1; Вхождения = мРегВыражение.НайтиВхождения(ТекстЗапроса); Если Вхождения.Количество() = 0 Тогда Продолжить; КонецЕсли; ИмяЗапроса = Вхождения[0].SubMatches(0); Если ирОбщий.ЛиИмяПеременнойЛкс(ИмяЗапроса) Тогда Результат.Вставить(ИмяЗапроса, Индекс); КонецЕсли; КонецЦикла; Возврат Результат; КонецФункции Функция ПреобразоватьЗапросВПодзапрос(Текст, ТекстВыбранныхПолей = "*", ПсевдонимВложенногоЗапроса = "ВложенныйЗапрос", ОбрезатьНачинаяСУпорядочивания = Ложь, ЭтоРусскийЯзык = Истина, Знач Смещение = "") Экспорт //ЭтоРусскийЯзык = ЭтоРусскийВариантТекстаЗапроса(ТекстЗапроса); мРегВыражение.Pattern = "^(?:\s|(" + шКомментарий + "))*((?:ВЫБРАТЬ|SELECT)\s+((?:РАЗРЕШЕННЫЕ|ALLOWED)\s+)?)((?:(?:.|\r|\n)*\s((?:УПОРЯДОЧИТЬ|ORDER)\s+(?:ПО|BY)\s+" + шИмя + "(?:\s*,\s*" + шИмя + ")*(?:\s+(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER))?|(?:АВТОУПОРЯДОЧИВАНИЕ|AUTOORDER)))*)((?:.|\r|\n)*)$"; РезультатПоиска = мРегВыражение.НайтиВхождения(Текст)[0]; Если ЭтоРусскийЯзык Тогда Результат = "ВЫБРАТЬ"; Иначе Результат = "SELECT"; КонецЕсли; Если РезультатПоиска.SubMatches(2) <> Неопределено Тогда Если ЭтоРусскийЯзык Тогда Результат = Результат + " РАЗРЕШЕННЫЕ"; Иначе Результат = Результат + " ALLOWED"; КонецЕсли; КонецЕсли; Смещение = Смещение + Символы.Таб; Если ЭтоРусскийЯзык Тогда Результат = Результат + " " + ТекстВыбранныхПолей + " ИЗ ("; Иначе Результат = Результат + " " + ТекстВыбранныхПолей + " FROM ("; КонецЕсли; НачальныйКомментарий = РезультатПоиска.SubMatches(0); Если ЗначениеЗаполнено(НачальныйКомментарий) Тогда Результат = Результат + Символы.ПС + Смещение + НачальныйКомментарий; Иначе Результат = Результат + Символы.ПС; КонецЕсли; Если ЭтоРусскийЯзык Тогда Результат = Результат + Смещение + "ВЫБРАТЬ "; Иначе Результат = Результат + Смещение + "SELECT "; КонецЕсли; ТекстДоПоследнегоУПОРЯДОЧИТЬ = РезультатПоиска.SubMatches(3); Если ЗначениеЗаполнено(ТекстДоПоследнегоУПОРЯДОЧИТЬ) Тогда ТекстДоПоследнегоУПОРЯДОЧИТЬ = ирОбщий.СтрокаБезКонцаЛкс(ТекстДоПоследнегоУПОРЯДОЧИТЬ, СтрДлина(РезультатПоиска.SubMatches(4))); ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, ТекстДоПоследнегоУПОРЯДОЧИТЬ, Смещение); Иначе ирОбщий.ДобавитьМногострочнуюСтрокуВТекстЛкс(Результат, РезультатПоиска.SubMatches(5), Смещение); КонецЕсли; Если ЭтоРусскийЯзык Тогда Результат = Результат + ") КАК "; Иначе Результат = Результат + ") AS "; КонецЕсли; Результат = Результат + ПсевдонимВложенногоЗапроса; Если Истина //И ТекстДоПоследнегоУПОРЯДОЧИТЬ <> Неопределено И Не ПустаяСтрока(ТекстДоПоследнегоУПОРЯДОЧИТЬ) И Не ОбрезатьНачинаяСУпорядочивания Тогда Результат = Результат + Символы.ПС + РезультатПоиска.SubMatches(4) + РезультатПоиска.SubMatches(5); КонецЕсли; Возврат Результат; КонецФункции // ПолучитьТекстЗапросаДоУпорядочивания() Функция СоздаваемыеВременныеТаблицыПакетаЗапросов(Знач ТекстПакетаИлиМассивТекстовЗапросов, Знач ТолькоТребующиеУничтоженияНаВходе = Ложь, Знач ВместеСУничтожениями = Ложь, Знач ВместеСДополнениями = Ложь, Знач БыстрыйАнализ = Ложь) Экспорт #Если Сервер И Не Сервер Тогда мРегВыражение2 = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли СозданныеТаблицы = Новый СписокЗначений; Если ТипЗнч(ТекстПакетаИлиМассивТекстовЗапросов) = Тип("Массив") Тогда ТекстыЗапросовПакета = ТекстПакетаИлиМассивТекстовЗапросов; Иначе Если Не ирКэш.ДоступноРегВыраженияЛкс() Тогда Если ирКэш.ДоступноСхемаЗапросаЛкс() Тогда Схема = Вычислить("Новый СхемаЗапроса"); #Если Сервер И Не Сервер Тогда Схема = Новый СхемаЗапроса; #КонецЕсли Попытка Схема.УстановитьТекстЗапроса(ТекстПакетаИлиМассивТекстовЗапросов); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки Возврат СозданныеТаблицы; КонецПопытки; Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл ИмяСоздаваемойТаблицы = Неопределено; Если Истина И ТипЗнч(ЗапросПакета) = Тип("ЗапросВыбораСхемыЗапроса") И ЗначениеЗаполнено(ЗапросПакета.ТаблицаДляПомещения) Тогда ИмяСоздаваемойТаблицы = ЗапросПакета.ТаблицаДляПомещения; КонецЕсли; СозданныеТаблицы.Добавить(НРег(ИмяСоздаваемойТаблицы), ИмяСоздаваемойТаблицы); КонецЦикла; КонецЕсли; Возврат СозданныеТаблицы; КонецЕсли; ТекстыЗапросовПакета = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ТекстПакетаИлиМассивТекстовЗапросов); КонецЕсли; мРегВыражение2.Global = Истина; // Ищем в каждом запросе пакета предложение ПОМЕСТИТЬ/УНИЧТОЖИТЬ // Теперь мы работаем с возможно грязным текстом в виде литерала встроенного языка ШаблонПОМЕСТИТЬИЗ = "(?:(?:" + шРазделитель + "|\|)(?:(ПОМЕСТИТЬ|INTO\s+TABLE|INTO|ДОБАВИТЬ|ADD)|(УНИЧТОЖИТЬ|DROP|DROP\s+TABLE))(?:" + шРазделитель + "|\|)" + "+(" + шИмяВременнойТаблицы + ")(" + шРазделитель + "|;|'|"")|\s)|" + шРазделитель; Если Не БыстрыйАнализ Тогда ШаблонПОМЕСТИТЬИЗ = ШаблонПОМЕСТИТЬИЗ + "|" + шЛитералВЗапросе; КонецЕсли; ШаблонПОМЕСТИТЬИЗ = ШаблонПОМЕСТИТЬИЗ + "|.+?"; мРегВыражение2.Pattern = ШаблонПОМЕСТИТЬИЗ; СозданныеТаблицыНрег = Новый Массив; СначалаУничтоженныеТаблицы = Новый Массив; Для Каждого ТекстЗапроса Из ТекстыЗапросовПакета Цикл ИмяСозданнойВременнойТаблицы = Неопределено; СозданиеВременнойТаблицы = мРегВыражение2.Заменить(ТекстЗапроса, "$1"); ИмяВременнойТаблицы = мРегВыражение2.Заменить(ТекстЗапроса, "$3"); Если ирОбщий.СтрокиРавныЛкс(СозданиеВременнойТаблицы, "добавить") Тогда Если ВместеСДополнениями И Не ТолькоТребующиеУничтоженияНаВходе Тогда ИмяСозданнойВременнойТаблицы = "*" + ИмяВременнойТаблицы; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(СозданиеВременнойТаблицы) Тогда Если Ложь Или Не ТолькоТребующиеУничтоженияНаВходе Или СначалаУничтоженныеТаблицы.Найти(НРег(ИмяВременнойТаблицы)) = Неопределено Тогда ИмяСозданнойВременнойТаблицы = ИмяВременнойТаблицы; Если ИмяСозданнойВременнойТаблицы <> Неопределено Тогда СозданныеТаблицыНрег.Добавить(НРег(ИмяСозданнойВременнойТаблицы)); КонецЕсли; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ИмяВременнойТаблицы) Тогда Если ВместеСУничтожениями Тогда ИмяСозданнойВременнойТаблицы = "-" + ИмяВременнойТаблицы; КонецЕсли; ИмяВременнойТаблицы = НРег(ИмяВременнойТаблицы); Если ТолькоТребующиеУничтоженияНаВходе Тогда Если СозданныеТаблицыНрег.Найти(ИмяВременнойТаблицы) = Неопределено Тогда СначалаУничтоженныеТаблицы.Добавить(ИмяВременнойТаблицы); КонецЕсли; КонецЕсли; КонецЕсли; СозданныеТаблицы.Добавить(НРег(ИмяСозданнойВременнойТаблицы), ИмяСозданнойВременнойТаблицы); КонецЦикла; Возврат СозданныеТаблицы; КонецФункции //////////////////////////////////////////////////////////////////////////////// // РАБОТА С ТИПАМИ // Получает чистую внутреннюю таблицу предопределенных слов. // // Параметры: // Нет. // // Возвращаемое значение: // ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов". // Функция НоваяТаблицаСлов() Экспорт ВнутрТаблицаСлов = Новый ТаблицаЗначений; ВнутрТаблицаСлов.Колонки.Добавить("Слово"); // Строка ВнутрТаблицаСлов.Колонки.Добавить("ТипСлова"); // Строка: см. ПеречТипСлова ВнутрТаблицаСлов.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов ВнутрТаблицаСлов.Колонки.Добавить("ТипЗначения"); // Строка ВнутрТаблицаСлов.Колонки.Добавить("ТипЗначенияИндекс"); // Строка ВнутрТаблицаСлов.Колонки.Добавить("Определение"); // Строка: см. ПеречИсточникСлова ВнутрТаблицаСлов.Колонки.Добавить("МожноУточнитьТип"); // Булево - используется только для частично рассчитанных ВнутрТаблицаСлов.Индексы.Добавить("Слово, ТипСлова"); Возврат ВнутрТаблицаСлов; КонецФункции // Функция - Подобрать вариант синтаксиса метода // // Параметры: // ТаблицаВариантов - - содержимое будет утеряно! // // Возвращаемое значение: // строка - название варианта синтаксиса // Функция ПодобратьВариантСинтаксисаМетода(Знач ТаблицаВариантов, Знач КоличествоФактПараметровМетода = 0, Знач ТекущийВариант = "", Знач ТекущийВариантУстановленВручную = Ложь, выхНомер = 0) Экспорт ТаблицаВариантов.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число")); ТаблицаВариантов.ЗаполнитьЗначения(1, "Количество"); ТаблицаВариантов.Свернуть("ВариантСинтаксиса", "Количество"); //ТаблицаВариантов.Сортировать("Количество"); // Если закомментировано, то ОткрытьФорму("") правильно показывает и ближе к поведению конфигуратора НовыйТекущийВариант = ""; Если ТаблицаВариантов.Количество() > 0 Тогда Для Каждого СтрокаВарианта Из ТаблицаВариантов Цикл Если ТекущийВариантУстановленВручную И СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда НовыйТекущийВариант = ТекущийВариант; выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта); Прервать; КонецЕсли; Если СтрокаВарианта.Количество >= КоличествоФактПараметровМетода Тогда НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса; выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта); Если Не ТекущийВариантУстановленВручную Тогда Если СтрокаВарианта.ВариантСинтаксиса = ТекущийВариант Тогда Прервать; Иначе Продолжить; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Если СтрокаВарианта.Количество < КоличествоФактПараметровМетода Тогда НовыйТекущийВариант = СтрокаВарианта.ВариантСинтаксиса; выхНомер = ТаблицаВариантов.Индекс(СтрокаВарианта); КонецЕсли; КонецЕсли; выхНомер = выхНомер + 1; Возврат НовыйТекущийВариант; КонецФункции Функция СинтаксПомощник() Экспорт Если СинтаксПомощник = Неопределено Тогда СинтаксПомощник = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирСинтаксПомощник"); КонецЕсли; Возврат СинтаксПомощник; КонецФункции Функция ДоступныеЗначенияТипа(Знач ИмяТипаИлиТипЗначения) Экспорт ИнициацияОписанияМетодовИСвойств(); Если ТипЗнч(ИмяТипаИлиТипЗначения) = Тип("Тип") Тогда ИмяТипаИлиТипЗначения = СтруктураТипаИзКонкретногоТипа(ИмяТипаИлиТипЗначения).ИмяОбщегоТипа; КонецЕсли; //Пустышка = Вычислить("Метаданные.СвойстваОбъектов." + ИмяТипаЗначения); СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", "ПеречислениеМетаданных" + ИмяТипаИлиТипЗначения, "Свойство")); Если СтрокиЗначений.Количество() = 0 Тогда ИмяТипаПеречисления = ИмяТипаИлиТипЗначения; Если Не ирОбщий.СтрНачинаетсяСЛкс(ИмяТипаИлиТипЗначения, "Перечисление") Тогда ИмяТипаПеречисления = "Перечисление" + ИмяТипаПеречисления; КонецЕсли; СтрокиЗначений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста, ТипСлова", ИмяТипаПеречисления, "Свойство")); КонецЕсли; СтрокиЗначений = ТаблицаКонтекстов.Скопировать(СтрокиЗначений); СписокЗначений = Новый СписокЗначений; СписокЗначений.ЗагрузитьЗначения(СтрокиЗначений.ВыгрузитьКолонку("Слово")); Возврат СписокЗначений; КонецФункции // Формирует построитель запроса по структуре типа. // // Параметры: // СтруктураТипа - Структура - описатель типа. // // Возвращаемое значение: // ПостроительЗапроса. // Функция ПостроительЗапросаПоСтруктуреТипа(Знач СтрокаОбщегоТипа, ВиртуальнаяТаблица = Неопределено) МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда ПолноеИмя = МетаданныеРодителя.ПолноеИмя(); Иначе ПолноеИмя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя); КонецЕсли; МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя); КорневойТипРодителя = МассивФрагментов[0]; Если ОписаниеТипаМетаОбъектов(КорневойТипРодителя, , 0) <> Неопределено Тогда Если Ложь Или (Истина И МассивФрагментов.Количество() = 2 И МассивФрагментов[0] <> "ВнешнийИсточникДанных") Или (Истина И МассивФрагментов.Количество() = 4 И (Ложь Или МассивФрагментов[2] = "ТабличнаяЧасть" Или МассивФрагментов[2] = "Перерасчет")) Тогда ПостроительЗапроса = Новый Структура("ДоступныеПоля", Новый Массив); Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда ИмяТаблицы = "Константы." + МассивФрагментов[1]; Иначе ИмяТаблицы = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмя, Ложь, ВиртуальнаяТаблица = Неопределено); КонецЕсли; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Если Ложь Или ВиртуальнаяТаблица = Неопределено Или Найти(ВиртуальнаяТаблица.Выражение, "(") = 0 Тогда ТаблицаРезультата = ирКэш.ПоляТаблицыБДЛкс(ИмяТаблицы + ВиртуальнаяТаблица.Выражение); ТаблицаРезультата = ТаблицаРезультата.Скопировать(, "Имя, ТипЗначения"); // Делаем копию, т.к. будем ее модифицировать //Для Каждого СтрокаПоля Из ТаблицаРезультата Цикл // Если Ложь // Или Не ЗначениеЗаполнено(СтрокаПоля.Метаданные) // Или (Истина // И СтрокаПоля.ТипЗначения <> "Строка" // И СтрокаПоля.ТипЗначения <> "ХранилищеЗначения") // Тогда // Продолжить; // КонецЕсли; // МетаРеквизит = Метаданные.НайтиПоПолномуИмени(СтрокаПоля.Метаданные); // ОбъектМетаданныхРеквизит // Если МетаРеквизит.Тип.КвалификаторыСтроки.Длина > 0 Тогда // Продолжить; // КонецЕсли; // ИмяВложенногоТипа = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПервыйФрагментЛкс(МетаРеквизит.Комментарий, " ")); // Попытка // ТипВложенный = Тип(ИмяВложенногоТипа); // Исключение // Продолжить; // КонецПопытки; // СтрокаПоля.ТипЗначения = ТаблицаТиповИзОписанияТипов(МетаРеквизит.Тип); // СтрокаПоля.ТипЗначения[0].Метаданные = ДобавитьВТаблицуТипов(, СтруктураТипаИзКонкретногоТипа(ТипВложенный)); //КонецЦикла; //ТаблицаРезультата.Колонки.Удалить("Метаданные"); ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата); Иначе Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Константы.<Имя константы>" Тогда ОпределениеТаблицы = "ВЫБРАТЬ " + ИмяТаблицы; Иначе УникальноеИмяТаблицы = "______________________"; ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ; Если ВиртуальнаяТаблица <> Неопределено Тогда ОпределениеТаблицы = ОпределениеТаблицы + ВиртуальнаяТаблица.Выражение; КонецЕсли; ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы; КонецЕсли; Попытка //ПостроительЗапроса.Текст = ОпределениеТаблицы; ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы,,, Ложь); Исключение Успех = Ложь; Если ВиртуальнаяТаблица <> Неопределено Тогда ПозицияСкобки = Найти(ВиртуальнаяТаблица.Выражение, "("); Если ПозицияСкобки > 0 Тогда ОпределениеТаблицы = "ВЫБРАТЬ * ИЗ " + ИмяТаблицы ; ОпределениеТаблицы = ОпределениеТаблицы + Лев(ВиртуальнаяТаблица.Выражение, ПозицияСкобки - 1); ОпределениеТаблицы = ОпределениеТаблицы + " КАК " + УникальноеИмяТаблицы; Попытка //ПостроительЗапроса.Текст = ОпределениеТаблицы; ТаблицаРезультата = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(ОпределениеТаблицы); Успех = Истина; Исключение КонецПопытки; КонецЕсли; КонецЕсли; Если Не Успех Тогда ВызватьИсключение "ОшибкаВычисленияВиртуальнойТаблицы"; КонецЕсли; КонецПопытки; ТаблицаРезультата = ирОбщий.ТаблицаЗначенийВТаблицуПолейБДЛкс(ТаблицаРезультата); ПостроительЗапроса = Новый Структура("ДоступныеПоля", ТаблицаРезультата); КонецЕсли; ТаблицаРезультата.Колонки.Добавить("НИмя"); ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаРезультата); ирОбщий.ДополнитьТаблицуПолейТаблицыБДВиртуальнымиПолямиЛкс(ПостроительЗапроса.ДоступныеПоля, ирОбщий.ОписаниеТаблицыБДЛкс(ИмяТаблицы)); Иначе // Внешние метаданные ПостроительЗапроса = Новый ПостроительЗапроса; ЗапросРеквизитов = Новый Запрос("ВЫБРАТЬ Имя, ТипыСтрокой ИЗ Справочник.СвойстваМетаданных ГДЕ Владелец = &СсылкаМД"); ЗапросРеквизитов.УстановитьПараметр("СсылкаМД", МетаданныеРодителя); ТаблицаРеквизитов = ЗапросРеквизитов.Выполнить().Выгрузить(); Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл ДоступноеПоле = ПостроительЗапроса.ДоступныеПоля.Добавить(СтрокаРеквизита.Имя, СтрокаРеквизита.Имя); Для Каждого СтрокаТипа Из СтрокаРеквизита.Типы Цикл МассивТипов = Новый Массив; ОбъектМД = КэшОбъект(СтрокаТипа.Объект); МассивТипов.Добавить(Тип(ОбъектМД.Наименование)); КонецЦикла; ДоступноеПоле.ТипЗначения = Новый ОписаниеТипов(МассивТипов); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ПостроительЗапроса; КонецФункции // Получает массив общих типов, дополняя исходный тип расширениями. // // Параметры: // СтруктураТипа - Структура. // // Возвращаемое значение: // Функция РазвернутаяТаблицаТиповИзСтруктурыТипа(Знач СтруктураТипа, Знач ЭтоЛокальныйКонтекст, Знач ДляФиксированныхСлов = Истина, Знач ДоступноКэширование = Ложь) Экспорт МассивОбщихТипов = НоваяТаблицаДополнительныхТипов(); Если СтруктураТипа.ТипЯзыка <> "" Тогда ЗаполнитьЗначенияСвойств(МассивОбщихТипов.Добавить(), СтруктураТипа); Возврат МассивОбщихТипов; КонецЕсли; Если Ложь Или (Истина И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("COMОбъект") И (Ложь Или СтруктураТипа.ИмяОбщегоТипа = "Локальный" // Для подстраховки Или ЭтоЛокальныйКонтекст И СтруктураТипа.ИмяОбщегоТипа <> "Глобальный")) Или СтруктураТипа.ИмяОбщегоТипа = "AutomationСервер" Или СтруктураТипа.ИмяОбщегоТипа = "ВнешнееСоединение" Тогда // Должен идти первым в списке чтобы кэширование глобального контекста работало! НоваяСтрока = МассивОбщихТипов.Добавить(); //ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа,, "ИмяОбщегоТипа, Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "Глобальный"; КонецЕсли; НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа); Если СтруктураТипа.ИмяОбщегоТипа = "УправляемаяФорма" Тогда СтруктураТипа.ИмяОбщегоТипа = "ФормаКлиентскогоПриложения"; КонецЕсли; Если Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "ТабличнаяЧасть"; ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧастьСтрока.") > 0 Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "СтрокаТабличнойЧасти"; ИначеЕсли Ложь Или СтруктураТипа.ИмяОбщегоТипа = "ПолеТекстовогоДокумента" //Или СтруктураТипа.ИмяОбщегоТипа = "РасширениеПоляФормыДляПоляТекстовогоДокумента" // В управляемой форме нет полного отражения ТекстовыйДокумент Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "ТекстовыйДокумент"; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеГрафическойСхемы" Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "ГрафическаяСхема"; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПолеТабличногоДокумента" Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "ТабличныйДокумент"; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ЭлементТелоHTML" Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "ЭлементHTML"; ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, МаркерКоллекцииМетаданных) > 0 Тогда Если ДляФиксированныхСлов Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "КоллекцияОбъектовМетаданных"; КонецЕсли; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ОбъектМетаданных" Тогда Если ДоступноКэширование Тогда Для Каждого СтрокаТипа Из ТаблицаТиповМетаОбъектов Цикл НоваяСтрока = МассивОбщихТипов.Добавить(); //ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "ОбъектМетаданных" + СтрокаТипа.Единственное; КонецЦикла; КонецЕсли; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ЛюбаяСсылка" Тогда Отбор = Новый Структура; Отбор.Вставить("Слово", "ПолучитьСсылку"); Для Каждого СтрокаСлова Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл НоваяСтрока = МассивОбщихТипов.Добавить(); НоваяСтрока.ИмяОбщегоТипа = СтрокаСлова.ТипЗначения; КонецЦикла; ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "СсылочныйОбъект" Тогда Отбор = Новый Структура; Отбор.Вставить("Слово", "ПолучитьОбъект"); Для Каждого СтрокаСлова Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл Если Найти(СтрокаСлова.ТипКонтекста, "Ссылка.") = 0 Тогда Продолжить; КонецЕсли; НоваяСтрока = МассивОбщихТипов.Добавить(); НоваяСтрока.ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(СтрокаСлова.ТипЗначения, ","); КонецЦикла; //ИначеЕсли Найти(СтруктураТипа.ИмяОбщегоТипа, "РасширениеФормы") > 0 Тогда // НоваяСтрока = МассивОбщихТипов.Добавить(); // ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); // НоваяСтрока.ИмяОбщегоТипа = "Форма"; //Иначе // ОбщийТипМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(СтруктураТипа.ИмяОбщегоТипа, , ": ", Ложь); // //Если ОбщийТипМетаданных <> "" Тогда // Если ЗначениеЗаполнено(ОбщийТипМетаданных) Тогда // НоваяСтрока = МассивОбщихТипов.Добавить(); // ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); // НоваяСтрока.ИмяОбщегоТипа = ОбщийТипМетаданных; // КонецЕсли; КонецЕсли; // TODO добавить расширения управляемой формы Мультиметка638663811 // Расширения, образованные элементом управления и типом связанных с ним данных СтрокаРасширения = ТаблицаРасширенийТипов.Найти(СтруктураТипа.ИмяОбщегоТипа, "Расширение"); Если Истина И СтрокаРасширения <> Неопределено И ЗначениеЗаполнено(СтрокаРасширения.ОсновнойТип) Тогда Если Истина И СтрокаРасширения.ОсновнойТип = "Форма" //И СтруктураТипа.ДополнительныеТипы = Неопределено Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип; #Если Клиент Тогда Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("Форма") Тогда СтруктураТипаОбъекта = СтруктураТипаОбъектаОбычнойФормы(СтруктураТипа.Метаданные); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипаОбъекта); КонецЕсли; #КонецЕсли КонецЕсли; Если СтрокаРасширения.ОсновнойТип = "ТаблицаФормы" Тогда НоваяСтрока = МассивОбщихТипов.Вставить(0); // Важно вставлять в начало для кэшируемых типов Иначе НоваяСтрока = МассивОбщихТипов.Добавить(); КонецЕсли; Если Истина И ирОбщий.СтрНачинаетсяСЛкс(СтруктураТипа.ИмяОбщегоТипа, "РасширениеФормы") И Не ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда // Нужно для вычисления параметров ненатуральной формы НоваяСтрока.Метаданные = СтруктураТипа.ИмяОбщегоТипа; Иначе ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); КонецЕсли; НоваяСтрока.ИмяОбщегоТипа = СтрокаРасширения.ОсновнойТип; КонецЕсли; // Общие расширения элементов управления Для Счетчик = 1 По Мин(2, МассивОбщихТипов.Количество()) Цикл // Для поля табличного документа будет 2 типа https://www.hostedredmine.com/issues/956247 ИмяПоследнегоОбщегоТипа = МассивОбщихТипов[МассивОбщихТипов.Количество() - Счетчик].ИмяОбщегоТипа; Если СтруктураТипа.Метаданные = Неопределено И ДоступноКэширование Тогда // Расширяемому типу без метаданных добавляем сразу все расширения Для Каждого СтрокаТипа Из ТаблицаРасширенийТипов.НайтиСтроки(Новый Структура("ОсновнойТип", СтруктураТипа.ИмяОбщегоТипа)) Цикл НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = СтрокаТипа.Расширение; КонецЦикла; КонецЕсли; Если МассивОбычныхЭлементовУправления.Найти(ИмяПоследнегоОбщегоТипа) <> Неопределено Тогда НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхВФорме"; НоваяСтрока = МассивОбщихТипов.Добавить(); ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхНаПанели"; //ИначеЕсли МассивУправляемыхЭлементовУправления.Найти(ИмяПоследнегоОбщегоТипа) <> Неопределено Тогда // // http://www.hostedredmine.com/issues/882998 // НоваяСтрока = МассивОбщихТипов.Добавить(); // ЗаполнитьЗначенияСвойств(НоваяСтрока, СтруктураТипа, "Метаданные"); // НоваяСтрока.ИмяОбщегоТипа = "РасширениеЭлементовУправленияРасположенныхВФорме"; КонецЕсли; КонецЦикла; //Если СтруктураТипа.ДополнительныеТипы <> Неопределено Тогда // ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(СтруктураТипа.ДополнительныеТипы, МассивОбщихТипов); //КонецЕсли; Возврат МассивОбщихТипов; КонецФункции Процедура ОчиститьКэшАнализатораЯзыка() Экспорт мПустойМодуль = Неопределено; мПоляТекстаПрограммы = Неопределено; мВызовыВсехМетодовПоМодулям = Неопределено; мМодулиМетаданных.Очистить(); мКэшСловГлобальногоКонтекста.Очистить(); мПассивныеФормы.Очистить(); мПрямыеВызовыМетодов.Очистить(); КонецПроцедуры Процедура ПроверитьОбновитьКэш() Экспорт НоваяДатаОбновленияКэшаМодулей = ирОбщий.ДатаОбновленияКэшаМодулейЛкс(); Если мДатаОбновленияКэшаМодулей <> НоваяДатаОбновленияКэшаМодулей Тогда ОчиститьКэшАнализатораЯзыка(); мДатаОбновленияКэшаМодулей = НоваяДатаОбновленияКэшаМодулей; КонецЕсли; КонецПроцедуры // Получает внутреннюю таблицу предопределенных слов заданного родительского типа. // Параметры: // РодительскаяСтруктураТипа - см. НоваяСтруктураТипа() - // ПараметрыЗаполнения - см. НовыеПараметрыЗаполненияСлов - // КлючКэширования - выходной, Неопределено - не использовать кэш, Истина - полная таблица взята из кэша - // выходной, Неопределено - не использовать кэш, Истина - полная таблица взята из кэша // Возвращаемое значение: // см. НоваяТаблицаСлов - Функция СловаКонтекстаПредопределенные(Знач РодительскаяСтруктураТипа, Знач ПараметрыЗаполнения, КлючКэширования = Неопределено) Экспорт ТаблицаСлов = ПараметрыЗаполнения.ТаблицаСлов; Если Истина И Не РодительскаяСтруктураТипа.Конструктор И Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа) И РодительскаяСтруктураТипа.ТипЯзыка = "" Тогда // родительский контекст является Процедурой Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСлов(); КонецЕсли; Возврат ТаблицаСлов; КонецЕсли; БазовоеРасширениеКонфигурации = ПараметрыЗаполнения.БазовоеРасширениеКонфигурации; ВычислятьТипы = ПараметрыЗаполнения.ВычислятьТипы; ДляЗаписи = ПараметрыЗаполнения.ДляЗаписи; ЗапретГлобальногоКонтекста = ПараметрыЗаполнения.ЗапретГлобальногоКонтекста; НаборыСлов = ПараметрыЗаполнения.НаборыСлов; СловоФильтр = ПараметрыЗаполнения.СловоФильтр; ТипСловаФильтр = ПараметрыЗаполнения.ТипСловаФильтр; ТолькоСоЗначениями = ПараметрыЗаполнения.ТолькоСоЗначениями; ФлагиКомпиляции = ПараметрыЗаполнения.ФлагиКомпиляции; ЭтоЛокальныйКонтекст = ПараметрыЗаполнения.ЭтоЛокальныйКонтекст; ЯзыкПрограммы = ПараметрыЗаполнения.ЯзыкПрограммы; Если РодительскаяСтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе" Тогда ЯзыкПрограммы = 1; КонецЕсли; КлючПоискаКонструктора = Новый Структура; Если РодительскаяСтруктураТипа.Конструктор Тогда КлючПоискаКонструктора = Новый Структура("ЕстьКонструктор, ЯзыкПрограммы, НСлово", Истина, ЯзыкПрограммы); КонецЕсли; ИмяОбщегоТипаРодителяБезДеталей = РодительскаяСтруктураТипа.ИмяОбщегоТипа; Если Найти(ИмяОбщегоТипаРодителяБезДеталей, " {") > 0 Тогда НИмяОбщегоТипаРодителя = НРег(ИмяОбщегоТипаРодителяБезДеталей); Если Найти(НИмяОбщегоТипаРодителя, " {v") > 0 Тогда ЧистоеИмяТипа = ирОбщий.ПервыйФрагментЛкс(НИмяОбщегоТипаРодителя, " "); Если Найти(ЧистоеИмяТипа, НРег("IV8COMConnector")) = 1 Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "МенеджерCOMСоединений"; ИначеЕсли Найти(ЧистоеИмяТипа, НРег("IServerAgentConnection")) = 1 Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с агентом сервера"; ИначеЕсли Найти(ЧистоеИмяТипа, НРег("IWorkingProcessConnection")) Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соединение с рабочим процессом"; ИначеЕсли Найти(ЧистоеИмяТипа, НРег("Application")) Тогда РодительскаяСтруктураТипа.ИмяОбщегоТипа = "AutomationСервер"; КонецЕсли; КонецЕсли; КонецЕсли; ЛиПолныйКонтрольУникальности = Неопределено; МассивОбщихТипов = РазвернутаяТаблицаТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст, Истина, Не ЗначениеЗаполнено(ТаблицаСлов)); ПроверятьДоступностьВКонтекстеКомпиляции = ПроверятьДоступностьВКонтекстеКомпиляции(ФлагиКомпиляции, РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст); Для Каждого СтрокаОбщегоТипа Из МассивОбщихТипов Цикл ИмяОбщегоТипаРодителяБезДеталей = ирОбщий.ПервыйФрагментЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "["); ИспользоватьКэширование = Ложь; Если ЗапретГлобальногоКонтекста И ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Тогда Продолжить; КонецЕсли; Если Ложь Или ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Или ИмяОбщегоТипаРодителяБезДеталей = "БиблиотекаКартинок" //Или ИмяОбщегоТипаРодителяБезДеталей = "ОбъектМетаданных" И РодительскаяСтруктураТипа.ТипЯзыка = "" // 60 видов Или (Истина И РодительскаяСтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРодителяБезДеталей // Это первая компонента типа И РодительскаяСтруктураТипа.ТипЯзыка = "" // Нужно для ОбъектМетаданных И МассивОбщихТипов.Количество() > 10 //И (Ложь // Или ИмяОбщегоТипаРодителяБезДеталей = "Форма" // 37 расширений // Или ИмяОбщегоТипаРодителяБезДеталей = "ТабличноеПоле" // 78 расширений // Или ИмяОбщегоТипаРодителяБезДеталей = "ПолеВвода" // 28 расширений // Или ИмяОбщегоТипаРодителяБезДеталей = "КолонкаТабличногоПоля" // 22 расширений // Или ИмяОбщегоТипаРодителяБезДеталей = "ФормаКлиентскогоПриложения" // 15 расширений // Или ИмяОбщегоТипаРодителяБезДеталей = "ТаблицаФормы" // 40 расширений // Или ИмяОбщегоТипаРодителяБезДеталей = "ПолеФормы" // 40 расширений // ) ) Или Найти(ИмяОбщегоТипаРодителяБезДеталей, " {") > 0 // COM Или ИмяОбщегоТипаРодителяБезДеталей = "" // ИмяТипа Тогда КлючКэширования = КлючКэшированияСловИзОбщегоТипа(ИмяОбщегоТипаРодителяБезДеталей); ИспользоватьКэширование = Истина И СловоФильтр = Неопределено И Не ДляЗаписи И Не ЗапретГлобальногоКонтекста; Если ИспользоватьКэширование И ЗначениеЗаполнено(ТаблицаСлов) Тогда Если Найти(ИмяОбщегоТипаРодителяБезДеталей, " {") > 0 Тогда // COM ИспользоватьКэширование = Ложь; Иначе // Мультметка8530527831 ВызватьИсключение "Для кэшируемого контекста нельзя передавать таблицу-приемник"; // Обычно помогает ОбработкаОбъект.ирКлсПолеТекстаПрограммы.ПодготовитьТаблицуТиповКЗаполнениюТаблицыСлов КонецЕсли; КонецЕсли; КонецЕсли; Если ИспользоватьКэширование Тогда Если Ложь Или ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Или ИмяОбщегоТипаРодителяБезДеталей = "" Тогда // Мультиметка3398476724 ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс(); НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина); КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП); КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП); ЛиПолноеКэширование = Ложь; КлючКэширования = ИмяОбщегоТипаРодителяБезДеталей + ";" + ЯзыкПрограммы + ";" + ПараметрыЗаполнения.Конфигурация + ";" + ВычислятьТипы + ";" + ТипСловаФильтр + ";" + НаСервере + ";" + КлиентОбычноеПриложение + ";" + КлиентУправляемоеПриложение + ";" + РодительскаяСтруктураТипа.ТипЯзыка + ";" + БазовоеРасширениеКонфигурации + ";" + РодительскаяСтруктураТипа.Конструктор + ";" + ДляЗаписи + ";" + ПараметрыЗаполнения.ТолькоСоЗначениями; Иначе ЛиПолноеКэширование = Истина; КонецЕсли; ТаблицаСловИзКэша = мКэшСловГлобальногоКонтекста[КлючКэширования]; Если ТаблицаСловИзКэша <> Неопределено Тогда #Если Сервер И Не Сервер Тогда ТаблицаСловИзКэша = Новый ТаблицаЗначений; #КонецЕсли Если НаборыСлов <> Неопределено Тогда НаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша); ТаблицаСлов = НоваяТаблицаСлов(); Иначе ТаблицаСлов = ТаблицаСловИзКэша.Скопировать(); КонецЕсли; Если ЛиПолноеКэширование Тогда КлючКэширования = Истина; Прервать; Иначе КлючКэширования = Неопределено; Продолжить; КонецЕсли; КонецЕсли; КонецЕсли; Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСлов(); КонецЕсли; Если Истина И ИмяОбщегоТипаРодителяБезДеталей <> "Глобальный" И ФлагиКомпиляции <> Неопределено И ФлагиКомпиляции.БезКонтекста И ЭтоЛокальныйКонтекст Тогда Продолжить; КонецЕсли; Если ЛиПолныйКонтрольУникальности = Неопределено Тогда ЛиПолныйКонтрольУникальности = ИспользоватьКэширование Или ТаблицаСлов.Количество() > 0; КонецЕсли; МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные; Если Истина И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Форма") <> Неопределено Тогда МетаданныеРодителя = МетаданныеРодителя.Форма; КонецЕсли; ЛиРодительЕстьУпрФормаИлиИмитатор = ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь); КорневойТипРодителя = Неопределено; ПостроительЗапросаРодителя = Неопределено; ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя); Если Истина И ТипМетаданныхРодителя = Тип("ОбъектМетаданных") И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя); Иначе КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя); КонецЕсли; ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица); КонецЕсли; Если ИмяОбщегоТипаРодителяБезДеталей = "Локальный" Тогда НайденныеСтроки = Новый Массив; ИначеЕсли ТипСловаФильтр = "Конструктор" Тогда НайденныеСтроки = Новый Массив; Если ИмяОбщегоТипаРодителяБезДеталей = "Глобальный" Тогда СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова", СловоФильтр, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка, ТипСловаФильтр); НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча); КонецЕсли; Иначе // Состав полей совпадает с индексом СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипаРодителяБезДеталей, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка); Если СловоФильтр <> Неопределено Тогда СтруктураКлюча.Вставить("НСлово", НРег(СловоФильтр)); Если Истина И ЯзыкПрограммы = 0 // В языке запросов может быть неоднозначность между типами слов Таблица и Поле. Поэтому для них жертвуем попаданием в индекс И ТипСловаФильтр = Неопределено Тогда //ирОбщий.СообщитьЛкс("Использован медленный поиск по таблице контекстов"); ТипСловаФильтр = "Свойство"; // Так будем всегда попадать в индекс КонецЕсли; КонецЕсли; Если ТипСловаФильтр <> Неопределено Тогда СтруктураКлюча.Вставить("ТипСлова", ТипСловаФильтр); КонецЕсли; Если ЯзыкПрограммы <> 0 Тогда ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаКонтекстов, СтруктураКлюча); // спасает в случае языка запросов, где ТипСловаФильтр не используется КонецЕсли; НайденныеСтроки = ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча); КонецЕсли; ПредыдущаяСтрокаСлова = Неопределено; // Для регистра бухгалтерии ВычислятьТипыЦикл = ВычислятьТипы Или НайденныеСтроки.Количество() < 100; Для Каждого СтрокаСлова Из НайденныеСтроки Цикл СловоЦикл = СтрокаСлова.Слово; ТипСловаЦикл = СтрокаСлова.ТипСлова; Если Ложь Или (Истина И ТолькоСоЗначениями И ПустаяСтрока(СтрокаСлова.ТипЗначения) И СтрокаСлова.ТипСлова <> "Свойство") Или ДляЗаписи И Не СтрокаСлова.Запись Или (Истина И ПредыдущаяСтрокаСлова <> Неопределено И ПредыдущаяСтрокаСлова.НСлово = СтрокаСлова.НСлово И ПредыдущаяСтрокаСлова.ТипСлова = ТипСловаЦикл) Или СтрокаСлова.НомерВерсииПлатформы > мНомерВерсииПлатформы Или (Истина И ТипСловаЦикл = ПеречТипСлова.Метод И СтрокаОбщегоТипа.НеВключатьМетоды) Или (Истина И ТипСловаФильтр = Неопределено И (Ложь Или ТипСловаЦикл = "Событие" Или ТипСловаЦикл = "Параметр" Или ТипСловаЦикл = "Конструктор")) Или (Истина И ПроверятьДоступностьВКонтекстеКомпиляции И (Ложь Или ФлагиКомпиляции.Сервер И СтрокаСлова.НеСервер Или ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТолстыйКлиент Или ФлагиКомпиляции.КлиентУправляемоеПриложение И Не ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТонкийКлиент)) Тогда Продолжить; КонецЕсли; ПредыдущаяСтрокаСлова = СтрокаСлова; Если РодительскаяСтруктураТипа.Конструктор Тогда КлючПоискаКонструктора.НСлово = НРег(СловоЦикл); Если ТаблицаОбщихТипов.НайтиСтроки(КлючПоискаКонструктора).Количество() = 0 Тогда Продолжить; КонецЕсли; КонецЕсли; МожноУточнитьТип = СловоЦикл = "ВладелецФормы"; ЛиТипСКвалификаторами = Истина И ТипСловаЦикл = "Свойство" И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаСлова.ТипЗначения) И Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ОбъектМетаданных"); ТаблицаТипов = Неопределено; Если ВычислятьТипыЦикл Тогда ТаблицаТипов = НоваяТаблицаТипов(); ЛиДобавляемСлово = Истина; Если Найти(СтрокаСлова.ТипЗначения, "[") > 0 Тогда МассивТиповЗначения = ирОбщий.ЗначенияВМассивЛкс(СтрокаСлова.ТипЗначения); Иначе МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.ТипЗначения, ", "); КонецЕсли; СтруктураТипаШаблон = НоваяСтруктураТипа(); СтруктураТипаШаблон.СтрокаОписания = СтрокаСлова; ЗаполнитьЗначенияСвойств(СтруктураТипаШаблон, РодительскаяСтруктураТипа, , "ИмяОбщегоТипа, СтрокаОписания, Метаданные, МетаданныеСвойства, ВиртуальнаяТаблица"); Если Истина И ЛиИмяТипаЭлементаУправляемойФормы(ИмяОбщегоТипаРодителяБезДеталей) И ТипЗнч(МетаданныеРодителя) <> Тип(ИмяОбщегоТипаРодителяБезДеталей) И ТипЗнч(МетаданныеРодителя) <> Тип("Структура") Тогда СтруктураТипаШаблон.Метаданные = НовыйИмитаторЭлементаФормы(); СтруктураТипаШаблон.Метаданные.Тип = Тип(ИмяОбщегоТипаРодителяБезДеталей); Если ИмяОбщегоТипаРодителяБезДеталей <> РодительскаяСтруктураТипа.ИмяОбщегоТипа Тогда СтруктураТипаШаблон.Метаданные.Вставить("ИмяТипаРасширения", РодительскаяСтруктураТипа.ИмяОбщегоТипа); КонецЕсли; ИначеЕсли Истина И ТипСловаФильтр = ПеречТипСлова.Метод И ИмяОбщегоТипаРодителяБезДеталей = "РасширениеЭлементовУправленияРасположенныхВФорме" Тогда СоздатьИмитатор = Ложь; Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя) Тогда СтруктураТипаШаблон.ДержательМетаданных = МетаданныеРодителя; СоздатьИмитатор = Истина; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда СоздатьИмитатор = Истина; КонецЕсли; Если СоздатьИмитатор Тогда СтруктураТипаШаблон.Метаданные = НовыйИмитаторЭлементаФормы(); СтруктураТипаШаблон.Метаданные.Тип = РодительскаяСтруктураТипа.ИмяОбщегоТипа; Иначе СтруктураТипаШаблон.Метаданные = МетаданныеРодителя; КонецЕсли; ИначеЕсли Истина //И ТипЗнч(МетаданныеРодителя) <> Тип("COMОбъект") //И ТипСловаЦикл = "Свойство" И СловоЦикл <> "ВладелецФормы" И ИмяОбщегоТипаРодителяБезДеталей <> "КлючИЗначение" // Для проверки выражений И ИмяОбщегоТипаРодителяБезДеталей <> "ЭлементСпискаЗначений" // Для проверки выражений //И Не ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаРодителяБезДеталей, "КоллекцияКолонок") // Закомментировал, т.к. ломает расчет возможных значений ТаблицаЗначений.Колоонки.Удалить("") И Не (Истина // Исключаем общее описание значений элементов структуры (МетаданныеРодителя = ТаблицаЗначений) И ИмяОбщегоТипаРодителяБезДеталей = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений")) И Не (Истина // Для ЭлементУправления.УстановитьДействие("") И ИмяОбщегоТипаРодителяБезДеталей = "КолонкаТабличногоПоля" И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")) Тогда СтруктураТипаШаблон.Метаданные = СтрокаОбщегоТипа.Метаданные; КонецЕсли; Для Каждого ИмяОбщегоТипаСлова Из МассивТиповЗначения Цикл Если МассивТиповЗначения.Количество() = 1 Тогда СтруктураТипа = СтруктураТипаШаблон; Иначе СтруктураТипа = НоваяСтруктураТипа(); ЗаполнитьЗначенияСвойств(СтруктураТипа, СтруктураТипаШаблон,, "ВиртуальнаяТаблица"); Если Истина И Не ЛиТипСКвалификаторами И ТипСловаЦикл = "Свойство" Тогда ЛиТипСКвалификаторами = ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(ИмяОбщегоТипаСлова); КонецЕсли; КонецЕсли; Если ИмяОбщегоТипаСлова = "ОбъектМетаданныхКонфигурация" Тогда //СтруктураТипа.Метаданные = Конфигурация; Если ПараметрыЗаполнения.Конфигурация <> Неопределено Тогда СтруктураТипа.Метаданные = ПараметрыЗаполнения.Конфигурация; Иначе СтруктураТипа.Метаданные = Неопределено; КонецЕсли; ИначеЕсли ИмяОбщегоТипаСлова = "Отбор" Тогда Если Истина И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных") И (Ложь //Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "объект.") > 0 Или Найти(НРег(СтрокаОбщегоТипа.ИмяОбщегоТипа), "наборзаписей.") > 0) Тогда ИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтрокаОбщегоТипа.Метаданные.ПолноеИмя()); СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ИмяТаблицыБД); СтруктураТипа.Метаданные = СтруктураОбъекта.Методы; ИначеЕсли Ложь Или ирОбщий.СтрНачинаетсяСЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "РасширениеТабличногоПоля") Тогда Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ТабличноеПоле") Тогда СтруктураТипа.Метаданные = Метаданные.НайтиПоТипу(ТипЗнч(СтрокаОбщегоТипа.Метаданные.Значение)); КонецЕсли; Иначе КонкретныйТип = ИмяТипаИзСтруктурыТипа(СтрокаОбщегоТипа); Если Истина И Найти(КонкретныйТип, "<") = 0 И ТипЗнч(СтруктураТипа.Метаданные) <> Тип(КонкретныйТип) Тогда Попытка Образователь = Новый (КонкретныйТип); СтруктураТипа.Метаданные = Образователь; Исключение // Срабатывает для табличных полей КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаСлова; Если ПараметрыЗаполнения.ВиртуальнаяТаблица <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа.ВиртуальнаяТаблица, ПараметрыЗаполнения.ВиртуальнаяТаблица); КонецЕсли; Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда СтруктураТипа.ИмяОбщегоТипа = СловоЦикл; Если СтрокаСлова.ТипКонтекста <> "" Тогда СтруктураТипа.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипа.ИмяОбщегоТипа; КонецЕсли; КонецЕсли; Если Истина И Найти(СтруктураТипа.ИмяОбщегоТипа, "СтрокаТабличнойЧасти") > 0 И Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.") > 0 Тогда ИмяТипаСтрокиТЧ = СтрЗаменить(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "ТабличнаяЧасть.", "ТабличнаяЧастьСтрока."); СтруктураТипа.ИмяОбщегоТипа = СтрЗаменить(СтруктураТипа.ИмяОбщегоТипа, "СтрокаТабличнойЧасти", ИмяТипаСтрокиТЧ); КонецЕсли; #Если Клиент Тогда Если Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") И ИмяОбщегоТипаСлова = "КолонкаТабличногоПоля" Тогда ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипаСлова, МетаданныеРодителя); Если ИмяОбщегоТипаРасширения <> Неопределено Тогда СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения; КонецЕсли; КонецЕсли; #КонецЕсли МаркерРасширений = "Расширение"; Если Истина И Лев(РодительскаяСтруктураТипа.ИмяОбщегоТипа, СтрДлина(МаркерРасширений)) = МаркерРасширений И СловоЦикл = "Значение" Тогда Если МетаданныеРодителя <> Неопределено Тогда ЭлементФормы = МетаданныеРодителя; // ПолеВвода СтруктураТипа = СтруктураТипаИзЗначения(ЭлементФормы.Значение); Иначе СтрокаРасширения = ТаблицаРасширенийТипов.Найти(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Расширение"); //Если СтрокаРасширения <> Неопределено Тогда СтруктураТипа.ИмяОбщегоТипа = СтрокаРасширения.РасширяющийТип; //КонецЕсли; КонецЕсли; МожноУточнитьТип = Истина; ИначеЕсли Истина И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ТабличноеПоле" И СловоЦикл = "Значение" Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") Тогда СтруктураТипа = СтруктураТипаИзЗначения(МетаданныеРодителя.Значение); Иначе ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("ДеревоЗначений")); ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("ТаблицаЗначений")); ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("ТабличнаяЧасть")); КонецЕсли; КонецЕсли; Если Истина И МетаданныеРодителя <> Неопределено И ТипСловаЦикл = "Свойство" Тогда Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") Или (Истина // Нельзя допускать неявного выполнения запроса при обращении к свойству "Результат" построителя И СтруктураТипа.ИмяОбщегоТипа = "РезультатЗапроса" И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")) Или (Истина // Здесь свойство есть у объекта метаданных, но имеет другой смысл И СловоЦикл = "ВидыСубконто" И СтруктураТипа.ИмяОбщегоТипа = "ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда ЗначениеСвойства = МетаданныеРодителя; Иначе Если Истина #Если Клиент Тогда И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") #Иначе И Ложь #КонецЕсли И СловоЦикл = "ТекущийРодитель" Тогда // Антибаг платформы 8.2.16. Вывести в чистом виде не удалось. Падает при вычислении свойства ТекущийРодитель в форме списка РС.ООП_ВаучерыТез ЗначениеСвойства = Неопределено; Иначе ПроверяемыеМетаданные = ?(МетаданныеРодителя = Неопределено, мМетаданные, МетаданныеРодителя); Попытка ЗначениеСвойства = ПроверяемыеМетаданные[СловоЦикл]; Исключение ЗначениеСвойства = Неопределено; КонецПопытки; КонецЕсли; КонецЕсли; Если ЗначениеСвойства <> Неопределено Тогда Если Истина И ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений") И ЗначениеСвойства.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено Тогда // Мультиметка241116_130557 Например КлючИЗначение, ЭлементСпискаЗначений, ПараметрыПеретаскивания и имитаторы описанные в типизирующих комментариях ТаблицаТипов = ЗначениеСвойства; ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); МожноУточнитьТип = Истина; Прервать; ИначеЕсли мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеСвойства)) <> Неопределено Тогда Если СтрокаСлова.ТипЗначения = "ВсеЭлементыФормы" Тогда // Для имитатора формы Иначе СтруктураТипа.Метаданные = ЗначениеСвойства; КонецЕсли; Если ЛиРодительЕстьУпрФормаИлиИмитатор Тогда СтруктураТипа.ДержательМетаданных = МетаданныеРодителя; КонецЕсли; ИначеЕсли ПустаяСтрока(СтрокаСлова.ТипЗначения) Тогда // Например ПолеВвода.Значение СтруктураТипа = СтруктураТипаИзЗначения(ЗначениеСвойства); МожноУточнитьТип = Истина; КонецЕсли; КонецЕсли; КонецЕсли; // Для методов метаданных нужна специфическая обработка для усечения типов Если Истина И СловоЦикл = "Родитель" И ТипСловаЦикл = ПеречТипСлова.Метод И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаСлова, МаркерОбъектаМетаданных) Тогда Родитель = Неопределено; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Родитель = МетаданныеРодителя.Родитель(); КонецЕсли; Если Родитель <> Неопределено Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(Родитель.ПолноеИмя()); СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + МассивФрагментов[МассивФрагментов.ВГраница() - 1]; Иначе СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаОбъектаМетаданных(); КонецЕсли; СтруктураТипа.Метаданные = Родитель; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И ТипСловаЦикл = ПеречТипСлова.Метод И Лев(ИмяОбщегоТипаСлова, СтрДлина(МаркерОбъектаМетаданных)) = МаркерОбъектаМетаданных И (Ложь Или СловоЦикл = "Найти" Или СловоЦикл = "Получить") Тогда СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", РодительскаяСтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча); СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].ТипЭлементаКоллекции; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Продолжить; ИначеЕсли Истина И СтрокаСлова.ТипКонтекста = "ОтчетОбъект.<Имя отчета>" И СловоЦикл = "СхемаКомпоновкиДанных" И ТипСловаЦикл = "Свойство" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда СхемаКомпоновкиДанных = ирКэш.ОсновнаяСхемаКомпоновкиОтчетаЛкс(МетаданныеРодителя.ПолноеИмя()); Если СхемаКомпоновкиДанных <> Неопределено Тогда СтруктураТипа.Метаданные = СхемаКомпоновкиДанных; КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И СтрокаСлова.ТипКонтекста = "ОтчетОбъект.<Имя отчета>" И СловоЦикл = "КомпоновщикНастроек" И ТипСловаЦикл = "Свойство" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда СхемаКомпоновкиДанных = ирКэш.ОсновнаяСхемаКомпоновкиОтчетаЛкс(МетаданныеРодителя.ПолноеИмя()); Если СхемаКомпоновкиДанных <> Неопределено Тогда СтруктураТипа.Метаданные = ирОбщий.КомпоновщикПоСхемеКомпоновкиЛкс(СхемаКомпоновкиДанных); КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ОписаниеТипов") И СтрокаСлова.ТипКонтекста = "ОписаниеТипов" И СловоЦикл = "ПривестиЗначение" Тогда Если МетаданныеРодителя.Типы().Количество() = 1 Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, МетаданныеРодителя); КонецЕсли; Прервать; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТекстовыйДокумент") И ИмяОбщегоТипаРодителяБезДеталей = "ТекстовыйДокумент" И СловоЦикл = "ПолучитьТекст" Тогда СтруктураТипа = НоваяСтруктураТипа("Строка"); СтруктураТипа.Метаданные = МетаданныеРодителя.ПолучитьТекст(); ИначеЕсли Истина И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Массив" И ТипСловаЦикл = ПеречТипСлова.Метод И (Ложь Или СловоЦикл = "Количество" Или СловоЦикл = "ВГраница") И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") И МетаданныеРодителя.Количество() > 0 И ТипЗнч(МетаданныеРодителя[0].Метаданные) = Тип("ПостроительЗапроса") Тогда // Мультиметка6091573442 КоличествоЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(МетаданныеРодителя[0].Метаданные.Текст).Количество(); Если СловоЦикл = "Количество" Тогда СтруктураТипа.Метаданные = КоличествоЗапросов; Иначе СтруктураТипа.Метаданные = КоличествоЗапросов - 1; КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Прервать; ИначеЕсли Истина И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаСлова, "Массив[") И МетаданныеРодителя <> Неопределено Тогда ПолеТекстаПрограммы = ирКэш.ПолеТекстаПрограммы(); ТаблицаТиповИзТекста = ПолеТекстаПрограммы.ТаблицаТиповИзТекста(ИмяОбщегоТипаСлова); //! ТаблицаТиповИзТекста[0].Метаданные = 0 // см. НоваяТаблицаТипов ТаблицаТиповИзТекста[0].Метаданные.ЗаполнитьЗначения(МетаданныеРодителя, "Метаданные"); // TODO проверить подобные места, чтобы там обновлялась детальность ТаблицаТиповИзТекста[0].Метаданные.ЗаполнитьЗначения(РодительскаяСтруктураТипа.ДержательМетаданных, "ДержательМетаданных"); // Для Запрос.ВыполнитьПакет() Для Каждого СтрокаТипаЭлемента Из ТаблицаТиповИзТекста[0].Метаданные Цикл ОбновитьДетальностьСтруктурыТипа(СтрокаТипаЭлемента); КонецЦикла; ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИзТекста[0]); ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); Прервать; ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение" И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И СловоЦикл = "Ключ" // Опасно, но более надежного простого способа отличить "Соответствие" не нашел И Не (Истина И МетаданныеРодителя.Количество() = 2 И МетаданныеРодителя.Свойство("Значение") И МетаданныеРодителя.Свойство("Ключ")) Тогда СтруктураТипа = НоваяСтруктураТипа("Строка"); // Мультиметка241116_130557 перенес выше //ИначеЕсли Истина // И (Ложь // Или ИмяОбщегоТипаРодителяБезДеталей = "ПараметрыПеретаскивания" // Или ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение" // Или ИмяОбщегоТипаРодителяБезДеталей = "ЭлементСпискаЗначений") // И ТипЗнч(МетаданныеРодителя) = Тип("Структура") // И МетаданныеРодителя.Свойство(СловоЦикл) //Тогда // ТаблицаТипов = МетаданныеРодителя[СловоЦикл]; // Если ТаблицаТипов <> Неопределено Тогда // ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); // МожноУточнитьТип = Истина; // Прервать; // КонецЕсли; //ИначеЕсли Истина // И ИмяОбщегоТипаРодителяБезДеталей = "КлючИЗначение" // И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") // И СловоЦикл = "Значение" //Тогда // ТаблицаТипов = МетаданныеРодителя; // ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); // МожноУточнитьТип = Истина; ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "Соответствие" И СловоЦикл = "Получить" И ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда ТаблицаТипов = МетаданныеРодителя.Значение; Если ТаблицаТипов <> Неопределено Тогда ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); МожноУточнитьТип = Истина; Прервать; КонецЕсли; ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "ХранилищеЗначения" И СловоЦикл = "Получить" И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") Тогда ТаблицаТипов = МетаданныеРодителя; Если ТаблицаТипов <> Неопределено Тогда ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); МожноУточнитьТип = Истина; Прервать; КонецЕсли; ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "ФабрикаXDTO" И СловоЦикл = "ЭкспортМоделиXDTO" И ТипСловаЦикл = ПеречТипСлова.Метод Тогда ДанныеИзТекста = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://v8.1c.ru/8.1/xdto", "Model")); СтруктураТипа = СтруктураТипаИзЗначения(ДанныеИзТекста); ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "Запрос" И ИмяОбщегоТипаСлова = "МенеджерВременныхТаблиц" Тогда МенеджерВременныхТаблиц = РодительскаяСтруктураТипа.ДержательМетаданных; Если Истина И ТипЗнч(МенеджерВременныхТаблиц) = Тип("Структура") //И МенеджерВременныхТаблиц.Тип = Тип("МенеджерВременныхТаблиц") //И МенеджерВременныхТаблиц.Активен Тогда //СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип("МенеджерВременныхТаблиц")); СтруктураТипа.Метаданные = МенеджерВременныхТаблиц; //ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Иначе СтруктураТипа.Метаданные = Неопределено; КонецЕсли; ИначеЕсли Истина И (Ложь Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ЭлементыФормы" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ВсеЭлементыФормы") И ТипСловаЦикл = ПеречТипСлова.Метод И (Ложь Или СловоЦикл = "Добавить" Или СловоЦикл = "Получить" Или СловоЦикл = "Найти") Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа,, ЯзыкПрограммы); ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); Прервать; ИначеЕсли Истина И СловоЦикл = "ИсходныйКлючЗаписи" //И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") // Такое условие будет часто не давать срабатывать ветке и потому это редко полезное свойство будет неоправданно добавляться Тогда ЛиДобавляемСлово = Истина И ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") И ЗначениеСвойства <> Неопределено; Если ЛиДобавляемСлово Тогда СтруктураТипа = СтруктураТипаИзЗначения(ЗначениеСвойства, СтруктураТипа); КонецЕсли; Прервать; ИначеЕсли Ложь Или СловоЦикл = "ЭтотОбъект" Или СловоЦикл = "ЭтаФорма" Тогда ЛиДобавляемСлово = Истина; Если ирОбщий.ЛиИмяТипаФормыЛкс(ИмяОбщегоТипаРодителяБезДеталей, СловоЦикл = "ЭтаФорма", Истина) Тогда СтруктураТипа = РодительскаяСтруктураТипа; КонецЕсли; Прервать; ИначеЕсли Истина И ТипСловаЦикл = "Свойство" И СловоЦикл = "ТекущаяСтрока" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы")) Тогда Форма = РодительскаяСтруктураТипа.ДержательМетаданных; ДанныеЭлементаФормы = ирОбщий.ДанныеЭлементаФормыЛкс(МетаданныеРодителя, , Форма); СтруктураТипа.ИмяОбщегоТипа = "Число"; Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДинамическийСписок") Тогда СтруктураТипаСписка = 0; // см. НоваяСтруктураТипа ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(МетаданныеРодителя,, СтруктураТипаСписка, ИмяТаблицыБД); Если ирОбщий.ЛиКорневойТипСсылкиЛкс(ИмяТаблицыБД) Тогда СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзПолногоИмениТаблицыБДЛкс(ИмяТаблицыБД); СтруктураТипа.Метаданные = СтруктураТипаСписка.Метаданные; КонецЕсли; КонецЕсли; ИначеЕсли Истина И СловоЦикл = "ПолучитьСтруктуруХраненияБазыДанных" И ТипСловаЦикл = ПеречТипСлова.Метод И Метаданные.Справочники.Количество() > 0 Тогда Отбор = Новый Массив; Отбор.Добавить(Метаданные.Справочники[0]); Образователь = ПолучитьСтруктуруХраненияБазыДанных(Отбор); СтруктураТипа = СтруктураТипаИзЗначения(Образователь); ИначеЕсли Истина И СловоЦикл = "ВыбратьВерсии" И ТипСловаЦикл = ПеречТипСлова.Метод И Метаданные.Справочники.Количество() > 0 И ирКэш.ДоступноИсторияДанныхЛкс() Тогда Отбор = Новый Структура("Данные", Справочники[Метаданные.Справочники[0].Имя].ПолучитьСсылку()); Образователь = ирОбщий.ИсторияДанныхЛкс().ВыбратьВерсии(Отбор); СтруктураТипа = СтруктураТипаИзЗначения(Образователь); ИначеЕсли Истина И СловоЦикл = "НайтиПоСсылкам" И ТипСловаЦикл = ПеречТипСлова.Метод Тогда Образователь = НайтиПоСсылкам(Новый Массив); СтруктураТипа = СтруктураТипаИзЗначения(Образователь); ИначеЕсли Истина И СловоЦикл = "ПроверитьЦиклическиеСсылкиВстроенногоЯзыка" И ТипСловаЦикл = ПеречТипСлова.Метод Тогда СтруктураЦиклическая = Новый Структура; СтруктураЦиклическая.Вставить("я", СтруктураЦиклическая); // Создаем цикл ссылок Образователь = ирОбщий.ПроверитьЦиклическиеСсылкиВстроенногоЯзыкаЛкс(СтруктураЦиклическая); // Платформа создает колонки только при добавлении первой строки СтруктураЦиклическая.я = Неопределено; // Разрываем цикл ссылок СтруктураТипа = СтруктураТипаИзЗначения(Образователь); ИначеЕсли Истина И СловоЦикл = "ВыгрузитьЖурналРегистрации" И ТипСловаЦикл = ПеречТипСлова.Метод Тогда Образователь = ирКэш.ПустаяТаблицаЖурналРегистрацииЛкс(); СтруктураТипа = СтруктураТипаИзЗначения(Образователь); #Если Не Сервер Тогда ИначеЕсли Истина И СловоЦикл = "ПользователиОС" И ТипСловаЦикл = ПеречТипСлова.Метод Тогда Образователь = ПользователиОС(); СтруктураТипа = СтруктураТипаИзЗначения(Образователь); #КонецЕсли #Если Клиент Тогда ИначеЕсли Ложь Или (Истина И ТипСловаЦикл = ПеречТипСлова.Метод И СловоЦикл = "ДанныеСтроки" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы") Или ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы"))) Или (Истина И ТипСловаЦикл = "Свойство" И (Ложь Или (Истина И (Ложь Или СловоЦикл = "ТекущиеДанные" Или СловоЦикл = "ОформленияЯчеекДинамическогоСписка") И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаФормы") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") И МетаданныеРодителя.Тип = Тип("ТаблицаФормы"))) Или (Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") И (Ложь Или СловоЦикл = "ДанныеСтроки" Или СловоЦикл = "ТекущаяСтрока" Или СловоЦикл = "ТекущиеДанные")))) Тогда НоваяТаблицаТипов = ТаблицаТиповСтрокиТабличногоПоля(РодительскаяСтруктураТипа, МетаданныеРодителя, СловоЦикл, СтрокаСлова.ТипЗначения, СтруктураТипа.Метаданные); Если НоваяТаблицаТипов <> Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов; ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); Прервать; КонецЕсли; #КонецЕсли ИначеЕсли Истина // Опасно широкое условие. Не подходит для Соответствие И КорневойТипРодителя = Неопределено И ТипСловаЦикл = ПеречТипСлова.Метод И СловоЦикл = "Получить" И СтрокаСлова.ТипЗначения = "Произвольный" И ТипЗнч(МетаданныеРодителя) <> Тип("ПостроительЗапроса") Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа,, ЯзыкПрограммы); ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); Прервать; КонецЕсли; Если Истина И КорневойТипРодителя <> Неопределено И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе" Тогда ДоступноеПолеСлова = Неопределено; Если ПостроительЗапросаРодителя <> Неопределено Тогда ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(СловоЦикл)); КонецЕсли; // Частные случаи Если Истина И ПостроительЗапросаРодителя <> Неопределено И ТипСловаЦикл <> ПеречТипСлова.Метод И (Ложь Или ЯзыкПрограммы > 0 И ТипСловаЦикл = "Свойство" Или СловоЦикл = "Активность" Или СловоЦикл = "Владелец" Или СловоЦикл = "ВидДвижения" Или СловоЦикл = "Код" Или СловоЦикл = "МоментВремени" Или СловоЦикл = "Представление" Или СловоЦикл = "НомерСтроки" Или СловоЦикл = "Период" Или СловоЦикл = "Регистратор" //Или СловоЦикл = "СубконтоДт" // Закомментировано 14.04.2012 //Или СловоЦикл = "СубконтоКт" // Закомментировано 14.04.2012 Или СловоЦикл = "СчетДт" Или СловоЦикл = "СчетКт" Или ЛиТипСКвалификаторами И ДоступноеПолеСлова <> Неопределено) Тогда Если ДоступноеПолеСлова = Неопределено Тогда ЛиДобавляемСлово = Ложь; Иначе ОписаниеТиповСлова = ДоступноеПолеСлова.ТипЗначения; // Мультиметка73777324 Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы"); ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова; ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова; ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка"); СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЦикла; КонецЕсли; Прервать; ИначеЕсли Ложь Или (Истина И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджер.<Имя константы>" И СловоЦикл = "Получить") Или (Истина И ИмяОбщегоТипаРодителяБезДеталей = "КонстантаМенеджерЗначения.<Имя константы>" И СловоЦикл = "Значение") Тогда //: МетаданныеРодителя = 0 // ОбъектМетаданныхКонстанта ОписаниеТиповСлова = МетаданныеРодителя.Тип; // Мультиметка73777324 Для Каждого ТипЗначенияСлова Из ОписаниеТиповСлова.Типы() Цикл ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Квалификаторы"); ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова; ШаблонСтруктурыТипа.Квалификаторы = ОписаниеТиповСлова; ЗаполнитьЗначенияСвойств(ШаблонСтруктурыТипа, РодительскаяСтруктураТипа, "ТипЯзыка"); СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗначенияСлова, ЯзыкПрограммы, ШаблонСтруктурыТипа); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЦикла; ИначеЕсли Истина И ТипСловаЦикл = ПеречТипСлова.Метод И (Ложь Или СловоЦикл = "Выгрузить" Или СловоЦикл = "ВыгрузитьКолонки") И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда Образователь = МетаКолонкиФункцииВыгрузитьКолонки(СтрокаОбщегоТипа); Если Образователь <> Неопределено Тогда СтруктураТипа.Метаданные = Образователь; КонецЕсли; ИначеЕсли Истина И (Ложь Или СловоЦикл = "СрезПервых" Или СловоЦикл = "СрезПоследних") И КорневойТипРодителя = "РегистрСведений" И МетаданныеРодителя.ПериодичностьРегистраСведений = мМетаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда ЛиДобавляемСлово = Ложь; Прервать; ИначеЕсли Истина И (Ложь Или СловоЦикл = "Остатки" Или СловоЦикл = "ОстаткиИОбороты") И КорневойТипРодителя = "РегистрНакопления" И МетаданныеРодителя.ВидРегистра = мМетаданные.СвойстваОбъектов.ВидРегистраНакопления.Обороты Тогда ЛиДобавляемСлово = Ложь; Прервать; ИначеЕсли Истина И СловоЦикл = "ОборотыДтКт" И КорневойТипРодителя = "РегистрБухгалтерии" И Не МетаданныеРодителя.Корреспонденция Тогда ЛиДобавляемСлово = Ложь; Прервать; ИначеЕсли Истина И СловоЦикл = "ФактическийПериодДействия" И КорневойТипРодителя = "РегистрРасчета" И Не МетаданныеРодителя.ПериодДействия Тогда ЛиДобавляемСлово = Ложь; Прервать; ИначеЕсли Истина И СловоЦикл = "ДанныеГрафика" И КорневойТипРодителя = "РегистрРасчета" И МетаданныеРодителя.График = Неопределено Тогда ЛиДобавляемСлово = Ложь; Прервать; Иначе ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЕсли; ИначеЕсли Истина И СловоЦикл = "Выполнить" И ТипСловаЦикл = ПеречТипСлова.Метод И ТипЗнч(МетаданныеРодителя) = Тип("Запрос") Тогда ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(МетаданныеРодителя.Текст); СтруктураТипа.Метаданные = ПостроительЗапроса; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); ИначеЕсли Истина И СловоЦикл = "Выгрузить" И ТипСловаЦикл = ПеречТипСлова.Метод И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("Запрос") Или ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса")) Тогда ПостроительЗапроса = МетаданныеРодителя; Если ТипЗнч(ПостроительЗапроса) = Тип("Запрос") Тогда ПостроительЗапроса = ПостроительЗапросаИзТекстаДляТипа(ПостроительЗапроса.Текст); КонецЕсли; ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса, РодительскаяСтруктураТипа.ДержательМетаданных); СтруктураТипа.Метаданные = ПустаяТаблицаЗначенийИзПостроителя(ПостроительЗапроса); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); ИначеЕсли Истина И СловоЦикл = "Выгрузить" И ТипСловаЦикл = ПеречТипСлова.Метод И (Ложь Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыКоллекция") Или ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("ДанныеФормыСтруктураСКоллекцией")) Тогда #Если Клиент Тогда ТаблицаЗначений = Новый ТаблицаЗначений; Для Каждого КлючИЗначение Из ДочерниеСвойстваДанныхФормы(МетаданныеРодителя,, РодительскаяСтруктураТипа.ДержательМетаданных, СловоФильтр) Цикл ТаблицаЗначений.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; СтруктураТипа.Метаданные = ТаблицаЗначений; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); #КонецЕсли ИначеЕсли Истина И СловоЦикл = "ВыгрузитьЗначения" И ТипСловаЦикл = ПеречТипСлова.Метод И ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда СтруктураТипа.Метаданные = МетаданныеРодителя.Значение; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); ИначеЕсли Истина И СловоЦикл = "Значение" И ТипСловаЦикл = "Свойство" И ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("СписокЗначений") И СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы().Количество() = 1 Тогда СтруктураТипа = СтруктураТипаИзКонкретногоТипа(СтрокаОбщегоТипа.Метаданные.ТипЗначения.Типы()[0]); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); ИначеЕсли Истина И ИмяОбщегоТипаРодителяБезДеталей = "ОбъектМетаданныхКонфигурация" И ТипСловаЦикл = "Свойство" И ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаСлова, МаркерКоллекцииМетаданных) Тогда СтруктураТипа.Метаданные = Метаданные[СловоЦикл]; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); Иначе Если Истина И ИмяОбщегоТипаСлова = "Форма" // TODO возможно нужно заменить на ирОбщий.ЛиИмяТипаФормыЛкс() И СловоЦикл = "ЭтаФорма" Тогда // Эта пока не несет пользы, но возможно дополнительные типы потом снова начну использовать ДобавитьВТаблицуТипов(ТаблицаТипов, РодительскаяСтруктураТипа, Истина); Иначе ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа, Ложь); КонецЕсли; КонецЕсли; КонецЦикла; Если Не ЛиДобавляемСлово Тогда Продолжить; КонецЕсли; Если ТаблицаТипов.Количество() = 0 Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЕсли; ТаблицаТипов.ЗаполнитьЗначения(СтрокаСлова, "СтрокаОписания"); КонецЕсли; ТипЗначенияИндекс = СтрокаСлова.ТипЗначения; Если ЛиТипСКвалификаторами Или МожноУточнитьТип Тогда ТипЗначения = "??," + ТипЗначенияИндекс; Иначе ТипЗначения = ТипЗначенияИндекс; КонецЕсли; ДобавитьВТаблицуСлов(ТаблицаСлов, СловоЦикл, ТипСловаЦикл, ТаблицаТипов, ТипЗначения, "Предопределенный",,,, ЛиПолныйКонтрольУникальности, ТипЗначенияИндекс); КонецЦикла; Если ИспользоватьКэширование И Не ЛиПолноеКэширование Тогда СтруктураТипаГлобальный = НоваяСтруктураТипа(ИмяОбщегоТипаРодителяБезДеталей); СтруктураТипаГлобальный.Метаданные = МетаданныеРодителя; СтруктураТипаГлобальный.Конструктор = РодительскаяСтруктураТипа.Конструктор; СтруктураТипаГлобальный.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка; ПараметрыЗаполнения.ТаблицаСлов = ТаблицаСлов; СловаКонтекстаМетаданные(СтруктураТипаГлобальный, ПараметрыЗаполнения); ДобавитьТаблицуСловВГлобальныйКэш(ТаблицаСлов, КлючКэширования, НаборыСлов); КлючКэширования = Неопределено; КонецЕсли; // Ускорение Если Истина И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ОбъектМетаданных" И ЗначениеЗаполнено(СловоФильтр) И ТаблицаСлов.Количество() > 0 Тогда Прервать; КонецЕсли; // Удаляем перегрузку метода глобального контекста методом объекта // Например ОбработкаОбъект.ПолучитьФорму(), Форма.ПодключитьОбработчикОжидания() Пока Истина И ЗначениеЗаполнено(СловоФильтр) И ТаблицаСлов.Количество() > 1 И ТаблицаСлов[0].ТипСлова = ТаблицаСлов[1].ТипСлова Цикл ТаблицаСлов.Удалить(0); КонецЦикла; КонецЦикла; Возврат ТаблицаСлов; КонецФункции Функция МетаКолонкиФункцииВыгрузитьКолонки(Знач СтруктураТипа, Знач ИменаКолонок = Неопределено) Экспорт ИмяКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа); Образователь = Неопределено; Если Ложь Или НРег(ИмяКонкретногоТипа) = Нрег("ТабличнаяЧасть") // СтрокаОбщегоТипа Или Найти(ИмяКонкретногоТипа, "ТабличнаяЧасть.") > 0 Тогда Образователь = ирОбщий.УстановитьМетаданныеКоллекцииЛкс(СтруктураТипа.Метаданные,, ИменаКолонок); ИменаКолонок = Неопределено; ИначеЕсли НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("ПланСчетовВидыСубконто.<Имя плана счетов>") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтруктураТипа.Метаданные.ПолноеИмя()); СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]); РеквизитыСчета = СтруктураОбъекта.Данные; // ПланСчетовОбъект Образователь = РеквизитыСчета.ВидыСубконто; ИначеЕсли Ложь Или НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("ВытесняющиеВидыРасчета.<Имя плана видов расчета>") Или НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("БазовыеВидыРасчета.<Имя плана видов расчета>") Или НРег(СтруктураТипа.ИмяОбщегоТипа) = Нрег("ВедущиеВидыРасчета.<Имя плана видов расчета>") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтруктураТипа.Метаданные.ПолноеИмя()); СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(МассивФрагментов[0] + "." + МассивФрагментов[1]); ИмяТЧ = ирОбщий.ПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа); Попытка Образователь = СтруктураОбъекта.Данные[ИмяТЧ]; Исключение КонецПопытки; ИначеЕсли Найти(ИмяКонкретногоТипа, "<") = 0 Тогда СтруктураОбъекта = ирОбщий.ОбъектБДПоКлючуЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(СтруктураТипа.Метаданные.ПолноеИмя())); Образователь = СтруктураОбъекта.Данные; КонецЕсли; Если Образователь <> Неопределено Тогда Если ТипЗнч(Образователь) <> Тип("ТаблицаЗначений") Тогда //! Образователь = 0; // ТабличнаяЧасть Попытка Образователь = Образователь.ВыгрузитьКолонки(ИменаКолонок); Исключение КонецПопытки; ИначеЕсли ЗначениеЗаполнено(ИменаКолонок) Тогда Попытка Образователь = Образователь.СкопироватьКолонки(ИменаКолонок); Исключение КонецПопытки; КонецЕсли; КонецЕсли; Возврат Образователь; КонецФункции Функция НовыйИмитаторЭлементаФормы() Экспорт Возврат Новый Структура("Тип, ПутьКДанным, Значение, Имя"); КонецФункции Функция ПроверятьДоступностьВКонтекстеКомпиляции(Знач ФлагиКомпиляции, Знач РодительскаяСтруктураТипа, Знач ЭтоЛокальныйКонтекст) Экспорт Результат = ФлагиКомпиляции <> Неопределено И Не (Истина // В таких модулях часто применяют инструкции препроцессора, которые анализатор пока не учитывает И ФлагиКомпиляции.Сервер И ФлагиКомпиляции.КлиентОбычноеПриложение И Не (Истина И ирОбщий.ЛиИмяТипаФормыЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа) И ЭтоЛокальныйКонтекст)) И Не (Истина // Чтобы СправочникОбъект в реквизите имитатора упр. формы на клиенте показывал дочерние свойства И ТипЗнч(РодительскаяСтруктураТипа.ДержательМетаданных) = Тип("Структура") И ирОбщий.ЛиФормаИлиИмитаторЛкс(РодительскаяСтруктураТипа.ДержательМетаданных, Ложь) И ТипЗнч(РодительскаяСтруктураТипа.СтрокаОписания) = Тип("СтрокаТаблицыЗначений") И РодительскаяСтруктураТипа.СтрокаОписания.Владелец().Колонки.Найти("Слово") <> Неопределено // Защита от переменной модуля И (Ложь Или РодительскаяСтруктураТипа.СтрокаОписания.Слово = "<Имя реквизита>" Или РодительскаяСтруктураТипа.СтрокаОписания.Слово = "<Имя табличной части>") И (Ложь Или Не ФлагиКомпиляции.Сервер Или ФлагиКомпиляции.БезКонтекста // чтобы в &НаКлиентеНаСервереБезКонтекста работало после ЭтаФорма.Объект. )); Возврат Результат; КонецФункции //. // Параметры: // ИмяОбщегоТипа - Строка - // Возвращаемое значение: // Строка, Неопределено - выходной, Неопределено - не использовать кэш, Истина - полная таблица взята из кэша Функция КлючКэшированияСловИзОбщегоТипа(Знач ИмяОбщегоТипа) Экспорт Возврат ИмяОбщегоТипа; КонецФункции //. // Параметры: // ТаблицаСлов - ТаблицаЗначений - // КлючКэширования - Строка - // НаборыСлов - - Процедура ДобавитьТаблицуСловВГлобальныйКэш(Знач ТаблицаСлов, Знач КлючКэширования, Знач НаборыСлов) Экспорт ТаблицаСловИзКэша = ТаблицаСлов.Скопировать(); мКэшСловГлобальногоКонтекста[КлючКэширования] = ТаблицаСловИзКэша; Если НаборыСлов <> Неопределено Тогда НаборыСлов.Вставить(КлючКэширования, ТаблицаСловИзКэша); ТаблицаСлов.Очистить(); КонецЕсли; КонецПроцедуры //. // Параметры: // ПостроительЗапроса - ПостроительЗапроса - // Возвращаемое значение: // ТаблицаЗначений, Неопределено - Функция ПустаяТаблицаЗначенийИзПостроителя(Знач ПостроительЗапроса) Экспорт ТаблицаЗначений = Новый ТаблицаЗначений; Для Каждого ВыбранноеПоле Из ПостроительЗапроса.ВыбранныеПоля Цикл ТаблицаЗначений.Колонки.Добавить(ВыбранноеПоле.Имя, ПостроительЗапроса.ДоступныеПоля[ВыбранноеПоле.Имя].ТипЗначения); КонецЦикла; Возврат ТаблицаЗначений; КонецФункции Функция МаксРазмерТаблицыТиповДляЗаполненияТаблицыСлов() Экспорт // У группы общих модулей БСП.ОбщегоНазначения* - 11шт Возврат 15; КонецФункции // Получает внутреннюю таблицу метаданных слов заданного родительского типа. // Параметры: // РодительскаяСтруктураТипа - см. НоваяСтруктураТипа - // ПараметрыЗаполнения - см. НовыеПараметрыЗаполненияСлов - // КлючКэширования - - // Возвращаемое значение: // см. НоваяТаблицаСлов - Функция СловаКонтекстаМетаданные(Знач РодительскаяСтруктураТипа, Знач ПараметрыЗаполнения, КлючКэширования = Неопределено) Экспорт ТаблицаСлов = ПараметрыЗаполнения.ТаблицаСлов; Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСлов(); КонецЕсли; ТипСловаФильтр = ПараметрыЗаполнения.ТипСловаФильтр; Если Ложь Или ТипСловаФильтр = "Конструктор" Или РодительскаяСтруктураТипа.Конструктор Или Не ЗначениеЗаполнено(РодительскаяСтруктураТипа.ИмяОбщегоТипа) // родительский контекст является процедурой Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Произвольный" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Неопределено" Тогда Возврат ТаблицаСлов; КонецЕсли; БазовоеРасширениеКонфигурации = ПараметрыЗаполнения.БазовоеРасширениеКонфигурации; ВнутриГруппыОбщихМодулей = ПараметрыЗаполнения.ВнутриГруппыОбщихМодулей; ВычислятьТипы = ПараметрыЗаполнения.ВычислятьТипы; ВычислятьТипыМетодовМодулей = ПараметрыЗаполнения.ВычислятьТипыМетодовМодулей; ДляЗаписи = ПараметрыЗаполнения.ДляЗаписи; ДляСвойства = ПараметрыЗаполнения.ДляСвойства; ЗапретГлобальногоКонтекста = ПараметрыЗаполнения.ЗапретГлобальногоКонтекста; ЛиВместеСЛокальнымКонтекстом = ПараметрыЗаполнения.ЛиВместеСЛокальнымКонтекстом; НаборыСлов = ПараметрыЗаполнения.НаборыСлов; СловоФильтр = ПараметрыЗаполнения.СловоФильтр; ТекущийИндекс = ПараметрыЗаполнения.ТекущийИндекс; ТолькоСоЗначениями = ПараметрыЗаполнения.ТолькоСоЗначениями; ФлагиКомпиляции = ПараметрыЗаполнения.ФлагиКомпиляции; ЭтоЛокальныйКонтекст = ПараметрыЗаполнения.ЭтоЛокальныйКонтекст; ЯзыкПрограммы = ПараметрыЗаполнения.ЯзыкПрограммы; Если РодительскаяСтруктураТипа.ТипЯзыка = "ЗначениеВЗапросе" Тогда ЯзыкПрограммы = 1; КонецЕсли; // Мультиметка3398476724 ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс(); НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина); КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП); КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП); БезКонтекста = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "БезКонтекста", ЛиСеансТолстогоКлиентаУП); ПредставлениеМетаданных = ирОбщий.ПредставлениеЗначенияЛкс(РодительскаяСтруктураТипа.Метаданные); ЭтоМетаданныеТабличнойЧастиВнешнейОбработки = ирОбщий.ПервыйФрагментЛкс(ПредставлениеМетаданных) = "ВнешняяОбработкаТабличнаяЧасть"; //Если Не ирОбщий.СтрНачинаетсяСЛкс(ПредставлениеМетаданных, "Внешн") Тогда // Не подходит для незаписанной внешней обработки Если Не ирОбщий.СтрНачинаетсяСЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Внешн") Тогда КонкретныйТип = ИмяТипаИзСтруктурыТипа(РодительскаяСтруктураТипа); Если Найти(ирОбщий.ПервыйФрагментЛкс(КонкретныйТип, "["), "<") > 0 Тогда // Такой конкретный тип не разрешен Возврат ТаблицаСлов; КонецЕсли; КонецЕсли; ЛиВместеСЛокальнымКонтекстом = ЛиВместеСЛокальнымКонтекстом Или ЭтоЛокальныйКонтекст; Если ВычислятьТипыМетодовМодулей = Неопределено Тогда ВычислятьТипыМетодовМодулей = СловоФильтр <> Неопределено; КонецЕсли; Если СловоФильтр <> Неопределено И ТекущийИндекс <> Неопределено Тогда ЛиСтруктура = Ложь Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Структура" Или РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ФиксированнаяСтруктура"; Если Не ЛиСтруктура Тогда ОписаниеОбщегоТипа = ОписаниеОбщегоТипа(РодительскаяСтруктураТипа.ИмяОбщегоТипа, ЯзыкПрограммы); Если Истина И ОписаниеОбщегоТипа <> Неопределено И ОписаниеОбщегоТипа.ТипЭлементаКоллекции = "КлючИЗначение" Тогда ТаблицаТиповЭлементов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа, СловоФильтр, ЯзыкПрограммы); СтруктураСвойств = ТаблицаТиповЭлементов[0].Метаданные; ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("Неопределено")); Если Истина И ТипЗнч(СтруктураСвойств) = Тип("Структура") И СтруктураСвойств.Значение <> Неопределено Тогда ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураСвойств.Значение); КонецЕсли; ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1"); Возврат ТаблицаСлов; КонецЕсли; КонецЕсли; ЛиИндексИдентификатор = Ложь; мРегВыражение.Pattern = "^""(" + шИмя + ")""$"; РезультатСтроковойКонстанты = мРегВыражение.НайтиВхождения(СловоФильтр); Если РезультатСтроковойКонстанты.Количество() > 0 Тогда СловоФильтр = РезультатСтроковойКонстанты[0].SubMatches(0); ЛиИндексИдентификатор = Истина; КонецЕсли; Если ЛиСтруктура Тогда // у них значениями именованных свойств являются произвольные типы. Их вычисляем дальше. Иначе Если Не ЛиИндексИдентификатор Тогда ТаблицаТипов = ТаблицаТиповЭлементовКоллекции(РодительскаяСтруктураТипа, СловоФильтр, ЯзыкПрограммы); ДобавитьВТаблицуСлов(ТаблицаСлов, "*", "Свойство", ТаблицаТипов,, "Метаданные1"); Возврат ТаблицаСлов; КонецЕсли; КонецЕсли; КонецЕсли; ЭтоГруппаОбщихМодулей = Ложь; ПолноеИмяПодсистемыИР = ирОбщий.ИмяПродуктаЛкс(); МаксЧислоТиповДляАнализа = МаксЧислоТиповДляАнализа(); ИмяКолонкиФлагаТаблицыТипов = ИмяКолонкиФлагаТаблицыТипов(); ТаблицаОбщихТиповСтруктурыТипа = РазвернутаяТаблицаТиповИзСтруктурыТипа(РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст, Ложь); ЕдинственнаяСтрокаВида = Неопределено; ПроверятьДоступностьВКонтекстеКомпиляции = ПроверятьДоступностьВКонтекстеКомпиляции(ФлагиКомпиляции, РодительскаяСтруктураТипа, ЭтоЛокальныйКонтекст); Для Каждого СтрокаОбщегоТипа Из ТаблицаОбщихТиповСтруктурыТипа Цикл ИмяОбщегоТипаРодителя = СтрокаОбщегоТипа.ИмяОбщегоТипа; Если ЗапретГлобальногоКонтекста И ИмяОбщегоТипаРодителя = "Глобальный" Тогда Продолжить; КонецЕсли; Если Истина И ИмяОбщегоТипаРодителя = "Глобальный" И РодительскаяСтруктураТипа.ИмяОбщегоТипа <> "Глобальный" // пропускаем вызов для заполнения кэша И СловоФильтр = Неопределено И ТекущийИндекс = Неопределено Тогда // Подразумеваем, что в ТаблицаСлов уже помещен кэш Предопределенные+Метаданные Продолжить; КонецЕсли; Если ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипаРодителя, "ISWbemObject {WbemScripting.SwbemLocator}") Тогда Если ТипЗнч(СтрокаОбщегоТипа.Метаданные) = Тип("COMОбъект") Тогда СтруктураЦикла = Новый Структура(); Попытка СтруктураЦикла.Вставить("Свойство", СтрокаОбщегоТипа.Метаданные.Properties_); СтруктураЦикла.Вставить("Метод", СтрокаОбщегоТипа.Метаданные.Methods_); Исключение КонецПопытки; Для Каждого КлючИЗначение Из СтруктураЦикла Цикл КоллекцияСвойств = КлючИЗначение.Значение; ТипСловаЧленаКласса = КлючИЗначение.Ключ; Если Истина И ТипСловаФильтр <> Неопределено И Не ирОбщий.СтрокиРавныЛкс(ТипСловаЧленаКласса, ТипСловаФильтр) Тогда Продолжить; КонецЕсли; Для Каждого Свойство Из КоллекцияСвойств Цикл ИмяСвойства = Свойство.Name; Если Истина И СловоФильтр <> Неопределено И Не ирОбщий.СтрокиРавныЛкс(ИмяСвойства, СловоФильтр) Тогда Продолжить; КонецЕсли; ТаблицаТипов = НоваяТаблицаТипов(); СтруктураТипа = ТаблицаТипов.Добавить(); СтруктураТипа.СтрокаОписания = Свойство; СтруктураТипа.ИмяОбщегоТипа = ирОбщий.ИмяТипаИзКвалификаторовWMIЛкс(Свойство); СтруктураТипа.Метаданные = РодительскаяСтруктураТипа.Метаданные; ДобавитьВТаблицуСлов(ТаблицаСлов, ИмяСвойства, ТипСловаЧленаКласса, ТаблицаТипов,, "Метаданные"); КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; МетаданныеРодителя = СтрокаОбщегоТипа.Метаданные; Если Ложь Или ИмяОбщегоТипаРодителя = "Локальный" Или (Истина И ИмяОбщегоТипаРодителя <> "Глобальный" И ФлагиКомпиляции <> Неопределено И ФлагиКомпиляции.БезКонтекста И ЭтоЛокальныйКонтекст) Тогда НайденныеСтроки = Новый Массив; Иначе КорневойТипРодителя = Неопределено; ПостроительЗапросаРодителя = Неопределено; Если РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" Тогда ТипМетаданныхРодителя = ТипЗнч(МетаданныеРодителя); Если Ложь Или ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Или (Истина И ЭтоИнтеграция И (Ложь Или ТипМетаданныхРодителя = Тип("СправочникСсылка.МетаданныеИис") Или ТипМетаданныхРодителя = Тип("СправочникСсылка.СвойстваМетаданныхИис"))) Тогда Если ТипМетаданныхРодителя = Тип("ОбъектМетаданных") Тогда КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(МетаданныеРодителя); Иначе КорневойТипРодителя = ирОбщий.КорневойТипКонфигурацииЛкс(КэшОбъект(МетаданныеРодителя).ПолноеИмя); КонецЕсли; ПостроительЗапросаРодителя = ПостроительЗапросаПоСтруктуреТипа(СтрокаОбщегоТипа, РодительскаяСтруктураТипа.ВиртуальнаяТаблица); КонецЕсли; КонецЕсли; Если Истина И ЯзыкПрограммы = 2 И ИмяОбщегоТипаРодителя = "Глобальный" И ПараметрыЗаполнения.ВнешниеФункцииКомпоновкиДанных Тогда СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, НСлово", ИмяОбщегоТипаРодителя, 0, РодительскаяСтруктураТипа.ТипЯзыка, НРег("<Имя общего модуля>")); Иначе СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипаРодителя, ЯзыкПрограммы, РодительскаяСтруктураТипа.ТипЯзыка); КонецЕсли; Если ТипСловаФильтр <> Неопределено Тогда СтруктураКлюча.Вставить("ТипСлова", ТипСловаФильтр); КонецЕсли; НайденныеСтроки = ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча); КонецЕсли; ПредыдущаяСтрокаВида = Неопределено; // см. НайденныеСтроки[0] - для регистра бухгалтерии Для Каждого СтрокаСлова Из НайденныеСтроки Цикл Если Ложь Или (Истина И ТолькоСоЗначениями И ПустаяСтрока(СтрокаСлова.ТипЗначения) И СтрокаСлова.ТипСлова <> "Свойство") Или ДляЗаписи И Не СтрокаСлова.Запись Или (Истина И ПредыдущаяСтрокаВида <> Неопределено И ПредыдущаяСтрокаВида.НСлово = СтрокаСлова.НСлово И ПредыдущаяСтрокаВида.ТипСлова = СтрокаСлова.ТипСлова) Или СтрокаСлова.НомерВерсииПлатформы > мНомерВерсииПлатформы Или СтрокаСлова.ТипСлова = "Событие" Или (Истина И ПроверятьДоступностьВКонтекстеКомпиляции И (Ложь Или ФлагиКомпиляции.Сервер И СтрокаСлова.НеСервер Или ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТолстыйКлиент Или ФлагиКомпиляции.КлиентУправляемоеПриложение И Не ФлагиКомпиляции.КлиентОбычноеПриложение И СтрокаСлова.НеТонкийКлиент)) Тогда Продолжить; КонецЕсли; // Нельзя делать переход, т.к. не будет работать перегрузка свойств, например "Параметры" в модуле конструктора запросов //Если Истина // И ЗначениеЗаполнено(СловоФильтр) // И СтрокаСлова.Слово = "<Имя реквизита>" // И ИмяОбщегоТипаРодителя = "Форма" // И ТаблицаСлов.Количество() > 0 //Тогда // Продолжить; //КонецЕсли; Если ЕдинственнаяСтрокаВида = Неопределено Тогда ЕдинственнаяСтрокаВида = СтрокаСлова; Иначе ЕдинственнаяСтрокаВида = Null; КонецЕсли; Если СловоФильтр = "?" Тогда Продолжить; КонецЕсли; ПредыдущаяСтрокаВида = СтрокаСлова; ЛиТипСКвалификаторами = ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(СтрокаСлова.ТипЗначения); СхемаКоллекции = Новый Соответствие; МетаданныеЭлементов = Новый Соответствие; КоллекцияЗначений = Неопределено; ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаСлова.Слово, "<", ">", Ложь, Истина); КлючПоиска = Новый Структура("ИмяОбщегоТипа, ИмяЭлементаКоллекции", ИмяОбщегоТипаРодителя, ИмяЭлементаКоллекции); СтрокаОписанияВида = Неопределено; НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска); Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда СтрокаОписанияВида = НайденныеСтрокиКоллекций[0]; Если НайденныеСтрокиКоллекций.Количество() > 1 Тогда #Если Клиент Тогда Если Истина И СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы" И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Форма") Тогда // Устранение неоднозначности одноименных типов "ЭлементыФормы" обычной и упрвляемой формы СтрокаОписанияВида = НайденныеСтрокиКоллекций[1]; КонецЕсли; #КонецЕсли КонецЕсли; КонецЕсли; Если СтрокаОписанияВида = Неопределено Тогда КлючПоиска.Удалить("ИмяОбщегоТипа"); НайденныеСтрокиКоллекций = ТаблицаИменЭлементовКоллекций.НайтиСтроки(КлючПоиска); Если НайденныеСтрокиКоллекций.Количество() > 0 Тогда СтрокаОписанияВида = НайденныеСтрокиКоллекций[0]; КонецЕсли; КонецЕсли; //// Исправление кривоты платформенной справки (неуникальные имена шаблона элемента коллекции между разными типами коллекций) //Если ИмяЭлементаКоллекции = "<Имя элемента управления>" Тогда // СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции); // Если ИмяОбщегоТипа = "ВсеЭлементыФормы" Тогда // СтруктураОтбора.ИмяКоллекции = "Элементы"; // Иначе//Если ИмяОбщегоТипа = "ЭлементыФормы" Тогда // СтруктураОтбора.ИмяКоллекции = "ЭлементыФормы"; // КонецЕсли; // СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0]; //ИначеЕсли ИмяЭлементаКоллекции = "<Имя колонки>" Тогда // СтруктураОтбора = Новый Структура("ИмяЭлементаКоллекции, ИмяКоллекции", ИмяЭлементаКоллекции); // Если ИмяОбщегоТипа = "Ячейки" Тогда // СтруктураОтбора.ИмяКоллекции = "ОформленияЯчеек"; // Иначе//Если ИмяОбщегоТипа = "СтрокаТаблицыЗначений" Тогда // СтруктураОтбора.ИмяКоллекции = "Колонки"; // КонецЕсли; // СтрокаОписанияВида = ТаблицаИменЭлементовКоллекций.НайтиСтроки(СтруктураОтбора)[0]; //КонецЕсли; Если СловоФильтр <> Неопределено Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(СтрокаСлова.Слово, ИмяЭлементаКоллекции); НачалоТекущегоСлова = Лев(СловоФильтр, СтрДлина(МассивФрагментов[0])); КонецТекущегоСлова = Прав(СловоФильтр, СтрДлина(МассивФрагментов[1])); ИмяТекущегоСлова = Сред(СловоФильтр, СтрДлина(НачалоТекущегоСлова) + 1, СтрДлина(СловоФильтр) - СтрДлина(КонецТекущегоСлова)); Если НачалоТекущегоСлова + ИмяЭлементаКоллекции + КонецТекущегоСлова <> СтрокаСлова.Слово Тогда Продолжить; КонецЕсли; КонецЕсли; Если СтрокаОписанияВида = Неопределено Тогда // Имя элемента коллекции не внесено в служебную таблицу Продолжить; КонецЕсли; Если Истина И СтрокаОписанияВида.ИмяКоллекции = "Предопределенные" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") // Тогда Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ Т.Ссылка ИЗ " + МетаданныеРодителя.ПолноеИмя() + " КАК Т ГДЕ Т.Предопределенный"; Результат = Запрос.Выполнить().Выгрузить(); МенеджерТипа = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя); Для Каждого СтрокаРезультата Из Результат Цикл СхемаКоллекции.Вставить(МенеджерТипа.ПолучитьИмяПредопределенного(СтрокаРезультата.Ссылка), Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(СтрокаРезультата.Ссылка)))); КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда КоллекцияЗначений = МетаданныеРодителя; Если Истина И ЗначениеЗаполнено(СловоФильтр) И МетаданныеРодителя.Свойство(СловоФильтр) Тогда ТаблицаТиповСлова = МетаданныеРодителя[СловоФильтр]; Если Истина И ТипЗнч(ТаблицаТиповСлова) = Тип("ТаблицаЗначений") И ТаблицаТиповСлова.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено И ТаблицаТиповСлова.Количество() > 0 И ТипЗнч(ТаблицаТиповСлова[0].СтрокаОписания) = Тип("Структура") Тогда ОписаниеСвойства = ТаблицаТиповСлова[0].СтрокаОписания; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовоеОписаниеДинамическогоСвойства ОписаниеСвойства = ирОбщий.СкопироватьКоллекциюЛкс(ОписаниеСвойства); ОписаниеСвойства.СтрокаОписания = СтрокаСлова; КоллекцияЗначений = ирОбщий.СкопироватьКоллекциюЛкс(КоллекцияЗначений); ТаблицаТиповСлова = КоллекцияЗначений[СловоФильтр].Скопировать(); ТаблицаТиповСлова.ЗаполнитьЗначения(ОписаниеСвойства, "СтрокаОписания"); КоллекцияЗначений[СловоФильтр] = ТаблицаТиповСлова; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или (Истина И (Ложь Или СтрокаОписанияВида.ИмяКоллекции = "Колонки" Или СтрокаОписанияВида.ИмяКоллекции = "Поля") И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") Или ТипЗнч(МетаданныеРодителя) = Тип("РезультатЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений") )) Или (Истина И СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>" И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле")) Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда ОписаниеСвойства = Неопределено; Если Истина И ЗначениеЗаполнено(СловоФильтр) И МетаданныеРодителя.Свойство(СловоФильтр) И ЗначениеЗаполнено(МетаданныеРодителя[СловоФильтр]) И ТипЗнч(МетаданныеРодителя[СловоФильтр][0].СтрокаОписания) = Тип("Структура") Тогда ОписаниеСвойства = МетаданныеРодителя[СловоФильтр][0].СтрокаОписания; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовоеОписаниеДинамическогоСвойства ОписаниеСвойства = ирОбщий.СкопироватьКоллекциюЛкс(ОписаниеСвойства); ОписаниеСвойства.СтрокаОписания = СтрокаСлова; КонецЕсли; Если Ложь Или СтрокаСлова.ТипЗначения = "КолонкаТаблицыЗначений" Или СтрокаСлова.ТипЗначения = "КолонкаДереваЗначений" Тогда СхемаКоллекции = Новый Структура; ОписаниеТиповКолонки = Новый ОписаниеТипов(СтрокаСлова.ТипЗначения); Для Каждого КлючИЗначение Из МетаданныеРодителя Цикл СхемаКоллекции.Вставить(КлючИЗначение.Ключ, ОписаниеТиповКолонки); КонецЦикла; Если ОписаниеСвойства <> Неопределено Тогда ТаблицаТиповСлова = ТаблицаТиповИзОписанияТипов(ОписаниеТиповКолонки); ТаблицаТиповСлова.ЗаполнитьЗначения(ОписаниеСвойства, "СтрокаОписания"); СхемаКоллекции[СловоФильтр] = ТаблицаТиповСлова; КонецЕсли; // //Для Каждого КлючИЗначение Из МетаданныеРодителя Цикл // СхемаКоллекции.Вставить(КлючИЗначение.Ключ); // Так всегда напрямую передаются метаданные родителя и потому в описании слова в свойствах появляется список всех колонок //КонецЦикла; Иначе КоллекцияЗначений = МетаданныеРодителя; Если ОписаниеСвойства <> Неопределено Тогда КоллекцияЗначений = ирОбщий.СкопироватьКоллекциюЛкс(КоллекцияЗначений); ТаблицаТиповСлова = КоллекцияЗначений[СловоФильтр].Скопировать(); ТаблицаТиповСлова.ЗаполнитьЗначения(ОписаниеСвойства, "СтрокаОписания"); КоллекцияЗначений[СловоФильтр] = ТаблицаТиповСлова; КонецЕсли; КонецЕсли; ИначеЕсли Найти(ИмяОбщегоТипаРодителя, "Колон") = 0 Тогда // %%%% Некрасиво, но работает Если СтрокаОписанияВида.ИмяЭлементаКоллекции = "<Имя колонки списка>" Тогда ДинамическийСписок = МетаданныеРодителя.Значение; ПостроительСписка = ПостроительЗапросаПоСтруктуреТипа(СтруктураТипаИзЗначения(ДинамическийСписок)); КоллекцияКолонок = ДинамическийСписок.Колонки; Для Каждого Колонка Из КоллекцияКолонок Цикл Если Колонка.Имя = "" Тогда // Антибаг платформы 8.2.16 Продолжить; КонецЕсли; СхемаКоллекции.Вставить(Колонка.Имя, ПостроительСписка.ДоступныеПоля[Колонка.Имя].ТипЗначения); КонецЦикла; Иначе Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений") Тогда Попытка МетаОбъект = МетаданныеРодителя.Владелец(); Исключение // Строка была удалена МетаОбъект = Неопределено; КонецПопытки; Если МетаОбъект <> Неопределено Тогда Для Каждого Колонка Из МетаОбъект.Колонки Цикл Если Колонка.Имя = "" Тогда // Строка таблицы/дерева при перетаскивании имеет такую колонку (вероятно ошибка платформы) Продолжить; КонецЕсли; ТипЗначенияКолонки = Колонка.ТипЗначения; Если ТипЗначенияКолонки.Типы().Количество() = 0 Тогда ТипЗначенияКолонки = МетаданныеРодителя[Колонка.Имя]; КонецЕсли; СхемаКоллекции.Вставить(Колонка.Имя, ТипЗначенияКолонки); КонецЦикла; КонецЕсли; Иначе Для Каждого Колонка Из МетаданныеРодителя.Колонки Цикл СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения); КонецЦикла; КонецЕсли; КонецЕсли; Иначе Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ВыборкаИзРезультатаЗапроса") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаТаблицыЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("СтрокаДереваЗначений") Тогда КоллекцияЗначений = МетаданныеРодителя.Владелец().Колонки; Иначе КоллекцияЗначений = МетаданныеРодителя.Колонки; КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда СхемаКоллекции = МетаданныеРодителя.Реквизиты; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И ЭтоМетаданныеТабличнойЧастиВнешнейОбработки Тогда //! МетаданныеРодителя = 0 // ТабличнаяЧасть Для Каждого Колонка Из МетаданныеРодителя.ВыгрузитьКолонки().Колонки Цикл Если Колонка.Имя = "НомерСтроки" Тогда Продолжить; КонецЕсли; СхемаКоллекции.Вставить(Колонка.Имя, Колонка.ТипЗначения); КонецЦикла; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И СтрокаОписанияВида.ИмяКоллекции = "Колонки" Тогда ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя, РодительскаяСтруктураТипа.ДержательМетаданных); Если СтрокаСлова.ТипЗначения <> "Произвольный" Тогда Попытка ОписаниеТиповЭлемента = Новый ОписаниеТипов(СтрокаСлова.ТипЗначения); Исключение ОписаниеТиповЭлемента = Неопределено; КонецПопытки; КонецЕсли; Для Каждого ВыбранноеПоле Из МетаданныеРодителя.ВыбранныеПоля Цикл лДоступноеПоле = МетаданныеРодителя.ДоступныеПоля.Найти(ВыбранноеПоле.Имя); Если СтрокаСлова.ТипЗначения = "Произвольный" Тогда ОписаниеТиповЭлемента = лДоступноеПоле.ТипЗначения; КонецЕсли; СхемаКоллекции.Вставить(ВыбранноеПоле.Имя, ОписаниеТиповЭлемента); КонецЦикла; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И СтрокаОписанияВида.ИмяКоллекции = "Поля" Тогда ПодготовитьМетаданныеПостроителяЗапроса(МетаданныеРодителя, РодительскаяСтруктураТипа.ДержательМетаданных); Для Каждого ДоступноеПоле Из МетаданныеРодителя.ДоступныеПоля Цикл ТипЗначения = ДоступноеПоле.ТипЗначения; Если Истина И ТипЗначения.СодержитТип(Тип("ТаблицаЗначений")) И ИмяОбщегоТипаРодителя = "ВыборкаИзРезультатаЗапроса" Тогда ТипЗначения = Новый ОписаниеТипов("РезультатЗапроса"); КонецЕсли; СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ТипЗначения); КонецЦикла; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ПостроительЗапроса") И СтрокаОписанияВида.ИмяКоллекции = "Структура" Тогда // Вроде бы мертвая ветка, т.к. для свойства "Параметры" всегда передается готовая структура вместо построителя Для Каждого КлючИЗначение Из МетаданныеРодителя.Параметры Цикл СхемаКоллекции.Вставить(ДоступноеПоле.Имя, ДоступноеПоле.ТипЗначения); КонецЦикла; ИначеЕсли Ложь Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "ФиксированнаяСтруктура" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") Или ТипЗнч(МетаданныеРодителя) = Тип("ФиксированнаяСтруктура"))) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "НастройкаОформления" И ТипЗнч(МетаданныеРодителя) = Тип("НастройкаОформления")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Отбор" И ТипЗнч(МетаданныеРодителя) = Тип("Отбор")) Тогда КоллекцияЗначений = МетаданныеРодителя; // Теперь это делается в конце метода более универсально //ИначеЕсли Истина // И СтрокаОписанияВида.ИмяКоллекции = "Структура" // И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") // И ЗначениеЗаполнено(СловоФильтр) //Тогда // СхемаКоллекции.Вставить(СловоФильтр, МетаданныеРодителя); ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеКомпоновкиДанных") Или ТипЗнч(МетаданныеРодителя) = Тип("ДоступноеПолеОтбораКомпоновкиДанных")) Тогда Для Каждого ДоступноеПоле Из МетаданныеРодителя.Элементы Цикл СхемаКоллекции.Вставить(ирОбщий.ПоследнийФрагментЛкс("" + ДоступноеПоле.Поле), ДоступноеПоле.ТипЗначения); КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеРеквизиты" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Попытка ОбщиеРеквизиты = Метаданные.ОбщиеРеквизиты; Исключение // Платформа 8.2.13 и ниже ОбщиеРеквизиты = Новый Массив; КонецПопытки; СхемаКоллекции = Новый Массив(); Для Каждого ОбщийРеквизит Из ОбщиеРеквизиты Цикл Если ирОбщий.ЛиОбщийРеквизитИспользуетсяВОбъектеМетаданныхЛкс(ОбщийРеквизит, МетаданныеРодителя) Тогда СхемаКоллекции.Добавить(ОбщийРеквизит); КонецЕсли; КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Картинки" И ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда Если ЗначениеЗаполнено(СловоФильтр) Тогда МетаКартинка = Метаданные.ОбщиеКартинки.Найти(СловоФильтр); Если МетаКартинка <> Неопределено Тогда СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка); КонецЕсли; Иначе // Долго СхемаКоллекции = Новый Структура; Для Каждого МетаКартинка Из Метаданные.ОбщиеКартинки Цикл СхемаКоллекции.Вставить(МетаКартинка.Имя, МетаКартинка); КонецЦикла; КонецЕсли; ИначеЕсли Истина // И СтрокаОписанияВида.ИмяКоллекции = "Свойства" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектXDTO") Тогда КоллекцияЗначений = Новый Структура; ОбъектXDTO = МетаданныеРодителя; Для Каждого Свойство Из ОбъектXDTO.Свойства() Цикл Если Истина И ЗначениеЗаполнено(Свойство.Имя) //И ОбъектXDTO.Установлено(Свойство.Имя) Тогда Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя); Иначе ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя); КонецЕсли; КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства); КонецЕсли; КонецЦикла; ИначеЕсли Истина // И СтрокаОписанияВида.ИмяКоллекции = "Свойства" И ТипЗнч(МетаданныеРодителя) = Тип("ТипОбъектаXDTO") Тогда СхемаКоллекции = Новый Структура; Для Каждого Свойство Из МетаданныеРодителя.Свойства Цикл Если Не ЗначениеЗаполнено(Свойство.Имя) Тогда Продолжить; КонецЕсли; ТаблицаТиповСлова = Неопределено; Если ТипЗнч(Свойство.Тип) = Тип("ТипОбъектаXDTO") Тогда СтруктураТипаСлова = НоваяСтруктураТипа("ОбъектXDTO"); СтруктураТипаСлова.Метаданные = Свойство.Тип; ТаблицаТиповСлова = ДобавитьВТаблицуТипов(, СтруктураТипаСлова); Иначе ТипЗначения = СериализаторXDTO.ИзXMLТипа(Свойство.Тип.БазовыйТип.Имя, Свойство.Тип.БазовыйТип.URIПространстваИмен); Если ТипЗначения <> Неопределено Тогда ТаблицаТиповСлова = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗначения)); КонецЕсли; КонецЕсли; СхемаКоллекции.Вставить(Свойство.Имя, ТаблицаТиповСлова); КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" И ТипЗнч(МетаданныеРодителя) = Тип("СвойствоXDTO") И МетаданныеРодителя.ОбъектВладелец <> Неопределено Тогда КоллекцияЗначений = Новый Структура; ОбъектXDTO = МетаданныеРодителя.ОбъектВладелец; Свойство = МетаданныеРодителя; Если ОбъектXDTO.Установлено(Свойство.Имя) Тогда Если Свойство.ВерхняяГраница > 1 Или Свойство.ВерхняяГраница = -1 Тогда ЗначениеСвойства = ОбъектXDTO.ПолучитьСписок(Свойство.Имя); Иначе ЗначениеСвойства = ОбъектXDTO.Получить(Свойство.Имя); КонецЕсли; КоллекцияЗначений.Вставить(Свойство.Имя, ЗначениеСвойства); КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Параметры" И ТипЗнч(МетаданныеРодителя) = Тип("ТабличныйДокумент") И МетаданныеРодителя.ВысотаТаблицы * МетаданныеРодителя.ШиринаТаблицы < 20000 Тогда КоллекцияЗначений = Новый Структура; СписокПараметров = ирОбщий.ПараметрыТабличногоДокументаЛкс(МетаданныеРодителя); Для Каждого ЭлементСписка Из СписокПараметров Цикл Попытка КоллекцияЗначений.Вставить(ЭлементСписка.Значение); Исключение // Имена параметров могут содержать запрещенные символы КонецПопытки; КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") Или ТипЗнч(МетаданныеРодителя) = Тип("ДеревоЗначений")) Тогда СхемаКоллекции = МетаданныеРодителя.Колонки; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда ПолноеИмяМД = МетаданныеРодителя.ПолноеИмя(); Если Ложь Или Найти(ПолноеИмяМД, "Обработка.") Или Найти(ПолноеИмяМД, "Отчет.") Тогда Для Каждого ОбъектМетаданныхРеквизит Из МетаданныеРодителя.Реквизиты Цикл СхемаКоллекции.Вставить(ОбъектМетаданныхРеквизит.Имя, ОбъектМетаданныхРеквизит); КонецЦикла; // TODO Пока дальше тип не дозревает Мультиметка240813_080918 Для Каждого ОбъектМетаданныхТабличнаяЧасть Из МетаданныеРодителя.ТабличныеЧасти Цикл СхемаКоллекции.Вставить(ОбъектМетаданныхТабличнаяЧасть.Имя, ОбъектМетаданныхТабличнаяЧасть); КонецЦикла; Иначе СхемаКоллекции = ирКэш.ПоляТаблицыБДЛкс(ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД), Истина); КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Свойства" // коллекция упр. формы И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И ирОбщий.СвойствоСтруктурыЛкс(МетаданныеРодителя, "Тип") <> ирОбщий.ТипУправляемаяФормаЛкс() Тогда СхемаКоллекции = МетаданныеРодителя; #Если Клиент Тогда ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Форма") Тогда КоллекцияЗначений = МетаданныеРодителя[РодительскаяСтруктураТипа.СтрокаОписания.Слово]; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты" И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя) Тогда Если ЗначениеЗаполнено(СловоФильтр) Тогда ИмитаторФормы = МетаданныеРодителя; Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда Попытка ЗначениеРеквизита = МетаданныеРодителя[СловоФильтр]; Исключение ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя); КонецПопытки; КонецЕсли; Если ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда СтруктураИмен = ИменаРеквизитовФормы(ИмитаторФормы, "").Все; Если СтруктураИмен.Свойство(СловоФильтр) Тогда ЗначениеСлова = СтруктураИмен[СловоФильтр]; СхемаКоллекции.Вставить(СловоФильтр, ЗначениеСлова); ИначеЕсли Не ЛиВместеСЛокальнымКонтекстом Тогда ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Реквизит:" + СловоФильтр); КонецЕсли; Иначе // Для ускорения особенно для управляемой формы КоллекцияЗначений = Новый Структура; Попытка ЗначениеРеквизита = МетаданныеРодителя[СловоФильтр]; Исключение ЗначениеРеквизита = Null; КонецПопытки; Если Истина И ЗначениеРеквизита <> Null И ТипЗнч(МетаданныеРодителя) = Тип("Форма") И Не ИменаРеквизитовФормы(ИмитаторФормы, "").Все.Свойство(СловоФильтр) Тогда // Это реквизит объекта, а не формы ЗначениеРеквизита = Null; КонецЕсли; Если ЗначениеРеквизита <> Null Тогда КоллекцияЗначений.Вставить(СловоФильтр, ЗначениеРеквизита); КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(МетаданныеРодителя) = Тип("Форма") Тогда ПутьКРодителю = Неопределено; Иначе ПутьКРодителю = ""; КонецЕсли; СтруктураИмен = ИменаРеквизитовФормы(МетаданныеРодителя, ПутьКРодителю).Все; Если ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда СхемаКоллекции = СтруктураИмен; Иначе КоллекцияЗначений = Новый Структура; Для Каждого КлючИЗначение Из СтруктураИмен Цикл Попытка ЗначениеРеквизита = МетаданныеРодителя[КлючИЗначение.Ключ]; Исключение Если КлючИЗначение.Значение <> Неопределено Тогда // Добавленный реквизит был получен через буфер обмена, но пока отсутствует в натуральной форме ЗначениеРеквизита = ТаблицаТиповИзОписанияТипов(КлючИЗначение.Значение); Иначе ЗначениеРеквизита = Неопределено; КонецЕсли; КонецПопытки; КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеРеквизита); КонецЦикла; КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Реквизиты" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") И ТипЗнч(РодительскаяСтруктураТипа.Метаданные) = Тип("Форма") И ЗначениеЗаполнено(СловоФильтр) И Метаданные.Обработки.Индекс(МетаданныеРодителя) <> -1 И МетаданныеРодителя.Реквизиты.Найти(СловоФильтр) <> Неопределено Тогда // Нужно для подготовки реквизита обработки, видимой в ее форме (Обработка.ирКонсольЗапросов.Реквизит.ДеревоЗапросов) Попытка ЗначениеРеквизита = РодительскаяСтруктураТипа.Метаданные[СловоФильтр]; Исключение ЗначениеРеквизита = Неопределено; КонецПопытки; Если ЗначениеРеквизита <> Неопределено Тогда КоллекцияЗначений = Новый Структура(СловоФильтр, ЗначениеРеквизита); Иначе СхемаКоллекции = МетаданныеРодителя.Реквизиты; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "Команды" И ирОбщий.ЛиФормаИлиИмитаторЛкс(РодительскаяСтруктураТипа.ДержательМетаданных, Ложь) Тогда Форма = РодительскаяСтруктураТипа.ДержательМетаданных; СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Если СлужебныеДанные <> Неопределено И СлужебныеДанные.Свойство("Команды") Тогда СхемаКоллекции = СлужебныеДанные.Команды; Если ЗначениеЗаполнено(СловоФильтр) И Не СхемаКоллекции.Свойство(СловоФильтр) Тогда ДобавитьОтсутствиеЭлементаФормы(Форма, "Команда:" + СловоФильтр); КонецЕсли; Иначе Если ТипЗнч(Форма) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда СхемаКоллекции = Форма.Команды; КонецЕсли; КонецЕсли; ИначеЕсли Истина И ИмяОбщегоТипаРодителя = "ДанныеФормыСтруктура" И ТипЗнч(РодительскаяСтруктураТипа.СтрокаОписания) = Тип("СтрокаТаблицыЗначений") И РодительскаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "ФормаКлиентскогоПриложения" И РодительскаяСтруктураТипа.СтрокаОписания.Слово = "Параметры" Тогда СхемаКоллекции = СхемаКоллекцииПараметровФормы(РодительскаяСтруктураТипа, СловоФильтр); ИначеЕсли ирОбщий.ЛиДанныеФормыССериализациейЛкс(МетаданныеРодителя) Тогда Форма = РодительскаяСтруктураТипа.ДержательМетаданных; ЛиКоллекция = Ложь Или ирОбщий.ЛиКоллекцияЛкс(МетаданныеРодителя) Или ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыДерево"); СтруктураИмен = ДочерниеСвойстваДанныхФормы(МетаданныеРодителя, ЛиКоллекция, Форма, СловоФильтр); СхемаКоллекции = СтруктураИмен; Если Не ЛиКоллекция Тогда Для Каждого КлючИЗначение Из СтруктураИмен Цикл ЗначениеСвойства = КлючИЗначение.Значение; // ОписаниеТипов, см. НоваяТаблицаТипов Если ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений") Тогда // ИначеЕсли Истина И ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") И ЗначениеСвойства.Типы().Количество() > 0 Тогда ЗначениеСвойства = ТаблицаТиповИзОписанияТипов(ЗначениеСвойства); Иначе Попытка ЗначениеСвойства = МетаданныеРодителя[КлючИЗначение.Ключ]; Исключение // Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/985380 ЗначениеСвойства = Неопределено; КонецПопытки; ЗначениеСвойства = ТаблицаТиповИзЗначения(ЗначениеСвойства); // Мультиметка250303_191432 КонецЕсли; ЗначениеСвойства.ЗаполнитьЗначения(Форма, "ДержательМетаданных"); Если КоллекцияЗначений = Неопределено Тогда КоллекцияЗначений = Новый Структура; КонецЕсли; КоллекцияЗначений.Вставить(КлючИЗначение.Ключ, ЗначениеСвойства); КонецЦикла; КонецЕсли; ИначеЕсли Истина И ИмяОбщегоТипаРодителя = "ЭлементыФормы" И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И ТипЗнч(РодительскаяСтруктураТипа.СтрокаОписания) = Тип("СтрокаТаблицыЗначений") И РодительскаяСтруктураТипа.СтрокаОписания.ТипКонтекста = "Форма" Тогда СхемаКоллекции = МетаданныеРодителя; ИначеЕсли Ложь Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "ЭлементыФормы" И ТипЗнч(МетаданныеРодителя) = Тип("Форма")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Элементы" И ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь)) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Страницы" И ТипЗнч(МетаданныеРодителя) = Тип("Панель")) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Колонки" И (Ложь //Или ТипЗнч(МетаданныеРодителя) = Тип("КолонкиТабличногоПоля") Или ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле"))) Или (Истина И СтрокаОписанияВида.ИмяКоллекции = "Кнопки" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкаКоманднойПанели") //Или ТипЗнч(МетаданныеРодителя) = Тип("КнопкиКоманднойПанели") Или ТипЗнч(МетаданныеРодителя) = Тип("КоманднаяПанель"))) Тогда СловаКонтекстаМетаданныеФормы(СловоФильтр, ИмяОбщегоТипаРодителя, МетаданныеРодителя, СтрокаОписанияВида, КоллекцияЗначений, СхемаКоллекции); ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "ПодчиненныеЭлементы" Тогда ФормаИлиИмитатор = РодительскаяСтруктураТипа.ДержательМетаданных; Если ФормаИлиИмитатор = Неопределено Тогда ФормаИлиИмитатор = МетаданныеРодителя; КонецЕсли; Если ирОбщий.ЛиФормаИлиИмитаторЛкс(ФормаИлиИмитатор, Ложь) Тогда ЭлементыФормы = Неопределено; Если ТипЗнч(ФормаИлиИмитатор) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда ЭлементыФормы = ФормаИлиИмитатор.Элементы; КонецЕсли; КоллекцияЗначений = Новый Структура; СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиИмитатор); Если СлужебныеДанные.Свойство("Элементы") Тогда Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Ложь) Тогда ИмяРодителя = Неопределено; Иначе ИмяРодителя = МетаданныеРодителя.Имя; КонецЕсли; ИмитаторыЭлементов = ирОбщий.ОтобратьКоллекциюЛкс(СлужебныеДанные.Элементы, "Э.Значение.ИмяРодителя = П1", "Э.Значение", ИмяРодителя); Для Каждого СтруктураЭлемента Из ИмитаторыЭлементов Цикл ДочернийЭлемент = Неопределено; Если ЭлементыФормы <> Неопределено Тогда ДочернийЭлемент = ЭлементыФормы.Найти(СтруктураЭлемента.Имя); КонецЕсли; Если ДочернийЭлемент = Неопределено Тогда СхемаКоллекции["_"] = 1; // Чтобы описания типов в значении считались как тип элемента ДочернийЭлемент = ТаблицаТиповИзИмитатораЭлементаФормы(СтруктураЭлемента, ИмитаторФормы, СловоФильтр); КонецЕсли; КоллекцияЗначений.Вставить(СтруктураЭлемента.Имя, ДочернийЭлемент); КонецЦикла; КонецЕсли; КонецЕсли; #КонецЕсли ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("НаборыДанныхСхемыКомпоновкиДанных") Тогда КоллекцияЗначений = МетаданныеРодителя; //ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Оформление" Тогда // Для Каждого МетаОбщийМодуль Из МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции] Цикл // Если МетаОбщийМодуль.Глобальный Тогда // Продолжить; // КонецЕсли; // СхемаКоллекции.Вставить(МетаОбщийМодуль.Имя); // КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ОбщиеМодули" И ИмяОбщегоТипаРодителя = "Глобальный" И ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") // Тогда СхемаКоллекции = ирКэш.ДоступныеОбщиеМодулиЛкс(НаСервере, КлиентОбычноеПриложение, КлиентУправляемоеПриложение); Если мДобавленныеОбщиеМодули.Количество() > 0 Тогда СхемаКоллекции = ирОбщий.СкопироватьКоллекциюЛкс(СхемаКоллекции); // Структура ирОбщий.СкопироватьКоллекциюЛкс(мДобавленныеОбщиеМодули, СхемаКоллекции); КонецЕсли; Если Прав(СловоФильтр, 1) = "_" Тогда ЭтоГруппаОбщихМодулей = Истина; НачальныйФрагмент = НРег(ирОбщий.СтрокаБезКонцаЛкс(СловоФильтр)); СловоФильтр = Неопределено; ТаблицаСлов.Очистить(); НоваяСхема = Новый Структура; Для Каждого КлючИЗначение Из СхемаКоллекции Цикл Если Не ирОбщий.СтрНачинаетсяСЛкс(КлючИЗначение.Ключ, НачальныйФрагмент) Тогда Продолжить; КонецЕсли; ОстатокИмени = Сред(КлючИЗначение.Ключ, СтрДлина(НачальныйФрагмент) + 1); Если СтрДлина(ОстатокИмени) > 1 И ВРег(Лев(ОстатокИмени, 2)) = Лев(ОстатокИмени, 2) Тогда Продолжить; КонецЕсли; НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; Если НоваяСхема.Количество() > МаксРазмерТаблицыТиповДляЗаполненияТаблицыСлов() Тогда НоваяСхема.Очистить(); КонецЕсли; СхемаКоллекции = НоваяСхема; ИначеЕсли Не ЗначениеЗаполнено(СловоФильтр) Тогда СписокЗначений = Новый СписокЗначений; НоваяСхема = Новый Структура; Для Каждого КлючИЗначение Из СхемаКоллекции Цикл СписокЗначений.Добавить(КлючИЗначение.Значение, КлючИЗначение.Ключ); НоваяСхема.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; СписокЗначений.СортироватьПоПредставлению(); СхемаКоллекции = НоваяСхема; ИмяГруппы = Неопределено; ЧленыГруппы = Новый Массив; ГруппыМодулей = Новый Структура; РегВыражение = мРегВыражение; РегВыражение.Global = Ложь; РегВыражение.IgnoreCase = Ложь; РегВыражение.Pattern = "(.+?)(?:Вызов|Клиент|Сервер|ПовтИсп|Кэш)"; Для Каждого МодульМД Из СписокЗначений.ВыгрузитьЗначения() Цикл Найденные = РегВыражение.НайтиВхождения(МодульМД.Имя); Если Найденные.Количество() > 0 Тогда ИмяГруппы = Найденные[0].SubMatches(0); Если ГруппыМодулей.Свойство(ИмяГруппы) Тогда ГруппыМодулей[ИмяГруппы] = 2; Иначе ГруппыМодулей.Вставить(ИмяГруппы, 1); КонецЕсли; КонецЕсли; КонецЦикла; РегВыражение.IgnoreCase = Истина; Для Каждого КлючИЗначение Из ГруппыМодулей Цикл Если Ложь Или КлючИЗначение.Значение > 1 Или СхемаКоллекции.Свойство(КлючИЗначение.Ключ) Тогда СхемаКоллекции.Вставить(КлючИЗначение.Ключ + "_"); КонецЕсли; КонецЦикла; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ВидыСубконто" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда //! МетаданныеРодителя = 0; // ОбъектМетаданныхРегистрБухгалтерии Для Счетчик = 1 По МетаданныеРодителя.ПланСчетов.МаксКоличествоСубконто Цикл СхемаКоллекции.Вставить(Строка(Счетчик), МетаданныеРодителя.ПланСчетов.ВидыСубконто); КонецЦикла; ИначеЕсли СтрокаОписанияВида.ИмяКоллекции = "Движения" Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда //! МетаданныеРодителя = 0; // ОбъектМетаданныхДокумент Для Каждого МетаРегистр Из МетаданныеРодителя.Движения Цикл МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаРегистр.ПолноеИмя()); СхемаКоллекции.Вставить(МетаРегистр.Имя, Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1])); КонецЦикла; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияДвижений") Тогда Для Каждого НаборЗаписейРегистра Из МетаданныеРодителя Цикл // РегистрСведенийНаборЗаписей.КурсыВалют СхемаКоллекции.Вставить(НаборЗаписейРегистра.Метаданные().Имя, НаборЗаписейРегистра); КонецЦикла; ИначеЕсли Истина И СловоФильтр <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") // Тогда МетаданныеРегистра = Метаданные.РегистрыСведений.Найти(СловоФильтр); Если МетаданныеРегистра = Неопределено Тогда МетаданныеРегистра = Метаданные.РегистрыНакопления.Найти(СловоФильтр); КонецЕсли; Если МетаданныеРегистра = Неопределено Тогда МетаданныеРегистра = Метаданные.РегистрыБухгалтерии.Найти(СловоФильтр); КонецЕсли; Если МетаданныеРегистра = Неопределено Тогда МетаданныеРегистра = Метаданные.РегистрыРасчета.Найти(СловоФильтр); КонецЕсли; Если МетаданныеРегистра <> Неопределено Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(МетаданныеРегистра.ПолноеИмя()); СхемаКоллекции.Вставить(МассивФрагментов[1], Новый ОписаниеТипов(МассивФрагментов[0] + "НаборЗаписей." + МассивФрагментов[1])); КонецЕсли; КонецЕсли; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "БазовыеВидыРасчета" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Для Каждого БазовыйПлан Из МетаданныеРодителя.ПланВидовРасчета.БазовыеВидыРасчета Цикл Для Каждого БазовыйРегистрРасчета Из Метаданные.РегистрыРасчета Цикл Если БазовыйРегистрРасчета.ПланВидовРасчета = БазовыйПлан Тогда СхемаКоллекции.Вставить(БазовыйРегистрРасчета.Имя, БазовыйРегистрРасчета); КонецЕсли; КонецЦикла; КонецЦикла; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "ТочкиМаршрута" И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда КоллекцияЗначений = ирОбщий.ПолучитьМенеджерЛкс(МетаданныеРодителя)[СтрокаОписанияВида.ИмяКоллекции]; ИначеЕсли Истина И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Или ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Или ТипЗнч(МетаданныеРодителя) = Тип("Неопределено")) Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("КоллекцияОбъектовМетаданных") Тогда КоллекцияЗначений = МетаданныеРодителя; Иначе ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииМетаданных, , Ложь); Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных); Если СтрокаКорневогоТипа <> Неопределено Тогда ПроверяемыеМетаданные = ?(МетаданныеРодителя = Неопределено, мМетаданные, МетаданныеРодителя); //КоллекцияЗначений = ПроверяемыеМетаданные[ИмяКоллекцииОбъектовМетаданных]; Попытка КоллекцияЗначений = ПроверяемыеМетаданные[РодительскаяСтруктураТипа.СтрокаОписания.Слово]; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); // Для отладки КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли Истина //И СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" И ЭтоИнтеграция И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.КонфигурацииМетаданныхИис") Или ТипЗнч(МетаданныеРодителя) = Тип("СправочникСсылка.МетаданныеИис")) Тогда Если СтрокаОписанияВида.ИмяКоллекции = "<Имя коллекции метаданных>" Тогда ИмяКоллекцииОбъектовМетаданных = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииМетаданных, , Ложь); Иначе ИмяКоллекцииОбъектовМетаданных = СтрокаОписанияВида.ИмяКоллекции; КонецЕсли; Если ЗначениеЗаполнено(ИмяКоллекцииОбъектовМетаданных) Тогда СтрокаКорневогоТипа = ОписаниеТипаМетаОбъектов(, ИмяКоллекцииОбъектовМетаданных); Запрос = Новый Запрос; Если СтрокаКорневогоТипа <> Неопределено Тогда //лИмяКоллекции = РодительскаяСтруктураТипа.СтрокаОписания.Слово; Если ИмяКоллекцииОбъектовМетаданных = "Реквизиты" Тогда ТекстЗапроса = "ВЫБРАТЬ Наименование КАК Имя, Типы Как Значение ИЗ Справочник.СвойстваМетаданныхИис |ГДЕ КонфигурацияМетаданных = &Владелец И Вид <> ЗНАЧЕНИЕ(Перечисление.ВидыСвойствМетаданныхИис.Свойство)"; Запрос.Текст = ТекстЗапроса; Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл СхемаКоллекции[Выборка.Имя] = Выборка.Значение.Выгрузить().ВыгрузитьКолонку("Тип"); КонецЦикла; Иначе ТекстЗапроса = "ВЫБРАТЬ Имя, Ссылка КАК Значение ИЗ Справочник.МетаданныеИис |ГДЕ КонфигурацияМетаданных = &Владелец И ТипМетаданных.ИмяМножественное = &ИмяРодителя"; Запрос.УстановитьПараметр("ИмяРодителя", ИмяКоллекцииОбъектовМетаданных); Запрос.Текст = ТекстЗапроса; Запрос.УстановитьПараметр("Владелец", МетаданныеРодителя); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл СхемаКоллекции[Выборка.Имя] = Выборка.Значение; КонецЦикла; КонецЕсли; КонецЕсли; Иначе //КоллекцияЗначений = МетаданныеРодителя; КонецЕсли; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("ОбщийМодуль") Тогда // Платформа пока не дает узнать имя модуля Иначе Если мМассивИсключенийИменКоллекций.НайтиПоЗначению(СтрокаОписанияВида.ИмяКоллекции) <> Неопределено Тогда Продолжить; КонецЕсли; СхемаКоллекции = МетаданныеРодителя; Если ТипЗнч(МетаданныеРодителя) <> Тип("КоллекцияОбъектовМетаданных") Тогда ЦелевойТип = Неопределено; Если Найти(СтрокаОбщегоТипа.ИмяОбщегоТипа, "<") = 0 Тогда Попытка ЦелевойТип = Тип(СтрокаОбщегоТипа.ИмяОбщегоТипа); Исключение КонецПопытки; КонецЕсли; Если ТипЗнч(МетаданныеРодителя) = ЦелевойТип Тогда СхемаКоллекции = МетаданныеРодителя; Иначе ПроверяемыеМетаданные = ?(МетаданныеРодителя = Неопределено, мМетаданные, МетаданныеРодителя); Попытка СхемаКоллекции = ПроверяемыеМетаданные[СтрокаОписанияВида.ИмяКоллекции]; Исключение Продолжить; КонецПопытки; КонецЕсли; КонецЕсли; КонецЕсли; Если КоллекцияЗначений = Неопределено Тогда КоллекцияЗначений = СхемаКоллекции; Если СловоФильтр <> Неопределено Тогда ЭлементСхемы = Неопределено; Если Ложь Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированнаяСтруктура") Или ТипЗнч(КоллекцияЗначений) = Тип("ФиксированноеСоответствие") Или ТипЗнч(КоллекцияЗначений) = Тип("Структура") Или ТипЗнч(КоллекцияЗначений) = Тип("Соответствие") Тогда //Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл // Если ЭлементКоллекции.Ключ = ИмяТекущегоСлова Тогда // ЭлементСхемы = ЭлементКоллекции.Значение; // Прервать; // КонецЕсли; //КонецЦикла; Попытка ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова]; Исключение КонецПопытки; Иначе ЭлементСхемы = Null; Если ТипЗнч(КоллекцияЗначений) <> Тип("Массив") Тогда Попытка ЭлементСхемы = КоллекцияЗначений.Найти(ИмяТекущегоСлова); Исключение КонецПопытки; КонецЕсли; Если ЭлементСхемы = Null Тогда ЭлементСхемы = Неопределено; Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл Если ЭлементКоллекции.Имя = ИмяТекущегоСлова Тогда ЭлементСхемы = ЭлементКоллекции; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; КоллекцияЗначений = Новый Соответствие; Если ЭлементСхемы <> Неопределено Тогда КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы); КонецЕсли; КонецЕсли; Иначе Если СловоФильтр <> Неопределено Тогда Попытка ЭлементСхемы = КоллекцияЗначений[ИмяТекущегоСлова]; Исключение ЭлементСхемы = Null; КонецПопытки; КоллекцияЗначений = Новый Соответствие; Если ЭлементСхемы <> Null Тогда КоллекцияЗначений.Вставить(ИмяТекущегоСлова, ЭлементСхемы); КонецЕсли; КонецЕсли; КонецЕсли; Если КоллекцияЗначений = Неопределено Тогда КоллекцияЗначений = Новый Массив(); КонецЕсли; //! СхемаКоллекции = Неопределено; // Соответствие, Структура ЭтоСубконто = Найти(СтрокаСлова.Слово, "Субконто") = 1; ПредыдущаяТаблицаТипов = Неопределено; ВычислятьТипыЦикл = ВычислятьТипы Или КоллекцияЗначений.Количество() < 100; Если ЗначениеЗаполнено(СтрокаСлова.ТипЗначения) Тогда ТипЗначенияСлова = ", " + СтрокаСлова.ТипЗначения; ТипЗначенияСлова = СтрЗаменить(ТипЗначенияСлова, ", Произвольный", ""); Иначе ТипЗначенияСлова = ""; КонецЕсли; Для Каждого ЭлементКоллекции Из КоллекцияЗначений Цикл Если ЭлементКоллекции = Неопределено Тогда // ПараметрыМакетаТабличногоДокумента Продолжить; КонецЕсли; Если ТипЗнч(ЭлементКоллекции) = Тип("КлючИЗначение") Тогда ИмяСвойства = ЭлементКоллекции.Ключ; ЗначениеСвойства = ЭлементКоллекции.Значение; Иначе ИмяСвойства = ЭлементКоллекции.Имя; ЗначениеСвойства = ЭлементКоллекции; КонецЕсли; КонечноеСлово = СтрЗаменить(СтрокаСлова.Слово, ИмяЭлементаКоллекции, ИмяСвойства); ТаблицаТипов = Неопределено; Если ВычислятьТипыЦикл Тогда Если ЭтоСубконто И ПредыдущаяТаблицаТипов <> Неопределено Тогда ТаблицаТипов = ПредыдущаяТаблицаТипов; ИначеЕсли Истина И ТипЗнч(ЗначениеСвойства) = Тип("ТаблицаЗначений") И ЗначениеСвойства.Количество() > 0 И ЗначениеСвойства.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено //И ЗначениеСвойства.Колонки.Найти("ИмяОбщегоТипа") <> Неопределено Тогда ТаблицаТипов = ЗначениеСвойства; Иначе ТаблицаТипов = НоваяТаблицаТипов(); ПредыдущаяТаблицаТипов = ТаблицаТипов; МассивТипов = Новый Массив; Квалификаторы = Неопределено; ОписаниеТиповЗначения = Неопределено; Если Истина И РодительскаяСтруктураТипа.ТипЯзыка <> "ИмяТипа" И СхемаКоллекции.Количество() > 0 И (Ложь Или СтрокаСлова.ТипЗначения = "" Или Найти(СтрокаСлова.ТипЗначения + ",", "Произвольный,") > 0 Или СтрокаСлова.ТипЗначения = "Набор записей регистра" Или Найти(СтрокаСлова.ТипЗначения, "<") > 0 Или ЛиТипСКвалификаторами) Тогда Если ТипЗнч(ЗначениеСвойства) = Тип("ОписаниеТипов") Тогда ОписаниеТиповЗначения = ЗначениеСвойства; КонецЕсли; Если Истина И ЯзыкПрограммы = 1 И РодительскаяСтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе" //И КорневойТипРодителя <> Неопределено //И КорневойТипРодителя <> "ВнешнийИсточникДанных" И СтрокаСлова.Слово <> "<Имя перерасчета>" И СтрокаСлова.Слово <> "База<Имя базового регистра расчета>" И ПостроительЗапросаРодителя <> Неопределено Тогда ДоступноеПолеСлова = ПостроительЗапросаРодителя.ДоступныеПоля.Найти(НРег(КонечноеСлово)); Если ДоступноеПолеСлова = Неопределено Тогда Продолжить; КонецЕсли; Если ДоступноеПолеСлова.ТипЗначения <> Новый ОписаниеТипов("ТаблицаЗначений") Тогда ОписаниеТиповЗначения = ДоступноеПолеСлова.ТипЗначения; КонецЕсли; КонецЕсли; Если Истина И ОписаниеТиповЗначения = Неопределено И СтрокаОписанияВида.ИмяКоллекции <> "КритерииОтбора" И СтрокаОписанияВида.ИмяКоллекции <> "ПланыВидовХарактеристик" И ИмяОбщегоТипаРодителя <> "Константа" Тогда СвойстваСТипом = Новый Структура("Тип, ТипЗначения"); Попытка ЗаполнитьЗначенияСвойств(СвойстваСТипом, ЗначениеСвойства); // Длительность равна одному выбросу исключения Исключение // Не объектное значение КонецПопытки; Если ТипЗнч(СвойстваСТипом.Тип) = Тип("ОписаниеТипов") Тогда ОписаниеТиповЗначения = СвойстваСТипом.Тип; ИначеЕсли ТипЗнч(СвойстваСТипом.ТипЗначения) = Тип("ОписаниеТипов") Тогда ОписаниеТиповЗначения = СвойстваСТипом.ТипЗначения; КонецЕсли; Если Истина И ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных") И ОписаниеТиповЗначения <> Неопределено Тогда ИмяВложенногоТипа = ЗначениеСвойства.Комментарий; Если ОписаниеТиповЗначения.Типы().Количество() = 0 Тогда // реквизит обработки с типом Произвольный ИмяТипа = ирОбщий.ПервыйФрагментЛкс(ИмяВложенногоТипа, " "); // Типизация реквизита из свойства "Комментарий" Фрагменты = ирОбщий.СтрРазделитьЛкс(ИмяТипа, ":", Истина); Попытка ОписаниеТиповЗначения = Новый ОписаниеТипов(Фрагменты[0]); Исключение // КонецПопытки; Если Фрагменты.Количество() > 1 Тогда ИмяВложенногоТипа = Фрагменты[1]; КонецЕсли; КонецЕсли; Если Ложь Или ОписаниеТиповЗначения.СодержитТип(Тип("ХранилищеЗначения")) Или ОписаниеТиповЗначения.СодержитТип(Тип("Строка")) И ОписаниеТиповЗначения.КвалификаторыСтроки.Длина = 0 Тогда ЕстьВложенныйТип = ЛиВСтрокеТиповЕстьКонструктор(ИмяВложенногоТипа); Если Не ЕстьВложенныйТип Тогда ИмяВложенногоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяВложенногоТипа, " "); // Типизация реквизита из свойства "Комментарий" Попытка ТипВложенный = Тип(ИмяВложенногоТипа); ЕстьВложенныйТип = Истина; Исключение КонецПопытки; КонецЕсли; Если ЕстьВложенныйТип Тогда ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТиповЗначения); ТаблицаТипов[0].Метаданные = ирКэш.ПолеТекстаПрограммы(0).ТаблицаТиповИзТекста(ИмяВложенногоТипа)[0].Метаданные; ОписаниеТиповЗначения = Неопределено; МассивТипов.Очистить(); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ТипЗнч(ОписаниеТиповЗначения) = Тип("ОписаниеТипов") Тогда МассивТипов = ОписаниеТиповЗначения.Типы(); Квалификаторы = ОписаниеТиповЗначения; ИначеЕсли ТипЗнч(ЗначениеСвойства) = Тип("Массив") Тогда МассивТипов = ЗначениеСвойства; КонецЕсли; КонецЕсли; Если Истина И МассивТипов.Количество() = 0 И (Ложь Или СхемаКоллекции.Количество() = 0 //Или ОписаниеТиповЗначения = Неопределено И СтрокаСлова.ТипЗначения = "Произвольный" ) Тогда МассивТипов.Добавить(ТипЗнч(ЗначениеСвойства)); КонецЕсли; ПередаватьМетаданныеСвойства = ТипЗнч(ЗначениеСвойства) = Тип("ОбъектМетаданных") И СтрокаСлова.ТипСлова = ПеречТипСлова.Свойство; Если Истина //И ОписаниеТиповЗначения <> Неопределено И МассивТипов.Количество() > 0 И СтрокаОписанияВида.ИмяКоллекции <> "<Имя коллекции метаданных>" И (Ложь Или СтрокаОписанияВида.ИмяКоллекции <> "Константы" Или ЯзыкПрограммы = 1) Тогда ШаблонСтруктурыТипа = Новый Структура("СтрокаОписания, ТипЯзыка, Метаданные, МетаданныеСвойства, ДержательМетаданных, Квалификаторы"); ШаблонСтруктурыТипа.СтрокаОписания = СтрокаСлова; ШаблонСтруктурыТипа.ТипЯзыка = РодительскаяСтруктураТипа.ТипЯзыка; Если ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя) Тогда ШаблонСтруктурыТипа.ДержательМетаданных = МетаданныеРодителя; Иначе ШаблонСтруктурыТипа.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; КонецЕсли; ШаблонСтруктурыТипа.Квалификаторы = Квалификаторы; //ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя; ПередаватьМетаданные = Ложь Или МассивТипов.Количество() <> 1 Или МассивТипов[0] <> Тип("ТаблицаЗначений"); ПередаватьМетаданныеРодителя = Истина И ИмяОбщегоТипаРодителя <> "ВсеЭлементыФормы" // Иначе в метаданные элемента формы запишется имитатор формы И ИмяОбщегоТипаРодителя <> "СтрокаДереваЗначений" И ИмяОбщегоТипаРодителя <> "СтрокаТаблицыЗначений" // Иначе у таблицы вложенной в другую таблицу будут наследоваться колонки И НЕ (ИмяОбщегоТипаРодителя = "Структура" И ТипЗнч(МетаданныеРодителя) = Тип("Структура")) //И (Ложь // У этого типа бывают свои метаданные Мультиметка62766134 // Или МассивТипов.Количество() <> 1 // Или МассивТипов[0] <> Тип("Строка")) ; Если ПередаватьМетаданныеСвойства Тогда ШаблонСтруктурыТипа.МетаданныеСвойства = ЗначениеСвойства; КонецЕсли; Если МассивТипов.Количество() > МаксЧислоТиповДляАнализа Тогда СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(МассивТипов[0], ЯзыкПрограммы, ШаблонСтруктурыТипа); СтруктураОбщегоТипа = НоваяСтруктураТипа(СтруктураТипаСвойства.ИмяОбщегоТипа); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураОбщегоТипа); Иначе МассивНакопления = Новый Массив; Для Каждого Тип Из МассивТипов Цикл Если Истина И Тип = ТипЗнч(ЗначениеСвойства) //И (Ложь // Или мМассивТиповСМетаданными.Найти(Тип) <> Неопределено // Или мМассивТиповЭлементовОбычнойФормы.Найти(Тип) <> Неопределено) Тогда МетаданныеЭлемента = МетаданныеЭлементов[ИмяСвойства]; Если МетаданныеЭлемента = Неопределено Тогда МетаданныеЭлемента = ЗначениеСвойства; КонецЕсли; ШаблонСтруктурыТипа.Метаданные = МетаданныеЭлемента; СтруктураТипаСвойства = СтруктураТипаИзЗначения(ЗначениеСвойства, ЯзыкПрограммы, ШаблонСтруктурыТипа); Иначе Если ПередаватьМетаданные Тогда Если ПередаватьМетаданныеСвойства Тогда ШаблонСтруктурыТипа.Метаданные = ЗначениеСвойства; ИначеЕсли ПередаватьМетаданныеРодителя Тогда ШаблонСтруктурыТипа.Метаданные = МетаданныеРодителя; КонецЕсли; КонецЕсли; СтруктураТипаСвойства = СтруктураТипаИзКонкретногоТипа(Тип, ЯзыкПрограммы, ШаблонСтруктурыТипа); КонецЕсли; МассивНакопления.Добавить(СтруктураТипаСвойства); КонецЦикла; ДобавитьВТаблицуТипов(ТаблицаТипов, МассивНакопления); КонецЕсли; Иначе СтруктураТипаСвойства = НоваяСтруктураТипа(); ЗаполнитьЗначенияСвойств(СтруктураТипаСвойства, РодительскаяСтруктураТипа, "ТипЯзыка"); Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда СтруктураТипаСвойства.ДержательМетаданных = МетаданныеРодителя; Иначе СтруктураТипаСвойства.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; КонецЕсли; Если РодительскаяСтруктураТипа.ТипЯзыка = "ИмяТипа" Тогда СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаСлова.Слово; Если СтрокаСлова.ТипКонтекста <> "" Тогда СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаСлова.ТипКонтекста + "." + СтруктураТипаСвойства.ИмяОбщегоТипа; КонецЕсли; Иначе СтруктураТипаСвойства.ИмяОбщегоТипа = СтрокаСлова.ТипЗначения; СтруктураТипаСвойства.СтрокаОписания = СтрокаСлова; КонецЕсли; СтруктураТипаСвойства.Метаданные = ЗначениеСвойства; //Если ПустаяСтрока(СтруктураТипаСвойства.ИмяОбщегоТипа) Тогда //КонецЕсли; Если ПередаватьМетаданныеСвойства Тогда СтруктураТипаСвойства.МетаданныеСвойства = ЗначениеСвойства; КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаСвойства); КонецЕсли; КонецЕсли; Иначе // КонецЕсли; ДобавитьВТаблицуСлов(ТаблицаСлов, КонечноеСлово, СтрокаСлова.ТипСлова, ТаблицаТипов, "??" + ТипЗначенияСлова, "Метаданные",,,,, ТипЗначенияСлова); КонецЦикла; Если ЭтоГруппаОбщихМодулей Тогда Прервать; КонецЕсли; КонецЦикла; Если ЭтоГруппаОбщихМодулей Тогда Прервать; КонецЕсли; // Модуль Если Истина И Не ирОбщий.СтрНачинаетсяСЛкс(СтрокаОбщегоТипа.ИмяОбщегоТипа, "РасширениеФормы") И (Ложь Или РодительскаяСтруктураТипа.ТипЯзыка = "" Или СтрокаОбщегоТипа.ИмяОбщегоТипа <> "Глобальный") И (Ложь Или ЯзыкПрограммы = 0 Или ЯзыкПрограммы = 2) Тогда Если СтрокаОбщегоТипа.ИмяОбщегоТипа = "Глобальный" Тогда ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(СтрокаОбщегоТипа, СловоФильтр, ТипСловаФильтр, ВычислятьТипы, ВычислятьТипыМетодовМодулей, Не ЭтоЛокальныйКонтекст, КлиентОбычноеПриложение, КлиентУправляемоеПриложение, НаСервере, ТаблицаСлов,, ТолькоСоЗначениями); Иначе МодульМетаданныхКомпонента = ПараметрыЗаполнения.МодульМетаданных; Если Истина И МодульМетаданныхКомпонента = Неопределено И ИмяОбщегоТипаРодителя <> "НеизвестныйКонтекст" И ТипЗнч(МетаданныеРодителя) <> Тип("Неопределено") И ТипЗнч(МетаданныеРодителя) <> Тип("Строка") Тогда Если ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаРодителя, "Форма") Тогда ИмяОбщегоТипаРодителя = РодительскаяСтруктураТипа.ИмяОбщегоТипа; КонецЕсли; СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя); СтруктураТипаМодуля.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; // Имя расширения конфигурации СтруктураТипаМодуля.Метаданные = МетаданныеРодителя; МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля); КонецЕсли; Если МодульМетаданныхКомпонента <> Неопределено Тогда РасширениеМодуля = ""; Если Истина И МодульМетаданныхКомпонента.СтруктураТипа <> Неопределено И ТипЗнч(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных) = Тип("Строка") И ЗначениеЗаполнено(МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных) Тогда РасширениеМодуля = МодульМетаданныхКомпонента.СтруктураТипа.ДержательМетаданных; КонецЕсли; Если Ложь Или Не ЗначениеЗаполнено(РасширениеМодуля) // методы конфигурации всегда видны расширению Или БазовоеРасширениеКонфигурации = "*" // методы конфигурации всегда видны внешнему модулю Или РасширениеМодуля = БазовоеРасширениеКонфигурации Или РасширениеМодуля = ПолноеИмяПодсистемыИР // расширение ИР видно всем Или ФлагиКомпиляции <> Неопределено И ФлагиКомпиляции.Свойство("Динамический") Тогда ТолькоЭкспорт = Не ЭтоЛокальныйКонтекст Или СтрокаОбщегоТипа.Метаданные <> РодительскаяСтруктураТипа.Метаданные; ТаблицаСлов = ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, СловоФильтр, ТипСловаФильтр, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт, ФлагиКомпиляции, ВнутриГруппыОбщихМодулей, ДляСвойства, ЛиВместеСЛокальнымКонтекстом,, ТолькоСоЗначениями, ПараметрыЗаполнения.СтрогийФильтр); КонецЕсли; ВидимыеРасширения = Новый Массив; Если Истина И ТипЗнч(РасширениеМодуля) = Тип("Строка") И ЗначениеЗаполнено(РасширениеМодуля) И (Ложь Или ТипЗнч(МетаданныеРодителя) <> Тип("ОбъектМетаданных") Или МетаданныеРодителя.РасширениеКонфигурации() = Неопределено) Тогда // Для расширения модуля добавляем базовый модуль ВидимыеРасширения.Добавить(Неопределено); ИначеЕсли БазовоеРасширениеКонфигурации = "*" Тогда // При вызове из внешнего модуля, добавляем расширение модуля этого расширения Для Каждого РасширениеКонфигурации Из ирКэш.РасширенияКонфигурацииЛкс() Цикл ВидимыеРасширения.Добавить(РасширениеКонфигурации.Ключ.Имя); КонецЦикла; ИначеЕсли ЗначениеЗаполнено(БазовоеРасширениеКонфигурации) И Не ЗначениеЗаполнено(РасширениеМодуля) Тогда // При вызове из модуля расширения, добавляем расширение модуля этого расширения ВидимыеРасширения.Добавить(БазовоеРасширениеКонфигурации); КонецЕсли; Для Каждого ВидимоеРасширение Из ВидимыеРасширения Цикл СтруктураТипаМодуля = НоваяСтруктураТипа(ИмяОбщегоТипаРодителя); СтруктураТипаМодуля.ДержательМетаданных = ВидимоеРасширение; СтруктураТипаМодуля.Метаданные = МетаданныеРодителя; МодульМетаданныхРасширение = ПодготовитьМодульМетаданных(СтруктураТипаМодуля); Если МодульМетаданныхРасширение <> Неопределено Тогда ТаблицаСлов = ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, СловоФильтр, ТипСловаФильтр, ТаблицаСлов, МодульМетаданныхРасширение, ВычислятьТипыМетодовМодулей, ВычислятьТипы, Не ЭтоЛокальныйКонтекст, ФлагиКомпиляции, ВнутриГруппыОбщихМодулей, ДляСвойства, ЛиВместеСЛокальнымКонтекстом,, ТолькоСоЗначениями); КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; #Если Клиент Тогда ТаблицаСлов = СловаКонтекстаМетаданныеCOM(СловоФильтр, ТипСловаФильтр, ИмяОбщегоТипаРодителя, МетаданныеРодителя, ТаблицаСлов, НаборыСлов, КлючКэширования); #КонецЕсли КонецЕсли; КонецЦикла; Если Истина И СловоФильтр <> Неопределено И Не ПараметрыЗаполнения.СтрогийФильтр И ТаблицаСлов.Количество() = 0 И ЕдинственнаяСтрокаВида <> Неопределено И ЕдинственнаяСтрокаВида <> Null И ЕдинственнаяСтрокаВида.Слово <> "<Имя общего модуля>" И (Ложь Или ЕдинственнаяСтрокаВида.ТипЗначения <> "Произвольный" // Иначе проверка модуля не будет обнаруживать ошибки в таких переменных Или Не ЛиВместеСЛокальнымКонтекстом) // Иначе при вычислении результата метода модуля менеджера все локальные переменные будут срабатывать И Найти(ЕдинственнаяСтрокаВида.Слово, "<Имя предопределенного") = 0 И Найти(ЕдинственнаяСтрокаВида.Слово, "<Имя значения перечисления") = 0 Тогда // Шаблон только один. Берем его даже если имя элемента коллекции не подошло. МассивТиповЗначения = ирОбщий.СтрРазделитьЛкс(ЕдинственнаяСтрокаВида.ТипЗначения, ", "); Для Каждого ТипЗначения Из МассивТиповЗначения Цикл //Если Истина // И Не ЗначениеЗаполнено(ТипЗначения) // И ЕдинственнаяСтрокаВида.ТипКонтекста <> "COMОбъект" //Тогда // ТипЗначения = "НеизвестныйКонтекст"; // Для ЭлементыФормы[0] // Вредно для проверки ДанныеФормыЭлементКоллекции //КонецЕсли; СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = ТипЗначения; СтруктураТипа.СтрокаОписания = ЕдинственнаяСтрокаВида; СтруктураТипа.ТипЯзыка = ЕдинственнаяСтрокаВида.ТипЯзыка; ИмяОбщегоТипаРодителя = СтрЗаменить(ИмяОбщегоТипаРодителя, "Менеджер", ""); // СправочникиМенеджер->Справочники Если Истина И ирОбщий.СтрКончаетсяНаЛкс(ИмяОбщегоТипаРодителя, "Структура") И ТипЗнч(МетаданныеРодителя) = Тип("ТаблицаЗначений") Тогда СтруктураТипа = МетаданныеРодителя; ИначеЕсли Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Или ирОбщий.ЕдинственноеИмяМДЛкс(ИмяОбщегоТипаРодителя) <> Неопределено Или ирОбщий.МножественноеИмяМДЛкс(ИмяОбщегоТипаРодителя) <> Неопределено Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаРодителя, МаркерКоллекцииМетаданных) Тогда // Мультиметка29332671 Чтобы проверка модуля отличила обращение к несуществующему реквизиту ТЧ в языке запросов СтруктураТипа.Метаданные = Null; Иначе СтруктураТипа.Метаданные = МетаданныеРодителя; КонецЕсли; ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); ДобавитьВТаблицуСлов(ТаблицаСлов, ЕдинственнаяСтрокаВида.Слово, ЕдинственнаяСтрокаВида.ТипСлова, ТаблицаТипов,, "Метаданные"); КонецЦикла; КонецЕсли; Возврат ТаблицаСлов; КонецФункции //. // Параметры: // РодительскаяСтруктураТипа - Структура - Структура; // МетаданныеРодителя - - // СхемаКоллекции - Соответствие - // Возвращаемое значение: // Структура - Функция СхемаКоллекцииПараметровФормы(Знач РодительскаяСтруктураТипа, Знач Слово = Неопределено) Экспорт Если Слово = "" Тогда Слово = Неопределено; КонецЕсли; СхемаКоллекции = Новый Структура; МетаданныеРодителя = РодительскаяСтруктураТипа.Метаданные; Форма = РодительскаяСтруктураТипа.ДержательМетаданных; // ФормаКлиентскогоПриложения Если ТипЗнч(Форма) = Тип("Структура") Тогда МетаданныеРодителя = Форма.ИмяОбщегоТипа; КонецЕсли; Если ТипЗнч(МетаданныеРодителя) = Тип("ДанныеФормыСтруктура") Тогда СтруктураТипаФормы = СтруктураТипаИзЗначения(Форма); // Системные параметры формы ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов("Параметр",,,,,,,, Слово); ТаблицаПараметровФормы = ТаблицаСловИзСтруктурыТипа(СтруктураТипаФормы, ПараметрыЗаполнения); Для Каждого СтрокаПараметра Из ТаблицаПараметровФормы Цикл ТаблицаТипов = СтрокаПараметра.ТаблицаТипов; Если СтрокаПараметра.Слово = "Ключ" Тогда КлючФормы = ирОбщий.КлючОсновногоОбъектаФормыЛкс(Форма); ОбъектМД = Метаданные.НайтиПоТипу(ТипЗнч(КлючФормы)); ТаблицаТипов[0].Метаданные = ОбъектМД; КонецЕсли; СхемаКоллекции.Вставить(СтрокаПараметра.Слово, ТаблицаТипов); КонецЦикла; СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Если СлужебныеДанные <> Неопределено И СлужебныеДанные.Свойство("Параметры") Тогда ирОбщий.СкопироватьКоллекциюЛкс(СлужебныеДанные.Параметры, СхемаКоллекции); // TODO добавить фильтр по Слово // Параметры часто не описаны в структуре формы //Если ЗначениеЗаполнено(Слово) И Не СхемаКоллекции.Свойство(Слово) Тогда // ДобавитьОтсутствиеЭлементаФормы(Форма, "Параметр:" + Слово); //КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов("Параметр",,,,,,,, Слово); ТаблицаПараметровФормы = ТаблицаСловИзСтруктурыТипа(НоваяСтруктураТипа(МетаданныеРодителя), ПараметрыЗаполнения); Для Каждого СтрокаПараметра Из ТаблицаПараметровФормы Цикл СхемаКоллекции.Вставить(СтрокаПараметра.Слово, СтрокаПараметра.ТаблицаТипов); КонецЦикла; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда СхемаКоллекции = МетаданныеРодителя; КонецЕсли; Если Истина И СтруктураТипаФормы = Неопределено И ТипЗнч(РодительскаяСтруктураТипа.ДержательМетаданных) = Тип("Структура") Тогда СтруктураТипаФормы = НоваяСтруктураТипа("ФормаКлиентскогоПриложения"); СтруктураТипаФормы.Метаданные = РодительскаяСтруктураТипа.ДержательМетаданных; КонецЕсли; // Ожидаемые в коде формы параметры Если СтруктураТипаФормы <> Неопределено Тогда МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипаФормы); Если МодульФормы <> Неопределено Тогда МетодМодуля = МодульФормы.Методы.Найти(НРег("ПриСозданииНаСервере"), "НИмя"); Если МетодМодуля <> Неопределено Тогда АнализаторМодуля = ПолеТекстаМодуля(МодульФормы.Имя); АнализаторМодуля.ЗагрузитьМетодМодуля(МетодМодуля); СтарыйРежимПроверкиМодуля = мРежимПроверкиМодуля; мРежимПроверкиМодуля = Ложь; СтруктураИзКода = АнализаторМодуля.СобратьСвойстваСтруктуры("Параметры",,,,,, Слово, АнализаторМодуля.ИмяФиктивногоСвойства()); Если СтруктураИзКода <> Неопределено Тогда мРежимПроверкиМодуля = СтарыйРежимПроверкиМодуля; ирОбщий.СкопироватьКоллекциюЛкс(СтруктураИзКода, СхемаКоллекции); АнализаторМодуля.мРодительскийКонтекст = "Параметры"; АнализаторМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(,, Истина,,,,, Истина); Для Каждого СтрокаСлова Из АнализаторМодуля.ТаблицаСлов Цикл СхемаКоллекции.Вставить(СтрокаСлова.Слово); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат СхемаКоллекции; КонецФункции //. // Параметры: // СтруктураЭлемента - см. ИмитаторЭлементаФормы - // ИмитаторФормы - - // Слово - Строка, Неопределено - Строка, *Неопределено - для отбора; // Возвращаемое значение: // - Функция ТаблицаТиповИзИмитатораЭлементаФормы(Знач СтруктураЭлемента, Знач ИмитаторФормы, Знач Слово) Экспорт ЗначениеЭлемента = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(СтруктураЭлемента.Тип)); Если ЗначениеЗаполнено(Слово) Тогда ЗначениеЭлемента = ТаблицаТиповИзОписанияТипов(ЗначениеЭлемента); ЗначениеЭлемента[0].Метаданные = СтруктураЭлемента; ЗначениеЭлемента[0].ДержательМетаданных = ИмитаторФормы; ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ЗначениеЭлемента[0].ИмяОбщегоТипа, СтруктураЭлемента); Если ИмяОбщегоТипаРасширения <> Неопределено Тогда ЗначениеЭлемента[0].ИмяОбщегоТипа = ИмяОбщегоТипаРасширения; КонецЕсли; КонецЕсли; Возврат ЗначениеЭлемента; КонецФункции // Функция - Слова контекста метаданные COM // // Параметры: // Слово - - // ТипСлова - - // ИмяОбщегоТипаРодителя - - // МетаданныеРодителя - - // ТаблицаСлов - см. НоваяТаблицаСлов() - // НаборыСлов - - // КлючКэширования - - // // Возвращаемое значение: // - // Функция СловаКонтекстаМетаданныеCOM(Знач Слово, Знач ТипСлова, Знач ИмяОбщегоТипаРодителя, Знач МетаданныеРодителя, Знач ТаблицаСлов, Знач НаборыСлов, КлючКэширования) Экспорт Если Истина И (Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("COMОбъект") Или ТипЗнч(МетаданныеРодителя) = Тип("ВнешнийОбъект") Или Найти(ИмяОбщегоТипаРодителя, " {") > 0) И ЛиИмяТипаComОбъекта(ИмяОбщегоТипаРодителя) Тогда КлючКэширования = КлючКэшированияСловИзОбщегоТипа(ИмяОбщегоТипаРодителя); ТаблицаСловОтдельная = мКэшСловГлобальногоКонтекста[КлючКэширования]; #Если Сервер И Не Сервер Тогда ТаблицаСловОтдельная = Новый ТаблицаЗначений; #КонецЕсли Если ТаблицаСловОтдельная <> Неопределено Тогда КлючКэширования = Неопределено; Иначе ТаблицаСловОтдельная = НоваяТаблицаСлов(); ИмяБиблиотеки = ""; ИнфоТипа = ПолучитьИнфоТипаCOMОбъекта(МетаданныеРодителя, ИмяОбщегоТипаРодителя, ИмяБиблиотеки); Если ИнфоТипа = Неопределено Тогда КлючКэширования = Неопределено; Иначе МассивИнфоТипа = ИнтерфейсыCOMОбъекта(ИнфоТипа, ИмяОбщегоТипаРодителя); Для Каждого ИнфоТипа Из МассивИнфоТипа Цикл Для Каждого Член Из ИнфоТипа.Members Цикл Если Член.AttributeMask = 1 Тогда // Это члены IDispatch Продолжить; КонецЕсли; ИмяЧлена = Член.Name; Если Член.InvokeKind = 1 Или Член.Parameters.Count > 0 Тогда ТипСловаЧленаКласса = ПеречТипСлова.Метод; ИначеЕсли Член.InvokeKind = 2 Тогда //Get ТипСловаЧленаКласса = "Свойство"; Иначе Продолжить; КонецЕсли; СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(Член, ИмяБиблиотеки, ИнфоТипа); СтруктураТипа.СтрокаОписания = Член; СтруктураТипа.Метаданные = МетаданныеРодителя; ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); ДобавитьВТаблицуСлов(ТаблицаСловОтдельная, ИмяЧлена, ТипСловаЧленаКласса, ТаблицаТипов,, "Метаданные"); Если Истина И ТипСловаЧленаКласса = "Свойство" И Член.ReturnType.TypeInfo <> Неопределено Тогда ТипСловаЧленаКласса = ПеречТипСлова.Метод; ИнфоТипаЧлена = Член.ReturnType.TypeInfo; Попытка ОписаниеЭлементаКоллекции = ИнфоТипаЧлена.GetMember("Item"); Исключение ОписаниеЭлементаКоллекции = Неопределено; КонецПопытки; Если ОписаниеЭлементаКоллекции <> Неопределено Тогда // Например ADODB.Connection.Properties("DBMS Name").Value СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = ПолучитьТипЗначенияЧленаИнтерфейса(ОписаниеЭлементаКоллекции, ИмяБиблиотеки, ИнфоТипа); СтруктураТипа.СтрокаОписания = Член; СтруктураТипа.Метаданные = МетаданныеРодителя; ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); ДобавитьВТаблицуСлов(ТаблицаСловОтдельная, ИмяЧлена, ТипСловаЧленаКласса, ТаблицаТипов,, "Метаданные"); КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; Если Ложь Или ЗначениеЗаполнено(ТипСлова) Или ЗначениеЗаполнено(Слово) Тогда НаборыСлов = Неопределено; Фильтр = Новый Структура; Если ЗначениеЗаполнено(Слово) Тогда Если ТаблицаСловОтдельная.Колонки.Найти("НСлово") = Неопределено Тогда ирОбщий.ОбновитьКопиюКолонкиВНижнемРегистреЛкс(ТаблицаСловОтдельная, "Слово"); //! ТаблицаСловОтдельная.Колонки.Добавить("НСлово") КонецЕсли; Фильтр.Вставить("НСлово", НРег(Слово)); КонецЕсли; Если Не ЗначениеЗаполнено(Слово) Тогда // Тип слова у КОМ типов может быть неверным Фильтр.Вставить("ТипСлова", ТипСлова); КонецЕсли; КонецЕсли; Если КлючКэширования <> Неопределено Тогда ДобавитьТаблицуСловВГлобальныйКэш(ТаблицаСловОтдельная, КлючКэширования, НаборыСлов); КлючКэширования = Неопределено; КонецЕсли; Если Фильтр <> Неопределено Тогда ТаблицаСловОтдельная = ТаблицаСловОтдельная.Скопировать(Фильтр); КонецЕсли; Если ЗначениеЗаполнено(Слово) Тогда ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаСловОтдельная, ТаблицаСлов); // Нельзя подменять таблицу слов, т.к. ВычислитьТипДочернегоЭлемента это не поддерживает Иначе ТаблицаСлов = СлитьТаблицыСлов(ТаблицаСлов, ТаблицаСловОтдельная); КонецЕсли; КонецЕсли; Возврат ТаблицаСлов; КонецФункции // Процедура - Слова контекста метаданные формы // // Параметры: // Слово - - // ИмяОбщегоТипаРодителя - - // МетаданныеРодителя - Форма, УправляемаяФорма, Структура, ТабличноеПоле, Панель, КнопкаКоманднойПанели, КнопкиКоманднойПанели - // СтрокаОписанияВида - - // КоллекцияЗначений - - // СхемаКоллекции - - // Процедура СловаКонтекстаМетаданныеФормы(Знач Слово, Знач ИмяОбщегоТипаРодителя, Знач МетаданныеРодителя, Знач СтрокаОписанияВида, КоллекцияЗначений = Неопределено, СхемаКоллекции = Неопределено) Экспорт Если Истина И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И Не МетаданныеРодителя.Свойство(СтрокаОписанияВида.ИмяКоллекции) Тогда Возврат; КонецЕсли; ДочерниеЭлементы = МетаданныеРодителя[СтрокаОписанияВида.ИмяКоллекции]; Если ИмяОбщегоТипаРодителя = "ОформленияЯчеек" Тогда СхемаКоллекции = ДочерниеЭлементы; Иначе ИмитаторФормы = МетаданныеРодителя; Если ТипЗнч(МетаданныеРодителя) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда //! ДочерниеЭлементы = 0 // ВсеЭлементыФормы КоллекцияЗначений = Новый Соответствие; Если ЗначениеЗаполнено(Слово) Тогда ЦелевойЭлемент = ДочерниеЭлементы.Найти(Слово); ДочерниеЭлементы = Новый Массив; Если ЦелевойЭлемент <> Неопределено Тогда ДочерниеЭлементы.Добавить(ЦелевойЭлемент); КонецЕсли; КонецЕсли; Для Каждого ЭлементФормы Из ДочерниеЭлементы Цикл КоллекцияЗначений.Вставить(ЭлементФормы.Имя, ЭлементФормы); КонецЦикла; ИмитаторФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя); ИначеЕсли ТипЗнч(ИмитаторФормы) = Тип("Структура") Тогда КоллекцияЗначений = Новый Соответствие; Иначе КоллекцияЗначений = ДочерниеЭлементы; КонецЕсли; Если Истина И ТипЗнч(ИмитаторФормы) = Тип("Структура") И ИмитаторФормы.Свойство(СтрокаОписанияВида.ИмяКоллекции) Тогда // имитатор формы ЭлементыИзИмитатора = ИмитаторФормы[СтрокаОписанияВида.ИмяКоллекции]; // Структура Если ЗначениеЗаполнено(Слово) Тогда ЭлементыИзИмитатора.Свойство(Слово, ЦелевойЭлемент); ЭлементыИзИмитатора = Новый Структура; Если ЦелевойЭлемент <> Неопределено Тогда ЭлементыИзИмитатора.Вставить(Слово, ЦелевойЭлемент); КонецЕсли; КонецЕсли; Для Каждого КлючИЗначение Из ЭлементыИзИмитатора Цикл Если КоллекцияЗначений[КлючИЗначение.Ключ] <> Неопределено Тогда Продолжить; КонецЕсли; СтруктураЭлемента = КлючИЗначение.Значение; СхемаКоллекции["_"] = 1; // Чтобы описания типов в значении считались как тип элемента КоллекцияЗначений.Вставить(СтруктураЭлемента.Имя, ТаблицаТиповИзИмитатораЭлементаФормы(СтруктураЭлемента, ИмитаторФормы, Слово)); КонецЦикла; Если ЗначениеЗаполнено(Слово) И КоллекцияЗначений[Слово] = Неопределено Тогда ДобавитьОтсутствиеЭлементаФормы(ИмитаторФормы, "Элемент:" + Слово); КонецЕсли; КонецЕсли; КонецЕсли; КонецПроцедуры // Функция - Добавить в таблицу слов элементы глобальных модулей // // Параметры: // СтрокаОбщегоТипа - см. РазвернутаяТаблицаТиповИзСтруктурыТипа()[0] - // Функция ДобавитьВТаблицуСловЭлементыГлобальныхМодулей(Знач СтрокаОбщегоТипа, Знач Слово = Неопределено, Знач ТипСлова = Неопределено, Знач ВычислятьТипы = Истина, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ТолькоЭкспорт = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач НаСервере = Ложь, Знач ТаблицаСлов = Неопределено, Знач БезПараметров = Ложь, Знач ТолькоСоЗначениями = Ложь) Экспорт Если ТаблицаСлов = Неопределено Тогда ТаблицаСлов = НоваяТаблицаСлов(); КонецЕсли; Если ПустаяСтрока(ТипСлова) Или ТипСлова = ПеречТипСлова.Метод Тогда // Глобальные общие модули СтруктураТипаМодуля = НоваяСтруктураТипа(); СтруктураТипаМодуля.ИмяОбщегоТипа = "ОбщийМодуль"; Для Каждого ОбщийМодульМД Из ирКэш.ГлобальныеОбщиеМодулиЛкс(НаСервере, КлиентОбычноеПриложение, КлиентУправляемоеПриложение) Цикл СтруктураТипаМодуля.Метаданные = ОбщийМодульМД; МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля); ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ПеречТипСлова.Метод, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,,,,, БезПараметров, ТолькоСоЗначениями); КонецЦикла; КонецЕсли; СтруктураТипаМодуля = НоваяСтруктураТипа(СтрокаОбщегоТипа.ИмяОбщегоТипа); СтруктураТипаМодуля.Метаданные = СтрокаОбщегоТипа.Метаданные; Если КлиентОбычноеПриложение Тогда МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульОбычногоПриложения"); ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,,,,, БезПараметров, ТолькоСоЗначениями); КонецЕсли; Если КлиентУправляемоеПриложение Тогда МодульМетаданныхКомпонента = ПодготовитьМодульМетаданных(СтруктураТипаМодуля, "МодульУправляемогоПриложения"); ДобавитьВТаблицуСловЭлементыМодуляМетаданных(СтрокаОбщегоТипа, Слово, ТипСлова, ТаблицаСлов, МодульМетаданныхКомпонента, ВычислятьТипыМетодовМодулей, ВычислятьТипы, ТолькоЭкспорт,,,,, БезПараметров, ТолькоСоЗначениями); КонецЕсли; Возврат ТаблицаСлов; КонецФункции Функция ИнтерфейсыCOMОбъекта(Знач ИнфоТипа, Знач ИмяОбщегоТипаРодителя) Экспорт МассивИнфоТипа = Новый Массив; Если Найти(ИмяОбщегоТипаРодителя, " {") > 0 Тогда ИнфоТипа = ИнфоТипа.Parent.TypeInfos.NamedItem(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипаРодителя, " {")); КонецЕсли; //Если ИмяCOMКласса = "" Тогда // Если Описатель.Parent.Name = "V" + ирКэш.НомерИзданияПлатформыЛкс() Тогда // ИмяОбщегоТипа = "COM-соединитель"; // КонецЕсли; //КонецЕсли; Если ИнфоТипа = Неопределено Тогда // ИначеЕсли НРег(ИнфоТипа.TypeKindString) = "coclass" Тогда //! ИнфоТипа = 0 // TypeInfo {TLI.TLIApplication} МассивИнфоТипа = ИнфоТипа.Interfaces; ИначеЕсли НРег(ИнфоТипа.TypeKindString) = "enum" Тогда // Иначе //! ИнфоТипа = 0 // InterfaceInfo {TLI.TLIApplication} МассивИнфоТипа = Новый Массив; МассивИнфоТипа.Добавить(ИнфоТипа); Для Каждого ИнтерфейсОбъекта Из ИнфоТипа.ImpliedInterfaces Цикл МассивИнфоТипа.Добавить(ИнтерфейсОбъекта); КонецЦикла; КонецЕсли; Возврат МассивИнфоТипа; КонецФункции // Помогает обновлять кэш управляемой формы из конфигуратора при следующем вызове автодополнения // Параметры: // ФормаИлиСтруктура - Форма, Структура - // Ключ - Строка - Процедура ДобавитьОтсутствиеЭлементаФормы(Знач ФормаИлиСтруктура, Знач Ключ) Экспорт СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(ФормаИлиСтруктура); ОтсутствуютЭлементы = Неопределено; Если Не СлужебныеДанные.Свойство("ОтсутствуютЭлементы", ОтсутствуютЭлементы) Тогда ОтсутствуютЭлементы = Новый Соответствие; СлужебныеДанные.Вставить("ОтсутствуютЭлементы", ОтсутствуютЭлементы); КонецЕсли; Если ОтсутствуютЭлементы[Ключ] = Неопределено Тогда ОтсутствуютЭлементы[Ключ] = 1; СлужебныеДанные.Вставить("ДатаОбновления", Дата(1,1,1)); КонецЕсли; КонецПроцедуры Функция ТаблицаТиповЭлементовКоллекции(Знач РодительскаяСтруктураТипа, Знач ТекстИндексаЭлемента = "", Знач ЯзыкПрограммы = 0, Знач ТаблицаТипов = Неопределено) Экспорт НужнаПроверкаТипов = Истина; МетаданныеКоллекции = РодительскаяСтруктураТипа.Метаданные; // Массив Если Истина И (Ложь Или ТипЗнч(МетаданныеКоллекции) = Тип("ТаблицаЗначений") Или ТипЗнч(МетаданныеКоллекции) = Тип("Массив")) И МетаданныеКоллекции.Количество() > 0 И ирОбщий.СтрКончаетсяНаЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Массив") // ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[") Тогда Если ТипЗнч(МетаданныеКоллекции) = Тип("ТаблицаЗначений") Тогда //! МетаданныеКоллекции = 0 // см. НоваяТаблицаТипов Если Не ЗначениеЗаполнено(ТекстИндексаЭлемента) Тогда Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = МетаданныеКоллекции; Иначе ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, МетаданныеКоллекции); КонецЕсли; Иначе Для Каждого СтрокаТипа Из МетаданныеКоллекции Цикл СтруктураТипаЭлемента = Неопределено; Если ТипЗнч(СтрокаТипа.Метаданные) = Тип("ПостроительЗапроса") Тогда Попытка ИндексВПакете = Число(ТекстИндексаЭлемента); Исключение ИндексВПакете = Неопределено; КонецПопытки; ПостроительЗапроса = СтрокаТипа.Метаданные; Если ИндексВПакете <> Неопределено И ЗначениеЗаполнено(ПостроительЗапроса.Текст) Тогда ТекстыЗапросов = РазбитьГрубоТекстПакетногоЗапросаНаЗапросы(ПостроительЗапроса.Текст); #Если Сервер И Не Сервер Тогда ТекстыЗапросов = Новый Массив; #КонецЕсли ПостроительЗапроса = ПостроительПакетаЗапросовДоИндекса(ТекстыЗапросов, ИндексВПакете, ПостроительЗапроса.Параметры,, СтрокаТипа.ДержательМетаданных); Если ПостроительЗапроса <> Неопределено Тогда СтруктураТипаЭлемента = НоваяСтруктураТипа(СтрокаТипа.ИмяОбщегоТипа); СтруктураТипаЭлемента.Метаданные = ПостроительЗапроса; МенеджерВременныхТаблиц = СтрокаТипа.ДержательМетаданных; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() ПоследнийПакетЗапросов = МенеджерВременныхТаблиц.ПакетыЗапросов[МенеджерВременныхТаблиц.ПакетыЗапросов.ВГраница()]; // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйПакетЗапросов() ПоследнийПакетЗапросов = ирОбщий.СкопироватьКоллекциюЛкс(ПоследнийПакетЗапросов); ПоследнийПакетЗапросов.Вставить("ИндексВПакете", ИндексВПакете); СтруктураТипаЭлемента.ДержательМетаданных = ПоследнийПакетЗапросов; КонецЕсли; КонецЕсли; КонецЕсли; Если СтруктураТипаЭлемента = Неопределено Тогда СтруктураТипаЭлемента = СтрокаТипа; КонецЕсли; ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); КонецЦикла; КонецЕсли; Иначе ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаИзЗначения(МетаданныеКоллекции[0])); КонецЕсли; ИначеЕсли Истина И ТипЗнч(МетаданныеКоллекции) = Тип("ТаблицаЗначений") И МетаданныеКоллекции.Количество() > 0 И ирОбщий.СтрКончаетсяНаЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "Структура") // ирОбщий.ПервыйФрагментЛкс(РодительскаяСтруктураТипа.ИмяОбщегоТипа, "[") Тогда СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение"); СтруктураТипаЭлемента.Метаданные = Новый Структура("Значение", МетаданныеКоллекции); ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); ИначеЕсли Истина И ТипЗнч(МетаданныеКоллекции) = Тип("Структура") И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "Соответствие" Тогда СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение"); СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции; ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); ИначеЕсли РодительскаяСтруктураТипа.ИмяОбщегоТипа = "СтрокиДинамическогоСписка" Тогда СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение"); СтруктураТипаЭлемента.Метаданные = Новый Структура; СтруктураТипаЭлемента.Метаданные.Вставить("Значение", ТаблицаТиповИзОписанияТипов(Новый ОписаниеТипов("СтрокаДинамическогоСписка"))); ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); ИначеЕсли РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ОформленияЯчеекДинамическогоСписка" Тогда СтруктураТипаЭлемента = НоваяСтруктураТипа("КлючИЗначение"); СтруктураТипаЭлемента.Метаданные = Новый Структура; СтруктураТипаЭлемента.Метаданные.Вставить("Значение", ТаблицаТиповИзОписанияТипов(Новый ОписаниеТипов("ОформлениеЯчейкиДинамическогоСписка"))); ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); ИначеЕсли Истина И ТипЗнч(МетаданныеКоллекции) = Тип("Структура") И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "СписокЗначений" Тогда СтруктураТипаЭлемента = НоваяСтруктураТипа("ЭлементСпискаЗначений"); СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции; ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); #Если Клиент Тогда ИначеЕсли Истина И ТипЗнч(МетаданныеКоллекции) = Тип("ТабличноеПоле") И РодительскаяСтруктураТипа.ИмяОбщегоТипа = "ВыделенныеСтрокиТабличногоПоля" Тогда НоваяТаблицаТипов = ТаблицаТиповСтрокиТабличногоПоля(РодительскаяСтруктураТипа); Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов; Иначе ТаблицаТипов = ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяТаблицаТипов); КонецЕсли; #КонецЕсли Иначе Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; ТипыЭлементовКоллекции = ТипыЭлементовКоллекции(РодительскаяСтруктураТипа, ЯзыкПрограммы, НужнаПроверкаТипов); Если ТипыЭлементовКоллекции.Количество() > 0 Тогда ТипТип = Тип("Тип"); Для Каждого БазовыйТипЭлемента Из ТипыЭлементовКоллекции Цикл Если ТипЗнч(БазовыйТипЭлемента) = ТипТип Тогда КонкретныйТип = БазовыйТипЭлемента; Иначе Попытка КонкретныйТип = Тип(БазовыйТипЭлемента); Исключение КонкретныйТип = Неопределено; КонецПопытки; КонецЕсли; Если КонкретныйТип <> Неопределено Тогда СтруктураТипаЭлемента = СтруктураТипаИзКонкретногоТипа(КонкретныйТип); Иначе СтруктураТипаЭлемента = НоваяСтруктураТипа(); СтруктураТипаЭлемента.ИмяОбщегоТипа = БазовыйТипЭлемента; КонецЕсли; Если Истина И ТипЗнч(СтруктураТипаЭлемента.Метаданные) = Тип("Неопределено") И Не ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеКоллекции) Тогда СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции; КонецЕсли; Если ТипЗнч(МетаданныеКоллекции) = ирОбщий.ТипУправляемаяФормаЛкс() Тогда СтруктураТипаЭлемента.ДержательМетаданных = МетаданныеКоллекции; Иначе СтруктураТипаЭлемента.ДержательМетаданных = РодительскаяСтруктураТипа.ДержательМетаданных; КонецЕсли; Если КонкретныйТип = Неопределено И НужнаПроверкаТипов Тогда СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", БазовыйТипЭлемента, ЯзыкПрограммы); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча); Если НайденныеСтроки.Количество() > 0 Тогда СтруктураТипаЭлемента.СтрокаОписания = НайденныеСтроки[0]; СтруктураТипаЭлемента.ИмяОбщегоТипа = НайденныеСтроки[0].Слово; Если ТипЗнч(МетаданныеКоллекции) <> Тип("КоллекцияОбъектовМетаданных") Тогда СтруктураТипаЭлемента.Метаданные = МетаданныеКоллекции; КонецЕсли; КонецЕсли; КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипаЭлемента); КонецЦикла; КонецЕсли; КонецЕсли; Возврат ТаблицаТипов; КонецФункции Функция ПараметрыИзТекстаЗапроса(Знач ТекстЗапроса, Знач ВВидеСтруктуры = Ложь, Знач СтруктураПриемник = Неопределено) Экспорт ПараметрыЗапроса = Новый Массив; Если Найти(ТекстЗапроса, "&") Тогда Запрос = Новый Запрос(ТекстЗапроса); Попытка ПараметрыЗапроса = Запрос.НайтиПараметры(); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Отладка КонецПопытки; КонецЕсли; Если ВВидеСтруктуры Тогда Результат = СтруктураПриемник; Если СтруктураПриемник = Неопределено Тогда Результат = Новый Структура; КонецЕсли; Если ПараметрыЗапроса <> Неопределено Тогда Для Каждого ОписаниеПараметра Из ПараметрыЗапроса Цикл ТаблицаТиповСтарая = Неопределено; Результат.Свойство(ОписаниеПараметра.Имя, ТаблицаТиповСтарая); Результат.Вставить(ОписаниеПараметра.Имя, ДобавитьВТаблицуТипов(ТаблицаТиповИзОписанияТипов(ОписаниеПараметра.ТипЗначения), ТаблицаТиповСтарая)); КонецЦикла; КонецЕсли; Иначе Результат = ПараметрыЗапроса; КонецЕсли; Возврат Результат; КонецФункции //. // Параметры: // ТекстЗапроса - Строка - // Возвращаемое значение: // ПостроительЗапроса - Функция ПостроительЗапросаИзТекстаДляТипа(Знач ТекстЗапроса, Знач ПостроительЗапроса = Неопределено) Экспорт Если ПостроительЗапроса = Неопределено Тогда ПостроительЗапроса = Новый ПостроительЗапроса; КонецЕсли; Попытка ПостроительЗапроса.Текст = ТекстЗапроса; Исключение // Даже если текст некорректный, он сохраняется в свойстве КонецПопытки; ПараметрыИзТекстаЗапроса(ТекстЗапроса, Истина, ПостроительЗапроса.Параметры); Возврат ПостроительЗапроса; КонецФункции // Функция - Построитель пакета запросов до индекса включительно // // Параметры: // ТекстыЗапросов - Массив - // ИндексЭлемента - - // Параметры - Структура - // ИмяРождаемойТаблицы - - // ДержательМетаданных - см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() - нужен для входящих временных таблиц // // Возвращаемое значение: // - // Функция ПостроительПакетаЗапросовДоИндекса(Знач ТекстыЗапросов, Знач ИндексЭлемента, Знач Параметры, Знач ИмяРождаемойТаблицы = "", Знач ДержательМетаданных = Неопределено) Экспорт ТекстЗапроса = ""; Если ТекстыЗапросов.Количество() <= ИндексЭлемента Тогда Возврат Неопределено; КонецЕсли; ТекстыЗапросов = ирОбщий.СкопироватьКоллекциюЛкс(ТекстыЗапросов); Если ЗначениеЗаполнено(ИмяРождаемойТаблицы) Тогда // Построитель сначала ищет последний запрос выборки, а затем создания. Поэтому сделаем последний запрос выборкой. ТекстЗапроса = ТекстыЗапросов[ИндексЭлемента]; Если Найти(ТекстЗапроса, "ИНДЕКСИРОВАТЬ ПО") = 0 Тогда ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПОМЕСТИТЬ " + ИмяРождаемойТаблицы, ""); ТекстыЗапросов[ИндексЭлемента] = ТекстЗапроса; КонецЕсли; КонецЕсли; Пока ТекстыЗапросов.Количество() > ИндексЭлемента + 1 Цикл ТекстыЗапросов.Удалить(ТекстыЗапросов.ВГраница()); КонецЦикла; ТекстЗапроса = ирОбщий.СтрСоединитьЛкс(ТекстыЗапросов, Символы.ПС); Если Лев(ТекстЗапроса, 1) = """" Тогда ТекстЗапроса = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ТекстЗапроса); КонецЕсли; ПостроительЗапроса = Новый ПостроительЗапроса; ирОбщий.СкопироватьКоллекциюЛкс(Параметры, ПостроительЗапроса.Параметры); Попытка ПостроительЗапроса.Текст = ТекстЗапроса; // Текст в любом случае установится, но еще может быть выброшено исключение Исключение КонецПопытки; ПодготовитьМетаданныеПостроителяЗапроса(ПостроительЗапроса, ДержательМетаданных, ТекстыЗапросов); Возврат ПостроительЗапроса; КонецФункции // . // Параметры: // ТекстЗапроса - Строка - // Параметры - Структура - // ТекстыЗапросов - - // КлючПакета - Строка - передается для устранения пересечения веток создания одноименных временных таблиц // Возвращаемое значение: // - Функция ДобавитьВременныеТаблицыПараметровВТекстЗапроса(Знач ТекстЗапроса, Знач Параметры, Знач ТекстыЗапросов = Неопределено, Знач КлючПакета = 0) Экспорт Если Не ЗначениеЗаполнено(ТекстЗапроса) Тогда Возврат ""; КонецЕсли; ПрефиксСлужебнойТаблицы = "ъ" + КлючПакета + "_"; //Если Найти(ТекстЗапроса, "ПОМЕСТИТЬ " + ПрефиксСлужебнойТаблицы) > 0 Тогда // Возврат ""; //КонецЕсли; Если ТекстыЗапросов = Неопределено Тогда ТекстыЗапросов = ирОбщий.СтрРазделитьЛкс(ТекстЗапроса, ";",,,, Истина); // Грубо КонецЕсли; ТекстПоследнегоЗапроса = ТекстыЗапросов[ТекстыЗапросов.ВГраница()]; Если Найти(ТекстПоследнегоЗапроса, "&") > 0 Тогда Найденные = ирОбщий.НайтиРегВыражениеЛкс(ТекстПоследнегоЗапроса, "[\s|](?:ИЗ|FROM)[\s|]+&("+ шИмя + ")",, Ложь); Для Каждого Вхождение Из Найденные Цикл ИмяТаблицыПараметра = Вхождение.Группа0; Если Не Параметры.Свойство(ИмяТаблицыПараметра) Тогда Параметры.Вставить(ИмяТаблицыПараметра, Новый ТаблицаЗначений); КонецЕсли; КонецЦикла; КонецЕсли; СлужебныеЗапросы = Новый Массив; ИменаСлужебныхЗапросов = Новый Массив; Для Каждого КлючИЗначение Из Параметры Цикл ЗначениеПараметра = ПодготовитьЗначениеПараметраЗапроса(КлючИЗначение.Значение); Если ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений") Тогда Если Истина И Найти(ТекстЗапроса, "&" + КлючИЗначение.Ключ) = 0 И Найти(ТекстЗапроса, "&" + НРег(КлючИЗначение.Ключ)) = 0 Тогда Продолжить; КонецЕсли; Если Истина И ЗначениеПараметра.Колонки.Количество() = 0 И ирОбщий.СтрокиРавныЛкс(ИмяТаблицыПараметра, КлючИЗначение.Ключ) Тогда ИменаПолей = ирОбщий.НайтиРегВыражениеЛкс(ирОбщий.ПервыйФрагментЛкс(ТекстПоследнегоЗапроса, "ИЗ"), "[\s\.]("+ шИмя +")\s*(?:,|$)"); Для Каждого Вхождение Из ИменаПолей Цикл Если ЗначениеПараметра.Колонки.Найти(Вхождение.Группа0) = Неопределено Тогда ЗначениеПараметра.Колонки.Добавить(Вхождение.Группа0); КонецЕсли; КонецЦикла; КонецЕсли; Если ЗначениеПараметра.Колонки.Количество() > 0 Тогда ТекстСлужебногоЗапроса = ирОбщий.ТекстЗапросаПоместитьИзПараметраЛкс(ПрефиксСлужебнойТаблицы + КлючИЗначение.Ключ, КлючИЗначение.Ключ, Истина, ЗначениеПараметра.Колонки,, Истина); СлужебныеЗапросы.Добавить(ТекстСлужебногоЗапроса); ИменаСлужебныхЗапросов.Добавить(КлючИЗначение.Ключ); КонецЕсли; КонецЕсли; КонецЦикла; Если СлужебныеЗапросы.Количество() > 0 Тогда НовыйТекст = ТекстЗапроса; Для Каждого ИмяТаблицы Из ИменаСлужебныхЗапросов Цикл НовыйТекст = СтрЗаменить(НовыйТекст, "&" + ИмяТаблицы, ПрефиксСлужебнойТаблицы + ИмяТаблицы); // TODO избавиться от чувствительности к регистру КонецЦикла; НовыйТекст = ирОбщий.СтрСоединитьЛкс(СлужебныеЗапросы, ";" + Символы.ПС) + ";" + Символы.ПС + НовыйТекст; КонецЕсли; Возврат НовыйТекст; КонецФункции Функция ПодготовитьЗначениеПараметраЗапроса(Знач ЗначениеПараметра, выхОписаниеТипов = Неопределено) Экспорт Если Истина И ТипЗнч(ЗначениеПараметра) = Тип("ТаблицаЗначений") И ЗначениеПараметра.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено Тогда выхОписаниеТипов = ОписаниеТиповИзТаблицыТипов(ЗначениеПараметра); ЛучшийТип = Неопределено; // см. НоваяСтруктураТипа() Если ЛиДетальностьТиповДостаточна(ЗначениеПараметра, 5, Истина, ЛучшийТип) Тогда ЗначениеПараметра = ЛучшийТип.Метаданные; Иначе ЗначениеПараметра = выхОписаниеТипов.ПривестиЗначение(); КонецЕсли; КонецЕсли; Если ТипЗнч(ЗначениеПараметра) = Тип("Структура") Тогда ТаблицаЗначений = Новый ТаблицаЗначений; Для Каждого ОписаниеКолонки Из ЗначениеПараметра Цикл ОписаниеТиповКолонки = Неопределено; Если Истина И ТипЗнч(ОписаниеКолонки.Значение) = Тип("ТаблицаЗначений") И ОписаниеКолонки.Значение.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено Тогда ОписаниеТиповКолонки = ОписаниеТиповИзТаблицыТипов(ОписаниеКолонки.Значение); КонецЕсли; ТаблицаЗначений.Колонки.Добавить(ОписаниеКолонки.Ключ, ОписаниеТиповКолонки); КонецЦикла; ЗначениеПараметра = ТаблицаЗначений; КонецЕсли; Возврат ЗначениеПараметра; КонецФункции // Процедура - Подготовить выбранные поля построителя // // Параметры: // ПостроительЗапроса - ПостроительЗапроса - // ДержательМетаданных - см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.НовыйМенеджерВременныхТаблиц() - нужен для входящих временных таблиц // Процедура ПодготовитьМетаданныеПостроителяЗапроса(Знач ПостроительЗапроса, Знач ДержательМетаданных = Неопределено, Знач ТекстыЗапросов = Неопределено) Экспорт Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 Тогда Попытка ПостроительЗапроса.ЗаполнитьНастройки(); Исключение КонецПопытки; КонецЕсли; Если ПостроительЗапроса.ВыбранныеПоля.Количество() = 0 И ирКэш.ДоступноСхемаЗапросаЛкс() Тогда Текст = ПостроительЗапроса.Текст; НовыйТекст = ДобавитьВременныеТаблицыПараметровВТекстЗапроса(Текст, ПостроительЗапроса.Параметры, ТекстыЗапросов); Если ЗначениеЗаполнено(НовыйТекст) Тогда Текст = НовыйТекст; КонецЕсли; Если Истина И ДержательМетаданных <> Неопределено И ДержательМетаданных.Тип = Тип("МенеджерВременныхТаблиц") //И ДержательМетаданных.Активен Тогда ТекстыПакетов = Новый Массив; Для Индекс = 0 По ДержательМетаданных.ПакетыЗапросов.ВГраница() - 1 Цикл ПредПакет = ДержательМетаданных.ПакетыЗапросов[Индекс]; ТекстПредпакета = ДобавитьВременныеТаблицыПараметровВТекстЗапроса(ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ПредПакет.Текст), ПредПакет.Параметры, ПредПакет.ТекстыЗапросов, Индекс + 1); Если ЗначениеЗаполнено(ТекстПредпакета) Тогда ТекстыПакетов.Добавить(ТекстПредпакета); КонецЕсли; КонецЦикла; ТекстыПакетов.Добавить(Текст); Текст = ирОбщий.СтрСоединитьЛкс(ТекстыПакетов, ";" + Символы.ПС); КонецЕсли; Попытка ПустаяТаблица = ирОбщий.ПустаяТаблицаЗначенийИзТекстаЗапросаЛкс(Текст,, Истина); Исключение ОписаниеОшибки = ОписаниеОшибки(); Возврат; КонецПопытки; ПостроительЗапроса.ИсточникДанных = Новый ОписаниеИсточникаДанных(ПустаяТаблица); ПостроительЗапроса.ЗаполнитьНастройки(); КонецЕсли; КонецПроцедуры Функция ЛиИмяТипаComОбъекта(ИмяОбщегоТипа) Экспорт Результат = Ложь Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Или Найти(ИмяОбщегоТипа, " {") > 0; Возврат Результат; КонецФункции Функция ДобавитьВТаблицуСловЭлементыМодуляМетаданных(Знач СтруктураТипаМини, Знач СловоФильтр = Неопределено, Знач ТипСловаФильтр = Неопределено, Знач ТаблицаСловПриемник = Неопределено, Знач МодульМетаданных, Знач ВычислятьТипыМетодовМодулей = Ложь, Знач ВычислятьТипы = Истина, Знач ТолькоЭкспорт = Истина, Знач ФлагиКомпиляции = Неопределено, Знач ВнутриГруппыОбщихМодулей = Ложь, Знач ДляСвойства = "", Знач ЛиВместеСЛокальнымКонтекстом = Ложь, Знач БезПараметров = Ложь, Знач ТолькоСоЗначениями = Ложь, Знач СтрогийФильтр = Ложь) Экспорт Если Истина И СтруктураТипаМини.ИмяОбщегоТипа <> "Глобальный" И Не ВнутриГруппыОбщихМодулей Тогда ЛиСеансТолстогоКлиентаУП = ирКэш.ЛиСеансТолстогоКлиентаУПЛкс(); НаСервере = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "Сервер", Истина); БезКонтекста = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "БезКонтекста", Ложь); КлиентОбычноеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентОбычноеПриложение", Не ЛиСеансТолстогоКлиентаУП); КлиентУправляемоеПриложение = ирОбщий.СвойствоСтруктурыЛкс(ФлагиКомпиляции, "КлиентУправляемоеПриложение", ЛиСеансТолстогоКлиентаУП); КлючКэша = "" + ТолькоЭкспорт + ";" + БезПараметров + ";" + ТолькоСоЗначениями + ";" + НаСервере + ";" + БезКонтекста + ";" + КлиентОбычноеПриложение + ";" + КлиентУправляемоеПриложение; ТаблицаИзКэша = МодульМетаданных.ТаблицыСлов[КлючКэша]; // см. НоваяТаблицаСлов() Если Истина И Не ВычислятьТипыМетодовМодулей И СловоФильтр = Неопределено И ТипСловаФильтр = Неопределено И Не ЗначениеЗаполнено(ДляСвойства) Тогда Если ТаблицаИзКэша <> Неопределено Тогда Возврат СлитьТаблицыСлов(ТаблицаСловПриемник, ТаблицаИзКэша); КонецЕсли; Иначе КлючКэша = Неопределено; КонецЕсли; КонецЕсли; Если ТаблицаСловПриемник = Неопределено Или КлючКэша <> Неопределено Тогда ТаблицаСлов = НоваяТаблицаСлов(); Если ТаблицаСловПриемник = Неопределено Тогда ТаблицаСловПриемник = ТаблицаСлов; КонецЕсли; Иначе ТаблицаСлов = ТаблицаСловПриемник; КонецЕсли; МетаданныеРодителя = СтруктураТипаМини.Метаданные; // см. Метаданные.ОбщиеМодули[0] ЛиИмяМодуляФормы = ЛиИмяМодуляФормы(МодульМетаданных.Имя); ОтборСловМодуля = Новый Структура; Если ТолькоЭкспорт Тогда ОтборСловМодуля.Вставить("ЛиЭкспорт", Истина); КонецЕсли; Если ЗначениеЗаполнено(СловоФильтр) Тогда ОтборСловМодуля.Вставить("НИмя", НРег(СловоФильтр)); КонецЕсли; Если Истина И Не ТолькоЭкспорт И ФлагиКомпиляции <> Неопределено И ЛиИмяМодуляФормы Тогда //Если ФлагиКомпиляции.Сервер Тогда // ОтборСловМодуля.Вставить("Сервер", Истина); //КонецЕсли; //Если ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение Тогда // ОтборСловМодуля.Вставить("Клиент", Истина); //КонецЕсли; Если Не (ФлагиКомпиляции.КлиентОбычноеПриложение Или ФлагиКомпиляции.КлиентУправляемоеПриложение) Тогда //ОтборСловМодуля.Вставить("Клиент", Ложь); // - Не учитывает двусторонние методы ОтборСловМодуля.Вставить("Сервер", Истина); КонецЕсли; КонецЕсли; Если Истина И (Ложь Или ФлагиКомпиляции = Неопределено Или Не ФлагиКомпиляции.БезКонтекста) И (Ложь Или ТипСловаФильтр = Неопределено Или ТипСловаФильтр = "Свойство") Тогда ПеременныеМодуля = МодульМетаданных.Переменные; Если ОтборСловМодуля.Количество() > 0 Тогда ПодходящиеПеременные = ПеременныеМодуля.НайтиСтроки(ОтборСловМодуля); Иначе ПодходящиеПеременные = ПеременныеМодуля; КонецЕсли; КомпонентаПодсказки = Неопределено; ТипСловаЦикл = "Свойство"; Для Каждого ПеременнаяМодуля Из ПодходящиеПеременные Цикл ТаблицаТипов = Неопределено; Если ВычислятьТипы Тогда Если Истина И ВычислятьТипыМетодовМодулей //И ПеременнаяМодуля.ПозицияСОписанием > 0 // так отбросим все специальные переменные модуля Тогда ТаблицаТипов = ПодготовитьТипЗначенияПеременнойМодуля(ПеременнаяМодуля, МодульМетаданных, КомпонентаПодсказки, ДляСвойства); КонецЕсли; ТаблицаТипов = ТаблицаТиповСловаМодуля(ПеременнаяМодуля, МодульМетаданных, ТаблицаТипов); Иначе ПодготовитьОписаниеПеременнойМодуля(ПеременнаяМодуля); КонецЕсли; ДобавитьВТаблицуСловЭлементМодуляМетаданных(ТаблицаСлов, ПеременнаяМодуля.Имя, ВычислятьТипы, ТаблицаИзКэша, ТаблицаТипов, ПеременнаяМодуля.ТипЗначения, ТипСловаЦикл, ПеременнаяМодуля.ПозицияОпределения <> 0); КонецЦикла; КонецЕсли; Если Истина И Не ТолькоЭкспорт И ФлагиКомпиляции <> Неопределено И ЛиИмяМодуляФормы Тогда Если ФлагиКомпиляции.БезКонтекста Тогда ОтборСловМодуля.Вставить("БезКонтекста", Истина); КонецЕсли; КонецЕсли; Если Ложь Или ТипСловаФильтр = Неопределено Или ТипСловаФильтр = ПеречТипСлова.Метод Тогда МетодыМодуля = МодульМетаданных.Методы; Если ОтборСловМодуля.Количество() > 0 Тогда ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля); Если Истина И Не ЛиВместеСЛокальнымКонтекстом И ПодходящиеМетоды.Количество() = 0 И ЗначениеЗаполнено(СловоФильтр) И СтруктураТипаМини.ИмяОбщегоТипа <> "Глобальный" И Не СтрогийФильтр Тогда ОтборСловМодуля.Вставить("НИмя", "<>"); ПодходящиеМетоды = МетодыМодуля.НайтиСтроки(ОтборСловМодуля); КонецЕсли; Иначе ПодходящиеМетоды = МетодыМодуля; КонецЕсли; ВычислятьТипы = Ложь Или ЗначениеЗаполнено(СловоФильтр) Или ВычислятьТипы; //Если ЗначениеЗаполнено(СловоФильтр) Тогда // ВычислятьТипыМетодовМодулей = Истина; // Лишнее при вычислении описания обрамляющего метода для текстового литерала //КонецЕсли; Если ВычислятьТипыМетодовМодулей И ПодходящиеМетоды.Количество() > 100 Тогда Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ПодходящиеМетоды.Количество(), "Вычисление типов функций"); Иначе Индикатор = Неопределено; КонецЕсли; ТипСловаЦикл = ПеречТипСлова.Метод; РазделительВариантаКонтекста = РазделительВариантаКонтекста(); Для Каждого МетодМодуля Из ПодходящиеМетоды Цикл Если Индикатор <> Неопределено Тогда ирОбщий.ОбработатьИндикаторЛкс(Индикатор); КонецЕсли; ИмяМетода = МетодМодуля.Имя; Если Ложь Или ТолькоСоЗначениями И ПустаяСтрока(МетодМодуля.ТипЗначения) Или БезПараметров И ЗначениеЗаполнено(МетодМодуля.Параметры) Или ИмяМетода = "<>" И ПустаяСтрока(СловоФильтр) Тогда Продолжить; КонецЕсли; Если ВнутриГруппыОбщихМодулей Тогда ИмяМетода = ИмяМетода + " - " + МетаданныеРодителя.Имя; КонецЕсли; ТаблицаТипов = Неопределено; Если ВычислятьТипы Тогда Если ВычислятьТипыМетодовМодулей Тогда ТаблицаТипов = ПодготовитьТипРезультатаМетода(МетодМодуля, МодульМетаданных,,, ДляСвойства); КонецЕсли; ТаблицаТипов = ТаблицаТиповСловаМодуля(МетодМодуля, МодульМетаданных, ТаблицаТипов); Иначе ПодготовитьОписаниеРезультатаМетода(МетодМодуля); КонецЕсли; ДобавитьВТаблицуСловЭлементМодуляМетаданных(ТаблицаСлов, ИмяМетода, ВычислятьТипы, ТаблицаИзКэша, ТаблицаТипов, МетодМодуля.ТипЗначения, ТипСловаЦикл); КонецЦикла; Если Индикатор <> Неопределено Тогда ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); КонецЕсли; КонецЕсли; Если КлючКэша <> Неопределено Тогда МодульМетаданных.ТаблицыСлов[КлючКэша] = ТаблицаСлов; ТаблицаСловПриемник = СлитьТаблицыСлов(ТаблицаСловПриемник, ТаблицаСлов); КонецЕсли; Возврат ТаблицаСловПриемник; КонецФункции //. // Параметры: // ТаблицаПриемник - ТаблицаЗначений - // Таблица2 - ТаблицаЗначений - Функция СлитьТаблицыСлов(Знач ТаблицаПриемник, Знач Таблица2) Экспорт Если Таблица2.Количество() > ТаблицаПриемник.Количество() Тогда ТаблицаИсточник = ТаблицаПриемник; ТаблицаПриемник = Таблица2.Скопировать(); Иначе ТаблицаИсточник = Таблица2; КонецЕсли; //ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ТаблицаИсточник, ТаблицаПриемник); Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл Если СтрокаИсточника.ТипСлова = ПеречТипСлова.Метод Или СтрокаИсточника.МожноУточнитьТип = Ложь Тогда ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаИсточника); Иначе // Убираем дубли реквизитов продублированных в переменных модуля ДобавитьВТаблицуСлов(ТаблицаПриемник, СтрокаИсточника.Слово, СтрокаИсточника.ТипСлова, СтрокаИсточника.ТаблицаТипов, СтрокаИсточника.ТипЗначения, СтрокаИсточника.Определение); КонецЕсли; КонецЦикла; Возврат ТаблицаПриемник; КонецФункции Функция ДобавитьВТаблицуСловЭлементМодуляМетаданных(Знач ТаблицаСлов, Знач Слово, Знач ВычислятьТипы, Знач ТаблицаИзКэша, Знач ТаблицаТипов, Знач ТипЗначения, Знач ТипСлова, Знач ВытеснятьСвойство = Истина) Экспорт Если Слово <> "<>" И ТипЗначения <> Неопределено Тогда Если Истина И ВычислятьТипы И ТаблицаИзКэша <> Неопределено Тогда Если ЛиВСтрокеТиповЕстьКонструктор(ТипЗначения) Тогда ТипЗначения = ПредставлениеМассиваСтруктурТипов(ТаблицаТипов); КонецЕсли; ТипЗначенияИндекс = ТипЗначенияИндексИзТипа(ТипЗначения); Если Не ирОбщий.СтрНачинаетсяСЛкс(ТипЗначения, "??") Тогда ТипЗначения = "??" + ?(ПустаяСтрока(ТипЗначения), "", ", " + ТипЗначения); КонецЕсли; КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова); Найденные = ТаблицаИзКэша.НайтиСтроки(КлючПоиска); Если Найденные.Количество() > 0 Тогда Найденные[0].ТипЗначения = ТипЗначения; Найденные[0].ТипЗначенияИндекс = ТипЗначенияИндекс; КонецЕсли; Иначе ТипЗначенияИндекс = ТипЗначенияИндексИзТипа(ТипЗначения); Если Не ирОбщий.СтрНачинаетсяСЛкс(ТипЗначения, "??") Тогда ТипЗначения = "??" + ?(ПустаяСтрока(ТипЗначения), "", ", " + ТипЗначения); КонецЕсли; КонецЕсли; КонецЕсли; ДобавитьВТаблицуСлов(ТаблицаСлов, Слово, ТипСлова, ТаблицаТипов, ТипЗначения, "Метаданные", ВытеснятьСвойство,,,, ТипЗначенияИндекс); Возврат ТипЗначения; КонецФункции Функция ТипЗначенияИндексИзТипа(Знач ТипЗначения) Экспорт ТипЗначенияИндекс = ирОбщий.ПервыйФрагментЛкс(ТипЗначения, "("); ТипЗначенияИндекс = СтрЗаменить(ТипЗначенияИндекс, ", Неопределено", ""); ТипЗначенияИндекс = СтрЗаменить(ТипЗначенияИндекс, "??, ", ""); Если Лев(ТипЗначенияИндекс, 3) = "см." Тогда // оставляем только последний фрагмент полного указателя на описание типа, т.к. его достаточно чтобы подбирать подходящие слова ТипЗначенияИндекс = "см. " + СокрЛП(ирОбщий.ПоследнийФрагментЛкс(ТипЗначенияИндекс)); КонецЕсли; Возврат ТипЗначенияИндекс; КонецФункции Функция РазделительВариантаКонтекста() Экспорт Возврат " - "; КонецФункции //. // Параметры: // МетодМодуля - СтрокаТаблицыЗначений - // Возвращаемое значение: // ТаблицаЗначений - Функция ТаблицаТиповСловаМодуля(Знач СловоМодуля, Знач МодульМетаданных, Знач ТаблицаТипов = Неопределено) Экспорт Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = СловоМодуля.ТаблицаТипов; КонецЕсли; Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов(); ИначеЕсли СловоМодуля.ТаблицаТипов = ТаблицаТипов Тогда ТаблицаТипов = ТаблицаТипов.Скопировать(); // Мультиметка4529884 против циклической ссылки КонецЕсли; Если ТаблицаТипов.Количество() = 0 Тогда СтруктураТипа = ТаблицаТипов.Добавить(); Если ЗначениеЗаполнено(СловоМодуля.ТипЗначения) Тогда Если СловоМодуля.Имя = "<>" Тогда СтруктураТипа.ИмяОбщегоТипа = СловоМодуля.ТипЗначения; Иначе СтруктураТипа.ИмяОбщегоТипа = ""; КонецЕсли; КонецЕсли; ОбновитьДетальностьСтруктурыТипа(СтруктураТипа); КонецЕсли; ТаблицаТипов.ЗаполнитьЗначения(СловоМодуля, "СтрокаОписания"); // Мультиметка4529884 против циклической ссылки СловоМодуля.ИмяМодуля = МодульМетаданных.Имя; Возврат ТаблицаТипов; КонецФункции Функция ПодготовитьМодульМетаданных(Знач СтруктураТипа, Знач ТипМодуля = "", выхИмяМодуля = "", Знач НовыйТекст = Неопределено, Знач ТекущаяПозиция = Неопределено) Экспорт ВерсияФормата = ВерсияФорматаКэшаМодулей(); СтрокаСозданияРодителя = ""; ФлагиКомпиляции = Неопределено; // см. НовыеФлагиКомпиляции() выхИмяМодуля = ИмяМодуляИзСтруктурыТипа(СтруктураТипа, ТипМодуля, СтрокаСозданияРодителя, ФлагиКомпиляции); Если ЗначениеЗаполнено(выхИмяМодуля) Тогда МодульМетаданных = МодульМетаданныхИзКэша(выхИмяМодуля); // см. МодульМетаданных - для ускорения расчета типа Если Ложь Или МодульМетаданных = Неопределено Или НовыйТекст <> Неопределено И МодульМетаданных.Текст <> НовыйТекст Тогда //ПроверитьСтруктуруФайловогоКэша(); #Если Сервер И Не Сервер Тогда ПапкаКэшаМодулей = Новый Файл; #КонецЕсли ФайлМодуля = ФайлМодуляИзИмениМодуля(выхИмяМодуля); ТекстовыйДокумент = Новый ТекстовыйДокумент; СтарыйТекст = Неопределено; Если НовыйТекст <> Неопределено Тогда Если МодульМетаданных <> Неопределено Тогда СтарыйТекст = МодульМетаданных.Текст; КонецЕсли; Если СтарыйТекст = Неопределено И ФайлМодуля.Существует() Тогда ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя); СтарыйТекст = ТекстовыйДокумент.ПолучитьТекст(); КонецЕсли; Если СтарыйТекст <> НовыйТекст Тогда ТекстовыйДокумент.УстановитьТекст(НовыйТекст); //Если Найти(выхИмяМодуля, " ") > 0 Тогда // проверка на расширение ФайлКаталог = Новый Файл(ФайлМодуля.Путь); Если Не ФайлКаталог.Существует() Тогда СоздатьКаталог(ФайлКаталог.ПолноеИмя); КонецЕсли; //КонецЕсли; Если ирКэш.НомерРежимаСовместимостиЛкс() >= 803018 Тогда ТекстовыйДокумент.ЗаписатьАсинх(ФайлМодуля.ПолноеИмя); // не видим исключения из-за асинхронности! Иначе ТекстовыйДокумент.Записать(ФайлМодуля.ПолноеИмя); КонецЕсли; КонецЕсли; КонецЕсли; ФайлОписанияМодуля = ФайлМодуляИзИмениМодуля(выхИмяМодуля, "ixd"); ОбновитьФайлОписания = Истина; Если Истина И МодульМетаданных = Неопределено //И ФайлОписанияМодуля.Существует() Тогда МодульМетаданных = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлОписанияМодуля.ПолноеИмя,, "Внутр", Ложь); // см. МодульМетаданных() - временно читаем без вывода ошибок для перехода XML->JSON ОбновитьФайлОписания = Ложь Или МодульМетаданных = Неопределено Или СтарыйТекст <> НовыйТекст Или (Истина И ФайлМодуля.Существует() И ФайлМодуля.ПолучитьВремяИзменения() > ФайлОписанияМодуля.ПолучитьВремяИзменения()); Если Ложь Или ТипЗнч(МодульМетаданных) <> Тип("Структура") Или ирОбщий.СвойствоСтруктурыЛкс(МодульМетаданных, "ВерсияФормата") <> ВерсияФормата Или МодульМетаданных.Имя <> выхИмяМодуля // Антибаг ИР. В старых версиях где то писалось пустое имя в кэш Тогда // Старый формат кэша ОбновитьФайлОписания = Истина; МодульМетаданных = Неопределено; Иначе // Мультиметка723368140 МодульМетаданных.Текст = СтарыйТекст; // Может установиться Неопределено ирОбщий.СкопироватьКолонкиКоллекцииЛкс(НоваяТаблицаМетодовМодуля(), МодульМетаданных.Методы); КонецЕсли; КонецЕсли; СтарыйМодуль = Неопределено; Если ОбновитьФайлОписания Тогда Если Не ФайлМодуля.Существует() И НовыйТекст = Неопределено Тогда Если СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось <> Истина Тогда // Может выводиться неоправданно, если модуль пуст. В этом случае конфигуратор не выгружает файл. Поэтому уведомляем только о полной пустоте кэша ФайлыМодулей = НайтиФайлы(ПапкаКэшаМодулей.ПолноеИмя, ИмяКонтрольногоФайлаКэшаМодулей()); Если ФайлыМодулей.Количество() = 0 Тогда #Если Клиент Тогда ирКлиент.ОткрытьНастройкиПоляПрограммыНаЗаднемПланеЛкс(); #КонецЕсли КонецЕсли; СообщениеОНеобходимостиОбновитьКэшМодулейВыводилось = Истина; КонецЕсли; МодульМетаданных = МодульМетаданных("", СтруктураТипа, выхИмяМодуля); Иначе Если НовыйТекст = Неопределено Тогда ТекстовыйДокумент.Прочитать(ФайлМодуля.ПолноеИмя); НовыйТекст = ТекстовыйДокумент.ПолучитьТекст(); МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяМодуля,,,, ФлагиКомпиляции); ЗаписатьМодульВКэш(МодульМетаданных); Иначе СтарыйМодуль = МодульМетаданных; МодульМетаданных = МодульМетаданных(НовыйТекст, СтруктураТипа, выхИмяМодуля, Ложь, МодульМетаданных, ТекущаяПозиция, ФлагиКомпиляции); // Т.к. в этом сценарии часто будет обновление текста модуля происходить, то не будем тратить время на обновление индекса в файле, но удалим его чтобы потом дату изменения не сверять УдалитьФайлы(ФайлОписанияМодуля.Путь, ФайлОписанияМодуля.ИмяБезРасширения + ".i*"); // Все расширения файлов индексов начинаются с "i" Если мВызовыВсехСловПоМодулям <> Неопределено Тогда мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяМодуля, Истина)] = Неопределено; мВызовыВсехСловПоМодулям[КлючКэшаВызововСловаПоМодулю(выхИмяМодуля, Ложь)] = Неопределено; КонецЕсли; КонецЕсли; //ирОбщий.СообщитьЛкс(ФайлМодуля.ПолноеИмя); // Отладка //УдалитьФайлы(ФайлМодуля.ПолноеИмя); КонецЕсли; КонецЕсли; мМодулиМетаданных[НРег(выхИмяМодуля)] = МодульМетаданных; Если МодульМетаданных.ЗапретыКомпиляции.Свойство("ТонкийКлиент") Тогда ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь; КонецЕсли; МодульМетаданных.СтруктураТипа = СтруктураТипа; МодульМетаданных.ФлагиКомпиляции = ФлагиКомпиляции; Если ФлагиКомпиляции.КлиентУправляемоеПриложение И Не ФлагиКомпиляции.КлиентОбычноеПриложение Тогда // Для видимости толстого контекста в управляемой форме ФлагиКомпиляции.КлиентОбычноеПриложение = ирОбщий.СтрНачинаетсяСЛкс(СокрЛ(НовыйТекст), "#Если ТолстыйКлиент"); КонецЕсли; МодульМетаданных.Вставить("СтрокаСоздания", СтрокаСозданияРодителя); МодульМетаданных.Вставить("ТипМодуля", ТипМодуля); МодульМетаданных.Вставить("ВерсияФормата", ВерсияФормата); Если МодульМетаданных <> Неопределено И СтарыйМодуль <> МодульМетаданных Тогда #Если Сервер И Не Сервер Тогда МетодыМодуля = Новый ТаблицаЗначений; #КонецЕсли БазовыйТип = ирОбщий.ПервыйФрагментЛкс(СтруктураТипа.ИмяОбщегоТипа); ЛиИмяТипаФормы = ирОбщий.ЛиИмяТипаФормыЛкс(БазовыйТип, Истина); Если Истина И МодульМетаданных <> мПустойМодуль И (Ложь Или ирОбщий.СтрКончаетсяНаЛкс(БазовыйТип, "Объект") Или ЛиИмяТипаФормы) Тогда // Добавим в переменные модуля реквизиты объекта с изменяемыми метаданными, чтобы уточнять их тип по коду Для Каждого СтрокаПеременной Из МодульМетаданных.Переменные.НайтиСтроки(Новый Структура("ПозицияСОписанием", 0)) Цикл МодульМетаданных.Переменные.Удалить(СтрокаПеременной); КонецЦикла; ИнициацияОписанияМетодовИСвойств(); ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов("Свойство",,,,,,,,, ПустойМодульМетаданных()); ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, ПараметрыЗаполнения); Если ЛиИмяТипаФормы Тогда ТаблицаСлов.Добавить().Слово = "ВладелецФормы"; КонецЕсли; Для Каждого СтрокаСлова Из ТаблицаСлов Цикл // TODO добавить фильтр по типу Если ЛиДетальностьТиповДостаточна(СтрокаСлова.ТаблицаТипов) Тогда ИмяОбщегоТипаСлова = СтрокаСлова.ТаблицаТипов[0].ИмяОбщегоТипа; Если Истина И ИмяОбщегоТипаСлова <> "ТаблицаЗначений" И ИмяОбщегоТипаСлова <> "ДеревоЗначений" И ИмяОбщегоТипаСлова <> "КомпоновщикНастроек" И ИмяОбщегоТипаСлова <> "ХранилищеЗначения" И ИмяОбщегоТипаСлова <> "Строка" // Мультиметка62766134 Тогда Продолжить; Иначе // В них часто добавляются неинтерактивные колонки КонецЕсли; КонецЕсли; СтрокаПеременной = МодульМетаданных.Переменные.Добавить(); СтрокаПеременной.Имя = СтрокаСлова.Слово; СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя); СтрокаПеременной.ЛиЭкспорт = Истина; // Нельзя опираться на эти типы, т.к. они очищаются чаще чем сюда приходим // Изначально использовал, чтобы добавляемые в модуле формы колонки реквизита-таблицы учитывались //СтрокаПеременной.ТаблицаТипов = СтрокаСлова.ТаблицаТипов; КонецЦикла; КонецЕсли; КонецЕсли; Иначе МодульМетаданных.Имя = выхИмяМодуля; // Нужно для единого пустого модуля, чтобы виртуальные методы в нем имели правильное имя модуля КонецЕсли; КонецЕсли; Возврат МодульМетаданных; КонецФункции //. // Возвращаемое значение: // Структура, Неопределено - Функция ПустойМодульМетаданных() Экспорт МодульВременный = МодульМетаданных("",, "кэш"); МодульВременный.Переменные.Очистить(); // Иногда там остаются какие то переменные Возврат МодульВременный; КонецФункции //. // Возвращаемое значение: // Число - Функция ВерсияФорматаКэшаМодулей() Экспорт Возврат 24; // Мультиметка91237881041 Каждый раз при изменении структуры увеличиваем на 1 КонецФункции Функция ПеречТипСлова() Экспорт Если ПеречТипСлова = Неопределено Тогда ПеречТипСлова = ирОбщий.ПеречТипСловаЛкс(); КонецЕсли; Возврат ПеречТипСлова; КонецФункции Функция ПеречИсточникСлова() Экспорт Если ПеречИсточникСлова = Неопределено Тогда ПеречИсточникСлова = ирОбщий.НовоеПеречислениеЛкс("Локальный, Статистический, Метаданные, Предопределенный"); КонецЕсли; Возврат ПеречИсточникСлова; КонецФункции // Возращает таблицу вызовов слова через точку. // Параметры: // ИмяМодуля - Строка - // ТекстовыйДокумент - ТекстовыйДокумент - // Файл - Файл - // ПолеТекстаПрограммы - ОбработкаОбъект.ирКлсПолеТекстаПрограммы // Возвращаемое значение: // ТаблицаЗначений - Функция НепрямыеВызовыСловаВМодуле(Знач ИмяМодуля, Знач ТекстовыйДокумент, Знач Файл, Знач ПолеТекстаПрограммы, Знач ИскатьСлово, Знач ЛиМетод = Истина) Экспорт Если ЛиМетод Тогда //ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками +"\.)("+шИмя+")\s*\(((?:(?:"+ПолеТекстаПрограммы.шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*)\)"; //ИндексГруппыВШаблоне = 0; ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шОбъектноеВыражение+"\.)("+шИмя+")\s*\(((?:(?:"+ПолеТекстаПрограммы.шВыражениеПрограммы+")?"+шРазделитель+"*(?=[,\)])|,)*)\)"; ИндексГруппыВШаблоне = 3; Расширение = "icl"; Иначе //ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шИмяСТочками +"\.)("+шИмя+")(?!\s*[\(])"+ПолеТекстаПрограммы.шПостИмяСвойства; //ИндексГруппыВШаблоне = 0; ШаблонВнешнегоВызова = ПолеТекстаПрограммы.шПредИмяПрямое+"(?:"+ПолеТекстаПрограммы.шОбъектноеВыражение+"\.)("+шИмя+")(?!\s*[\(])"+ПолеТекстаПрограммы.шПостИмяСвойства; ИндексГруппыВШаблоне = 3; Расширение = "ipr"; КонецЕсли; Если мВызовыВсехСловПоМодулям = Неопределено Тогда мВызовыВсехСловПоМодулям = Новый Соответствие; КонецЕсли; КлючКэша = КлючКэшаВызововСловаПоМодулю(ИмяМодуля, ЛиМетод); ИндексВызововМодуля = мВызовыВсехСловПоМодулям[КлючКэша]; Если ИндексВызововМодуля = Неопределено Тогда Если ИмяМодуля = ИмяДинамическогоМодуля() Тогда ОбновитьИндекс = Истина; ИмяФайлаИндекса = Неопределено; КлючКэша = Неопределено; Иначе ВерсияФорматаИндекса = 11; ИмяФайлаИндекса = ИмяФайлаМодуляИзИмениМодуля(ИмяМодуля, Расширение); //ОбновитьИндекс = Не ФайлИндекса.Существует(); // Долго ОбновитьИндекс = Ложь; Если Не ОбновитьИндекс Тогда Попытка ИндексВызововМодуля = ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ИмяФайлаИндекса,, "Внутр", Ложь); // - временно читаем без вывода ошибок для перехода XML->JSON->Внутр Исключение // Экономим на проверке существования файла КонецПопытки; //! ИндексВызововМодуля = Новый Структура(ИменаСвойствИндекса); Если Ложь Или ТипЗнч(ИндексВызововМодуля) <> Тип("Структура") Или ИндексВызововМодуля.ВерсияФормата <> ВерсияФорматаИндекса Тогда // Старый формат кэша ОбновитьИндекс = Истина; ИндексВызововМодуля = Неопределено; ИначеЕсли Не ИндексВызововМодуля.Свойство("ДатаИзменения") Тогда ИндексВызововМодуля.Вставить("ДатаИзменения"); КонецЕсли; КонецЕсли; КонецЕсли; Если ОбновитьИндекс Тогда ТекстМодуля = ТекстовыйДокумент.ПолучитьТекст(); ИндексВызововМодуля = НовыйИндексПоискаВызововСловаВМодуле(, ВерсияФорматаИндекса); ЗаполнитьИндексПоискаВызововСловаВМодуле(ИндексВызововМодуля, ТекстМодуля, ШаблонВнешнегоВызова,, Истина,, ИндексГруппыВШаблоне); Если ИмяФайлаИндекса <> Неопределено Тогда ирОбщий.СохранитьЗначениеВФайлЛкс(ИндексВызововМодуля, ИмяФайлаИндекса,,, "Внутр"); КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(ИндексВызововМодуля.ДатаИзменения) Тогда ИндексВызововМодуля.ДатаИзменения = Файл.ПолучитьВремяИзменения(); // - пока не стал использовать, чтобы не замедлять код ради редкого сценария КонецЕсли; ирОбщий.ДобавитьИндексВТаблицуЛкс(ИндексВызововМодуля.Вызовы, "НомерСлова"); Если КлючКэша <> Неопределено Тогда мВызовыВсехСловПоМодулям[КлючКэша] = ИндексВызововМодуля; КонецЕсли; КонецЕсли; НомерСлова = 0; Результат = Новый Массив; Если ИндексВызововМодуля.СтруктураСлов.Свойство(ИскатьСлово, НомерСлова) Тогда Результат = ИндексВызововМодуля.Вызовы.НайтиСтроки(Новый Структура("НомерСлова", НомерСлова)); КонецЕсли; Возврат Результат; КонецФункции //. // Параметры: // ТекстМодуля - Строка - // ШаблонВнешнегоВызова - Строка - регулярное выражение, где в первой группе находится слово Функция НовыйИндексПоискаВызововСловаВМодуле(Знач Модуль = Неопределено, Знач ВерсияФорматаИндекса = 0, Знач ЛиИскатьОповещения = Неопределено) Экспорт Если ЛиИскатьОповещения = Неопределено Тогда ЛиИскатьОповещения = Истина И Модуль <> Неопределено И Модуль.СтруктураТипа <> Неопределено И (Ложь Или (Истина И Модуль.ФлагиКомпиляции.КлиентУправляемоеПриложение И Не Модуль.ФлагиКомпиляции.Сервер) Или ирОбщий.ЛиИмяТипаФормыЛкс(Модуль.СтруктураТипа.ИмяОбщегоТипа)); КонецЕсли; ТаблицаВызовов = Новый ТаблицаЗначений; ТаблицаВызовов.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число")); ТаблицаВызовов.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число")); ТаблицаВызовов.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка")); ТаблицаВызовов.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число")); СтруктураСлов = Новый Структура; Если ЛиИскатьОповещения Тогда ТаблицаОповещений = Новый ТаблицаЗначений; ТаблицаОповещений.Колонки.Добавить("ПозицияВхождения", Новый ОписаниеТипов("Число")); ТаблицаОповещений.Колонки.Добавить("ДлинаВхождения", Новый ОписаниеТипов("Число")); ТаблицаОповещений.Колонки.Добавить("Слово", Новый ОписаниеТипов("Строка")); ТаблицаОповещений.Колонки.Добавить("Параметр", Новый ОписаниеТипов("Строка")); ТаблицаОповещений.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число")); КонецЕсли; ИндексВызововМодуля = Новый Структура("ВерсияФормата, Вызовы, СтруктураСлов, Оповещения, ДатаИзменения"); ИндексВызововМодуля.ВерсияФормата = ВерсияФорматаИндекса; ИндексВызововМодуля.Вызовы = ТаблицаВызовов; ИндексВызововМодуля.Оповещения = ТаблицаОповещений; ИндексВызововМодуля.СтруктураСлов = СтруктураСлов; Возврат ИндексВызововМодуля; КонецФункции //. // Параметры: // ТекстБлока - Строка - // ШаблонВнешнегоВызова - Строка - регулярное выражение, где в первой группе находится слово // ШаблонОповещения - Строка - // СВложенными - Булево - // Смещение - Число - // ТаблицаВызовов - ТаблицаЗначений - // ТаблицаОповещений - ТаблицаЗначений - Процедура ЗаполнитьИндексПоискаВызововСловаВМодуле(Знач ИндексВызововМодуля, Знач ТекстБлока, Знач ШаблонВнешнегоВызова, Знач ШаблонОповещения = "", Знач СВложенными = Ложь, Знач Смещение = 0, Знач ИндексГруппыВШаблоне = 0) Экспорт Если ТекстБлока = Неопределено Тогда ВызватьИсключение "Текст модуля не загружен в память"; КонецЕсли; ТаблицаВызовов = ИндексВызововМодуля.Вызовы; РегВыражение = ирКэш.ВычислительРегВыраженийЛкс(); РегВыражение.IgnoreCase = Истина; РегВыражение.Global = Истина; РегВыражение.Pattern = ШаблонВнешнегоВызова; Вхождения = РегВыражение.НайтиВхождения(ТекстБлока,, Истина); ДобавитьВхожденияСловаВИндекс(Вхождения, РегВыражение, ТаблицаВызовов, СВложенными, Смещение, ИндексГруппыВШаблоне); НумероватьСловаВИндексе(ТаблицаВызовов, ИндексВызововМодуля.СтруктураСлов); Если ЗначениеЗаполнено(ШаблонОповещения) Тогда ТаблицаОповещений = ИндексВызововМодуля.Оповещения; РегВыражение.Pattern = ШаблонОповещения; Вхождения = РегВыражение.НайтиВхождения(ТекстБлока,, Истина); Для Каждого Вхождение Из Вхождения Цикл СтрокаРезультата = ТаблицаОповещений.Добавить(); СтрокаРезультата.ПозицияВхождения = Смещение + Вхождение.FirstIndex; СтрокаРезультата.ДлинаВхождения = Вхождение.Length; СтрокаРезультата.Слово = Вхождение.SubMatches(0); СтрокаРезультата.Параметр = Вхождение.SubMatches(1); КонецЦикла; НумероватьСловаВИндексе(ТаблицаОповещений, ИндексВызововМодуля.СтруктураСлов); КонецЕсли; КонецПроцедуры //. // Параметры: // Вхождения - Массив из ОбработкаОбъект.ирОболочкаРегВхождение - // РегВыражение - ОбработкаОбъект.ирОболочкаРегВыражение - // ТаблицаВызовов - ТаблицаЗначений - // Смещение - Число - // _РежимОтладки - Булево - Процедура ДобавитьВхожденияСловаВИндекс(Знач Вхождения, Знач РегВыражение, Знач ТаблицаВызовов, Знач СВложенными = Ложь, Знач Смещение = 0, Знач ИндексГруппыВШаблоне = 0) Экспорт ИндексГруппыПараметровВШаблоне = ИндексГруппыВШаблоне + 1; _РежимОтладки = Ложь; Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого Вхождение Из Вхождения Цикл СтрокаРезультата = ТаблицаВызовов.Добавить(); СтрокаРезультата.ПозицияВхождения = Смещение + Вхождение.FirstIndex; СтрокаРезультата.ДлинаВхождения = Вхождение.Length; СтрокаРезультата.Слово = Вхождение.SubMatches(ИндексГруппыВШаблоне); Если СВложенными Тогда Если Вхождение.SubMatches.Count > ИндексГруппыПараметровВШаблоне Тогда ПараметрыВызова = Вхождение.SubMatches(ИндексГруппыПараметровВШаблоне); Если Найти(ПараметрыВызова, "(") > 0 Тогда ВхожденияВложенные = РегВыражение.НайтиВхождения(" " + ПараметрыВызова,, Истина); ДобавитьВхожденияСловаВИндекс(ВхожденияВложенные, РегВыражение, ТаблицаВызовов, Истина, Вхождение.FirstIndex + Найти(Вхождение.Value, ПараметрыВызова) - 2, ИндексГруппыВШаблоне); КонецЕсли; Иначе Если Вхождение.FirstIndex > 0 Тогда Текст = Сред(Вхождение.Value, 2); СмещениеДлины = 1; Иначе Текст = Вхождение.Value; СмещениеДлины = 0; КонецЕсли; ЧислоТочек = СтрЧислоВхождений(Текст, "."); Пока ЧислоТочек > 0 Цикл Текст = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(Текст); СтрокаВложенная = ТаблицаВызовов.Добавить(); СтрокаВложенная.ПозицияВхождения = СтрокаРезультата.ПозицияВхождения; СтрокаВложенная.ДлинаВхождения = СтрДлина(Текст) + СмещениеДлины; СтрокаВложенная.Слово = ирОбщий.ПоследнийФрагментЛкс(Текст); ЧислоТочек = ЧислоТочек - 1; КонецЦикла; КонецЕсли; КонецЕсли; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для Каждого Вхождение Из Вхождения Цикл   СтрокаРезультата = ТаблицаВызовов.Добавить();   СтрокаРезультата.ПозицияВхождения = Смещение + Вхождение.FirstIndex;   СтрокаРезультата.ДлинаВхождения = Вхождение.Length;   СтрокаРезультата.Слово = Вхождение.SubMatches(ИндексГруппыВШаблоне);   Если СВложенными Тогда   Если Вхождение.SubMatches.Count > ИндексГруппыПараметровВШаблоне Тогда   ПараметрыВызова = Вхождение.SubMatches(ИндексГруппыПараметровВШаблоне);   Если Найти(ПараметрыВызова, "(") > 0 Тогда   ВхожденияВложенные = РегВыражение.НайтиВхождения(" " + ПараметрыВызова,, Истина);   ДобавитьВхожденияСловаВИндекс(ВхожденияВложенные, РегВыражение, ТаблицаВызовов, Истина, Вхождение.FirstIndex + Найти(Вхождение.Value, ПараметрыВызова) - 2, ИндексГруппыВШаблоне);   КонецЕсли;   Иначе   Если Вхождение.FirstIndex > 0 Тогда   Текст = Сред(Вхождение.Value, 2);   СмещениеДлины = 1;   Иначе   Текст = Вхождение.Value;   СмещениеДлины = 0;   КонецЕсли;   ЧислоТочек = СтрЧислоВхождений(Текст, ".");   Пока ЧислоТочек > 0 Цикл   Текст = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(Текст);   СтрокаВложенная = ТаблицаВызовов.Добавить();   СтрокаВложенная.ПозицияВхождения = СтрокаРезультата.ПозицияВхождения;   СтрокаВложенная.ДлинаВхождения = СтрДлина(Текст) + СмещениеДлины;   СтрокаВложенная.Слово = ирОбщий.ПоследнийФрагментЛкс(Текст);   ЧислоТочек = ЧислоТочек - 1;   КонецЦикла;   КонецЕсли;   КонецЕсли;   КонецЦикла;   КонецЕсли; КонецПроцедуры //. // Параметры: // ТаблицаВызовов - ТаблицаЗначений - // Слово - Строка(0) - // _РежимОтладки - Булево - // Возвращаемое значение: // Структура - Функция НумероватьСловаВИндексе(ТаблицаВызовов, СтруктураСлов) Экспорт _РежимОтладки = Ложь; ВременныйИндекс = ирОбщий.ДобавитьИндексВТаблицуЛкс(ТаблицаВызовов, "Слово"); МассивСлов = ирОбщий.РазличныеЗначенияКолонкиТаблицыЛкс(ТаблицаВызовов, "Слово"); ПервыйСвободныйНомерСлова = СтруктураСлов.Количество(); СтарыйНомерСлова = 0; //ТаблицаВызовов.Колонки.Добавить("НомерСлова", Новый ОписаниеТипов("Число")); // Вынес наружу для анализатора кода Для Каждого Слово Из МассивСлов Цикл Если Не СтруктураСлов.Свойство(Слово, СтарыйНомерСлова) Тогда ПервыйСвободныйНомерСлова = ПервыйСвободныйНомерСлова + 1; СтруктураСлов.Вставить(Слово, ПервыйСвободныйНомерСлова); НомерСлова = ПервыйСвободныйНомерСлова; Иначе НомерСлова = СтарыйНомерСлова; КонецЕсли; ВызовыСлова = ТаблицаВызовов.НайтиСтроки(Новый Структура("Слово", Слово)); Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого СтрокаВызова Из ВызовыСлова Цикл СтрокаВызова.НомерСлова = НомерСлова; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для Каждого СтрокаВызова Из ВызовыСлова Цикл   СтрокаВызова.НомерСлова = НомерСлова;   КонецЦикла;   КонецЕсли; КонецЦикла; ТаблицаВызовов.Индексы.Удалить(ВременныйИндекс); // Платформа 8.3.27 сама не удаляет почему то ТаблицаВызовов.Колонки.Удалить("Слово"); Возврат СтруктураСлов; КонецФункции Функция КлючКэшаВызововСловаПоМодулю(Знач Модуль, Знач ЛиМетод) Экспорт Возврат НРег(Модуль) + "." + ЛиМетод; КонецФункции // Возвращаемое значение: // Строка - Функция ИмяКонтрольногоФайлаКэшаМодулей() Экспорт Возврат "КонтрольныйФайл.ixd"; КонецФункции Функция ИмяДинамическогоМодуля() Экспорт Возврат "Динамический.Модуль"; КонецФункции Функция ИмяДинамическойФормы() Экспорт Возврат "ОбщаяФорма.ирДинамический"; КонецФункции Функция ИмяМодуляПсевдокодаПлатформы() Экспорт Результат = "Обработка.ирПлатформа.Форма.ПсевдокодПлатформы.Форма.Модуль"; Если ирКэш.ЛиЭтоРасширениеКонфигурацииЛкс() Тогда Результат = ирКэш.ИмяПродукта() + " " + Результат; КонецЕсли; Возврат Результат; КонецФункции Функция ИмяМетодаИнициация() Экспорт Возврат "<Инициация>"; КонецФункции //. // Параметры: // МодульМетаданных - см. ПодготовитьМодульМетаданных - // ОбнулятьВычисляемое - Булево - немного дольше, но гарантирует успех Процедура ЗаписатьМодульВКэш(Знач МодульМетаданных, Знач ЧерезКопию = Ложь) Экспорт Если МодульМетаданных = мПустойМодуль Тогда Возврат; КонецЕсли; ФайлОписанияМодуля = ФайлМодуляИзИмениМодуля(МодульМетаданных.Имя, "ixd"); Если ЧерезКопию Тогда // Мультиметка723368140 КопияМодуля = ирОбщий.СкопироватьКоллекциюЛкс(МодульМетаданных); // см. ПодготовитьМодульМетаданных - указываем явно, чтобы ДляСвойства применялось на полную глубину. КопияМодуля.Текст = Неопределено; КопияМодуля.СтруктураТипа = Неопределено; КопияМодуля.ТекущийМетод = Неопределено; КопияМодуля.ТекстПоискаОпределенияСловМодуля = Неопределено; Если Не ЛиСохранятьОшибкиМодуля(КопияМодуля) Тогда КопияМодуля.Ошибки = Неопределено; КонецЕсли; КопияМодуля.ТаблицыСлов.Очистить(); КопияМодуля.Переменные = КопияМодуля.Переменные.Скопировать(); КопияМодуля.Методы = КопияМодуля.Методы.Скопировать(); КопияМодуля.Методы.ЗаполнитьЗначения(Неопределено, "КэшПоиска, ТелоБезВозвратов, СтарыеТипы"); СброситьКэшТиповВыраженийМодуля(КопияМодуля); МодульМетаданных = КопияМодуля; КонецЕсли; МодульМетаданных.Вставить("ВерсияФормата", ВерсияФорматаКэшаМодулей()); Текст = МодульМетаданных.Текст; СтруктураТипа = МодульМетаданных.СтруктураТипа; МодульМетаданных.Текст = Неопределено; МодульМетаданных.СтруктураТипа = Неопределено; ирОбщий.СохранитьЗначениеВФайлЛкс(МодульМетаданных, ФайлОписанияМодуля.ПолноеИмя,,, "Внутр"); МодульМетаданных.Текст = Текст; МодульМетаданных.СтруктураТипа = СтруктураТипа; КонецПроцедуры // Запускает асинхронную загрузку файлов модулей в памятный кэш ОС Windows // Параметры: // МаскаФайлов - Строка - Процедура ЗагрузитьКэшМодулейВПамятьОС(Знач МаскаФайлов = "*.*") Экспорт Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда // Фоновое многопоточное наполнение кэша ОС файлами, в которых будем искать ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("ps1"); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ПолучитьМакет("НаполнительКэшаФайловОС").ПолучитьТекст()); ТекстовыйДокумент.Записать(ИмяФайлаСкрипта, КодировкаТекста.Системная); //ИмяФайлаСкрипта = """" + ИмяФайлаСкрипта + """ -Directory """ + мПлатформа.ПапкаКэшаМодулей.ПолноеИмя + """ -FileMask """ + МаскаФайлов + """"; ИмяФайлаСкрипта = """" + ИмяФайлаСкрипта + """ """ + ПапкаКэшаМодулей.ПолноеИмя + """ """ + МаскаФайлов + """"; КомандаСистемыЗапускаСкрипта = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ИмяФайлаСкрипта); ирОбщий.ВыполнитьКомандуОСЛкс(КомандаСистемыЗапускаСкрипта, Ложь); // Удалять файл ИмяФайлаСкрипта нельзя, т.к. он выполняется асинхронно КонецЕсли; КонецПроцедуры //. // Параметры: // Модуль - Структура - // Возвращаемое значение: // Булево - Функция ЛиСохранятьОшибкиМодуля(Модуль) Экспорт Результат = Истина И Модуль.Имя <> ИмяДинамическогоМодуля() // Там типы переменных модуля не очищаем И Модуль.Ошибки <> Неопределено И Модуль.Ошибки.Количество() < 50; Возврат Результат; КонецФункции //. // Параметры: // ИмяМодуля - Строка - // Возвращаемое значение: // см. ПодготовитьМодульМетаданных - Функция МодульМетаданныхИзКэша(Знач ИмяМодуля) Экспорт Возврат мМодулиМетаданных[НРег(ИмяМодуля)]; КонецФункции Процедура СброситьКэшиТиповВыраженийМодулей(Знач КромеМодуля = "") Экспорт Для Каждого КлючИЗначение Из мМодулиМетаданных Цикл Если КлючИЗначение.Ключ = НРег(КромеМодуля) Тогда Продолжить; КонецЕсли; СброситьКэшТиповВыраженийМодуля(КлючИЗначение.Значение); КонецЦикла; КонецПроцедуры //. // Параметры: // Модуль - см. МодульМетаданных - Процедура СброситьКэшТиповВыраженийМодуля(Знач Модуль, Знач СбросВМетодах = Истина) Экспорт Если Модуль.Имя <> ИмяДинамическогоМодуля() Тогда Переменные = Модуль.Переменные; Переменные.ЗаполнитьЗначения(, "Вычислено, ТаблицаТипов"); // Чтобы не отслеживать зависимости КонецЕсли; Модуль.ТипыВыраженийПрограммы.Очистить(); Модуль.КэшПоискаПрограммы.Очистить(); //Модуль.ТаблицыСлов.Очистить(); Если СбросВМетодах Тогда Методы = Модуль.Методы; ирОбщий.ОчиститьКолонкиТаблицыЛкс(Методы, "Вычислено, ТаблицаТипов, ТипыВыражений"); _РежимОтладки = Ложь; Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого СтрокаМетода Из Методы Цикл Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда СтрокаМетода.Параметры.ЗаполнитьЗначения(, "Вычислено, ТаблицаТипов"); КонецЕсли; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для Каждого СтрокаМетода Из Методы Цикл   Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда   СтрокаМетода.Параметры.ЗаполнитьЗначения(, "Вычислено, ТаблицаТипов");   КонецЕсли;   КонецЦикла;   КонецЕсли; //Для Каждого СтрокаМетода Из Методы Цикл // Если ТипЗнч(СтрокаМетода.Параметры) = Тип("ТаблицаЗначений") Тогда // СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов"); // КонецЕсли; // Если СтрокаМетода.ТаблицаТипов <> Неопределено Тогда // СтрокаМетода.ТаблицаТипов = Неопределено; // КонецЕсли; // Если СтрокаМетода.ТипыВыражений <> Неопределено Тогда // СтрокаМетода.ТипыВыражений = Неопределено; // КонецЕсли; //КонецЦикла; КонецЕсли; КонецПроцедуры //. // Параметры: // ИмяМодуля - Строка - например "ИнструментыРазработчикаTormozit ОбщийМодуль.ирОбщий.Модуль" // Расширение - Строка - // ЗаменитьНедопустимыеСимволы - Булево - // Возвращаемое значение: // Файл - Функция ФайлМодуляИзИмениМодуля(Знач ИмяМодуля, Знач Расширение = "txt", Знач ЗаменитьНедопустимыеСимволы = Ложь) Экспорт ИмяФайла = ИмяФайлаМодуляИзИмениМодуля(ИмяМодуля, Расширение, ЗаменитьНедопустимыеСимволы); ФайлМодуля = Новый Файл(ИмяФайла); Возврат ФайлМодуля; КонецФункции //. // Параметры: // ИмяМодуля - Строка - например "ИнструментыРазработчикаTormozit ОбщийМодуль.ирОбщий.Модуль" // Расширение - Строка - // ЗаменитьНедопустимыеСимволы - Булево - // Возвращаемое значение: // Строка - Функция ИмяФайлаМодуляИзИмениМодуля(Знач ИмяМодуля, Знач Расширение = "txt", Знач ЗаменитьНедопустимыеСимволы = Ложь) Экспорт ИмяМодуля = СтрЗаменить(ИмяМодуля, " ", "\"); Если ЗаменитьНедопустимыеСимволы Тогда ИмяМодуля = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(ИмяМодуля, "_"); КонецЕсли; ИмяФайла = ПапкаКэшаМодулей.ПолноеИмя + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМодуля + "." + Расширение; Возврат ИмяФайла; КонецФункции // Функция - Имя файла модуля без расширения // // Параметры: // СтруктураТипа - см. НоваяСтруктураТипа() - // ТипМодуля - Строка - входное значение имеет смысл только для модулей приложения (безобъектных) // СтрокаСозданияРодителя - Строка - // ФлагиКомпиляции - Структура - выход, заполняется если ТипМодуля на входе пустой // // Возвращаемое значение: // Строка - // Функция ИмяМодуляИзСтруктурыТипа(Знач СтруктураТипа, ТипМодуля = "", СтрокаСозданияРодителя = "", ФлагиКомпиляции = Неопределено) Экспорт ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; МетаданныеРодителя = СтруктураТипа.Метаданные; ТипыМетаОбъектов = ирКэш.ТипыМетаОбъектов(); Результат = ""; ФлагиКомпиляции = НовыеФлагиКомпиляции(Ложь, Ложь, Ложь); Если ТипМодуля = "МодульОбычногоПриложения" Тогда ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", Истина); ИначеЕсли ТипМодуля = "МодульУправляемогоПриложения" Тогда ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", Истина); ИначеЕсли ТипМодуля = "МодульСеанса" Тогда ФлагиКомпиляции.Вставить("Сервер", Истина); Иначе ФлагиКомпиляции = НовыеФлагиКомпиляции(); КонецЕсли; Если ИмяОбщегоТипа = "Глобальный" Тогда //Если ИмяОбщегоТипа = "ОбъектМетаданныхКонфигурация" Тогда //#Если ТолстыйКлиентОбычноеПриложение Тогда // ТипМодуля = "МодульОбычногоПриложения"; //#Иначе // ТипМодуля = "МодульУправляемогоПриложения"; //#КонецЕсли Если Не ЗначениеЗаполнено(ТипМодуля) Тогда ВызватьИсключение "Требуется передача типа модуля конфигурации"; КонецЕсли; ИначеЕсли Ложь Или ИмяОбщегоТипа = "Команда" Или ИмяОбщегоТипа = "ОбщаяКоманда" Тогда ТипМодуля = "МодульКоманды"; ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь; ИначеЕсли Ложь Или ИмяОбщегоТипа = "WebСервис" Или ИмяОбщегоТипа = "HttpСервис" Или ИмяОбщегоТипа = "ОбщийМодуль" Тогда ТипМодуля = "Модуль"; Если ИмяОбщегоТипа = "ОбщийМодуль" Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда // Добавленный/переименованный объект метаданных Фрагменты = ирОбщий.СтрРазделитьЛкс(МетаданныеРодителя); МетаданныеРодителя = Новый Структура; МетаданныеРодителя.Вставить("ВызовСервера", Истина); МетаданныеРодителя.Вставить("Сервер", Истина); МетаданныеРодителя.Вставить("КлиентУправляемоеПриложение", Истина); МетаданныеРодителя.Вставить("КлиентОбычноеПриложение", Истина); МетаданныеРодителя.Вставить("Имя", Фрагменты[1]); //МетаданныеРодителя.Вставить("ИмяРасширения", СтруктураТипа.ДержательМетаданных); мДобавленныеОбщиеМодули.Вставить(Фрагменты[1], МетаданныеРодителя); КонецЕсли; Если Ложь Или ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Или ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда ФлагиКомпиляции.Сервер = МетаданныеРодителя.Сервер; ФлагиКомпиляции.КлиентОбычноеПриложение = МетаданныеРодителя.КлиентОбычноеПриложение; ФлагиКомпиляции.КлиентУправляемоеПриложение = МетаданныеРодителя.КлиентУправляемоеПриложение; СтрокаСозданияРодителя = МетаданныеРодителя.Имя; Результат = ИмяОбщегоТипа + "." + МетаданныеРодителя.Имя + "." + ТипМодуля; Иначе // Если ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда // см. ОбработкаОбъект.ирКлсПолеТекстаПрограммы.СтруктураТипаМодуля КонецЕсли; Иначе ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь; ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь; КонецЕсли; ИначеЕсли ирОбщий.ЛиИмяТипаФормыЛкс(ИмяОбщегоТипа, Истина) Тогда Если Ложь #Если Клиент Тогда Или ТипЗнч(МетаданныеРодителя) = Тип("Форма") #КонецЕсли Тогда СлужебныеДанныеФормы = ирОбщий.СлужебныеДанныеФормыЛкс(МетаданныеРодителя); Если СлужебныеДанныеФормы.Свойство("ИмяФормы") Тогда МетаданныеРодителя = СлужебныеДанныеФормы.ИмяФормы; КонецЕсли; ФлагиКомпиляции.Сервер = Ложь; ФлагиКомпиляции.КлиентУправляемоеПриложение = Ложь; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя(); ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(МетаданныеРодителя, Истина) Тогда МетаданныеРодителя = МетаданныеРодителя.ИмяФормы; ФлагиКомпиляции.КлиентОбычноеПриложение = Ложь; КонецЕсли; Если ТипЗнч(МетаданныеРодителя) <> Тип("Строка") Тогда МетаданныеРодителя = Неопределено; ИначеЕсли ЗначениеЗаполнено(МетаданныеРодителя) Тогда ТипМодуля = "Модуль"; Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда МетаданныеРодителя = МетаданныеРодителя + ".Форма"; КонецЕсли; КонецЕсли; ИначеЕсли Истина И ТипЗнч(МетаданныеРодителя) = Тип("Структура") И ирОбщий.ЛиИмяТипаВнешнегоОбъектаМетаданныхЛкс(ИмяОбщегоТипа) Тогда // Нужно для некомпилируемых внешних объектов МетаданныеРодителя = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь) + "." + МетаданныеРодителя.Имя; ТипМодуля = "МодульОбъекта"; Иначе КорневойТипОбъекта = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Объект.", Ложь); Если ЗначениеЗаполнено(КорневойТипОбъекта) Тогда ТипМодуля = "МодульОбъекта"; СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТипОбъекта, "Единственное"); Если Истина И СтрокаТипаМетаОбъекта <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Множественное = СтрокаТипаМетаОбъекта.Множественное; Если СтрокаТипаМетаОбъекта.Категория = 1 Тогда СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".Создать()"; ИначеЕсли СтрокаТипаМетаОбъекта.Категория = 0 Тогда СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".ПустаяСсылка().ПолучитьОбъект()"; КонецЕсли; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей.", Ложь)) Тогда ТипМодуля = "МодульНабораЗаписей"; КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "НаборЗаписей"); СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное"); Если Истина И СтрокаТипаМетаОбъекта <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Множественное = СтрокаТипаМетаОбъекта.Множественное; СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя + ".СоздатьНаборЗаписей()"; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "МенеджерЗначения.", Ложь)) Тогда ТипМодуля = "МодульМенеджераЗначения"; Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда СтрокаСозданияРодителя = "Константы." + МетаданныеРодителя.Имя + ".СоздатьМенеджерЗначения()"; КонецЕсли; ИначеЕсли ЗначениеЗаполнено(ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер.", Ложь)) Тогда ТипМодуля = "МодульМенеджера"; КорневойТип = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "Менеджер"); СтрокаТипаМетаОбъекта = ТипыМетаОбъектов.Найти(КорневойТип, "Единственное"); Если Истина И СтрокаТипаМетаОбъекта <> Неопределено И ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда Множественное = СтрокаТипаМетаОбъекта.Множественное; СтрокаСозданияРодителя = Множественное + "." + МетаданныеРодителя.Имя; КонецЕсли; Иначе // Тип объекта не имеет модуля ТипМодуля = Неопределено; КонецЕсли; КонецЕсли; Если Не ЗначениеЗаполнено(Результат) Тогда Если ЗначениеЗаполнено(ТипМодуля) Тогда Если ТипЗнч(МетаданныеРодителя) = Тип("Неопределено") Тогда Результат = "Конфигурация" + "." + ТипМодуля; Иначе Если ТипЗнч(МетаданныеРодителя) = Тип("ОбъектМетаданных") Тогда МетаданныеРодителя = МетаданныеРодителя.ПолноеИмя(); КонецЕсли; Если ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда Результат = МетаданныеРодителя + "." + ТипМодуля; КонецЕсли; КонецЕсли; Если Найти(Результат, ":") > 0 Тогда ЗапрещенныеСимволы = "."; Если Найти(Результат, "::") > 0 Тогда ЗапрещенныеСимволы = ЗапрещенныеСимволы + " "; // Иначе он потом в "/" превратится КонецЕсли; Результат = ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(Результат, "_", ЗапрещенныеСимволы); // Заменяем точки, чтобы по такому имени модуля не делалось попытки создать форму КонецЕсли; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Строка") Тогда Результат = МетаданныеРодителя; КонецЕсли; КонецЕсли; Если Истина И мНомерВерсииПлатформы >= 803008 И СтруктураТипа.ДержательМетаданных = Неопределено Тогда Если ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда МетаданныеРасширения = СтруктураТипа.Метаданные.РасширениеКонфигурации(); ИначеЕсли ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда МетаданныеРасширения = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные)); Если МетаданныеРасширения <> Неопределено Тогда МетаданныеРасширения = МетаданныеРасширения.РасширениеКонфигурации(); КонецЕсли; КонецЕсли; Если МетаданныеРасширения <> Неопределено Тогда СтруктураТипа.ДержательМетаданных = МетаданныеРасширения.Имя; КонецЕсли; КонецЕсли; Если ТипЗнч(СтруктураТипа.ДержательМетаданных) = Тип("Строка") Тогда Результат = СтруктураТипа.ДержательМетаданных + " " + Результат; КонецЕсли; Возврат Результат; КонецФункции // Функция - Обновить кэш структуры формы из буфера // // Параметры: // СлужебныеДанные - см. ирОбщий.СлужебныеДанныеФормыЛкс() - // ТекстБуфераОбмена - Строка - снимок формы из буфера обмена // ТекстМодуляФормы - массив из Строка - передается для быстрого удаления текста модуля из снимка формы для повышения надежности разбора структуры // Форма - Форма, ФормаКлиентскогоПриложения - // // Возвращаемое значение: // - // Функция ОбновитьКэшСтруктурыФормыИзБуфера(Знач СлужебныеДанные, Знач ТекстБуфераОбмена, Знач ТекстМодуляФормы = "", Знач Форма = Неопределено) Экспорт Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда СлужебныеДанные.Удалить("КорневыеИменаРеквизитов"); КонецЕсли; ЛиОбычнаяФорма = Ложь; Попытка ДвоичныеДанные = Base64Значение(ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстБуфераОбмена, "#base64:", "}")); Текст = Новый ТекстовыйДокумент; Текст.Прочитать(ДвоичныеДанные.ОткрытьПотокДляЧтения()); ТекстФайла = Текст.ПолучитьТекст(); ЛиОбычнаяФорма = ЗначениеЗаполнено(ТекстФайла) И Лев(ТекстФайла, 1) <> "{"; Если ЛиОбычнаяФорма Тогда СлужебныеДанные.Тип = Тип("Форма"); ВызватьИсключение "ОбычнаяФорма"; КонецЕсли; Если СтрДлина(СокрЛП(ТекстМодуляФормы)) > 300 Тогда ТекстФайла = СтрЗаменить(ТекстФайла, ирОбщий.ТекстВВыражениеВстроенногоЯзыкаЛкс(ТекстМодуляФормы, Ложь, Ложь), ""); КонецЕсли; XMLСтрока = ирОбщий.СтрокаВнутрВХМЛТелоЛкс(ТекстФайла); // Если ошибка, то обычная форма ДокументDOM = ирОбщий.ТекстВДокументDOMЛкс(XMLСтрока); // Если ошибка, то не поддерживаемый формат управляемой формы. Например Обработка.упРМПланированиеРейсов.ФормаРедактированияРейса Исключение ОписаниеОшибки = ОписаниеОшибки(); Если Не ЛиОбычнаяФорма Тогда ИмитаторФормы = ИмитаторУправляемойФормы(); ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата()); КонецЕсли; Если Не ЛиОбычнаяФорма И ЗначениеЗаполнено(ТекстБуфераОбмена) Тогда ирОбщий.СообщитьЛкс("Ошибка разбора буферного описания формы " + ирОбщий.ПолноеИмяФормыЛкс(СлужебныеДанные) + ": " + ОписаниеОшибки); КонецЕсли; Возврат Ложь; КонецПопытки; ФайлФормы = ФайлМодуляИзИмениМодуля(СлужебныеДанные.ИмяФормы, "xml", Истина); ИмитаторФормы = ИмитаторУправляемойФормыИзДокументаДОМ(ДокументDOM, Форма); Если Истина И Найти(СлужебныеДанные.ИмяФормы, ":") > 0 И ЗначениеЗаполнено(ИмитаторФормы.ИмяОсновногоРеквизита) Тогда СтрокаРеквизитаОбъект = ИмитаторФормы.Реквизиты.Найти(ИмитаторФормы.ИмяОсновногоРеквизита, "Имя"); Если Не ЗначениеЗаполнено(СтрокаРеквизитаОбъект.ОписаниеТипов) Тогда ИмяФайла = ирОбщий.СтрРазделитьЛкс(СлужебныеДанные.ИмяФормы, "::")[1]; Попытка ВнешнийОбъект = ирОбщий.МенеджерВнешнегоОбъектаЛкс(ИмяФайла); Исключение ОписаниеОшибки = ОписаниеОшибки(); // Для отладки ВнешнийОбъект = Неопределено; КонецПопытки; Если ВнешнийОбъект <> Неопределено Тогда СтрокаРеквизитаОбъект.ОписаниеТипов = Новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(ТипЗнч(ВнешнийОбъект))); СтрокаРеквизитаОбъект.Значение = ВнешнийОбъект; КонецЕсли; КонецЕсли; Иначе ирОбщий.СохранитьЗначениеВФайлЛкс(ИмитаторФормы, ФайлФормы.ПолноеИмя); // JSON дает тут больший размер чем XML КонецЕсли; ДополнитьСлужебныеДанныеИзКэшаФормы(СлужебныеДанные, ИмитаторФормы, ТекущаяДата()); Возврат Истина; КонецФункции //. // Параметры: // ДокументDOM - ДокументDOM - // Форма - УправляемаяФорма - // Возвращаемое значение: // Структура - Функция ИмитаторУправляемойФормыИзДокументаДОМ(Знач ДокументDOM, Знач Форма = Неопределено) Экспорт ИмитаторФормы = ИмитаторУправляемойФормы(); Разыменователь = Новый РазыменовательПространствИмен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.ТекстовоеСодержимое); Если УзелDOM.РодительскийУзел.РодительскийУзел.ДочерниеУзлы[10].ТекстовоеСодержимое = "1" Тогда ИмитаторФормы.ИмяОсновногоРеквизита = ИмяРеквизита; КонецЕсли; ОписаниеРеквизита = Новый Структура; РеквизитыКоллекции = НоваяТаблицаРеквизитовФормы(); НомерУзлаВложенных = 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", ПолучитьПолноеИмяПредопределенногоЗначения(ВидПоляФормы.ПолеПланировщика)); ВидыЭлементовГруппы = Новый Соответствие; ВидыЭлементовГруппы.Вставить("0", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.КоманднаяПанель)); // Опасно ВидыЭлементовГруппы.Вставить("1", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.Подменю)); ВидыЭлементовГруппы.Вставить("3", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.Страницы)); ВидыЭлементовГруппы.Вставить("4", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.Страница)); ВидыЭлементовГруппы.Вставить("5", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.ОбычнаяГруппа)); ВидыЭлементовГруппы.Вставить("6", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.ГруппаКнопок)); ВидыЭлементовГруппы.Вставить("8", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.КонтекстноеМеню)); ВидыЭлементовГруппы.Вставить("9", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.КоманднаяПанель)); // TODO узнать номера остальных видов групп //ВидыЭлементовГруппы.Вставить("?", ПолучитьПолноеИмяПредопределенногоЗначения(ВидГруппыФормы.ГруппаКолонок)); ПутиКРодителям = Новый Соответствие; //Выражение = "/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.РодительскийУзел.РодительскийУзел, Разыменователь); КонецЕсли; УзлыПоискаРодителя = УзелDOM.РодительскийУзел.РодительскийУзел.РодительскийУзел.ДочерниеУзлы; Для ИндексУзлаРодителя = 6 По 7 Цикл // Не понял от чего зависит Попытка ИмяРодителя = УзлыПоискаРодителя[ИндексУзлаРодителя].ПервыйДочерний.ЗначениеУзла; Исключение ИмяРодителя = Неопределено; КонецПопытки; Если Лев(ИмяРодителя, 1) <> """" Тогда // Ускорение Продолжить; КонецЕсли; ИмяРодителя = ирОбщий.ТекстИзВстроенногоЯзыкаЛкс(ИмяРодителя); Если ЗначениеЗаполнено(ИмяРодителя) Тогда Прервать; КонецЕсли; КонецЦикла; ИмитаторЭлементаФормы = ИмитаторЭлементаФормы(ИмяЭлемента, ВидЭлементаИмя, ИменаОбработчиков, ИмяРодителя, ПутьКДанным, ТипЭлемента); ИмитаторФормы.Элементы.Вставить(ИмяЭлемента, ИмитаторЭлементаФормы); //ИмитаторФормы.Элементы[я]. ~СледующийЭлемент: Узел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 = НаборУзлов.ПолучитьСледующий(); КонецЦикла; Возврат ИмитаторФормы; КонецФункции //. // Параметры: // ИмяЭлемента - Строка, Неопределено - // ВидЭлементаИмя - Строка - // ИменаОбработчиков - Массив[Неопределено, Строка], Неопределено - // ИмяРодителя - Строка, Неопределено - // ПутьКДанным - Строка - // ТипЭлемента - Тип - // Возвращаемое значение: // Структура - Функция ИмитаторЭлементаФормы(ИмяЭлемента, Знач ВидЭлементаИмя, Знач ИменаОбработчиков, Знач ИмяРодителя, Знач ПутьКДанным, Знач ТипЭлемента) Экспорт ОписаниеЭлемента = Новый Структура; ОписаниеЭлемента.Вставить("ИменаОбработчиков", ИменаОбработчиков); ОписаниеЭлемента.Вставить("ПутьКДанным", ПутьКДанным); ОписаниеЭлемента.Вставить("Тип", ТипЭлемента); ОписаниеЭлемента.Вставить("Вид", ВидЭлементаИмя); ОписаниеЭлемента.Вставить("Имя", ИмяЭлемента); ОписаниеЭлемента.Вставить("ИмяРодителя", ИмяРодителя); Возврат ОписаниеЭлемента; КонецФункции //. // Возвращаемое значение: // Структура - Функция ИмитаторУправляемойФормы() Экспорт // Каждый раз при изменении структуры увеличиваем ВерсияФорматаСтруктурыФормы() на 1 ИмитаторФормы = Новый Структура; ИмитаторФормы.Вставить("ВерсияФормата", ВерсияФорматаСтруктурыФормы()); ИмитаторФормы.Вставить("Элементы", Новый Структура); ИмитаторФормы.Вставить("Параметры", Новый Структура); ИмитаторФормы.Вставить("Команды", Новый Структура); ИмитаторФормы.Вставить("ДинамическиеСписки", Новый Структура); ИмитаторФормы.Вставить("ИменаОбработчиков", Новый Массив); ИмитаторФормы.Вставить("ИмяОсновногоРеквизита"); ИмитаторФормы.Вставить("Реквизиты"); // см. НоваяТаблицаРеквизитовФормы Возврат ИмитаторФормы; КонецФункции Функция ВерсияФорматаСтруктурыФормы() Возврат 4; КонецФункции Процедура ДополнитьСлужебныеДанныеИзКэшаФормы(Знач СлужебныеДанные, Знач ИмитаторФормы, Знач ДатаОбновления) Экспорт Если Ложь Или Не СлужебныеДанные.Свойство("Элементы") Или ИмитаторФормы.Элементы.Количество() > 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""" Тогда Тип = Тип("Строка"); Если ДочерниеУзлы.Количество() > 1 Тогда КвалификаторыСтроки = Новый КвалификаторыСтроки(Число(ДочерниеУзлы[1].ТекстовоеСодержимое)); КонецЕсли; ИначеЕсли РодТипа.ТекстовоеСодержимое = """B""" Тогда Тип = Тип("Булево"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """N""" Тогда Тип = Тип("Число"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """D""" Тогда Тип = Тип("Число"); ИначеЕсли РодТипа.ТекстовоеСодержимое = """#""" Тогда ИДТипа = ДочерниеУзлы[1].ТекстовоеСодержимое; Попытка Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}"); Исключение // Например для объекта внешней обработки почему то так не опознается тип КонецПопытки; Иначе Пустышка = 0; КонецЕсли; КонецЕсли; Возврат новый ОписаниеТипов(ирОбщий.ЗначенияВМассивЛкс(Тип),,,, КвалификаторыСтроки); КонецФункции // Возвращаемое значение: // Структура - Функция НовыеФлагиКомпиляции(Знач Сервер = Истина, Знач КлиентОбычноеПриложение = Истина, Знач КлиентУправляемоеПриложение = Истина, Знач БезКонтекста = Ложь) Экспорт ФлагиКомпиляции = Новый Структура; ФлагиКомпиляции.Вставить("Сервер", Сервер); ФлагиКомпиляции.Вставить("КлиентОбычноеПриложение", КлиентОбычноеПриложение); ФлагиКомпиляции.Вставить("КлиентУправляемоеПриложение", КлиентУправляемоеПриложение); ФлагиКомпиляции.Вставить("БезКонтекста", БезКонтекста); Возврат ФлагиКомпиляции; КонецФункции Функция ОписаниеМетодаМодуля(ПолноеИмяМетода) Экспорт СтруктураТипа = НоваяСтруктураТипа(); СтруктураТипа.ИмяОбщегоТипа = "ОбщийМодуль"; СтруктураТипа.Метаданные = Метаданные.ОбщиеМодули[ирОбщий.ПервыйФрагментЛкс(ПолноеИмяМетода)]; МодульМетаданных = ПодготовитьМодульМетаданных(СтруктураТипа); Если МодульМетаданных = Неопределено Тогда Возврат Неопределено; КонецЕсли; МетодыМодуля = МодульМетаданных.Методы; ОписаниеМетода = МетодыМодуля.Найти(ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяМетода), "Имя"); Возврат ОписаниеМетода; КонецФункции Функция ПолучитьРазделыМодуля1С(Знач ТекстМодуля = "") Экспорт #Если Сервер И Не Сервер Тогда мРегВыражение = Обработки.ирОболочкаРегВыражение.Создать(); #КонецЕсли Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); мРегВыражение.IgnoreCase = Истина; мРегВыражение.MultiLine = Ложь; мРегВыражение.Global = Истина; мРегВыражение.Pattern = Шаблоны.ЭлементОбластиМетодов; ВхожденияМетодов = мРегВыражение.НайтиВхождения(ТекстМодуля); ПозицияНачалаПервогоМетода = 1; ПозицияКонцаПоследнегоМетода = 1; Для Индекс = 0 По ВхожденияМетодов.Количество() - 1 Цикл Вхождение = ВхожденияМетодов[Индекс]; Если Вхождение.SubMatches(1) <> Неопределено Тогда ПозицияНачалаПервогоМетода = Вхождение.FirstIndex + 1; Прервать; КонецЕсли; КонецЦикла; Для Индекс = 1 - ВхожденияМетодов.Количество() По 0 Цикл // Обратный обход Вхождение = ВхожденияМетодов[-Индекс]; Если Вхождение.SubMatches(1) <> Неопределено Тогда ПозицияКонцаПоследнегоМетода = Вхождение.FirstIndex + Вхождение.Length + 1; Прервать; КонецЕсли; КонецЦикла; Если ПозицияКонцаПоследнегоМетода = 1 Тогда мРегВыражение.Pattern = Шаблоны.ОписаниеСтрокиПеременных; ВхожденияПеременных = мРегВыражение.НайтиВхождения(ТекстМодуля); Для Индекс = 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|$) // + <шБлокКомментов> = <шКомментарий>(?:<шПустоеНачалоСтроки><шКомментарий>)*(?=(?:\n|$)) // + <шСтруктураКомментаПарам> = Параметры(?:\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|$))*) // + <шМетодНачало> = (?:Функция|Процедура|Function|Procedure) // + <шМетодКонец> = (?:Конец|End)(?:Процедуры|Функции|Procedure|Function) // + <шКомментМетода> = ((?:[ \f\r\t\v]*//[^\n]*\n)+)<шМетодНачало><шРазделитель>*(<шИмя>) // + <шОписаниеПеременной> = (<шИмя>)(<шРазделитель>+(?:Экспорт|Export))? // + <шСтрокаПеременныхБезКомментов> = <шПустоеНачалоСтроки>(?:Перем|Var)((?:<шРазделитель>*<шОписаниеПеременной><шРазделитель>*[;,])+) // + <шСтрокаПеременных> = <шСтрокаПеременныхБезКомментов>([ \f\r\t\v]*<шБлокКомментов>)? // + <шЛитералПрограммы> = "(?:(?:"")|[^"\n])*(?:<шРазделитель>*\|(?:(?:"")|[^"\n])*)*(?:"|$) // + <шПараметрыМетода> = <шРазделитель>*(Знач\s)?<шРазделитель>*(<шИмя>)<шРазделитель>*=?((?:<шРазделитель>*|(<шЛитералПрограммы>)|(?:[^,\n]*))+)(?:,|$) // + <шДирективаИлиАннотация> = (?:<шПустоеНачалоСтроки>)?<шПустоеНачалоСтроки>[#&][^\n]*(?=\n|$) // + <шМетодЧистый> = ([\t ]*(?:(?:Асинх|Async)\s+)?(<шМетодНачало>)<шРазделитель>*(<шИмя>)<шРазделитель>*\(([^\)]*)\)(<шРазделитель>*(?:Экспорт|Export))?(?:\s*?(?=\n))?(?:\n\s*(?:Перем|Var) .*(?=\n))*)((?:<шБлокКомментов>|\.<шМетодКонец>|(?:\r|\n|.)(?!<шМетодКонец>(?![^\n]*(?:"|\n\s*\|))))*)(?:$|[^а-яё_a-z0-9\."]<шМетодКонец>(?=(?:<шКомментарий>|[^а-яё_a-z0-9\."]|$))) // + <шМетодСПредКомментом> = (?:(<шБлокКомментов>\n)|\n|^)[\t ]*<шМетодЧистый> // + <шЭлементОбластиМетодов> = <шМетодСПредКомментом>|(<шБлокКомментов>)|(<шДирективаИлиАннотация>) // {Шаблон.Конец} шИмя = ЭтотОбъект.шИмя; шПустоеНачалоСтроки = ЭтотОбъект.шПустоеНачалоСтроки; шКомментарий = ЭтотОбъект.шКомментарий; шРазделитель = ЭтотОбъект.шРазделитель; шЛитералПрограммы = ЭтотОбъект.шЛитералПрограммы; шБлокКомментов = "" + шКомментарий + "(?:" + шПустоеНачалоСтроки + "" + шКомментарий + ")*(?=(?:\n|$))"; шСтруктураКомментаПарам = "Параметры(?:\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|$))*)"; шМетодНачало = "(?:Функция|Процедура|Function|Procedure)"; шМетодКонец = "(?:Конец|End)(?:Процедуры|Функции|Procedure|Function)"; шКомментМетода = "((?:[ \f\r\t\v]*//[^\n]*\n)+)" + шМетодНачало + шРазделитель + "+(" + шИмя + ")"; шОписаниеПеременной = "(" + шИмя + ")(" + шРазделитель + "+(?:Экспорт|Export))?"; шСтрокаПеременныхБезКомментов = "(?:Перем|Var)((?:" + шРазделитель + "*" + шОписаниеПеременной + шРазделитель + "*[;,])+)"; шСтрокаПеременных = "" + шПустоеНачалоСтроки + шСтрокаПеременныхБезКомментов + "([ \f\r\t\v]*" + шБлокКомментов + ")?"; шПараметрыМетода = "" + шРазделитель + "*(Знач\s)?" + шРазделитель + "*(" + шИмя + ")\s*=?((?:\s*(" + шЛитералПрограммы + ")|(?:[^,\n/]*))+)(?:(" + шКомментарий + ")|\n|,|$)"; шДирективаИлиАннотация = "(?:" + шПустоеНачалоСтроки + ")?" + шПустоеНачалоСтроки + "[#&][^\n]*(?=\n|$)"; шМетодЧистый = "([\t ]*(?:(?:Асинх|Async)\s+)?(" + шМетодНачало + ")" + шРазделитель + "+(" + шИмя + ")" + шРазделитель + "*\(([^\)]*)\)(" + шРазделитель + "*(?:Экспорт|Export))?(?:[\t ]*(" + шКомментарий + "))?(?:\s*?(?=\n))?(?:\n\s*(?:Перем|Var) .*(?=\n))*)" + "((?:" + шБлокКомментов + "|\." + шМетодКонец + "|(?:\r|\n|.)(?!" + шМетодКонец + "(?![^\n]*(?:""|\n\s*\|))))*)(?:$|[^а-яё_a-z0-9\.""]" + шМетодКонец + "(?=(?:" + шКомментарий + "|[^а-яё_a-z0-9\.""]|$)))"; шМетодСПредКомментом = "(?:((?:\n|^)[\t ]*" + шБлокКомментов + "\n)|\n|^)" + шМетодЧистый + ""; шЭлементОбластиМетодов = "" + шМетодСПредКомментом + "|((?:\n|^)[\t ]*" + шБлокКомментов + ")|(" + шДирективаИлиАннотация + ")"; // {ОписаниеРегулярногоВыражения.Конец} Результат = Новый Структура; Результат.Вставить("СтрокаПрограммы", шЛитералПрограммы); Результат.Вставить("ДирективаПрепроцессора", шДирективаИлиАннотация); Результат.Вставить("БлокКомментариев", шБлокКомментов); Результат.Вставить("ОписаниеМетодаСКомментарием", шМетодСПредКомментом); Результат.Вставить("ОписаниеМетодаЧистое", шМетодЧистый); Результат.Вставить("ЭлементОбластиМетодов", шЭлементОбластиМетодов); Результат.Вставить("ОписаниеПеременной", шОписаниеПеременной); Результат.Вставить("ОписаниеСтрокиПеременных", шСтрокаПеременных); Результат.Вставить("ОписаниеСтрокиПеременныхБезКомментов", шСтрокаПеременныхБезКомментов); Результат.Вставить("КомментарийОписаниеМетода", шКомментМетода); Результат.Вставить("ПараметрыМетода", шПараметрыМетода); Результат.Вставить("СтруктураКомментарияВозвр", шСтруктураКомментаВозвр); Результат.Вставить("СтруктураКомментарияПарам", шСтруктураКомментаПарам); Результат.Вставить("СтруктураКомментарияОписаниеПараметров", шСтруктураКомментаОписаниеПараметров); Результат.Вставить("Возврат", шВозврат); Результат.Вставить("ОписаниеПараметра", ".*(?:\n(?://)?(?:[\t ]{8,}|[\t ]+[*-]).*)*"); мШаблоныДляАнализаВстроенногоЯзыка = Результат; Возврат Результат; КонецФункции // Функция - Модуль метаданных. Для пустого текста и НЕ пустого имени возращает единый модуль с именем "<Пустой>"! // // Параметры: // ТекстМодуля - Строка - // СтруктураТипа - см. НоваяСтруктураТипа() - // ИмяМодуля - Строка - // ПодготовитьОписанияРезультатовМетодов - Булево - // СтарыйМодуль - см. МодульМетаданных() - // ТекущийМетод - см. НоваяТаблицаМетодовМодуля()[0] - // ТекущаяПозиция - Число - позиция в модуле // // Возвращаемое значение: // Структура - // Функция МодульМетаданных(Знач ТекстМодуля, Знач СтруктураТипа = Неопределено, Знач ИмяМодуля = "", Знач ПодготовитьОписанияРезультатовМетодов = Истина, Знач СтарыйМодуль = Неопределено, Знач ТекущаяПозиция = 0, Знач ФлагиКомпиляции = Неопределено) Экспорт РазрешитьЕдиныйПустойМодуль = Истина И ПустаяСтрока(ТекстМодуля) И ИмяМодуля <> ИмяДинамическогоМодуля() И ЗначениеЗаполнено(ИмяМодуля); Если РазрешитьЕдиныйПустойМодуль И мПустойМодуль <> Неопределено Тогда // Для ускорения заполнения списка в Обработка.ирКлсПолеТекстаПрограммы.Форма.МетодыМодулей Возврат мПустойМодуль; КонецЕсли; ЭтоМодульФормыУпр = Истина И ЛиИмяМодуляФормы(ИмяМодуля) И (Ложь Или СтруктураТипа = Неопределено Или ирОбщий.ЛиИмяТипаФормыЛкс(СтруктураТипа.ИмяОбщегоТипа)); ЛиНачальныйДиапазонСовпал = Ложь; ЛиКонечныйДиапазонСовпал = Ложь; ПозицияНачалаСтарая = 0; Если Истина И Не ПустаяСтрока(ТекстМодуля) И СтарыйМодуль <> Неопределено //И СтарыйМодуль.Свойство("Текст") И ЗначениеЗаполнено(ТекущаяПозиция) И ирКэш.НомерРежимаСовместимостиЛкс() >= 803006 // СтрНайти() Тогда МетодыСтарые = СтарыйМодуль.Методы; ТекущийМетод = СтарыйМодуль.ТекущийМетод; // см. МетодыСтарые.Добавить() Если ТекущийМетод <> Неопределено Тогда Если Ложь Или МетодыСтарые.Индекс(ТекущийМетод) = -1 Или ТекущийМетод.ПозицияСОписанием - ТекущаяПозиция > 1000 Или ТекущаяПозиция - (ТекущийМетод.ПозицияСОписанием + ТекущийМетод.ДлинаСОписанием) > 1000 Тогда ТекущийМетод = Неопределено; КонецЕсли; КонецЕсли; ИндексТекущегоМетода = -1; Если ТекущийМетод <> Неопределено Тогда ИндексТекущегоМетода = МетодыСтарые.Индекс(ТекущийМетод); КонецЕсли; Если ИндексТекущегоМетода = -1 Тогда ИндексТекущегоМетода = МетодыСтарые.Количество(); Для Каждого Метод Из МетодыСтарые Цикл Если Метод.ПозицияСОписанием = 0 Тогда Продолжить; КонецЕсли; Если Метод.ПозицияСОписанием + Метод.ДлинаСОписанием + 100 > ТекущаяПозиция Тогда ИндексТекущегоМетода = МетодыСтарые.Индекс(Метод); ТекущийМетод = Метод; Прервать; КонецЕсли; КонецЦикла; КонецЕсли; Если ТекущийМетод <> Неопределено Тогда ПозицияНачалаСтарая = ТекущийМетод.ПозицияСОписанием; ПозицияКонцаСтарая = ПозицияНачалаСтарая + ТекущийМетод.ДлинаСОписанием; Иначе ПозицияНачалаСтарая = СтарыйМодуль.ПозицияПрограммы; ПозицияКонцаСтарая = СтрДлина(СтарыйМодуль.Текст); ОпределениеСОписанием = Сред(ТекстМодуля, ПозицияНачалаСтарая); КонецЕсли; ЧастьДоМетодаСтарая = Лев(СтарыйМодуль.Текст, ПозицияНачалаСтарая); ЧастьДоМетодаНовая = Лев(ТекстМодуля, ПозицияНачалаСтарая); Если Истина И ЧастьДоМетодаСтарая = ЧастьДоМетодаНовая И Найти(ОпределениеСОписанием, "Перем ") = 0 // Чтобы при вставке строки с переменной модуля обновлялось корректно Тогда ЛиНачальныйДиапазонСовпал = Истина; Если ТекущийМетод <> Неопределено Тогда Если ТекущийМетод.ТипЗначения = Неопределено Тогда МаркерКонца = Символы.ПС + "КонецПроцедуры"; Иначе МаркерКонца = Символы.ПС + "КонецФункции"; КонецЕсли; ПозицияКонцаНовая = ирОбщий.СтрНайтиЛкс(ТекстМодуля, МаркерКонца,, ПозицияНачалаСтарая) + СтрДлина(МаркерКонца); Иначе ПозицияКонцаНовая = СтрДлина(ТекстМодуля); Если Ложь Или ирОбщий.СтрНайтиЛкс(ТекстМодуля, "КонецФункции",, ПозицияНачалаСтарая) > 0 Или ирОбщий.СтрНайтиЛкс(ТекстМодуля, "КонецПроцедуры",, ПозицияНачалаСтарая) > 0 Тогда // в конец модуля вставлен метод ПозицияКонцаСтарая = 0; КонецЕсли; КонецЕсли; ЧастьПослеМетодаНовая = Сред(ТекстМодуля, ПозицияКонцаНовая); ЧастьПослеМетодаСтарая = Сред(СтарыйМодуль.Текст, ПозицияКонцаСтарая); ЛиКонечныйДиапазонСовпал = ЧастьПослеМетодаНовая = ЧастьПослеМетодаСтарая; СмещениеКонечногоДиапазона = ПозицияКонцаНовая - ПозицияКонцаСтарая; КонецЕсли; КонецЕсли; НачальнаяПозицияДиапазона = 0; ПоследняяАннотация = ""; ПоследнееОписание = ""; ПоследнееНачалоОписания = Неопределено; ПоследнееНачалоАннотации = Неопределено; ОбластиГруппировки = Новый ДеревоЗначений; ОбластиГруппировки.Колонки.Добавить("Имя"); ОбластиГруппировки.Колонки.Добавить("Начало"); ОбластиГруппировки.Колонки.Добавить("Конец"); ОбластиКомпиляции = Новый ДеревоЗначений; ОбластиКомпиляции.Колонки.Добавить("Условие"); ОбластиКомпиляции.Колонки.Добавить("Начало"); ОбластиКомпиляции.Колонки.Добавить("Конец"); ТекущаяОбластьГруппировки = Неопределено; // см. ОбластиГруппировки.Строки[0] ТекущаяОбластьКомпиляции = Неопределено; // см. ОбластиКомпиляции.Строки[0] ТекущийАдресГруппировки = ""; ТекущийАдресКомпиляции = ""; Если ЛиНачальныйДиапазонСовпал Тогда Модуль = СтарыйМодуль; Если Модуль.ОбластиКомпиляции <> Неопределено Тогда ОбластиКомпиляции = Модуль.ОбластиКомпиляции; КонецЕсли; Если Модуль.ОбластиГруппировки <> Неопределено Тогда ОбластиГруппировки = Модуль.ОбластиГруппировки; КонецЕсли; Методы = Модуль.Методы; Ошибки = Модуль.Ошибки; // ОбработкаТабличнаяЧасть.ирКлсПолеТекстаПрограммы.ОшибкиМодуля Если Ошибки <> Неопределено Тогда УдалитьОшибкиМетода(ТекущийМетод, Ошибки); КонецЕсли; НачальнаяПозицияДиапазона = ПозицияНачалаСтарая - 1; Если ЛиКонечныйДиапазонСовпал Тогда Если ТекущийМетод <> Неопределено Тогда ТипыВыраженийТекущегоМетода = ТекущийМетод.ТипыВыражений; //Берем старую таблицу строго тут, т.к. дальше последняя ссылка на нее удаляется Если ТипЗнч(ТекущийМетод.Параметры) = Тип("ТаблицаЗначений") Тогда ТаблицаПараметровТекущегоМетода = ТекущийМетод.Параметры.Скопировать(); // Опасно. Копирование сохраняет таблицы типов внутри параметров КонецЕсли; КонецЕсли; СброситьКэшТиповВыраженийМодуля(Модуль, Истина); Если ТекущийМетод = Неопределено Тогда Модуль.Программа = ОпределениеСОписанием; ВхожденияМетодов = Новый Массив; Иначе // Сброс кэшей текущего метода ТекущийМетод.ОписаниеРезультата = Неопределено; ТекущийМетод.ТелоБезВозвратов = Неопределено; ТекущийМетод.КлючевыеПараметры = Неопределено; ТекущийМетод.КэшПоиска = Неопределено; // Оптимизация для ускорения расчета ожидаемого типа при вводе "=" после имени переменной. Может влиять на свежесть расчета в рекурсивных функциях Если ТекущаяПозиция < 2 Тогда ПозицияНачалаСтроки = 0; Иначе ПозицияНачалаСтроки = ирОбщий.СтрНайтиЛкс(ТекстМодуля, Символы.ПС, Истина, ТекущаяПозиция - 1); КонецЕсли; НачалоСтроки = Сред(ТекстМодуля, ПозицияНачалаСтроки + 1, ТекущаяПозиция - ПозицияНачалаСтроки); ПозицияПроверкиИзменений = ПозицияНачалаСтроки + Найти(НачалоСтроки, "="); ПозицияВТелеМетода = ПозицияПроверкиИзменений - ТекущийМетод.ПозицияТела; ДлинаСверяемойЧасти = ТекущийМетод.ПозицияТела + ПозицияВТелеМетода - ТекущийМетод.ПозицияСОписанием - 1; Если Сред(ТекстМодуля, ПозицияНачалаСтарая, ДлинаСверяемойЧасти) = Сред(СтарыйМодуль.Текст, ПозицияНачалаСтарая, ДлинаСверяемойЧасти) Тогда // Начало метода совпало Если ТипыВыраженийТекущегоМетода <> Неопределено Тогда УдаляемыеКлючи = Новый Массив; Для Каждого КлючИЗначение Из ТипыВыраженийТекущегоМетода Цикл ПозицияВыражения = Число(ирОбщий.ПервыйФрагментЛкс(КлючИЗначение.Ключ, ";")); Если ПозицияВыражения > ПозицияВТелеМетода Тогда УдаляемыеКлючи.Добавить(КлючИЗначение.Ключ); КонецЕсли; КонецЦикла; Для Каждого УдаляемыеЭлемент Из УдаляемыеКлючи Цикл ТипыВыраженийТекущегоМетода.Удалить(УдаляемыеЭлемент); КонецЦикла; ТекущийМетод.ТипыВыражений = ТипыВыраженийТекущегоМетода; КонецЕсли; Иначе ТаблицаПараметровТекущегоМетода = Неопределено; ТекущийМетод.ВызывающиеМодули = Неопределено; КонецЕсли; ТекущийМетод.Параметры = ТаблицаПараметровТекущегоМетода; ОпределениеСОписанием = Сред(ТекстМодуля, ПозицияНачалаСтарая, ТекущийМетод.ДлинаСОписанием + СмещениеКонечногоДиапазона); ВхожденияМетодов = ПолучитьРазделыМодуля1С(ОпределениеСОписанием).ВхожденияМетодов; _РежимОтладки = Ложь; Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для ИндексМетодаЦикл = ИндексТекущегоМетода + 1 По Методы.Количество() - 1 Цикл СтрокаМетода = Методы[ИндексМетодаЦикл]; Если СтрокаМетода.ПозицияСОписанием = 0 Тогда Продолжить; // Возможно даже Прервать КонецЕсли; СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием + СмещениеКонечногоДиапазона; СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияОпределения + СмещениеКонечногоДиапазона; СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияТела + СмещениеКонечногоДиапазона; Если Ошибки <> Неопределено И СтрокаМетода.ЕстьОшибки = Истина Тогда Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", СтрокаМетода.Имя)) Цикл СтрокаОшибки.Позиция = СтрокаОшибки.Позиция + СмещениеКонечногоДиапазона; КонецЦикла; КонецЕсли; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для ИндексМетодаЦикл = ИндексТекущегоМетода + 1 По Методы.Количество() - 1 Цикл   СтрокаМетода = Методы[ИндексМетодаЦикл];   Если СтрокаМетода.ПозицияСОписанием = 0 Тогда   Продолжить;   КонецЕсли;   СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием + СмещениеКонечногоДиапазона;   СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияОпределения + СмещениеКонечногоДиапазона;   СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияТела + СмещениеКонечногоДиапазона;   Если Ошибки <> Неопределено И СтрокаМетода.ЕстьОшибки = Истина Тогда   Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", СтрокаМетода.Имя)) Цикл   СтрокаОшибки.Позиция = СтрокаОшибки.Позиция + СмещениеКонечногоДиапазона;   КонецЦикла;   КонецЕсли;   КонецЦикла;   КонецЕсли; Модуль.ПозицияПрограммы = Модуль.ПозицияПрограммы + СмещениеКонечногоДиапазона; КонецЕсли; ПрямыеВызовыМетодов = ПрямыеВызовыМетодовМодуля(ИмяМодуля, ПозицияНачалаСтарая); Если ПрямыеВызовыМетодов <> Неопределено Тогда ОтложенныйСдвиг = НовыйОтложенныйСдвигВызововСловМодуля(); ОтложенныйСдвиг.ПозицияНачалаСтарая = ПозицияНачалаСтарая; ОтложенныйСдвиг.ПозицияКонцаСтарая = ПозицияКонцаСтарая; ОтложенныйСдвиг.СмещениеКонечногоДиапазона = СмещениеКонечногоДиапазона; ОтложенныйСдвиг.ОпределениеСОписанием = ОпределениеСОписанием; ПрямыеВызовыМетодов.Вставить("ОтложенныйСдвиг", ОтложенныйСдвиг); //Модуль.ФлагиКомпиляции. КонецЕсли; //ИзмененаТолькоОднаСтрока = СтароеНачалоБлока = НовоеНачалоБлока И СтароеКонецБлока = НовоеКонецБлока; Иначе СброситьКэшТиповВыраженийМодуля(Модуль, Истина); Модуль.ТаблицыСлов.Очистить(); КонечныйДиапазон = Сред(ТекстМодуля, ПозицияНачалаСтарая); РазделыМодуля = ПолучитьРазделыМодуля1С(КонечныйДиапазон); Модуль.Программа = РазделыМодуля.Программа; Модуль.ПозицияПрограммы = ПозицияНачалаСтарая + РазделыМодуля.ПозицияПрограммы - 1; ВхожденияМетодов = РазделыМодуля.ВхожденияМетодов; Пока Методы.Количество() > ИндексТекущегоМетода Цикл Если Ошибки <> Неопределено Тогда УдалитьОшибкиМетода(Методы[ИндексТекущегоМетода], Ошибки); КонецЕсли; Методы.Удалить(ИндексТекущегоМетода); КонецЦикла; ТекущийМетод = Неопределено; Если ИндексТекущегоМетода > 0 Тогда ПредМетод = Методы[ИндексТекущегоМетода - 1]; ТекущийАдресГруппировки = ПредМетод.АдресГруппировки; Если ЗначениеЗаполнено(ТекущийАдресГруппировки) Тогда ТекущаяОбластьГруппировки = ирОбщий.Дерево_НайтиПоПутиСтрокойЛкс(ОбластиГруппировки, "", ТекущийАдресГруппировки); ирОбщий.УдалитьЧастьДереваПослеСтрокиЛкс(ОбластиГруппировки, ТекущаяОбластьГруппировки); КонецЕсли; ТекущийАдресКомпиляции = ПредМетод.АдресКомпиляции; Если ЗначениеЗаполнено(ТекущийАдресКомпиляции) Тогда ТекущаяОбластьКомпиляции = ирОбщий.Дерево_НайтиПоПутиСтрокойЛкс(ОбластиКомпиляции, "", ТекущийАдресКомпиляции); ирОбщий.УдалитьЧастьДереваПослеСтрокиЛкс(ОбластиКомпиляции, ТекущаяОбластьКомпиляции); КонецЕсли; КонецЕсли; КонецЕсли; Модуль.Текст = ТекстМодуля; Иначе ТекущийМетод = Неопределено; Ошибки = Неопределено; ЗапретыКомпиляции = Новый Структура; Модуль = ПолучитьРазделыМодуля1С(ТекстМодуля); УстановитьПрямыеВызовыМетодовМодуля(ИмяМодуля); // При изменении нужно увеличивать версию формата Мультиметка91237881041 Модуль.Вставить("СтруктураТипа", СтруктураТипа); Модуль.Вставить("Имя", ИмяМодуля); Модуль.Вставить("ФлагиКомпиляции"); // см. НовыеФлагиКомпиляции() Модуль.Вставить("ЗапретыКомпиляции", ЗапретыКомпиляции); Модуль.Вставить("ТекущийМетод"); Модуль.Вставить("ТипыВыраженийПрограммы", Новый Соответствие); Модуль.Вставить("КэшПоискаПрограммы", Новый Соответствие); Модуль.Вставить("ТаблицыСлов", Новый Соответствие); Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); мРегВыражение.IgnoreCase = Истина; мРегВыражение.Multiline = Ложь; Переменные = НоваяТаблицаПеременныхМодуля(); мРегВыражение.Pattern = Шаблоны.ОписаниеСтрокиПеременных + "|(" + Шаблоны.БлокКомментариев + ")|(" + Шаблоны.ДирективаПрепроцессора + ")"; Вхождения = мРегВыражение.НайтиВхождения(Модуль.ПеременныеТекст); Для Каждого Вхождение Из Вхождения Цикл Если Вхождение.SubMatches(0) <> Неопределено Тогда ПоследняяАннотацияН = НРег(ПоследняяАннотация); Сервер = ПустаяСтрока(ПоследняяАннотацияН) Или Найти(ПоследняяАннотацияН, "насервере") > 0; Клиент = Ложь Или Найти(ПоследняяАннотацияН, "наклиенте") > 0 Или (Истина И ПустаяСтрока(ПоследняяАннотацияН) И Не ЭтоМодульФормыУпр); ТекстСтроки = Вхождение.SubMatches(0); ОписаниеСтроки = ОчиститьТекстМодуляОтПрефиксаКомментария(Вхождение.SubMatches(3)); ПозицияСОписанием = Вхождение.FirstIndex + 2; Если Найти(ТекстСтроки, ",") = 0 Тогда // Одна переменная в строке ИмяПеременной = ирОбщий.ПервыйФрагментЛкс(Вхождение.SubMatches(1)); ЭкспортПеременной = ?(Вхождение.SubMatches(2) = Неопределено, Ложь, Истина); ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием, ПоследняяАннотация, Сервер, Клиент); Иначе // Несколько переменных в строке мРегВыражение2.Pattern = Шаблоны.ОписаниеПеременной + "|\s*(?:;|,)"; Результат2 = мРегВыражение2.НайтиВхождения(ТекстСтроки); // тяжелая операция Для Каждого Вхождение2 Из Результат2 Цикл Если Вхождение2.SubMatches(0) <> Неопределено Тогда ИмяПеременной = Вхождение2.SubMatches(0); ЭкспортПеременной = ?(Вхождение2.SubMatches(1) = Неопределено, Ложь, Истина); ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, ОписаниеСтроки, ПозицияСОписанием, ПоследняяАннотация, Сервер, Клиент); КонецЕсли; КонецЦикла; КонецЕсли; ПоследняяАннотация = ""; ПоследнееНачалоОписания = Неопределено; ПоследнееНачалоАннотации = Неопределено; ИначеЕсли Вхождение.SubMatches(4) <> Неопределено Тогда ПоследнееОписание = Вхождение.SubMatches(4); ПоследнееНачалоОписания = Вхождение.FirstIndex + 1; ИначеЕсли Вхождение.SubMatches(5) <> Неопределено Тогда НоваяАннотация = Вхождение.SubMatches(5); НоваяАннотация = СокрЛП(НоваяАннотация); Если Истина И Лев(НоваяАннотация, 1) = "&" И (Ложь // отдаем приоритет директиве компиляции Или ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "(")) Тогда ПоследняяАннотация = НоваяАннотация; ПоследнееНачалоАннотации = Вхождение.FirstIndex + 1; ИначеЕсли Лев(НоваяАннотация, 1) = "#" Тогда Если Найти(НоваяАннотация, "Не ТонкийКлиент") > 0 Тогда ЗапретыКомпиляции.Вставить("ТонкийКлиент"); КонецЕсли; ОбработатьАннотациюОбласти(НоваяАннотация, Вхождение.FirstIndex, ОбластиГруппировки, ТекущаяОбластьГруппировки, ТекущийАдресГруппировки, ОбластиКомпиляции, ТекущаяОбластьКомпиляции, ТекущийАдресКомпиляции); КонецЕсли; КонецЕсли; КонецЦикла; Модуль.Удалить("ПеременныеТекст"); Модуль.Вставить("Переменные", Переменные); Методы = НоваяТаблицаМетодовМодуля(); ВхожденияМетодов = Модуль.ВхожденияМетодов; Если СтруктураТипа <> Неопределено Тогда СтрокаМетода = Методы.Добавить(); СтрокаМетода.Сервер = Истина; СтрокаМетода.Клиент = Истина; СтрокаМетода.ЛиЭкспорт = Истина; СтрокаМетода.ЕстьОшибки = Ложь; СтрокаМетода.Имя = "<>"; СтрокаМетода.ТипЗначения = "НеизвестныйКонтекст"; ирОбщий.ОбновитьКопиюСвойстваВНижнемРегистреЛкс(СтрокаМетода); КонецЕсли; КонецЕсли; ПорогДлиныМаркераТела = 20; НачальнаяПозицияДиапазона = НачальнаяПозицияДиапазона + 1; Если ПоследнееНачалоАннотации <> Неопределено Тогда Модуль.ПозицияМетодов = ПоследнееНачалоАннотации; КонецЕсли; Для Каждого Вхождение Из ВхожденияМетодов Цикл ПозицияВхождения = Вхождение.FirstIndex + НачальнаяПозицияДиапазона; Если Модуль.ПозицияМетодов > ПозицияВхождения Тогда Продолжить; КонецЕсли; Заголовок = Вхождение.SubMatches(1); Если Заголовок <> Неопределено Тогда СброситьПараметры = Истина; Если ТекущийМетод <> Неопределено Тогда СтрокаМетода = ТекущийМетод; СтароеИмя = СтрокаМетода.Имя; СброситьПараметры = ТаблицаПараметровТекущегоМетода = Неопределено; Иначе СтрокаМетода = Методы.Добавить(); КонецЕсли; ОписаниеМетода = Вхождение.SubMatches(0); ДлинаОписания = СтрДлина(ОписаниеМетода); ОпределениеБезОписания = Сред(Вхождение.Value, ДлинаОписания + 1); Если Лев(ОпределениеБезОписания, 1) = Символы.ПС Тогда ОпределениеБезОписания = Сред(ОпределениеБезОписания, 2); ДлинаОписания = ДлинаОписания + 1; КонецЕсли; СтрокаМетода.ПозицияСОписанием = ПозицияВхождения; СтрокаМетода.ДлинаСОписанием = Вхождение.Length; СтрокаМетода.ПозицияОпределения = СтрокаМетода.ПозицияСОписанием + ДлинаОписания; СтрокаМетода.ДлинаОпределения = СтрДлина(ОпределениеБезОписания); //СтрокаМетода.Индекс = Вхождение.FirstIndex + Смещение; СтрокаМетода.Имя = Вхождение.SubMatches(3); СтрокаМетода.НИмя = Нрег(СтрокаМетода.Имя); ТекстПараметров = Вхождение.SubMatches(4); ТекстЭкспорта = Вхождение.SubMatches(5); ЛиЭкспорт = ?(ТекстЭкспорта = Неопределено, Ложь, Истина); Тело = Вхождение.SubMatches(7); ПерваяСтрокаТела = ирОбщий.ПервыйФрагментЛкс(Тело, Символы.ПС); ПозицияЭкспортаВТеле = Найти(ПерваяСтрокаТела, ") Экспорт"); ДлинаЗаголовка = СтрДлина(Заголовок); Если ПозицияЭкспортаВТеле > 0 Тогда // Сработал ложный конец секции параметров из-за ")" в значении по умолчанию ДобавкаЗаголовка = ")" + Лев(ПерваяСтрокаТела, ПозицияЭкспортаВТеле - 1); ТекстПараметров = ТекстПараметров + ДобавкаЗаголовка; ДлинаЗаголовка = ДлинаЗаголовка + СтрДлина(ДобавкаЗаголовка); ЛиЭкспорт = Истина; КонецЕсли; СтрокаМетода.ЛиЭкспорт = ЛиЭкспорт; Тело = Сред(Тело, 2); // Мультиметка38422941 Сдвиг добавлен после вынужденного переноса символа "переноса строки" из заголовка в тело СтрокаМетода.ДлинаТела = СтрДлина(Тело); Если СтрокаМетода.ДлинаТела = 0 Тогда // TODO надо полностью перейти на этот способ СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + ДлинаЗаголовка; Иначе МаркерНачалаТела = Тело; //Если СтрДлина(МаркерНачалаТела) < ПорогДлиныМаркераТела Тогда // МаркерНачалаТела = МаркерНачалаТела + Символы.ПС; //КонецЕсли; МаркерНачалаТела = Лев(МаркерНачалаТела, ПорогДлиныМаркераТела); СтрокаМетода.ПозицияТела = СтрокаМетода.ПозицияОпределения + Найти(ОпределениеБезОписания, МаркерНачалаТела) - 2; // Мультиметка38422941 КонецЕсли; Если ЗначениеЗаполнено(ПоследняяАннотация) И Не ЗначениеЗаполнено(ОписаниеМетода) Тогда ОписаниеМетода = ПоследнееОписание; КонецЕсли; ПоследнееОписание = ""; СтрокаМетода.Описание = ОписаниеМетода; СтрокаМетода.Аннотация = ПоследняяАннотация; Если СброситьПараметры Или ТекущаяПозиция < СтрокаМетода.ПозицияОпределения + ДлинаЗаголовка Тогда СтрокаМетода.Параметры = ТекстПараметров; // Сначала тип "Строка". Позже разбираем их в ПараметрыМетодаМодуля() КонецЕсли; СтрокаМетода.ОписаниеРезультата = Вхождение.SubMatches(6); Если НРег(Вхождение.SubMatches(2)) = "функция" Тогда СтрокаМетода.ТипЗначения = "??"; Если ПодготовитьОписанияРезультатовМетодов Тогда // очень небольшая экономия времени ПодготовитьОписаниеРезультатаМетода(СтрокаМетода); КонецЕсли; КонецЕсли; Если ЗначениеЗаполнено(ПоследняяАннотация) Тогда // TODO Сделать учет случая 2-х аннотаций СтрокаМетода.РасширяемыйМетод = ирОбщий.ТекстМеждуМаркерамиЛкс(ПоследняяАннотация, "(""", """)", Ложь); Если ЗначениеЗаполнено(СтрокаМетода.РасширяемыйМетод) Тогда ПоследняяАннотация = ""; КонецЕсли; КонецЕсли; ПоследняяАннотация = НРег(ПоследняяАннотация); СтрокаМетода.Сервер = ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "насервере") > 0; СтрокаМетода.Клиент = Ложь Или Найти(ПоследняяАннотация, "наклиенте") > 0 Или (Истина И ПустаяСтрока(ПоследняяАннотация) И Не ЭтоМодульФормыУпр); СтрокаМетода.БезКонтекста = Найти(ПоследняяАннотация, "безконтекста") > 0; СтрокаМетода.ЛиАсинх = НРег(Лев(Заголовок, 1)) = "а"; СтрокаМетода.АдресГруппировки = ТекущийАдресГруппировки; СтрокаМетода.АдресКомпиляции = ТекущийАдресКомпиляции; Если СтарыйМодуль <> Неопределено Тогда //СтарыйМетод = СтарыйМодуль.Методы.Найти(СтрокаМетода.НИмя, "НИмя"); //Если Истина // //И СтарыйМетод.Вычислено // И ТипЗнч(СтарыйМетод.Параметры) <> Тип("Строка") // И Сред(СтарыйМодуль.Текст, СтарыйМетод.ПозицияСОписанием, СтарыйМетод.ДлинаСОписанием) = Вхождение.Value // И СтарыйМетод.Аннотация = СтрокаМетода.Аннотация //Тогда // СтрокаМетода.Параметры = СтарыйМетод.Параметры; // СтрокаМетода.Параметры.ЗаполнитьЗначения(, "ТаблицаТипов"); // СтрокаМетода.ОписаниеРезультата = СтарыйМетод.ОписаниеРезультата; // СтрокаМетода.ТипЗначения = СтарыйМетод.ТипЗначения; //КонецЕсли; КонецЕсли; Если ТекущийМетод <> Неопределено И СтрокаМетода.Имя <> СтароеИмя Тогда Модуль.ТаблицыСлов.Очистить(); КонецЕсли; ПозицияНачалаМетода = ПозицияВхождения; Если ПоследнееНачалоОписания <> Неопределено Тогда ПозицияНачалаМетода = Мин(ПозицияНачалаМетода, ПоследнееНачалоОписания); КонецЕсли; Если ПоследнееНачалоАннотации <> Неопределено Тогда ПозицияНачалаМетода = Мин(ПозицияНачалаМетода, ПоследнееНачалоАннотации); КонецЕсли; СмещениеНазад = ПозицияВхождения - ПозицияНачалаМетода; Если СмещениеНазад > 0 Тогда СтрокаМетода.ПозицияСОписанием = СтрокаМетода.ПозицияСОписанием - СмещениеНазад; СтрокаМетода.ДлинаСОписанием = СтрокаМетода.ДлинаСОписанием + СмещениеНазад; КонецЕсли; ПоследняяАннотация = ""; ПоследнееНачалоОписания = Неопределено; ПоследнееНачалоАннотации = Неопределено; ИначеЕсли Вхождение.SubMatches(8) <> Неопределено Тогда Если Модуль.ПозицияМетодов > ПозицияВхождения Тогда Продолжить; КонецЕсли; ПоследнееОписание = Вхождение.SubMatches(8); ПоследнееНачалоОписания = Вхождение.FirstIndex + НачальнаяПозицияДиапазона; ИначеЕсли Вхождение.SubMatches(9) <> Неопределено Тогда НоваяАннотация = Вхождение.SubMatches(9); СмещениеПозиции = 0; Если СтрЧислоСтрок(НоваяАннотация) = 3 Тогда ПоследнееОписание = ""; СмещениеПозиции = ирОбщий.ДлинаОтступаЛкс(НоваяАннотация, Ложь) - 1; КонецЕсли; НоваяАннотация = СокрЛП(НоваяАннотация); Если Истина И Лев(НоваяАннотация, 1) = "&" И (Ложь // отдаем приоритет директиве компиляции Или ПустаяСтрока(ПоследняяАннотация) Или Найти(ПоследняяАннотация, "(")) Тогда ПоследняяАннотация = НоваяАннотация; ПоследнееНачалоАннотации = Вхождение.FirstIndex + НачальнаяПозицияДиапазона + СмещениеПозиции; КонецЕсли; Если Лев(НоваяАннотация, 1) = "#" Тогда // TODO Сложность - обновление с середины модуля ПозицияАннотации = Вхождение.FirstIndex + НачальнаяПозицияДиапазона + СмещениеПозиции; ОбработатьАннотациюОбласти(НоваяАннотация, ПозицияАннотации, ОбластиГруппировки, ТекущаяОбластьГруппировки, ТекущийАдресГруппировки, ОбластиКомпиляции, ТекущаяОбластьКомпиляции, ТекущийАдресКомпиляции); КонецЕсли; КонецЕсли; КонецЦикла; Модуль.Удалить("МетодыТекст"); Модуль.Удалить("ВхожденияМетодов"); Если ОбластиКомпиляции.Строки.Количество() = 0 Тогда ОбластиКомпиляции = Неопределено; КонецЕсли; Если ОбластиГруппировки.Строки.Количество() = 0 Тогда ОбластиГруппировки = Неопределено; КонецЕсли; Модуль.Вставить("ОбластиКомпиляции", ОбластиКомпиляции); Модуль.Вставить("ОбластиГруппировки", ОбластиГруппировки); // Мультиметка723368140 Модуль.Вставить("Методы", Методы); Модуль.Вставить("Текст", ТекстМодуля); Модуль.Вставить("Ошибки", Ошибки); Модуль.Вставить("ТекстПоискаОпределенияСловМодуля"); ирОбщий.ДобавитьИндексВТаблицуЛкс(Методы, "ЛиЭкспорт"); ирОбщий.ДобавитьИндексВТаблицуЛкс(Методы, "ЛиЭкспорт, НИмя"); ирОбщий.ДобавитьИндексВТаблицуЛкс(Методы, "НИмя"); Если РазрешитьЕдиныйПустойМодуль Тогда Модуль.Имя = "<Пустой>"; мПустойМодуль = Модуль; КонецЕсли; Возврат Модуль; КонецФункции Процедура ОбработатьАннотациюОбласти(Знач НоваяАннотация, Знач ПозицияАннотации, Знач ОбластиГруппировки, ТекущаяОбластьГруппировки, ТекущийАдресГруппировки, Знач ОбластиКомпиляции, ТекущаяОбластьКомпиляции, ТекущийАдресКомпиляции) Если Найти(НоваяАннотация, "Область ") = 2 Тогда Если ТекущаяОбластьГруппировки = Неопределено Тогда ТекущаяОбластьГруппировки = ОбластиГруппировки; КонецЕсли; ТекущийАдресГруппировки = ?(ПустаяСтрока(ТекущийАдресГруппировки), "", ТекущийАдресГруппировки + ".") + ТекущаяОбластьГруппировки.Строки.Количество(); ТекущаяОбластьГруппировки = ТекущаяОбластьГруппировки.Строки.Добавить(); ТекущаяОбластьГруппировки.Имя = ирОбщий.ПоследнийФрагментЛкс(НоваяАннотация, " "); ТекущаяОбластьГруппировки.Начало = ПозицияАннотации; ИначеЕсли Найти(НоваяАннотация, "КонецОбласти") = 2 Тогда Если ТекущаяОбластьГруппировки <> Неопределено Тогда ТекущаяОбластьГруппировки.Конец = ПозицияАннотации; ТекущаяОбластьГруппировки = ирОбщий.РодительСтрокиДереваЛкс(ТекущаяОбластьГруппировки, ОбластиГруппировки); ТекущийАдресГруппировки = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ТекущийАдресГруппировки); КонецЕсли; ИначеЕсли Найти(НоваяАннотация, "Если ") = 2 Тогда Если ТекущаяОбластьКомпиляции = Неопределено Тогда ТекущаяОбластьКомпиляции = ОбластиКомпиляции; КонецЕсли; ТекущийАдресКомпиляции = ?(ПустаяСтрока(ТекущийАдресКомпиляции), "", ТекущийАдресКомпиляции + ".") + ТекущаяОбластьКомпиляции.Строки.Количество(); ТекущаяОбластьКомпиляции = ТекущаяОбластьКомпиляции.Строки.Добавить(); ТекущаяОбластьКомпиляции.Условие = ирОбщий.ТекстМеждуМаркерамиЛкс(НоваяАннотация, " ", " Тогда", Ложь); ТекущаяОбластьКомпиляции.Начало = ПозицияАннотации; ИначеЕсли Найти(НоваяАннотация, "КонецЕсли") = 2 Тогда Если ТекущаяОбластьКомпиляции <> Неопределено Тогда ТекущаяОбластьКомпиляции.Конец = ПозицияАннотации; ТекущаяОбластьКомпиляции = ирОбщий.РодительСтрокиДереваЛкс(ТекущаяОбластьКомпиляции, ОбластиКомпиляции); ТекущийАдресКомпиляции = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(ТекущийАдресКомпиляции); КонецЕсли; КонецЕсли; КонецПроцедуры // Параметры: // ИмяМодуля - Строка - // Возвращаемое значение: // см. НовыйИндексПоискаВызововСловаВМодуле - Функция ПрямыеВызовыМетодовМодуля(Знач ИмяМодуля, Знач ПозицияНачалаСтарая = Неопределено) Экспорт ПрямыеВызовыМетодов = мПрямыеВызовыМетодов[НРег(ИмяМодуля)]; Если ПрямыеВызовыМетодов <> Неопределено Тогда ВыполнитьОтложенноеОбновлениеВызововСловМодуля(ИмяМодуля, ПозицияНачалаСтарая); КонецЕсли; Возврат ПрямыеВызовыМетодов; КонецФункции //. // Параметры: // ИмяМодуля - Строка - // ПрямыеВызовыМетодов - см. НовыйИндексПоискаВызововСловаВМодуле - Процедура УстановитьПрямыеВызовыМетодовМодуля(Знач ИмяМодуля, Знач ПрямыеВызовыМетодов = Неопределено) Экспорт мПрямыеВызовыМетодов[НРег(ИмяМодуля)] = ПрямыеВызовыМетодов; КонецПроцедуры //. // Возвращаемое значение: // ТаблицаЗначений - Функция НоваяТаблицаПеременныхМодуля() Экспорт // При изменении нужно увеличивать версию формата Мультиметка91237881041 Переменные = Новый ТаблицаЗначений; Переменные.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево")); Переменные.Колонки.Добавить("Аннотация", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("Сервер", Новый ОписаниеТипов("Булево")); Переменные.Колонки.Добавить("Клиент", Новый ОписаниеТипов("Булево")); Переменные.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // вычислено по коду Переменные.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1. Переменные.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1. Переменные.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка")); Переменные.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов() Переменные.Индексы.Добавить("НИмя"); Возврат Переменные; КонецФункции Функция ЛиИмяМодуляФормы(Знач Имя) Экспорт Возврат ирОбщий.СтрКончаетсяНаЛкс(Имя, ".Форма.Модуль"); КонецФункции Функция ЛиПолноеИмяМакета(Знач ПолноеИмя) Экспорт Результат = Ложь Или ирОбщий.СтрНайтиЛкс(ПолноеИмя, ".Макет.") > 0 Или ирОбщий.СтрНачинаетсяСЛкс(ПолноеИмя, "ОбщийМакет.") > 0; Возврат Результат; КонецФункции Функция ЛиПолноеИмяФормы(Знач ПолноеИмя) Экспорт Результат = Ложь Или ирОбщий.СтрНайтиЛкс(ПолноеИмя, ".Форма.") > 0 Или ирОбщий.СтрНачинаетсяСЛкс(ПолноеИмя, "ОбщаяФорма.") > 0; Возврат Результат; КонецФункции Процедура ВыполнитьОтложенноеОбновлениеВызововСловМодуля(Знач ИмяМодуля, Знач ПозицияНачалаСтарая = Неопределено) Экспорт ПрямыеВызовыМетодов = мПрямыеВызовыМетодов[НРег(ИмяМодуля)]; // см. НовыйИндексПоискаВызововСловаВМодуле() Если Ложь Или ПрямыеВызовыМетодов = Неопределено Или Не ПрямыеВызовыМетодов.Свойство("ОтложенныйСдвиг") Тогда Возврат; КонецЕсли; ВыполнитьОтложенныйСдвигВызововСловМодуля(ПрямыеВызовыМетодов); ОтложенныйСдвиг = ПрямыеВызовыМетодов.ОтложенныйСдвиг; // см. НовыйОтложенныйСдвигВызововСловМодуля() Если ОтложенныйСдвиг.ПозицияНачалаСтарая = ПозицияНачалаСтарая Тогда Возврат; КонецЕсли; ПрямыеВызовыМетодовВМетоде = НовыйИндексПоискаВызововСловаВМодуле(,, ПрямыеВызовыМетодов.Оповещения <> Неопределено); ПрямыеВызовыМетодовВМетоде.СтруктураСлов = ПрямыеВызовыМетодов.СтруктураСлов; ирКэш.ПолеТекстаПрограммы().ЗаполнитьИндексПоискаВызововМетодовВМодуле(ПрямыеВызовыМетодовВМетоде, ОтложенныйСдвиг.ОпределениеСОписанием, ОтложенныйСдвиг.ПозицияНачалаСтарая); НачальныйИндекс = ОтложенныйСдвиг.НачальныеИндексы[ПрямыеВызовыМетодов.Вызовы]; ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ПрямыеВызовыМетодовВМетоде.Вызовы, ПрямыеВызовыМетодов.Вызовы,,,,, НачальныйИндекс); Если ПрямыеВызовыМетодов.Оповещения <> Неопределено Тогда НачальныйИндекс = ОтложенныйСдвиг.НачальныеИндексы[ПрямыеВызовыМетодов.Оповещения]; ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(ПрямыеВызовыМетодовВМетоде.Оповещения, ПрямыеВызовыМетодов.Оповещения,,,,, НачальныйИндекс); КонецЕсли; ПрямыеВызовыМетодов.Удалить("ОтложенныйСдвиг"); КонецПроцедуры Процедура ВыполнитьОтложенныйСдвигВызововСловМодуля(ПрямыеВызовыМетодов) Экспорт ОтложенныйСдвиг = ПрямыеВызовыМетодов.ОтложенныйСдвиг; // см. НовыйОтложенныйСдвигВызововСловМодуля() СдвинутьПозицииВТаблицеВызовов(ПрямыеВызовыМетодов.Вызовы, ОтложенныйСдвиг); Если ПрямыеВызовыМетодов.Оповещения <> Неопределено Тогда СдвинутьПозицииВТаблицеВызовов(ПрямыеВызовыМетодов.Оповещения, ОтложенныйСдвиг); КонецЕсли; КонецПроцедуры //. // Возвращаемое значение: // Структура - Функция НовыйОтложенныйСдвигВызововСловМодуля() Экспорт ОтложенныйСдвиг = Новый Структура; ОтложенныйСдвиг.Вставить("ПозицияНачалаСтарая", 0); ОтложенныйСдвиг.Вставить("ПозицияКонцаСтарая", 0); ОтложенныйСдвиг.Вставить("СмещениеКонечногоДиапазона", 0); ОтложенныйСдвиг.Вставить("ОпределениеСОписанием", ""); ОтложенныйСдвиг.Вставить("НачальныеИндексы", Новый Соответствие); Возврат ОтложенныйСдвиг; КонецФункции //. // Параметры: // ТаблицаВызовов - ТаблицаЗначений - // ПозицияКонцаСтарая - Число - // ПозицияНачалаСтарая - Число(10,0) - // СмещениеКонечногоДиапазона - Число, Неопределено - Процедура СдвинутьПозицииВТаблицеВызовов(Знач ТаблицаВызовов, Знач ОтложенныйСдвиг) Экспорт ПозицияНачалаСтарая = ОтложенныйСдвиг.ПозицияНачалаСтарая; ПозицияКонцаСтарая = ОтложенныйСдвиг.ПозицияКонцаСтарая; СмещениеКонечногоДиапазона = ОтложенныйСдвиг.СмещениеКонечногоДиапазона; ОпределениеСОписанием = ОтложенныйСдвиг.ОпределениеСОписанием; _РежимОтладки = Ложь; Если _РежимОтладки Тогда // Можно менять на Истина в точке останова, например условием ирОбщий.Пр(_РежимОтладки, 1, 1) // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для ИндексВызова = -ТаблицаВызовов.Количество()+1 По 0 Цикл СтрокаВызова = ТаблицаВызовов[-ИндексВызова]; Если СтрокаВызова.ПозицияВхождения < ПозицияНачалаСтарая Тогда Прервать; КонецЕсли; Если СтрокаВызова.ПозицияВхождения < ПозицияКонцаСтарая Тогда ТаблицаВызовов.Удалить(СтрокаВызова); Продолжить; КонецЕсли; СтрокаВызова.ПозицияВхождения = СтрокаВызова.ПозицияВхождения + СмещениеКонечногоДиапазона; КонецЦикла; Иначе // Однострочный код использован для ускорения при разрешенной отладке. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" Для ИндексВызова = -ТаблицаВызовов.Количество()+1 По 0 Цикл   СтрокаВызова = ТаблицаВызовов[-ИндексВызова];   Если СтрокаВызова.ПозицияВхождения < ПозицияНачалаСтарая Тогда   Прервать;   КонецЕсли;   Если СтрокаВызова.ПозицияВхождения < ПозицияКонцаСтарая Тогда   ТаблицаВызовов.Удалить(СтрокаВызова);   Продолжить;   КонецЕсли;   СтрокаВызова.ПозицияВхождения = СтрокаВызова.ПозицияВхождения + СмещениеКонечногоДиапазона;   КонецЦикла;   КонецЕсли; ОтложенныйСдвиг.НачальныеИндексы[ТаблицаВызовов] = -ИндексВызова + 1; КонецПроцедуры //. // Параметры: // СтрокаМетода - СтрокаТаблицыЗначений - // Ошибки - ОбработкаТабличнаяЧасть.ирКлсПолеТекстаПрограммы.ОшибкиМодуля - Процедура УдалитьОшибкиМетода(Знач СтрокаМетода, Знач Ошибки) Экспорт Если СтрокаМетода = Неопределено Тогда ИмяМетода = "<Инициация>"; Иначе БылиОшибки = СтрокаМетода.ЕстьОшибки = Истина; СтрокаМетода.ЕстьОшибки = Неопределено; Если Не БылиОшибки Тогда Возврат; КонецЕсли; ИмяМетода = СтрокаМетода.Имя; КонецЕсли; Для Каждого СтрокаОшибки Из Ошибки.НайтиСтроки(Новый Структура("Метод", ИмяМетода)) Цикл Ошибки.Удалить(СтрокаОшибки); КонецЦикла; КонецПроцедуры // Функция - Новая таблица методов модуля // // Возвращаемое значение: // ТаблицаЗначений // Функция НоваяТаблицаМетодовМодуля() Экспорт // При добавлении колонок желательно увеличивать версию формата Мультиметка91237881041 Методы = Новый ТаблицаЗначений; Методы.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); //Методы.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка")); //Методы.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("Аннотация", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("РасширяемыйМетод", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("Параметры"); // Строка, см. НоваяТаблицаПараметровМетодаМодуля Методы.Колонки.Добавить("МинЧислоПараметров"); // Число Методы.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1 Методы.Колонки.Добавить("ДлинаСОписанием", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("ПозицияОпределения", Новый ОписаниеТипов("Число")); // Начиная с 1. Может содержать непечатное смещение от начала строки Методы.Колонки.Добавить("ДлинаОпределения", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("ПозицияТела", Новый ОписаниеТипов("Число")); // Начиная с 1 Методы.Колонки.Добавить("ДлинаТела", Новый ОписаниеТипов("Число")); Методы.Колонки.Добавить("ТелоБезВозвратов"); Методы.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("ОписаниеРезультата"); Методы.Колонки.Добавить("ПозицияОписанияРезультата", Новый ОписаниеТипов("Число")); // Начиная с 1 Методы.Колонки.Добавить("ТипЗначения"); // - Используем значение Неопределено Методы.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов, Неопределено Методы.Колонки.Добавить("Сервер", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("Клиент", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("БезКонтекста", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("ЛиЭкспорт", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("ЛиАсинх", Новый ОписаниеТипов("Булево")); Методы.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); // тип значения вычислен по коду Методы.Колонки.Добавить("ЕстьОшибки"); // Булево Методы.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка")); Методы.Колонки.Добавить("КлючевыеПараметры"); // Структура, Неопределено Методы.Колонки.Добавить("КэшПоиска"); // Соответствие, Неопределено Методы.Колонки.Добавить("ТипыВыражений"); // Соответствие, Неопределено Методы.Колонки.Добавить("СтарыеТипы"); // Соответствие, Неопределено Методы.Колонки.Добавить("ВызывающиеМодули"); // Массив, Неопределено Методы.Колонки.Добавить("АдресГруппировки"); // Строка Методы.Колонки.Добавить("АдресКомпиляции"); // Строка Возврат Методы; КонецФункции Функция ПрефиксВременногоКомментирования() Экспорт Возврат "СлужебноИР "; КонецФункции Функция ЗамаскироватьДирективыПрепроцессора(Знач Текст, Знач ВнутриТекстовогоЛитерала = Истина) Экспорт Префикс = "//" + ПрефиксВременногоКомментирования(); НачалоСтрокиЗамены = ""; НачалоИскомойСтроки = "#"; Если ВнутриТекстовогоЛитерала Тогда НачалоСтрокиЗамены = "|"; НачалоИскомойСтроки = "#|//"; // - Обычные комментарии маскируем, чтобы отличать их от вложенных в текст литерала КонецЕсли; ВхожденияБлоков = ирОбщий.НайтиРегВыражениеЛкс(Текст, шПустоеНачалоСтроки + "#Удаление\s[\S\s]*?" + шПустоеНачалоСтроки + "#КонецУдаления",, Ложь); Для Каждого Вхождение Из ВхожденияБлоков Цикл НовыйФрагмент = СтрЗаменить(Вхождение.ТекстВхождения, Символы.ПС, Символы.ПС + НачалоСтрокиЗамены + Префикс); Текст = СтрЗаменить(Текст, Вхождение.ТекстВхождения, НовыйФрагмент); КонецЦикла; ВхожденияБлоков = ирОбщий.НайтиРегВыражениеЛкс(Текст, шПустоеНачалоСтроки + "#Если Сервер И Не Сервер Тогда\s[\S\s]*?" + шПустоеНачалоСтроки + "#КонецЕсли",, Ложь); Для Каждого Вхождение Из ВхожденияБлоков Цикл НовыйФрагмент = СтрЗаменить(Вхождение.ТекстВхождения, Символы.ПС, Символы.ПС + НачалоСтрокиЗамены + Префикс); Текст = СтрЗаменить(Текст, Вхождение.ТекстВхождения, НовыйФрагмент); КонецЦикла; Текст = ирОбщий.ЗаменитьРегВыражениеЛкс(Текст, "(\n|^)(\t| )*(" + НачалоИскомойСтроки + ")", "$1" + НачалоСтрокиЗамены + "$2" + Префикс + "$3", Ложь); Возврат Текст; КонецФункции Функция РазмаскироватьДирективыПрепроцессора(Знач Текст) Экспорт Текст = СтрЗаменить(Текст, Символы.ПС + "|//" + ПрефиксВременногоКомментирования(), Символы.ПС); Возврат Текст; КонецФункции //. // Параметры: // Переменные - ТаблицаЗначений - // ИмяПеременной - ? - // ЭкспортПеременной - ? - // ОписаниеСтроки - Строка - // ПозицияСОписанием - ? - Процедура ДобавитьПеременную(Переменные, ИмяПеременной, ЭкспортПеременной, Знач ОписаниеСтроки, Знач ПозицияСОписанием, Знач ПоследняяАннотация, Знач Сервер, Знач Клиент) Экспорт СтрокаПеременной = Переменные.Добавить(); СтрокаПеременной.Имя = ИмяПеременной; СтрокаПеременной.НИмя = Нрег(СтрокаПеременной.Имя); СтрокаПеременной.ЛиЭкспорт = ЭкспортПеременной; СтрокаПеременной.ПозицияСОписанием = ПозицияСОписанием; СтрокаПеременной.ПозицияОпределения = ПозицияСОписанием; СтрокаПеременной.Описание = ОписаниеСтроки; СтрокаПеременной.Аннотация = ПоследняяАннотация; СтрокаПеременной.Сервер = Сервер; СтрокаПеременной.Клиент = Клиент; КонецПроцедуры //. // Параметры: // СтрокаМетода - см. НоваяТаблицаМетодовМодуля()[0] - // выхБылиИзменения - Булево - // Возвращаемое значение: // ТаблицаЗначений, Неопределено - Функция ПараметрыМетодаМодуля(Знач СтрокаМетода, выхБылиИзменения = Ложь, Знач ДляКонструктора = Ложь) Экспорт Если СтрокаМетода = Неопределено Тогда Возврат Неопределено; КонецЕсли; Результат = СтрокаМетода.Параметры; Если ТипЗнч(Результат) = Тип("Строка") Тогда выхБылиИзменения = Истина; МинЧислоПараметров = 0; СтрокаМетода.Описание = ОчиститьТекстМодуляОтПрефиксаКомментария(СтрокаМетода.Описание); Если Не ДляКонструктора И Не ЗначениеЗаполнено(СтрокаМетода.Параметры) Тогда Результат = Неопределено; Иначе Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); мРегВыражение2.Global = Истина; мРегВыражение2.Pattern = Шаблоны.ПараметрыМетода; РезультатПараметров = мРегВыражение2.НайтиВхождения(СтрокаМетода.Параметры); Если Не ДляКонструктора И РезультатПараметров.Количество() = 0 Тогда Результат = Неопределено; Иначе Результат = НоваяТаблицаПараметровМетодаМодуля(); Если ДляКонструктора Тогда Результат.Колонки.Добавить("Виртуальный", Новый ОписаниеТипов("Булево")); КонецЕсли; Для Каждого ВхождениеПараметра Из РезультатПараметров Цикл СтрокаПараметра = Результат.Добавить(); СтрокаПараметра.Имя = ВхождениеПараметра.SubMatches(1); СтрокаПараметра.НИмя = НРег(СтрокаПараметра.Имя); СтрокаПараметра.Знач = ?(ВхождениеПараметра.SubMatches(0) = Неопределено, Ложь, Истина); СтрокаПараметра.Значение = СокрЛП(ВхождениеПараметра.SubMatches(2)); Если СтрокаПараметра.Значение = "" Тогда МинЧислоПараметров = Результат.Количество(); КонецЕсли; ОписаниеПараметра = ОчиститьТекстМодуляОтПрефиксаКомментария(ВхождениеПараметра.SubMatches(4)); ПозицияТире = Найти(ОписаниеПараметра, "-"); Если ПозицияТире > 0 Тогда СтрокаПараметра.ТипЗначения = Лев(ОписаниеПараметра, ПозицияТире - 1); СтрокаПараметра.Описание = Сред(ОписаниеПараметра, ПозицияТире + 1); Иначе СтрокаПараметра.ТипЗначения = ОписаниеПараметра; КонецЕсли; КонецЦикла; Если ЗначениеЗаполнено(СтрокаМетода.Описание) Тогда ОписанияПараметровЗагружены = Ложь; Если Найти(СтрокаМетода.Описание, ":") = 0 Тогда СсылкаНаОписание = ирОбщий.ПоследнийФрагментЛкс(СокрП(СтрокаМетода.Описание), Символы.ПС); Если УдалитьПрефиксИзТекстаТипов(СсылкаНаОписание) Тогда // Ссылка на описание друго метода. Параметры сопоставляются по позиции. //СтрокаМетода.Описание = СтрокаБазовогоМетода.Описание; Методы = Неопределено; Если Найти(СсылкаНаОписание, ".") = 0 Тогда Методы = СтрокаМетода.Владелец(); Иначе Если Прав(СсылкаНаОписание, 1) = "." Тогда СсылкаНаОписание = СокрП(ирОбщий.СтрокаБезКонцаЛкс(СсылкаНаОписание)); КонецЕсли; КраткоеИмяМодуля = ирОбщий.СтрокаБезПоследнегоФрагментаЛкс(СсылкаНаОписание); Анализатор = ирКэш.ПолеТекстаМодуляБезСтруктурыТипаЛкс(""); ТаблицаТиповМодуля = Анализатор.ВычислитьТипЗначенияВыражения(КраткоеИмяМодуля,,,,,, Ложь); Если ТаблицаТиповМодуля.Количество() > 0 Тогда Модуль = ПодготовитьМодульМетаданных(ТаблицаТиповМодуля[0]); Если Модуль <> Неопределено Тогда Методы = Модуль.Методы; КонецЕсли; КонецЕсли; КонецЕсли; Если Методы <> Неопределено Тогда ИмяБазовогоМетода = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПоследнийФрагментЛкс(СсылкаНаОписание), "("); СтрокаБазовогоМетода = Методы.Найти(НРег(ИмяБазовогоМетода), "НИмя"); Если СтрокаБазовогоМетода <> Неопределено Тогда ПараметрыБазовогоМетода = ПараметрыМетодаМодуля(СтрокаБазовогоМетода); Если ПараметрыБазовогоМетода <> Неопределено Тогда Для Индекс = 0 По Мин(ПараметрыБазовогоМетода.Количество(), Результат.Количество()) - 1 Цикл Результат[Индекс].Описание = ПараметрыБазовогоМетода[Индекс].Описание; Результат[Индекс].ТипЗначения = ПараметрыБазовогоМетода[Индекс].ТипЗначения; КонецЦикла; КонецЕсли; СтрокаМетода.ВызывающиеМодули = СтрокаБазовогоМетода.ВызывающиеМодули; ОписанияПараметровЗагружены = Истина; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ОписанияПараметровЗагружены Тогда ОписаниеПараметров = ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаМетода.Описание, ЗаголовокРазделаПараметры(), ЗаголовокРазделаВозвращаемоеЗначение(), Ложь,,, Истина); ВхожденияОписаний = ПараметрыМетодаИзКомментария(ОписаниеПараметров, Шаблоны); ПозицияОписания = СтрокаМетода.ПозицияСОписанием - СтрокаМетода.ПозицияТела; Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл СтрокаПараметра = Результат.Найти(НРег(ВхождениеОписания.Имя)); Если ДляКонструктора И СтрокаПараметра = Неопределено Тогда СтрокаПараметра = Результат.Добавить(); СтрокаПараметра.Имя = ВхождениеОписания.Имя; СтрокаПараметра.НИмя = НРег(СтрокаПараметра.Имя); СтрокаПараметра.Виртуальный = Истина; КонецЕсли; Если СтрокаПараметра <> Неопределено Тогда СтрокаПараметра.Описание = ВхождениеОписания.Описание; СтрокаПараметра.ПозицияСОписанием = ПозицияОписания + ВхождениеОписания.ПозицияВхождения + СтрДлина(ВхождениеОписания.Разделитель1) + СтрДлина(ВхождениеОписания.Имя) + СтрДлина(ВхождениеОписания.Разделитель2); СтрокаПараметра.ТипЗначения = ВхождениеОписания.ТипЗначения; Если Истина //И Не ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения) И ВхождениеОписания.ТипЗначения = Неопределено //И Не ДляКонструктора Тогда СтрокаПараметра.ТипЗначения = СокрЛП(ГрязныйТипИзОписанияПараметра(СтрокаПараметра.Описание)); КонецЕсли; ЧастьСоВторойСтроки = ирОбщий.СтрокаБезПервогоФрагментаЛкс(СтрокаПараметра.Описание, Символы.ПС); Если Истина И ЗначениеЗаполнено(ЧастьСоВторойСтроки) И Найти(ЧастьСоВторойСтроки, "-") // хорошо бы и второй вариант тире проверять Тогда // Если каждый тип описан с новой строки описания, то нужнен анализ описания https://www.hostedredmine.com/issues/984526 Если ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения) Тогда ОстатокОписания = ЧастьСоВторойСтроки; Иначе ОстатокОписания = ВхождениеОписания.Описание; КонецЕсли; ВхожденияТипов = ирОбщий.НайтиРегВыражениеЛкс(ОстатокОписания, шПустоеНачалоСтроки + "-\s*([^\-\:\n]+)"); Если ВхожденияТипов.Количество() > 0 Тогда Типы = ВхожденияТипов.ВыгрузитьКолонку("Группа0"); Если ЗначениеЗаполнено(СтрокаПараметра.ТипЗначения) Тогда Типы.Вставить(0, СтрокаПараметра.ТипЗначения); КонецЕсли; СтрокаПараметра.ТипЗначения = ирОбщий.СтрСоединитьЛкс(Типы); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; // ВызывающиеМодули шИмяМодуля = "\n[\t ]+(" + шИмяВременнойТаблицы + ")(?=\s)"; ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(ирОбщий.ТекстМеждуМаркерамиЛкс(СтрокаМетода.Описание + Символы.ПС, ЗаголовокРазделаВызывающиеМодули(), ":", Ложь,,, Истина), шИмяМодуля,,,, Ложь, Ложь); Если ВхожденияОписаний.Количество() > 0 Тогда СтрокаМетода.ВызывающиеМодули = Новый Массив; Для каждого ВхождениеОписания Из ВхожденияОписаний Цикл СтрокаМетода.ВызывающиеМодули.Добавить(ВхождениеОписания.Группа0); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; Если Не ДляКонструктора Тогда Для Каждого СтрокаПараметра Из Результат.НайтиСтроки(Новый Структура("ТипЗначения", "")) Цикл Если ПустаяСтрока(СтрокаПараметра.Значение) Тогда Продолжить; КонецЕсли; Если ирОбщий.ЛиБулевыйЛитералЛкс(СтрокаПараметра.Значение) Тогда СтрокаПараметра.ТипЗначения = "Булево"; Иначе ПервыйСимвол = Лев(СтрокаПараметра.Значение, 1); Если ПервыйСимвол = """" Тогда СтрокаПараметра.ТипЗначения = "Строка"; ИначеЕсли Найти("0123456789", ПервыйСимвол) > 0 Тогда СтрокаПараметра.ТипЗначения = "Число"; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; СтрокаМетода.МинЧислоПараметров = МинЧислоПараметров; Если Не ДляКонструктора Тогда СтрокаМетода.Параметры = Результат; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЗаголовокРазделаПараметры() Экспорт Возврат "Параметры:"; КонецФункции Функция ЗаголовокРазделаВызывающиеМодули() Экспорт Возврат "Вызывающие модули:"; КонецФункции Функция ЗаголовокРазделаВозвращаемоеЗначение() Экспорт Возврат "Возвращаемое значение:"; КонецФункции Функция ГрязныйТипИзОписанияПараметра(Знач Описание) Экспорт Возврат ирОбщий.ТекстМеждуМаркерамиЛкс(Описание, "-", Символы.ПС); КонецФункции //. // Возвращаемое значение: // ТаблицаЗначений - Функция НоваяТаблицаПараметровМетодаМодуля() Экспорт Результат = Новый ТаблицаЗначений; Результат.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("НИмя", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("ТипЗначения", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Описание", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Значение", Новый ОписаниеТипов("Строка")); Результат.Колонки.Добавить("Знач", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("ПозицияСОписанием", Новый ОписаниеТипов("Число")); // Начиная с 1 Результат.Колонки.Добавить("Вычислено", Новый ОписаниеТипов("Булево")); Результат.Колонки.Добавить("ТаблицаТипов"); // см. НоваяТаблицаТипов, Неопределено Возврат Результат; КонецФункции // Вызывается из других конфигураций! // Параметры: // ОписаниеМетода - Строка - // Шаблоны - Структура - для ускорения // Возвращаемое значение: // ТаблицаЗначений - Функция ПараметрыМетодаИзКомментария(Знач ОписаниеМетода, Шаблоны = Неопределено) Экспорт Если Шаблоны = Неопределено Тогда Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); КонецЕсли; шТире = "-–"; // Здесь 2 разных символа // Не поддерживает разбивку секции типа значения на 2 строки см. ирОбщий.ОтладитьЛкс Сделать TODO шОписаниеПараметра = "(\n[\t ]{0,8})(" + шИмя + ")(\*?[\t ]*(?:[" + шТире + "][\t ]*)([^" + шТире + "\n]*?))?([\t ]*[" + шТире + "]\s*?" + Шаблоны.ОписаниеПараметра + ")"; ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(ОписаниеМетода, шОписаниеПараметра, "Разделитель1, Имя, Разделитель2, ТипЗначения, Описание",,, Ложь, Ложь); Возврат ВхожденияОписаний; КонецФункции Функция ОчиститьТекстМодуляОтПрефиксаКомментария(Знач ТекстМодуля) Экспорт Если Не ЗначениеЗаполнено(ТекстМодуля) Тогда Возврат ""; КонецЕсли; Если Найти(ТекстМодуля, Символы.ПС) = 0 Тогда Позиция = Найти(ТекстМодуля, "//"); Если Позиция > 0 Тогда ТекстМодуля = Сред(ТекстМодуля, Позиция + 3); КонецЕсли; Возврат ТекстМодуля; КонецЕсли; мРегВыражение.Global = Истина; //мРегВыражение.Pattern = шПустоеНачалоСтроки + "(?:/){2,}"; //Результат = мРегВыражение.Заменить(ТекстМодуля, Символы.ПС); мРегВыражение.Pattern = "(" + шПустоеНачалоСтроки + ")(?://)"; Результат = мРегВыражение.Заменить(ТекстМодуля, "$1 "); // Сохраняем все позиции Если Лев(Результат, 1) = Символы.ПС Тогда Результат = Сред(Результат, 2); // Отрезаем начальный перенос строки КонецЕсли; Возврат Результат; КонецФункции Функция ПодготовитьТипРезультатаМетода(МетодМодуля, ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено, Знач СФактическимиПараметрами = Ложь, Знач ДляСвойства = "") Экспорт Если МетодМодуля.ТипЗначения = Неопределено Тогда // тип метода - "процедура" Возврат Неопределено; КонецЕсли; // Отключил 30.03.2025 //Если Истина // И МетодМодуля.ТаблицаТипов = Неопределено // И Не МетодМодуля.Вычислено // Временно добавил 30.03.2025 //Тогда // МетодМодуля.ТаблицаТипов = НоваяТаблицаТипов(); //КонецЕсли; ПодготовитьОписаниеРезультатаМетода(МетодМодуля); ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш); ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(МетодМодуля, Истина); ТаблицаТипов = ПодготовитьТипЗначенияСловаМодуля(ПолеТекстаМодуляКэш.ИмяПеременнойВозвращаемогоЗначения(), ПолеТекстаМодуляКэш, МетодМодуля, ИмяИлиМодуль, МетодМодуля, МетодМодуля.ОписаниеРезультата, СФактическимиПараметрами, Истина, ДляСвойства, МетодМодуля.ПозицияОписанияРезультата); Возврат ТаблицаТипов; КонецФункции //. // Параметры: // СтрокаОпределения - СтрокаТаблицыЗначений - Процедура ПодготовитьОписаниеРезультатаМетода(СтрокаОпределения, Знач ДляКонструктора = Ложь) Экспорт СыроеОписание = Неопределено; Если Истина И ЗначениеЗаполнено(СтрокаОпределения.Описание) И СтрокаОпределения.ОписаниеРезультата = Неопределено И (Ложь Или ДляКонструктора Или СтрокаОпределения.ТипЗначения <> Неопределено) Тогда СыроеОписание = СтрокаОпределения.Описание; ИначеЕсли Лев(СтрокаОпределения.ОписаниеРезультата, 2) = "//" Тогда СыроеОписание = СтрЗаменить(СтрокаОпределения.ОписаниеРезультата, "//", "// Результат:"); КонецЕсли; Если СыроеОписание <> Неопределено Тогда Шаблоны = ШаблоныДляАнализаВстроенногоЯзыка(); шТире = "-–"; // Здесь 2 разных символа ШаблонОписанияРезультата = "(?:Возвращаемое\s+значение|Результат)\:\s*(?:([^" + шТире + ":\n]+)\s*(?=[" + шТире + ":\n]))?\s*(" + Шаблоны.ОписаниеПараметра + ")"; ВхожденияОписаний = ирОбщий.НайтиРегВыражениеЛкс(СыроеОписание, ШаблонОписанияРезультата, "ТипЗначения, Описание", Ложь,, Ложь, Ложь); Если ВхожденияОписаний.Количество() > 0 Тогда ВхождениеОписания = ВхожденияОписаний[ВхожденияОписаний.Количество() - 1]; ОписаниеРезультата = СокрЛП(ВхождениеОписания.Описание); СтрокаОпределения.ОписаниеРезультата = ОчиститьТекстМодуляОтПрефиксаКомментария(ОписаниеРезультата); СтрокаОпределения.ПозицияОписанияРезультата = ВхождениеОписания.ПозицияВхождения - СтрДлина(СыроеОписание); Если СтрокаОпределения.ТипЗначения <> Неопределено Тогда ТекстТипаЗначения = СокрЛП(СтрЗаменить(ВхождениеОписания.ТипЗначения, "//", "")); Если ЗначениеЗаполнено(ТекстТипаЗначения) Тогда КопияТекстТипаЗначения = ТекстТипаЗначения; Если УдалитьПрефиксИзТекстаТипов(КопияТекстТипаЗначения) Тогда СтрокаОпределения.ТипЗначения = ТекстТипаЗначения; Иначе СтрокаОпределения.ТипЗначения = СтрокаОпределения.ТипЗначения + ", " + ТекстТипаЗначения; // TODO удаление дублей КонецЕсли; КонецЕсли; КонецЕсли; Иначе СтрокаОпределения.ОписаниеРезультата = ""; КонецЕсли; КонецЕсли; КонецПроцедуры // Функция - Удалить префикс из текста типов // // Параметры: // Текст - - // // Возвращаемое значение: // Булево - является ли ссылкой на описание (см.) // Функция УдалитьПрефиксИзТекстаТипов(Текст) Экспорт Текст = СокрЛП(Текст); МаркерСм = "см."; Если ирОбщий.СтрНачинаетсяСЛкс(Текст, МаркерСм) Тогда Текст = СокрЛ(Сред(Текст, СтрДлина(МаркерСм) + 1)); Возврат Истина; КонецЕсли; Если Найти(Текст, "(") > 0 И Найти(Текст, " ") = 0 Тогда Возврат Истина; КонецЕсли; Возврат Ложь; КонецФункции Функция ПодготовитьТипЗначенияПеременнойМодуля(СтрокаОпределения, ИмяИлиМодуль, Знач ПолеТекстаМодуляКэш = Неопределено, Знач ДляСвойства = "") Экспорт Если СтрокаОпределения.ТаблицаТипов = Неопределено Тогда СтрокаОпределения.ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; ПодготовитьОписаниеПеременнойМодуля(СтрокаОпределения); ПолеТекстаМодуляКэш = ПолеТекстаМодуля(ИмяИлиМодуль, ПолеТекстаМодуляКэш); ТаблицаТипов = ПодготовитьТипЗначенияСловаМодуля(СтрокаОпределения.Имя, ПолеТекстаМодуляКэш,, ИмяИлиМодуль, СтрокаОпределения, СтрокаОпределения.Описание,,, ДляСвойства); Если ТаблицаТипов.Количество() > 1 Тогда ирОбщий.УдалитьСтрокиТаблицыИлиДереваПоЗначениюЛкс(ТаблицаТипов, "ИмяОбщегоТипа", "Произвольный"); // Нужно для проверок выражений КонецЕсли; Возврат ТаблицаТипов; КонецФункции Процедура ПодготовитьОписаниеПеременнойМодуля(Знач СтрокаОпределения) Экспорт Если Истина И ЗначениеЗаполнено(СтрокаОпределения.Описание) И Не ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения) Тогда ТипЗначения = ирОбщий.ПервыйФрагментЛкс(СтрокаОпределения.Описание, "-"); СтрокаОпределения.Описание = Сред(СтрокаОпределения.Описание, СтрДлина(ТипЗначения) + 1); СтрокаОпределения.ТипЗначения = СокрЛ(ТипЗначения); КонецЕсли; КонецПроцедуры Функция ПодготовитьТипЗначенияСловаМодуля(Знач ИмяПеременной, Знач ПолеТекстаМодуляКэш, Знач МетодМодуля, Знач ИмяИлиМодуль, Знач СтрокаОпределения, Знач ОписаниеТипа = "", Знач СФактическимиПараметрами = Ложь, Знач ЭтоПрисвоенноеВыражение = Ложь, Знач ДляСвойства = "", Знач ПозицияОписания = 0) Если ПустаяСтрока(ИмяПеременной) Тогда ВызватьИсключение "Э"; КонецЕсли; Если СФактическимиПараметрами Тогда ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,, , ДляСвойства); Если ТаблицаТипов.Количество() = 0 И ТаблицаТипов.Колонки.Метаданные.Заголовок = "" Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("Произвольный")); КонецЕсли; ТаблицаТипов.ЗаполнитьЗначения(СтрокаОпределения, "СтрокаОписания"); Иначе //ТаблицаТипов = СтрокаОпределения.ТаблицаТипов; Если Ложь Или СтрокаОпределения.Вычислено Или СтрокаОпределения.Имя = "<>" Тогда ТаблицаТипов = СтрокаОпределения.ТаблицаТипов; Иначе СтрокаОпределения.ТаблицаТипов = Неопределено; // На случай рекурсивного обращения до завершения вычисления СтрокаОпределения.Вычислено = Истина; Попытка Если Истина И ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения) И (Ложь Или СтрокаОпределения.ТипЗначения <> "??" Или ЗначениеЗаполнено(ОписаниеТипа)) И СтрокаОпределения.ТипЗначения <> "?" Тогда ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(Неопределено); ТаблицаТиповИзКомментария = ПолеТекстаМодуляКэш.ТаблицаТиповИзТекста(СтрокаОпределения.ТипЗначения, ОписаниеТипа,, ДляСвойства,,,, ПозицияОписания, Истина); Если ТаблицаТиповИзКомментария.Колонки.Метаданные.Заголовок = "" Тогда ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТиповИзКомментария); КонецЕсли; КонецЕсли; УказанКонструктор = ЛиВСтрокеТиповЕстьКонструктор(СтрокаОпределения.ТипЗначения); Если Истина И Не УказанКонструктор И ЗначениеЗаполнено(ТаблицаТиповИзКомментария) И Лев(СтрокаОпределения.ТипЗначения, 1) = "?" //И Найти(НРег(СтрокаОпределения.ТипЗначения), " из ") = 0 // Иначе часть после "из" будет потеряна https://turboconf.ru/Tasks/9668 Тогда СтрокаОпределения.ТипЗначения = ПредставлениеМассиваСтруктурТипов(ТаблицаТиповИзКомментария); КонецЕсли; Если Ложь // Жертвует качеством расчета ради ускорения - дает 10% скорости при проверке модуля ирКлсПолеТекстаПрограммы Или (Истина И УказанКонструктор И Не ЗначениеЗаполнено(ДляСвойства) И ЛиДетальностьТиповДостаточна(ТаблицаТиповИзКомментария)) Или (Истина И МетодМодуля = Неопределено // только для переменных И ЗначениеЗаполнено(СтрокаОпределения.ТипЗначения) И Не УказанКонструктор И ЛиДетальностьТиповДостаточна(ТаблицаТиповИзКомментария, 4)) // Мультиметка481662548 Тогда // Считаем что тип в комментарии описан достаточно подробно ТаблицаТипов = ТаблицаТиповИзКомментария; Иначе ПолеТекстаМодуляКэш.ЗагрузитьМетодМодуля(МетодМодуля); ТаблицаТипов = ПолеТекстаМодуляКэш.ВычислитьТипЗначенияВыражения(ИмяПеременной,,,,,,, МетодМодуля = Неопределено, НоваяТаблицаТипов(), Истина,,,, ДляСвойства); Если ТаблицаТипов.Количество() > 0 Тогда // Мультиметка4529884 против циклической ссылки Для Каждого СтрокаТипа Из ТаблицаТипов.НайтиСтроки(Новый Структура("СтрокаОписания", СтрокаОпределения)) Цикл СтрокаТипа.СтрокаОписания = Неопределено; КонецЦикла; КонецЕсли; Если ТаблицаТипов.Колонки.Метаданные.Заголовок = "" Тогда ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТипов); Если Истина И ТаблицаТиповИзКомментария <> Неопределено И ТаблицаТиповИзКомментария.Колонки.Метаданные.Заголовок <> "" Тогда Если Истина И СтрокаОпределения.ТаблицаТипов.Количество() > 0 И СтрокаОпределения.ТаблицаТипов[0].Метаданные <> Неопределено // Иначе обрезанная Структура будет считаться полной Тогда // Для обогащения НоваяСтруктураТипа().ВиртуальнаяТаблица ТаблицаТиповИзКомментария.Колонки.Метаданные.Заголовок = ""; // - опасно, т.к. может сломать вычисление результата ОбъектБДПоКлючуЛкс через докОбъектБДПоКлючуСсылочный КонецЕсли; ДобавитьВТаблицуТипов(СтрокаОпределения.ТаблицаТипов, ТаблицаТиповИзКомментария); КонецЕсли; ТаблицаТипов = СтрокаОпределения.ТаблицаТипов; КонецЕсли; Если Истина И ТаблицаТиповИзКомментария <> Неопределено И (Ложь Или ТаблицаТипов.Количество() = 0 Или ТаблицаТипов.Колонки.Метаданные.Заголовок <> "") Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, ТаблицаТиповИзКомментария); КонецЕсли; КонецЕсли; Если ТаблицаТипов.Количество() = 0 И ТаблицаТипов.Колонки.Метаданные.Заголовок = "" Тогда ДобавитьВТаблицуТипов(ТаблицаТипов, НоваяСтруктураТипа("Произвольный")); КонецЕсли; //СтрокаОпределения.ТаблицаТипов.ЗаполнитьЗначения(СтрокаОпределения, "СтрокаОписания"); // Мультиметка4529884 Была циклическая ссылка ! Теперь заполняем ссылку позже уже в копии таблицы Исключение СтрокаОпределения.Вычислено = Ложь; // ВызватьИсключение; КонецПопытки; Если ТаблицаТипов.Колонки.Метаданные.Заголовок <> "" Тогда СтрокаОпределения.Вычислено = Ложь; КонецЕсли; Если Истина И МетодМодуля <> Неопределено И МетодМодуля.КлючевыеПараметры <> Неопределено Тогда Если Ложь Или ЛиДетальностьТиповДостаточна(ТаблицаТиповИзКомментария, 4) Или Не ЛиНестрогаяТаблицаТипов(ТаблицаТипов, Ложь, МетодМодуля.ТипЗначения) Тогда МетодМодуля.КлючевыеПараметры = Неопределено; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Возврат ТаблицаТипов; КонецФункции //. // Параметры: // ТаблицаТипов - ТаблицаЗначений - // Возвращаемое значение: // Булево Функция ЛиНестрогаяТаблицаТипов(Знач ТаблицаТипов, Знач ЛиВходящий, Знач ОбъявленныйТип) Экспорт ЛиКлючевойПараметр = Ложь Или ТаблицаТипов.Количество() - ТаблицаТипов.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", "Неопределено")).Количество() > 1 // Составной тип Или ТаблицаТипов.Найти("Произвольный", "ИмяОбщегоТипа") <> Неопределено; Если Не ЛиКлючевойПараметр Тогда Для Каждого СтрокаТипа Из ТаблицаТипов Цикл ИмяОбщегоТипа = СтрокаТипа.ИмяОбщегоТипа; Если ИмяОбщегоТипа = "Неопределено" Тогда Продолжить; КонецЕсли; ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "["); Попытка Тип = Тип(ИмяОбщегоТипа); Исключение Продолжить; КонецПопытки; ЛиКлючевойПараметр = Истина И (Ложь Или мМассивТиповСМетаданными.Найти(Тип) <> Неопределено //Или (Истина // И ЛиВходящий // И (Ложь // Или Тип = Тип("Строка") // Или Тип = Тип("Число"))) ) И (Ложь Или СтрокаТипа.Детальность < 4 Или (Истина И ОбъявленныйТип <> "??" И ЗначениеЗаполнено(ОбъявленныйТип) И Не ЛиВСтрокеТиповЕстьКонструктор(ОбъявленныйТип))); Прервать; // В таблице может быть макс. 2 шт КонецЦикла; КонецЕсли; Возврат ЛиКлючевойПараметр; КонецФункции Функция ЛиВСтрокеТиповЕстьКонструктор(Знач ОбъявленныйТип) Экспорт Возврат Найти(НРег(ОбъявленныйТип), "см.") > 0; КонецФункции // Модуль уже должен быть в кэше. // Параметры: // ИмяИлиМодуль - Структура - // ПолеТекстаМодуляКэш - ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено - // Возвращаемое значение: // ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено - Функция ПолеТекстаМодуля(Знач ИмяИлиМодуль, ПолеТекстаМодуляКэш = Неопределено) Экспорт Если ПолеТекстаМодуляКэш = Неопределено Тогда Если ТипЗнч(ИмяИлиМодуль) = Тип("Строка") Тогда ИмяМодуля = ИмяИлиМодуль; Иначе ИмяМодуля = ИмяИлиМодуль.Имя КонецЕсли; ПолеТекстаМодуляКэш = ирКэш.ПолеТекстаМодуляЛкс(ИмяМодуля); Если ТипЗнч(ИмяИлиМодуль) = Тип("Структура") Тогда НовыйМодуль = ИмяИлиМодуль; // Точно из кэша Иначе НовыйМодуль = МодульМетаданныхИзКэша(ИмяМодуля); КонецЕсли; Если НовыйМодуль <> Неопределено Тогда ПолеТекстаМодуляКэш.ЗагрузитьМодульМетаданных(НовыйМодуль); // Мультиметка250323_114539 КонецЕсли; ПолеТекстаМодуляКэш = ПолеТекстаМодуляКэш.КопияКомпоненты(); // Иначе при вызовах в рамках одного модуля будет переиспользоваться один объект и портиться контекст КонецЕсли; Возврат ПолеТекстаМодуляКэш; КонецФункции // Получает представление массива типов. // // Параметры: // ТаблицаТиповКонтекста - ТаблицаЗначений. // // Возвращаемое значение: // Строка - представление массива типов. // Функция ПредставлениеМассиваСтруктурТипов(ТаблицаТиповКонтекста, БезДублей = Ложь, МаксКоличествоТипов = 10, Знач Подробное = Истина) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаТиповКонтекста = Новый ТаблицаЗначений; #КонецЕсли ПредставлениеТипаКонтекста = ""; Если ТаблицаТиповКонтекста <> Неопределено Тогда Если ТаблицаТиповКонтекста.Количество() = 0 Тогда ИначеЕсли ТаблицаТиповКонтекста.Количество() = 1 Тогда ПредставлениеТипаКонтекста = ИмяТипаИзСтруктурыТипа(ТаблицаТиповКонтекста[0], Подробное); Иначе СписокОбрезан = Неопределено; СписокИменТипов = ТаблицаТиповДляПользователя(ТаблицаТиповКонтекста, БезДублей, МаксКоличествоТипов, СписокОбрезан, Подробное); Если СписокОбрезан Тогда СписокИменТипов.Добавить().Имя = "..."; КонецЕсли; ПредставлениеТипаКонтекста = ирОбщий.СтрСоединитьЛкс(СписокИменТипов.ВыгрузитьКолонку("Имя"), ", "); ПредставлениеТипаКонтекста = СтрЗаменить(ПредставлениеТипаКонтекста, "?, ", ""); КонецЕсли; КонецЕсли; Возврат ПредставлениеТипаКонтекста; КонецФункции Функция ТаблицаТиповДляПользователя(Знач ТаблицаТиповКонтекста, Знач БезДублей = Истина, Знач МаксКоличествоТипов = 0, выхСписокОбрезан = Ложь, Знач Подробное = Истина) Экспорт #Если Сервер И Не Сервер Тогда ТаблицаТиповКонтекста = Новый ТаблицаЗначений; #КонецЕсли Счетчик = 0; выхСписокОбрезан = Ложь; СписокИменТипов = Новый ТаблицаЗначений; СписокИменТипов.Колонки.Добавить("Имя"); СписокИменТипов.Колонки.Добавить("СтруктураТипа"); СтруктураТипаНеопределено = Неопределено; Для Каждого СтруктураТипаКонтекста Из ТаблицаТиповКонтекста Цикл Счетчик = Счетчик + 1; Если МаксКоличествоТипов > 0 И Счетчик > МаксКоличествоТипов Тогда выхСписокОбрезан = Истина; Прервать; КонецЕсли; ИмяТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипаКонтекста, Подробное); Если Не ЗначениеЗаполнено(ИмяТипа) Тогда Продолжить; КонецЕсли; Если ИмяТипа = "Неопределено" Тогда СтруктураТипаНеопределено = СтруктураТипаКонтекста; Продолжить; КонецЕсли; СтрокаИменТипов = СписокИменТипов.Добавить(); СтрокаИменТипов.Имя = ИмяТипа; СтрокаИменТипов.СтруктураТипа = СтруктураТипаКонтекста; КонецЦикла; СписокИменТипов.Сортировать("Имя"); Если СтруктураТипаНеопределено <> Неопределено Тогда // Чтобы Неопределено всегда шло последним СтрокаИменТипов = СписокИменТипов.Добавить(); СтрокаИменТипов.Имя = "Неопределено"; СтрокаИменТипов.СтруктураТипа = СтруктураТипаНеопределено; КонецЕсли; Если БезДублей Тогда СписокИменТипов.Свернуть("Имя"); КонецЕсли; Возврат СписокИменТипов; КонецФункции // Функция - Отбор параметров метода // // Параметры: // СтрокаОписания - СтрокаТаблицыЗначений - строка таблицы ТаблицаКонтекстов // // Возвращаемое значение: // - // Функция ОтборПараметровМетода(Знач СтрокаОписания) Экспорт ОтборПараметров = Новый Структура; ОтборПараметров.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста); Если СтрокаОписания.ТипСлова = "Конструктор" Тогда ОтборПараметров.Вставить("Слово", "<Новый>"); Иначе ОтборПараметров.Вставить("Слово", СтрокаОписания.Слово); КонецЕсли; ОтборПараметров.Вставить("ЯзыкПрограммы", СтрокаОписания.ЯзыкПрограммы); Возврат ОтборПараметров; КонецФункции // Функция - Таблица параметров метода для всех вариантов синтаксиса // // Параметры: // СтрокаОписания - СтрокаТаблицыЗначений, см. ОбработкаОбъект.ирПлатформа.ТаблицаКонтекстов[0] - // ОтборПараметров - - // // Возвращаемое значение: // - // Функция ПараметрыМетодаПлатформы(Знач СтрокаОписания) Экспорт ОтборПараметров = ОтборПараметровМетода(СтрокаОписания); КоличествоПараметров = 0; Если Не ЗначениеЗаполнено(СтрокаОписания.Описание) Тогда // Мультиметка443985642 СинтаксПомощник = СинтаксПомощник(); #Если Сервер И Не Сервер Тогда СинтаксПомощник = Обработки.ирСинтаксПомощник.Создать(); #КонецЕсли МассивВариантов = Новый Массив; Если СтрокаОписания.ТипСлова = "Конструктор" Тогда Отбор = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка, ТипСлова"); // индекс ЗаполнитьЗначенияСвойств(Отбор, СтрокаОписания); Для Каждого СтрокаВарианта Из ТаблицаКонтекстов.НайтиСтроки(Отбор) Цикл МассивВариантов.Добавить(СтрокаВарианта); КонецЦикла; Иначе МассивВариантов.Добавить(СтрокаОписания); КонецЕсли; Для Каждого ВариантМетода Из МассивВариантов Цикл ПутьКЭлементуАрхива = ВариантМетода.ПутьКОписанию; Если Не ЗначениеЗаполнено(ПутьКЭлементуАрхива) Тогда Продолжить; КонецЕсли; НовыйАдрес = СинтаксПомощник.РаспаковатьЭлементАрхиваСинтаксПомощника(ПутьКЭлементуАрхива); КоличествоПараметров = 100; Если НовыйАдрес <> Неопределено Тогда ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ирОбщий.ПервыйФрагментЛкс(НовыйАдрес, "#")); ТекстДокумента = ТекстовыйДокумент.ПолучитьТекст(); КоличествоПараметров = СинтаксПомощник.ЗагрузитьОписаниеМетода(ВариантМетода.ТипКонтекста, ВариантМетода.Слово, ТекстДокумента, ВариантМетода.ТипСлова, ВариантМетода.ЯзыкПрограммы,,, ВариантМетода); Иначе СтрокаОписания.Описание = "<Описание не найдено>"; // Чтобы больше не пытаться загружать КонецЕсли; КонецЦикла; КонецЕсли; СтрокиПараметров = ТаблицаПараметров.НайтиСтроки(ОтборПараметров); Пока Истина И КоличествоПараметров > 0 И КоличествоПараметров < СтрокиПараметров.Количество() И СтрокиПараметров[0].ВариантСинтаксиса = СтрокиПараметров[КоличествоПараметров].ВариантСинтаксиса Цикл // Удаляем дубли параметров виртуальных таблиц регистра бухгалтерии https://www.hostedredmine.com/issues/952173 ТаблицаПараметров.Удалить(СтрокиПараметров[КоличествоПараметров]); СтрокиПараметров.Удалить(КоличествоПараметров); КонецЦикла; СтрокиПараметров = ТаблицаПараметров.Скопировать(СтрокиПараметров); Возврат СтрокиПараметров; КонецФункции Функция ПолучитьТипЗначенияЧленаИнтерфейса(Член, ИмяБиблиотеки = "", ИнфоИнтерфейса = Неопределено) Экспорт //Тест = ПолучитьИмяТипаCOMVariant(Член); Попытка ОписаниеРезультата = Член.ReturnType; Исключение // Параметр метода //: Член = 0 // ParameterInfo {TLI.TLIApplication} ОписаниеРезультата = Член.VarTypeInfo; КонецПопытки; ИнфоТипаРезультата = ОписаниеРезультата.TypeInfo; Если ИнфоТипаРезультата <> Неопределено Тогда ТипЗначенияРезультата = ПолноеИмяТипаCOMОбъектаИзИнфоТипа(ИнфоТипаРезультата, ИмяБиблиотеки); ИначеЕсли Истина И ИмяБиблиотеки = "VBScript.RegExp" И ИнфоИнтерфейса.Name = "IRegExp2" И Член.Name = "Execute" Тогда ТипЗначенияРезультата = "MatchCollection {VBScript.RegExp}"; ИначеЕсли Истина И ИмяБиблиотеки = "VBScript.RegExp" И ИнфоИнтерфейса.Name = "IMatchCollection2" И Член.Name = "Item" Тогда ТипЗначенияРезультата = "Match {VBScript.RegExp}"; Иначе НомерТипа = ОписаниеРезультата.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Объект - - // ИмяОбщегоТипа - - // выхПолноеИмяОсновногоКласса - - // // Возвращаемое значение: // TypeInfo {TLI.TLIApplication}, InterfaceInfo {TLI.TLIApplication} - // Функция ПолучитьИнфоТипаCOMОбъекта(выхCOMОбъект, Знач ИмяОбщегоТипа = Неопределено, выхПолноеИмяОсновногоКласса = "") Экспорт ПолучитьCOMНавигатор(); Если COMНавигатор = "Отказ" Тогда Возврат Неопределено; КонецЕсли; Если ТипЗнч(выхCOMОбъект) = Тип("COMОбъект") Тогда Попытка COMНавигатор.ResolveAliases = Ложь; // Тут бывает кривой объект без свойств и методов и при выводе строки эта ошибка очень раздражает //ИнфоКласса = COMНавигатор.TypeLibInfoFromRegistry(); // По ИУД //ИнфоКласса = COMНавигатор.ClassInfoFromObject(выхCOMОбъект); // Этот способ не поддерживается в большинстве классов ИнфоИнтерфейса = COMНавигатор.InterfaceInfoFromObject(выхCOMОбъект); // Тут возникает ошибка для некоторых объектов, например V83.Application, ADODB.Recorset.Fields(*).Precision, WindowsInstaller.Installer Исключение ОписаниеОшибки = ОписаниеОшибки(); //ирОбщий.СообщитьЛкс(ОписаниеОшибки); Возврат Неопределено; КонецПопытки; КонецЕсли; Если ЗначениеЗаполнено(ИмяОбщегоТипа) Тогда выхПолноеИмяОсновногоКласса = ирОбщий.ТекстМеждуМаркерамиЛкс(ИмяОбщегоТипа, "{", "}", Ложь); ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, " "); КонецЕсли; Если Не ЗначениеЗаполнено(выхПолноеИмяОсновногоКласса) Тогда Если ТипЗнч(вых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Объекта(Знач ПолноеИмяОсновногоКлассаCOM, Знач ЧерезНовый = Истина) Экспорт КлючКэша = НРег(ПолноеИмяОсновногоКлассаCOM); Результат = мОбразцыCOMОбъектов[КлючКэша]; // Закомментировал т.к. замедляет работу анализатора кода например для V83.Application //Если Результат <> Неопределено Тогда // ИнфоИнтерфейса = ПолучитьИнфоТипаCOMОбъекта(Результат,, ПолноеИмяОсновногоКлассаCOM); // Если ИнфоИнтерфейса = Неопределено Тогда // // Объект испорчен // Результат = Неопределено; // КонецЕсли; //КонецЕсли; Если Результат = Неопределено Тогда Попытка Если ЧерезНовый Тогда Результат = Новый 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") Тогда ИмяОбщегоТипаЭлемента = ПолучитьТипЗначенияЧленаИнтерфейса(Член, ИмяБиблиотеки, ИнфоТипа); Результат.Добавить(ИмяОбщегоТипаЭлемента); Прервать; КонецЕсли; КонецЦикла; КонецЦикла; ИначеЕсли Истина И СтруктураТипаКоллекции.ИмяОбщегоТипа = "ЭлементыФормы" И ТипЗнч(СтруктураТипаКоллекции.СтрокаОписания) = Тип("СтрокаТаблицыЗначений") И СтруктураТипаКоллекции.СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено И СтруктураТипаКоллекции.СтрокаОписания.ТипКонтекста = "Форма" Тогда Результат = мМассивТиповЭлементовОбычнойФормы; ИначеЕсли Ложь Или СтруктураТипаКоллекции.ИмяОбщегоТипа = "ВсеЭлементыФормы" Или (Истина И СтруктураТипаКоллекции.ИмяОбщегоТипа = "ЭлементыФормы" // Если не обычные ЭлементыФормы, то управляемые //И ТипЗнч(СтруктураТипаКоллекции.СтрокаОписания) = Тип("СтрокаТаблицыЗначений") //И СтруктураТипаКоллекции.СтрокаОписания.ТипКонтекста = "ФормаКлиентскогоПриложения" ) Тогда // Нужно для типа результата Найти() Результат.Добавить("ГруппаФормы"); Результат.Добавить("ТаблицаФормы"); Результат.Добавить("ПолеФормы"); Результат.Добавить("КнопкаФормы"); Результат.Добавить("ДекорацияФормы"); Иначе СтруктураКлюча = Новый Структура("Слово, ЯзыкПрограммы", СтруктураТипаКоллекции.ИмяОбщегоТипа, ЯзыкПрограммы); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча); Если НайденныеСтроки.Количество() > 0 Тогда Если НайденныеСтроки[0].ТипЭлементаКоллекции <> "" Тогда Результат = ирОбщий.СтрРазделитьЛкс(НайденныеСтроки[0].ТипЭлементаКоллекции, ",", Истина); КонецЕсли; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиИмяСистемногоПеречисления(Знач ИмяОбщегоТипа) Экспорт Если Найти(ИмяОбщегоТипа, ".") > 0 Тогда Возврат Ложь; КонецЕсли; Если ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипа, "Перечисление") Тогда Возврат Истина; КонецЕсли; СтруктураКлюча = Новый Структура("БазовыйТип, ЯзыкПрограммы", "Перечисление" + ИмяОбщегоТипа, 0); ЛиИмяСистемногоПеречисления = ТаблицаОбщихТипов.НайтиСтроки(СтруктураКлюча).Количество() > 0; Возврат ЛиИмяСистемногоПеречисления; КонецФункции // Добавляет и заполняет строку в таблицу слов при условии отсутствия там строк по ключу (Слово, ТипСлова) // // Параметры: // ТаблицаСлов - ТаблицаЗначений, ТабличнаяЧасть - обычно см. НоваяТаблицаСлов() // Слово - Строка - // ТипСлова - Строка // ТаблицаТипов - ТаблицаЗначений // ТипЗначения - - // Определение - - // Вытеснять - - // СтарыеТипы - - // // Возвращаемое значение: // - // Функция ДобавитьВТаблицуСлов(Знач ТаблицаСлов, Знач Слово, Знач ТипСлова = "Свойство", Знач ТаблицаТипов = Неопределено, Знач ТипЗначения = "??", Знач Определение = "", Знач Вытеснять = Истина, Знач СтарыеТипы = Неопределено, Знач УстановитьНСлово = Ложь, Знач ЛиПолныйКонтрольУникальности = Ложь, Знач ТипЗначенияИндекс = "") Экспорт Если ТипЗначения = "??" И СтарыеТипы <> Неопределено Тогда СтарыйТип = СтарыеТипы[НРег(Слово)]; Если ЗначениеЗаполнено(СтарыйТип) Тогда ТипЗначения = ТипЗначения + ", " + СтарыйТип; КонецЕсли; КонецЕсли; Если ТипСлова = ПеречТипСлова.Конструкция Тогда Если ТипЗначения = "??" Тогда ТипЗначения = ""; КонецЕсли; Если Не ЗначениеЗаполнено(Определение) Тогда Определение = "Локальный"; КонецЕсли; КонецЕсли; Если ПустаяСтрока(ТипЗначенияИндекс) Тогда //ТипЗначенияИндекс = ТипЗначенияИндексИзТипа(ТипЗначения); // Вроде бы здесь это бессмысленно, т.к. тут не бывает скобок. Они появляются позже. ТипЗначенияИндекс = ТипЗначения; КонецЕсли; КлючПоиска = Новый Структура("Слово, ТипСлова", Слово, ТипСлова); Если Ложь Или (Истина И ТипСлова <> ПеречТипСлова.Метод // Для ускорения, т.к. платформа не позволяет перегружать методы И ТипСлова <> ПеречТипСлова.Конструкция) Или ЛиПолныйКонтрольУникальности // Но методы могут дублироваться при объединении (например равноправных типов) Тогда НайденныеСтроки = ТаблицаСлов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда Если ТаблицаТипов <> Неопределено Тогда // Например свойство "Параметры" перегружено в модуле конструктора запроса Если Вытеснять Тогда НайденныеСтроки[0].ТаблицаТипов = ТаблицаТипов; НайденныеСтроки[0].ТипЗначения = ТипЗначения; НайденныеСтроки[0].ТипЗначенияИндекс = ТипЗначенияИндекс; НайденныеСтроки[0].Определение = Определение; Иначе ДобавитьВТаблицуТипов(НайденныеСтроки[0].ТаблицаТипов, ТаблицаТипов); КонецЕсли; КонецЕсли; Возврат НайденныеСтроки[0]; КонецЕсли; КонецЕсли; СтрокаСлова = ТаблицаСлов.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаСлова, КлючПоиска); Если УстановитьНСлово Тогда СтрокаСлова.НСлово = НРег(Слово); КонецЕсли; СтрокаСлова.ТипЗначения = ТипЗначения; СтрокаСлова.ТипЗначенияИндекс = ТипЗначенияИндекс; СтрокаСлова.Определение = Определение; Если ЗначениеЗаполнено(ТаблицаТипов) Тогда СтрокаСлова.ТаблицаТипов = ТаблицаТипов; СтрокаОписания = ТаблицаТипов[0].СтрокаОписания; ТипЗначенияВложенный = Неопределено; Если СтрокаОписания <> Неопределено Тогда Попытка ТипЗначенияВложенный = СтрокаОписания.ТипЗначения; Исключение КонецПопытки; КонецЕсли; //Если Ложь // //Или ТипЗначенияВложенный = Неопределено // Отключил, чтобы вычисление представлений примитивных типов не откладывалось // //Или ТипЗначенияВложенный = "Произвольный" //Тогда // ТипЗначенияВложенный = "??"; //КонецЕсли; СтрокаСлова.МожноУточнитьТип = Ложь Или (Истина И ТипЗначенияВложенный <> "??" // Нужно чтобы вычисляемые по коду свойства и функции не вычислялись сразу при заполнении списка автодополнения И Лев(ТипЗначения, 2) = "??") Или Найти(ТипЗначения, "<") > 0; КонецЕсли; //: Если ТипСлова = "Метод" //: Если ТипСлова = "Свойство" //: Если ТипСлова = "Конструкция" Возврат СтрокаСлова; КонецФункции //. // Параметры: // ТипСловаФильтр - - // БазовоеРасширениеКонфигурации - - // ЯзыкПрограммы - - // Конфигурация - - // ВнешниеФункцииКомпоновкиДанных - - // ВычислятьТипы - - // ВнутриГруппыОбщихМодулей - - // ФлагиКомпиляции - см. НовыеФлагиКомпиляции - // СловоФильтр - - // МодульМетаданных - см. МодульМетаданных - // ВычислятьТипыМетодовМодулей - - // ТаблицаСлов - см. НоваяТаблицаСлов - // ЭтоЛокальныйКонтекст - - // НаборыСлов - - // СтрогийФильтр - - // ДляЗаписи - - // ТолькоСоЗначениями - - // ЗапретГлобальногоКонтекста - - Функция НовыеПараметрыЗаполненияСлов(Знач ТипСловаФильтр = Неопределено, Знач БазовоеРасширениеКонфигурации = "", Знач ЯзыкПрограммы = 0, Знач Конфигурация = Неопределено, Знач ВнешниеФункцииКомпоновкиДанных = Истина, Знач ВычислятьТипы = Истина, Знач ВнутриГруппыОбщихМодулей = Ложь, Знач ФлагиКомпиляции = Неопределено, Знач СловоФильтр = Неопределено, Знач МодульМетаданных = Неопределено, Знач ВычислятьТипыМетодовМодулей = Неопределено, Знач ТаблицаСлов = Неопределено, Знач ЭтоЛокальныйКонтекст = Ложь, Знач НаборыСлов = Неопределено, Знач СтрогийФильтр = Ложь, Знач ДляЗаписи = Ложь, Знач ТолькоСоЗначениями = Ложь, Знач ЗапретГлобальногоКонтекста = Ложь, Знач ТекущийИндекс = Неопределено, Знач ДляСвойства = "", Знач ЛиВместеСЛокальнымКонтекстом = Ложь, Знач ВиртуальнаяТаблица = Неопределено, Знач ПрименятьКонтракты = Ложь) Экспорт Результат = Новый Структура; Результат.Вставить("БазовоеРасширениеКонфигурации", БазовоеРасширениеКонфигурации); Результат.Вставить("ВиртуальнаяТаблица", ВиртуальнаяТаблица); Результат.Вставить("ВнешниеФункцииКомпоновкиДанных", ВнешниеФункцииКомпоновкиДанных); Результат.Вставить("ВнутриГруппыОбщихМодулей", ВнутриГруппыОбщихМодулей); Результат.Вставить("ВычислятьТипы", ВычислятьТипы); // - ЗаполнятьТипы Результат.Вставить("ВычислятьТипыМетодовМодулей", ВычислятьТипыМетодовМодулей); Результат.Вставить("ДляЗаписи", ДляЗаписи); Результат.Вставить("ДляСвойства", ДляСвойства); Результат.Вставить("ЗапретГлобальногоКонтекста", ЗапретГлобальногоКонтекста); Результат.Вставить("Конфигурация", Конфигурация); Результат.Вставить("ЛиВместеСЛокальнымКонтекстом", ЛиВместеСЛокальнымКонтекстом); Результат.Вставить("МодульМетаданных", МодульМетаданных); Результат.Вставить("НаборыСлов", НаборыСлов); Результат.Вставить("ПрименятьКонтракты", ПрименятьКонтракты И Не ЭтоЛокальныйКонтекст); Результат.Вставить("СловоФильтр", СловоФильтр); Результат.Вставить("СтрогийФильтр", СтрогийФильтр); Результат.Вставить("ТаблицаСлов", ТаблицаСлов); Результат.Вставить("ТекущийИндекс", ТекущийИндекс); Результат.Вставить("ТипСловаФильтр", ТипСловаФильтр); Результат.Вставить("ТолькоСоЗначениями", ТолькоСоЗначениями); Результат.Вставить("ФлагиКомпиляции", ФлагиКомпиляции); Результат.Вставить("ЭтоЛокальныйКонтекст", ЭтоЛокальныйКонтекст); Результат.Вставить("ЯзыкПрограммы", ЯзыкПрограммы); //: Если ТипСловаФильтр = "Метод" //: Если ТипСловаФильтр = "Свойство" //: Если ТипСловаФильтр = "Конструкция" Возврат Результат; КонецФункции // Получает таблицу слов указанной структуры типа. // // Параметры: // СтруктураТипа - см. НоваяСтруктураТипа - описание типа. // ПараметрыЗаполнения - см. НовыеПараметрыЗаполненияСлов - "" для основная конфигурация, "*" для все расширения // // Возвращаемое значение: // ТаблицаЗначений - с колонками "Слово", "ТипСлова", "ТаблицаТипов", "Определение". // Функция ТаблицаСловИзСтруктурыТипа(Знач СтруктураТипа, Знач ПараметрыЗаполнения = Неопределено) Экспорт ИнициацияОписанияМетодовИСвойств(); Если ПараметрыЗаполнения = Неопределено Тогда ПараметрыЗаполнения = НовыеПараметрыЗаполненияСлов(); КонецЕсли; Если ПараметрыЗаполнения.ФлагиКомпиляции = Неопределено Тогда ФлагиКомпиляции = НовыеФлагиКомпиляции(); КонецЕсли; КлючКэширования = Неопределено; ЭтоКонтракт = Истина И ПараметрыЗаполнения.ПрименятьКонтракты И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") И ирОбщий.СтрКончаетсяНаЛкс(СтруктураТипа.Метаданные.Имя, "Кнт", Истина); Если Истина И Не ПараметрыЗаполнения.ВнутриГруппыОбщихМодулей И Не ЭтоКонтракт Тогда ПараметрыЗаполнения.ТаблицаСлов = СловаКонтекстаПредопределенные(СтруктураТипа, ПараметрыЗаполнения, КлючКэширования); КонецЕсли; Если КлючКэширования <> Истина Тогда Если ЭтоКонтракт Тогда СтарыйСтрогийФильтр = ПараметрыЗаполнения.СтрогийФильтр; ПараметрыЗаполнения.СтрогийФильтр = Истина; КонецЕсли; ПараметрыЗаполнения.ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, ПараметрыЗаполнения, КлючКэширования); Если ЭтоКонтракт Тогда ПараметрыЗаполнения.СтрогийФильтр = СтарыйСтрогийФильтр; КонецЕсли; Если Истина И ПараметрыЗаполнения.СловоФильтр = Неопределено И КлючКэширования <> Неопределено Тогда ДобавитьТаблицуСловВГлобальныйКэш(ПараметрыЗаполнения.ТаблицаСлов, КлючКэширования, ПараметрыЗаполнения.НаборыСлов); КонецЕсли; КонецЕсли; Возврат ПараметрыЗаполнения.ТаблицаСлов; КонецФункции Функция ИмяКолонкиФлагаТаблицыТипов() Экспорт Возврат "ДержательМетаданных"; КонецФункции // Получает новую структуру типа. // // Параметры: // Нет. // // Возвращаемое значение: // Функция НоваяТаблицаДополнительныхТипов() Экспорт ТаблицаСтруктурТипа = Новый ТаблицаЗначений; ТаблицаСтруктурТипа.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка")); ТаблицаСтруктурТипа.Колонки.Добавить("Метаданные"); //ТаблицаСтруктурТипа.Колонки.Добавить("ВключатьСвойства", Новый ОписаниеТипов("Булево")); ТаблицаСтруктурТипа.Колонки.Добавить("НеВключатьМетоды", Новый ОписаниеТипов("Булево")); Возврат ТаблицаСтруктурТипа; КонецФункции // Получает допустимые типы (строку) из таблицы структур типа. // // Параметры: // ТаблицаТипов - ТаблицаЗначений. // // Возвращаемое значение: // Строка. // Функция ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов) Экспорт СтрокаСериализованныхТипов = ""; Для Каждого СтруктураТипа Из ТаблицаТипов Цикл СтрокаСериализованныхТипов = СтрокаСериализованныхТипов + ";" + СтруктураТипаВСтрокуВнутр(СтруктураТипа); КонецЦикла; СтрокаСериализованныхТипов = Сред(СтрокаСериализованныхТипов, 2); Возврат СтрокаСериализованныхТипов; КонецФункции Функция ДопустимыеТипыИзОписанияТипов(ОписаниеТипов) Экспорт ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов); ДопустимыеТипы = ДопустимыеТипыИзТаблицыСтруктурТипа(ТаблицаТипов); Возврат ДопустимыеТипы; КонецФункции // Получает представление допустимых типов. // // Параметры: // ДопустимыеТипы - Строка. // // Возвращаемое значение: // СтрокаПредставления - Строка. // Функция ПредставлениеДопустимыхТипов(ДопустимыеТипы) Экспорт ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы); СтрокаПредставления = ""; Для Каждого СтруктураТипа Из ТаблицаТипов Цикл СтрокаПредставления = СтрокаПредставления + ", " + ИмяТипаИзСтруктурыТипа(СтруктураТипа); ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); Если ТипМетаданных = Тип("КвалификаторыДаты") Тогда Квалификаторы = СтруктураТипа.Метаданные; Если Квалификаторы.ЧастиДаты = ЧастиДаты.Время Тогда ПредставлениеСоставаДаты = "В"; ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.Дата Тогда ПредставлениеСоставаДаты = "Д"; ИначеЕсли Квалификаторы.ЧастиДаты = ЧастиДаты.ДатаВремя Тогда ПредставлениеСоставаДаты = "ДВ"; КонецЕсли; СтрокаПредставления = СтрокаПредставления + "(" + ПредставлениеСоставаДаты + ")"; ИначеЕсли ТипМетаданных = Тип("КвалификаторыСтроки") Тогда Квалификаторы = СтруктураТипа.Метаданные; СтрокаПредставления = СтрокаПредставления + "(" + Квалификаторы.Длина + "," + ?(Квалификаторы.ДопустимаяДлина = ДопустимаяДлина.Фиксированная, "Ф", "П") + ")"; ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда Квалификаторы = СтруктураТипа.Метаданные; СтрокаПредставления = СтрокаПредставления + "(" + ?(Квалификаторы.ДопустимыйЗнак = ДопустимыйЗнак.Неотрицательный, "Н", "") + Квалификаторы.Разрядность + "," + Квалификаторы.РазрядностьДробнойЧасти + ")"; КонецЕсли; КонецЦикла; СтрокаПредставления = Сред(СтрокаПредставления, 3); Возврат СтрокаПредставления; КонецФункции // ПредставлениеДопустимыхТипов() // Получает структуру типа из значения. // // Параметры: // Значение - Произвольный; // *ЯзыкПрограммы - Число, *0; // *ШаблонСтруктурыТипа - Структура, СтрокаТаблицыЗначений, *Неопределено - содержит значения по умолчанию для новой структуры типа. // // Возвращаемое значение: // см. НоваяСтруктураТипа() - // Функция СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы = 0, ШаблонСтруктурыТипа = Неопределено, Знач РазрешитьЛюбойТипВКачествеМетаданных = Ложь) Экспорт Если Ложь Или РазрешитьЛюбойТипВКачествеМетаданных Или мМассивТиповСМетаданными.Найти(ТипЗнч(Значение)) <> Неопределено Тогда Если ШаблонСтруктурыТипа = Неопределено Тогда ШаблонСтруктурыТипа = Новый Структура; КонецЕсли; Если ТипЗнч(ШаблонСтруктурыТипа) = Тип("Структура") Тогда Если ирОбщий.СвойствоСтруктурыЛкс(ШаблонСтруктурыТипа, "Метаданные") = Неопределено Тогда ШаблонСтруктурыТипа.Вставить("Метаданные", Значение); КонецЕсли; КонецЕсли; КонецЕсли; СтруктураТипа = СтруктураТипаИзКонкретногоТипа(ТипЗнч(Значение), ЯзыкПрограммы, ШаблонСтруктурыТипа); Если СтруктураТипа.ИмяОбщегоТипа = "COMОбъект" Тогда СтруктураТипа.ИмяОбщегоТипа = ПолноеИмяТипаCOMОбъекта(Значение); //ИначеЕсли СтруктураТипа.ИмяОбщегоТипа = "ПеречислимоеСвойствоОбъектовМетаданных" Тогда // // Не работает. Оказывается одно ПеречислимоеСвойствоОбъектовМетаданных может иметь много экземпляров // СтрокиСвойствПеречислений = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ТипКонтекста", "ПеречислимыеСвойстваОбъектовМетаданных")); // Для Каждого СтрокиСвойстваПеречисления Из СтрокиСвойствПеречислений Цикл // Если Метаданные.СвойстваОбъектов[СтрокиСвойстваПеречисления.Слово] = Значение Тогда // СтруктураТипа.ИмяОбщегоТипа = "ПеречислениеМетаданных" + СтрокиСвойстваПеречисления.Слово; // Прервать; // КонецЕсли; // КонецЦикла; КонецЕсли; ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; //Если Ложь // Или (Истина // И ИмяОбщегоТипа = "СтрокаТаблицыЗначений" // И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ТаблицаЗначений")) // Или (Истина // И ИмяОбщегоТипа = "СтрокаДереваЗначений" // И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("ДеревоЗначений")) // Или (Истина // И ИмяОбщегоТипа = "ВыборкаИзРезультатаЗапроса" // И ТипЗнч(СтруктураТипа.Метаданные) <> Тип("РезультатЗапроса")) //Тогда // Попытка // СтруктураТипа.Метаданные = Значение.Владелец(); // Исключение // // Строка была удалена из коллекции // КонецПопытки; //КонецЕсли; Если ирОбщий.ЛиИмяТипаВнешнегоОбъектаМетаданныхЛкс(ИмяОбщегоТипа) Тогда //! Значение = 0 // ВнешняяОбработкаОбъект МетаданныеЗначения = Значение.Метаданные(); ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"; ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(ТипЗнч(Значение), МетаданныеЗначения, ЛиНеУчитыватьПодтип); СтруктураТипа.Метаданные = МетаданныеЗначения; СтруктураТипа.ДержательМетаданных = Значение; КлючПоиска = Новый Структура("Слово", ИмяОбщегоТипа); НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово; //Если СтруктураТипа.СтрокаОписания = Неопределено Тогда // СтруктураТипа.СтрокаОписания = НайденныеСтроки[0]; //КонецЕсли; КонецЕсли; КонецЕсли; Если Ложь Или ИмяОбщегоТипа = "Форма" Или ИмяОбщегоТипа = "ПолеВвода" //Или ИмяОбщегоТипа = "КолонкаТабличногоПоля" // в другом месте делаем Или ИмяОбщегоТипа = "ТабличноеПоле" Или ИмяОбщегоТипа = "УправляемаяФорма" Или ИмяОбщегоТипа = "ФормаКлиентскогоПриложения" Или ЛиИмяТипаЭлементаУправляемойФормы(ИмяОбщегоТипа) Тогда ИмяОбщегоТипаРасширения = ИмяТипаРасширенияЭлементаФормы(ИмяОбщегоТипа, Значение); Если ИмяОбщегоТипаРасширения <> Неопределено Тогда СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаРасширения; КонецЕсли; КонецЕсли; Если ИмяОбщегоТипа = "Форма" Тогда //СтруктураТипа.ДержательМетаданных = Значение; // Для формы тут должно быть имя расширения, а не сама форма КонецЕсли; Возврат СтруктураТипа; КонецФункции Функция ВсеИменаСобытийЭлементовФормы() Экспорт Если мВсеИменаСобытийЭлементовФормы = Неопределено Тогда ВсеИменаСобытий = ТаблицаКонтекстов.НайтиСтроки(Новый Структура("ЯзыкПрограммы, ТипЯзыка, ТипСлова", 0, "", "Событие")); мВсеИменаСобытийЭлементовФормы = Новый Структура; Для Каждого СтрокаСобытия Из ВсеИменаСобытий Цикл Если Ложь Или СтрокаСобытия.ТипКонтекста = "Глобальный" Или ирОбщий.СтрНачинаетсяСЛкс(СтрокаСобытия.ТипКонтекста, "Модуль") Или ирОбщий.ЛиИмяТипаФормыЛкс(СтрокаСобытия.ТипКонтекста, Истина) Или Найти(СтрокаСобытия.ТипКонтекста, ".") Тогда Продолжить; КонецЕсли; мВсеИменаСобытийЭлементовФормы.Вставить(СтрокаСобытия.Слово, СтрокаСобытия); КонецЦикла; КонецЕсли; Возврат мВсеИменаСобытийЭлементовФормы; КонецФункции Функция ОписаниеОбщегоТипа(Знач ИмяОбщегоТипа, Знач ЯзыкПрограммы = 0) Экспорт ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "["); // - для результата НайтиФайлы() СтрокиОбщегоТипа = ТаблицаОбщихТипов.НайтиСтроки(Новый Структура("Слово, ЯзыкПрограммы", ИмяОбщегоТипа, ЯзыкПрограммы)); Если СтрокиОбщегоТипа.Количество() > 0 Тогда Результат = СтрокиОбщегоТипа[0]; КонецЕсли; Возврат Результат; КонецФункции Функция ЛиИмяТипаЭлементаУправляемойФормы(Знач ИмяОбщегоТипа) Экспорт Результат = Ложь Или ИмяОбщегоТипа = "ДекорацияФормы" Или ИмяОбщегоТипа = "ПолеФормы" Или ИмяОбщегоТипа = "КнопкаФормы" Или ИмяОбщегоТипа = "ГруппаФормы" Или ИмяОбщегоТипа = "ТаблицаФормы"; Возврат Результат; КонецФункции // . Мультиметка638663811 // // Параметры: // БазовоеИмяОбщегоТипа - - // ЭлементИлиФорма - Форма, ПолеФормы, ПолеВвода - // // Возвращаемое значение: // - // Функция ИмяТипаРасширенияЭлементаФормы(БазовоеИмяОбщегоТипа, ЭлементИлиФорма = Неопределено) Экспорт ИмяОбщегоТипаРасширения = Неопределено; РасширяющийТип = Неопределено; Если Ложь Тогда #Если Клиент Тогда ИначеЕсли Ложь Или БазовоеИмяОбщегоТипа = "УправляемаяФорма" Или БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения" Тогда БазовоеИмяОбщегоТипа = "ФормаКлиентскогоПриложения"; СтруктураРасширяющегоТипа = СтруктураТипаОбъектаОбычнойФормы(ЭлементИлиФорма); Если СтруктураРасширяющегоТипа <> Неопределено Тогда РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; Иначе КлючОсновногоОбъекта = ирОбщий.КлючОсновногоОбъектаФормыЛкс(ЭлементИлиФорма); Если КлючОсновногоОбъекта <> Неопределено Тогда СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(КлючОсновногоОбъекта); ИмяОбщегоТипаОбъекта = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; Если Найти(ИмяОбщегоТипаОбъекта, "Ссылка.") > 0 Тогда Если Ложь Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Справочник") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Документ") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "ПланВидовХарактеристик") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "Задача") Или ирОбщий.СтрНачинаетсяСЛкс(ИмяОбщегоТипаОбъекта, "БизнесПроцесс") Тогда РасширяющийТип = СтрЗаменить(ИмяОбщегоТипаОбъекта, "Ссылка.", "Объект."); Иначе РасширяющийТип = "СсылочныйОбъект"; КонецЕсли; Иначе РасширяющийТип = СтрЗаменить(СтруктураРасширяющегоТипа.ИмяОбщегоТипа, "КлючЗаписи.", "Запись."); КонецЕсли; Иначе Попытка Пустышка = ЭлементИлиФорма.Параметры.РежимВыбора; ЭтоФормаДинамическогоСписка = ТипЗнч(ЭлементИлиФорма.Список) = Тип("ДинамическийСписок"); Исключение ЭтоФормаДинамическогоСписка = Ложь; КонецПопытки; Если ЭтоФормаДинамическогоСписка Тогда РасширяющийТип = "ДинамическийСписок"; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или БазовоеИмяОбщегоТипа = "ДекорацияФормы" Или БазовоеИмяОбщегоТипа = "ПолеФормы" Или БазовоеИмяОбщегоТипа = "ГруппаФормы" Тогда Если Ложь Или ирОбщий.ЛиФормаИлиИмитаторЛкс(ЭлементИлиФорма) Или ТипЗнч(ЭлементИлиФорма) = Тип("Структура") И Не ЭлементИлиФорма.Свойство("Вид") Тогда Пустышка = 0; // TODO Приходим сюда при вводе имени события в ДинамическоеПолеФормы.Установитьдействие(" Иначе Если Истина И ТипЗнч(ЭлементИлиФорма.Вид) <> Тип("Строка") И ЗначениеЗаполнено(ЭлементИлиФорма.Вид) Тогда ИмяВида = ПолучитьПолноеИмяПредопределенногоЗначения(ЭлементИлиФорма.Вид); Иначе ИмяВида = ЭлементИлиФорма.Вид; КонецЕсли; РасширяющийТип = ирОбщий.ПоследнийФрагментЛкс(ИмяВида); КонецЕсли; ИначеЕсли БазовоеИмяОбщегоТипа = "ТаблицаФормы" Тогда РасширяющийТип = ирОбщий.ОбщийТипДанныхТабличногоПоляЛкс(ЭлементИлиФорма); Если РасширяющийТип = "Список" Тогда РасширяющийТип = "ДинамическийСписок"; КонецЕсли; ИначеЕсли БазовоеИмяОбщегоТипа = "Форма" Тогда СтруктураРасширяющегоТипа = СтруктураТипаОбъектаОбычнойФормы(ЭлементИлиФорма); Если СтруктураРасширяющегоТипа <> Неопределено Тогда РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; КонецЕсли; Иначе #КонецЕсли Попытка ДанныеЭлементаФормы = ЭлементИлиФорма.Значение; Исключение // Случается из-за особенностей платформы. Иногда она убирает это свойство из элемента управления. КонецПопытки; СтруктураРасширяющегоТипа = СтруктураТипаИзЗначения(ДанныеЭлементаФормы); РасширяющийТип = СтруктураРасширяющегоТипа.ИмяОбщегоТипа; Если ирОбщий.СтрКончаетсяНаЛкс(РасширяющийТип, ".<Имя табличной части>") Тогда РасширяющийТип = "ТабличнаяЧасть"; КонецЕсли; Если ЛиИмяСистемногоПеречисления(СтруктураРасширяющегоТипа.ИмяОбщегоТипа) Тогда РасширяющийТип = "Системное перечисление"; КонецЕсли; КонецЕсли; Если РасширяющийТип <> Неопределено Тогда Если РасширяющийТип = "ВнешняяОбработкаОбъект.<Имя внешней обработки>" Тогда РасширяющийТип = "ОбработкаОбъект.<Имя обработки>"; ИначеЕсли РасширяющийТип = "ВнешнийОтчетОбъект.<Имя внешнего отчета>" Тогда РасширяющийТип = "ОтчетОбъект.<Имя отчета>"; КонецЕсли; СтруктураКлюча = Новый Структура("РасширяющийТип, ОсновнойТип", РасширяющийТип, БазовоеИмяОбщегоТипа); МассивНайденных = ТаблицаРасширенийТипов.НайтиСтроки(СтруктураКлюча); Если МассивНайденных.Количество() > 0 Тогда ИмяОбщегоТипаРасширения = МассивНайденных[0].Расширение; КонецЕсли; КонецЕсли; Возврат ИмяОбщегоТипаРасширения; КонецФункции Функция ОписаниеРасширенногоТипа(Знач РасширенныйТип) Экспорт Если ирОбщий.СтрНачинаетсяСЛкс(РасширенныйТип, "ОбъектМетаданных") Тогда //Результат = Новый Структура(ирОбщий.СтрСоединитьЛкс(ТаблицаРасширенийТипов.Колонки,,,,, "Имя")); ////! Результат = ирОбщий.СтруктураИзСтрокиТаблицыИлиДереваИлиВыборкиЛкс(ТаблицаРасширенийТипов[0]) Результат = Новый Структура("ОсновнойТип, РасширяющийТип, Расширение"); Результат.ОсновнойТип = "ОбъектМетаданных"; Иначе Результат = ТаблицаРасширенийТипов.Найти(РасширенныйТип, "Расширение"); КонецЕсли; Возврат Результат; КонецФункции Функция УникальныйИдентификаторИзСтроки(Текст) Экспорт Цифра = "[a-fA-F0-9]"; мРегВыражение.Pattern = "(" + ирОбщий.СтрокаПовторомЛкс(Цифра, 32) + ")|(" + ирОбщий.СтрокаПовторомЛкс(Цифра, 8) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 4) + "-" + ирОбщий.СтрокаПовторомЛкс(Цифра, 12) + ")"; Вхождения = мРегВыражение.НайтиВхождения(Текст); Если Вхождения.Количество() > 0 Тогда Вхождение = Вхождения[0]; Если Вхождение.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, ШаблонСтруктурыТипа = Неопределено) Экспорт //ШаблонСтруктурыТипа. СтруктураТипа = НоваяСтруктураТипа(); Если ШаблонСтруктурыТипа <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа); КонецЕсли; Если ЯзыкПрограммы = 1 И КонкрентыйТип = Тип("ТаблицаЗначений") Тогда СтруктураТипа.ИмяОбщегоТипа = "ВременнаяТаблица"; // Для ускорения ИначеЕсли КонкрентыйТип = Тип("Число") Тогда СтруктураТипа.ИмяОбщегоТипа = "Число"; ИначеЕсли КонкрентыйТип = Тип("Строка") Тогда СтруктураТипа.ИмяОбщегоТипа = "Строка"; ИначеЕсли КонкрентыйТип = Тип("Булево") Тогда СтруктураТипа.ИмяОбщегоТипа = "Булево"; ИначеЕсли КонкрентыйТип = Тип("ОписаниеТипов") Тогда СтруктураТипа.ИмяОбщегоТипа = "ОписаниеТипов"; ИначеЕсли КонкрентыйТип = Тип("Массив") Тогда СтруктураТипа.ИмяОбщегоТипа = "Массив"; ИначеЕсли КонкрентыйТип = Тип("Структура") Тогда СтруктураТипа.ИмяОбщегоТипа = "Структура"; ИначеЕсли КонкрентыйТип = Тип("ОбъектМетаданных") Тогда Если Истина И ШаблонСтруктурыТипа <> Неопределено // было закомментировано И ТипЗнч(ШаблонСтруктурыТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ШаблонСтруктурыТипа.Метаданные.ПолноеИмя()); // Исключения из общего правила Если МассивФрагментов[0] = "ОбщаяФорма" Тогда МассивФрагментов[0] = "Форма"; ИначеЕсли МассивФрагментов[0] = "ОбщийМакет" Тогда МассивФрагментов[0] = "Макет"; КонецЕсли; СтруктураТипа.ИмяОбщегоТипа = МаркерОбъектаМетаданных + МассивФрагментов[МассивФрагментов.ВГраница() - 1]; Иначе СтруктураТипа.ИмяОбщегоТипа = ИмяОбщегоТипаОбъектаМетаданных(); КонецЕсли; ИначеЕсли Истина И КонкрентыйТип = Тип("КоллекцияОбъектовМетаданных") И ШаблонСтруктурыТипа <> Неопределено И СтруктураТипа.ИмяОбщегоТипа <> "НеизвестныйКонтекст" Тогда // Иначе Если Истина И ТипЗнч(КонкрентыйТип) = Тип("Тип") //И КонкрентыйТип <> Тип("КонстантыНабор") // Антибаг платформы http://partners.v8.1c.ru/forum/thread.jsp?id=876094#876094 . Отключил, т.к. первое вычисление занимает 200мс https://www.hostedredmine.com/issues/995887 И Не (Истина // Антибаг платформы. При правке внешней обработки во время ее отладки ее тип может становиться "Тип не определен '794a4eb3-0aff-402c-b654-e1670e90df73'" https://www.hostedredmine.com/issues/992088 И Найти(КонкрентыйТип, "'") > 0 И Найти(КонкрентыйТип, ":") = 0) Тогда МетаданныеТипа = мМетаданные.НайтиПоТипу(КонкрентыйТип); КонецЕсли; Если Ложь Или МетаданныеТипа = Неопределено Или ТипЗнч(МетаданныеТипа) = Тип("ОбъектМетаданныхКонфигурация") Тогда ПредставлениеТипа = Строка(КонкрентыйТип); ИдентификаторТипа = ""; Если Найти(ПредставлениеТипа, "'") > 0 Тогда // Антибаг платформы. При правке внешней обработки во время ее отладки ее тип может становиться "Тип не определен '794a4eb3-0aff-402c-b654-e1670e90df73'" https://www.hostedredmine.com/issues/992088 ПредставлениеТипа = "Внешняя обработка"; ИначеЕсли Найти(ПредставлениеТипа, ":") = 0 Тогда ИдентификаторТипа = ирОбщий.ИдентификаторТипаЛкс(КонкрентыйТип); Иначе // Внешние метаданные ПредставлениеТипа = ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"); Если НРег(ПредставлениеТипа) = Нрег("External data processor") Тогда ПредставлениеТипа = "Внешняя обработка"; ИначеЕсли НРег(ПредставлениеТипа) = Нрег("External data processor tabular section") Тогда ПредставлениеТипа = "Внешняя обработка табличная часть"; КонецЕсли; КонецЕсли; Если ИдентификаторТипа <> "" Тогда КлючПоиска = Новый Структура("ИД", ИдентификаторТипа); Иначе //КлючПоиска = Новый Структура("Представление, ТипТипа", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":"), "Основной"); КлючПоиска = Новый Структура("Представление", ирОбщий.ПервыйФрагментЛкс(ПредставлениеТипа, ":")); КонецЕсли; Иначе ЛиНеУчитыватьПодтип = (ЯзыкПрограммы <> 0) И СтруктураТипа.ТипЯзыка <> "ЗначениеВЗапросе"; ИмяОбщегоТипа = ИмяОбщегоТипаИзТипаЗначенияСМетаданными(КонкрентыйТип, МетаданныеТипа, ЛиНеУчитыватьПодтип); СтруктураТипа.Метаданные = МетаданныеТипа; КлючПоиска = Новый Структура("Слово, ТипТипа", ИмяОбщегоТипа, "Основной"); КонецЕсли; НайденныеСтроки = ТаблицаОбщихТипов.НайтиСтроки(КлючПоиска); Если НайденныеСтроки.Количество() > 0 Тогда СтруктураТипа.ИмяОбщегоТипа = НайденныеСтроки[0].Слово; //Если СтруктураТипа.СтрокаОписания = Неопределено Тогда // СтруктураТипа.СтрокаОписания = НайденныеСтроки[0]; //КонецЕсли; ИначеЕсли Найти(КонкрентыйТип, " ") = 0 Тогда СтруктураТипа.ИмяОбщегоТипа = Строка(КонкрентыйТип); Иначе // Например тупиковый устаревший ПолеТабличногоДокументаФормы //ирОбщий.СообщитьЛкс("Невозможно восстановить имя типа """ + КонкрентыйТип + """", СтатусСообщения.Важное); КонецЕсли; КонецЕсли; Возврат СтруктураТипа; КонецФункции // Наиболее частый тип объекта метаданных. Это лучше чем абстрактный тип "ОбъектМетаданных" без членов. Функция ИмяОбщегоТипаОбъектаМетаданных() Экспорт //Возврат "ОбъектМетаданныхСправочник"; Возврат "ОбъектМетаданных"; КонецФункции // Получает таблицу структур типов из описания типов. // // Параметры: // ОписаниеТипов - ОписаниеТипов - // *ТаблицаТипов - см. НоваяТаблицаТипов(), *Неопределено - существующая таблица. // // Возвращаемое значение: // см. НоваяТаблицаТипов() // Функция ТаблицаТиповИзОписанияТипов(ОписаниеТипов, ТаблицаТипов = Неопределено) Экспорт // TODO Заменить на прямой вызов ДобавитьВТаблицуТипов Возврат ДобавитьВТаблицуТипов(ТаблицаТипов, ОписаниеТипов); КонецФункции Функция МаксЧислоТиповДляАнализа() Экспорт Возврат 100; КонецФункции Функция ТаблицаТиповИзЗначения(Значение, ТаблицаТипов = Неопределено, ЯзыкПрограммы = 0) Экспорт Если ТаблицаТипов = Неопределено Тогда ТаблицаТипов = НоваяТаблицаТипов(); КонецЕсли; СтруктураТипа = СтруктураТипаИзЗначения(Значение, ЯзыкПрограммы); ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); Возврат ТаблицаТипов; КонецФункции // Получает объект по ссылке, кэшируя результат в соответствии. // // Параметры: // Ссылка - Ссылка; // ПринудительноОбновить - Булево, *Ложь. // // Возвращаемое значение: // Объект. // Функция КэшОбъект(Ссылка, ПринудительноОбновить = Ложь) Экспорт ТипСсылки = ТипЗнч(Ссылка); Кэш = КэшОбъектов[ТипСсылки]; Если Кэш = Неопределено Тогда Кэш = Новый Соответствие; КэшОбъектов[ТипСсылки] = Кэш; КонецЕсли; Если Не ПринудительноОбновить Тогда Результат = Кэш[Ссылка]; КонецЕсли; Если Результат = Неопределено Тогда Результат = Ссылка.ПолучитьОбъект(); Кэш[Ссылка] = Результат; КонецЕсли; Возврат Результат; КонецФункции // Получает строку конкретного типа. // // Параметры: // СтруктураТипа - см. НоваяСтруктураТипа - описание типа. // // Возвращаемое значение: // Строка - конкрентого типа. // Функция ИмяТипаИзСтруктурыТипа(Знач СтруктураТипа, Знач Подробное = Истина) Экспорт КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа; МаркерРасширенияФормы = "РасширениеФормы"; Если ирОбщий.СтрНачинаетсяСЛкс(КонкретныйТип, МаркерРасширенияФормы, Истина) Тогда КонкретныйТип = "Форма"; // TODO Сделать учет типа формы КонецЕсли; Если Подробное Тогда Если Истина И ирОбщий.ЛиИмяТипаФормыЛкс(КонкретныйТип, Истина, Истина) И ирОбщий.ЛиФормаИлиИмитаторЛкс(СтруктураТипа.Метаданные) Тогда ИмяФормы = ирОбщий.ПолноеИмяФормыЛкс(СтруктураТипа.Метаданные); Если ЗначениеЗаполнено(ИмяФормы) Тогда КонкретныйТип = "Форма[" + ИмяФормы + "]"; Иначе КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа; КонецЕсли; ИначеЕсли КонкретныйТип = "ОбщийМодуль" И ТипЗнч(СтруктураТипа.Метаданные) = Тип("ОбъектМетаданных") Тогда КонкретныйТип = КонкретныйТип + "[" + СтруктураТипа.Метаданные.Имя + "]"; Иначе КонкретныйТип = СтруктураТипа.ИмяОбщегоТипа; КонецЕсли; КонецЕсли; //Если Лев(КонкретныйТип, СтрДлина(МаркерКоллекцииМетаданных)) = МаркерКоллекцииМетаданных Тогда // КонкретныйТип = МаркерКоллекцииМетаданных; //КонецЕсли; ОбъектМД = СтруктураТипа.Метаданные; Если Истина И ТипЗнч(ОбъектМД) = Тип("КоллекцияОбъектовМетаданных") И ОбъектМД.Количество() > 0 Тогда ОбъектМД = ОбъектМД[0].Родитель(); КонецЕсли; ТипМетаданных = ТипЗнч(ОбъектМД); Если Истина И ТипМетаданных = Тип("ОбъектМетаданных") И Найти(КонкретныйТип, "<") > 0 Тогда ПолноеИмя = ОбъектМД.ПолноеИмя(); МассивФрагментов = ирОбщий.СтрРазделитьЛкс(ПолноеИмя); Если МассивФрагментов[0] = "ТабличнаяЧасть" Тогда // Баг платформы. У внешних метаданных полное имя не включает сам внешний метаобъект МассивФрагментов.Вставить(0, "Имя"); МассивФрагментов.Вставить(0, ""); КонецЕсли; Для Счетчик = 0 По МассивФрагментов.Количество() / 2 - 1 Цикл ИмяЭлементаКоллекции = ирОбщий.ТекстМеждуМаркерамиЛкс(КонкретныйТип, "<", ">", Ложь, Истина); КонкретныйТип = СтрЗаменить(КонкретныйТип, ИмяЭлементаКоллекции, МассивФрагментов[Счетчик * 2 + 1]); КонецЦикла; //ИначеЕсли ТипЗнч(СтруктураТипа.Метаданные) = Тип("Соответствие") Тогда // Для Каждого ЭлементВида Из СтруктураТипа.Метаданные Цикл // КонкретныйТип = СтрЗаменить(КонкретныйТип, ЭлементВида.Ключ, ЭлементВида.Значение); // КонецЦикла; ИначеЕсли Истина И Подробное И (Ложь Или КонкретныйТип = "Массив" Или КонкретныйТип = "ФиксированныйМассив") И ТипЗнч(ОбъектМД) = Тип("ТаблицаЗначений") И СтруктураТипа.Метаданные.Количество() > 0 И СтруктураТипа.Метаданные.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено Тогда КонкретныйТип = КонкретныйТип + " Из " + ИмяТипаИзСтруктурыТипа(СтруктураТипа.Метаданные[0]); // Нужно для описания результата метода https://turboconf.ru/Tasks/9668 //ИначеЕсли Истина // И (Ложь // Или КонкретныйТип = "Структура" // Или КонкретныйТип = "ФиксированнаяСтруктура") // И ТипЗнч(ОбъектМД) = Тип("ТаблицаЗначений") // И СтруктураТипа.Метаданные.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено //Тогда // КонкретныйТип = КонкретныйТип + " Из КлючИЗначение"; // Нужно для описания результата метода https://turboconf.ru/Tasks/9668 ИначеЕсли Ложь Или КонкретныйТип = "НеизвестныйКонтекст" //Или КонкретныйТип = "Произвольный" // На него опирается подготовка ключевых параметров Тогда КонкретныйТип = "?"; КонецЕсли; Попытка Квалификаторы = СтруктураТипа.Квалификаторы; Исключение // Урезанная структура типа Квалификаторы = Неопределено; КонецПопытки; Если Истина И Подробное И Квалификаторы <> Неопределено И ирОбщий.ЛиИмяТипаСКвалификаторамиЛкс(КонкретныйТип) Тогда ирОбщий.ДобавитьКвалификаторыВПредставлениеТипаЛкс(КонкретныйТип, Тип(КонкретныйТип), Квалификаторы); КонецЕсли; Возврат КонкретныйТип; КонецФункции // Десериализатор структуры типа из неполной сериализации. // // Параметры: // СтрокаСтруктурыТипа - Строка. // // Возвращаемое значение: // СтруктураТипа - Структура. // Функция СтруктураТипаИзСтрокиВнутр(СтрокаСтруктурыТипа) Экспорт СтруктураТипа = НоваяСтруктураТипа(); Если ПустаяСтрока(СтрокаСтруктурыТипа) Тогда Возврат СтруктураТипа; КонецЕсли; Успех = Ложь; Попытка ОписательТипа = ЗначениеИзСтрокиВнутр(СтрокаСтруктурыТипа); Успех = Истина; Исключение ОписательТипа = НоваяСтруктураТипа(); ОписательТипа.ИмяОбщегоТипа = "<Ошибка преобразования>"; КонецПопытки; Если Успех Тогда СтруктураТипа.ИмяОбщегоТипа = ОписательТипа.ИмяОбщегоТипа; Если ТипЗнч(ОписательТипа.Метаданные) = Тип("Строка") Тогда СтруктураТипа.Метаданные = ирКэш.ОбъектМДПоПолномуИмениЛкс(ОписательТипа.Метаданные); ИначеЕсли ТипЗнч(ОписательТипа.Метаданные) = Тип("ХранилищеЗначения") Тогда Поток = Новый ЧтениеXML; Поток.УстановитьСтроку(ОписательТипа.Метаданные.Получить()); // Тут тормоз СтруктураТипа.Метаданные = СериализаторXDTO.ПрочитатьXML(Поток); Иначе СтруктураТипа.Метаданные = ОписательТипа.Метаданные; КонецЕсли; КонецЕсли; Возврат СтруктураТипа; КонецФункции // СтруктураТипаВСтрокуВнутр() // Получает новую структуру типа. // // Параметры: // ИмяОбщегоТипа - Строка - // // Возвращаемое значение: // Структура - : // *ИмяОбщегоТипа - Строка // *Метаданные // *СтрокаОписания - СтрокаТаблицыЗначений, Структура // *ТипЯзыка - Строка // *Конструктор - Булево - каретка находится в имени конструктора (например "Новый К<>") // *ДержательМетаданных - Произвольный - для объектов с модулем содержит имя расширения конфигурации, для элементов формы содержит форму // *ВиртуальнаяТаблица - Структура -: // **Выражение // **НомерСтроки // Функция НоваяСтруктураТипа(ИмяОбщегоТипа = "НеизвестныйКонтекст") Экспорт // Мультиметка73327878378078 Возврат Новый Структура("ИмяОбщегоТипа, Метаданные, СтрокаОписания, ТипЯзыка, Конструктор, ВиртуальнаяТаблица, ДержательМетаданных, Квалификаторы, МетаданныеСвойства", ИмяОбщегоТипа, Неопределено, Неопределено, "", Ложь, Новый Структура("Выражение, НомерСтроки", "", 0)); КонецФункции Функция НоваяТаблицаТипов() Экспорт Если мТаблицаТипов = Неопределено Тогда // Мультиметка73327878378078 мТаблицаТипов = Новый ТаблицаЗначений; мТаблицаТипов.Колонки.Добавить("ИмяОбщегоТипа", Новый ОписаниеТипов("Строка")); мТаблицаТипов.Колонки.Добавить("Метаданные"); мТаблицаТипов.Колонки.Добавить("СтрокаОписания"); // СтрокаТаблицыЗначений, Структура мТаблицаТипов.Колонки.Добавить("ТипЯзыка", Новый ОписаниеТипов("Строка")); мТаблицаТипов.Колонки.Добавить("ВиртуальнаяТаблица"); мТаблицаТипов.Колонки.Добавить("Конструктор", Новый ОписаниеТипов("Булево")); мТаблицаТипов.Колонки.Добавить("ДержательМетаданных"); мТаблицаТипов.Колонки.Добавить("Квалификаторы"); мТаблицаТипов.Колонки.Добавить("МетаданныеСвойства"); мТаблицаТипов.Колонки.Добавить("Детальность"); КонецЕсли; Возврат мТаблицаТипов.Скопировать(); КонецФункции // Добавляет структуру типа в таблицу структур типов с поглощением. // // Параметры: // ТаблицаПриемник - ТаблицаЗначений - ; // ОписаниеТипов - Структура, ТаблицаЗначений, ОписаниеТипов, Массив из Структура - считаем что внутри этой коллекции типы не пересекаются. // Функция ДобавитьВТаблицуТипов(ТаблицаПриемник = Неопределено, Знач ОписаниеТипов, Знач _ПередаватьДополнительныеТипы = Ложь, Знач ВытеснятьБезУчетаОписания = Истина, Знач КопироватьСтруктуры = Ложь, Знач ПереноситьОписание = Истина) Экспорт Если ТаблицаПриемник = Неопределено Тогда ТаблицаПриемник = НоваяТаблицаТипов(); КонецЕсли; Если ОписаниеТипов = Неопределено Тогда Возврат ТаблицаПриемник; КонецЕсли; ТипОписания = ТипЗнч(ОписаниеТипов); Если ТипОписания = Тип("ОписаниеТипов") Тогда //! ОписаниеТипов=0 // ОписаниеТипов ТаблицаИсточник = Новый Массив; Типы = ОписаниеТипов.Типы(); СлишкомМногоТипов = Типы.Количество() > МаксЧислоТиповДляАнализа(); Для Каждого Тип Из Типы Цикл СтруктураТипа = СтруктураТипаИзКонкретногоТипа(Тип); // Циклическая ссылка СтрокаОписания СтруктураТипа.Квалификаторы = ОписаниеТипов; СтруктураТипа.Вставить("Детальность"); ТаблицаИсточник.Добавить(СтруктураТипа); Если СлишкомМногоТипов И ТаблицаИсточник.Количество() = 10 Тогда Прервать; КонецЕсли; КонецЦикла; ИначеЕсли Истина И ТипОписания <> Тип("ТаблицаЗначений") И ТипОписания <> Тип("Массив") Тогда ТаблицаИсточник = Новый Массив; ТаблицаИсточник.Добавить(ОписаниеТипов); Иначе ТаблицаИсточник = ОписаниеТипов; // см. НоваяТаблицаТипов() Если Истина И ТипОписания = Тип("ТаблицаЗначений") И ТаблицаИсточник.Колонки.Метаданные.Заголовок <> "" Тогда ТаблицаПриемник.Колонки.Метаданные.Заголовок = ТаблицаИсточник.Колонки.Метаданные.Заголовок; // Флаги КонецЕсли; КонецЕсли; КоличествоТипов = ТаблицаИсточник.Количество(); Если КоличествоТипов > МаксЧислоТиповДляАнализа() Тогда // Для подстраховки. Нужно в вызывающем контексте это контролировать Возврат ТаблицаПриемник; КонецЕсли; НужноВытеснять = КоличествоТипов > 0 И ТаблицаПриемник.Количество() > 0; Детальность = Неопределено; ИсключаемыеСвойства = ""; //Если Не _ПередаватьДополнительныеТипы Тогда // ИсключаемыеСвойства = ИсключаемыеСвойства + ",ДополнительныеТипы"; //КонецЕсли; Если Не ПереноситьОписание Тогда ИсключаемыеСвойства = ИсключаемыеСвойства + ",СтрокаОписания"; СтрокаОписания = Неопределено; Если НужноВытеснять Тогда СтрокаОписания = ТаблицаПриемник[0].СтрокаОписания; КонецЕсли; КонецЕсли; ИсключаемыеСвойства = Сред(ИсключаемыеСвойства, 2); Если ВытеснятьБезУчетаОписания Тогда ИменаПоиска = "ИмяОбщегоТипа"; Иначе ИменаПоиска = "ИмяОбщегоТипа,СтрокаОписания"; КонецЕсли; Для Каждого СтрокаИсточника Из ТаблицаИсточник Цикл Если Истина //И НужноВытеснять И СтрокаИсточника.ИмяОбщегоТипа = "НеизвестныйКонтекст" И СтрокаИсточника.СтрокаОписания = Неопределено Тогда Продолжить; КонецЕсли; Если Истина И ТипЗнч(СтрокаИсточника) = Тип("Структура") И Не СтрокаИсточника.Свойство("Детальность", Детальность) Тогда СтрокаИсточника.Вставить("Детальность", Неопределено); Иначе Детальность = СтрокаИсточника.Детальность; КонецЕсли; Если Детальность = Неопределено Тогда ОбновитьДетальностьСтруктурыТипа(СтрокаИсточника); КонецЕсли; Если НужноВытеснять Тогда Если Найти(СтрокаИсточника.ИмяОбщегоТипа, "Массив") = 1 Тогда ДобавлятьТип = Истина; Для Каждого СтрокаПриемника Из ТаблицаПриемник Цикл Если Найти(СтрокаПриемника.ИмяОбщегоТипа, "Массив") = 1 Тогда Если Истина И СтрокаИсточника.Метаданные = Неопределено И СтрокаПриемника.Метаданные = Неопределено Тогда // Иначе ТипыЭлементовИсточника = ТаблицаТиповЭлементовКоллекции(СтрокаИсточника); ТипыЭлементовПриемника = ТаблицаТиповЭлементовКоллекции(СтрокаПриемника); СтрокаПриемника.Метаданные = ДобавитьВТаблицуТипов(ТипыЭлементовПриемника, ТипыЭлементовИсточника); Если СтрокаПриемника.Метаданные.Количество() = 0 Тогда СтрокаПриемника.Метаданные = Неопределено; КонецЕсли; КонецЕсли; ДобавлятьТип = Ложь; СтрокаПриемника.Детальность = Макс(СтрокаИсточника.Детальность, СтрокаПриемника.Детальность); Прервать; КонецЕсли; КонецЦикла; Если Не ДобавлятьТип Тогда Прервать; КонецЕсли; Иначе КлючПоиска = Новый Структура(ИменаПоиска); ЗаполнитьЗначенияСвойств(КлючПоиска, СтрокаИсточника); Найденные = ТаблицаПриемник.НайтиСтроки(КлючПоиска); Если СтрокаИсточника.Детальность > 0 Тогда Для Каждого СтрокаПриемника Из ТаблицаПриемник.НайтиСтроки(Новый Структура("Детальность", 0)) Цикл ТаблицаПриемник.Удалить(СтрокаПриемника); КонецЦикла; Если ирОбщий.СтрНачинаетсяСЛкс(СтрокаИсточника.ИмяОбщегоТипа, "РасширениеФормы", Истина) Тогда // Учитывам регистр для ускорения НайденныеФормы = ТаблицаПриемник.НайтиСтроки(Новый Структура("ИмяОбщегоТипа", "Форма")); ирОбщий.ДополнитьМассивЛкс(Найденные, НайденныеФормы); КонецЕсли; КонецЕсли; Для Каждого НайденнаяСтрока Из Найденные Цикл Если СлитьМетаданныеСтруктурТипов(ТаблицаПриемник, СтрокаИсточника, НайденнаяСтрока) Тогда Перейти ~КонецВерхний; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; ТипМетаданных = ТипЗнч(СтрокаИсточника.Метаданные); Если ТипМетаданных = Тип("COMОбъект") Тогда // Мультметка8530527831 Их таблицы слов кэшируются https://www.hostedredmine.com/issues/986088 СтрокаПриемника = ТаблицаПриемник.Вставить(0); Иначе СтрокаПриемника = ТаблицаПриемник.Добавить(); КонецЕсли; ЗаполнитьЗначенияСвойств(СтрокаПриемника, СтрокаИсточника, , ИсключаемыеСвойства); Если Истина И КопироватьСтруктуры И ТипЗнч(СтрокаИсточника.Метаданные) = Тип("Структура") Тогда СтрокаПриемника.Метаданные = ирОбщий.СкопироватьКоллекциюЛкс(СтрокаПриемника.Метаданные); КонецЕсли; Если Не ПереноситьОписание Тогда СтрокаПриемника.СтрокаОписания = СтрокаОписания; КонецЕсли; ~КонецВерхний: КонецЦикла; Возврат ТаблицаПриемник; КонецФункции // . // // Параметры: // ТаблицаТиповПриемник - ТаблицаЗначений - ; // СтрокаИсточника - СтрокаТаблицыЗначений - // СтрокаПриемника - СтрокаТаблицыЗначений - // // Возвращаемое значение: // Булеов - Истина, если слияние выполнено в строку приемника и добавлять строку в таблицу приемника не нужно // Функция СлитьМетаданныеСтруктурТипов(Знач ТаблицаТиповПриемник, Знач СтрокаИсточника, Знач СтрокаПриемника) Экспорт ТипМетаданныхИсточника = ТипЗнч(СтрокаИсточника.Метаданные); ТипМетаданныхПриемника = ТипЗнч(СтрокаПриемника.Метаданные); Если Истина И СтрокаИсточника.СтрокаОписания <> Неопределено И СтрокаПриемника.СтрокаОписания = Неопределено Тогда СтрокаПриемника.СтрокаОписания = СтрокаИсточника.СтрокаОписания; КонецЕсли; Если Ложь Или СтрокаПриемника.Метаданные = СтрокаИсточника.Метаданные Или СтрокаПриемника.Детальность > СтрокаИсточника.Детальность Тогда Возврат Истина; КонецЕсли; Если СтрокаПриемника.Детальность < СтрокаИсточника.Детальность Тогда ТаблицаТиповПриемник.Удалить(СтрокаПриемника); Иначе // Далее детальности равны Если Ложь Или ТаблицаТиповПриемник.Количество() > 10 Или СтрокаПриемника.ИмяОбщегоТипа = "Строка" // Для ускорения вычисления типа результата ИмяМодуляИзСтруктурыТипа() Или СтрокаПриемника.ИмяОбщегоТипа = "Число" Или СтрокаПриемника.ИмяОбщегоТипа = "Булево" Или СтрокаПриемника.ИмяОбщегоТипа = "Тип" Тогда Возврат Истина; КонецЕсли; ИмяКолонкиФлагаТаблицыТипов = ИмяКолонкиФлагаТаблицыТипов(); Если Ложь Или (Истина И ТипМетаданныхИсточника = Тип("ТаблицаЗначений") И ТипМетаданныхПриемника = Тип("ТаблицаЗначений")) Или (Истина И ТипМетаданныхИсточника = Тип("ДеревоЗначений") И ТипМетаданныхПриемника = Тип("ДеревоЗначений")) Тогда ирОбщий.СкопироватьКолонкиКоллекцииЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные); Возврат Истина; ИначеЕсли Истина И ТипМетаданныхПриемника = Тип("Неопределено") И ТипМетаданныхИсточника = Тип("Структура") Тогда СтрокаПриемника.Метаданные = ирОбщий.СкопироватьКоллекциюЛкс(СтрокаИсточника.Метаданные); Возврат Истина; ИначеЕсли Истина И ТипМетаданныхИсточника = Тип("Неопределено") //И ТипМетаданныхПриемника = Тип("Структура") Тогда Возврат Истина; ИначеЕсли Истина И ТипМетаданныхИсточника = Тип("Структура") И ТипМетаданныхПриемника = Тип("Структура") Тогда Для Каждого КлючИЗначение Из СтрокаИсточника.Метаданные Цикл ЗначениеИзПриемника = ирОбщий.СвойствоСтруктурыЛкс(СтрокаПриемника.Метаданные, КлючИЗначение.Ключ); Если Истина И ТипЗнч(ЗначениеИзПриемника) = Тип("ТаблицаЗначений") И ЗначениеИзПриемника.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено И ТипЗнч(КлючИЗначение.Значение) = Тип("ТаблицаЗначений") И КлючИЗначение.Значение.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) <> Неопределено Тогда ДобавитьВТаблицуТипов(ЗначениеИзПриемника, КлючИЗначение.Значение); Продолжить; КонецЕсли; //Если ЗначениеИзПриемника = Неопределено Тогда Если Не ЗначениеЗаполнено(ЗначениеИзПриемника) Тогда // Чтобы пустая структура заменялась на полную для результата НоваяСтруктураТипа СтрокаПриемника.Метаданные.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЕсли; КонецЦикла; Возврат Истина; ИначеЕсли Истина И ТипМетаданныхИсточника = Тип("Массив") И ТипМетаданныхПриемника = Тип("Массив") Тогда ирОбщий.СкопироватьКоллекциюЛкс(СтрокаИсточника.Метаданные, СтрокаПриемника.Метаданные); Возврат Истина; Иначе СтруктураПриемник = Неопределено; Если Истина И ТипМетаданныхИсточника = Тип("ТаблицаЗначений") И ТипМетаданныхПриемника = Тип("Структура") Тогда ТаблицаИсточник = СтрокаИсточника.Метаданные; СтруктураПриемник = СтрокаПриемника.Метаданные; ИначеЕсли Истина И ТипМетаданныхИсточника = Тип("Структура") И ТипМетаданныхПриемника = Тип("ТаблицаЗначений") Тогда ТаблицаИсточник = СтрокаПриемника.Метаданные; СтруктураПриемник = СтрокаИсточника.Метаданные; КонецЕсли; Если Истина И СтруктураПриемник <> Неопределено И ТаблицаИсточник.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов) = Неопределено Тогда Для Каждого Колонка Из ТаблицаИсточник.Колонки Цикл Если Истина И ЗначениеЗаполнено(Колонка.Имя) И ирОбщий.СвойствоСтруктурыЛкс(СтруктураПриемник, Колонка.Имя) = Неопределено Тогда ТаблицаТиповКолонки = ТаблицаТиповИзОписанияТипов(Колонка.ТипЗначения); Если ТаблицаТиповКолонки.Количество() = 0 Тогда ТаблицаТиповКолонки = Неопределено; КонецЕсли; СтруктураПриемник.Вставить(Колонка.Имя, ТаблицаТиповКолонки); КонецЕсли; КонецЦикла; СтрокаПриемника.Метаданные = СтруктураПриемник; Возврат Истина; КонецЕсли; КонецЕсли; КонецЕсли; Возврат Ложь; КонецФункции Функция ОбновитьДетальностьСтруктурыТипа(СтруктураТипа) Экспорт ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); ИмяОбщегоТипа = СтруктураТипа.ИмяОбщегоТипа; Если Ложь Или ИмяОбщегоТипа = "??" Или ИмяОбщегоТипа = "НеизвестныйКонтекст" Тогда Результат = 0; ИначеЕсли Ложь Или ИмяОбщегоТипа = "" // Процедура Или ИмяОбщегоТипа = "Произвольный" Или ИмяОбщегоТипа = "Неопределено" Тогда Результат = 1; // Отключил из-за Мультиметка29332671 //Если ИмяОбщегоТипа = "Неопределено" Тогда // СтруктураТипа.Метаданные = Неопределено; // Чтобы раньше склеивались типы в ДобавитьВТаблицуТипов //КонецЕсли; ИначеЕсли Ложь Или ИмяОбщегоТипа = "Строка" Или ИмяОбщегоТипа = "Число" Или ИмяОбщегоТипа = "Булево" Или ИмяОбщегоТипа = "Дата" Или ИмяОбщегоТипа = "Null" Или ИмяОбщегоТипа = "Тип" //Или ИмяОбщегоТипа = "Примитивный" Тогда Если ТипМетаданных = Тип(ИмяОбщегоТипа) Тогда Результат = 3; Иначе Результат = 2; Если Истина И ИмяОбщегоТипа = "Строка" И ТипМетаданных = Тип("ТаблицаЗначений") Тогда Результат = 5; КонецЕсли; КонецЕсли; ИначеЕсли Ложь Или ТипМетаданных = Тип("Неопределено") Или ТипМетаданных = Тип("КоллекцияОбъектовМетаданных") Или ТипМетаданных = Тип("ОбщийМодуль") // Пока платформа не позволяет узнать его имя Тогда Результат = 3; ИначеЕсли ТипМетаданных = Тип("ОбъектМетаданных") Тогда Результат = 4; ИначеЕсли Истина И ТипМетаданных = Тип("ТаблицаЗначений") И СтруктураТипа.Метаданные.Количество() > 0 И СтруктураТипа.Метаданные.Колонки.Найти(ИмяКолонкиФлагаТаблицыТипов()) <> Неопределено Тогда //! СтруктураТипа.Метаданные = 0 // ТаблицаЗначений Результат = Макс(3, СтруктураТипа.Метаданные[0].Детальность); ИначеЕсли Ложь #Если Клиент Тогда Или ТипМетаданных = Тип("Форма") Или ТипМетаданных = Тип("УправляемаяФорма") #КонецЕсли Тогда Результат = 6; ИначеЕсли ТипМетаданных = Тип("ПостроительЗапроса") Тогда Результат = 7; Иначе Результат = 5; КонецЕсли; СтруктураТипа.Детальность = Результат; Возврат Результат; КонецФункции //. // Параметры: // ТаблицаТипов - ТаблицаЗначений - // МинДетальность - Число - минимальное достаточное значение детальности // Возвращаемое значение: // Булево - Функция ЛиДетальностьТиповДостаточна(ТаблицаТипов, Знач МинДетальность = 3, Знач ВыбратьЛучшийТип = Ложь, выхЛучшийТип = Неопределено, Знач УчитыватьПримитивные = Истина) Экспорт Если Ложь Или ТаблицаТипов = Неопределено Или ТаблицаТипов.Количество() = 0 Тогда Возврат Ложь; КонецЕсли; Счетчик = 1; МинДетальность = МинДетальность - 1; Для Индекс = 1 - ТаблицаТипов.Количество() По 0 Цикл // Обратный обход СтрокаТипа = ТаблицаТипов[-Индекс]; Успех = Ложь; СтрокаВложенногоТипа = СтрокаТипа; Если СтрокаТипа.Детальность > МинДетальность Тогда Успех = Истина; ИначеЕсли Истина И СтрокаТипа.ИмяОбщегоТипа = "Массив" И ТипЗнч(СтрокаТипа.Метаданные) = Тип("ТаблицаЗначений") И СтрокаТипа.Метаданные.Количество() Тогда СтрокаВложенногоТипа = СтрокаТипа.Метаданные[0]; Если СтрокаВложенногоТипа.Детальность > МинДетальность Тогда Успех = Истина; КонецЕсли; КонецЕсли; Если Ложь Или Успех Или (Истина И УчитыватьПримитивные И (Ложь Или СтрокаВложенногоТипа.ИмяОбщегоТипа = "Строка" Или СтрокаВложенногоТипа.ИмяОбщегоТипа = "Число" Или СтрокаВложенногоТипа.ИмяОбщегоТипа = "Булево" // почему закомментировал? )) Тогда выхЛучшийТип = СтрокаТипа; МинДетальность = СтрокаТипа.Детальность; Если Не ВыбратьЛучшийТип Тогда Прервать; КонецЕсли; КонецЕсли; Если Счетчик = 3 Тогда // Проверяем не больше 3-х, т.к. бесполезных типов обычно очень мало указывают в описании, например Неопределено, Null Прервать; КонецЕсли; Счетчик = Счетчик + 1; КонецЦикла; Возврат выхЛучшийТип <> Неопределено; КонецФункции // Получает массив структур типов из строки допустимых типов. // // Параметры: // ДопустимыеТипы - Строка; // *ШаблонСтруктурыТипа - Структура, *Неопределено - содержит значения по умолчанию для новой структуры типа. // Функция ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы, ШаблонСтруктурыТипа = Неопределено) Экспорт ТаблицаТипов = НоваяТаблицаТипов(); Если ПустаяСтрока(ДопустимыеТипы) Тогда Возврат ТаблицаТипов; КонецЕсли; МассивСериализованныхТипов = ирОбщий.СтрРазделитьЛкс(ДопустимыеТипы, ";"); Для Каждого СериализованныйТип Из МассивСериализованныхТипов Цикл СтруктураТипа = СтруктураТипаИзСтрокиВнутр(СериализованныйТип); Если ШаблонСтруктурыТипа <> Неопределено Тогда ЗаполнитьЗначенияСвойств(СтруктураТипа, ШаблонСтруктурыТипа); КонецЕсли; ДобавитьВТаблицуТипов(ТаблицаТипов, СтруктураТипа); КонецЦикла; Возврат ТаблицаТипов; КонецФункции // Получает описание типов из допустимых типов. // // Параметры: // ДопустимыеТипы - Строка; // ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления. // // Возвращаемое значение: // ОписаниеТипов. // Функция ОписаниеТиповИзДопустимыхТипов(ДопустимыеТипы, ТипЗначенияЭУ = Неопределено) Экспорт ТаблицаТипов = ТаблицаТиповИзДопустимыхТипов(ДопустимыеТипы); ОписаниеТипов = ОписаниеТиповИзТаблицыТипов(ТаблицаТипов, ТипЗначенияЭУ); Возврат ОписаниеТипов; КонецФункции // Получает описание типов из таблицы структур типов. // // Параметры: // ДопустимыеТипы - Строка; // ТипЗначенияЭУ - ОписаниеТипов - все возможные типы из элемента управления. // // Возвращаемое значение: // ОписаниеТипов. // Функция ОписаниеТиповИзТаблицыТипов(ТаблицаТипов, ТипЗначенияЭУ = Неопределено) Экспорт Если ТаблицаТипов = Неопределено Тогда Возврат Новый ОписаниеТипов; КонецЕсли; МассивТипов = Новый Массив; Для Каждого СтруктураТипа Из ТаблицаТипов Цикл СтрокаКонкретногоТипа = ИмяТипаИзСтруктурыТипа(СтруктураТипа, Ложь); Попытка ТекущийТип = Тип(СтрокаКонкретногоТипа); Исключение Продолжить; КонецПопытки; ТипМетаданных = ТипЗнч(СтруктураТипа.Метаданные); Если ТипМетаданных = Тип("КвалификаторыСтроки") Тогда КвалификаторыСтроки = СтруктураТипа.Метаданные; ИначеЕсли ТипМетаданных = Тип("КвалификаторыЧисла") Тогда КвалификаторыЧисла = СтруктураТипа.Метаданные; ИначеЕсли ТипМетаданных = Тип("КвалификаторыДаты") Тогда КвалификаторыДаты = СтруктураТипа.Метаданные; КонецЕсли; Если ТипЗначенияЭУ <> Неопределено Тогда Если Не ТипЗначенияЭУ.СодержитТип(ТекущийТип) Тогда Продолжить; КонецЕсли; КонецЕсли; МассивТипов.Добавить(ТекущийТип); КонецЦикла; ОписаниеТипов = Новый ОписаниеТипов(МассивТипов, КвалификаторыЧисла, КвалификаторыСтроки, КвалификаторыСтроки); Возврат ОписаниеТипов; КонецФункции // Получает строку типа метаобъектов по единственному или множественному числу. // // Параметры: // *Единственное - Строка, *Неопределено - единственное число типа; // *Множественное - Строка, *Неопределено - множественное число типа. // *Категория - Число, *Неопределено. // // Возвращаемое значение: // СтрокаТаблицыЗначений - найденная строка типа; // Неопределено - корневой тип не найден. // Функция ОписаниеТипаМетаОбъектов(Знач Единственное = Неопределено, Знач Множественное = Неопределено, Категория = Неопределено) Экспорт СтруктураПоиска = Новый Структура; Если Категория <> Неопределено Тогда СтруктураПоиска.Вставить("Категория", Категория); КонецЕсли; Если Единственное <> Неопределено Тогда СтруктураПоиска.Вставить("НЕдинственное", НРег(Единственное)); КонецЕсли; Если Множественное <> Неопределено Тогда СтруктураПоиска.Вставить("НМножественное", НРег(Множественное)); КонецЕсли; НайденныеСтроки = ТаблицаТиповМетаОбъектов.НайтиСтроки(СтруктураПоиска); Если НайденныеСтроки.Количество() = 0 Тогда Результат = Неопределено; Иначе Результат = НайденныеСтроки[0]; КонецЕсли; Возврат Результат; КонецФункции Процедура ПроверитьЗагрузитьКэшМДСеанса() ПереданныйКэш = ирКэш.ПараметрыСеансаЛкс().ПереданныйКэш; КэшМДСеанса = Неопределено; Если ЗначениеЗаполнено(ПереданныйКэш) Тогда КэшМДСеанса = ПолучитьИзВременногоХранилища(ПереданныйКэш); КонецЕсли; Если КэшМДСеанса = Неопределено Тогда СостояниеРасчета = ирКэш.СостояниеПодготовкиКэшМДСеансаЛкс(); Если СостояниеРасчета <> Неопределено Тогда ФоновоеЗадание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(СостояниеРасчета.ИдентификаторЗадания); КонецЕсли; Если ФоновоеЗадание <> Неопределено Тогда Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Активно Тогда ирОбщий.ОжидатьЗавершенияФоновойОперацииЛкс(ФоновоеЗадание); КонецЕсли; Если ФоновоеЗадание.Состояние = СостояниеФоновогоЗадания.Завершено Тогда КэшМДСеанса = ирОбщий.ПрочитатьРезультатФоновогоЗаданияЛкс(СостояниеРасчета.АдресРезультата, СостояниеРасчета.ФормаРезультата); Если КэшМДСеанса = Null Тогда КэшМДСеанса = Неопределено; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если КэшМДСеанса <> Неопределено Тогда #Если Сервер И Не Сервер Тогда КэшМДСеанса = Новый Структура; #КонецЕсли мТаблицаВсехТаблицБД = КэшМДСеанса.ТаблицаВсехТаблицБД; Если КэшМДСеанса.Свойство("ДеревоОбъектовМД") Тогда мДеревоОбъектовМД = КэшМДСеанса.ДеревоОбъектовМД; КонецЕсли; Возврат; КонецЕсли; КонецПроцедуры Функция ДеревоОбъектовМД() Экспорт ПроверитьЗагрузитьКэшМДСеанса(); Если мДеревоОбъектовМД <> Неопределено Тогда #Если Сервер И Не Сервер Тогда мДеревоОбъектовМД = Новый ДеревоЗначений; #КонецЕсли #Если Клиент Тогда Если мДеревоОбъектовМД.Колонки.Найти("КоличествоСтрок") = Неопределено Тогда мДеревоОбъектовМД.Колонки.Добавить("КоличествоСтрок", Новый ОписаниеТипов("Строка, Число")); КонецЕсли; #КонецЕсли Возврат мДеревоОбъектовМД; КонецЕсли; ДеревоОбъектовМД = Новый ДеревоЗначений; ДеревоОбъектовМД.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка")); ДеревоОбъектовМД.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка")); ДеревоОбъектовМД.Колонки.Добавить("ПолноеИмяОбъекта", Новый ОписаниеТипов("Строка")); ДеревоОбъектовМД.Колонки.Добавить("ИндексКартинки", Новый ОписаниеТипов("Число")); ДеревоОбъектовМД.Колонки.Добавить("ЕстьДоступ", Новый ОписаниеТипов("Булево")); ДеревоОбъектовМД.Колонки.Добавить("ПравоПросмотр", Новый ОписаниеТипов("Булево")); ДеревоОбъектовМД.Колонки.Добавить("ТипТаблицы", Новый ОписаниеТипов("Строка")); АнализаторКода = ирОбщий.НовыйАнализаторКодаЛкс(); #Если Сервер И Не Сервер Тогда АнализаторКода = Обработки.ирКлсПолеТекстаПрограммы.Создать(); #КонецЕсли мТаблицаВсехТаблицБД = АнализаторКода.ДоступныеТаблицы.ВыгрузитьКолонки(); мТаблицаВсехТаблицБД.Колонки.Удалить("ПородившийЗапрос"); // Для экономии памяти мТаблицаВсехТаблицБД.Колонки.Добавить("ТипСсылки"); //ТаблицаВсехТаблицБД.Колонки.Добавить("СтруктураКлюча"); Если Метаданные.Константы.Количество() > 0 Тогда ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ирОбщий.ПеревестиСтроку("Константы"),, "Константы"); // Мультиметка0012741388 опираемся на то, что эта таблица БД идет первой в списке КонецЕсли; КоллекцияКорневыхТипов = Новый Массив; СтрокиМетаОбъектов = ТаблицаТиповМетаОбъектов.НайтиСтроки(Новый Структура("Категория", 0)); Для Каждого СтрокаТаблицыМетаОбъектов Из СтрокиМетаОбъектов Цикл КоллекцияКорневыхТипов.Добавить(СтрокаТаблицыМетаОбъектов.Единственное); КонецЦикла; Если ирКэш.ДоступноВнешниеИсточникДанныхЛкс() Тогда Для Каждого МетаВнешнийИсточникДанных Из Метаданные.ВнешниеИсточникиДанных Цикл КоллекцияКорневыхТипов.Добавить(МетаВнешнийИсточникДанных.ПолноеИмя()); КонецЦикла; КонецЕсли; КоллекцияКорневыхТипов.Добавить("Отчет"); КоллекцияКорневыхТипов.Добавить("Обработка"); КоллекцияКорневыхТипов.Добавить("Роль"); КоллекцияКорневыхТипов.Добавить("Подсистема"); КоллекцияКорневыхТипов.Добавить("РегламентноеЗадание"); КоллекцияКорневыхТипов.Добавить("HTTPСервис"); КоллекцияКорневыхТипов.Добавить("WebСервис"); КоллекцияКорневыхТипов.Добавить("ОбщаяКоманда"); ИмяДвиженияССубконто = ирОбщий.ПеревестиСтроку("ДвиженияССубконто"); ИмяГраницы = ирОбщий.ПеревестиСтроку("Границы"); ИмяБаза = ирОбщий.ПеревестиСтроку("База"); ИмяДанныеГрафика = ирОбщий.ПеревестиСтроку("ДанныеГрафика"); ИмяФактическийПериодДействия = ирОбщий.ПеревестиСтроку("ФактическийПериодДействия"); ИмяЗадачиПоИсполнителю = ирОбщий.ПеревестиСтроку("ЗадачиПоИсполнителю"); ИмяКонстанта = ирОбщий.ПеревестиСтроку("Константа"); ИмяОбороты = ирОбщий.ПеревестиСтроку("Обороты"); ИмяОборотыДтКт = ирОбщий.ПеревестиСтроку("ОборотыДтКт"); ИмяОстатки = ирОбщий.ПеревестиСтроку("Остатки"); ИмяОстаткиИОбороты = ирОбщий.ПеревестиСтроку("ОстаткиИОбороты"); ИмяСрезПервых = ирОбщий.ПеревестиСтроку("СрезПервых"); ИмяСрезПоследних = ирОбщий.ПеревестиСтроку("СрезПоследних"); ИмяСубконто = ирОбщий.ПеревестиСтроку("Субконто"); ИмяТабличнаяЧасть = ирОбщий.ПеревестиСтроку("ТабличнаяЧасть"); ИмяТочки = ирОбщий.ПеревестиСтроку("Точки"); ИндексКартинкиТЧ = мОписаниеТипаМДТабличнаяЧасть.ИндексКартинкиЕдинственное; ИндикаторТиповМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияКорневыхТипов.Количество(), "Анализ конфигурации"); Для Каждого КорневойТип Из КоллекцияКорневыхТипов Цикл ирОбщий.ОбработатьИндикаторЛкс(ИндикаторТиповМД); ОписаниеКорневогоТипа = ОписаниеТипаМетаОбъектов(КорневойТип); Если ОписаниеКорневогоТипа = Неопределено Тогда Если Найти(КорневойТип, ".") = 0 Тогда // В текущей версии платформы нет поддержки такого типа метаданных Продолжить; КонецЕсли; // Внешний источник данных ОписаниеКорневогоТипа = мОписаниеТипаМДВнешнийИсточникДанных; ОбъектМДКорневогоТипа = ирКэш.ОбъектМДПоПолномуИмениЛкс(КорневойТип); МножественноеКорневогоТипа = КорневойТип; ЕдинственноеКорневогоТипа = ОбъектМДКорневогоТипа.Имя; ПредставлениеКатегории = ОбъектМДКорневогоТипа.Представление(); ЕстьДоступ = ПравоДоступа("Использование", ОбъектМДКорневогоТипа); СхемаТаблиц = ОбъектМДКорневогоТипа.Имя; ТипТаблицы = "Внешняя"; КоллекцияМетаОбъектов = ОбъектМДКорневогоТипа.Таблицы; ЕстьТаблицаБД = Истина; Иначе МножественноеКорневогоТипа = ОписаниеКорневогоТипа.Множественное; ЕдинственноеКорневогоТипа = ОписаниеКорневогоТипа.Единственное; ПредставлениеКатегории = ирОбщий.ПредставлениеИзИдентификатораЛкс(МножественноеКорневогоТипа); ЕстьДоступ = Истина; СхемаТаблиц = ""; //Если КорневойТип = "КритерийОтбора" Тогда // ТипТаблицы = "ВиртуальнаяТаблица"; //Иначе ТипТаблицы = КорневойТип; //КонецЕсли; Если КорневойТип = "Перерасчет" Тогда КоллекцияМетаОбъектов = Новый Массив; Для Каждого МетаРегистрРасчета Из Метаданные.РегистрыРасчета Цикл Для Каждого Перерасчет Из МетаРегистрРасчета.Перерасчеты Цикл КоллекцияМетаОбъектов.Добавить(Перерасчет); КонецЦикла; КонецЦикла; Иначе КоллекцияМетаОбъектов = Метаданные[МножественноеКорневогоТипа]; // КоллекцияОбъектовМетаданных КонецЕсли; ЕстьТаблицаБД = Истина И (Ложь Или КорневойТип <> "Константа" Или ирКэш.ДоступноТаблицыКонстантЛкс()) И (Ложь Или КорневойТип = "Константа" Или КорневойТип = "КритерийОтбора" Или КорневойТип = "ЖурналДокументов" Или ирОбщий.ЛиКорневойТипПеречисленияЛкс(КорневойТип) Или ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип) Или ирОбщий.ЛиКорневойТипРегистраБДЛкс(КорневойТип) Или ирОбщий.ЛиКорневойТипПоследовательностиЛкс(КорневойТип)); КонецЕсли; Если КоллекцияМетаОбъектов.Количество() = 0 Тогда Продолжить; КонецЕсли; СтрокаТипаМетаданных = ДеревоОбъектовМД.Строки.Добавить(); СтрокаТипаМетаданных.Представление = ПредставлениеКатегории; СтрокаТипаМетаданных.Имя = ЕдинственноеКорневогоТипа; СтрокаТипаМетаданных.ПолноеИмяОбъекта = МножественноеКорневогоТипа; СтрокаТипаМетаданных.ИндексКартинки = ОписаниеКорневогоТипа.ИндексКартинкиМножественное; СтрокаТипаМетаданных.ЕстьДоступ = ЕстьДоступ; ЛиКорневойТипОбъектаСТабличнымиЧастями = ирОбщий.ЛиКорневойТипСсылочногоОбъектаБДЛкс(КорневойТип); ИндикаторОбъектовМД = ирОбщий.ПолучитьИндикаторПроцессаЛкс(КоллекцияМетаОбъектов.Количество(), "Анализ " + КорневойТип); Для Каждого ОбъектМД Из КоллекцияМетаОбъектов Цикл ирОбщий.ОбработатьИндикаторЛкс(ИндикаторОбъектовМД); ПолноеИмяМД = ОбъектМД.ПолноеИмя(); ПредставлениеМД = ОбъектМД.Представление(); ПолноеИмяТаблицыБД = ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД,, Ложь); ФрагментыИмениТаблицы = ирОбщий.СтрРазделитьЛкс(ПолноеИмяТаблицыБД); ИмяОбъектаМД = ОбъектМД.Имя; Если КорневойТип = "Перерасчет" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхПерерасчет МетаРегистрРасчета = ОбъектМД.Родитель(); // ОбъектМетаданныхРегистрРасчета ИмяОбъектаМД = МетаРегистрРасчета.Имя + "." + ИмяОбъектаМД; ПредставлениеМД = МетаРегистрРасчета.Представление() + "." + ПредставлениеМД; КонецЕсли; СтрокаОбъектаМД = ДобавитьСтрокуДереваМД(СтрокаТипаМетаданных, ПолноеИмяТаблицыБД, ИмяОбъектаМД, ПредставлениеМД, ТипТаблицы, ОписаниеКорневогоТипа.ИндексКартинкиЕдинственное, ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД, ОбъектМД.Имя, ПредставлениеМД, СхемаТаблиц, ОбъектМД,, ФрагментыИмениТаблицы); Попытка СтрокаОбъектаМД.ПравоПросмотр = ПравоДоступа("Просмотр", ОбъектМД); Исключение СтрокаОбъектаМД.ПравоПросмотр = Истина; КонецПопытки; Если ЛиКорневойТипОбъектаСТабличнымиЧастями Тогда СтруктураТЧ = ирОбщий.ТабличныеЧастиОбъектаЛкс(ОбъектМД, ФрагментыИмениТаблицы); Для Каждого КлючИЗначение Из СтруктураТЧ Цикл СтрокаТЧВДереве = ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + КлючИЗначение.Ключ, КлючИЗначение.Ключ, КлючИЗначение.Значение, "ТабличнаяЧасть", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД, ПолноеИмяМД + "." + ИмяТабличнаяЧасть + "." + КлючИЗначение.Ключ,, ПредставлениеМД + "." + КлючИЗначение.Значение,, ОбъектМД); МетаТЧ = ОбъектМД.ТабличныеЧасти.Найти(КлючИЗначение.Ключ); Если МетаТЧ <> Неопределено Тогда СтрокаТЧВДереве.ПравоПросмотр = ПравоДоступа("Просмотр", МетаТЧ); КонецЕсли; КонецЦикла; Если КорневойТип = "БизнесПроцесс" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхБизнесПроцесс ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяТочки, "Точки", "Точки", "Точки", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Точки",, ОбъектМД); КонецЕсли; Если КорневойТип = "Задача" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхЗадача Если ОбъектМД.Адресация <> Неопределено Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяЗадачиПоИсполнителю, "ЗадачиПоИсполнителю", "Задачи по исполнителю", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Задачи по исполнителю",, ОбъектМД, 1); КонецЕсли; КонецЕсли; КонецЕсли; Если КорневойТип = "РегистрСведений" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхРегистрСведений Если ОбъектМД.ПериодичностьРегистраСведений <> Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПоследних, "СрезПоследних", "срез последних", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез последних",, ОбъектМД, 1); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСрезПервых, "СрезПервых", "срез первых", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Срез первых",, ОбъектМД, 1); КонецЕсли; ИначеЕсли КорневойТип = "РегистрНакопления" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхРегистрНакопления ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 3); Если ОбъектМД.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 1); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 4); КонецЕсли; ИначеЕсли КорневойТип = "РегистрБухгалтерии" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхРегистрБухгалтерии ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОбороты, "Обороты", "Обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты",, ОбъектМД, 5); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстатки, "Остатки", "Остатки", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки",, ОбъектМД, 3); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОстаткиИОбороты, "ОстаткиИОбороты", "Остатки и обороты", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Остатки и обороты",, ОбъектМД, 6); ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДвиженияССубконто, "ДвиженияССубконто", "Движения с субконто", "ДвиженияССубконто", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Движения с субконто",, ОбъектМД, 2); Если ОбъектМД.ПланСчетов.МаксКоличествоСубконто > 0 Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяСубконто, "Субконто", "Субконто", "Субконто", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Субконто",, ОбъектМД); КонецЕсли; Если ОбъектМД.Корреспонденция Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяОборотыДтКт, "ОборотыДтКт", "Обороты Дт Кт", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Обороты Дт Кт",, ОбъектМД, 7); КонецЕсли; ИначеЕсли КорневойТип = "Последовательность" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхПоследовательность ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяГраницы, "Границы", "Границы", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Границы",, ОбъектМД); ИначеЕсли КорневойТип = "РегистрРасчета" Тогда //! ОбъектМД = 0 // ОбъектМетаданныхРегистрРасчета Для Каждого БазовыйПлан Из ОбъектМД.ПланВидовРасчета.БазовыеВидыРасчета Цикл Для Каждого БазовыйРегистрРасчета Из Метаданные.РегистрыРасчета Цикл Если БазовыйРегистрРасчета.ПланВидовРасчета = БазовыйПлан Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяБаза + БазовыйРегистрРасчета.Имя, "База", "База", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "База " + БазовыйРегистрРасчета.Представление(),, ОбъектМД, 3); КонецЕсли; КонецЦикла; КонецЦикла; Если ОбъектМД.График <> Неопределено Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяДанныеГрафика, "ДанныеГрафика", "Данные графика", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Данные графика",, ОбъектМД, 0); КонецЕсли; Если ОбъектМД.ПериодДействия Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ПолноеИмяМД + "." + ИмяФактическийПериодДействия, "ФактическийПериодДействия", "Фактический период действия", "ВиртуальнаяТаблица", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Фактический период действия",, ОбъектМД, 0); КонецЕсли; КонецЕсли; Если ирОбщий.ЕстьТаблицаИзмененийОбъектаМетаданных(ОбъектМД) Тогда ДобавитьСтрокуДереваМД(СтрокаОбъектаМД, ирКэш.ИмяТаблицыИзМетаданныхЛкс(ПолноеИмяМД, Истина, Ложь), "Изменения", "Изменения", "Изменения", ИндексКартинкиТЧ, ЕстьТаблицаБД, мТаблицаВсехТаблицБД,,, ПредставлениеМД + "." + "Изменения",, ОбъектМД); КонецЕсли; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Если СтрокаТипаМетаданных.Строки.Количество() = 0 Тогда ДеревоОбъектовМД.Строки.Удалить(СтрокаТипаМетаданных); КонецЕсли; КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); мТаблицаВсехТаблицБД.Индексы.Добавить("НПолноеИмя"); //мТаблицаВсехТаблицБД.Сортировать("НПолноеИмя"); // Вроде бы сортировка хранения уже не используется мДеревоОбъектовМД = ДеревоОбъектовМД; Возврат мДеревоОбъектовМД; КонецФункции Функция ДобавитьСтрокуДереваМД(СтрокаРодителяМД, ПолноеИмяТаблицы, Имя, Представление, ТипТаблицы = "", ИндексКартинки = 0, ЕстьТаблицаБД = Ложь, мТаблицаВсехТаблицБД = Неопределено, ПолноеИмяМД ="", ИмяТаблицы = "", ПредставлениеТаблицы = "", СхемаТаблицы = "", ОбъектМД = Неопределено, ИндексПараметраОтбора = Неопределено, ФрагментыИмениТаблицы = Неопределено) ДочерняяТаблица = СтрокаРодителяМД.Строки.Добавить(); ДочерняяТаблица.Имя = Имя; ДочерняяТаблица.Представление = Представление; ДочерняяТаблица.ПолноеИмяОбъекта = ПолноеИмяТаблицы; ДочерняяТаблица.ИндексКартинки = ИндексКартинки; ДочерняяТаблица.ПравоПросмотр = СтрокаРодителяМД.ПравоПросмотр; ДочерняяТаблица.ТипТаблицы = ТипТаблицы; Если ЕстьТаблицаБД Тогда ОписаниеТаблицы = ирОбщий.ДобавитьДоступнуюТаблицуБДЛкс(мТаблицаВсехТаблицБД, ПолноеИмяТаблицы, ПолноеИмяМД, ТипТаблицы, ИмяТаблицы, ПредставлениеТаблицы, СхемаТаблицы,, ОбъектМД, ИндексПараметраОтбора, ФрагментыИмениТаблицы); ДочерняяТаблица.ЕстьДоступ = ОписаниеТаблицы.ЕстьДоступ; Иначе ДочерняяТаблица.ЕстьДоступ = СтрокаРодителяМД.ЕстьДоступ; КонецЕсли; Возврат ДочерняяТаблица; КонецФункции Функция ТаблицаВсехТаблицБД() Экспорт ПроверитьЗагрузитьКэшМДСеанса(); Если мТаблицаВсехТаблицБД <> Неопределено Тогда Возврат мТаблицаВсехТаблицБД; КонецЕсли; ДеревоОбъектовМД(); Возврат мТаблицаВсехТаблицБД; КонецФункции // Проверяет общий тип на агрегатность. // // Параметры: // ИмяОбщегоТипа - Строка; // *ЯзыкПрограммы - *Число, 0. // // Возвращаемое значение: // Булево. // Функция ЭтоАгрегатныйОбщийТип(Знач ИмяОбщегоТипа, Знач ЯзыкПрограммы = 0) Экспорт Если ИмяОбщегоТипа = "" Тогда Возврат Ложь; КонецЕсли; ИмяОбщегоТипа = ирОбщий.ПервыйФрагментЛкс(ИмяОбщегоТипа, "["); СтруктураКлюча = Новый Структура("ТипКонтекста, ЯзыкПрограммы, ТипЯзыка", ИмяОбщегоТипа, ЯзыкПрограммы, ""); // 2021 добавил ТипЯзыка для попадания в индекс Если Ложь Или ирОбщий.СтрокиРавныЛкс(ИмяОбщегоТипа, "COMОбъект") Или (Истина И Найти(ИмяОбщегоТипа, " {") = 0 // подробный COM И ТаблицаКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0 И ТаблицаШаблоновКонтекстов.НайтиСтроки(СтруктураКлюча).Количество() = 0 ) Тогда Результат = Ложь; Иначе Результат = Истина; КонецЕсли; Возврат Результат; КонецФункции Функция БазовыйФайлРедактора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 ПутьКРодителю = ПутьКРеквизитуУправляемойФормы(ДанныеФормы, ЛиДляКоллекции, ДокументДОМ); СтруктураИмен = Новый Структура; Если ЗначениеЗаполнено(ПутьКРодителю) Тогда СтруктураИмен = ИменаРеквизитовФормы(Форма, ПутьКРодителю, ЛиДляКоллекции,, ДокументДОМ).Все; Если ЗначениеЗаполнено(ИмяСвойства) И Не СтруктураИмен.Свойство(ИмяСвойства) Тогда ДобавитьОтсутствиеЭлементаФормы(Форма, "Реквизит:" + ПутьКРодителю + "." + ИмяСвойства); КонецЕсли; Иначе // parameters - там почему то всегда пусто КонецЕсли; Возврат СтруктураИмен; КонецФункции //. // Параметры: // ДанныеФормы - ДанныеФормы - // ЛиДляКоллекции - Булево, Неопределено - // выхДокументДОМ - ДокументDOM - // Возвращаемое значение: // Строка - Функция ПутьКРеквизитуУправляемойФормы(Знач ДанныеФормы, выхЛиДляКоллекции = Неопределено, выхДокументДОМ = Неопределено) Экспорт Если выхЛиДляКоллекции = Неопределено Тогда выхЛиДляКоллекции = ирОбщий.ЛиКоллекцияЛкс(ДанныеФормы); КонецЕсли; выхДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ДанныеФормы)); // 1.2 мс на малой форме Разыменователь = РазыменовательПространствИменDOM(); Выражение = "/*[last()]/t:type[1]/text()"; ПутьКРодителю = выхДокументДОМ.ВычислитьВыражениеXPath(Выражение, выхДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Строка).СтроковоеЗначение; Если Найти(ПутьКРодителю, "root.") = 1 Тогда ПутьКРодителю = Сред(ПутьКРодителю, СтрДлина("root.") + 1); Иначе ПутьКРодителю = ""; КонецЕсли; Возврат ПутьКРодителю; КонецФункции // Позволяет пользователю выбрать один из возможных вариантов описания слова. // // Параметры: // СтруктураЦикла - Соответствие - где ключи - имена ветвей дерева, а значения - таблицы структур типов; // *ВключатьПутьКОписаниюТипаЗначения - Булево, *Неопределено - признак добавления в список выбора тип значения слова. // // Возвращаемое значение: // СтрокаТаблицыЗначений, Структура - описание слова. // Функция ВыбратьСтрокуОписанияИзМассиваСтруктурТипов(СтруктураЦикла, ВключатьПутьКОписаниюТипаЗначения = Ложь, ВладелецФормы = Неопределено, Слово = "", НомерПараметраМетода = 0, БезусловнаяАктивизацияРезультатов = Истина, выхФормаВыбора = Неопределено, КоличествоФактПараметровМетода = 0) Экспорт ДеревоВыбора = Новый ДеревоЗначений; ДеревоВыбора.Колонки.Добавить("Ключ"); ДеревоВыбора.Колонки.Добавить("Представление"); ДеревоВыбора.Колонки.Добавить("ТипСлова"); СчетчикСтрокВторогоУровня = 0; НачальнаяСтрокаВыбора = Неопределено; Для Каждого ЭлементЦикла Из СтруктураЦикла Цикл СтрокаЭлементаЦикла = ДеревоВыбора.Строки.Добавить(); СтрокаЭлементаЦикла.Представление = ЭлементЦикла.Ключ; КонецЦикла; ДеревоВыбора.Строки.Сортировать("Представление"); Для Каждого СтрокаЭлементаЦикла Из ДеревоВыбора.Строки Цикл Для Каждого СтруктураТипаКонтекста Из СтруктураЦикла[СтрокаЭлементаЦикла.Представление] Цикл //Если СтруктураТипаКонтекста.СтрокаОписания = Неопределено Тогда // Продолжить; //КонецЕсли; Если СтруктураТипаКонтекста.ИмяОбщегоТипа = "НеизвестныйКонтекст" Тогда Продолжить; КонецЕсли; СтрокаОписания = СтруктураТипаКонтекста.СтрокаОписания; Если ТипЗнч(СтрокаОписания) = Тип("Структура") Тогда СтрокаОписания = СтрокаОписания.СтрокаОписания; КонецЕсли; // Ранее среди параметров были: ПутьКСлову = "", ТекущееСлово = "", //// Добавим строку описания слова //ЭтоИмяТипа = Ложь; //Попытка // Если СтрокаОписания.ТипЯзыка = "ИмяТипа" Тогда // ЭтоИмяТипа = Истина; // КонецЕсли; //Исключение //КонецПопытки; // //Если ЭтоИмяТипа Тогда // // Если Прав(ПутьКСлову, 1) = "(" Тогда // ЧистыйПутьКСлову = Лев(ПутьКСлову, СтрДлина(ПутьКСлову) - 1); // Иначе // ЧистыйПутьКСлову = ТекущееСлово; // КонецЕсли; // // БазовыйТип = ирОбщий.ПервыйФрагментЛкс(ЧистыйПутьКСлову); // Если БазовыйТип = "" Тогда // // НеизвестныйКонтекст // СтрокаОписания = Неопределено; // Иначе // СтрокаОписания = ТаблицаОбщихТипов.Найти(БазовыйТип, "БазовыйТип"); // КонецЕсли; //КонецЕсли; Если Истина И ТипЗнч(СтрокаОписания) = Тип("СтрокаТаблицыЗначений") И СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписания, "Ключ") = Неопределено И СтрокаОписания.Владелец().Колонки.Найти("ЛиЭкспорт") = Неопределено И (Ложь Или СтрокаОписания.Владелец().Колонки.Найти("ТипЯзыка") = Неопределено Или СтрокаОписания.ТипЯзыка <> "ИмяТипа") Тогда ПредставлениеТипа = СтрокаОписания.Слово; Если Истина И СтрокаОписания.Владелец().Колонки.Найти("ТипКонтекста") <> Неопределено И ЗначениеЗаполнено(СтрокаОписания.ТипКонтекста) Тогда ПредставлениеТипа = СтрокаОписания.ТипКонтекста + "." + ПредставлениеТипа; КонецЕсли; СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить(); СтрокаДереваВыбора.Ключ = СтрокаОписания; Попытка СтрокаДереваВыбора.ТипСлова = СтрокаОписания.ТипСлова; Исключение СтрокаДереваВыбора.ТипСлова = "Тип"; КонецПопытки; СтрокаДереваВыбора.Представление = ПредставлениеТипа; КонецЕсли; Если ВключатьПутьКОписаниюТипаЗначения Тогда // Добавим строку описания типа значения СтрокаОписанияТипаЗначения = ТаблицаОбщихТипов.Найти(НРег(СтруктураТипаКонтекста.ИмяОбщегоТипа), "НСлово"); Если СтрокаОписанияТипаЗначения <> Неопределено Тогда Если СтрокаЭлементаЦикла.Строки.Найти(СтрокаОписанияТипаЗначения, "Ключ") = Неопределено Тогда ПредставлениеТипа = СтрокаОписанияТипаЗначения.Слово; СтрокаДереваВыбора = СтрокаЭлементаЦикла.Строки.Добавить(); СтрокаДереваВыбора.Ключ = СтрокаОписанияТипаЗначения; СтрокаДереваВыбора.ТипСлова = "Тип"; СтрокаДереваВыбора.Представление = ПредставлениеТипа; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; СчетчикСтрокВторогоУровня = СчетчикСтрокВторогоУровня + СтрокаЭлементаЦикла.Строки.Количество(); Если Истина И НачальнаяСтрокаВыбора = Неопределено И СтрокаЭлементаЦикла.Строки.Количество() > 0 Тогда Если СтрокаДереваВыбора.ТипСлова = "Конструктор" Тогда Отбор = Новый Структура; Отбор.Вставить("ТипКонтекста", СтрокаОписания.ТипКонтекста); Отбор.Вставить("Слово", "<Новый>"); Отбор.Вставить("ЯзыкПрограммы", 0); ТаблицаВариантов = ТаблицаПараметров.Скопировать(Отбор); НовыйТекущийВариант = ПодобратьВариантСинтаксисаМетода(ТаблицаВариантов, КоличествоФактПараметровМетода); Для Каждого СтрокаВарианта Из СтрокаЭлементаЦикла.Строки Цикл Если НовыйТекущийВариант = СтрокаВарианта.Ключ.Слово Тогда НачальнаяСтрокаВыбора = СтрокаВарианта; Прервать; КонецЕсли; КонецЦикла; Иначе НачальнаяСтрокаВыбора = СтрокаЭлементаЦикла.Строки[0]; КонецЕсли; КонецЕсли; СтрокаЭлементаЦикла.Строки.Сортировать("Представление"); КонецЦикла; Если выхФормаВыбора = Неопределено Тогда выхФормаВыбора = ирКлиент.ПолучитьФормуЛкс("Обработка.ирСинтаксПомощник.Форма"); КонецЕсли; Если Ложь Или Истина //Или СчетчикСтрокВторогоУровня > 0 //Или выхФормаВыбора.Открыта() Тогда выхФормаВыбора.ДеревоТиповСлова = ДеревоВыбора; выхФормаВыбора.ИскомоеСлово = Слово; выхФормаВыбора.ПоискСУчетомТипаСлова = Истина; выхФормаВыбора.НомерИскомогоПараметра = НомерПараметраМетода; выхФормаВыбора.ВладелецФормы = ВладелецФормы; выхФормаВыбора.ЗакрыватьПриЗакрытииВладельца = Ложь; Если НачальнаяСтрокаВыбора <> Неопределено Тогда выхФормаВыбора.ВыбратьИскомуюСтроку(НачальнаяСтрокаВыбора, БезусловнаяАктивизацияРезультатов); Иначе Если выхФормаВыбора.Открыта() Тогда //выхФормаВыбора.ОбновитьРезультатыПоиска(); // - бесконечная рекурсия при открытии из поля текста по слову Иначе выхФормаВыбора.Открыть(); // - нужно для вызова из адаптера КонецЕсли; КонецЕсли; выхФормаВыбора.ВладелецФормы = Неопределено; // Перенес в саму форму КонецЕсли; Если Ложь Или СчетчикСтрокВторогоУровня = 1 Или (Истина И СчетчикСтрокВторогоУровня = 2 И ДеревоВыбора.Строки[0].Строки.Количество() = 1 И НачальнаяСтрокаВыбора.Ключ = ДеревоВыбора.Строки[1].Строки[0].Ключ) Тогда ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора; ИначеЕсли СчетчикСтрокВторогоУровня > 1 Тогда //ФормаВыбора = ПолучитьФорму("ФормаВыбораСправкиПоСлову"); //ФормаВыбора.ДеревоТиповСлова = ДеревоВыбора; //ФормаВыбора.НачальноеЗначениеВыбора = НачальнаяСтрокаВыбора; //ВыбранныйЭлементТипа = ФормаВыбора.ОткрытьМодально(); ВыбранныйЭлементТипа = НачальнаяСтрокаВыбора; Иначе ВыбранныйЭлементТипа = Неопределено; КонецЕсли; Если ВыбранныйЭлементТипа = Неопределено Тогда СтрокаОписания = Неопределено; Иначе СтрокаОписания = ВыбранныйЭлементТипа.Ключ; КонецЕсли; Возврат СтрокаОписания; КонецФункции Функция НайтиИмяМетодаСтрокиМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "", Знач ЧислоСтрокДляПоискаИмениМетода = 1000, выхСодержаниеСтроки = "") Экспорт Если Не ЗначениеЗаполнено(ИмяМодуля) Тогда // Динамический код Возврат ""; КонецЕсли; ОписаниеМодуля = ирКлиент.ОписаниеМодуляПоСжатомуИмениЛкс(ИмяМодуля); ИмяМетода = НайтиИмяМетодаСтрокиФайлаМодуля(ОписаниеМодуля.ИмяМодуля, НомерСтроки, СодержаниеСтроки, ТекстыМодулей, СтароеИмяФайлаМодуляБезРасширения, ЧислоСтрокДляПоискаИмениМетода,,, выхСодержаниеСтроки); Возврат ИмяМетода; КонецФункции Функция НайтиИмяМетодаСтрокиФайлаМодуля(Знач ИмяМодуля, Знач НомерСтроки, Знач СодержаниеСтроки = Неопределено, ТекстыМодулей = Неопределено, СтароеИмяФайлаМодуляБезРасширения = "", Знач ЧислоСтрокДляПоискаИмениМетода = 2000, выхСмещениеСтрокиМетода = 0, Знач ПолеТекстаМодуля = Неопределено, выхСодержаниеСтроки = "") Экспорт Если ПолеТекстаМодуля = Неопределено Тогда ПолеТекстаМодуля = ирКлиент.ПолеТекстаМодуляБезСтруктурыТипаЛкс(ИмяМодуля); КонецЕсли; Если ПолеТекстаМодуля = Неопределено Тогда Возврат Неопределено; КонецЕсли; выхСодержаниеСтроки = СокрЛП(ПолеТекстаМодуля.ПолеТекста.ПолучитьСтроку(НомерСтроки)); Если Ложь Или СодержаниеСтроки = Неопределено Или выхСодержаниеСтроки = СокрЛП(СодержаниеСтроки) Тогда НужноеОписаниеМетода = Неопределено; // СтрокаТаблицыЗначений, Неопределено ИмяМетода = НайтиМетодПоНомеруСтроки(ПолеТекстаМодуля, НомерСтроки, ИмяМодуля, ТекстыМодулей, ЧислоСтрокДляПоискаИмениМетода, НужноеОписаниеМетода); Если НужноеОписаниеМетода <> Неопределено Тогда выхСмещениеСтрокиМетода = НомерСтроки - НужноеОписаниеМетода.НачальнаяСтрока; Если НомерСтроки > НужноеОписаниеМетода.КонечнаяСтрока Тогда НужноеОписаниеМетода.КонечнаяСтрока = НомерСтроки; КонецЕсли; КонецЕсли; Иначе Пустышка = 0; // Для отладки КонецЕсли; Возврат ИмяМетода; КонецФункции //. // Параметры: // ПолеТекстаМодуля - ОбработкаОбъект.ирКлсПолеТекстаПрограммы, Неопределено - // НомерСтроки - - // ИмяМодуля - Произвольный, Строка - // ТекстыМодулейКэш - Соответствие, Неопределено - // ЧислоСтрокДляПоискаИмениМетода - Число - // КэшРазметкиМодуля - Структура, Неопределено - // НужноеОписаниеМетода - СтрокаТаблицыЗначений, Неопределено - // Возвращаемое значение: // Произвольный, Строка, Неопределено - Функция НайтиМетодПоНомеруСтроки(Знач ПолеТекстаМодуля, Знач НомерСтроки, Знач ИмяМодуля = "", Знач ТекстыМодулейКэш = Неопределено, Знач ЧислоСтрокДляПоискаИмениМетода = 2000, НужноеОписаниеМетода = Неопределено) Экспорт Если ТекстыМодулейКэш = Неопределено Тогда ТекстыМодулейКэш = Новый Соответствие; КонецЕсли; КэшРазметкиМодуля = ТекстыМодулейКэш[ИмяМодуля]; Если КэшРазметкиМодуля = Неопределено Тогда Методы = Новый ТаблицаЗначений; Методы.Колонки.Добавить("Метод"); Методы.Индексы.Добавить("Метод"); Методы.Колонки.Добавить("НачальнаяСтрока"); Методы.Колонки.Добавить("КонечнаяСтрока", Новый ОписаниеТипов("Число")); КэшРазметкиМодуля = Новый Структура("Методы", Методы); Если ТекстыМодулейКэш <> Неопределено Тогда ТекстыМодулейКэш[ИмяМодуля] = КэшРазметкиМодуля; КонецЕсли; Методы = Неопределено; КонецЕсли; НужноеОписаниеМетода = Неопределено; Если ирКэш.РежимОтладкиЛкс() Тогда // Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах. Для Каждого ОписаниеМетода Из КэшРазметкиМодуля.Методы Цикл Если Истина И ОписаниеМетода.НачальнаяСтрока <= НомерСтроки И ОписаниеМетода.КонечнаяСтрока >= НомерСтроки Тогда НужноеОписаниеМетода = ОписаниеМетода; Прервать; КонецЕсли; КонецЦикла; Иначе // Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (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]; Если Ложь Или ирОбщий.СтрКончаетсяНаЛкс(ТекущееИмяТипа, "ТабличнаяЧасть") Или ирОбщий.СтрКончаетсяНаЛкс(ТекущееИмяТипа, "ТабличнаяЧастьСтрока") Тогда КорневойТипМетаданных = "ТабличнаяЧасть"; Иначе КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Выборка.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Ссылка.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Объект.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Список.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Запись.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "НаборЗаписей.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "МенеджерЗначения.", "."); КорневойТипМетаданных = СтрЗаменить(КорневойТипМетаданных, "Менеджер.", "."); // Должно быть последним, т.к. есть WSСсылкаМенеджер КорневойТипМетаданных = ирОбщий.ПервыйФрагментЛкс(КорневойТипМетаданных); КонецЕсли; Иначе КорневойТипМетаданных = ТекущееИмяТипа; КонецЕсли; СтрокаТипаМетаОбъектов = ОписаниеТипаМетаОбъектов(КорневойТипМетаданных); Если СтрокаТипаМетаОбъектов <> Неопределено Тогда СтрокаТипа.ИндексКартинки = СтрокаТипаМетаОбъектов.ИндексКартинкиЕдинственное; КонецЕсли; Уровень = 0; //СтрокаТипа.ИмяОбщегоТипа = ТекущееИмяТипа; Иначе Если КорневаяСтруктураТипа <> Неопределено Тогда КорневаяСтруктураТипа.Свойство("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа); КонецЕсли; СтрокаТипа.ИндексКартинки = Строки.Родитель.ИндексКартинки; КонецЕсли; Если ФрагментыОбщегоТипа <> Неопределено Тогда Если ФрагментыОбщегоТипа.ВГраница() > Уровень Тогда ТекущийФрагмент = ФрагментыОбщегоТипа[Уровень + 1]; КонецЕсли; Если Найти(ТекущийФрагмент, "<") > 0 Тогда Если Истина И КорневаяСтруктураТипа = Неопределено Тогда КорневаяСтруктураТипа = НоваяСтруктураТипа(); КорневаяСтруктураТипа.ТипЯзыка = "ИмяТипа"; КорневаяСтруктураТипа.ИмяОбщегоТипа = СтрокаТипа.Имя; КонецЕсли; Если Уровень = 0 Тогда КорневаяСтруктураТипа.Вставить("ФрагментыОбщегоТипа", ФрагментыОбщегоТипа); СтруктураТипа = НоваяСтруктураТипа(); ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа); СтруктураТипа.ИмяОбщегоТипа = ТекущееИмяТипа; Иначе СтруктураТипа = СтрокаТипа.СтруктураТипа; КонецЕсли; Попытка ТаблицаСлов = СловаКонтекстаМетаданные(СтруктураТипа, НовыеПараметрыЗаполненияСлов("Свойство")); Исключение ТаблицаСлов = Новый ТаблицаЗначений; КонецПопытки; Если Истина И Уровень > 0 И ТаблицаСлов.Количество() = 0 Тогда МассивСтрокКУдалению.Добавить(СтрокаТипа); Продолжить; Иначе ОкончаниеСтрокиТипаВниз = ""; Для Счетчик = Уровень + 2 По ФрагментыОбщегоТипа.ВГраница() Цикл Фрагмент = ФрагментыОбщегоТипа[Счетчик]; ОкончаниеСтрокиТипаВниз = ОкончаниеСтрокиТипаВниз + "." + Фрагмент; КонецЦикла; Для Каждого СтрокаСлова Из ТаблицаСлов Цикл НоваяСтрока = СтрокаТипа.Строки.Добавить(); СтруктураТипаВниз = СтрокаСлова.ТаблицаТипов[0]; НоваяСтрока.СтруктураТипа = СтруктураТипаВниз; //НоваяСтрока.Имя = ИмяТипаИзСтруктурыТипа(СтруктураТипаВниз); НоваяСтрока.Имя = ТекущееИмяТипа + "." + СтруктураТипаВниз.Метаданные.Имя; КонецЦикла; ОбработатьСтрокиДереваТипов(СтрокаТипа.Строки, КорневаяСтруктураТипа, ОкончаниеСтрокиТипаВниз); КонецЕсли; КонецЕсли; КонецЕсли; //ЗаполнитьЗначенияСвойств(СтруктураТипа, КорневаяСтруктураТипа, "ИмяОбщегоТипа"); ЗаполнитьЗначенияСвойств(ВсеТипы.Добавить(), СтрокаТипа); КонецЦикла; РодительСтрок = Строки.Родитель; Для Каждого СтрокаКУдалению Из МассивСтрокКУдалению Цикл РодительСтрок.Строки.Удалить(СтрокаКУдалению); КонецЦикла; КонецПроцедуры // Открыть диалог для редактирования допустимых типов. // // Параметры: // ДопустимыеТипы - Строка - сериализованные допустимые типы; // *ТолькоПросмотр - Булево, *Истина - открыть только для просмотра. // // Возвращаемое значение: // Строка - сериализованных допустимых типов; // Неопределено - отмена. // Функция РедактироватьДопустимыеТипы(ДопустимыеТипы, ТолькоПросмотр = Ложь) Экспорт ФормаВыбора = ПолучитьФорму("ВыборДопустимыхТипов"); ФормаВыбора.ДопустимыеТипы = ДопустимыеТипы; ФормаВыбора.ТолькоПросмотр = ТолькоПросмотр; Если ФормаВыбора.ОткрытьМодально() = Истина Тогда Возврат ФормаВыбора.ДопустимыеТипы; Иначе Возврат Неопределено; КонецЕсли; КонецФункции // Убирает из строки лишние кавычки. // // Параметры: // ПервичнаяСтрока - Строка. // // Возвращаемое значение: // Строка. // Функция ИзвлечьСтрокуШаблонаТекста(ПервичнаяСтрока) мРегВыражение.Global = Истина; СтрокаБезГраниц = Сред(ПервичнаяСтрока, 2, СтрДлина(ПервичнаяСтрока) - 2); мРегВыражение.Pattern = "([^""]*"")"""; Результат = мРегВыражение.Заменить(СтрокаБезГраниц, "$1"); Возврат Результат; КонецФункции // ИзвлечьСтрокуШаблонаТекста () // Загружает шаблоны текста из файла. // // Параметры: // Нет. // // Возвращаемое значение: // Булево - успешность операции. // Функция ПолучитьТаблицуШаблоновТекста(ИмяКласса, _мСообщенияЧерезПредупреждения = Ложь, ПринудительноОбновить = Ложь) Экспорт Если Истина И Не ПринудительноОбновить И ТаблицаШаблоновТекста <> Неопределено Тогда Возврат ТаблицаШаблоновТекста; КонецЕсли; ТаблицаШаблоновТекста = Новый ТаблицаЗначений; ТаблицаШаблоновТекста.Колонки.Добавить("Шаблон"); ТаблицаШаблоновТекста.Колонки.Добавить("Замена"); ТаблицаШаблоновТекста.Индексы.Добавить("Шаблон"); ФайлШаблонов = ирОбщий.ВосстановитьЗначениеЛкс(ИмяКласса + ".ФайлШаблоновТекста"); Файл = Новый Файл(ФайлШаблонов); Если Не Файл.Существует() Тогда Если ЗначениеЗаполнено(ФайлШаблонов) Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Не обнаружен файл шаблонов текста """ + ФайлШаблонов + """, указанный в настройках компоненты ""Контекстная подсказка"""); КонецЕсли; Возврат Неопределено; КонецЕсли; Парсер = мПолучитьПарсер("ГрамматикаФайлаШаблоновТекста"); Если Парсер = Неопределено Тогда Возврат Неопределено; КонецЕсли; ТекстовыйДокументФайла = Новый ТекстовыйДокумент; ТекстовыйДокументФайла.Прочитать(ФайлШаблонов); //Состояние("Идет загрузка файла шаблонов текста..."); gpMsgReduction = 2; gpMsgAccept = 3; gpMsgNotLoadedError = 4; gpMsgLexicalError = 5; gpMsgSyntaxError = 6; gpMsgInternalError = 8; Парсер.OpenTextString(ТекстовыйДокументФайла.ПолучитьТекст()); Закончили = Ложь; ТекущаяСтрокаТаблицыШаблоновТекста = Неопределено; Пока Не Закончили Цикл Ответ = Парсер.Parse(); Если Ложь Или Ответ = gpMsgLexicalError Или Ответ = gpMsgSyntaxError Или Ответ = gpMsgInternalError Или Ответ = gpMsgNotLoadedError Или Ответ = gpMsgAccept Тогда Закончили = Истина; ИначеЕсли Ответ = gpMsgReduction Тогда ТекущееСокращение = Парсер.CurrentReduction; // Reduction {GoldParserForNet.Parser} - Почему то TypeLib не сам видит этот тип ИмяПравила = ТекущееСокращение.ParentRule.RuleNonterminal.Text; Если ИмяПравила = "" Тогда СтартовыйТокен = ТекущееСокращение.Tokens(0); ТекущаяСтрокаТаблицыШаблоновТекста = ТаблицаШаблоновТекста.Добавить(); ТекущаяСтрокаТаблицыШаблоновТекста.Шаблон = Нрег(ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data)); ИначеЕсли ИмяПравила = "" Тогда СтартовыйТокен = ТекущееСокращение.Tokens(0); ТекущаяСтрокаТаблицыШаблоновТекста.Замена = ИзвлечьСтрокуШаблонаТекста(СтартовыйТокен.Data); КонецЕсли; КонецЕсли; КонецЦикла; //Состояние(); Если Ответ <> gpMsgAccept Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Указан неправильный файл шаблонов """ + ФайлШаблонов + """"); ТаблицаШаблоновТекста = Неопределено; КонецЕсли; Возврат ТаблицаШаблоновТекста; КонецФункции // . // Параметры: // Параметры - ТаблицаЗначений - : // *ИмяПараметра // *Значение // *ТипЗначения // ТипЗапроса - Строка, *"Построитель" - "Обычный", "Компоновка", "Построитель" Функция РедактироватьЗапрос(Текст, Параметры = Неопределено, Знач ТипЗапроса = "Построитель", ПараметрыADO = Неопределено, ПараметрыWMI = Неопределено, ВыделениеДвумерное = Неопределено, Знач Запрос = Неопределено) Экспорт СтруктураЗапроса = Новый Структура; СтруктураЗапроса.Вставить("ТекстЗапроса", Текст); Если ПараметрыADO <> Неопределено Тогда СтруктураЗапроса.Вставить("ПараметрыADO", ПараметрыADO); КонецЕсли; Если ПараметрыWMI <> Неопределено Тогда СтруктураЗапроса.Вставить("ПараметрыWMI", ПараметрыWMI); КонецЕсли; СтруктураЗапроса.Вставить("ТипЗапроса", ТипЗапроса); СтруктураЗапроса.Вставить("Имя", "Запрос"); СтруктураЗапроса.Вставить("ВыделениеДвумерное", ВыделениеДвумерное); КонсольЗапросов = ирОбщий.СоздатьОбъектПоИмениМетаданныхЛкс("Обработка.ирКонсольЗапросов"); #Если Сервер И Не Сервер Тогда КонсольЗапросов = Обработки.ирКонсольЗапросов.Создать(); #КонецЕсли Если Параметры <> Неопределено Тогда ПолныеПараметры = КонсольЗапросов.НоваяТаблицаПараметров(); ирОбщий.ЗагрузитьВТаблицуЗначенийЛкс(Параметры, ПолныеПараметры); СтруктураЗапроса.Вставить("Параметры", ПолныеПараметры); КонецЕсли; Если Запрос <> Неопределено Тогда КонсольЗапросов.мОбъектЗапроса = Запрос; КонецЕсли; РезультатФормы = КонсольЗапросов.РедактироватьСтруктуруЗапроса(, СтруктураЗапроса); Результат = РезультатФормы <> Неопределено; Если Результат Тогда Текст = РезультатФормы.ТекстЗапроса; Параметры = РезультатФормы.Параметры; ПараметрыADO = РезультатФормы.ПараметрыADO; ПараметрыWMI = РезультатФормы.ПараметрыWMI; ВыделениеДвумерное = РезультатФормы.ВыделениеДвумерное; КонецЕсли; Возврат Результат; КонецФункции #КонецЕсли //////////////////////////////////////////////////////////////////////////////// // РАБОТА С АЛГОРИТМАМИ // Выполняет текст программы. // // Параметры: // ТекстДляВыполнения - Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Функция ВыполнитьЛокально(ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Если ЛиСинтаксическийКонтроль Тогда ирОбщий.ВыполнитьАлгоритмБезРезультата(ТекстДляВыполнения); Иначе Результат = ирОбщий.ВыполнитьАлгоритм(ТекстДляВыполнения); КонецЕсли; Возврат Результат; КонецФункции // Выполняет программный код в контексте. // // Параметры: // ТекстДляВыполнения - Строка; // *ЛиСинтаксическийКонтроль - Булево, *Ложь - признак вызова только для синтаксического контроля. // Функция ВыполнитьПрограммныйКодВКонтексте(КонтекстВыполнения, МетодВыполнения = "ВыполнитьЛокально", ТекстДляВыполнения, ЛиСинтаксическийКонтроль = Ложь) Экспорт Если ПустаяСтрока(МетодВыполнения) Тогда ВызватьИсключение "Не указан метод выполнения"; КонецЕсли; Если КонтекстВыполнения = Неопределено Тогда ИнформацияОбОшибке = Вычислить(МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)"); Иначе ИнформацияОбОшибке = Вычислить("КонтекстВыполнения." + МетодВыполнения + "(ТекстДляВыполнения, ЛиСинтаксическийКонтроль)"); КонецЕсли; Возврат ИнформацияОбОшибке; КонецФункции // Получает новый экземпляр ком-объекта парсера. // // Параметры: // Нет. // // Возвращаемое значение: // ОбработкаОбъект.ирТипКомпонентаADOUtils // Функция ПолучитьADOUtils(_ПытатьсяУстанавливать = Ложь, Знач СмещениеГодаADO = Неопределено, Знач Типизировать1С = Ложь, Знач БинарныеВСтроку = Ложь) Экспорт Если мADOUtils = Неопределено Тогда ИдентификаторКласса = "GameWithFire.ADOUtils"; ИмяОбъекта = "ADOUtils"; ПодключитьВнешнююКомпоненту(ИдентификаторКласса); Попытка мADOUtils = Новый ("AddIn." + ИмяОбъекта); мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки Исключение мADOUtils = Неопределено; КонецПопытки; Если Истина И мADOUtils = Неопределено //И ПытатьсяУстанавливать И Ложь Тогда ИмяМакетаДополнительнойБиблиотеки = "Zlib1"; ИмяМакетаКомпоненты = "GameWithFire"; ПолучитьCOMОбъектИзМакета(ИмяМакетаКомпоненты, ИдентификаторКласса,, ИмяМакетаДополнительнойБиблиотеки, ИмяОбъекта); ПодключитьВнешнююКомпоненту(ИдентификаторКласса); Попытка мADOUtils = Новый ("AddIn." + ИмяОбъекта); мADOUtils.BinaryDataAs1C = Истина; // Для проверки актуальности версии библиотеки Исключение КонецПопытки; КонецЕсли; // такой способ почему то не работает //мADOUtils = ПолучитьОбъектВнешнейКомпонентыИзМакета(ИмяМакетаКомпоненты, , ИдентификаторКласса, ТипВнешнейКомпоненты.COM, ИмяМакетаДополнительнойБиблиотеки); КонецЕсли; Если мADOUtils <> Неопределено Тогда мADOUtils.ДвоичныеДанныеВВидеСтрок = БинарныеВСтроку; м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"; ПортСервераОтладки = ирОбщий.ПоследнийФрагментЛкс(Результат, ":", Ложь); Если ПортСервераОтладки = "" Тогда ПортСервераОтладки = Неопределено; КонецЕсли; мРегВыражение.Global = Истина; шСоединениеССерверомОтладки = "TCP(?:\s+)(" + шАдресIP4 +"):(?:\d+)(?:\s+)" + шАдресIP4 + ":" + ПортСервераОтладки +"(?:\s+)ESTABLISHED(?:\s+)"; мРегВыражение.Pattern = шСоединениеССерверомОтладки + Формат(ИдентификаторЭтогоПроцесса, "ЧГ="); Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата); Для Каждого Вхождение Из Вхождения Цикл ЛокальныйАдрес4 = Вхождение.SubMatches(0); Прервать; КонецЦикла; мРегВыражение.Pattern = шСоединениеССерверомОтладки + "(\d+)"; Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата); Для Каждого Вхождение Из Вхождения Цикл ИдентификаторОтладчика = Вхождение.SubMatches(1); Если Истина И ИдентификаторОтладчика <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=") И выхИдентификаторыОтладчиков.Найти(ИдентификаторОтладчика) = Неопределено Тогда ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(ИдентификаторОтладчика); Если Истина И ТипЗнч(ПроцессОС) = Тип("COMОбъект") И ирОбщий.СтрокиРавныЛкс(ПроцессОС.Name, ирОбщий.ИмяИсполняемогоФайлаКлиентаПлатформыЛкс(Ложь)) И ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС) Тогда выхИдентификаторыОтладчиков.Добавить(ИдентификаторОтладчика); КонецЕсли; КонецЕсли; КонецЦикла; выхИдентификаторыОтладчиков.Добавить("0"); // Чтобы неоднозначность сохранялась и с одним найденным отладчиком Иначе выхПротокол = "tcp"; мРегВыражение.Global = Истина; мРегВыражение.Pattern = "TCP(?:\s+)0\.0\.0\.0:(\d+)(?:\s+)" + шАдресIP4 + ":(\d+)(?:\s+)LISTENING(?:\s+)" + Формат(ИдентификаторЭтогоПроцесса, "ЧГ="); Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата); МассивСлушающихПортов = Новый Массив; СтрокаПоиска = ""; // Т.к. неясно какой из портов для отладки, используем все Для Каждого Вхождение Из Вхождения Цикл МассивСлушающихПортов.Добавить(Вхождение.SubMatches(0)); СтрокаПоиска = СтрокаПоиска + "|" + Вхождение.SubMatches(0); КонецЦикла; Если МассивСлушающихПортов.Количество() = 0 Тогда Результат = Неопределено; Возврат Результат; КонецЕсли; СтрокаПоиска = Сред(СтрокаПоиска, 2); ЛокальныйАдрес = ирОбщий.ТекстДляРегВыраженияЛкс("127.0.0.1"); мРегВыражение.Pattern = "TCP(?:\s+)" + ЛокальныйАдрес + ":(?:\d+)(?:\s+)" + ЛокальныйАдрес + ":(" + СтрокаПоиска + ")(?:\s+)ESTABLISHED(?:\s+)(\d+)"; Вхождения = мРегВыражение.НайтиВхождения(ТекстРезультата); Для Каждого Вхождение Из Вхождения Цикл ИдентификаторКорреспондента = Вхождение.SubMatches(1); Если ИдентификаторКорреспондента <> Формат(ИдентификаторЭтогоПроцесса, "ЧГ=") Тогда выхИдентификаторыОтладчиков.Добавить(ИдентификаторКорреспондента); Иначе МассивСлушающихПортов.Удалить(МассивСлушающихПортов.Найти(Вхождение.SubMatches(0))); КонецЕсли; КонецЦикла; Если МассивСлушающихПортов.Количество() > 0 Тогда Результат = "tcp://127.0.0.1:" + МассивСлушающихПортов[0]; КонецЕсли; КонецЕсли; Возврат Результат; КонецФункции #Если Клиент Тогда Функция ТаблицаТиповСтрокиТабличногоПоля(Знач РодительскаяСтруктураТипа, Знач МетаданныеРодителя = Неопределено, Знач СловоЦикл = "", Знач ТипЗначенияСлова = "", Знач выхМетаданныеСлова = Неопределено, Знач ТаблицаТипов = Неопределено) Экспорт Если МетаданныеРодителя = Неопределено Тогда МетаданныеРодителя = РодительскаяСтруктураТипа.Метаданные КонецЕсли; Форма = РодительскаяСтруктураТипа.ДержательМетаданных; ИмяРеквизитаФормы = ""; ДанныеЭлементаФормы = ирОбщий.ДанныеЭлементаФормыЛкс(МетаданныеРодителя, ИмяРеквизитаФормы, Форма); Если ДанныеЭлементаФормы <> Неопределено Тогда Если Форма = Неопределено И ТипЗнч(МетаданныеРодителя) <> Тип("ТабличноеПоле") Тогда Форма = ирОбщий.РодительЭлементаУправляемойФормыЛкс(МетаданныеРодителя); КонецЕсли; Если ТипЗнч(ДанныеЭлементаФормы) = Тип("НастройкиКомпоновкиДанных") Тогда Если СловоЦикл = "ТекущиеДанные" Тогда НоваяТаблицаТипов = ДобавитьВТаблицуТипов(, НоваяСтруктураТипа("ТекущиеДанныеСтруктурыНастроекКомпоновкиДанных")); Иначе НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы.Структура)); КонецЕсли; ИначеЕсли ирОбщий.ЛиКоллекцияКомпоновкиЛкс(ДанныеЭлементаФормы) Тогда НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ДанныеЭлементаФормы.Элементы)); ИначеЕсли ТипЗнч(ДанныеЭлементаФормы) = Тип("ДинамическийСписок") Тогда Если ТипЗначенияСлова <> "Произвольный" Тогда выхМетаданныеСлова = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы, Истина).Все; КонецЕсли; Иначе НоваяСтруктураТипа = СтруктураТипаИзЗначения(ДанныеЭлементаФормы); Если Истина И ТипЗнч(МетаданныеРодителя) = Тип("ТабличноеПоле") И ТипЗнч(Форма) = Тип("Форма") Тогда МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипаИзЗначения(Форма)); Если МодульФормы.Переменные.Найти(НРег(МетаданныеРодителя.Данные), "НИмя") <> Неопределено Тогда АнализаторКода = ПолеТекстаМодуля(МодульФормы); ТаблицаТиповТаблицыФормы = АнализаторКода.ВычислитьТипЗначенияВыражения(МетаданныеРодителя.Данные,,,,,,, Истина); ЗаполнитьЗначенияСвойств(НоваяСтруктураТипа, ТаблицаТиповТаблицыФормы[0]); КонецЕсли; КонецЕсли; Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДеревоЗначений") Тогда НоваяСтруктураТипа.ИмяОбщегоТипа = "КоллекцияСтрокДереваЗначений"; КонецЕсли; НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(НоваяСтруктураТипа); Если НоваяТаблицаТипов.Количество() = 0 Тогда //Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДеревоЗначений") Тогда // ТаблицаЗначений = ирОбщий.ДеревоЗначенийВТаблицуЛкс(ДанныеЭлементаФормы, Новый Массив); //Иначе Если ТипЗнч(МетаданныеРодителя) <> Тип("ТабличноеПоле") Тогда ТаблицаЗначений = Новый ТаблицаЗначений; Для Каждого КлючИЗначение Из ДочерниеСвойстваДанныхФормы(ДанныеЭлементаФормы, Истина, Форма) Цикл ТаблицаЗначений.Колонки.Добавить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(СтруктураТипаИзЗначения(ТаблицаЗначений)); Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДеревоЗначений") Тогда НоваяТаблицаТипов[0].ИмяОбщегоТипа = "СтрокаДереваЗначений"; Иначе // Если ТипЗнч(ДанныеЭлементаФормы) = Тип("ДанныеФормыДерево") Тогда НоваяТаблицаТипов[0].ИмяОбщегоТипа = "ДанныеФормыЭлементДерева"; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; ИначеЕсли ТипЗнч(МетаданныеРодителя) = Тип("Структура") Тогда //: МетаданныеРодителя = 0 // см. ИмитаторЭлементаФормы() выхМетаданныеСлова = Неопределено; РеквизитФормы = ирОбщий.СлужебныеДанныеФормыЛкс(Форма).Реквизиты.Найти(НРег(МетаданныеРодителя.ПутьКДанным), "НИмя"); Если РеквизитФормы <> Неопределено Тогда ОписаниеТипов = РеквизитФормы.ОписаниеТипов; //ОписаниеТипов Если ОписаниеТипов <> Неопределено Тогда Если ОписаниеТипов.СодержитТип(Тип("ДинамическийСписок")) Тогда Если ТипЗначенияСлова <> "Произвольный" Тогда выхМетаданныеСлова = ИменаРеквизитовФормы(Форма, ИмяРеквизитаФормы, Истина).Все; КонецЕсли; Иначе ТаблицаТиповКоллекции = ТаблицаТиповИзОписанияТипов(ОписаниеТипов); НоваяТаблицаТипов = ТаблицаТиповЭлементовКоллекции(ТаблицаТиповКоллекции[0]); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если Истина И НоваяТаблицаТипов <> Неопределено И Форма <> Неопределено Тогда НоваяТаблицаТипов.ЗаполнитьЗначения(Форма, "ДержательМетаданных"); КонецЕсли; Возврат НоваяТаблицаТипов; КонецФункции //. // Параметры: // ИмяФормы - Строка - // Возвращаемое значение: // Форма - Функция ПассивнаяФормаПоИмениКэш(Знач ИмяФормы) Экспорт Результат = мПассивныеФормы[НРег(ИмяФормы)]; Если Результат = Неопределено Тогда Попытка ОбъектМД = ирОбщий.ОбъектМДПоПолномуИмениЛкс(ИмяФормы); Если ОбъектМД <> Неопределено Тогда ИмяФормы = ОбъектМД.ПолноеИмя(); // Нормализуем имя, чтобы файл в кэше модулей имел оригинальные регистры букв КонецЕсли; ТекстРекомендации = ". |Рекомендуется добавить в начало ПриСоздании: Если Параметры.Свойство(""АвтоТест"") Тогда Возврат КонецЕсли;"; Форма = ирКлиент.ПассивнаяФормаПоИмениЛкс(ИмяФормы); ОписаниеОшибки = "Обработчик ПриСоздании формы вернул Отказ" + ТекстРекомендации; Если Найти(ИмяФормы, "Ф::") > 0 И Не ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда ОписаниеОшибки = "Если форма управляемая, то ее невозможно создать из внешней обработки в обычном приложении."; КонецЕсли; Исключение Форма = Неопределено; ОписаниеОшибки = ОписаниеОшибки() + ТекстРекомендации; Если Найти(ИмяФормы, "Ф::") > 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) = ТипУправляемаяФорма Или ПутьКРодителю <> Неопределено Тогда // Управляемая форма ИменаРеквизитов = Неопределено; КорневыеИменаРеквизитов = Неопределено; выхИдентификаторыРеквизитов = Новый Соответствие; ИмяОсновногоРеквизита = ""; Форма = ФормаИлиДокументDOM; Если Форма <> Неопределено Тогда СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); Иначе Пустышка = 0; // Для отладки. Желательно чтобы сюда не было приходов КонецЕсли; Если СлужебныеДанные = Неопределено Тогда // Редко. Открытая форма. Фактически не используем кэш СлужебныеДанные = Новый Структура; КонецЕсли; Если СлужебныеДанные.Свойство("КорневыеИменаРеквизитов") Тогда КорневыеИменаРеквизитов = СлужебныеДанные.КорневыеИменаРеквизитов.Все; КонецЕсли; Если ДокументДОМ = Неопределено И СлужебныеДанные.Свойство("ДокументДОМ") Тогда ДокументДОМ = СлужебныеДанные.ДокументДОМ; КонецЕсли; Если ТипЗнч(Форма) = ТипУправляемаяФорма И ДокументДОМ = Неопределено Тогда СтруктураТипа = НоваяСтруктураТипа("ФормаКлиентскогоПриложения"); СтруктураТипа.Метаданные = Форма; //МодульФормы = ПодготовитьМодульМетаданных(СтруктураТипа); // Раньше кэш ДокументДОМ хранился тут ЛюбыеДанныеФормы = Неопределено; КорневыеИменаРеквизитов = Новый Структура; ИмяМодуля = ИмяМодуляИзСтруктурыТипа(СтруктураТипа); КандидатыИменРеквизитов = ирОбщий.КандидатыИменОбъектныхРеквизитовФормыЛкс(Форма); ПолеТекстаПрограммы = Неопределено; МодульПроанализирован = Ложь; Пока Истина Цикл Для Каждого ИмяРеквизита Из КандидатыИменРеквизитов Цикл Попытка ЗначениеРеквизита = Форма[ИмяРеквизита]; Исключение Продолжить; КонецПопытки; КорневыеИменаРеквизитов.Вставить(ИмяРеквизита); Если Истина И ТипЗнч(ЗначениеРеквизита) <> Тип("СписокЗначений") И мМассивТиповСМетаданными.Найти(ТипЗнч(ЗначениеРеквизита)) <> Неопределено Тогда ЛюбыеДанныеФормы = ЗначениеРеквизита; Перейти ~Конец; КонецЕсли; КонецЦикла; Если МодульПроанализирован Тогда Прервать; КонецЕсли; Для Каждого ЭлементФормы Из Форма.Элементы Цикл ИмяРеквизита = ирОбщий.ПервыйФрагментЛкс(ирОбщий.ПутьКДаннымЭлементаУправляемойФормыЛкс(ЭлементФормы,, Форма)); Если Истина И ЗначениеЗаполнено(ИмяРеквизита) И Не КорневыеИменаРеквизитов.Свойство(ИмяРеквизита) Тогда КорневыеИменаРеквизитов.Вставить(ИмяРеквизита); Попытка ЗначениеРеквизита = Форма[ИмяРеквизита]; Исключение Продолжить; КонецПопытки; ТипЗначения = ТипЗнч(ЗначениеРеквизита); Если мМассивТиповСМетаданными.Найти(ТипЗначения) <> Неопределено Тогда ИмяТипа = ирОбщий.ИмяТипаЛкс(ТипЗначения); Если МассивУправляемыхЭлементовУправления.Найти(ИмяТипа) = Неопределено Тогда ЛюбыеДанныеФормы = ЗначениеРеквизита; Перейти ~Конец; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Если ЛюбыеДанныеФормы = Неопределено И РазрешитьАнализМодуля Тогда // Самый долгий способ ПолеТекстаМодуля = ПолеТекстаМодуля(ИмяМодуля); #Если Сервер И Не Сервер Тогда ПолеТекстаМодуля = Обработки.ирКлсПолеТекстаПрограммы.Создать(); #КонецЕсли ТаблицаТипов = ДобавитьВТаблицуТипов(, СтруктураТипаИзКонкретногоТипа(ирОбщий.ТипУправляемаяФормаЛкс())); ПолеТекстаМодуля.ЗаполнитьТаблицуСлов(ТаблицаТипов, Ложь,, Ложь, Ложь); ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь,,,,,, Истина); ПолеТекстаМодуля.мРодительскийКонтекст = "ЭтаФорма"; // TODO добавить слова от ЭтотОбъект ПолеТекстаМодуля.ЗаполнитьЛокальныеСвойстваИМетодыПоТексту(Ложь, Ложь, Истина, Ложь,,,, Истина); КандидатыИменРеквизитов = ПолеТекстаМодуля.ТаблицаСлов.Выгрузить(Новый Структура("Определение", "Статистический")).ВыгрузитьКолонку("НСлово"); ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтаФорма")); Если ВредныйКандидат <> Неопределено Тогда КандидатыИменРеквизитов.Удалить(ВредныйКандидат); КонецЕсли; ВредныйКандидат = КандидатыИменРеквизитов.Найти(НРег("ЭтотОбъект")); Если ВредныйКандидат <> Неопределено Тогда КандидатыИменРеквизитов.Удалить(ВредныйКандидат); КонецЕсли; КонецЕсли; МодульПроанализирован = Истина; КонецЦикла; ~Конец: Если ЛюбыеДанныеФормы <> Неопределено Тогда ДокументДОМ = ирОбщий.ТекстВДокументDOMЛкс(ирОбщий.ОбъектВСтрокуXMLЛкс(ЛюбыеДанныеФормы)); // Обычно выполняется достаточно быстро КонецЕсли; КонецЕсли; Если ПутьКРодителю = "" И Не ЛиДляКоллекции Тогда ИменаРеквизитов = КорневыеИменаРеквизитов; КонецЕсли; Если ИменаРеквизитов = Неопределено Тогда ИменаРеквизитов = Новый Структура; КонецЕсли; Если СлужебныеДанные.Свойство("Реквизиты") Тогда ИмяОсновногоРеквизита = СлужебныеДанные.ИмяОсновногоРеквизита; //Если Истина // И ЗначениеЗаполнено(ИмяОсновногоРеквизита) // И ТипЗнч(Форма) = ТипУправляемаяФорма //Тогда // Попытка // ЗначениеРеквизита = Форма[ИмяОсновногоРеквизита]; // может быть затратно часто обращаться к данным формы // Исключение // // Мультиметка250321_182536 Снимок формы устарел // ДобавитьОтсутствиеЭлементаФормы(Форма, ИмяОсновногоРеквизита); // ИмяОсновногоРеквизита = ""; // СлужебныеДанные.ИмяОсновногоРеквизита = ""; // КонецПопытки; //КонецЕсли; ТаблицаРеквизитов = СлужебныеДанные.Реквизиты; Если ТаблицаРеквизитов <> Неопределено Тогда УспехРеквизита = Истина; Для Каждого ИмяРодителя Из ирОбщий.СтрРазделитьЛкс(НРег(ПутьКРодителю),,, Ложь) Цикл СтрокаРодителя = ТаблицаРеквизитов.Найти(ИмяРодителя, "НИмя"); Если СтрокаРодителя = Неопределено Тогда УспехРеквизита = Ложь; Прервать; КонецЕсли; ТаблицаРеквизитов = СтрокаРодителя.Реквизиты; КонецЦикла; ЭтоКоллекция = Истина И СтрокаРодителя <> Неопределено И ТипЗнч(СтрокаРодителя.Значение) <> Тип("Структура"); // Мультиметка7726614 Если Истина И УспехРеквизита И (Ложь Или ЛиДляКоллекции И ЭтоКоллекция Или Не ЛиДляКоллекции) Тогда Для Каждого СтрокаРеквизита Из ТаблицаРеквизитов Цикл ОписаниеТипов = СтрокаРеквизита.ОписаниеТипов; // ОписаниеТипов Если СтрокаРеквизита.Значение = Неопределено Тогда Если ОписаниеТипов = Неопределено Тогда //ОписаниеТипов = Новый ОписаниеТипов; ИначеЕсли ТипЗнч(ОписаниеТипов) = Тип("ТаблицаЗначений") Тогда // см. ТаблицаТиповИзТекста Иначе Типы = ОписаниеТипов.Типы(); Если Типы.Количество() > 0 Тогда ТипЗначения = Типы[0]; Если Ложь Или ирОбщий.ЛиНаборЗаписейРегистраЛкс(ТипЗначения) //Или ирОбщий.ЛиТипОбъектаБДЛкс(ТипЗначения) // TODO сделать для объектов генерацию структуры их свойств Тогда ОписаниеТипов = ТаблицаТиповИзОписанияТипов(ОписаниеТипов); ОписаниеТипов[0].ИмяОбщегоТипа = "ДанныеФормыСтруктураСКоллекцией"; КонецЕсли; КонецЕсли; КонецЕсли; Иначе Если ТипЗнч(СтрокаРеквизита.Значение) = Тип("ТаблицаЗначений") Тогда СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыКоллекция"); ИначеЕсли ТипЗнч(СтрокаРеквизита.Значение) = Тип("ДеревоЗначений") Тогда СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыДерево"); // TODO Пока табличные части не сделаны и надо делать и для остальных типов объектов аналогично Мультиметка240813_080918 //ИначеЕсли ирОбщий.ЛиВнешняяОбработкаЛкс(СтрокаРеквизита.Значение) Тогда // СтруктураТипа = НоваяСтруктураТипа("ДанныеФормыСтруктура"); // СтруктураТипа.Метаданные = СтрокаРеквизита.Значение.Метаданные(); Иначе СтруктураТипа = СтруктураТипаИзЗначения(СтрокаРеквизита.Значение); КонецЕсли; Если СтруктураТипа.Метаданные = Неопределено Тогда СтруктураТипа.Метаданные = СтрокаРеквизита.Значение; КонецЕсли; ОписаниеТипов = ДобавитьВТаблицуТипов(, СтруктураТипа); КонецЕсли; ИменаРеквизитов.Вставить(СтрокаРеквизита.Имя, ОписаниеТипов); КонецЦикла; Если Истина И ТаблицаРеквизитов.Количество() = 0 И СтрокаРодителя <> Неопределено Тогда Типы = СтрокаРодителя.ОписаниеТипов.Типы(); Если Истина И Типы.Количество() > 0 И Не ирОбщий.ЛиТипСсылкиБДЛкс(Типы[0], Ложь) И Метаданные.НайтиПоТипу(Типы[0]) <> 0 Тогда ТаблицаСлов = ТаблицаСловИзСтруктурыТипа(СтруктураТипаИзКонкретногоТипа(Типы[0]), НовыеПараметрыЗаполненияСлов("Свойство")); Для Каждого СтрокаСлова Из ТаблицаСлов Цикл ИменаРеквизитов.Вставить(СтрокаСлова.Слово, СтрокаСлова.ТаблицаТипов); КонецЦикла; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ДокументДОМ <> Неопределено Тогда ЗначениеРодитель = Неопределено; Если ЗначениеЗаполнено(ПутьКРодителю) Тогда Если Найти(ПутьКРодителю, ".") = 0 Тогда Попытка ЗначениеРодитель = Форма[СтрЗаменить(ПутьКРодителю, ".", "")]; Исключение // Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/98538 КонецПопытки; КонецЕсли; ПутьКРодителю = "." + ПутьКРодителю; КонецЕсли; Разыменователь = РазыменовательПространствИменDOM(); Если ЛиДляКоллекции Тогда ПутьКРодителю = ПутьКРодителю + ".item"; КонецЕсли; Выражение = "/*/*/*[@name=""root" + ПутьКРодителю + """]/*"; НаборУзлов = ДокументДОМ.ВычислитьВыражениеXPath(Выражение, ДокументДОМ, Разыменователь, ТипРезультатаDOMXPath.Любой); УзелDOM = НаборУзлов.ПолучитьСледующий(); Пока УзелDOM <> Неопределено Цикл ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("nameRu"); Если ИмяРеквизита = Неопределено Тогда ИмяРеквизита = УзелDOM.Атрибуты.ПолучитьИменованныйЭлемент("name"); КонецЕсли; Если ИмяРеквизита <> Неопределено Тогда ИмяРеквизита = ИмяРеквизита.ТекстовоеСодержимое; Если Истина И Найти(ИмяРеквизита, ".") = 0 // Защита от нахождения "root" + ПутьКРодителю И УзелDOM.ПервыйДочерний <> Неопределено Тогда КвалификаторыСтроки = Неопределено; Типы = Новый Массив; УзелТипаЗначения = УзелDOM.ПервыйДочерний.ПервыйДочерний; Если УзелТипаЗначения <> Неопределено Тогда ИменаТипов = ирОбщий.СтрРазделитьЛкс(УзелТипаЗначения.ТекстовоеСодержимое, " "); Если ИменаТипов.Количество() < 11 Тогда Для Каждого ИДТипа Из ИменаТипов Цикл Попытка Тип = ЗначениеИзСтрокиВнутр("{""T""," + ИДТипа + "}"); Исключение Тип = Неопределено; КонецПопытки; Если Тип <> Неопределено Тогда Типы.Добавить(Тип); Если Тип = Тип("Строка") Тогда Атрибут = УзелТипаЗначения.РодительскийУзел.Атрибуты.ПолучитьИменованныйЭлемент("length"); Если Атрибут <> Неопределено Тогда ДлинаСтрока = Атрибут.ТекстовоеСодержимое; КвалификаторыСтроки = Новый КвалификаторыСтроки(Число(ДлинаСтрока)); КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; Если Истина И Типы.Количество() = 0 И ТипЗнч(Форма) = ТипУправляемаяФорма Тогда ЗначениеРеквизита = Null; Если ПутьКРодителю = "" Тогда Попытка ЗначениеРеквизита = Форма[ИмяРеквизита]; Исключение // Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/985380 КонецПопытки; Если ЗначениеРеквизита <> Null Тогда Типы.Добавить(ТипЗнч(ЗначениеРеквизита)); КонецЕсли; ИначеЕсли ЗначениеРодитель <> Неопределено Тогда Попытка ЗначениеРеквизита = ЗначениеРодитель[ИмяРеквизита]; Исключение // Может быть ошибка "Поле объекта недоступно для чтения" https://www.hostedredmine.com/issues/98538 КонецПопытки; Если ЗначениеРеквизита <> Null Тогда ТаблицаТипов = ТаблицаТиповИзЗначения(ЗначениеРеквизита); Если ИменаРеквизитов.Свойство(ИмяРеквизита) Тогда ТаблицаТипов[0].МетаданныеСвойства = ИменаРеквизитов[ИмяРеквизита][0].Метаданные; /// Например объект МД табличной части КонецЕсли; ИменаРеквизитов.Вставить(ИмяРеквизита, ТаблицаТипов); // Мультиметка250303_191432 КонецЕсли; КонецЕсли; КонецЕсли; Если Ложь Или Не ИменаРеквизитов.Свойство(ИмяРеквизита) Или (Истина И Типы.Количество() И ИменаРеквизитов[ИмяРеквизита] = Неопределено) Тогда ИменаРеквизитов.Вставить(ИмяРеквизита, Новый ОписаниеТипов(Типы,,,, КвалификаторыСтроки)); КонецЕсли; выхИдентификаторыРеквизитов.Вставить(Узел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); КонецЕсли; КонецЕсли; Результат = Новый Структура; Результат.Вставить("Основной", ИмяОсновногоРеквизита); Результат.Вставить("Все", ИменаРеквизитов); Если СлужебныеДанные <> Неопределено И Не ЗначениеЗаполнено(ПутьКРодителю) Тогда СлужебныеДанные.Вставить("КорневыеИменаРеквизитов", Результат); КонецЕсли; Возврат Результат; КонецФункции //. // Возвращаемое значение: // РазыменовательПространствИменDOM - Функция РазыменовательПространствИменDOM() Экспорт СоответствиеПИ = Новый Соответствие; СоответствиеПИ.Вставить("t", "http://v8.1c.ru/8.2/uobjects"); СоответствиеПИ.Вставить("xs", "http://www.w3.org/2001/XMLSchema"); СоответствиеПИ.Вставить("xsi", "http://www.w3.org/2001/XMLSchema-instance"); Разыменователь = Новый РазыменовательПространствИменDOM(СоответствиеПИ); Возврат Разыменователь; КонецФункции //. // Параметры: // Форма - Форма - // Возвращаемое значение: // Структура, Неопределено - Функция СтруктураТипаОбъектаОбычнойФормы(Знач Форма) Экспорт СлужебныеДанные = ирОбщий.СлужебныеДанныеФормыЛкс(Форма); СтруктураТипаОбъекта = Неопределено; Если Истина И СлужебныеДанные <> Неопределено И Не СлужебныеДанные.Свойство("СтруктураТипаОбъекта", СтруктураТипаОбъекта) Тогда ОсновнойРеквизитФормы = ИмяОсновногоРеквизитаФормы(Форма, Ложь); // Иначе будет циклическая рекурсия при инициации модуля упр. формы Если Истина И ЗначениеЗаполнено(ОсновнойРеквизитФормы) И ТипЗнч(Форма) <> Тип("Структура") Тогда Попытка ОбъектОсновнойРеквизит = Форма[ОсновнойРеквизитФормы]; Исключение // Мультиметка250321_182536 Снимок формы устарел ОбъектОсновнойРеквизит = Неопределено; КонецПопытки; Если ОбъектОсновнойРеквизит <> Неопределено Тогда Если ТипЗнч(ОбъектОсновнойРеквизит) = Тип("ДанныеФормыСтруктура") Тогда ТаблицаТипов = ТаблицаТиповИзОписанияТипов(ИменаРеквизитовФормы(Форма).Все[ОсновнойРеквизитФормы]); Если ТаблицаТипов.Количество() > 0 Тогда СтруктураТипаОбъекта = ТаблицаТипов[0]; Иначе Попытка Ключ = Форма.Параметры.Ключ; Исключение Ключ = Неопределено; КонецПопытки; Если Ключ <> Неопределено Тогда ИмяМД = Метаданные.НайтиПоТипу(ТипЗнч(Ключ)).ПолноеИмя(); Если ирОбщий.ЛиКлючЗаписиРегистраЛкс(Ключ) Тогда Подтип = "МенеджерЗаписи"; Иначе Подтип = "Объект"; КонецЕсли; СтруктураТипаОбъекта = СтруктураТипаИзКонкретногоТипа(Тип(ирОбщий.ИмяТипаИзПолногоИмениМДЛкс(ИмяМД, Подтип))); КонецЕсли; КонецЕсли; Иначе СтруктураТипаОбъекта = СтруктураТипаИзЗначения(ОбъектОсновнойРеквизит); КонецЕсли; СлужебныеДанные.Вставить("СтруктураТипаОбъекта", СтруктураТипаОбъекта); КонецЕсли; КонецЕсли; КонецЕсли; Возврат СтруктураТипаОбъекта; КонецФункции //. // Возвращаемое значение: // Структура - Функция ВсеИменаСтандартныхФорм() Экспорт ВсеИменаСтандартныхФорм = Новый Структура; ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаГруппы", "Форма группы"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ИменаСтандартныхФорм.Добавить("ФормаВыбораГруппы", "Форма выбора группы"); ВсеИменаСтандартныхФорм.Вставить("Справочник", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаСохранения", "Форма сохранения"); ИменаСтандартныхФорм.Добавить("ФормаЗагрузки", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("ХранилищеНастроек", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("Документ", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("Перечисление", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("Форма", "Форма"); ИменаСтандартныхФорм.Добавить("ФормаНастроек", "Форма настроек"); ИменаСтандартныхФорм.Добавить("ФормаВарианта", "Форма варианта"); ВсеИменаСтандартныхФорм.Вставить("Отчет", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаЗаписи", "Форма записи"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ВсеИменаСтандартныхФорм.Вставить("РегистрСведений", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаГруппы", "Форма группы"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ИменаСтандартныхФорм.Добавить("ФормаВыбораГруппы", "Форма выбора группы"); ВсеИменаСтандартныхФорм.Вставить("ПланВидовХарактеристик", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("ПланСчетов", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("ПланВидовРасчета", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("БизнесПроцесс", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаОбъекта", "Форма объекта"); ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ИменаСтандартныхФорм.Добавить("ФормаВыбора", "Форма выбора"); ВсеИменаСтандартныхФорм.Вставить("Задача", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("ФормаСписка", "Форма списка"); ВсеИменаСтандартныхФорм.Вставить("РегистрБухгалтерии", ИменаСтандартныхФорм); ВсеИменаСтандартныхФорм.Вставить("РегистрРасчета", ИменаСтандартныхФорм); ВсеИменаСтандартныхФорм.Вставить("РегистрНакопления", ИменаСтандартныхФорм); ИменаСтандартныхФорм = Новый СписокЗначений; ИменаСтандартныхФорм.Добавить("Форма", "Форма"); ВсеИменаСтандартныхФорм.Вставить("КритерийОтбора", ИменаСтандартныхФорм); ВсеИменаСтандартныхФорм.Вставить("ЖурналДокументов", ИменаСтандартныхФорм); ВсеИменаСтандартныхФорм.Вставить("Обработка", ИменаСтандартныхФорм); Возврат ВсеИменаСтандартныхФорм; КонецФункции // Функция - Получить макет компоненты // // Параметры: // Компонента - ОбработкаОбъект, ОбработкаОбъект.ирКлсПолеТекстаПрограммы - // // Возвращаемое значение: // Форма - // Функция ПолучитьМакетКомпоненты(Компонента) Экспорт Макет = 0; Если Не МакетыКомпонент.Свойство(Компонента.ИмяКласса, Макет) Тогда Макет = Компонента.ПолучитьФорму("ФормаМакет"); Попытка Пустышка = Макет.мПлатформа; Успех = Истина; Исключение Успех = Ложь; КонецПопытки; Если Успех Тогда ирОбщий.СообщитьЛкс("Образована циклическая ссылка на ирПлатформа", СтатусСообщения.Внимание); КонецЕсли; МакетыКомпонент.Вставить(Компонента.ИмяКласса, Макет); КонецЕсли; Возврат Макет; КонецФункции //. // Параметры: // ФайлВнешнейОбработки - Файл - // ОтФормы - - // Возвращаемое значение: // - Функция ТекстМодуляВнешнейОбработкиАлгоритма(ФайлВнешнейОбработки, Знач ОтФормы = Ложь) Экспорт Если Не ФайлВнешнейОбработки.Существует() Тогда Возврат Неопределено; КонецЕсли; ТекстМодуля = ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки, ОтФормы); Если ТекстМодуля = Неопределено Тогда Возврат Неопределено; КонецЕсли; ТекстАлгоритма = ирОбщий.ТекстМеждуМаркерамиЛкс(ТекстМодуля, МаркерНачалаАлгоритма, МаркерКонцаАлгоритма); Результат = ""; ТекстАлгоритмаТД = Новый ТекстовыйДокумент; ТекстАлгоритмаТД.УстановитьТекст(ТекстАлгоритма); Для Счетчик = 1 По ТекстАлгоритмаТД.КоличествоСтрок() Цикл СтрокаАлгоритма = ТекстАлгоритмаТД.ПолучитьСтроку(Счетчик); Если Лев(СтрокаАлгоритма, 1) = Символы.Таб Тогда СтрокаАлгоритма = Сред(СтрокаАлгоритма, 2); КонецЕсли; Результат = Результат + СтрокаАлгоритма + Символы.ПС; КонецЦикла; Возврат Результат; КонецФункции Функция ТекстМодуляСгенерированнойВнешнейОбработки(ФайлВнешнейОбработки, Знач ЛиМодульОтФормы = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ФайлВнешнейОбработки = Новый Файл; #КонецЕсли ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки(); Если Не ИспользоватьБыструюРаспаковку Тогда // Штатный способ платформы, но работает только на 8.3.8+ ТекстЛога = Неопределено; ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ИмяВременногоФайла + """ """ + ФайлВнешнейОбработки.ПолноеИмя + """",, ТекстЛога, Истина) Тогда УдалитьФайлы(ИмяВременногоФайла); ирОбщий.СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; Если ЛиМодульОтФормы Тогда ИмяФайлаМодуля = "Module.bsl" Иначе ИмяФайлаМодуля = "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, Знач ПерейтиКОпределению = Ложь, Знач ВнутреннееИмя = "", Знач ЛиМодульОтФормы = Ложь) Экспорт ФайлВнешнейОбработки = Новый Файл(ПолноеИмяФайла); Если Ложь Или мНомерВерсииПлатформы >= 803008 И ирКэш.НомерВерсииPowerShellЛкс() >= 3 Тогда Если Не ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда ИдентификаторПроцесса = ВыбратьПроцессКонфигуратора(); Если ИдентификаторПроцесса = Неопределено Тогда Возврат; КонецЕсли; КонецЕсли; ТекстСкрипта = ПолучитьМакет("СкриптОткрытьМодульВнешнейОбработки"); ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1")); ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя); СтрокаЗапуска = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя + " -processID " + ИдентификаторПроцесса + " -file """ + ПолноеИмяФайла + """"); Если НомерСтрокиВМодуле > 0 Тогда СтрокаЗапуска = СтрокаЗапуска + " -line " + Формат(НомерСтрокиВМодуле, "ЧГ="); КонецЕсли; Если ЗначениеЗаполнено(ВнутреннееИмя) Тогда СтрокаЗапуска = СтрокаЗапуска + " -internalName """ + ВнутреннееИмя + """"; КонецЕсли; Если ЛиМодульОтФормы Тогда СтрокаЗапуска = СтрокаЗапуска + " -form 1"; КонецЕсли; Если ПерейтиКОпределению Тогда СтрокаЗапуска = СтрокаЗапуска + " -jump 1"; КонецЕсли; ЖдатьКонца = Ложь; // - иначе возникает 20с ожидание на инструкции $mainWindow = $rootElement.FindFirst(...) РезультатКоманды = ирОбщий.ВыполнитьКомандуОСЛкс(СтрокаЗапуска, ЖдатьКонца); //ЗапуститьПриложение(СтрокаЗапуска, КаталогВременныхФайлов(), ЖдатьКонца); Иначе ПолучитьФайлОткрывателя1С(); СтрокаЗапуска = """" + ФайлОткрывателя1С.ПолноеИмя + """ -com -ob1""" + ФайлВнешнейОбработки.ПолноеИмя + """"; Если НомерСтрокиВМодуле > 0 Тогда СтрокаЗапуска = СтрокаЗапуска + " -num" + Формат(НомерСтрокиВМодуле, "ЧГ="); КонецЕсли; Если ЗначениеЗаполнено(ИдентификаторПроцесса) Тогда СтрокаЗапуска = СтрокаЗапуска + " -pid" + Формат(ИдентификаторПроцесса, "ЧГ="); КонецЕсли; СтрокаЗапуска = СтрокаЗапуска + " -reopen"; WshShell().Run(СтрокаЗапуска, 0, ЖдатьКонца); КонецЕсли; КонецПроцедуры Функция ВыбратьПроцессКонфигуратора(Знач ИдентификаторыОтладчиков = Неопределено) Экспорт Если ИдентификаторыОтладчиков = Неопределено Тогда ИдентификаторыОтладчиков = ИдентификаторыПроцессовОтладчиков(); #Если Сервер И Не Сервер Тогда ИдентификаторыОтладчиков = Новый Массив; #КонецЕсли КонецЕсли; ТекстСкрипта = ПолучитьМакет("СкриптОткрытыеПриложения1С"); ФайлСкрипта = Новый Файл(ПолучитьИмяВременногоФайла("ps1")); ТекстСкрипта.Записать(ФайлСкрипта.ПолноеИмя); КомандаСистемыЗапускаСкрипта = ирОбщий.КомандаСистемыЗапускаСкриптаPowerShellЛкс(ФайлСкрипта.Имя); РезультатСкрипта = ирОбщий.ВыполнитьКомандуОСЛкс(КомандаСистемыЗапускаСкрипта); // - 1000мс ТаблицаКонфигураторов = ирОбщий.ТаблицаИзСтрокиСРазделителемЛкс(РезультатСкрипта,,, Истина); НачальноеЗначениеВыбора = Неопределено; ПодходящиеПоПредставлению = Новый Массив; СписокКонфигураторов = Новый СписокЗначений; Для Каждого СтрокаКонфигуратора Из ТаблицаКонфигураторов Цикл ПроцессОС = ирОбщий.ПолучитьПроцессОСЛкс(СтрокаКонфигуратора.Id); // - 50мс Если Не ирОбщий.ЛиПроцессОСКонфигуратораЛкс(ПроцессОС) Тогда Продолжить; КонецЕсли; ПредставлениеПроцесса = СтрокаКонфигуратора.MainWindowTitle; ЛиОтладчик = ИдентификаторыОтладчиков.Найти(СтрокаКонфигуратора.Id) <> Неопределено; Если ЛиОтладчик Тогда ПредставлениеПроцесса = "<Отладчик>" + ПредставлениеПроцесса; КонецЕсли; НовыйЭлемент = СписокКонфигураторов.Добавить(СтрокаКонфигуратора.Id, ПредставлениеПроцесса); Если ЛиОтладчик Тогда НачальноеЗначениеВыбора = НовыйЭлемент; КонецЕсли; Если Найти(ПредставлениеПроцесса, Метаданные.Представление()) Тогда НачальноеЗначениеВыбора = НовыйЭлемент; ПодходящиеПоПредставлению.Добавить(НовыйЭлемент); КонецЕсли; КонецЦикла; Если ПодходящиеПоПредставлению.Количество() = 1 Тогда РезультатВыбора = ПодходящиеПоПредставлению[0]; ИначеЕсли СписокКонфигураторов.Количество() = 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(мСвязанныйКонфигуратор.ИД); ТекстДок = Новый ТекстовыйДокумент; ТекстДок.УстановитьТекст(ПередаваемыйТекст); ТекстДок.Записать(мСвязанныйКонфигуратор.ИмяФайлаБуфера); КонецПроцедуры Процедура СохранитьНастройкиАлгоритмов() Экспорт ирОбщий.СохранитьЗначениеЛкс("СинтаксическийКонтрольПередЗаписью", СинтаксическийКонтрольПередЗаписью); ирОбщий.СохранитьЗначениеЛкс("ВыполнятьАлгоритмыЧерезВнешниеОбработки", ВыполнятьАлгоритмыЧерезВнешниеОбработки); ирОбщий.СохранитьЗначениеЛкс("ФайловыйКэшАлгоритмовДопускаетРедактирование", ФайловыйКэшАлгоритмовДопускаетРедактирование); КонецПроцедуры // СохранитьНастройкиАлгоритмов() Функция ТаблицаРедактируемыхТиповИзОписанияТипов(ОписаниеТипов = Неопределено) Экспорт #Если Сервер И Не Сервер Тогда ОписаниеТипов = Новый ОписаниеТипов; #КонецЕсли ПоляКлюча = "Имя, 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 //! Парсер = Новый COMОбъект("GoldParserForNet.Parser"); Если Парсер <> Неопределено Тогда Парсер.TrimReductions = Истина; МакетГрамматики = ПолучитьМакет(ИмяГрамматики); ФайлСкомпилированнойГрамматики = ПолучитьИмяВременногоФайла("cgt"); МакетГрамматики.Записать(ФайлСкомпилированнойГрамматики); Если Не Парсер.LoadCompiledGrammar(ФайлСкомпилированнойГрамматики) Тогда ирОбщий.СообщитьСУчетомМодальностиЛкс("Не удалось загрузить файл грамматики """ + ФайлСкомпилированнойГрамматики + """", Истина, СтатусСообщения.Важное); Парсер = Неопределено; КонецЕсли; УдалитьФайлы(ФайлСкомпилированнойГрамматики); Иначе ирОбщий.СообщитьЛкс(СообщениеПользователюПриНеудаче, СтатусСообщения.Внимание); КонецЕсли; Если Кэшировать Тогда Парсеры.Вставить(ИмяГрамматики, Парсер); КонецЕсли; Возврат Парсер; КонецФункции Процедура ПроверитьСтруктуруФайловогоКэша() Экспорт ПроверитьКаталогФайловогоКэша(); СтруктураПодкаталоговФайловогоКэша = Новый Структура; СтруктураПодкаталоговФайловогоКэша.Вставить("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 ВызватьИсключение "Нельзя использовать кириллические буквы в именах файлов внешних компонент"; КонецЕсли; Если ЗначениеЗаполнено(ИмяМакетаДополнительнойБиблиотеки) Тогда ФайлДополнительнойБиблиотеки = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаДополнительнойБиблиотеки); КонецЕсли; // Таким способом в некоторых средах не создавались объекты, возможно из-за работы антивируса https://www.hostedredmine.com/issues/1005009 //ФайлКомпоненты = ПроверитьЗаписатьКомпонентуИзМакетаВФайл(ИмяМакетаКомпоненты); //Местоположение = ФайлКомпоненты.ПолноеИмя; // ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты); Местоположение = ПоместитьВоВременноеХранилище(ДвоичныеДанныеМакета); Успех = ПодключитьВнешнююКомпоненту(Местоположение, ИмяКомпоненты, ТипКомпоненты); ПодключитьВнешнююКомпоненту(ИмяОбъекта); Попытка Результат = Новый (ИмяОбъекта); Исключение Описание = ОписаниеОшибки(); // Для отладки КонецПопытки; КонецПопытки; Возврат Результат; КонецФункции Функция НечеткоеСравнениеСлов() Экспорт Если мНечеткоеСравнениеСлов = Неопределено Тогда мНечеткоеСравнениеСлов = ПолучитьОбъектВнешнейКомпонентыИзМакета("FuzzySearch", "AddIn.FuzzySearch.FuzzyStringMatchExtension", "FuzzySearch"); // ОбработкаОбъект.ирТипКомпонентаFuzzySearch КонецЕсли; Возврат мНечеткоеСравнениеСлов; КонецФункции Функция ПроверитьЗаписатьКомпонентуИзМакетаВФайл(Знач ИмяМакетаКомпоненты, КаталогУстановки = "", Расширение = "dll") Экспорт Если Не ЗначениеЗаполнено(КаталогУстановки) Тогда КаталогУстановки = ПапкаВнешнихКомпонент.ПолноеИмя; КонецЕсли; ДвоичныеДанныеМакета = ПолучитьДвоичныеДанныеКомпоненты(ИмяМакетаКомпоненты); ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "." + Расширение); ВременныйФайл = Новый Файл(ПолучитьИмяВременногоФайла()); Попытка ДвоичныеДанныеМакета.Записать(ВременныйФайл.ПолноеИмя); Исключение ирОбщий.СообщитьЛкс("Не удалось создать временный файл компоненты """ + ИмяМакетаКомпоненты + """: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат Неопределено; КонецПопытки; Счетчик = 1; ФайлПодходит = Ложь; Пока ФайлКомпоненты.Существует() Цикл #Если Клиент Тогда СравнениеФайлов = Новый СравнениеФайлов; СравнениеФайлов.СпособСравнения = СпособСравненияФайлов.Двоичное; СравнениеФайлов.ПервыйФайл = ВременныйФайл.ПолноеИмя; СравнениеФайлов.ВторойФайл = ФайлКомпоненты.ПолноеИмя; Если СравнениеФайлов.Сравнить() Тогда ФайлПодходит = Истина; Прервать; КонецЕсли; #Иначе // Внешняя компонента может собираться с одинаковым размером (сборщик ее дополняет пустотой до нужного размера) //Если ВременныйФайл.Размер() = ФайлКомпоненты.Размер() Тогда // Опасно. Переделать на Хэш // ФайлПодходит = Истина; // Прервать; //КонецЕсли; #КонецЕсли Попытка УдалитьФайлы(ФайлКомпоненты.ПолноеИмя); Исключение ФайлКомпоненты = Новый Файл(КаталогУстановки + ирОбщий.РазделительПутиКФайлуЛкс() + ИмяМакетаКомпоненты + "_" + Формат(Счетчик, "ЧГ=") + "." + Расширение); Счетчик = Счетчик + 1; КонецПопытки; КонецЦикла; Если Не ФайлПодходит Тогда Попытка ПереместитьФайлКакАдминистратор(ВременныйФайл.ПолноеИмя, ФайлКомпоненты.ПолноеИмя); Исключение УдалитьФайлы(ВременныйФайл.ПолноеИмя); ирОбщий.СообщитьЛкс("Файл """ + ФайлКомпоненты.ПолноеИмя + """ недоступен для изменения и не был перезаписан.", СтатусСообщения.Внимание); Возврат Неопределено; КонецПопытки; КонецЕсли; Возврат ФайлКомпоненты; КонецФункции // Способ через ZIP архив (32+64) появился только в 8.3 Функция ПолучитьДвоичныеДанныеКомпоненты(БазовоеИмяМакетаКомпоненты) Экспорт Если Метаданные().Макеты.Найти(БазовоеИмяМакетаКомпоненты) = Неопределено Тогда Если ирКэш.ЛиПлатформаWindowsЛкс() Тогда БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Win"; Иначе БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "Lin"; КонецЕсли; Если ирКэш.Это64битныйПроцессЛкс() Тогда БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "64"; Иначе БазовоеИмяМакетаКомпоненты = БазовоеИмяМакетаКомпоненты + "32"; КонецЕсли; КонецЕсли; ДвоичныеДанныеМакета = ПолучитьМакет(БазовоеИмяМакетаКомпоненты); Возврат ДвоичныеДанныеМакета; КонецФункции Функция СоздатьОбъектВнешнихМетаданных(ПолноеИмяФайла, МенеджерВнешнихОбъектов = Неопределено, Конвертировать = Истина) Экспорт Если МенеджерВнешнихОбъектов = Неопределено Тогда МенеджерВнешнихОбъектов = ВнешниеОбработки; КонецЕсли; Попытка ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь); Исключение #Если Клиент Тогда ОписаниеОшибки = ОписаниеОшибки(); Если Истина И Конвертировать И Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитан")) > 0 //И мНомерВерсииПлатформы <> 802015 // Антибаг 8.2.15 http://partners.v8.1c.ru/forum/thread.jsp?id=1003164#1003164 Тогда СтрокаЗапуска = "DESIGNER /ConvertFiles""" + ПолноеИмяФайла + """"; ЗапуститьСистему(СтрокаЗапуска, Истина); ВнешнийОбъект = МенеджерВнешнихОбъектов.Создать(ПолноеИмяФайла, Ложь); Иначе #КонецЕсли ВызватьИсключение; #Если Клиент Тогда КонецЕсли; #КонецЕсли КонецПопытки; Возврат ВнешнийОбъект; КонецФункции Функция СоздатьВнешнююОбработкуАлгоритма(АлгоритмОбъект, ПолноеИмя) Экспорт Попытка ВнешняяОбработка = СоздатьОбъектВнешнихМетаданных(ПолноеИмя); Результат = ВнешняяОбработка; Исключение ИнформацияОбОшибке = ИнформацияОбОшибке(); ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке); Если Найти(НРег(ОписаниеОшибки), НРег("не может быть прочитана текущей версией")) > 0 Тогда УдалитьФайлы(ПолноеИмя); КонецЕсли; СобытиеОшибки = "Ошибка создания внешнего объекта"; ОписаниеОшибки = "Загрузка сервиса """ + АлгоритмОбъект.Наименование + """"; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + " |" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина); КонецЕсли; ОписаниеОшибки = СобытиеОшибки + ": " + ОписаниеОшибки; ОписаниеОшибки = ОписаниеОшибки + ": " + ИнформацияОбОшибке.Описание + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока; ирОбщий.СообщитьЛкс(ОписаниеОшибки, СтатусСообщения.Важное); ЗаписьЖурналаРегистрации(СобытиеОшибки, УровеньЖурналаРегистрации.Ошибка, Метаданные.НайтиПоТипу(ТипЗнч(АлгоритмОбъект.Ссылка)), АлгоритмОбъект.Ссылка, ОписаниеОшибки); Результат = Неопределено; КонецПопытки; Возврат Результат; КонецФункции // СоздатьВнешнююОбработкуАлгоритма() // Проверяет актуальность кэша. Вызывается когда кэш в памяти уже точно не соотвествует объекту БД. Функция ПроверитьАктуальностьКэшаВнешнейОбработки(ЭлементКэша, ДатаИзмененияКэша, ФайлВнешнейОбработки, ДатаИзмененияОбъекта, КэшВнешнейОбработкиАктуален, ФайлВнешнейОбработкиАктуален, ФайловыйКэшДопускаетРедактирование) Экспорт Попытка ДатаИзмененияФайла = ФайлВнешнейОбработки.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс(); ФайлВнешнейОбработкиСуществует = Истина; Исключение ФайлВнешнейОбработкиСуществует = Ложь; КонецПопытки; Если ФайлВнешнейОбработкиСуществует Тогда Если Истина И ЭлементКэша <> Неопределено И ЭлементКэша.ДатаИзменения >= ДатаИзмененияФайла И ЭлементКэша.ДатаИзменения >= ДатаИзмененияОбъекта Тогда КэшВнешнейОбработкиАктуален = Истина; ИначеЕсли Ложь Или (Истина И ЭлементКэша = Неопределено И ДатаИзмененияФайла = ДатаИзмененияОбъекта) Или (Истина И ЭлементКэша <> Неопределено И ДатаИзмененияФайла = ЭлементКэша.ДатаИзменения И ДатаИзмененияФайла = ДатаИзмененияОбъекта) Или (Истина И ФайловыйКэшДопускаетРедактирование И (Ложь Или (Истина И ЭлементКэша = Неопределено И ДатаИзмененияФайла >= ДатаИзмененияОбъекта) Или (Истина И ЭлементКэша <> Неопределено И ДатаИзмененияФайла >= ЭлементКэша.ДатаИзменения И ДатаИзмененияФайла >= ДатаИзмененияОбъекта))) Тогда ФайлВнешнейОбработкиАктуален = Истина; ДатаИзмененияКэша = ДатаИзмененияФайла; КонецЕсли; КонецЕсли; КонецФункции // ПроверитьАктуальностьКэшаВнешнейОбработки() Функция РазвернутьНовыйШаблонВнешнейОбработки(СуффиксМакета = "СМодулем", ГлобальныйКлюч = Неопределено, ФайлСИменем, ТекстФайлаСИменем = "") Экспорт Если ГлобальныйКлюч = Неопределено Тогда ГлобальныйКлюч = "" + Новый УникальныйИдентификатор; КонецЕсли; лПутьКШаблонуВнешнейОбработки = ПутьККаталогуСлужебныхВременныхФайлов + ГлобальныйКлюч; Файл = Новый Файл(ПолучитьИмяВременногоФайла()); //ПолучитьМакет("ВнешняяОбработка").Записать(Файл.ПолноеИмя); ИмяМакета = "ШаблонВнешнейОбработки" + СуффиксМакета; ПолучитьМакет(ИмяМакета).Записать(Файл.ПолноеИмя); Чтение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; КонецЕсли; Возврат ИспользоватьБыстрыйГенератор; КонецФункции Функция СформироватьВнешнююОбработку(Знач ФайлОбработки, Знач ИмяОбработки, Знач ТекстМодуля, Знач ТекстМакета = Неопределено, Знач _ДляИДВерсииПлатформы = "", Знач ИспользоватьБыструюРаспаковку = Неопределено, ЛиМодульОтФормы = Ложь) Экспорт #Если Сервер И Не Сервер Тогда ФайлОбработки = Новый файл; #КонецЕсли ДляИДВерсииПлатформы = "83"; //Если ИспользоватьБыструюРаспаковку = Неопределено Тогда // ИспользоватьБыструюРаспаковку = ЛиИспользоватьБыструюРаспаковкуВнешнейОбработки(); //КонецЕсли; ИспользоватьБыструюРаспаковку = Истина; // используется шаблон с макетом, то там надо добавить файл versions.data.und - https://github.com/e8tools/v8unpack/issues/69 Если Не ИспользоватьБыструюРаспаковку Тогда // Штатный способ платформы, но работает только на 8.3.8+ Если ТекстМакета <> Неопределено Тогда ВызватьИсключение "Парамер ТекстМакета для 8.3.11+ не поддерживается"; КонецЕсли; КлючШаблона = "8" + ЛиМодульОтФормы; ШаблонВнешнейОбработки = ШаблоныВнешнейОбработки[КлючШаблона]; Если ШаблонВнешнейОбработки = Неопределено Тогда ИмяВременногоФайла = ПолучитьИмяВременногоФайла("epf"); ПолучитьМакет("ВнешняяОбработка").Записать(ИмяВременногоФайла); ШаблонВнешнейОбработки = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ШаблонВнешнейОбработки); ТекстЛога = Неопределено; Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/DumpExternalDataProcessorOrReportToFiles """ + ШаблонВнешнейОбработки + """ """ + ИмяВременногоФайла + """",, ТекстЛога, Истина,,,,,,, Ложь) Тогда УдалитьФайлы(ШаблонВнешнейОбработки); УдалитьФайлы(ИмяВременногоФайла); ирОбщий.СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; ШаблоныВнешнейОбработки[КлючШаблона] = ШаблонВнешнейОбработки; КонецЕсли; Если ЛиМодульОтФормы Тогда ИмяФайлаМодуля = "Module.bsl" Иначе ИмяФайлаМодуля = "ObjectModule.bsl"; КонецЕсли; Файлы = НайтиФайлы(ШаблонВнешнейОбработки, ИмяФайлаМодуля, Истина); ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.УстановитьТекст(ТекстМодуля); ТекстовыйДокумент.Записать(Файлы[0].ПолноеИмя); ТекстЛога = Неопределено; ИмяКорневогоФайла = ШаблонВнешнейОбработки + ирОбщий.РазделительПутиКФайлуЛкс() + "ИмяВнешнейОбработки.xml"; Если ЗначениеЗаполнено(ИмяОбработки) Тогда ПотокСИменемОбработки = Новый ТекстовыйДокумент; ПотокСИменемОбработки.Прочитать(ИмяКорневогоФайла); ПотокСИменемОбработки.УстановитьТекст(СтрЗаменить(ПотокСИменемОбработки.ПолучитьТекст(), "ИмяВнешнейОбработки", ИмяОбработки)); ПотокСИменемОбработки.Записать(ИмяКорневогоФайла); КонецЕсли; Если Не ирОбщий.ВыполнитьКомандуКонфигуратораЛкс("/LoadExternalDataProcessorOrReportFromFiles """ + ИмяКорневогоФайла + """ """ + ФайлОбработки.ПолноеИмя + """", , ТекстЛога, Истина,,,,,,, Ложь) Тогда УдалитьФайлы(ШаблонВнешнейОбработки); УдалитьФайлы(ИмяВременногоФайла); ирОбщий.СообщитьЛкс(ТекстЛога); Возврат Ложь; КонецЕсли; Результат = Истина; Иначе КлючШаблона = ДляИДВерсииПлатформы + ЛиМодульОтФормы; Если ТекстМакета <> Неопределено Тогда ШаблонВнешнейОбработкиСМакетом = ШаблоныВнешнейОбработкиСМакетом[КлючШаблона]; Если ШаблонВнешнейОбработкиСМакетом = Неопределено Тогда ШаблонВнешнейОбработкиСМакетом = Новый Структура("Путь, ФайлСИменем, ФайлЗамок, ТекстФайлаСИменем"); ШаблонВнешнейОбработкиСМакетом.Путь = РазвернутьНовыйШаблонВнешнейОбработки("СМакетом",, ШаблонВнешнейОбработкиСМакетом.ФайлСИменем, ШаблонВнешнейОбработкиСМакетом.ТекстФайлаСИменем); ФайлЗамокШаблонаСМакетом = Новый ЗаписьТекста; ФайлЗамокШаблонаСМакетом.Открыть(ШаблонВнешнейОбработкиСМакетом.Путь + ".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"); КонецЕсли; КонецЕсли; КонецЕсли; Если ЭлементКэша <> Неопределено Тогда Результат = ЭлементКэша.ВнешняяОбработка; Иначе Результат = Неопределено; КонецЕсли; Возврат Результат; КонецФункции // ПолучитьВнешнююОбработкуПоАлгоритму() // https://www.mista.ru/topic/779525 Функция ЕстьАдминистративныеПраваУУчетнойЗаписиОС() Экспорт Если мЕстьАдминистративныеПраваУУчетнойЗаписиОС <> Неопределено Тогда Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС; КонецЕсли; Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда Возврат Ложь; КонецЕсли; //Попытка // Network = Новый COMОбъект("WScript.Network"); //Исключение // ОписаниеОшибки = ОписаниеОшибки(); // Возврат Ложь; //КонецПопытки; ////ПользовательОС = Network.UserDomain + "\" + Network.UserName; //ПользовательОС = Network.UserName; //КомандаСистемы = "Net user " + ПользовательОС; КомандаСистемы = "whoami /all"; // ОС Windows Vista+ РезультатКоманды = ТекстРезультатаКомандыСистемы(КомандаСистемы); мЕстьАдминистративныеПраваУУчетнойЗаписиОС = Ложь Или Найти(РезультатКоманды, "Администраторы") > 0 Или Найти(РезультатКоманды, "Administrators") > 0; Возврат мЕстьАдминистративныеПраваУУчетнойЗаписиОС; КонецФункции Функция ПереместитьФайлКакАдминистратор(ИмяИсточника, ИмяПриемника) Экспорт Успех = Истина; Попытка //ПереместитьФайл(ИмяИсточника, ИмяПриемника); // так не работает наследование прав от каталога-приемника! КопироватьФайл(ИмяИсточника, ИмяПриемника); Исключение ОписаниеОшибки = ОписаниеОшибки(); КонецПопытки; Если ОписаниеОшибки <> Неопределено Тогда //КомандаСистемы = "cmd.exe /c move """ + ИмяИсточника + """ """ + ИмяПриемника + """"; // так не работает наследование прав от каталога-приемника! КомандаСистемы = "cmd.exe /c copy """ + ИмяИсточника + """ """ + ИмяПриемника + """"; ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина); // При успехе возвращает: // Скопировано файлов: 1. Если Найти(ОписаниеОшибки, "1") = 0 Тогда ВызватьИсключение "Ошибка доступа к файлу """ + ИмяПриемника + """: " + ОписаниеОшибки; КонецЕсли; КонецЕсли; Если Успех Тогда Попытка УдалитьФайлы(ИмяИсточника); Исключение КомандаСистемы = "cmd.exe /c del """ + ИмяИсточника + """"; ОписаниеОшибки = ТекстРезультатаКомандыСистемы(КомандаСистемы,, Истина); // При успехе возвращает пустую строку Если Не ПустаяСтрока(ОписаниеОшибки) Тогда ВызватьИсключение "Ошибка доступа к файлу """ + ИмяИсточника + """: " + ОписаниеОшибки; КонецЕсли; КонецПопытки; КонецЕсли; Возврат Успех; КонецФункции Функция ПолучитьПолноеИмяКомпьютераСетиПоЛюбомуИмени(ИмяКомпьютера) Экспорт ФайлРезультата = Новый Файл(ПолучитьИмяВременногоФайла()); ирОбщий.ЗапуститьСкрытоеПриложениеИДождатьсяЗавершенияЛкс("nslookup " + ИмяКомпьютера, ФайлРезультата.Путь, ФайлРезультата.Имя); Если Не ФайлРезультата.Существует() Тогда ПолноеИмяКомпьютера = ""; Иначе ТекстовыйДокумент = Новый ТекстовыйДокумент; ТекстовыйДокумент.Прочитать(ФайлРезультата.ПолноеИмя); УдалитьФайлы(ФайлРезультата.ПолноеИмя); ТекстРезультата = ТекстовыйДокумент.ПолучитьТекст(); мРегВыражение.IgnoreCase = Истина; мРегВыражение.Pattern = "(?:name|имя|╚ь ):\s*([-" + шБукваЦифра + "]+(\.([-" + шБукваЦифра + "]+))*)\s*"; Результат = мРегВыражение.НайтиВхождения(ТекстРезультата); Если Результат.Количество() > 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"; Возврат ИмяФайлаНастроекКомпьютера; КонецФункции Функция ИмяНеопределеннойПеременнойИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт Если ИнформацияОбОшибке <> Неопределено Тогда мРегВыражение.Global = Ложь; //ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке); Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; ОписаниеОшибки = ИнформацияОбОшибке.Описание; мРегВыражение.Pattern = "(?:Переменная не определена |Variable is not defined )\(([_0-9" + шБуква + "]+)\)"; Результат = мРегВыражение.НайтиВхождения(ОписаниеОшибки); Если Результат.Количество() > 0 Тогда ИмяПеременнойРезультата = Результат[0].SubMatches(0); Иначе Если СообщитьНеобрабатываемуюОшибку Тогда ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИмяПеременнойРезультата; КонецФункции Функция ИмяНеопределенногоМетодаИзИнформацииОбОшибке(ИнформацияОбОшибке, СообщитьНеобрабатываемуюОшибку = Ложь) Экспорт Если ИнформацияОбОшибке <> Неопределено Тогда мРегВыражение.Global = Ложь; //ОписаниеОшибки = ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке); Пока ИнформацияОбОшибке.Причина <> Неопределено Цикл // Добавлено 26.07.2011 из-за доработки синтаксического контроля в COM сеансе ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; ОписаниеОшибки = ИнформацияОбОшибке.Описание; мРегВыражение.Pattern = "(?:Процедура или функция с указанным именем не определена |TODO_xxxx9469326459823 )\(([_0-9" + шБуква + "]+)\)"; Результат = мРегВыражение.НайтиВхождения(ОписаниеОшибки); Если Результат.Количество() > 0 Тогда ИмяМетодаРезультата = Результат[0].SubMatches(0); Иначе Если СообщитьНеобрабатываемуюОшибку Тогда ирОбщий.СообщитьЛкс(ирОбщий.ПодробноеПредставлениеОшибкиЛкс(ИнформацияОбОшибке), СтатусСообщения.Важное); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ИмяМетодаРезультата; КонецФункции #Если Клиент Или ВнешнееСоединение Тогда Функция ВыполнитьАлгоритм(СсылкаАлгоритма, СтруктураПараметров = Неопределено) Экспорт Если СтруктураПараметров = Неопределено Тогда СтруктураПараметров = Новый Структура; КонецЕсли; АлгоритмОбъект = Неопределено; Если Не КешАлгоритмов.Свойство(СсылкаАлгоритма, АлгоритмОбъект) Тогда АлгоритмОбъект = СсылкаАлгоритма.ПолучитьОбъект(); КешАлгоритмов.Вставить(СсылкаАлгоритма, АлгоритмОбъект); КонецЕсли; Результат = ВыполнитьМетодАлгоритма(АлгоритмОбъект, 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; КонецЕсли; ПолеТекстаПрограммы = мПоляТекстаПрограммы[ЯзыкПрограммы]; Если ПолеТекстаПрограммы = Неопределено Тогда ПолеТекстаПрограммы = ирОбщий.НовыйАнализаторКодаЛкс(); #Если Сервер И Не Сервер Тогда ПолеТекстаПрограммы = Обработки.ирКлсПолеТекстаПрограммы.Создать(); #КонецЕсли ПолеТекстаПрограммы.ИнициироватьНеинтерактивно(ЯзыкПрограммы); ПолеТекстаПрограммы.ЭтоМодуль = Истина; мПоляТекстаПрограммы[ЯзыкПрограммы] = ПолеТекстаПрограммы; КонецЕсли; Возврат ПолеТекстаПрограммы; КонецФункции #КонецЕсли Функция РеквизитыДляСервера(Параметры) Экспорт //Результат = ирОбщий.РеквизитыОбработкиЛкс(ЭтотОбъект); Возврат Новый Структура; КонецФункции Функция ЗаполнитьТипыДанныхМакетовКонфигурации(Знач Параметры) Экспорт ТаблицаМакетов = Параметры.МакетыКонфигурации; // см. МакетыКонфигурации.Выгрузить() ИндикаторМакетов = ирОбщий.ПолучитьИндикаторПроцессаЛкс(МакетыКонфигурации.Количество()); Для Каждого СтрокаМакета Из ТаблицаМакетов Цикл ирОбщий.ОбработатьИндикаторЛкс(ИндикаторМакетов); ИзвлечьСодержимоеМакета(СтрокаМакета); КонецЦикла; ирОбщий.ОсвободитьИндикаторПроцессаЛкс(); Результат = Новый Структура; Результат.Вставить("МакетыКонфигурации", ТаблицаМакетов); Возврат Результат; КонецФункции //. // Параметры: // СтрокаМакета - ОбработкаТабличнаяЧастьСтрока.ирПлатформа.МакетыКонфигурации - // МетаМакет - ОбъектМетаданныхМакет - Процедура ИзвлечьСодержимоеМакета(Знач СтрокаМакета, Знач МетаМакет = Неопределено) Экспорт Если МетаМакет = Неопределено Тогда МетаМакет = Метаданные.НайтиПоПолномуИмени(СтрокаМакета.ПолноеИмя); КонецЕсли; РодительМД = МетаМакет.Родитель(); Если ТипЗнч(РодительМД) = Тип("ОбъектМетаданныхКонфигурация") Тогда ДанныеМакета = ПолучитьОбщийМакет(МетаМакет.Имя); Иначе Менеджер = ирОбщий.ПолучитьМенеджерЛкс(РодительМД); ДанныеМакета = Менеджер.ПолучитьМакет(МетаМакет.Имя); КонецЕсли; ТипМакета = ТипЗнч(ДанныеМакета); СтрокаМакета.ТипДанных = ТипМакета; СтрокаМакета.ИмяТипа = ирОбщий.ИмяТипаЛкс(ТипМакета); КонецПроцедуры Функция ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение) Экспорт Результат = мКэшПустыхЗначений[ПустоеЗначение]; Если Результат = Неопределено Тогда Результат = ирОбщий.ПредставлениеПустогоЗначенияЛкс(ПустоеЗначение); мКэшПустыхЗначений[ПустоеЗначение] = Результат; КонецЕсли; Возврат Результат; КонецФункции // Возвращает текущее время в миллисекундах. // // Параметры: // Нет. // // Возвращаемое значение: // Число. // Функция ПолучитьТекущееВремяВМиллисекундах() Экспорт Если ирКэш.НомерИзданияПлатформыЛкс() > "82" Тогда Результат = Вычислить("ТекущаяУниверсальнаяДатаВМиллисекундах()"); КонецЕсли; Если Результат = Неопределено Тогда Если JavaScript = Неопределено Тогда Попытка JavaScript = Новый COMОбъект("MSScriptControl.ScriptControl"); Исключение ирОбщий.СообщитьЛкс("Ошибка создания MSScriptControl.ScriptControl: " + ОписаниеОшибки(), СтатусСообщения.Внимание); Возврат 0; КонецПопытки; JavaScript.Language = "javascript"; КонецЕсли; Результат = JavaScript.Eval("new Date().getTime()"); КонецЕсли; Возврат Результат; КонецФункции Функция ПроверитьПолучитьОбъектСервиса(Знач АлгоритмОбъект) Экспорт Если ТипЗнч(АлгоритмОбъект) = Тип("СтрокаТаблицыЗначений") Тогда лОбъект = АлгоритмОбъект.ЭтотОбъект; Если лОбъект = Неопределено Тогда лОбъект = АлгоритмОбъект.Ссылка.ПолучитьОбъект(); ЗаполнитьЗначенияСвойств(лОбъект, АлгоритмОбъект, , "ЭтотОбъект, Ссылка, мПолнаяТаблицаПараметров"); ////%!% АлгоритмОбъект.ЭтотОбъект = лОбъект; КонецЕсли; АлгоритмОбъект = лОбъект; КонецЕсли; Возврат АлгоритмОбъект; КонецФункции // ПроверитьПолучитьОбъектСервиса() Функция ПредставлениеИнформацииОбОшибке(Знач ИнформацияОбОшибке) Экспорт // Антибаг платформы. В описании повторяется причина и описание между уровнями. В общем бардак. ОписаниеОшибки = ИнформацияОбОшибке.Описание; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда Пока Истина И ИнформацияОбОшибке.Причина <> Неопределено И ИнформацияОбОшибке.Описание = ОписаниеОшибки Цикл ИнформацияОбОшибке = ИнформацияОбОшибке.Причина; КонецЦикла; Если ИнформацияОбОшибке.Описание <> ОписаниеОшибки Тогда ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке); КонецЕсли; Иначе Фрагмент = ирОбщий.ПоследнийФрагментЛкс(ОписаниеОшибки, "по причине:" + Символы.ПС); Позиция = Найти(ОписаниеОшибки, Фрагмент + Символы.ПС + "по причине:" + Символы.ПС + Фрагмент); Если Позиция > 0 Тогда ОписаниеОшибки = Лев(ОписаниеОшибки, Позиция) + Фрагмент; КонецЕсли; КонецЕсли; Возврат ОписаниеОшибки; КонецФункции // ПредставлениеИнформацииОбОшибке() Функция ОбработатьВнешнееИсключениеАлгоритма(ДескрипторСервиса, ИнформацияОбОшибке, РежимВыполненияАлгоритма, Интерактивно = Истина) Экспорт //СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса); // Такой прием применен для избежания обращения к БД внутри сломанной транзакции Если ТипЗнч(ДескрипторСервиса) = Тип("СтрокаТаблицыЗначений") Тогда лОбъект = ДескрипторСервиса.ЭтотОбъект; Если лОбъект = Неопределено Тогда //лОбъект = Справочники.Сервисы2iS.СоздатьЭлемент(); //ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, , "ЭтотОбъект, Ссылка, КэшПараметров"); лОбъект = Новый ("СправочникОбъект.Сервисы2iS"); ЗаполнитьЗначенияСвойств(лОбъект, ДескрипторСервиса, "мЗначенияПоУмолчанию, мВнешниеПараметры, мВнутренниеПараметры"); КонецЕсли; СервисОбъект = лОбъект; Иначе //! ДескрипторСервиса = Справочники.ирАлгоритмы.СоздатьЭлемент(); СервисОбъект = ДескрипторСервиса; КонецЕсли; Если РежимВыполненияАлгоритма = 2 Тогда Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуАлгоритмаВТексте(); ИмяМодуляСервиса = ""; ИначеЕсли Ложь Или РежимВыполненияАлгоритма = 1 Или РежимВыполненияАлгоритма = 0 Тогда Смещение = СервисОбъект.ПолучитьСтартовуюСтрокуМетодаВМодуле(); ИмяМодуляСервиса = "ВнешняяОбработка." + ДескрипторСервиса.Наименование; ИмяМодуляСервиса = ИмяМодуляСервиса + ".МодульОбъекта"; КонецЕсли; ПрефиксСервиса = "Сервис "; Если ИмяМодуляСервиса = ИнформацияОбОшибке.ИмяМодуля Тогда НомерСтрокиАлгоритма = ИнформацияОбОшибке.НомерСтроки; НомерСтрокиАлгоритма = НомерСтрокиАлгоритма - Смещение; ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]{" + НомерСтрокиАлгоритма + "}:" + Символы.ПС + "==========================================================================" + Символы.ПС + ИнформацияОбОшибке.Описание + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока; Иначе ОписаниеОшибки = ПрефиксСервиса + """" + ДескрипторСервиса.Наименование + """[" + РежимВыполненияАлгоритма + "]"; МаркерСлужебногоИсключения = "ВызватьИсключение Ошибка;//#Служебное"; Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда ОписаниеОшибки = ОписаниеОшибки + "{" + ИнформацияОбОшибке.ИмяМодуля + "(" + ИнформацияОбОшибке.НомерСтроки + ")}: "; КонецЕсли; ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.Описание; Если Найти(ИнформацияОбОшибке.ИсходнаяСтрока, МаркерСлужебногоИсключения) = 0 Тогда ОписаниеОшибки = ОписаниеОшибки + Символы.ПС + ИнформацияОбОшибке.ИсходнаяСтрока; КонецЕсли; КонецЕсли; Если ИнформацияОбОшибке.Причина <> Неопределено Тогда ОписаниеОшибки = ОписаниеОшибки + " |" + ПредставлениеИнформацииОбОшибке(ИнформацияОбОшибке.Причина); КонецЕсли; Возврат ОписаниеОшибки; КонецФункции Функция ВыполнитьМетодАлгоритма(ДескрипторСервиса, Режим, П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, П1, П2, П3, П4, П5, П6, П7, П8, П9)"); КонецЕсли; Иначе //#КонецЕсли //#Если Не Клиент И Не ВнешнееСоединение Тогда //ДескрипторСервиса.ирПлатформа = ЭтотОбъект; //#КонецЕсли СервисОбъект = ПроверитьПолучитьОбъектСервиса(ДескрипторСервиса); #Если Сервер И Не Сервер Тогда СервисОбъект = Обработки.ирИмитаторАлгоритмОбъект.Создать(); #КонецЕсли ТекстАлгоритмаСПараметрами = СервисОбъект.ПолучитьТелоМетода(); Результат = ирОбщий.ВыполнитьАлгоритм(ТекстАлгоритмаСПараметрами, СервисОбъект, Режим, П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Компонент); ОбщиеНастройки.Вставить("ПерехватКлавиатурногоВводаВОбычномПриложении", ПерехватКлавиатурногоВводаВОбычномПриложении); ОбщиеНастройки.Вставить("ВыделениеРезультатовПоиска", ВыделениеРезультатовПоиска); ОбщиеНастройки.Вставить("НеИспользоватьУправляемыеФормыИнструментов", НеИспользоватьУправляемыеФормыИнструментов); ирОбщий.СохранитьЗначениеЛкс("ОбщиеНастройки", ОбщиеНастройки); КонецПроцедуры Функция НовоеСлужебноеПолеТекста(Знач СлужебнаяФорма = Неопределено, Знач Суффикс = "") Экспорт Перем ПолеТекста; Если СлужебнаяФорма = Неопределено Тогда СлужебнаяФорма = мСлужебнаяФорма; КонецЕсли; ПолеТекста = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеТекстовогоДокумента"), "СлужебноеПолеТекста" + Суффикс, Ложь); Возврат ПолеТекста; КонецФункции Функция ТерминалыЯзыкаЗапросов() Экспорт Если мТерминалыЯзыкаЗапросов = Неопределено Тогда мТерминалыЯзыкаЗапросов = ирОбщий.ТаблицаЗначенийИзТабличногоДокументаЛкс(ПолучитьМакет("ТерминалыЯзыкаЗапросов")); мТерминалыЯзыкаЗапросов.Индексы.Добавить("Ключ"); мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Русский"); мТерминалыЯзыкаЗапросов.Индексы.Добавить("МожетБытьПсевдонимом, Английский"); КонецЕсли; Возврат мТерминалыЯзыкаЗапросов; КонецФункции Функция КлючСервисаИИ() Экспорт КлючСервисаИИ = ирОбщий.ВосстановитьЗначениеЛкс("КлючСервисаИИ"); Если КлючСервисаИИ <> Неопределено Тогда КлючСервисаИИ = КлючСервисаИИ.Получить(); КонецЕсли; Возврат КлючСервисаИИ; КонецФункции Функция МодельИИ(Знач РазрешитьПоУмолчанию = Истина, Знач Модель = Неопределено, Знач Сервер = "") Экспорт Если Модель = Неопределено Тогда Модель = ирОбщий.ВосстановитьЗначениеЛкс("МодельИИ"); КонецЕсли; Если ПустаяСтрока(Модель) И РазрешитьПоУмолчанию Тогда Если Сервер = "https://api.smartbuddy.ru" Тогда Модель = "deepseek/deepseek-chat"; ИначеЕсли Сервер = "https://api.vsegpt.ru" Тогда Модель = "deepseek/deepseek-chat"; ИначеЕсли Сервер = "https://api.together.xyz" Тогда Модель = "deepseek-ai/DeepSeek-V3"; Иначе Модель = "deepseek/deepseek-chat-v3-0324:free"; //Модель = "qwen/qwen-2.5-coder-32b-instruct:free"; // Слишком тупая КонецЕсли; КонецЕсли; Возврат Модель; КонецФункции Функция СерверИИ(Знач РазрешитьПоУмолчанию = Истина, Знач Сервер = Неопределено) Экспорт Если Сервер = Неопределено Тогда Сервер = ирОбщий.ВосстановитьЗначениеЛкс("СерверИИ"); КонецЕсли; Если ПустаяСтрока(Сервер) И РазрешитьПоУмолчанию Тогда Сервер = "https://openrouter.ai/api"; КонецЕсли; Возврат Сервер; КонецФункции Функция МаксОжиданиеИИ() Экспорт МаксОжидание = ирОбщий.ВосстановитьЗначениеЛкс("МаксОжиданиеИИ"); Если ПустаяСтрока(МаксОжидание) Тогда МаксОжидание = 60; КонецЕсли; Возврат МаксОжидание; КонецФункции Функция ЛиЗапросыИИНаСервере() Экспорт ЛиЗапросыИИНаСервере = ирОбщий.ВосстановитьЗначениеЛкс("ЛиЗапросыИИНаСервере"); Если ЛиЗапросыИИНаСервере = Неопределено Тогда ЛиЗапросыИИНаСервере = ирОбщий.ЛиАсинхронностьДоступнаЛкс(); КонецЕсли; Возврат ЛиЗапросыИИНаСервере; КонецФункции Функция ЗаголовокСтороныМодуляКонфигуратора() Экспорт Возврат "Кэш (новый)"; КонецФункции //ирПортативный Контейнер = Новый Структура(); //ирПортативный #Если Клиент Тогда //ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер); //ирПортативный #КонецЕсли //ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда //ирПортативный Файл = Новый Файл(ИспользуемоеИмяФайла); //ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(Файл.Путь, СтрДлина(Файл.Путь) - СтрДлина("Модули\")) + "ирПортативный.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| )*"; шИнструкцияПрепроцессора = "#[^\n\r]*(?=(?:\n|$))"; // Когда внутри шРазделитель был управляющий символ <начало строки>, то возникали зависания на больших литералах https://www.hostedredmine.com/issues/966307 //шЛитералПрограммы = """(?:""""|[^""\n])*(?:" + шРазделитель + "*\|(?:""""|[^""\n])*(?=(?:""|\n|$)))*(?:""|$)"; // Возможно, что с последними правками и этот вариант будет хорошо работать, но в нем не учтены инструкции препроцессора шЛитералПрограммы = """(?:""""|[^""\n\r])*(?:(?:\n|\r|^)(?:\t| )*(?:" + шКомментарий + "|" + шИнструкцияПрепроцессора + "|\|(?:""""|[^""\n\r])*(?=(?:""|\n|$)))|[\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+)?"; шИндекс = "(\[[^\n\r\]\[]+?(?:(?:\[[^\n\r\]]+?\][^\n\r\]\[]*?)*)*\])"; // Внутри квадратных скобок не допускаем переноса строки для избежания бесконечных откатов //шЛитералПростой = шЛитералПрограммы; // Так будут зависания в тесте "завис" шЛитералПростой = """(?:[^""\n\r]|[\s\xa0]*\|)*"""; шМеждуСкобок = "[^\(\);""]"; шСкобки = "(\(" + шМеждуСкобок + "*(?:(?:" + шЛитералПростой + "|\((?:" + "[^\);""]" + "|" + шЛитералПростой + ")*\))" + шМеждуСкобок + "*)*\))"; // МультиМетка82355611 шИмя = "[" + шБуква + "][" + шБуква + "\d]*"; шИмяСРешеткой = "[" + шБукваСРешеткой + "][" + шБукваСРешеткой + "\d]*"; шИмяВременнойТаблицы = шИмяСРешеткой + "(?:\." + шИмяСРешеткой + ")*"; шГиперСсылка = "(\b(?:[" + шБукваЦифра + "]+)://[" + шБукваЦифра + "\-+&@#\\/%?=~|!:,.;()]*[" + шБукваЦифра + "/])"; ВложенностьИндикации = 0; ИмяКластераСерверов = НСтр(СтрокаСоединенияИнформационнойБазы(), "Srvr"); ЭтоФайловаяБаза = ПустаяСтрока(ИмяКластераСерверов); ПрочитатьОбщиеНастройки(); Парсеры = Новый Структура; ШаблоныВнешнейОбработки = Новый Соответствие; ШаблоныВнешнейОбработкиСМакетом = Новый Соответствие; ПроверитьСтруктуруФайловогоКэша(); ИмяФайлаПакера = "v8unpack.exe"; МассивОбычныхЭлементовУправления = Новый Массив; мМассивТиповЭлементовОбычнойФормы = Новый Массив; РежимОтладки = Ложь; АсинхронностьЗапрещена = Ложь; #Если Клиент Тогда РежимОтладки = Найти(НРег(ПараметрЗапуска), НРег("РежимОтладкиИР")) > 0; АсинхронностьЗапрещена = Найти(НРег(ПараметрЗапуска), НРег("ЗапретитьАсинхронностьИР")) > 0; COMНавигатор = "НеИнициализирован"; ОтложенноеОткрытиеИсточникаОшибки = Новый ТаблицаЗначений; ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("АлгоритмОбъект"); ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("ИнформацияОбОшибке"); ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("РежимВыполненияАлгоритма"); ОтложенноеОткрытиеИсточникаОшибки.Колонки.Добавить("Смещение", Новый ОписаниеТипов("Число")); мСлужебнаяФорма = ПолучитьФорму("Служебная"); Если мСлужебнаяФорма <> Неопределено Тогда // Для портативного режима управляемого приложения СлужебноеПолеТекста = НовоеСлужебноеПолеТекста(); СлужебноеПолеТекста2 = НовоеСлужебноеПолеТекста(, "2"); //СлужебноеПолеHtmlДокумента = СлужебнаяФорма.ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"), "СлужебноеПолеHTMLДокумента", Ложь); // Тяжелая операция КонецЕсли; МассивОбычныхЭлементовУправления.Добавить("Диаграмма"); МассивОбычныхЭлементовУправления.Добавить("ДиаграммаГанта"); МассивОбычныхЭлементовУправления.Добавить("Дендрограмма"); МассивОбычныхЭлементовУправления.Добавить("Индикатор"); МассивОбычныхЭлементовУправления.Добавить("ПолеКалендаря"); МассивОбычныхЭлементовУправления.Добавить("Кнопка"); МассивОбычныхЭлементовУправления.Добавить("КолонкаТабличногоПоля"); МассивОбычныхЭлементовУправления.Добавить("КоманднаяПанель"); МассивОбычныхЭлементовУправления.Добавить("Надпись"); МассивОбычныхЭлементовУправления.Добавить("Панель"); МассивОбычныхЭлементовУправления.Добавить("Переключатель"); МассивОбычныхЭлементовУправления.Добавить("ПолеГрафическойСхемы"); МассивОбычныхЭлементовУправления.Добавить("ПолеГеографическойСхемы"); МассивОбычныхЭлементовУправления.Добавить("ПолеТабличногоДокумента"); МассивОбычныхЭлементовУправления.Добавить("ПолеHTMLДокумента"); МассивОбычныхЭлементовУправления.Добавить("ПолеТекстовогоДокумента"); МассивОбычныхЭлементовУправления.Добавить("ПолеВвода"); МассивОбычныхЭлементовУправления.Добавить("ПолеВыбора"); МассивОбычныхЭлементовУправления.Добавить("ПолеСписка"); МассивОбычныхЭлементовУправления.Добавить("ПолеКартинки"); МассивОбычныхЭлементовУправления.Добавить("ПолосаРегулирования"); МассивОбычныхЭлементовУправления.Добавить("Разделитель"); МассивОбычныхЭлементовУправления.Добавить("РамкаГруппы"); МассивОбычныхЭлементовУправления.Добавить("СводнаяДиаграмма"); МассивОбычныхЭлементовУправления.Добавить("СтраницаПанели"); МассивОбычныхЭлементовУправления.Добавить("ТабличноеПоле"); МассивОбычныхЭлементовУправления.Добавить("Флажок"); Для Каждого ИмяТипа Из МассивОбычныхЭлементовУправления Цикл мМассивТиповЭлементовОбычнойФормы.Добавить(Тип(ИмяТипа)); КонецЦикла; #КонецЕсли МассивУправляемыхЭлементовУправления = Новый Массив; мМассивТиповЭлементовУправляемойФормы = Новый Массив; МассивУправляемыхЭлементовУправления.Добавить("ПолеФормы"); МассивУправляемыхЭлементовУправления.Добавить("КнопкаФормы"); МассивУправляемыхЭлементовУправления.Добавить("ТаблицаФормы"); МассивУправляемыхЭлементовУправления.Добавить("ГруппаФормы"); МассивУправляемыхЭлементовУправления.Добавить("ДекорацияФормы"); Для Каждого ИмяТипа Из МассивУправляемыхЭлементовУправления Цикл мМассивТиповЭлементовУправляемойФормы.Добавить(Тип(ИмяТипа)); КонецЦикла; // Мультиметка121095773 мМассивТиповСМетаданными = Новый Массив; мМассивТиповСМетаданными.Добавить(Тип("ОбъектМетаданных")); мМассивТиповСМетаданными.Добавить(Тип("КоллекцияОбъектовМетаданных")); мМассивТиповСМетаданными.Добавить(Тип("КоллекцияДвижений")); мМассивТиповСМетаданными.Добавить(Тип("ОписанияСтандартныхРеквизитов")); мМассивТиповСМетаданными.Добавить(Тип("СписокПолей")); мМассивТиповСМетаданными.Добавить(Тип("Структура")); мМассивТиповСМетаданными.Добавить(Тип("СписокЗначений")); мМассивТиповСМетаданными.Добавить(Тип("ФиксированнаяСтруктура")); мМассивТиповСМетаданными.Добавить(Тип("Массив")); мМассивТиповСМетаданными.Добавить(Тип("Соответствие")); мМассивТиповСМетаданными.Добавить(Тип("ТаблицаЗначений")); мМассивТиповСМетаданными.Добавить(Тип("ДеревоЗначений")); мМассивТиповСМетаданными.Добавить(Тип("СтрокаТаблицыЗначений")); мМассивТиповСМетаданными.Добавить(Тип("СтрокаДереваЗначений")); //мМассивТиповСМетаданными.Добавить(Тип("КолонкаТаблицыЗначений")); //мМассивТиповСМетаданными.Добавить(Тип("КолонкаДереваЗначений")); мМассивТиповСМетаданными.Добавить(Тип("ВыборкаИзРезультатаЗапроса")); мМассивТиповСМетаданными.Добавить(Тип("РезультатЗапроса")); мМассивТиповСМетаданными.Добавить(Тип("Отбор")); мМассивТиповСМетаданными.Добавить(Тип("НастройкаОформления")); мМассивТиповСМетаданными.Добавить(Тип("COMОбъект")); мМассивТиповСМетаданными.Добавить(Тип("ВнешнийОбъект")); мМассивТиповСМетаданными.Добавить(Тип("ОбъектXDTO")); мМассивТиповСМетаданными.Добавить(Тип("СвойствоXDTO")); //мМассивТиповСМетаданными.Добавить(Тип("ОбщийМодуль")); мМассивТиповСМетаданными.Добавить(Тип("ПостроительЗапроса")); мМассивТиповСМетаданными.Добавить(Тип("ПостроительОтчета")); мМассивТиповСМетаданными.Добавить(Тип("ПоляНастройки")); мМассивТиповСМетаданными.Добавить(Тип("СхемаКомпоновкиДанных")); мМассивТиповСМетаданными.Добавить(Тип("ТабличныйДокумент")); мМассивТиповСМетаданными.Добавить(Тип("ОбластьЯчеекТабличногоДокумента")); мМассивТиповСМетаданными.Добавить(Тип("ТекстовыйДокумент")); мМассивТиповСМетаданными.Добавить(Тип("НаборыДанныхСхемыКомпоновкиДанных")); мМассивТиповСМетаданными.Добавить(Тип("ПараметрыСхемыКомпоновкиДанных")); //мМассивТиповСМетаданными.Добавить(Тип("ДинамическийСписок")); // Будет давать ошибку сериализации мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыДерево")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекция")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыКоллекцияЭлементовДерева")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктура")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыСтруктураСКоллекцией")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементДерева")); мМассивТиповСМетаданными.Добавить(Тип("ДанныеФормыЭлементКоллекции")); мМассивТиповСМетаданными.Добавить(ирОбщий.ТипУправляемаяФормаЛкс()); мМассивТиповСМетаданными.Добавить(Тип("ПолеФормы")); мМассивТиповСМетаданными.Добавить(Тип("ГруппаФормы")); мМассивТиповСМетаданными.Добавить(Тип("ТаблицаФормы")); мМассивТиповСМетаданными.Добавить(Тип("КомандаФормы")); //мМассивТиповСМетаданными.Добавить(Тип("СообщениеПользователю")); #Если Клиент Тогда мМассивТиповСМетаданными.Добавить(Тип("Форма")); мМассивТиповСМетаданными.Добавить(Тип("ТабличноеПоле")); мМассивТиповСМетаданными.Добавить(Тип("КолонкиТабличногоПоля")); //мМассивТиповСМетаданными.Добавить(Тип("КолонкаТабличногоПоля")); // Пользы не увидел мМассивТиповСМетаданными.Добавить(Тип("Панель")); мМассивТиповСМетаданными.Добавить(Тип("КнопкаКоманднойПанели")); мМассивТиповСМетаданными.Добавить(Тип("КнопкиКоманднойПанели")); мМассивТиповСМетаданными.Добавить(Тип("КоманднаяПанель")); мМассивТиповСМетаданными.Добавить(Тип("ПолеВвода")); #КонецЕсли Если ирКэш.НомерВерсииПлатформыЛкс() > 803007 Тогда мМассивТиповСМетаданными.Добавить(Тип("ВременнаяТаблицаЗапроса")); КонецЕсли; //#Если Клиент Или ВнешнееСоединение Тогда СубПутьКФайлуМодуляВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data.und.unp\text.data"; СубПутьКФайлуМодуляФормыВнешнейОбработки = "f362602c-e100-4638-b267-aa18ef493734.0.data.und"; СубПутьКФайлуМакетаВнешнейОбработки = "902f74d3-f929-4b0f-8719-4cbb655891aa.0.data.und"; СубПутьКФайлуЗаголовкаВнешнейОбработки = "4eb1cc18-835d-4f8c-a120-3f9d886d75d4.data.und"; СубПутьККонтрольномуФайлуВнешнейОбработки = "1ad4dbd4-e136-4202-8121-02c33ad2af45.0.data"; //КешВнешнихОбработокАлгоритмов = Новый Структура; КешАлгоритмов = Новый Структура; ТаблицаТиповМетаОбъектов = ирКэш.ТипыМетаОбъектов(); МакетыКомпонент = Новый Структура; //МаркерКоллекцииМетаданных = "КоллекцияОбъектовМетаданных"; МаркерКоллекцииМетаданных = "КоллекцияМетаданных"; МаркерОбъектаМетаданных = "ОбъектМетаданных"; мМассивИсключенийИменКоллекций = Новый СписокЗначений; мМассивИсключенийИменКоллекций.Добавить("Свойства"); мМассивИсключенийИменКоллекций.Добавить("Методы"); мМассивИсключенийИменКоллекций.Добавить(""); СоответствиеВидовСравнения = Новый ТаблицаЗначений; СоответствиеВидовСравнения.Колонки.Добавить("Построитель"); СоответствиеВидовСравнения.Колонки.Добавить("Компоновка"); СоответствиеВидовСравнения.Колонки.Добавить("Имя"); СоответствиеВидовСравнения.Индексы.Добавить("Построитель"); СоответствиеВидовСравнения.Индексы.Добавить("Компоновка"); //Интервал //ИнтервалВключаяГраницы //ИнтервалВключаяНачало //ИнтервалВключаяОкончание СоответствиеВидовСравнения.Добавить().Имя = "Больше"; СоответствиеВидовСравнения.Добавить().Имя = "БольшеИлиРавно"; СоответствиеВидовСравнения.Добавить().Имя = "ВИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "ВСписке"; СоответствиеВидовСравнения.Добавить().Имя = "ВСпискеПоИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "Меньше"; СоответствиеВидовСравнения.Добавить().Имя = "МеньшеИлиРавно"; СоответствиеВидовСравнения.Добавить().Имя = "НеВИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "НеВСписке"; СоответствиеВидовСравнения.Добавить().Имя = "НеВСпискеПоИерархии"; СоответствиеВидовСравнения.Добавить().Имя = "НеРавно"; СоответствиеВидовСравнения.Добавить().Имя = "НеСодержит"; СоответствиеВидовСравнения.Добавить().Имя = "Равно"; СоответствиеВидовСравнения.Добавить().Имя = "Содержит"; Для Каждого СтрокаСоответствия Из СоответствиеВидовСравнения Цикл СтрокаСоответствия.Построитель = ПредопределенноеЗначение("ВидСравнения." + СтрокаСоответствия.Имя); СтрокаСоответствия.Компоновка = ПредопределенноеЗначение("ВидСравненияКомпоновкиДанных." + СтрокаСоответствия.Имя); КонецЦикла; мТаблицаЗамеров = Новый ТаблицаЗначений; мТаблицаЗамеров.Колонки.Добавить("_0"); мТаблицаЗамеров.Колонки.Добавить("Ключ"); мТаблицаЗамеров.Колонки.Добавить("ДатаНачала"); мТаблицаЗамеров.Колонки.Добавить("ОтладкаРазрешена", Новый ОписаниеТипов("Булево")); мТаблицаЗамеров.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число")); мИндикаторы = Новый ТаблицаЗначений; мИндикаторы.Колонки.Добавить("КоличествоПроходов", Новый ОписаниеТипов("Число")); мИндикаторы.Колонки.Добавить("ПредставлениеПроцесса", Новый ОписаниеТипов("Строка")); мИндикаторы.Колонки.Добавить("ЛиВыводитьВремя", Новый ОписаниеТипов("Булево")); мИндикаторы.Колонки.Добавить("РазрешитьПрерывание", Новый ОписаниеТипов("Булево")); мИндикаторы.Колонки.Добавить("ДатаНачалаПроцесса", Новый ОписаниеТипов("Дата")); мИндикаторы.Колонки.Добавить("МинимальныйПериодОбновления", Новый ОписаниеТипов("Число")); мИндикаторы.Колонки.Добавить("СледующееОбновление", Новый ОписаниеТипов("Дата")); мИндикаторы.Колонки.Добавить("Шаг", Новый ОписаниеТипов("Число")); мИндикаторы.Колонки.Добавить("ТекстСостояния", Новый ОписаниеТипов("Строка")); мИндикаторы.Колонки.Добавить("СледующийСчетчик", Новый ОписаниеТипов("Число")); мИндикаторы.Колонки.Добавить("Счетчик", Новый ОписаниеТипов("Число")); мИндикаторы.Колонки.Добавить("СледующаяПроверкаПрерывания", Новый ОписаниеТипов("Дата")); //#КонецЕсли мРегВыражение = ирОбщий.НовоеРегВыражениеЛкс(); мРегВыражение.IgnoreCase = Истина; мРегВыражение.MultiLine = Ложь; мРегВыражение2 = ирОбщий.НовоеРегВыражениеЛкс(); мРегВыражение2.IgnoreCase = Истина; мРегВыражение2.MultiLine = Ложь; мИменаОсновныхКлассовБиблиотекCOM = Новый Соответствие; мОбразцыCOMОбъектов = Новый Соответствие; БуферыСравнения = Новый Соответствие; МодальныеГруппы = Новый СписокЗначений; ОтмененныеФоновыеЗадания = Новый Массив; мДобавленныеОбщиеМодули = Новый Структура; мОписаниеТипаМДТабличнаяЧасть = ОписаниеТипаМетаОбъектов("ТабличнаяЧасть"); мОписаниеТипаМДВнешнийИсточникДанных = ОписаниеТипаМетаОбъектов("ВнешнийИсточникДанных"); мРежимПроверкиМодуля = Ложь; мРежимПереходаКОпределению = Ложь; мКэшСловГлобальногоКонтекста = Новый Соответствие; ЛиРежимСовместимости83 = ирКэш.НомерРежимаСовместимостиЛкс() >= 803006; мМодулиМетаданных = Новый Соответствие; мПрямыеВызовыМетодов = Новый Соответствие; мТипыВыражений = Новый Соответствие;