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

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции систем 1С с Microsoft Excel разработчики часто сталкиваются с неприятной особенностью табличного процессора: при записи длинных числовых последовательностей (например, штрихкодов, номеров расчетных счетов, артикулов или GUID) Excel автоматически преобразует их в экспоненциальный формат вида 1,23E+24. Более того, из-за внутренних ограничений платформы Excel все цифры после 15-го знака безвозвратно заменяются нулями.

В этой статье мы подробно разберем, почему это происходит, и рассмотрим все существующие способы решения этой проблемы — от классического использования COM-соединения до современных серверных методов генерации файлов XLSX без привлечения стороннего ПО.

Выясняем причину: почему Excel искажает длинные числа

Прежде чем перейти к написанию кода, важно понять физику процесса. Microsoft Excel хранит и обрабатывает числовые значения в соответствии со стандартом IEEE 754 (числа с плавающей запятой двойной точности). Этот стандарт накладывает жесткое ограничение: точность любого числа в ячейке не может превышать 15 значащих цифр.

Если мы попытаемся записать в ячейку строку, состоящую только из цифр длиной более 15 символов (например, 1234567890123456789012345), Excel автоматически:

  1. Попытается интерпретировать строку как число.
  2. Применит экспоненциальную форму отображения (научный формат).
  3. Внимание! Отрежет всё, что находится после 15-го символа, заменив хвост числа нулями. Восстановить эти данные обратно программным путем или вручную будет уже невозможно.

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

---

Способ 1. Установка текстового формата через NumberFormat

Это наиболее правильный и профессиональный подход при работе через COM-объект Excel.Application. Мы явно указываем приложению Excel, что конкретные ячейки должны обрабатываться как текст. Текстовому формату в спецификации Excel соответствует маска "@".

Рассмотрим пример кода на языке 1С, где сначала создается объект Excel, а затем для ячейки задается текстовый формат:


// Создаем COM-объект для работы с Excel (пример для 1С v8)
Excel = Новый COMОбъект("Excel.Application");
WorkBook = Excel.WorkBooks.Add();
MainPage = WorkBook.Sheets(1);

// Шаг 1. Сначала задаем текстовый формат для конкретной ячейки
MainPage.Cells(1, 1).NumberFormat = "@";

// Шаг 2. Записываем длинное число-строку
MainPage.Cells(1, 1).Value = "1234567890123456789012345";

// Сохраняем и закрываем
WorkBook.SaveAs("D:\file.xlsx");
Excel.Quit();

Важнейшее правило: порядок действий имеет значение! Сначала необходимо присвоить ячейке формат "@", и только затем записывать туда текстовое значение. Если сделать наоборот (сначала присвоить значение, а затем поменять формат на текстовый), Excel успеет испортить число и занулить цифры после 15-го знака. Смена формата в таком случае просто отобразит уже испорченное число в текстовом виде.

---

Способ 2. Быстрый обход проблемы с помощью апострофа

Если вам не хочется писать дополнительные строки кода для форматирования или структура файла формируется динамически, можно воспользоваться стандартной "фичей" самого Excel — префиксом в виде одинарной кавычки (апострофа) '.

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

Посмотрим на пример реализации:


Excel = Новый COMОбъект("Excel.Application");
WorkBook = Excel.WorkBooks.Add();
MainPage = WorkBook.Sheets(1);

// Добавляем апостроф в начало строки
ДлинноеЧисло = "1234567890123456789012345";
MainPage.Cells(1, 1).Value = "'" + ДлинноеЧисло;

WorkBook.SaveAs("D:\file.xlsx");
Excel.Quit();

Этот способ прост и надежен, однако у него есть два архитектурных недостатка:

  1. При считывании этих данных обратно в другие системы (не через 1С, а, например, сторонними парсерами) в начале строки может остаться физический символ апострофа, что потребует дополнительной очистки данных.
  2. В углу ячейки может появиться навязчивый зеленый треугольник, предупреждающий пользователя о том, что "Число сохранено как текст".

---

Способ 3. Оптимизация производительности (Форматирование диапазонов)

