За основу взята стандартная консоль для управляемого приложения с https://its.1c.ru/db/metod8dev/content/4500/hdoc для версии 8.3. Цель доработки - возможность редактирования (создания) отчетов из ЗУП 3.х с использованием механизма представлений в консоли.
Для примера стандартный отчет График Отпусков, в запросе 3 пакета. При попытке выполнить данный запрос в консоли, он возвратит пустой результат, т.к. механизм представлений ЗУП 3.х преобразует временную таблицу Представления_КадровыеДанныеСотрудников в несколько таблиц. Идея доработки - при обращении к конструктору консоли передать текст запроса в ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаВФорме);
Собственно на этом все :). Ниже детали моей реализации:
В консоли запросов добавил реквизит УчестьПредставленияЗУП(булево) и табличную часть ПараметрыЗУП(реквизиты Ключ и Значение)
В процедуру ОткрытьКонструкторЗапроса(Команда) в модуле формы консоли добавил вызов преобразования запроса из общего модуля путем копирования целиком ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаВФорме) плюс обработка параметров и удаление пакетов на уничтожение таблиц. Также изменил немного код в процедуре ДобавитьПараметрВФорму(ПараметрыВФорме, ПараметрСтруктуры)
&НаКлиенте
////
Процедура ОткрытьКонструкторЗапроса(Команда)
ИндексТекущегоЗапроса = ИндексТекущегоВопроса();
Если ИндексТекущегоЗапроса = Неопределено Тогда
ТекстСообщения = НСтр("ru = 'Выберите запрос.'");
СообщитьПользователю(ТекстСообщения, "Объект");
Возврат;
КонецЕсли;
ТекстЗапросаВФорме = СокрЛП(ТекстЗапроса.ПолучитьТекст());
//// + Механизм представлений
Если УчестьПредставленияЗУП И СтрНайти(ТекстЗапросаВФорме, "Представления_") > 0 Тогда
ТекстЗапросаВФорме = ПолучитьТекстНаСервере(ТекстЗапросаВФорме);
КонецЕсли;
//// - Механизм представлений
КонструкторЗапроса = Новый КонструкторЗапроса(ТекстЗапросаВФорме);
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияКонструктораЗапроса", ЭтотОбъект, ИндексТекущегоЗапроса);
КонструкторЗапроса.Показать(Оповещение);
КонецПроцедуры
#Область ДляОбработкиПредставленийЗУП
&НаСервере
Функция ПолучитьТекстНаСервере(ТекстЗапросаВФорме)
//ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаВФорме);
ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаВФорме);
Возврат ТекстЗапросаВФорме;
КонецФункции
&НаСервере
Процедура ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаПриемник, СхемаКомпоновкиДанных = Неопределено) Экспорт
СоответствиеПараметров = Новый Структура;
МассивЗапросов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ТекстЗапросаПриемник, ";");
Для Каждого ТекстЗапроса1 Из МассивЗапросов Цикл
ТекстЗапросаВРег = ВРег(ТекстЗапроса1);
ПозицияСловаПоместить = СтрНайти(ТекстЗапросаВРег, "ПОМЕСТИТЬ ");
Если ПозицияСловаПоместить > 0 Тогда
ПозицияСловаПредставления = СтрНайти(ТекстЗапросаВРег, "ПРЕДСТАВЛЕНИЯ_");
ЭтоОписаниеПредставления = Ложь;
Если ПозицияСловаПредставления > 0
И ПозицияСловаПредставления > ПозицияСловаПоместить Тогда
ЭтоОписаниеПредставления = ПустаяСтрока(Сред(ТекстЗапросаВРег, ПозицияСловаПоместить + СтрДлина("ПОМЕСТИТЬ"), ПозицияСловаПредставления - ПозицияСловаПоместить - СтрДлина("ПОМЕСТИТЬ")));
КонецЕсли;
Если ЭтоОписаниеПредставления Тогда
//Запрос = ПолучитьЗапросПоПредставлению(ТекстЗапроса1, СоответствиеПараметров);
Запрос = ЗарплатаКадрыОбщиеНаборыДанных.ПолучитьЗапросПоПредставлению(ТекстЗапроса1, СоответствиеПараметров);
Если Запрос <> Неопределено Тогда
ТекстЗапросаИсточник = Запрос.Текст;
ИмяИсточникаДанных = ЗарплатаКадрыОбщиеНаборыДанных.ПервоеСловоНачинаяСПозицииВТексте(ТекстЗапроса1, ПозицияСловаПоместить + СтрДлина("ПОМЕСТИТЬ "));
ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьИмяСоздаваемойВременнойТаблицы(ТекстЗапросаИсточник, ИмяИсточникаДанных, СтрЗаменить(ИмяИсточникаДанных, "Представления_", "Представления"));
//ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаИсточник, СхемаКомпоновкиДанных);
ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапросаИсточник, СхемаКомпоновкиДанных);
ТекстЗапросаПриемник = СтрЗаменить(ТекстЗапросаПриемник, ТекстЗапроса1, ТекстЗапросаИсточник);
Если СхемаКомпоновкиДанных <> Неопределено И Запрос.Параметры.Количество() > 0 Тогда
УдаляемыеПараметры = Новый Массив;
Для Каждого КлючИЗначение Из Запрос.Параметры Цикл
ИмяПараметра = КлючИЗначение.Ключ;
Если СтрНайти(ИмяПараметра, "Представления_") = 0 Тогда
Продолжить;
КонецЕсли;
НовоеИмяПараметра = СтрЗаменить(ИмяПараметра, "Представления_", "Представления");
Запрос.Параметры.Вставить(НовоеИмяПараметра, КлючИЗначение.Значение);
УдаляемыеПараметры.Добавить(ИмяПараметра);
КонецЦикла;
Для Каждого УдаляемыйПараметр Из УдаляемыеПараметры Цикл
Запрос.Параметры.Удалить(УдаляемыйПараметр);
КонецЦикла;
Если ТипЗнч(СхемаКомпоновкиДанных) = Тип("Запрос") Тогда
//СкопироватьПараметрыЗапроса(СхемаКомпоновкиДанных, Запрос);
ЗарплатаКадрыОбщиеНаборыДанных.СкопироватьПараметрыЗапроса(СхемаКомпоновкиДанных, Запрос);
ИначеЕсли ТипЗнч(СхемаКомпоновкиДанных) = Тип("ДинамическийСписок") Тогда
ЗарплатаКадрыОбщиеНаборыДанных.СкопироватьПараметрыЗапросаВДинамическийСписок(СхемаКомпоновкиДанных, Запрос);
Иначе
ЗарплатаКадрыОбщиеНаборыДанных.СкопироватьПараметрыЗапросаВСКД(СхемаКомпоновкиДанных, Запрос);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
ИмяИсточникаДанных = ЗарплатаКадрыОбщиеНаборыДанных.ПервоеСловоНачинаяСПозицииВТексте(ТекстЗапроса1, ПозицияСловаПоместить + СтрДлина("ПОМЕСТИТЬ "));
СоответствиеПараметров.Вставить(ИмяИсточникаДанных, Лев(ТекстЗапроса1, ПозицияСловаПоместить - 1));
КонецЕсли;
КонецЕсли;
КонецЦикла;
ТекстЗапросаПриемник = СтрЗаменить(ТекстЗапросаПриемник, "Представления_", "Представления");
//// Параметры представлений
Если Строка(ТипЗнч(Запрос.Параметры)) = "Структура" И Не Запрос.Параметры.Количество() = 0 Тогда
Объект.ПараметрыЗУП.Очистить();
Для Каждого Стр Из Запрос.Параметры Цикл
ТекЭлемент = Объект.ПараметрыЗУП.Добавить();
ТекЭлемент.Ключ = Стр.Ключ;
ТекЭлемент.Значение = Стр.Значение;
КонецЦикла;
КонецЕсли;
//// Удалить запрос уничтожения
ЧислоСтрок = СтрЧислоСтрок(ТекстЗапросаПриемник);
Для Стр = 1 По ЧислоСтрок Цикл
ТекСтрока = СтрПолучитьСтроку(ТекстЗапросаПриемник, Стр);
Если СтрНачинаетсяС(ТекСтрока, "УНИЧТОЖИТЬ ") Тогда
ТекстЗапросаПриемник = СтрЗаменить(ТекстЗапросаПриемник, ТекСтрока + Символы.ПС + ";", "//");
ТекстЗапросаПриемник = СтрЗаменить(ТекстЗапросаПриемник, ТекСтрока + Символы.ПС + Символы.ПС +";", "//");
ТекстЗапросаПриемник = СтрЗаменить(ТекстЗапросаПриемник, ТекСтрока, "//");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
Процедура ДобавитьПараметрВФорму(ПараметрыВФорме, ПараметрСтруктуры)
Значение = ПараметрСтруктуры.Значение;
Тип = ОбъектОбработки().ИмяТипаИзЗначения(Значение);
// Основные реквизиты.
Элемент = ПараметрыВФорме.Добавить();
Элемент.Идентификатор = Новый УникальныйИдентификатор;
Элемент.ИдентификаторЗапроса = ПараметрСтруктуры.ИдентификаторЗапроса;
Элемент.Имя = ПараметрСтруктуры.Имя;
Элемент.Тип = Тип;
//////
Если УчестьПредставленияЗУП И СтрНайти(ПараметрСтруктуры.Имя, "Периоды") <> 0 Тогда
Значение = "{""D"",00010101000000}";
КонецЕсли;
//////
Элемент.Значение = Значение;
Значение = ЗначениеИзСтрокиВнутр(Значение);
// Форменные реквизиты.
Элемент.ТипВФорме = Строка(ТипЗнч(Значение));
//Элемент.ЗначениеВФорме = Значение;
////
Если УчестьПредставленияЗУП Тогда
ОбъектФормы = РеквизитФормыВЗначение("Объект");
НайденнаяСтрока = ОбъектФормы.ПараметрыЗУП.Найти(Элемент.Имя, "Ключ");
Если НайденнаяСтрока <> Неопределено Тогда
Элемент.ЗначениеВФорме = НайденнаяСтрока.Значение;
Иначе
Элемент.ЗначениеВФорме = Значение;
КонецЕсли;
Иначе
Элемент.ЗначениеВФорме = Значение;
КонецЕсли;
////
КонецПроцедуры
Вернемся к запросу из отчета График отпусков. На рисунке ниже запрос до и после обработки представлений:
Параметры подхватываются автоматически:
Получившийся результат в консоли:
В заключение: тестировал в Зарплата и управление персоналом КОРП, редакция 3.1 (3.1.9.159), тонкий клиент. К сожалению, формат публикации не позволяет выложить бесплатно. Надеюсь, приведенное описание позволит легко повторить идею.