Итераторы выборки

Программирование - Практика программирования

Обход результата запроса Выбрать Результат запроса Следующий по значению поля

9
Обход результата запроса можно сделать по группировкам и по полям. В первом случае используются итоговые записи, во втором - линейный список. Еще можно обходить коллекцию элементов строк, однако в этом случае никаких дополнительных средств обхода, кроме детального, платформа не предоставляет. В статье рассматривается решение, расширяющее возможности стандартных средств обхода результата запроса, а также применимое для обхода коллекции строк.

Оглавление

Постановка проблемы.. 1

Обход элементов по шаблону проектирования Итератор. 1

Реализация шаблона Итератор. 1

Описание подсистемы.. 1

Примеры использования. 1

Производительность. 1

Вывод. 1

Постановка проблемы

Обход выборки из результата запроса по группировкам можно выполнить двумя способами: с итогами или без итогов. В первом случае необходимо в запросе указать поля группировки и итогов. Обход элементов выборки в этом случае осуществляется методом Следующий(). Во 2-м - достаточно получить линейный список и выполнить обход элементов выборки с помощью метода СледующийПоЗначениюПоля(). В обоих случаях обход элементов необходимо выполнять с использованием вложенных циклов, каждый уровень которых будет соответствовать обходу по одному полю группировки. Последнее обстоятельство может быть очень неудобным: приводит к громоздкому коду со вложенными циклами, значительно усложняет алгоритмы выборки, когда заранее неизвестен состав и порядок полей группировки.

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

Шаблон проектирования Итератор решает проблему обхода элементов коллекции без использования методов самой коллекции. Удобство шаблона в том, что он предоставляет единый интерфейс обхода элементов без привязки к типу данных коллекции.

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

Использование шаблона Итератор значительно упрощает алгоритмы обхода элементов коллекций. Следующим шагом будет реализация такого итератора на языке 1С.

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

Структура итератора:

  • ТекущиеДанные - ВыборкаИзРезультатаЗапроса, СтрокаТаблицыЗначений - структура для получения данных итератора

  • Источник - РезультатЗапроса, ВыборкаИзРезультатаЗапроса, Таблица

  • ПоляГруппировки - Массив - имена полей группировки

  • ИспользоватьИтоги - Булево - признак использования варианта обхода ПоГруппировкам для выборки из результата запроса

Основная функция работы с итератором: Следующий(СтруктураИтератора). Функция возвращает Истина, если Итератор спозиционировался на следующем элементе и Ложь - если предыдущее значение было последним.

В подсистему входит один общий модуль РаботаСИтератором. Модуль реализует функции

  • ПолучитьСтруктуруИтератораВыборки
  • СледующийИз*

Рисунок 1. Обработка стенд, реализующая различные алгоритмы обхода.

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

Типичные алгоритмы с использованием итератора и без представлены на следующих листингах.

Листинг 1. Реализация обхода с использованием итератора

Листинг 2. Реализация обхода с использованием вложенных циклов

Рисунок

Рисунок 2. Сравнительный график времени выполнения различных алгоритмов обхода выборки из 2000 элементов, среднее время на 20 измерениях.

Реализация алгоритмов обхода выборки эквивалентна реализации через использование вложенных циклов. Дополнительные затраты связаны с проверками из-за универсальности реализации.

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

В целом нельзя сказать, что производительность в данном случае фатально низкая. Многое зависит от условий задачи, размера выборки. У меня получилось, что обход с использованием итератора раз в 6-8 медленнее, чем через использование вложенных циклов. Анализ потерь производительности выявил, что потери сопоставимы с затратами на операторы проверки, чтения переменных и полей вспомогательной структуры (речь идет о микросекундах).

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

На мой взгляд решение получилось красивое. Однако оно не безупречно, производительность решения по сравнению с классическим подходом оказалось меньше в несколько раз. Там где это возможно, решение использовать классический подход будет определяться в том числе и вопросом производительности. В тех же случаях, когда производительность не будет являться критическим фактором, решение вполне может себя оправдать за счет упрощения алгоритмов.

