Как программно загрузить данные из Excel в 1С:Бухгалтерия 3.0 и правильно преобразовать их в объекты

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

Загрузка данных из внешних файлов, таких как Excel, является одной из самых частых задач для разработчика 1С. Начинающие программисты часто сталкиваются с ситуацией, когда данные из таблицы вроде бы считываются, но при попытке записать их в справочник возникают ошибки или поля остаются пустыми. Чаще всего это происходит из-за непонимания разницы между строковыми данными из файла и ссылочными типами данных в системе 1С.

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

Разбор основной проблемы: Ссылка или Строка?

Проанализируем типичную ситуацию. У нас есть файл Excel с колонками: "Номенклатура", "Вид номенклатуры", "Единица измерения". При чтении файла 1С получает обычные строки. Однако реквизит ВидНоменклатуры в справочнике Номенклатура имеет тип СправочникСсылка.ВидыНоменклатуры. Если вы попытаетесь напрямую присвоить строку реквизиту ссылки, система либо выдаст ошибку, либо проигнорирует значение.

Рассмотрим ошибочный код, который часто пишут новички:


НовыйЭлемент.ВидНоменклатуры = Справочники.ВидыНоменклатуры.НайтиПоНаименованию(ИмяИзЭкскль).Наименование;

В данном примере метод НайтиПоНаименованию возвращает ссылку, но обращение через точку к свойству Наименование превращает её обратно в строку. В итоге вы пытаетесь записать текст там, где должна быть ссылка. Правильный подход — всегда получать и сохранять именно ссылку.

Шаг 1: Подготовка алгоритма поиска и создания

Прежде чем создавать новый элемент, хорошим тоном считается проверка: а нет ли уже такой номенклатуры в базе? Поиск лучше всего осуществлять по наименованию или артикулу. Разберем по шагам, как организовать цикл обхода загруженных из Excel данных (предположим, они уже находятся в Таблице Значений ЗагруженныеДанные).

Рассмотрим структуру цикла:


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

Шаг 2: Получение ссылок для связанных справочников

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

Проанализируем пример заполнения реквизитов:


// Поиск вида номенклатуры
ВидНомСсылка = Справочники.ВидыНоменклатуры.НайтиПоНаименованию(СтрокаДанных.ВидНоменклатуры, Истина);
Если НЕ ВидНомСсылка.Пустая() Тогда
    НовыйОбъект.ВидНоменклатуры = ВидНомСсылка;
КонецЕсли;

// Поиск единицы измерения в классификаторе
ЕдИзмСсылка = Справочники.КлассификаторЕдиницИзмерения.НайтиПоНаименованию(СтрокаДанных.ЕдиницаИзмерения, Истина);
Если НЕ ЕдИзмСсылка.Пустая() Тогда
    НовыйОбъект.ЕдиницаИзмерения = ЕдИзмСсылка;
КонецЕсли;

Шаг 3: Работа с перечислениями

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

Посмотрим на пример установки ставки НДС:


// Если в файле указано "20%", сопоставим это со значением перечисления
Если СтрокаДанных.СтавкаНДС = "20%" Тогда
    НовыйОбъект.ВидСтавкиНДС = Перечисления.ВидыСтавокНДС.НДС20;
ИначеЕсли СтрокаДанных.СтавкаНДС = "Без НДС" Тогда
    НовыйОбъект.ВидСтавкиНДС = Перечисления.ВидыСтавокНДС.БезНДС;
Иначе
    // Значение по умолчанию
    НовыйОбъект.ВидСтавкиНДС = Перечисления.ВидыСтавокНДС.Общая;
КонецЕсли;

Шаг 4: Оптимизация процесса (Важно!)

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

Рассмотрим профессиональный подход к оптимизации:

  1. Использование запросов: Вместо поиска в цикле, соберите все наименования из Excel в массив и одним запросом выгрузите все существующие ссылки в таблицу значений или соответствие (кэш).
  2. Режим загрузки: Используйте свойство ОбменДанными.Загрузка = Истина. Это отключит лишние проверки в модулях объекта и подписках на события, что значительно ускорит процесс.
  3. Транзакции: Оборачивайте цикл загрузки в транзакцию. Если произойдет ошибка на 100-й строке, система откатит изменения, и у вас не останется "мусора" в базе.

Пример использования режима загрузки:


НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НовыйОбъект.ОбменДанными.Загрузка = Истина; // Отключаем лишние проверки
НовыйОбъект.Наименование = СтрокаДанных.Номенклатура;
// ... заполнение ...
НовыйОбъект.Записать();

Итоговый алгоритм качественной загрузки

Подведем итог. Чтобы ваша обработка работала надежно, придерживайтесь следующей последовательности действий:

  1. Прочитайте файл Excel в ТаблицуЗначений.
  2. Проверьте данные на корректность (заполнены ли обязательные поля).
  3. Откройте транзакцию с помощью НачатьТранзакцию().
  4. В цикле выполняйте поиск ссылок для каждого реквизита. Если реквизит — справочник, используйте НайтиПоНаименованию (или поиск по коду/артикулу). Если перечисление — используйте логику Если...ИначеЕсли.
  5. Создавайте или обновляйте объект справочника, устанавливая ОбменДанными.Загрузка = Истина.
  6. Зафиксируйте транзакцию ЗафиксироватьТранзакцию() после успешного завершения цикла.

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

← На главную