Почему Построитель запроса в 1С 8.3.26 преобразует дробные числа в целые и как это исправить

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

С выходом платформы 1С:Предприятие 8.3.26 многие разработчики столкнулись с неожиданным поведением механизмов, которые годами работали стабильно. Одной из таких проблем стала некорректная выгрузка данных через ПостроительЗапроса при работе с ТабличнымДокументом, полученным из файлов Excel. Суть проблемы заключается в том, что дробные числа (например, 0,003) при попадании в Результат.Выгрузить() превращаются в целые числа (в данном примере — 3), полностью теряя дробную часть и разделитель.

В этой статье мы подробно разберем, почему это происходит, проанализируем изменения в новой платформе и рассмотрим несколько способов решения данной задачи.

Анализ ситуации: почему ломается типизация

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


ЧитаемаяОбласть = ТаблДок.ПолучитьОбласть(Стр.Имя); 
ПЗ = Новый ПостроительЗапроса; 
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ЧитаемаяОбласть.Область); 
ПЗ.ЗаполнитьНастройки; 
ТЗ = ПЗ.Результат.Выгрузить;

В версиях платформы до 8.3.26 этот механизм работал корректно: система автоматически распознавала тип данных в ячейках. Однако в 8.3.26 разработчики «1С» внесли существенные корректировки в логику работы механизмов локализации. Теперь ОписаниеИсточникаДанных более строго привязывается к региональным установкам сеанса. Если в ячейке в качестве разделителя используется запятая, а система (согласно внутренним или системным настройкам) ожидает точку, алгоритм парсинга может ошибочно игнорировать разделитель и интерпретировать строку как набор цифр, приводя 0,003 к 3.

Решение №1: Принудительная замена разделителя в источнике

Как выяснилось в ходе обсуждения, наиболее быстрым и действенным способом является приведение всех числовых данных в Excel (или непосредственно в ТабличномДокументе перед обработкой) к формату с точкой в качестве разделителя. Если в ячейке стоит значение 0.003 вместо 0,003, построитель запроса отрабатывает верно.

Мы можем автоматизировать этот процесс программно, пройдясь по ячейкам табличного документа перед тем, как передавать его в ОписаниеИсточникаДанных. Проанализируем пример кода для такой обработки:


// Проходим по всем значимым ячейкам области
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
    Для НомерКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
        ТекущаяОбласть = ТабДок.Область(НомерСтроки, НомерКолонки);
        // Проверяем, содержит ли текст запятую
        Если Найти(ТекущаяОбласть.Текст, ",") > 0 Тогда
            // Заменяем запятую на точку для корректного парсинга в 8.3.26
            ТекущаяОбласть.Текст = СтрЗаменить(ТекущаяОбласть.Текст, ",", ".");
        КонецЕсли;
    КонецЦикла;
КонецЦикла;

После выполнения такой замены ПостроительЗапроса увидит точку и корректно сформирует колонку с типом Число, сохранив точность до третьего знака после запятой.

Решение №2: Использование региональных установок информационной базы

В платформе 8.3.26 появились расширенные возможности управления локализацией. Выясним причину конфликта в настройках системы. Необходимо проверить следующие параметры в Конфигураторе:

  1. Перейдите в меню Администрирование — Региональные установки информационной базы.
  2. Обратите внимание на флаг «Использовать региональные установки текущего сеанса». Если он включен, 1С берет разделитель из настроек операционной системы пользователя.
  3. Проверьте поле «Разделитель дробной части». Если там жестко задана точка, а в загружаемых данных используется запятая, возникнет описанная проблема.

Попробуйте установить разделитель явно или убедиться, что настройки Excel-файла соответствуют региональным стандартам сервера 1С.

Решение №3: Изменение способа чтения Табличного Документа

При чтении файла Excel в ТабличныйДокумент рекомендуется явно указывать способ интерпретации значений. Рассмотрим метод Прочитать():


ТабДок = Новый ТабличныйДокумент;
// Используем явное указание способа чтения
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Текст);

Если мы используем параметр СпособЧтенияЗначенийТабличногоДокумента.Значение, платформа пытается самостоятельно определить тип данных Excel. В версии 8.3.26 этот механизм может работать нестабильно. Выбрав Текст, мы получаем строковое представление, которое затем можем обработать программно (заменив разделители), прежде чем передавать в ПостроительЗапроса.

Решение №4: Альтернативный метод через Excel.Application

Если работа через ПостроительЗапроса и ОписаниеИсточникаДанных остается нестабильной, рассмотрим вариант прямого чтения данных через COM-объект. Этот метод не зависит от внутренних механизмов типизации ТабличногоДокумента 1С и позволяет более гибко управлять процессом получения данных.


Попытка
    ExcelПриложение = Новый COMОбъект("Excel.Application");
    Книга = ExcelПриложение.Workbooks.Open(ПутьКФайлу);
    Лист = Книга.Sheets(1);
    
    // Прямое чтение значения ячейки
    Значение = Лист.Cells(НомерСтроки, НомерКолонки).Value;
    
    Книга.Close(Ложь);
    ExcelПриложение.Quit();
Исключение
    // Обработка ошибок работы с COM
КонецПопытки;

Хотя автор вопроса отметил, что этот вариант ему менее интересен, он является наиболее надежным «обходным путем», когда штатные механизмы новой платформы содержат ошибки (баги), которые еще не исправлены в текущем релизе (патче).

Резюме и рекомендации

Подводя итог, можно сказать, что проблема в 8.3.26 носит системный характер и связана с ужесточением правил приведения типов в зависимости от локали. Для исправления ситуации выполним следующие шаги:

  1. Проанализируем разделитель: убедимся, что в исходном файле и в настройках 1С используется один и тот же символ.
  2. Применим программную замену: если файлы приходят из разных источников, самым надежным способом будет принудительная замена "," на "." в тексте ячеек перед созданием ОписаниеИсточникаДанных.
  3. Следим за обновлениями: подобные ошибки парсинга обычно признаются багами платформы и исправляются в последующих минорных релизах (например, в патчах к 8.3.26.xxxx).

Использование ПостроителяЗапроса для парсинга Excel-файлов — это мощный и удобный инструмент, так как он позволяет сразу получить готовую ТаблицуЗначений с типизированными колонками, но в новых версиях платформы он требует более внимательного отношения к региональным настройкам данных.

← На главную