При работе с запросами в 1С:Предприятие программисты часто сталкиваются с ситуацией, когда числовые данные, имеющие в базе данных высокую точность (например, 5 знаков после запятой), после выполнения запроса отображаются округленными до 2 знаков. Это создает иллюзию потери данных, особенно когда используется агрегатная функция СУММА или оператор ВЫРАЗИТЬ. Проанализируем, почему это происходит и как убедиться в сохранности данных.
Прежде всего, нам необходимо проверить определение реквизита в конфигураторе. Если в метаданных документа (например, РеализацияТоваровУслуг) для реквизита Количество установлено значение "15, 2", то никакие манипуляции в тексте запроса не помогут восстановить точность. Система SQL просто не хранит те знаки, которые не предусмотрены структурой таблицы. Если же в метаданных указано "15, 5", данные в базе хранятся верно, и проблема кроется в механизмах извлечения и представления.
Рассмотрим типичный запрос, вызывающий вопросы у разработчиков:
ВЫБРАТЬ
РеализацияТоваровУслугТовары.Номенклатура.ГлавнаяНоменклатура КАК ГЛНоменклатура,
ВЫРАЗИТЬ(СУММА(РеализацияТоваровУслугТовары.Количество) КАК ЧИСЛО(15, 5)) КАК Количество,
СРЕДНЕЕ(РеализацияТоваровУслугТовары.Цена) КАК Цена
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ГДЕ
РеализацияТоваровУслугТовары.Ссылка = &Ссылка
СГРУППИРОВАТЬ ПО
РеализацияТоваровУслугТовары.Номенклатура.ГлавнаяНоменклатура
В данном примере использование ВЫРАЗИТЬ(СУММА(...) КАК ЧИСЛО(15, 5)) является корректным с точки зрения типизации результата. Однако важно понимать: число в 1С — это не строка. Оно хранит значение, а не количество нулей в конце. Если результат суммы равен 10.5, то платформа будет считать его как 10.5, а не как 10.50000.
Одной из самых частых причин паники разработчика является окно "Вычислить выражение" в отладчике. Проанализируем ситуацию: вы смотрите на значение переменной после выполнения запроса и видите "10,99". Означает ли это, что данные обрезаны? Не всегда.
Отладчик 1С часто использует стандартные системные установки для вывода чисел. Он может скрывать незначащие нули или использовать региональные настройки Windows для форматирования. Чтобы увидеть реальное содержимое переменной, воспользуемся функцией Формат прямо в окне отладчика:
Формат(ЗначениеИзЗапроса, "ЧЦ=15; ЧДЦ=5; ЧГ=0")
Если после применения этого формата вы увидите "10,99000", значит, число в памяти 1С хранится с полной точностью, и проблема заключается исключительно в визуализации.
Когда мы используем функцию СУММА, платформа автоматически определяет тип результата на основе исходного поля. Рассмотрим два сценария:
Количество имеет точность 5, то и результат СУММА(Количество) будет иметь точность 5.ВЫРАЗИТЬ(СУММА(...) КАК ЧИСЛО(15, 5)), вы жестко ограничиваете тип, выполняя арифметическое округление по правилам СУБД.Посмотрим на пример: если сумма фактически равна 10.999994, то после ВЫРАЗИТЬ(... КАК ЧИСЛО(15, 5)) она превратится в 10.99999. Если же исходные данные уже имели 2 знака, то ВЫРАЗИТЬ просто добавит "виртуальные" нули, которые не отображаются без принудительного форматирования.
Чтобы окончательно убедиться, что запрос возвращает нужный тип данных, мы можем выгрузить результат запроса в ТаблицуЗначений и программно проверить квалификаторы числа. Рассмотрим код:
РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультат = РезультатЗапроса.Выгрузить();
// Проверим описание типа колонки "Количество"
ОписаниеТипа = ТаблицаРезультат.Колонки.Количество.ТипЗначения;
КвалификаторыЧисла = ОписаниеТипа.КвалификаторыЧисла;
Сообщить("Допустимая точность: " + КвалификаторыЧисла.ДесятичныеЗнаки);
Если в сообщении вы увидите "5", значит, колонка таблицы значений жестко типизирована под 5 знаков. Любое "обрезание", которое вы видите в формах или отчетах — это лишь вопрос представления (оформления).
Если нам необходимо, чтобы пользователь видел все 5 знаков (включая нули), мы должны управлять форматом вывода. Рассмотрим основные способы:
ЧДЦ=5. Это заставит систему всегда выводить 5 знаков после запятой, заполняя пустоты нулями.ВЫРАЗИТЬ из запроса, если в настройках самого поля указан другой формат.Формат(), если число нужно вставить в текстовое сообщение.Подводя итог нашему анализу, сформулируем краткий алгоритм действий при подозрении на "обрезание" точности:
ВЫРАЗИТЬ, которые могут округлять промежуточные расчеты до 2 знаков.Формат(), не доверяя стандартному представлению.Помните, что 1С разделяет хранение и отображение. Точность 5 знаков будет сохранена платформой, пока вы явно не приведете тип к меньшей точности или не выполните операцию, приводящую к округлению.