Поячеечный обход таблицы 1С и последовательное присвоение формата каждой ячейке через COM-соединение — это крайне медленный процесс. При передаче каждого обращения через COM-границу операционная система тратит значительные ресурсы. Если в вашем отчете десятки тысяч строк, выгрузка может затянуться на часы.

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

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


// Форматируем всю колонку "A" (первая колонка) целиком как текст
MainPage.Columns("A").NumberFormat = "@";

// Или форматируем конкретный диапазон ячеек (например, с первой по сотую строку в колонках A, B, C)
MainPage.Range("A1:C100").NumberFormat = "@";

// После этого можно производить быстрое заполнение ячеек данными
Для НомерСтроки = 1 По 100 Цикл
    MainPage.Cells(НомерСтроки, 1).Value = "30201810400000000123"; // Счет откроется корректно!
КонецЦикла;

Использование свойства Columns или Range позволяет оптимизировать работу скрипта и выполнить тяжелую операцию по назначению стилей за доли секунды.

---

Дополнительные настройки оформления и локализации

При активной работе с файлами Excel полезно знать еще несколько нюансов, которые делают результирующий файл визуально чистым и профессиональным.

Избавляемся от "зеленых треугольников"

Чтобы отключить предупреждения Excel о "числах, сохраненных как текст", и убрать зеленые индикаторы ошибок в углах ячеек, добавьте в инициализацию приложения следующую строку кода:

Excel.Application.ErrorCheckingOptions.NumberAsText = Ложь;

Это отключит данное раздражающее предупреждение на время сессии выгрузки.

Использование NumberFormatLocal

В зависимости от региональных настроек операционной системы Windows и языковой версии пакета Microsoft Office, стандартное англоязычное свойство NumberFormat может вызывать исключения (например, при попытке задать сложные маски дат или денежных единиц). В русскоязычной среде рекомендуется использовать альтернативное свойство NumberFormatLocal. Хотя для текстового формата значение "@" универсально во всех локалях, использование локализованного свойства повышает общую отказоустойчивость интеграционного кода.

---

Современная альтернатива: выгрузка штатными средствами 1С (без COM)

Использование COM-объекта Excel.Application накладывает жесткое ограничение: на компьютере, где выполняется данный код, обязательно должен быть установлен лицензионный пакет Microsoft Office. На серверных ОС семейства Linux или в облачных кластерах этот метод попросту не сработает.

Современный стандарт разработки в 1С v8.3 предполагает использование платформенного объекта ТабличныйДокумент с последующим сохранением в формат XLSX.

Чтобы при таком сохранении длинные текстовые числа не искажались, достаточно соблюдать простые правила разметки макета 1С:

  1. Для ячеек с длинными числовыми идентификаторами в свойствах макета необходимо явно установить Тип значения как Строка (а не Число).
  2. Выравнивание ячейки: Excel при импорте файлов XLSX ориентируется на визуальное выравнивание. Если для числовой строки в 1С задано выравнивание по правому краю, Excel попытается прочитать ее как число и обрежет. Установите выравнивание ячейки по левому краю или по центру — тогда Excel гарантированно импортирует значение как чистый текст, сохранив все знаки исходного штрихкода или счета.

Проанализируем пример сохранения табличного документа без использования COM-объектов:


ТабДок = Новый ТабличныйДокумент;

// Заполняем табличный документ данными из выборки или запроса...
Область = ТабДок.ПолучитьОбласть("РабочаяОбласть");
Ячейка = Область.Область("R1C1");

// Явно указываем тип значения и выравнивание
Ячейка.СодержитЗначение = Истина;
Ячейка.ТипЗначения = Новый ОписаниеТипов("Строка");
Ячейка.Значение = "1234567890123456789012345";
Ячейка.ГоризонтальноеПоложение = ГоризонтальноеПоложение.Лево;

ТабДок.Вывести(Область);

// Сохраняем напрямую в формат XLSX на диске или сервере
ТабДок.Записать("D:\file_native.xlsx", ТипФайлаТабличногоДокумента.XLSX);

Этот способ работает в десятки раз быстрее, полностью автономен, отлично выполняется на сервере под управлением как Windows, так и Linux, и гарантирует корректность отображения всех данных у конечного пользователя.

← На главную