Грызлов Никита | Ведущий программист | Первый БИТ

«Тестирование интеграций между системами»

Онлайн-магазин и УТ, ЗУП и внутренний портал, почта, СКУД. Зоопарк систем и протоколов обмена. Как начать разрабатывать интеграцию без реальной "второй стороны"? Как быть уверенным, что обмен не сломается при следующем обновлении? * Распространенные технологии интеграции - как, с чем и чем интегрируемся * Проблемы, возникающие при разработке и тестировании интеграции * Три уровня тестирования интеграции: * модульное тестирование обработчиков интеграции, применение моков * использование эмуляторов при вызове интеграционных механизмов * тестирование реальных внешних систем * Чем и как может помочь автоматизация тестирования: * тестовые сценарии * запуск и работа эмуляторов * "кликатели" сайтов * "кликатели" прочих программ

Обход запроса по нескольким группировкам

0. zfilin 1937 24.04.12 04:31 Сейчас в теме
Хочу поделиться с вами небольшой "зарисовкой", которая помогает мне обходить выборку запроса, как бы пропуская некоторые группировки.

Перейти к публикации

Вознаграждение за ответ
Показать полностью
Комментарии
Сортировка: Древо
1. zfilin 1937 24.04.12 21:50 Сейчас в теме
В основном блоге коллега советует для данного примера применить к полю "Номенклатура" агрегатную функцию МАКСИМУМ.

Не пробовал, но почему ему не работать?
16. i132 115 28.04.12 16:08 Сейчас в теме
(1) Максимум при группировке по Характеристики не поможет, если есть пустые характеристики.
2. Новиков 289 24.04.12 23:44 Сейчас в теме
Непонятно мне, а почему нельзя подготовить текст запроса таким образом чтобы получить простую выборку для простого обхода вот без этих всех квадратных треуголок? )
3. zfilin 1937 25.04.12 00:01 Сейчас в теме
(2) Новиков, Да, почему ж нельзя? Можно, конечно! Более того, это было бы даже лучше и быстрее.
Но иногда приходится и с треуголками. =)

А предложите свой вариант для такого обхода?
4. Новиков 289 25.04.12 00:06 Сейчас в теме
(3) я признаться, уже забыл, когда руками обходил результат запроса с группировками. Я обычно делаю базовую схему компоновки, и при помощи настроек компоновки (двигаю группировки вверх и вниз) получаю нужный резалт. И уже его как-то обрабатываю. Т.е. даже текст запроса никакого не нужно собирать. А Ваш вариант - он наверное крут, я не спорю. И наверное даже где-то находит применение. Вот и хотелось бы узнать - где! :%)
5. zfilin 1937 25.04.12 00:22 Сейчас в теме
(4) Новиков, А! СКД. Да, я тоже люблю скормить данные СКД, а потом получить их в нужно виде и по ним ходить. Но, вот недавно решил выбрать просто запросом и просто ходить по группировкам без СКД. Как-раз документы создавал. Так и применял.
Глупо было бы утверждать, что это единственный и уникальный способ и я сейчас выдам прям такую исключительную ситуацию, где запрос применить можно, а СКД нельзя.
С другой стороны какое-то внутреннее стремление к простоте протестует против того, чтобы "городить ЦЕЛУЮ СКД", когда надо просто обойти группировки простого запроса. Если бы это было возможно реализовать штатными средствами (как в не работающем примере), это был бы win. А поскольку сами функции получились достаточно "мозгачными", то это, конечно не win, а так - посокрушаться.
15. i132 115 28.04.12 15:34 Сейчас в теме
Если нет пустых характеристик, можно сделать запрос без группирповки итогов и воспользоваться методом Выборка.СледующийПоЗначениюПоля()

Описание метода на ИТС

либо как предложил Новиков в (2) прямой запрос, без группировок остортировать по списку полей шапки:
СтруктураУникальнойШапки = Новый Структура("Поле1,Поле2,Поле3");

Док = Неопределено; //Лучше объявить переменную до цикла, заодно проверим первый вход
Пока выборка.Следующий() Цикл
   ФлНоваяШапка =Ложь;
   Для каждого ПолеШапки из СтруктураУникальнойШапки Цикл
      Если НЕ ПолеШапки.Значение= выборка[ПолеШапки.Ключ] Тогда
		Если Док = Неопределено тогда 
		 	Док.Записать();
		КонецЕсли;	
         ЗаполнитьЗначенияСвойств(СтруктураУникальнойШапки,Выборка);
         Док = СоздатьДокПоШапке(СтруктураУникальнойШапки);
         Прервать;
      КонецЕсли;   
   КонецЦикла;   
   НоваяСтрока = Док.(ТабЧасть).Добавить();
   Док = ЗаполнитьЗначенияСвойств(НоваяСтрока,Выборка);
