Обращение к результатам пакетного запроса по именам

25.04.16

Разработка - Запросы

Пакетный запрос возвращает массив результатов, обращаться к которым можно лишь по индексам. При изменениях запроса индексы сбиваются. Их много. Их трудно помнить и считать, тыкая пальцем по порядку. Упростим себе жизнь!

Используется это так: в тексте запроса, например, рядом с "итоговой" выборкой, результат которой надо будет получить из пакетного запроса, пишется некое ключевое слово и указывается осмысленное имя для этого результата. Например:

ВЫБРАТЬ ДыраВКармане.Виновник ПОМЕСТИТЬ ВТ_КтоКрайний
ИЗ РегистрыРазорения.Убытки(&ДеньПослеКорпоратива) КАК ДыраВКармане;
ВЫБРАТЬ * ИЗ Справочник.VIP КАК Оборзевшие ГДЕ Оборзевшие.Пол = "М";
ВЫБРАТЬ //ИмяРезультата:МояНужнаяВыборка
Крайние.Виновник.Фамилия,
Крайние.Виновник.Адрес,
ИЗ ВТ_КтоКрайний КАК Крайние

Обратим внимание на строку "//ИмяРезультата:МояНужнаяВыборка" - это и есть желаемая маркировка блока в пакете.

Готовый текст запроса (до или после его выполнения, неважно) передаётся этой функции:

// Возвращает соответствие, где ключ - строковое имя результата в пакетном запросе, а значение - его числовой индекс.
// Параметры:
//    тзИсходная - строка, исходный текст запроса, который следует обработать;
//    рМаркер - строка, предваряющая имя результата в исходном тексте запроса.
//
Функция ПостроитьСоответствиеИмёнИНомеровРезультатовПакетногоЗапроса(тзИсходная,рМаркер="")
	соотИмён=Новый Соответствие;
	//
	Если ПустаяСтрока(рМаркер) Тогда рМаркер="//ИмяРезультата:" КонецЕсли;
	рДлинаМаркера=СтрДлина(рМаркер);
	рРазделители="?,=\|:;&"" @#$^!~`'[]{}№+-/*%()<>"+Символы.ВК+Символы.ВТаб+Символы.НПП+Символы.ПС+Символы.ПФ+Символы.Таб;
	//
	тзПлоская=СтрЗаменить(тзИсходная,Символы.ПС,Символы.Таб);
	тзПлоская=СтрЗаменить(тзПлоская,";",Символы.ПС);
	Для й=1 По СтрЧислоСтрок(тзПлоская) Цикл
		стрБлок=СтрПолучитьСтроку(тзПлоская,й);
		пози=Найти(стрБлок,рМаркер);
		Если пози=0 Тогда Продолжить КонецЕсли;
		рДлинаБлока=СтрДлина(стрБлок);
		пози=пози+рДлинаМаркера;
		резИмя="";
		Для ы=пози По рДлинаБлока Цикл
			сим=Сред(стрБлок,ы,1);
			Если Найти(рРазделители,сим)<>0 Тогда Прервать КонецЕсли;
			резИмя=резИмя+сим;
		КонецЦикла;
		Если не ПустаяСтрока(резИмя) Тогда
			соотИмён.Вставить(резИмя,й-1);
		КонецЕсли;
	КонецЦикла;
	//
	Возврат соотИмён;
КонецФункции

После можно работать с полученным соответствием следующим образом:

НужныйРезультат=МассивРезультатов.Получить(соотИмён.Получить("МояНужнаяВыборка")); // ну и можно проверку, получено ли

Собственно, всё. Эта мелочь сильно упрощает работу, если текст запроса часто перетасовывается, меняется, или если в нём более 5-7 "финальных" фрагмента, чьи данные нужны, и компонуется он в разных местах кода. Ведь достаточно появиться одному дополнительному "Выбрать" или "Уничтожить", чтобы ВСЯ нумерация поехала известно куда. А так можно не беспокоиться, которым по счёту идёт получение нужной вам выборки.

Жаль, что разработчики платформы не предусмотрели подобные зарезервированные слова и конструкции в тексте запроса и получение по ним средствами языка. Пришлось эмулировать)

