Почему возникает погрешность в 2 копейки при расчете страховых взносов в 1С и как её исправить?

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

При расчете страховых взносов по пониженным тарифам для субъектов малого и среднего предпринимательства (МСП) многие пользователи столкнулись с неприятной проблемой: в клиент-серверном варианте работы базы данных взносы могли распределяться с погрешностью в 1–2 копейки. В результате подготовленный отчет по расчету по страховым взносам (РСВ) не проходил жесткие контрольные соотношения ФНС, из-за чего сдать его с первого раза становилось невозможно. В этой статье мы подробно разберем природу данной ошибки (зарегистрированной под номером 000069447 на Bugboard 1С и 10223536 в базе ЗУП), выясним, при чем здесь клиент-серверный режим работы, и как решить проблему без кардинального обновления платформы.

Суть технической проблемы: почему косячит клиент-сервер?

Давайте проанализируем ситуацию и разберемся, почему одна и та же конфигурация выдает разные результаты расчета в файловом и клиент-серверном режимах работы. Многим кажется странным, что база данных, развернутая на MS SQL Server или PostgreSQL, считает цифры иначе, чем локальная файловая версия 1CD. Однако физика процесса здесь принципиально отличается.

При расчете страховых взносов для МСП начисления делятся на две части: в пределах МРОТ (облагаются по стандартному тарифу) и свыше МРОТ (облагаются по пониженному тарифу 15%). Для этого внутри конфигурации выполняются сложные запросы со множеством делений, умножений и последующих округлений результатов.

Разница в вычислениях объясняется следующими факторами:

  1. Математические движки СУБД: В файловой базе данных все расчеты выполняются встроенным движком 1С, который строго следует внутренним алгоритмам округления платформы. В клиент-серверном режиме вычисления переносятся на внешнюю СУБД. При делении чисел СУБД (например, Microsoft SQL Server) может использовать типы данных с плавающей точкой по умолчанию, если разработчик в тексте запроса не указал иное.
  2. Неявное приведение типов: Если в теле запроса конфигурации отсутствует жесткое ограничение разрядности чисел, СУБД производит промежуточные вычисления с максимальной точностью (например, до 6 и более знаков после запятой). При последующей передаче этих данных обратно на сервер приложений 1С и попытке округлить их до двух знаков («копеек») возникает микроскопическое расхождение, которое на больших объемах данных выливается в стабильные 1–2 копейки погрешности.

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

Как правильно приводить типы чисел в запросах 1С

Чтобы избежать вольностей со стороны СУБД при расчете округлений, в запросах необходимо использовать конструкцию ВЫРАЗИТЬ. Проанализируем пример кода запроса, в котором может возникать ошибка, и вариант его исправления.

Неправильный вариант (зависит от настроек округления СУБД):


ВЫБРАТЬ
    Начисления.Сотрудник,
    Начисления.БазаПревышения * 0.15 КАК СуммаВзносовПониженная
ИЗ
    РегистрНакопления.Начисления КАК Начисления

В этом случае СУБД вернет результат умножения как число с плавающей точкой, и на сервере 1С округление может сработать некорректно. Чтобы гарантировать одинаковый результат в файловой базе и на MS SQL, запрос необходимо переписать следующим образом:


ВЫБРАТЬ
    Начисления.Сотрудник,
    ВЫРАЗИТЬ(Начисления.БазаПревышения * 0.15 КАК ЧИСЛО(15, 2)) КАК СуммаВзносовПониженная
ИЗ
    РегистрНакопления.Начисления КАК Начисления

Использование конструкции ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 2)) принудительно заставляет СУБД округлить результат до сотых долей непосредственно на этапе выполнения запроса, исключая любые расхождения при передаче данных между клиентом и сервером.

Решение проблемы: нужно ли обновлять платформу?

Отвечая на вопрос автора темы: исправлена ли эта ошибка в платформе 8.3.17.1549? Нет, так как это ошибка прикладного кода (конфигурации), а не самой платформы.

Фирма «1С» оперативно отреагировала на эту проблему в середине 2020 года и выпустила решения, которые не требуют глобального обновления платформы или даже конфигурации:

Поэтому для исправления ошибки расчета СВ вам достаточно обновить конфигурацию до актуального релиза (где этот патч уже интегрирован в основной код) либо подключить интернет-поддержку и разрешить системе автоматически установить исправление EF_10223536.

Другие проблемы разделения контекста на клиенте и сервере

Подобное поведение системы (когда в файловой базе все работает штатно, а в клиент-серверной возникают ошибки) — не редкость в практике разработчика 1С. Рассмотрим еще одну схожую проблему, упомянутую в ходе обсуждения — неподтягивание некоторых мероприятий (например, изменение профессии с кодом «4») в отчет СЗВ-ТД.

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

Если разработчик при формировании СЗВ-ТД допускает обращение к клиентским процедурам или некорректно передает временные таблицы с сервера на клиент без использования промежуточных массивов или структур данных, то серверная часть просто теряет эти данные. В результате табличная часть документа «Регистрация трудовой деятельности» заполняется, но при формировании файла выгрузки отчет оказывается пустым. Такие проблемы также решаются исключительно выпуском обновлений конфигураций, в которых оптимизирована серверная логика сбора сведений.

Резюмируем: Если вы столкнулись с расхождением сумм или неподтягиванием данных в регламентированной отчетности при работе в клиент-серверном варианте, не спешите переустанавливать или обновлять платформу 1С. В 99% случаев проблема кроется в особенностях выполнения запросов СУБД или передаче контекста между клиентом и сервером. Проверьте базу на наличие актуальных патчей конфигурации и установите последние обновления прикладного решения.

← На главную