Многие разработчики сталкиваются с неожиданным поведением платформы 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С не подходят для вашей задачи из-за сложной структуры документа, проанализируем другие популярные подходы:
NumberFormat = "@" (текст) или NumberFormat = "0.00" (число) нужным ячейкам. Этот метод на 100% точен, однако он работает значительно медленнее штатного сохранения и строго не рекомендуется к использованию на сервере 1С (требует установленного MS Office)..xlsx по своей сути является zip-архивом, в сложных сценариях можно сгенерировать файл штатным методом 1С, а затем программно открыть его как архив и исправить узлы в файлах sharedStrings.xml или sheet1.xml средствами работы с XML, принудительно устраняя неточности преобразования.Используя явную типизацию ячеек табличного документа перед сохранением, мы сможем гарантировать высокую точность передаваемых данных и избежать неприятных сюрпризов с числами с плавающей запятой в итоговых файлах.