Почему искажаются числа при сохранении табличного документа 1С в формат .xlsx и как это исправить?

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

Многие разработчики сталкиваются с неожиданным поведением платформы 1С при сохранении сформированного табличного документа в формат Excel. Разберем типичную ситуацию: мы программно заполняем ячейку числом с двумя знаками после запятой, но после сохранения в файл формата .xlsx число приобретает длинный «хвост» из девяток.

Проанализируем проблему на примере

Рассмотрим простейший код, который вызывает данное искажение:


ТабДок = Новый ТабличныйДокумент;
ТабДок.Область(1, 1).Текст = "560128,69";
ТабДок.Записать("C:\Пример.xlsx", ТипФайлаТабличногоДокумента.XLSX);
ТабДок.Записать("C:\Пример.xls", ТипФайлаТабличногоДокумента.XLS97);

Если мы откроем полученные файлы в Excel, то увидим, что в старом бинарном формате .xls число осталось таким же (560128,69), а в файле .xlsx оно превратилось в 560128.689999999. Попытка использовать свойство Value (или Значение) вместо Текст также не всегда приводит к желаемому результату, так как Excel может перестать распознавать переданное значение как число, если оно не было должным образом типизировано.

Выясним причину искажения

Искажение возникает из-за особенностей внутреннего устройства формата .xlsx (Office Open XML) и работы штатного конвертера 1С. В отличие от старого бинарного формата .xls, формат .xlsx хранит данные в виде набора XML-файлов. Числа в нем конвертируются и сохраняются по стандарту плавающей запятой двойной точности (IEEE 754).

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

Метод платформы 1С Записать() со вторым параметром ТипФайлаТабличногоДокумента.XLSX работает как универсальный механизм и не всегда корректно переносит типы данных, если они предварительно строго не описаны в свойствах ячейки.

Разберем способы решения

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

1. Явное указание числового типа с форматом

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


Область = ТабДок.Область(1, 1);
Область.СодержитЗначение = Истина;
Область.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
Область.Значение = 560128.69;
Область.Формат = "ЧДЦ=2";

2. Явное сохранение как текста

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


Область = ТабДок.Область(1, 1);
Область.СодержитЗначение = Истина;
Область.ТипЗначения = Новый ОписаниеТипов("Строка");
Область.Значение = "560128,69";

Рассмотрим альтернативные варианты выгрузки

Если штатные средства 1С не подходят для вашей задачи из-за сложной структуры документа, проанализируем другие популярные подходы:

  1. Использование COM-объекта (Excel.Application). Вместо использования штатного метода сохранения 1С, табличный документ или отдельные его массивы выгружаются напрямую через инициализацию COM-соединения с Excel. Это позволяет напрямую задать свойство NumberFormat = "@" (текст) или NumberFormat = "0.00" (число) нужным ячейкам. Этот метод на 100% точен, однако он работает значительно медленнее штатного сохранения и строго не рекомендуется к использованию на сервере 1С (требует установленного MS Office).
  2. Выгрузка в формат CSV. Если стоит задача передать только плоские табличные данные без сложного оформления (рамок, шрифтов, объединенных ячеек), формирование обычного текстового документа с разделителями (CSV) исключит любые искажения. Программа Excel корректно открывает такие файлы, сохраняя исходный вид дробей и чисел.
  3. Прямое редактирование OpenXML. Так как файл .xlsx по своей сути является zip-архивом, в сложных сценариях можно сгенерировать файл штатным методом 1С, а затем программно открыть его как архив и исправить узлы в файлах sharedStrings.xml или sheet1.xml средствами работы с XML, принудительно устраняя неточности преобразования.

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

← На главную