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