Хотел было сделать через схему запроса (новомодную объектную технику), но - упс, она игнорирует комментарии как таковые. Зато этот подход можно применять и на 8.2, где схем запроса нет в принципе.

Почти наверняка это велосипед, и многие, столкнувшиеся с проблемой раньше меня, уже сделали себе такие "костыльчики", но супруга сказала - публиковать. Вот я и публикую)  Если баян, просьба кинуть в меня тапкой ссылкой.

Кому пригодится, передайте дальше)

пакетный запрос; результат пакетного запроса; парсинг текста запроса;

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    184726    1029    403    

968

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

2 стартмани

06.02.2025    2200    17    XilDen    26    

36

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    5733    artemusII    11    

23

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    13140    sergey279    18    

66

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8220    XilDen    36    

90

СКД Механизмы типовых конфигураций Запросы Программист Платформа 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    3192    PROSTO-1C    0    

23

Запросы Программист Запросы Бесплатно (free)

Отлаживая взаимодействие с базой данных, мы регулярно сталкиваемся с зависающими или подозрительно долго выполняющимися обращениями, негативно влияющими на производительность. О том, как в PostgreSQL выявить подозрительные запросы, основываясь на доступной о них информации, расскажем в статье.

16.08.2024    10801    user1840182    5    

29
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Поручик 4675 25.04.16 15:20 Сейчас в теме
Действительно, стоит добавить запрос в пакет и надо перенумеровывать выборки в коде и потом заново отлаживать.
2. Yashazz 4842 25.04.16 17:35 Сейчас в теме
Ах да, естественно, имя результата должно удовлетворять нотации имён переменных в 1С.
3. karpik666 3952 25.04.16 17:51 Сейчас в теме
Я так понимаю, любое неосторожное использование конструктора запроса затрет эти имена таблиц, не помню только в 1С добавил поддержку комментариев в конструкторе или нет, но идея интересная.
4. Yashazz 4842 25.04.16 18:10 Сейчас в теме
(3) karpik666, затрёт, конечно. Но подобные монструозные запросы уже и не рассчитаны на конструктор. Они собираются по частям, иногда в разных блоках кода, изобилуют нечитаемыми для конструктора кусками, и потому... Терять особо нечего.
TanyTany; +1 Ответить
9. konstruktiv 26.04.16 15:56 Сейчас в теме
(4) круто, а ведь наверное можно "идентификатор" результата в пакете поместить не как комментарий, а в виде фиктивного поля в выборке в самом запросе:
...
;
ВЫБРАТЬ
"МояНужнаяВыборка" КАК IDРезультат,
Крайние.Виновник.Фамилия,
Крайние.Виновник.Адрес ...

или
...
0 КАК ID_МояНужнаяВыборка,
...

Ну и доработать функцию, которая строит соответствие. Плюс в том, что эта конструкция не затрется, а минус в том, что дополнительное поле не должно повлиять на сам конечный результат вопроса, но оно вроде в большинстве случаев и не повлияет.
sevushka; Yashazz; +2 Ответить
10. Патриот 459 26.04.16 18:13 Сейчас в теме
(9) konstruktiv, ну тогда уж лучше фиктивная выборка. Никаких минусов и данных хранить в ней можно сколько душе угодно.
ВЫБРАТЬ
	"Это фиктивный пакет для записи любого количества сведений о нижеидущем пакете, которые не будут стираться конструктором запросов." КАК МаркерФиктивности,
	"МояНужнаяВыборка" КАК ИмяРезультата,
	"любой текст 1" КАК Параметр1,
	"любой текст 2" КАК Параметр2,
	"любой текст 3" КАК Параметр3
;

////////////////////////////////////////////////////////////­////////////////////
Показать
11. PrinzOfMunchen 84 27.04.16 06:12 Сейчас в теме
(10) Патриот, не, тогда уж лучше так
//Пакет основных запросов
..........................................
..........................................
//Служебный запрос
ВЫБРАТЬ РАЗРЕШЕННЫЕ
&КоличествоЗапросовВПакете - 2 Как МойВажныйЗапрос,
&КоличествоЗапросовВПакете - 3 Как МойВлажныйЗапрос,
&КоличествоЗапросовВПакете - 4 Как МойХорошийЗапрос,
&КоличествоЗапросовВПакете - 5 Как ЗапросЛайкаБосс
Показать