КонецЦикла;   

Если НЕ Док = Неопределено тогда 
	Док.Записать();
КонецЕсли;
Показать
18. zfilin 1937 28.04.12 18:20 Сейчас в теме
(15) i132, За "СледующийПоЗначениюПоля()" спасибо, нужно будет посмотреть.

А по поводу кода. Мне кажется или у вас там первая строка проглатывается? Когда вы в выборке дважды в подряд "Следующий()" вызываете?
Ну в целом, после первого "Следующий" выборку можно и на начало сбросить, так что принцип понятен.

Но вот именно от такого кода и хочется избавиться в первую очередь. Собственно, эти процедуры я и "затеял", чтобы уйти от "мониторинга момента смены ключа".
Чем мне не нравится такой подход, это во-первых тем, что логика алгоритма несколько "размазывается" по коду. Мы имеем заполнение внутри цикла, создание и запись документа там же, а еще такие же блоки за пределами цикла. Причем, когда мы записываем документ внутри цикла, имеется документ относящийся к предыдущей итерации выборки, а данные в выборке соответствуют уже новому. Все это, что ни говори, повышает сложность кода. Да, что я говорю, думаю все отписавшиеся не раз писали код, который мониторил бы смену одного из полей и в зависимости от этого что-то происходил.
А еще мне очень не нравится то, что код дублируется. Хорошо, когда это одна строка "ЗаполнитьЗначенияСвойств", но когда по смене ключа предусматриваются более обширные действия, блок в начале (до начала цикла) и блок в цикле нужно не забывать обновлять одновременно. Так же как и "Записать()", если нужна не просто запись, а еще какие-то финализирующие действия.
А хочется стройной конструкции, где на одном уровне вложенности документ создавался бы, затем как-то заполнялся (следующая вложенность) и потом на том же уровне и записывался. Без разделения и дублирования.
user597343_netcpv22; i132; +2 Ответить
19. i132 115 28.04.12 19:25 Сейчас в теме
(18) >первая строка проглатывается
упс, спасибо, не заметил действительно обработку первой строки пропустил. старый пост (15) переписал.
6. Yashazz 2256 25.04.12 12:21 Сейчас в теме
Хм, никогда не пользуюсь указанным обходом. Работаю с плоской таблицей значений, можно как угодно выкручивать, сортировать и обходить, безо всяких доп.функций и страшных вложений циклов. В самом хитром случае учреждаются доп.колонки для управления обходом (прям в запросе, или одним обходом таблицы), а дальше рулёжка уже по ним.
Да, и СКД рулит, конечно. Чего её "городить", дело-то простое, а выигрыш иной раз нехилый.
17. Созинов 28.04.12 17:55 Сейчас в теме
(6) Yashazz,
Согласен с вами, но при большом объеме иногда удобнее прогуливаться по иерархии.

Как раз на прошлой неделе столкнулся с такой проблемой, делал перенос с 7.7 на 8.2 (да знаю, что есть куча обработок и Конвертация данных, которую пока не освоил к сожалению), каждый раз делать запросы или сортировать/обходить таблицу со всей номенклатурой, контрагентами и т.д. накладно (хотя какая разница, один раз перенос будет).
Автору + - еще одно интересное решение в копилку, думаю пригодится, хотя использовать буду редко.

