Почему путается порядок строк при печати документов в 1С и как его исправить в запросе?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

При обновлении конфигураций (например, 1С:Управление нашей фирмой) или при печати типовых форм пользователей может встретить неприятная проблема: порядок позиций в печатной форме документа не соответствует порядку строк в его табличной части. Попытки очистить кэш платформы или выполнить тестирование и исправление информационной базы дают лишь временный эффект — для новых документов порядок строк снова сбивается.

Рассмотрим подробно причины такого поведения СУБД и платформы 1С, а также разберем, как правильно скорректировать запрос для получения гарантированной сортировки.

Причина проблемы: поведение СУБД и вложенные таблицы

Проанализируем ситуацию с точки зрения работы баз данных. В языке запросов 1С порядок строк без явно заданного условия сортировки считается произвольным. Системы управления базами данных (Microsoft SQL Server, PostgreSQL и др.) возвращают записи так, как им удобнее в конкретный момент — в порядке размещения на диске, по первичному индексу или с учетом текущего плана выполнения запроса.

После проведения процедуры «Тестирование и исправление» индексы таблицы перестраиваются, и СУБД какое-то время может выдавать данные последовательно. Однако по мере добавления новых документов и фрагментации индексов порядок выдачи записей снова начинает меняться.

Особое внимание стоит обратить на конструкцию запросов, выбирающих данные через синтаксис вложенных таблиц, например ЗаказПокупателя.Запасы.(...). Если в секции УПОРЯДОЧИТЬ ПО указать неуточненное имя поля НомерСтроки, транслятор запросов 1С не сможет корректно сопоставить его со строками вложенных таблиц шапки документа.

Ошибка в конструкции запроса печатной формы

Посмотрим на пример запроса, в котором сортировка задана некорректно для вложенных табличных частей:


ВЫБРАТЬ
	ЗаказПокупателя.Ссылка КАК Ссылка,
	ЗаказПокупателя.Номер КАК Номер,
	ЗаказПокупателя.Работы.(
		НомерСтроки КАК НомерСтроки,
		Номенклатура.Наименование КАК Запас
	),
	ЗаказПокупателя.Запасы.(
		НомерСтроки КАК НомерСтроки,
		Номенклатура.Наименование КАК Запас
	)
ИЗ
	Документ.ЗаказПокупателя КАК ЗаказПокупателя
ГДЕ
	ЗаказПокупателя.Ссылка В(&МассивОбъектов)

УПОРЯДОЧИТЬ ПО
	Ссылка,
	НомерСтроки

В этом варианте условие УПОРЯДОЧИТЬ ПО НомерСтроки игнорируется для вложенных выборок Работы и Запасы, так как реквизита НомерСтроки нет у самого документа-родителя. В результате строки внутри выгруженных таблиц выводятся в хаотичном порядке.

Решение 1. Явное указание полного пути к полю сортировки

Чтобы сортировка сработала для каждой вложенной табличной части, необходимо в секции УПОРЯДОЧИТЬ ПО явно обратиться к реквизитам НомерСтроки соответствующего вложенного поля через точку.

Исправленный вариант запроса выглядит следующим образом:


ВЫБРАТЬ
	ЗаказПокупателя.Ссылка КАК Ссылка,
	ЗаказПокупателя.Номер КАК Номер,
	ЗаказПокупателя.Работы.(
		НомерСтроки КАК НомерСтроки,
		Номенклатура.Наименование КАК Запас
	),
	ЗаказПокупателя.Запасы.(
		НомерСтроки КАК НомерСтроки,
		Номенклатура.Наименование КАК Запас
	)
ИЗ
	Документ.ЗаказПокупателя КАК ЗаказПокупателя
ГДЕ
	ЗаказПокупателя.Ссылка В(&МассивОбъектов)

УПОРЯДОЧИТЬ ПО
	Ссылка,
	ЗаказПокупателя.Запасы.НомерСтроки,
	ЗаказПокупателя.Работы.НомерСтроки

После такого уточнения платформа передает в СУБД корректные инструкции по сортировке внутри каждой вложенной выборки, и порядок строк при печати строго совпадает с табличной частью документа.

Решение 2. Отказ от вложенных таблиц в пользу обращения к табличной части (Рекомендуемый стандарт)

Использование синтаксиса вложенных таблиц в секции ВЫБРАТЬ считается устаревшей практикой разработки. Для гарантированного порядка строк и высокой читаемости кода рекомендуется запрашивать данные табличной части напрямую как самостоятельный источник.

Разберем по шагам построение такого запроса:

  1. Выбираем данные напрямую из табличной части Документ.ЗаказПокупателя.Запасы.
  2. Связываем табличную часть с шапкой документа (при необходимости получить реквизиты шапки).
  3. Задаем прямую сортировку по номеру строки табличной части.

Пример запроса по стандартам разработки 1С:


ВЫБРАТЬ
	ЗаказыЗапасы.Ссылка КАК Ссылка,
	ЗаказыЗапасы.Ссылка.Номер КАК Номер,
	ЗаказыЗапасы.НомерСтроки КАК НомерСтроки,
	ЗаказыЗапасы.Номенклатура.Наименование КАК Запас,
	ЗаказыЗапасы.Количество КАК Количество
ИЗ
	Документ.ЗаказПокупателя.Запасы КАК ЗаказыЗапасы
ГДЕ
	ЗаказыЗапасы.Ссылка В(&МассивОбъектов)

УПОРЯДОЧИТЬ ПО
	Ссылка,
	НомерСтроки ВОЗР

Решение 3. Программная сортировка таблицы значений

Если текст запроса менять нежелательно или механизм формирования печатной формы закрыт, порядок строк можно восстановить программно во встроенном языке 1С перед выводом в макет.

После выполнения запроса выгрузим вложенную выборку или табличную часть в объект ТаблицаЗначений и вызовем метод Сортировать():


// Выгружаем результат выборки в таблицу значений
ТаблицаЗапасов = ВыборкаСтрок.Запасы.Выгрузить();

// Принудительно сортируем по возрастанию номера строки
ТаблицаЗапасов.Сортировать("НомерСтроки ВОЗР");

// Далее производим обход выгруженной таблицы и вывод в область макета
Для Каждого СтрТаблицы Из ТаблицаЗапасов Цикл
	// Заполнение параметров области печатной формы
КонецЦикла;

Резюме

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

← На главную