Почему различается разрядность числовых колонок при выгрузке результата запроса в Таблицу Значений?

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

При работе с платформой 1С:Предприятие разработчики часто сталкиваются с ситуацией, когда данные, полученные в результате выполнения запроса, при выгрузке в ТаблицаЗначений имеют непредсказуемую разрядность числовых колонок. Рассмотрим подробнее, почему возникают значения 38, 15 или 0, и как управлять этим поведением.

Разберемся в причинах поведения платформы

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

  1. Виртуальные таблицы (например, Остатки): Платформа часто присваивает таким колонкам максимальную разрядность (38 знаков), чтобы гарантировать отсутствие потерь данных при любых арифметических операциях, выполняемых на стороне СУБД.
  2. Прямая выборка из физической таблицы: В этом случае система наследует квалификаторы числа напрямую из метаданных ресурса регистра (например, Число(15, 3)).
  3. Агрегатные функции (СУММА, СРЕДНЕЕ, МИНИМУМ): Это наиболее проблемная область. При использовании агрегатных функций или константных выражений платформа не всегда может однозначно определить итоговую точность, что приводит к обнулению разрядности или установке «автоматического» режима, который часто интерпретируется как 0.

Проанализируем примеры и способы исправления

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

Рассмотрим, как правильно работать с разрядностью на примерах:

Решение 1: Приведение типов после выгрузки

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

Воспользуемся методом Добавить с указанием ОписаниеТипов:


// Пример принудительной настройки колонки
Таблица = Запрос.Выполнить().Выгрузить();
Квалификаторы = Новый КвалификаторыЧисла(15, 3);
ОписаниеТипаЧисло = Новый ОписаниеТипов("Число", Квалификаторы);

Таблица.Колонки["ИмяВашейКолонки"].ТипЗначения = ОписаниеТипаЧисло;

Решение 2: Обход строк таблицы

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


Для Каждого Строка Из Таблица Цикл
    Строка.Количество = Число(Строка.Количество);
КонецЦикла;

Важное примечание: Использование функции Число() в коде 1С не меняет структуру (метаданные) колонки ТаблицаЗначений, но позволяет привести конкретное значение к нужной точности, если вы работаете с данными в цикле.

Почему не помогает ВЫРАЗИТЬ в запросе?

Разберем ситуацию подробнее. Когда мы пишем:


ВЫБРАТЬ
    ВЫРАЗИТЬ(СУММА(Количество) КАК ЧИСЛО(15, 3)) КАК Количество
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

Результат всё равно может возвращать разрядность 0 в колонке ТаблицаЗначений. Это происходит потому, что платформа 1С при создании колонок в ТаблицаЗначений на основе запроса опирается на тип, который возвращает СУБД для данного выражения, а не всегда на жесткие квалификаторы внутри оператора ВЫРАЗИТЬ, особенно при сложных объединениях или наличии NULL.

Итоги и рекомендации

  1. Не полагайтесь на автоматическое определение типов при работе с агрегатными функциями или вычисляемыми полями в запросе.
  2. Если точность критична (например, для вывода в печатные формы или передачи в отчеты), всегда описывайте тип колонки ТаблицаЗначений вручную после метода Выгрузить().
  3. Если в запросе предполагается наличие NULL, используйте функцию ЕСТЬNULL(Поле, 0), чтобы избавиться от составного типа данных, что упрощает дальнейшую работу с типизацией.

Помните, что ТаблицаЗначений — это объект, который живет в памяти, и его метаданные (типы колонок) могут быть изменены вами в любой момент выполнения программы. Это дает вам полный контроль над тем, как именно будут представлены ваши числа.

← На главную