СКД и получение реквизита через точку от поля, выборка которого, находится в подзапросе и это поле привязано к ФО¶
Допустим у нас есть такой запрос:
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