Как прочитать точные значения из Excel в 1С без округления через ТабличныйДокумент

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

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

Причина проблемы: Текст vs Значение

Когда мы используем метод Прочитать() для объекта ТабличныйДокумент, 1С анализирует структуру файла Excel. По умолчанию в ячейки табличного документа записывается то, что пользователь видит глазами (свойство Текст). Если в Excel настроен денежный формат с округлением до 2-х знаков, то попытка получить данные через Область().Текст вернет округленное строковое значение. Для сверки итоговых сумм этого недостаточно, так как итоговая формула в самом Excel может суммировать неокругленные данные, и ваша программная сумма не сойдется с суммой документа.

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

Решение №1: Использование СпособаЧтенияЗначений

Самый эффективный и быстрый способ — использование специального параметра в методе Прочитать(). Начиная с современных версий платформы 8.3, метод поддерживает второй параметр, который определяет, что именно будет помещено в ячейки табличного документа.

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


// Создаем объект табличного документа
ТаблДок = Новый ТабличныйДокумент;

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

// Теперь при обходе ячеек мы можем обращаться к свойству Значение
Для НомерСтроки = 1 По ТаблДок.ВысотаТаблицы Цикл
    ТекущаяОбласть = ТаблДок.Область(НомерСтроки, 2); // Допустим, сумма во второй колонке
    
    // Если мы обратимся к ТекущаяОбласть.Текст - получим "100.50"
    // Если обратимся к ТекущаяОбласть.Значение - получим число 100.4998
    РеальнаяСумма = ТекущаяОбласть.Значение;
    
    Если ТипЗнч(РеальнаяСумма) = Тип("Число") Тогда
        // Здесь мы можем самостоятельно решить, как округлять
        ИтоговаяСумма = ИтоговаяСумма + Окр(РеальнаяСумма, 2);
    КонецЕсли;
КонецЦикла;

Важный нюанс: при использовании этого метода 1С пытается преобразовать типы данных Excel в типы данных 1С (Число, Дата, Строка). Это позволяет работать с данными напрямую, не прибегая к медленным COM-объектам.

Решение №2: Преобразование в Таблицу Значений через Построитель Запроса

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

Проанализируем этот алгоритм по шагам:

  1. Сначала читаем файл в ТабличныйДокумент со способом «Значение».
  2. Используем ОписаниеИсточникаДанных для передачи области документа в построитель.
  3. Выгружаем результат в ТаблицуЗначений.

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

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

ТаблицаРезультат = ПЗ.Результат.Выгрузить();

Обратите внимание: если в вашем Excel-файле «шапка» таблицы находится не в первой строке или есть объединенные ячейки, построитель запроса может выдать ошибку или некорректно сформировать колонки. В таких случаях лучше использовать классический обход строк в цикле.

Особенности работы с форматами XLSX и точностью

Выясним причины, по которым даже при чтении значений могут возникать расхождения. Excel хранит числа в формате с плавающей запятой (Double), в то время как 1С использует формат Decimal. При программном разборе XML-структуры XLSX файла платформа 1С может прочитать число как 10.10000000000002 вместо 10.1.

Чтобы ваша сверка итогов была корректной, придерживайтесь следующих правил:

Сравнение методов: COM vs ТабличныйДокумент

Разберем, почему использование ТабличныйДокумент.Прочитать() предпочтительнее работы через COM-объект Excel.Application:

  1. Скорость: Нативное чтение платформой происходит в разы быстрее, особенно на больших файлах (от 10 000 строк).
  2. Кроссплатформенность: Метод работает на серверах под управлением Linux, где установка MS Excel невозможна.
  3. Безопасность: Не создаются «зависшие» процессы excel.exe в памяти сервера, которые часто становятся причиной утечек ресурсов.

Используя свойство СпособЧтенияЗначенийТабличногоДокумента.Значение, вы получаете все преимущества скорости нативного чтения, сохраняя при этом доступ к точным данным, необходимым для корректного ведения учета.

← На главную