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

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    178901    992    403    

949

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

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

2 стартмани

06.02.2025    1854    14    XilDen    26    

35

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

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

18.10.2024    12540    sergey279    18    

65

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

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

11.10.2024    7570    XilDen    36    

91

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

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

16.08.2024    10215    user1840182    5    

29

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    3037    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    12205    implecs    6    

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

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

Ну и доработать функцию, которая строит соответствие. Плюс в том, что эта конструкция не затрется, а минус в том, что дополнительное поле не должно повлиять на сам конечный результат вопроса, но оно вроде в большинстве случаев и не повлияет.
sevushka; Yashazz; +2 Ответить
10. Патриот 458 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 7270 25.04.16 18:48 Сейчас в теме
Конструктор запроса из подсистемы "Инструменты разработчика" не затрет такие комментарии.
6. tormozit 7270 25.04.16 18:59 Сейчас в теме
Для тех, кто имеет доступ на партнерский форум 1С, приведу ссылку на одну из тем где это обсуждалось https://partners.v8.1c.ru/forum/topic/1182939
Думаю скоро это добавят в платформе.
7. Yashazz 4829 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 7270 27.04.16 11:49 Сейчас в теме
В следующей версии подсистемы "Инструменты разработчика" будет широкая поддержка имен запросов и частей объединений.
19. zqzq 25 27.04.16 16:49 Сейчас в теме
Я обычно пишу:
последний результат запроса:
МассивРезультатов.Получить(МассивРезультатов.Количество() - 1);

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

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

В том что ты читаешь данные один раз. И возвращаешь результаты нескольких запросов за один раз. А не выполняешь трижды(или сколько у тебя пакетов) чтение из базы.
22. Xershi 1531 27.04.16 17:01 Сейчас в теме
(21) TODD22, т.е. только скорость и не более?
23. TODD22 20 27.04.16 17:02 Сейчас в теме
(22) Xershi, Уменьшение количества обращений к базе.
24. starik-2005 3163 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 7270 03.05.16 19:48 Сейчас в теме
В версии 3.61 подсистемы "Инструменты разработчика" реализовано:

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

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


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

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