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