Как исключить списанные основные средства из печатной формы ИНВ-8а и исправить ошибку сравнения типов в 1С?

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

При доработке инвентаризационных описей (в частности, формы ИНВ-8а по учету драгоценных металлов в основных средствах) разработчики часто сталкиваются с двумя проблемами: попаданием списанных объектов в отчет и аварийным завершением работы программы с ошибкой «Операции сравнения на больше-меньше допустимы только для значений совпадающих примитивных типов».

В этой статье мы подробно проанализируем причины возникновения данных ошибок, разберем исправление логики работы с типами данных и рассмотрим правильные варианты исключения списанных основных средств из выборки запроса.

Причина ошибки сравнения типов и обработка значений NULL

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


Если ОС.Амортизация > 0 Тогда
    // Заполнение секции макета
КонецЕсли;

Если в запросе применяется ЛЕВОЕ СОЕДИНЕНИЕ с виртуальными таблицами (например, с таблицей оборотов регистра накопителя или сведений), а для основного средства соответствующие записи отсутствуют, запрос возвращает значение типа NULL. В языке BSL значение NULL не является числовым типом, поэтому операция вида ОС.Амортизация > 0 приводит к выполнению ошибки сравнения несравнимых типов.

Для решения этой проблемы разберем два подхода.

Подход 1. Преобразование NULL в ноль на уровне запроса

Самый надежный способ — обернуть все соединяемые числовые поля в функцию ЕСТЬNULL() прямо в тексте запроса. В этом случае вместо отсутствующего значения NULL запрос гарантированно вернет число 0:


// В тексте запроса изменяем выборку амортизации и показателей свойств:
ЕСТЬNULL(СтоимостьОСБухгалтерскийУчетОстаткиИОбороты.АмортизацияОборот, 0) КАК Амортизация

Подход 2. Проверка значения на NULL в коде BSL

Если изменить текст запроса нет возможности, следует выполнять проверку заполнености поля перед сравнением с числом в цикле обхода выборки:


Для Каждого ОС Из ВыборкаЗапроса Цикл
    Если ОС.Амортизация <> NULL И ОС.Амортизация > 0 Тогда
        // Обработка данных
    КонецЕсли;
КонецЦикла;

Также для проверки можно использовать встроенную функцию ЗначениеЗаполнено(ОС.Амортизация).

Исправление логической ошибки с приоритетом операторов И и ИЛИ

Проанализируем фрагмент кода, используемый для фильтрации строк перед выводом на печать:


Если ОС.Амортизация > 0 и ОС.КолЗолото <> 0 ИЛИ ОС.КолСеребро <> 0 ИЛИ ОС.КолПлатина <> 0 Тогда
    // Вывод строки
КонецЕсли;

В языке BSL оператор И имеет более высокий приоритет, чем ИЛИ. Из-за отсутствия скобок данное условие вычисляется как (ОС.Амортизация > 0 И ОС.КолЗолото <> 0) ИЛИ ОС.КолСеребро <> 0.... В результате, если у списанного основного средства заполнен хотя бы один драгметалл (например, ОС.КолСеребро <> 0), вся конструкция принимается как ИСТИНА, и проверка амортизации полностью игнорируется.

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


Если ОС.Амортизация > 0 И (ОС.КолЗолото <> 0 ИЛИ ОС.КолСеребро <> 0 ИЛИ ОС.КолПлатина <> 0) Тогда
    // Вывод строки в печатную форму
КонецЕсли;

Методически верное исключение списанных основных средств

Определение факта списания ОС по наличию амортизации (Амортизация > 0) является методологической ошибкой по следующим причинам:

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

Рассмотрим правильные способы исключения списанных объектов на уровне запроса.

Способ 1. Использование регистра сведений «Состояния ОС организаций»

Для получения актуального состояния основного средства выполним соединение с срезом последних регистра сведений СостоянияОСОрганизаций на дату проведения инвентаризации:


ВЫБРАТЬ
    МестонахождениеОС.ОсновноеСредство КАК ОсновноеСредство,
    СостоянияОССрезПоследних.Состояние КАК Состояние
ИЗ
    РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&КонецПериода, Организация = &Организация) КАК МестонахождениеОС
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияОСОрганизаций.СрезПоследних(&КонецПериода, Организация = &Организация) КАК СостоянияОССрезПоследних
        ПО МестонахождениеОС.ОсновноеСредство = СостоянияОССрезПоследних.ОсновноеСредство
ГДЕ
    СостоянияОССрезПоследних.Состояние <> ЗНАЧЕНИЕ(Перечисление.СостоянияОС.СнятоСУчета)

Способ 2. Проверка балансовых остатков по счетам учета ОС

Чтобы убедиться, что объект числится на балансе организации, присоединим виртуальную таблицу остатков регистра бухгалтерии (например, по счету 01.01):


ВЫБРАТЬ
    МестонахождениеОС.ОсновноеСредство КАК ОсновноеСредство,
    ЕСТЬNULL(ХозрасчетныйОстатки.СуммаОстатокДт, 0) КАК ОстаточнаяСтоимость
ИЗ
    РегистрСведений.МестонахождениеОСБухгалтерскийУчет.СрезПоследних(&КонецПериода, Организация = &Организация) КАК МестонахождениеОС
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(
        &КонецПериода,
        Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновныеСредстваНаСкладе),
        ,
        Организация = &Организация
    ) КАК ХозрасчетныйОстатки
        ПО МестонахождениеОС.ОсновноеСредство = ХозрасчетныйОстатки.Субконто1

Применение внутреннего соединения (ВНУТРЕННЕЕ СОЕДИНЕНИЕ) с остатками счета автоматически отсечет все объекты, не имеющие остатка на балансе на указанную дату, исключая списанные основные средства из формируемого отчета.

← На главную