При работе с запросами в системе 1С:Предприятие разработчики часто используют конструкцию выбора табличных частей через точку от ссылки (так называемые вложенные таблицы). Типичный пример такого запроса можно встретить в типовых конфигурациях, таких как 1С:Управление нашей фирмой (УНФ). Однако возникает неприятная особенность: добавление предложения УПОРЯДОЧИТЬ ПО в конце запроса с указанием поля НомерСтроки вложенной таблицы не дает ожидаемого результата. Строки внутри полученной коллекции остаются в произвольном порядке или в порядке их физического добавления в базу, игнорируя инструкцию сортировки.
В этой статье мы подробно разберем, почему так происходит, проанализируем механизмы работы платформы и рассмотрим несколько эффективных способов решения этой задачи.
Давайте проанализируем ситуацию с точки зрения архитектуры СУБД и платформы 1С. Когда мы пишем запрос вида ВЫБРАТЬ Ссылка, Запасы.(НомерСтроки, Номенклатура) ИЗ Документ.ЗаказПокупателя, платформа не создает один плоский набор данных. Она формирует иерархическую структуру.
Основная причина отсутствия сортировки заключается в следующем:
УПОРЯДОЧИТЬ ПО определяет порядок следования записей основного результата запроса. В нашем случае основной записью является ссылка на документ ЗаказПокупателя. Платформа отсортирует сами документы, но не содержимое объекта «вложенная таблица», который является лишь полем в этой записи.ВЫБРАТЬ просто не поддерживает).Работы и Запасы), и в конце указано УПОРЯДОЧИТЬ ПО НомерСтроки, возникает конфликт имен. Платформа не может понять, к какой именно таблице относится этот номер строки для сортировки основного списка документов.Рассмотрим пример кода, который часто вызывает вопросы:
ВЫБРАТЬ
ЗаказПокупателя.Ссылка КАК Ссылка,
ЗаказПокупателя.Запасы.(
НомерСтроки КАК НомерСтроки,
Номенклатура КАК Номенклатура,
Количество КАК Количество
) КАК ТаблицаЗапасы
ИЗ
Документ.ЗаказПокупателя КАК ЗаказПокупателя
ГДЕ
ЗаказПокупателя.Ссылка = &ЗаказПокупателя
УПОРЯДОЧИТЬ ПО
Ссылка,
НомерСтроки
В данном примере НомерСтроки в секции УПОРЯДОЧИТЬ ПО будет либо проигнорирован в контексте содержимого ТаблицаЗапасы, либо вызовет ошибку, так как поле не принадлежит верхнему уровню выборки. Выясним, как обойти это ограничение.
Самый надежный и производительный способ получить отсортированные строки — это отказаться от вложенных таблиц и обратиться напрямую к табличной части документа. Рассмотрим, как переписать запрос по шагам:
Вместо выбора документа, выберем данные из таблицы Запасы. В этом случае каждая строка табличной части станет отдельной записью основного результата запроса, и стандартная сортировка сработает идеально.
ВЫБРАТЬ
Запасы.Ссылка КАК Ссылка,
Запасы.НомерСтроки КАК НомерСтроки,
Запасы.Номенклатура КАК Номенклатура,
Запасы.Количество КАК Количество
ИЗ
Документ.ЗаказПокупателя.Запасы КАК Запасы
ГДЕ
Запасы.Ссылка = &ЗаказПокупателя
УПОРЯДОЧИТЬ ПО
Ссылка,
НомерСтроки
Преимущества этого метода:
Если специфика вашей задачи (например, сложная печатная форма или интеграция) требует сохранения структуры с вложенными таблицами, мы можем применить сортировку программно. Метод Выгрузить() для результата запроса позволяет получить таблицу значений, в колонках которой будут находиться другие таблицы значений (вложенные).
Проанализируем пример обхода и сортировки:
РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультат = РезультатЗапроса.Выгрузить();
Для Каждого СтрокаДокумент Из ТаблицаРезультат Цикл
// Получаем вложенную таблицу из колонки
ТаблицаЗапасы = СтрокаДокумент.ТаблицаЗапасы;
// Сортируем её по номеру строки или любому другому полю
ТаблицаЗапасы.Сортировать("НомерСтроки Возр");
// Теперь данные внутри строки отсортированы
КонецЦикла;
Этот способ удобен тем, что вы сохраняете иерархическую структуру данных, но платите за это дополнительным временем на итерацию по строкам и перестроение коллекций в памяти сервера.
Если вы разрабатываете отчет или форму, использующую Схему компоновки данных, проблема вложенных таблиц решается самой системой автоматически. В СКД рекомендуется использовать Связи наборов данных.
Рассмотрим алгоритм действий в СКД:
Ссылка.Набора данных 2 указываем нужную сортировку в стандартной вкладке Сортировка.Система компоновки данных сама сформирует правильные пакеты запросов и обеспечит корректный порядок вывода строк для каждой родительской записи.
Стоит отметить, что в некоторых типовых запросах 1С (в том числе в УНФ) поле НомерСтроки все же включают в секцию УПОРЯДОЧИТЬ ПО. Зачем это делается, если сортировка не работает? Часто это "задел" для Построителя отчета или Построителя выходных форм. Эти механизмы могут анализировать текст запроса и автоматически применять настройки сортировки к результату, если он обходится определенным образом. Однако при обычном программном выполнении Запрос.Выполнить().Выбрать() надеяться на это не стоит.
Мы выяснили, что вложенные таблицы в запросах 1С — это удобный инструмент для получения иерархии, но они крайне ограничены в вопросах управления порядком строк. Для решения проблемы сортировки:
Сортировать() к выгруженной таблице значений, если работаете в коде.Помните, что правильное структурирование запроса на начальном этапе избавляет от необходимости "допиливать" результат программно, что положительно сказывается на производительности системы.