Часто при программном сохранении прайс-листов или отчетов из 1С в формат XLSX через метод Записать() табличного документа разработчики сталкиваются с неприятной особенностью. При открытии итогового файла Excel присваивает всем ячейкам формат «Общий». Из-за этого строковые значения, похожие на числа, искажаются: пропадают ведущие нули (например, артикул "0001" превращается в "1"), а длинные цифровые коды (штрихкоды, номера счетов) могут преобразоваться в экспоненциальный вид вроде "1.24Е18".
Разберем подробнее, почему возникает эта проблема, и проанализируем несколько способов ее решения — от стандартных средств платформы 1С до более сложных вариантов, подходящих для фоновых заданий.
Самый простой подход, не требующий сторонних средств, заключается в явном указании типа значения для конкретных ячеек перед сохранением. Платформа 1С позволяет задать для области табличного документа свойство СодержитЗначение и явно указать тип Строка. При экспорте в Excel формат ячейки формально останется «Общим», но само значение не будет сконвертировано в число, сохранив ведущие нули и предотвратив появление экспоненциального формата.
Посмотрим на пример кода, который обходит весь сформированный табличный документ и корректирует проблемные ячейки:
ТипСтрока = Новый ОписаниеТипов("Строка");
Для НомерСтроки = 1 По ТабличныйДокумент.ВысотаТаблицы Цикл
Для НомерСтолбца = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
Ячейка = ТабличныйДокумент.Область(НомерСтроки, НомерСтолбца, НомерСтроки, НомерСтолбца);
ТекТекст = Ячейка.Текст;
// Анализируем текст: если начинается с "0" или содержит длинное число
Если ТребуетсяПреобразованиеВСтроку(ТекТекст) Тогда
Ячейка.СодержитЗначение = Истина;
Ячейка.ТипЗначения = ТипСтрока;
Ячейка.Текст = ТекТекст; // Обязательно переприсваиваем текст
КонецЕсли;
КонецЦикла;
КонецЦикла;
ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Важное замечание: в некоторых случаях (особенно со сложными артикулами) требуется принудительно переприсвоить свойство Текст после установки типа, иначе выгрузка может сработать некорректно. Однако этот метод не задает жесткий «Текстовый» формат в самом интерфейсе Excel — для некоторых требовательных систем автоматической загрузки у клиентов этого может быть недостаточно.
Если заказчику принципиально важно, чтобы в свойствах ячейки в самом Excel стоял формат «Текстовый», можно воспользоваться COM-соединением. Мы открываем уже сохраненный файл через приложение Excel и меняем формат NumberFormat на @.
Проанализируем пример кода для такой постобработки:
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(ИмяФайла);
Excel.Visible = 0;
Excel.Cells.Select();
Excel.Selection.NumberFormat = "@"; // Устанавливаем текстовый формат
Excel.DisplayAlerts = Ложь;
// Сохраняем файл в нужном формате
Если Расширение = "XLSX" Тогда
Excel.ActiveWorkbook.SaveAs(ИмяФайла, 51); // 51 - xlsx 2007-2013
Иначе
Excel.ActiveWorkbook.SaveAs(ИмяФайла, 18); // 18 - xls 97-2003
КонецЕсли;
Excel.Application.Quit();
Excel = Неопределено;
Недостатки метода:
Так как файл формата XLSX по своей сути является ZIP-архивом с набором XML-документов, мы можем отредактировать этот архив средствами самой платформы 1С. Этот метод идеален для фоновых заданий, не требует установленного Excel и работает предельно быстро.
Разберем по шагам алгоритм действий:
ЧтениеZipФайла распаковываем сохраненный файл во временный каталог на сервере.xl/worksheets/sheet1.xml) и файл стилей (xl/styles.xml).ЧтениеXML и ЗаписьXML (или ПостроительDOM), модифицируем XML-разметку. Мы можем присвоить нужным ячейкам атрибут текстового типа (t="str") или добавить новый текстовый стиль в файл стилей.ЗаписьZipФайла и меняем расширение на .xlsx.Данный подход является самым технически грамотным для высоконагруженных серверных систем.
Если клиенту важен не сам контейнер XLSX, а факт успешного импорта данных в сторонние системы (без потери нулей), можно генерировать отчет в текстовом формате Microsoft XML Spreadsheet (сохраняется с расширением .xml или .xls).
Создавая файл напрямую через конкатенацию строк или ЗаписьXML, мы получаем полный контроль над форматированием. В таком файле можно жестко прописать тег:
<NumberFormat ss:Format="@"/>
При открытии такого файла MS Excel гарантированно распознает колонку как текстовую, и никакие числа не будут усечены.
Еще один серверный вариант, не требующий установки самого пакета Office. Достаточно установить бесплатный провайдер Access Database Engine. Подключившись к файлу Excel через объект ADODB.Connection, можно создавать листы как таблицы базы данных (CREATE TABLE) и вставлять строки через INSERT INTO.
При выполнении SQL-запроса на создание таблицы мы можем явно определить тип проблемных колонок как VARCHAR или TEXT. При записи в такие колонки Excel не будет применять автоматическую конвертацию в числа, сохранив данные в исходном виде.
Выбор конкретного решения зависит от архитектуры вашей базы. Если вы формируете прайсы небольшого объема интерактивно на клиенте, может быть достаточно COM-объекта. Если же рассылка отчетов работает на сервере через регламентные задания РегламентныеЗадания, лучше использовать метод корректировки свойств СодержитЗначение в самом ТабличныйДокумент или применять продвинутые подходы с модификацией структуры XLSX-архива.