(12) romansun,
Спасибо за наводку.
7. dandrontiy 25.04.12 13:00 Сейчас в теме
Круто, но применение непонятно.
И мне почему то удобней не выборками пользоваться, а ТаблицаЗначений = Запрос.Выполнить().Выгрузить();
И мне кажется это к тому же просто быстрее. Как раз применимо для случая, когда надо что-то чем то заполнить, нет разве ?
8. karakozov 25.04.12 13:45 Сейчас в теме
Решение конечно для конкретной задачи, такой подход возможно имеет смысл в ситуации когда таблица имеет очень большой объем.И выбирать ее несколько раз для каждой выборки в рамках одной процедуры очень долго.Может быть конечно так разъяснено что не совсем понятно цель.В общем все от ситуации.
9. Yashazz 2256 25.04.12 16:22 Сейчас в теме
(8) Вопрос знатокам - выборка, полученная из результата запроса методом "Выбрать", или сам результат, кэшируется где-либо или болтается в оперативке? Если да, то в клиентской или где?
10. zfilin 1937 25.04.12 22:18 Сейчас в теме
Друзья, но когда мне нужно обойти плоскую таблицу, мне же нужно понимать момент, когда у меня появляется другой склад в первой колонке, чтобы, если взять уже приведенный пример, создать новый документ с ДРУГИМ складом. Как же это реализовать в плоской выборке?
Т.е. тот случай, когда на разных "уровнях группировок" реализуется разное поведение, разный код.
Gesperid; +1 Ответить
11. zfilin 1937 25.04.12 22:20 Сейчас в теме
Т.е. я сейчас не защищаю свои функции, но интересен сам принцип.
12. romansun 177 26.04.12 11:05 Сейчас в теме
я последнее продолжительное время возвращаю запросом дерево, да, с составным ключом

циклы упрощаются до невозможности

и самое главное масштабирование кода также упрощается в разы! Достаточно изменить состав ключа в запросе - и всё, никакой 1С код в цикле менять не приходится

особенно помогла в этом метода "конвертации" даты в строку прям в запросе для успешного склеивания
veiuper; Gesperid; AllexSoft; invertercant; +4 Ответить
13. MGraf 2 27.04.12 12:14 Сейчас в теме
(12) romansun, напишите пожалуйста публикацию! Хотя бы пару строк с примером :)
AllexSoft; +1 Ответить
20. romansun 177 10.05.12 16:14 Сейчас в теме
(13) ох.. это ж писать надо :)

идея-то, в общем, простая. Вот такой упрощенно пример: есть таблица с кучей колонок (Организация, Контрагент, ДоговорКонтрагента, Номенклатура, Сумма, Количество и т.п.)

Нужно по этим строкам создавать документы, в шапку которых пихать реквизиты (Организация, Контрагент, ДоговорКонтрагента), в ТЧ пихать (Номенклатура, Сумма, Количество).

В запросе создаем поле "Ключ", которое определяем уникальными значениями для соответствующих интересующих нас полей. В нашем примере это "Организация", "Контрагент", "ДоговорКонтрагента". Т.е.

ВЫБРАТЬ
 ВложенныйЗапрос.Организация.Код + ВложенныйЗапрос.Контрагент.Код + ВложенныйЗапрос.ДоговорКонтрагента.Код КАК Ключ
...


(отмечу, что обычно договор это подчиненный справочник к контрагенту со сквозной нумерацией, т.е. все кода уникальны независимо от владельца, посему контрагент в этом ключе не нужен - договора будет достаточно. Но оставим для полноты примера :) )

данное поле "Ключ" будет однозначно уникальным для будущих документов. Т.е. мы получили составной уникальный ключ.

А дальше просто "итожим" по нему

ИТОГИ
   МАКСИМУМ(Организация),
   МАКСИМУМ(Контрагент),
   МАКСИМУМ(ДоговорКонтрагента)
ПО
   Ключ


максимум для этих полей определяем только для того, чтобы получить их в вернем уровне дерева, чтобы потом подставить в наш документ

в 1С-ном коде будет обычный цикл обхода дерева, где по итерации цикла на верхнем уровне создаем новый документ, а по итерациям на втором - заполняем его ТЧ. При этом нам совершенно не надо задумываться создавать ли новый документ на данной итерации цикла, или писать всё еще в предыдущий... и т.п. "приятные" вопросы.

И самое вкусное - если вдруг возникнет необходимость "доразбить" создаваемые документы еще по какому-нить полю, мы просто дописываем его в "Ключ" (например "... + БанковскиеСчета.Код КАК Ключ") и всё.

Таким образом можно делать достаточно сложные ключи. Можно использовать в качестве слагаемых, соответственно, результаты каких-то ВЫБОР КОГДА ТОГДА и т.п.

(14)
Хм. Насколько я понимаю, в запросе можно создать составной ключ склеиванием строк. Но поддерживается ли уникальность при конвертации ссылочных типов в строку? Т.е. вы получаете представление ссылки или просто представление, как наименование, код, НомерДок и т.д?


