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

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

При импорте данных из внешних файлов Excel в информационные базы 1С разработчики и аналитики регулярно сталкиваются с классической проблемой: потерей лидирующих (ведущих) нулей в кодах номенклатуры, артикулах или штрихкодах. Например, код номенклатуры в конфигурации "Управление производственным предприятием" (УПП) имеет текстовый формат и жестко заданную длину (например, 11 символов: 00000016207). При открытии или чтении файла Excel этот код часто интерпретируется системой как число, превращаясь в 16207. В результате стандартный поиск по коду в 1С не может сопоставить элементы, и загрузка завершается ошибкой.

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

Способ 1. Использование свойства .Text вместо .Value при COM-соединении

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

Для решения этой проблемы мы должны использовать свойство Text. Оно возвращает строковое представление значения ячейки именно в том виде, в каком пользователь видит его на экране монитора, сохраняя все форматирование и ведущие нули.

Важное техническое предостережение: проблема "решеток" (###)
Использование свойства .Text имеет один очень опасный подводный камень. Если колонка в файле Excel физически слишком узкая для отображения длинного числа или кода, Excel визуально заменяет данные в ячейках на символы решеток ###. В этом случае свойство .Text вернет в 1С строку "###" вместо реального кода. Чтобы избежать этой ошибки, перед чтением данных необходимо программно расширить колонки.

Рассмотрим пример кода, реализующий этот подход:


// Создаем COM-объект для работы с Excel
Попытка
    ExcelПриложение = Новый COMОбъект("Excel.Application");
Исключение
    Сообщить("Не удалось запустить Excel! Возможно, MS Office не установлен.");
    Возврат;
КонецПопытки;

// Открываем книгу и выбираем первый лист
Книга = ExcelПриложение.Workbooks.Open(ПутьКФайлу);
Лист = Книга.Sheets(1);

// КРИТИЧЕСКИ ВАЖНО: Принудительно автоподбираем ширину всех колонок,
// чтобы избежать появления символов "###" вместо данных
Лист.Cells.EntireColumn.AutoFit();

// Читаем данные из конкретной ячейки
СтрокаДанных = 2; // Например, начинаем со второй строки
КолонкаКода = 1;  // Код номенклатуры находится в первой колонке

// Получаем значение именно через свойство Text
КодИзExcel = СокрЛП(Лист.Cells(СтрокаДанных, КолонкаКода).Text);

// Закрываем книгу и завершаем работу с Excel
Книга.Close(Ложь);
ExcelПриложение.Quit();

Способ 2. Чтение файла через "Табличный документ" (Кроссплатформенный метод)

Использование COM-объектов жестко привязывает ваше решение к операционной системе Windows и требует обязательной установки Microsoft Office на клиентском компьютере или сервере 1С. В современных реалиях, когда серверы 1С часто работают под управлением ОС Linux, этот метод не применим. К счастью, платформа "1С:Предприятие 8" предоставляет мощную альтернативу — прямое чтение файлов Excel с помощью объекта ТабличныйДокумент.

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

Разберем этот метод по шагам:


// Создаем объект табличного документа
ТабДок = Новый ТабличныйДокумент;

// Читаем файл Excel напрямую.
// Вторым параметром передаем СпособЧтенияЗначенийТабличногоДокумента.Текст.
// Это заставит 1С считывать абсолютно все ячейки как форматированный текст,
// гарантируя сохранность ведущих нулей.
Попытка
    ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Текст);
Исключение
    ВызватьИсключение "Не удалось прочитать файл Excel: " + ОписаниеОшибки();
КонецПопытки;

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

Способ 3. Программное восстановление кодов на стороне 1С (Форматирование "на лету")

Иногда файлы Excel приходят от поставщиков уже поврежденными — когда нули были стерты еще на этапе выгрузки или сохранения документа на стороне контрагента. В таких случаях ни свойство .Text, ни чтение через ТабличныйДокумент не помогут вернуть утерянные данные, так как в файле физически записано число 16207 вместо 00000016207.

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

  1. Использование функции Формат():
    Это наиболее элегантный и быстрый способ. Мы задаем фиксированную длину числа с заполнением пустыми символами (нулями) слева.

    Рассмотрим пример:

    
    // Допустим, мы считали из Excel число или строку "16207"
    ИсходныйКод = "16207";
    ЧисловойКод = Число(ИсходныйКод);
    
    // ЧЦ=11 — задает общую длину кода в 11 символов
    // ЧВН= — указывает выводить ведущие нули
    // ЧГ=0 — отключает группировку разрядов (чтобы не появились пробелы "16 207")
    НормализованныйКод = Формат(ЧисловойКод, "ЧЦ=11; ЧВН=; ЧГ=0");
    
    // Результат: "00000016207"
    
  2. Дополнение строки нулями слева (строковый метод):
    Этот метод полезен, если код может содержать не только цифры, но и буквенные префиксы, из-за чего прямое преобразование в число невозможно.

    Пример реализации алгоритма:

    
    ИсходныйКод = СокрЛП(ЗначениеИзExcel); // Получили, например, "16207" или "А16207"
    НеобходимаяДлина = 11;
    
    // Создаем строку-маску из нулей нужной длины
    МаскаНулей = "00000000000"; 
    
    // Складываем маску с кодом и берем правые символы результирующей строки
    НормализованныйКод = Прав(МаскаНулей + ИсходныйКод, НеобходимаяДлина);
    
    // Результат: "00000016207"
    

Способ 4. Нюансы загрузки данных через ADO (OLEDB)

Для быстрой загрузки больших объемов данных разработчики часто применяют технологию ADO (ActiveX Data Objects). При подключении к Excel как к базе данных через провайдер OLEDB возникает специфическая проблема: драйвер Microsoft Excel сканирует первые несколько строк таблицы (количество определяется системным параметром реестра TypeGuessRows, обычно это 8 строк), чтобы автоматически определить тип данных в колонке.

Если первые 8 строк содержат только числовые значения, драйвер жестко присваивает всей колонке числовой тип данных. Все последующие строки, содержащие коды с ведущими нулями или даже смешанные буквенно-цифровые значения, будут прочитаны некорректно (нули отбросятся, а ячейки с буквами вернут значение NULL).

Решение:
Для обхода этой особенности в строке подключения ADO необходимо обязательно использовать специальный параметр IMEX=1 (Import Mode). Этот параметр указывает драйверу импортировать смешанные типы данных как обычный текст, предотвращая преобразование в число.

Пример правильной строки подключения:


Connection = Новый COMОбъект("ADODB.Connection");
// Задаем параметры подключения с IMEX=1
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";";
Connection.Open(ConnectionString);

Резюме

Для надежного сопоставления номенклатуры при импорте из Excel всегда анализируйте источник данных и архитектуру вашей системы:

← На главную