При автоматизации загрузки данных из внешних файлов Excel разработчики часто сталкиваются с ситуацией, когда визуальное представление числа в ячейке не совпадает с его реальным внутренним содержанием. Особенно это критично для бухгалтерских и финансовых документов, где в ячейке с денежным форматом может храниться число с четырьмя знаками после запятой, а на экране отображаться только два. При обычном чтении через ТабличныйДокумент платформа 1С по умолчанию считывает именно текст, что приводит к накоплению погрешности при расчете итогов. Разберем подробно, как решить эту проблему и получить доступ к «сырым» данным.
Когда мы используем метод Прочитать() для объекта ТабличныйДокумент, 1С анализирует структуру файла Excel. По умолчанию в ячейки табличного документа записывается то, что пользователь видит глазами (свойство Текст). Если в Excel настроен денежный формат с округлением до 2-х знаков, то попытка получить данные через Область().Текст вернет округленное строковое значение. Для сверки итоговых сумм этого недостаточно, так как итоговая формула в самом Excel может суммировать неокругленные данные, и ваша программная сумма не сойдется с суммой документа.
Чтобы избежать этой ловушки, необходимо переключить режим чтения документа таким образом, чтобы платформа извлекала именно Значение ячейки.
Самый эффективный и быстрый способ — использование специального параметра в методе Прочитать(). Начиная с современных версий платформы 8.3, метод поддерживает второй параметр, который определяет, что именно будет помещено в ячейки табличного документа.
Рассмотрим пример кода, который позволяет прочитать файл на сервере с сохранением исходной точности чисел:
// Создаем объект табличного документа
ТаблДок = Новый ТабличныйДокумент;
// Читаем файл, указывая способ чтения значений
// Используем перечисление СпособЧтенияЗначенийТабличногоДокумента.Значение
ТаблДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Теперь при обходе ячеек мы можем обращаться к свойству Значение
Для НомерСтроки = 1 По ТаблДок.ВысотаТаблицы Цикл
ТекущаяОбласть = ТаблДок.Область(НомерСтроки, 2); // Допустим, сумма во второй колонке
// Если мы обратимся к ТекущаяОбласть.Текст - получим "100.50"
// Если обратимся к ТекущаяОбласть.Значение - получим число 100.4998
РеальнаяСумма = ТекущаяОбласть.Значение;
Если ТипЗнч(РеальнаяСумма) = Тип("Число") Тогда
// Здесь мы можем самостоятельно решить, как округлять
ИтоговаяСумма = ИтоговаяСумма + Окр(РеальнаяСумма, 2);
КонецЕсли;
КонецЦикла;
Важный нюанс: при использовании этого метода 1С пытается преобразовать типы данных Excel в типы данных 1С (Число, Дата, Строка). Это позволяет работать с данными напрямую, не прибегая к медленным COM-объектам.
Если после загрузки данных вам требуется сложная обработка, фильтрация или расчет итогов, удобнее всего трансформировать ТабличныйДокумент в ТаблицуЗначений. Это можно сделать быстро с помощью ПостроителяЗапроса, не перебирая тысячи строк вручную.
Проанализируем этот алгоритм по шагам:
ТабличныйДокумент со способом «Значение».ОписаниеИсточникаДанных для передачи области документа в построитель.ТаблицуЗначений.
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.Прочитать(Файл, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Важно: Построитель запроса ожидает, что первая строка области содержит заголовки
ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабличныйДокумент.Область());
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();
ТаблицаРезультат = ПЗ.Результат.Выгрузить();
Обратите внимание: если в вашем Excel-файле «шапка» таблицы находится не в первой строке или есть объединенные ячейки, построитель запроса может выдать ошибку или некорректно сформировать колонки. В таких случаях лучше использовать классический обход строк в цикле.
Выясним причины, по которым даже при чтении значений могут возникать расхождения. Excel хранит числа в формате с плавающей запятой (Double), в то время как 1С использует формат Decimal. При программном разборе XML-структуры XLSX файла платформа 1С может прочитать число как 10.10000000000002 вместо 10.1.
Чтобы ваша сверка итогов была корректной, придерживайтесь следующих правил:
Окр(Значение, 2) к загруженным числам, если вы планируете сравнивать их с финансовыми итогами.СтрЗаменить(Текст, Символы.НПП, "") и преобразуйте в число.Разберем, почему использование ТабличныйДокумент.Прочитать() предпочтительнее работы через COM-объект Excel.Application:
excel.exe в памяти сервера, которые часто становятся причиной утечек ресурсов.Используя свойство СпособЧтенияЗначенийТабличногоДокумента.Значение, вы получаете все преимущества скорости нативного чтения, сохраняя при этом доступ к точным данным, необходимым для корректного ведения учета.