А потом

РезультатыЗапроса = Запрос.ВыполнитьПакет();
ВыборкаПакетов = РезультатыЗапросов[РезультатыЗапросов.Количество() - 1].Выбрать();
ВыборкаПакетов.Следующий();

РезультатЗапросаЛайкаБос = ПолучитьРезультатПакетаЗапросовПоИмени(ВыборкаПакетов, "ЗапросЛайкаБосс", РезультатыЗапроса);

....................................................................

Функция ПолучитьРезультатПакетаЗапросовПоИмени(ХранилищеПакетов, ИмяПакета, ПакетРезультатов)

    Возврат ПакетРезультатов[ХранилищеПакетов.ИмяПакета];

КонецФункции

Показать


Ну это если без проверок. )))))
14. konstruktiv 27.04.16 06:53 Сейчас в теме
(11) PrinzOfMunchen, что-то я не разобрался спросонья, получается в последнем запросе опять же нужно вручную указать где какой результат, и при редактировании исходного запроса следить, чтобы эти места соответствовали реальным - от чего и хотел избавиться автор публикации?
15. PrinzOfMunchen 84 27.04.16 07:27 Сейчас в теме
(14) konstruktiv, да. ) Но это так, в порядке бреда, в ответ на пост (10).
А вообще, за всю свою насыщенную 1С-кой жизнь, не натыкался на такой уж огромный запрос, который надо настолько часто редактировать, что можно забить на производительность и пойдя на поводу лени написать такую функцию, вместо того чтобы один раз указать индексы.
13. konstruktiv 27.04.16 06:50 Сейчас в теме
(10) Патриот, тогда при редактировании запроса в конструкторе придется следить за положением запросов для идентификации результатов, быть особенно аккуратным при изменении места запроса в очереди, которая в конструкторе выглядит просто "запрос1/запрос2/.../запросN".
5. tormozit 7273 25.04.16 18:48 Сейчас в теме
Конструктор запроса из подсистемы "Инструменты разработчика" не затрет такие комментарии.
6. tormozit 7273 25.04.16 18:59 Сейчас в теме
Для тех, кто имеет доступ на партнерский форум 1С, приведу ссылку на одну из тем где это обсуждалось https://partners.v8.1c.ru/forum/topic/1182939
Думаю скоро это добавят в платформе.
7. Yashazz 4842 25.04.16 19:49 Сейчас в теме
(6) tormozit, ага, оно самое. Приятно, что не мне одному сие показалось неудобно; спасибо за ссылку.
Честно говоря, вообще впервые имел дело с большим пакетным запросом, раньше как-то везло. А тут... Не вынесла душа поэта))
8. TODD22 20 26.04.16 12:31 Сейчас в теме
(6) tormozit,
Думаю скоро это добавят в платформе.

Из топика по ссылке таких выводов сделать нельзя...
28. Пацталоцци 119 02.09.18 08:33 Сейчас в теме
(6)
Для тех, кто имеет доступ на партнерский форум 1С, приведу ссылку на одну из тем где это обсуждалось https://partners.v8.1c.ru/forum/topic/1182939
Думаю скоро это добавят в платформе.

чёто прошло два с половиной года, а воз и ныне там.
Автору спасибо и плюс, полезная фишка.
29. PerlAmutor 158 29.10.20 06:18 Сейчас в теме
(28) Прошло еще 2 года, появились "ПО ГРУППИРУЮЩИМ НАБОРАМ", "АВТОНОМЕРЗАПИСИ" и возможность использовать временные таблицы в динамических списках, но воз все еще ныне там.
12. NazarovV 87 27.04.16 06:45 Сейчас в теме
Ну раз супруга сказала...) Мне пригодиться, спасибо!
16. МимохожийОднако 142 27.04.16 07:30 Сейчас в теме
Может быть, в каждый выходной запрос добавить поле как идентификатор очередного результата?
17. konstruktiv 27.04.16 10:12 Сейчас в теме
(16) МимохожийОднако, см. 9)
18. tormozit 7273 27.04.16 11:49 Сейчас в теме
В следующей версии подсистемы "Инструменты разработчика" будет широкая поддержка имен запросов и частей объединений.
19. zqzq 25 27.04.16 16:49 Сейчас в теме
Я обычно пишу:
последний результат запроса:
МассивРезультатов.Получить(МассивРезультатов.Количество() - 1);

