СКД и получение реквизита через точку от поля, выборка которого, находится в подзапросе и это поле привязано к ФО

Допустим у нас есть такой запрос:

select QuantityBalance / isnull ( Balances.Package.Capacity, 1 ) as Balance
from ( select QuantityBalance, Package from AccumulationRegister.Items.Balance ) as Balances

где Package – привязано в функциональной опции Упаковки.

Проблема в том, что если в базе будет выключена ФО Упаковки, СКД в некоторых случаях выбрасывает всё верхнее выражение, в результате чего, поле Balance – будет отсутствовать в выборке и давать ошибки вида “Replacement is not found”, что неверно.

Поле Balance – это значение остатка товара, из выборки исключаться не должно, вне зависимости от того, ведется учет по упаковкам или нет.

Во избежание таких ситуаций (такое поведение наблюдается в сложных запросах без четкой закономерности), запрос должен быть переписан следующим образом:

select QuantityBalance / Capacity as Balance
from ( select QuantityBalance, isnull ( Balances.Package.Capacity, 1 ) as Capacity, Package from AccumulationRegister.Items.Balance ) as Balances

Таким образом, мы помещаем нужное нам поле на уровень источника этого поля.

Другими словами, если нам нужно получить реквизит поля (Capacity) от поля, которое находится под ФО (Package) – нужно получать это поле (Capacity) на том же уровне выборки, где выбирается и само поле (Package).

Данную особенность необходимо учитывать при разработке отчетов на базе СКД.

Вывод полей без права Просмотр

По умолчанию, платформа не позволяет выводить в отчет поля, если у пользователя нет права Просмотр (но при этом право Чтение есть).

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

Решение

Механизм формирования отчетов в конфигурации Core, позволяет решать подобные проблемы.

Для этого, нужно в отчете перехватить событие OnCompose (), и включить нужные поля вручную (они будут выключены платформой, но не удалены).

Пример:

var Params export;

Procedure OnCompose () export

    // Выключение проверки доступности полей
    Params.CheckAccess = false;

    // Включение полей для вывода.
    // В реальной ситуации, здесь должен быть код получения
    // поля по имени с использованием модуля DC
    Params.Settings.Selection.Items [ 1 ].Use = true;

EndProcedure