достаточно просто текстового представления уникального поля (группы полей) - код, наименование и т.п. С числами сложнее, а с датами еще сложнее, ибо их не сложишь как строку, да. А нормальной конвертации в 1С-ных запросах нет. Но числовые коды редко когда бывают, всё-таки. Насчет дат (да и чисел, кстати, тоже) за нас уже всё придумали (23 пост - отлично всё работает)
http://www.forum.mista.ru/topic.php?id=388253

Соответственно, дату (и число) можно представить строкой и приклеить к ключу.
huzden; RadoLex; Daynestro07; MbIwb; 7fortune; Gorr; skalex; Lord_Alexandr; TeMochkiN; slavik_s; python.pm; Mozgolom1988; klinval; DexterMorgan777; MI_HAN; Михаська; YuriFm; swimdog; Angry; AllexSoft; ftm; kayen; DoctorRoza; zfilin; +24 Ответить
14. zfilin 1937 27.04.12 13:43 Сейчас в теме
(12) romansun, Хм. Насколько я понимаю, в запросе можно создать составной ключ склеиванием строк. Но поддерживается ли уникальность при конвертации ссылочных типов в строку? Т.е. вы получаете представление ссылки или просто представление, как наименование, код, НомерДок и т.д?
21. DoctorRoza 17.05.12 09:46 Сейчас в теме
Достаточно интересная статья, написано доходчиво и наглядно, сразу чувствуется высокий уровень автора! Предложенная идея больше смахивает на "лабораторную" раскопку 1С.
22. RainyAugust22 223 12.11.12 07:27 Сейчас в теме
хорошая статья,спасибо за инфу.
23. xomaq 14 12.11.12 08:26 Сейчас в теме
Огромное спасибо автору!!
Как раз сегодня мучился с подобной задачей. С кодом, приведенным автором, у меня все заработало!!
Респект и уважуха!!!
24. kit 65 23.11.12 00:27 Сейчас в теме
Хорошая статья. Тоже сижу разбираюсь с обходом группировок в запросе, а тут как раз в тему.
25. Evgen.Ponomarenko 529 13.08.13 13:01 Сейчас в теме
Действительно, актуально!
26. dimk@a 14.08.13 10:56 Сейчас в теме
Спасибо, хорошая статья. И в обсуждении как всегда много важного!
27. olbu 08.10.15 12:31 Сейчас в теме
А если переделать запрос та вот так:
ВЫБРАТЬ
	ТоварыНаСкладахОстатки.Склад КАК Склад,
	ТоварыНаСкладахОстатки.Номенклатура,
	ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры,
	ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
ИТОГИ
	СУММА(КоличествоОстаток)
ПО
	Склад
Показать


Верхняя группировка будет по складу, а нижняя - по номенклатуре + характеристике.
Или я не верно понял?
28. zfilin 1937 09.10.15 15:46 Сейчас в теме
В таком простом случае, да сработает. Но это все же немного не то.
А если две составных группировки?
Например склад+контрагент и товар+характеристика.
29. EvgeniuXP 04.02.16 23:14 Сейчас в теме
Вот вам применение: есть документы, там 13 реквизитов, надо выявить одинаковые документы, если их два и более то один провести, остальные пометить на удаление. Методом группировок мы отсеиваем одинаковые, оставляем только одинаковые два и более документа, потом группируем по всем 13 реквизитам и на выходе имеем на самом нижнем уровне одинаковые записи двух и более документов. При первом входе проводим, при втором и последующих - метим на удаление.
30. iott 09.01.17 03:29 Сейчас в теме
Полезная статья по группировкам! Мне оказалась полезной!

Получается, что на уровне выборки по складу номенклатуры еще нет, а на уровне выборки по характеристике ее... все еще нет. Бида.

"Бида."....тут опечатка или так задумано? =)
31. zfilin 1937 10.01.17 16:17 Сейчас в теме
32. i.kovtun 135 29.07.17 12:38 Сейчас в теме
Саша, спасибо :) Быстро загуглилось и пригодилось!
33. zfilin 1937 05.08.17 00:34 Сейчас в теме
(32) О, приветствую! Ну, вот, хорошо что пригодилось. Я когда-то полголовы себе об это сломал. Значит не зря.
Оставьте свое сообщение
Все разделы

Вакансии


Программист 1С
Москва
зарплата от 100 000 руб. до 200 000 руб.
Полный день

Преподаватель 1С
Санкт-Петербург
Полный день

Удаленный ИТ-журналист
Санкт-Петербург
По совместительству

Программист 1С
Санкт-Петербург
зарплата от 80 000 руб. до 150 000 руб.
Полный день