Как сохранить лидирующие нули в ИНН и других кодах при выгрузке из 1С в Excel

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

При формировании отчетов или выгрузке данных из 1С в формат Excel разработчики часто сталкиваются с неприятной особенностью: лидирующие нули в таких строках, как ИНН, КПП или артикулы, бесследно исчезают. Например, значение 071111111111 превращается в число 71111111111. Это происходит потому, что Excel по умолчанию интерпретирует последовательность цифр как число и применяет к нему свои правила форматирования.

В старых релизах платформы (до 8.3.14) проблему часто решали добавлением апострофа (') перед значением, но в современных версиях (8.3.20, 8.3.21 и выше) механизмы формирования файлов .xlsx изменились, и старые «костыли» перестали работать или начали отображаться в самом файле. Рассмотрим подробнее, как победить эту проблему нативными средствами 1С.

Выясним причину: почему Excel «обрезает» нули?

Когда мы вызываем метод Записать() у табличного документа, платформа 1С формирует структуру файла XLSX (OpenXML). Если в макете для ячейки не задан строгий тип данных, 1С помечает ее как «Общий» (General). При открытии такого файла Excel анализирует содержимое: если он видит только цифры, он автоматически конвертирует ячейку в числовой формат. Число не может начинаться с нуля, поэтому он удаляется.

Проанализируем ситуацию: простое визуальное выравнивание в 1С (прижать влево) никак не влияет на тип данных в итоговом файле. Нам нужно явно передать информацию о том, что данное значение является строкой, а не числом.

Решение 1: Правильная настройка макета (самый надежный способ)

Разберем по шагам, как настроить ячейку макета так, чтобы платформа принудительно записывала ее как текст. Это решение позволяет избежать использования тяжеловесных COM-объектов и установки Microsoft Office на сервере.

  1. Откроем макет, который используется для формирования табличного документа.
  2. Выделим ячейку (или параметр), где выводится ИНН.
  3. Перейдем в палитру свойств (Alt + Enter).
  4. Найдем свойство «Содержит значение» и установим флажок в значение Истина.
  5. В появившемся поле «Тип значения» нажмем на кнопку выбора и выберем Строка. Здесь же можно ограничить длину строки, если это необходимо.
  6. В свойстве «Размещение текста» лучше оставить Переносить или Авто, но критически важно, чтобы тип данных был зафиксирован.

Теперь, когда мы будем заполнять этот параметр, платформа 1С запишет в XML-структуру файла Excel специальный тег t="s" (string). Увидев его, Excel даже не попытается преобразовать данные в число.

Решение 2: Программное управление значением в области

Иногда простого заполнения через Параметры недостаточно, особенно если вы используете метод ЗаполнитьЗначенияСвойств(), который может затирать настройки типов. В таких случаях стоит обратиться к свойству Значение конкретной области. Рассмотрим пример кода:


// Получаем область из макета
ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаДанных");

// Вместо заполнения через параметр, обращаемся к конкретной ячейке области по имени
// Предположим, ячейка с ИНН называется "ОбластьИНН"
ЯчейкаИНН = ОбластьСтрока.Область("ОбластьИНН");

// Устанавливаем тип и значение программно
ЯчейкаИНН.СодержитЗначение = Истина;
ЯчейкаИНН.ТипЗначения = Новый ОписаниеТипов("Строка");
ЯчейкаИНН.Значение = Строка(ДанныеСтроки.ИНН);

// Выводим область в результирующий табличный документ
ТабДок.Вывести(ОбластьСтрока);

Обратите внимание: мы используем ЯчейкаИНН.Значение вместо ЯчейкаИНН.Текст. Это принципиальный момент для корректного экспорта в XLSX.

Решение 3: Использование составного макета (для сложных случаев)

Если ваш макет заполняется динамически и настройки «сбиваются», можно воспользоваться методом «сборки» строки из разных областей. Посмотрим на ситуацию, когда ИНН выводится отдельным блоком:


Для Каждого СтрокаДанных Из РезультатЗапроса Цикл
    // Выводим основную часть строки (до ИНН)
    ОбластьЛево = Макет.ПолучитьОбласть("Строка|Лево");
    ТабДок.Вывести(ОбластьЛево);
    
    // Выводим ячейку с ИНН с жестким типом
    ОбластьИНН = Макет.ПолучитьОбласть("Строка|ЦентрИНН");
    Если ОбластьИНН.ТекущаяОбласть.СодержитЗначение Тогда
        // Присваиваем значение параметру, зная, что тип в макете уже "Строка"
        ОбластьИНН.Параметры.ИНН = Строка(СтрокаДанных.ИНН);
    КонецЕсли;
    ТабДок.Присоединить(ОбластьИНН);
    
    // Выводим остаток строки
    ОбластьПраво = Макет.ПолучитьОбласть("Строка|Право");
    ТабДок.Присоединить(ОбластьПраво);
КонецЦикла;

Решение 4: Использование «невидимых» символов (альтернатива апострофу)

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


// Символ(160) - это неразрывный пробел
// Добавляем его в конец значения
Область.Параметры.ИНН = Строка(Данные.ИНН) + Символ(160);

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

Почему не стоит использовать COM-объекты?

Часто в обсуждениях советуют использовать Новый COMОбъект("Excel.Application"). Проанализируем, почему это плохой совет для современной разработки:

  1. Зависимость от ОС: Работает только под Windows.
  2. Требования к ПО: На сервере должен быть установлен Microsoft Excel, что требует лицензирования и создает нагрузку на память.
  3. Производительность: COM-вызовы работают значительно медленнее, чем нативный метод Записать().
  4. Стабильность: Процессы Excel часто «зависают» в памяти сервера, требуя ручного вмешательства.

Использование свойств СодержитЗначение и ТипЗначения в самом макете 1С является «чистым» и наиболее эффективным способом решения проблемы лидирующих нулей, который поддерживается платформой на уровне формирования файлов OpenXML.

← На главную