В процессе эксплуатации платформы 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-кода, которые привели к потере точности промежуточных вычислений.
Проанализируем техническую сторону вопроса. Согласно официальному баг-трекеру 1С, в версии 8.3.15 была допущена ошибка в логике работы с арифметическими операциями в языке запросов. При использовании деления совместно с другими операциями (умножением, сложением) точность промежуточного результата стала отличаться от поведения предыдущих версий платформы.
Основные аспекты ошибки:
Numeric.ВЫРАЗИТЬ(... КАК ЧИСЛО(20, 10)), мы фактически заставляем систему зафиксировать эту микроскопическую погрешность. При последующем округлении до целого в интерфейсе или при логическом сравнении (например, "Если Процент < 100") система интерпретирует 99.9999 как 99.Рассмотрим два основных пути решения данной задачи: радикальный (обновление) и программный (обход ошибки в коде).
Самый правильный и надежный способ — это установка исправленного релиза платформы. Ошибка 000055388 была официально исправлена. Рассмотрим, на какие версии необходимо ориентироваться:
Как показывает практика, после обновления платформы до 8.3.15.1534 расчеты в динамических списках заказов приходят в норму без изменения программного кода конфигурации.
Если по каким-то причинам оперативное обновление платформы невозможно, проанализируем, как можно изменить запрос, чтобы минимизировать риск возникновения погрешности. Рассмотрим несколько приемов:
(Число1 * 100) / Число2 обычно точнее, чем Число1 / Число2 * 100.
ВЫРАЗИТЬ(Результат КАК ЧИСЛО(15, 2)).
Стоит отметить, что релиз 8.3.15.1489 оказался богат на неприятные сюрпризы. Помимо проблем с расчетами в запросах, пользователи часто сталкивались с ошибкой при сохранении печатных форм в формат Excel. При попытке сохранить табличный документ возникало сообщение: "Удаленный компонент: Рисованная фигура".
Эта проблема (Bug ID 000055395) также связана с некорректной работой платформы с объектами графики в памяти. Она исправлена в тех же релизах, что и ошибка с точностью вычислений (начиная с 8.3.15.1534). Таким образом, обновление платформы решает сразу целый комплекс критических проблем.
Подводя итог, можно сказать, что появление "99%" вместо "100%" — это классический пример того, как изменения в низкоуровневых механизмах платформы могут повлиять на бизнес-логику прикладных решений. Если вы столкнулись с подобным поведением:
Мы проанализировали ситуацию и выяснили, что современные конфигурации 1С крайне чувствительны к точности типов данных, поэтому поддержка платформы в актуальном состоянии является залогом корректного отображения данных в учете.