Предпоследний:
МассивРезультатов.Получить(МассивРезультатов.Количество() - 2);

и т.д., так меньше вероятность словить ошибку, чем если с начала считать, т.к. новые пакеты обычно перед результирующими добавляются и нумерация с конца не сбивается. И с конца в любом случае проще считать.
kiruha; fomstas; SiAl; skif47; +4 Ответить
20. Xershi 1540 27.04.16 16:54 Сейчас в теме
Сегодня наткнулся на такой запрос. Его же сложно понять, в чем специфика? Скорость?
21. TODD22 20 27.04.16 16:58 Сейчас в теме
(20) Xershi,
Его же сложно понять, в чем специфика? Скорость?

В том что ты читаешь данные один раз. И возвращаешь результаты нескольких запросов за один раз. А не выполняешь трижды(или сколько у тебя пакетов) чтение из базы.
22. Xershi 1540 27.04.16 17:01 Сейчас в теме
(21) TODD22, т.е. только скорость и не более?
23. TODD22 20 27.04.16 17:02 Сейчас в теме
(22) Xershi, Уменьшение количества обращений к базе.
24. starik-2005 3171 27.04.16 17:07 Сейчас в теме
(20) Xershi, в базовом функционале последних версий типовых пакетный запрос часто используется для сборки всех движений, Но там грамотно сделано, а не как у автора заметки - там используются функции, возвращающие текст запросов, которые в итоге объединяются в один пакет и за раз отправляются на сервер. Обычно первая часть запроса - это временные таблицы, в которые выбираются ТЧ документа и прочие нужные параметры.

Лично я так бы делать не стал, как в статье описано.
25. sss999 49 27.04.16 20:53 Сейчас в теме
У меня в консоли запросов есть парсинг по именам таблиц может пригодится,сделал для упр форм тоже,раньше были только обычные формы.http://infostart.ru/public/64616/
26. killovolt 257 28.04.16 08:05 Сейчас в теме
На платформе 8.3.8
Во время отладки запросов реализована возможность работы с временными таблицами: просмотр списка временных таблиц, структуры временных таблиц и содержимого временных таблиц.
Реализован метод Запрос.ВыполнитьПакетСПромежуточнымиДанными(). Реализовано свойство МенеджерВременныхТаблиц.Таблицы.
27. tormozit 7273 03.05.16 19:48 Сейчас в теме
В версии 3.61 подсистемы "Инструменты разработчика" реализовано:

Консоль запросов
+Реализовано чтение имен запросов и частей объединений при построении дерева запроса
+Над таблицей результата пакета добавлен флажок "По именам" для вывода только именованных элементов
+Добавлен параметр мРезультатПоИменам обработчика результата для доступа к именованным элементам результата пакета
Конструктор запроса
+Реализована возможность присвоения имен запросам и частям объединений с чтением и сохранением их в комментариях

Пример текста запроса:
//{Запрос: МойЗапрос1 ////////////////////////////////////////
ВЫБРАТЬ
    1 КАК _1
;
//{Запрос: МойЗапрос2 ////////////////////////////////////////
ВЫБРАТЬ
    2 КАК _2
ОБЪЕДИНИТЬ
//{Выборка: МояВыборка1 ////////////////////////////////////////
ВЫБРАТЬ
    5 КАК _2
Показать


На скриншотах показан вид этого текста в дереве запроса консоли запросов и конструкторе запросов.

Пример кода:
РезультатПакета = Запрос.ВыполнитьПакет();
РезультатПоИменам = ПолучитьСтруктуруРезультатаПакетногоЗапроса(Запрос.Текст);
РезультатЗапросаМойЗапрос1 = РезультатПакета[РезультатПоИменам.МойЗапрос1];
Прикрепленные файлы:
mvxyz; RailMen; +2 Ответить
Оставьте свое сообщение