Принцип реализации шаблона проектирования Итератор на 1С универсален и его можно распространить и на другие алгоритмы обхода чего бы то ни было.

9

Скачать файлы

Наименование Файл Версия Размер
Работа с итератором
.cf 17,04Kb
15.05.18
4
.cf 1.01 17,04Kb 4 Скачать

См. также

Комментарии
Избранное Подписка Сортировка: Древо
1. МихаилМ 16.05.18 14:48 Сейчас в теме
2к - очень маленькая выборка . тк 36мс велика погрешность замера . сделайте 100к из тз в пз.
также интересна обработка тз по тз в пз + Ваш итератор.
6. kalyaka 396 16.05.18 16:13 Сейчас в теме
(1) не вижу смысла. Алгоритмически зависимость времени линейная. Для уменьшения погрешности я использовал среднее значение по 20 измерениям
2. HAMMER_59 72 16.05.18 15:23 Сейчас в теме
Так я и не понял, для чего все эти танцы с бубном.

Не хватает возможностей объекта запрос - используйте СКД.
Никаких проблем не составляет таблицу значений передать в СКД.
5. МихаилМ 16.05.18 16:09 Сейчас в теме
(2) если из скд получать из , то это медленный способ обрабртки если использовать ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений
7. kalyaka 396 16.05.18 16:21 Сейчас в теме
(2) идея статьи не в многообразии решений, а в едином подходе к решению разнообразных задач обхода коллекций.

Ваше решение вполне можно применить в рамках шаблона. Если оно действительно эффективно, то это имеет смысл и при этом те решения, которые уже используют итератор автоматически без переписывания станут работать быстрее.
3. МихаилМ 16.05.18 16:00 Сейчас в теме
"Однако существует способ свести задачу обхода из таблицы значений к обходу элементов выборки из результата запроса, использовав временную таблицу" -
ерунда . тк построитель запроса (пз) преобразует тз в выборку без временных таблиц. исправьте статью.
8. kalyaka 396 16.05.18 16:23 Сейчас в теме
(3) я имел в виду использование для обхода таблицы по группировкам выборку из запроса
4. neikist 16.05.18 16:08 Сейчас в теме
Одна из причин почему не хватает ООП в платформе - невозможность удобно писать подобные вещи не через одно место.
10. HAMMER_59 72 17.05.18 07:16 Сейчас в теме
(4) ИМХО когда говорят, что в 1С очень не хватает ООП, рассматривают далека не все аспекты, а только некоторые случаи, где ООП пригодилось бы.

Уже сейчас даже с типовыми конфигурациями работать стало довольно сложно.
Вчера разбирался с задачей: нужно было чтобы при выгрузки бухгалтерских счетов с аналитикой из БП в ЗиК, не помечались на удаления раннее загруженные счета с аналитикой.
Вроде все понятно - нужно подправить правила. И правило то понятно где лежат.
Пытаюсь пойти самым простым путем. Добавляю расширение, в расширение добавляю нужный макет. Макет добавился но доступа на редактирование нет.
Ладно замещаю функцию, которая получаем макет - 1С начинает вылетать с ошибкой.
Сохраняю обработку как внешнюю. Меняю макет - выгрузка не меняется. Начинаю разбираться - макет получает не из обработки, а напрямую обращением к метаданным. Не проблема - меняю кусок кода. Все равно не получается.
Разбираюсь дальше, а дальше становится понятно, что используется другая обработка, это все еще накладывается на особенности управляемых форм.
Можно сказать что 1С-ники чуть-чуть применили самый что не на есть настоящий ООП. Лучше стало?
Для разработчиков, думаю, что да.
А теперь представим что ООП будет не чуть-чуть, т.е. в типовых конфигурациях будут присутствовать не всем нам знакомые объекты, а просто море новых совершенно незнакомых нам объектов.
11. neikist 17.05.18 14:20 Сейчас в теме
(10) Ну так зато можно будет применять кучу удобных вещей, управлять зависимостями компонентов. Интерфейсов из ООП не хватает, инкапсуляции небольших структур с буквально парой методов... В общем хочется, очень хочется.
Артано; +1 Ответить
Оставьте свое сообщение