Консоль запросов для ЗУП 3.х





Доработка стандартной консоли запросов для работы с механизмом представлений из ЗУП 3.х.

За основу взята стандартная консоль для управляемого приложения с 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), тонкий клиент.  К сожалению, формат публикации не позволяет выложить бесплатно. Надеюсь, приведенное описание позволит легко повторить идею. 

5 Comments

  1. gull22

    Для реализации Вашего желания о бесплатности ответьте на мое сообщение и прикрепите свой файл 🙂

    Reply
  2. evgeni-red

    (1)

    Ваша публикация «Консоль запросов для ЗУП 3.х» была отклонена модератором по причине: Файл необходимо добавить в раздел Файлы. Прочие варианты распространения файлов запрещены, в том числе через личные сообщения. Выставляйте за стартмани.
    Reply
  3. akim2040

    (2) Я вот упустил, в какой момент политика инфостарта стала против бесплатной раздачи наработок и как следствие знаний? Ведь раньше было много бесплатных публикаций

    Reply
  4. evgeni-red

    (3) Боюсь не отвечу на ваш вопрос, но могу предположить, что Инфостарт не против распространения знаний, но с раздачи наработок( в виде вложений) хочет получить свой процент.

    Reply
  5. milov.aleksey

    (3) Добрый день. По-моему с весны 2019 года. Публиковал новую обработку или отчет и тоже не мог выложить бесплатно. Идём по пути капитализма:( Да, платформа, форум перестали меценатствовать. И видеоролики с ликбезом по многим темам переехали на Инфостарт.рф.

    Недавно знакомая бухгалетр спрашивала про настройку раздела Производство в БП3.0 и пришлось рыскать

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *