Почему в 1С 8.3.15 проценты в заказах отображаются как 99% вместо 100% и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В процессе эксплуатации платформы 1С:Предприятие 8.3.15 (в частности релиза 8.3.15.1489) многие специалисты столкнулись с необъяснимым поведением системы при расчете финансовых показателей в динамических списках и отчетах. Типичный сценарий: в конфигурациях «Управление торговлей 11», «ERP» или «Комплексная автоматизация» в форме списка заказов клиентов поля Процент оплаты или Процент отгрузки внезапно начинают принимать значение 99, хотя фактически документ полностью оплачен и отгружен на 100%.

Проанализируем ситуацию: расчеты выполняются корректно в модулях менеджера, данные в регистрах верны, но результат запроса выдает число с бесконечной дробной частью, например 99,99999888. В этой статье мы подробно разберем причины такого поведения, связанные с особенностями работы ядра платформы 8.3.15, и рассмотрим способы решения данной проблемы.

Анализ программного кода и условий возникновения ошибки

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


ВЫБОР
    КОГДА
        ДокументЗаказКлиента.ПорядокРасчетов = ЗНАЧЕНИЕ(Перечисление.ПорядокРасчетов.ПоЗаказамНакладным) И
        ДокументЗаказКлиента.Проведен И
        ДокументЗаказКлиента.СуммаДокумента > 0
    ТОГДА
        ВЫРАЗИТЬ((ЕСТЬNULL(РасчетыСКлиентамиОстатки.КОплатеРасход, 0)) * 100 / ДокументЗаказКлиента.СуммаДокумента КАК ЧИСЛО(20, 10))
    ИНАЧЕ
        0
КОНЕЦ КАК ПроцентОплаты

В данной конструкции мы видим попытку вычислить долю оплаты. Обратите внимание на использование функции ВЫРАЗИТЬ с высокой точностью (10 знаков после запятой). Проблема заключается в том, что при выполнении этой операции на определенных релизах платформы результат деления в SQL-запросе получается нецелым числом из-за накопленной погрешности, даже если делимое точно равно делителю.

Выясним причину: почему в консоли запросов результат может быть 100, а в реальной работе системы — 99? Это связано с тем, как платформа 1С транслирует запрос в инструкции для СУБД (MS SQL Server, PostgreSQL). В версии 8.3.15 были внедрены изменения в механизм генерации SQL-кода, которые привели к потере точности промежуточных вычислений.

Техническая причина: Ошибка платформы (Bug ID 000055388)

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

Основные аспекты ошибки:

  1. Неявное приведение типов в СУБД: Платформа стала иначе определять типы данных для промежуточных итогов в SQL. Если в старых версиях 1С жестко контролировала масштаб (количество знаков после запятой), то в 8.3.15 выполнение части расчетов было переложено на СУБД с потерей контроля над точностью Numeric.
  2. Погрешность при делении: В SQL Server результат деления получает тип данных, точность и масштаб которого рассчитываются по сложным формулам. В результате число 100 / 1 превращается в 99.9999999999...
  3. Влияние функции ВЫРАЗИТЬ: Когда мы используем ВЫРАЗИТЬ(... КАК ЧИСЛО(20, 10)), мы фактически заставляем систему зафиксировать эту микроскопическую погрешность. При последующем округлении до целого в интерфейсе или при логическом сравнении (например, "Если Процент < 100") система интерпретирует 99.9999 как 99.

Способы решения проблемы

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

Решение 1: Обновление платформы (Рекомендуемое)

Самый правильный и надежный способ — это установка исправленного релиза платформы. Ошибка 000055388 была официально исправлена. Рассмотрим, на какие версии необходимо ориентироваться:

Как показывает практика, после обновления платформы до 8.3.15.1534 расчеты в динамических списках заказов приходят в норму без изменения программного кода конфигурации.

Решение 2: Корректировка логики запроса

Если по каким-то причинам оперативное обновление платформы невозможно, проанализируем, как можно изменить запрос, чтобы минимизировать риск возникновения погрешности. Рассмотрим несколько приемов:

  1. Изменение порядка операций: Математически выгоднее сначала выполнять умножение, а затем деление. Это позволяет работать с большими числами в целой части до появления дроби.
    (Число1 * 100) / Число2 обычно точнее, чем Число1 / Число2 * 100.
  2. Снижение точности в ВЫРАЗИТЬ: Нет смысла вычислять процент оплаты с точностью до 10 знаков, если для бизнеса важны только целые единицы. Попробуем ограничить точность двумя знаками:
    ВЫРАЗИТЬ(Результат КАК ЧИСЛО(15, 2)).
  3. Использование функции ОКРУГЛИТЬ: В некоторых случаях в запросах (если это поддерживается конфигурацией) или при обработке результата в коде 1С следует использовать явное округление.

Сопутствующие проблемы релиза 8.3.15.1489

Стоит отметить, что релиз 8.3.15.1489 оказался богат на неприятные сюрпризы. Помимо проблем с расчетами в запросах, пользователи часто сталкивались с ошибкой при сохранении печатных форм в формат Excel. При попытке сохранить табличный документ возникало сообщение: "Удаленный компонент: Рисованная фигура".

Эта проблема (Bug ID 000055395) также связана с некорректной работой платформы с объектами графики в памяти. Она исправлена в тех же релизах, что и ошибка с точностью вычислений (начиная с 8.3.15.1534). Таким образом, обновление платформы решает сразу целый комплекс критических проблем.

Заключение

Подводя итог, можно сказать, что появление "99%" вместо "100%" — это классический пример того, как изменения в низкоуровневых механизмах платформы могут повлиять на бизнес-логику прикладных решений. Если вы столкнулись с подобным поведением:

Мы проанализировали ситуацию и выяснили, что современные конфигурации 1С крайне чувствительны к точности типов данных, поэтому поддержка платформы в актуальном состоянии является залогом корректного отображения данных в учете.

← На главную