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

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

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

В этой статье мы подробно разберем, как обновить существующие реквизиты объектов в 1С на основе данных из табличного документа Excel. Мы рассмотрим стандартную обработку загрузки, научимся использовать встроенные обработчики событий для гибкой настройки логики и разберем современный механизм загрузки из БСП.

Метод 1. Настройка стандартной обработки «Загрузка данных из табличного документа»

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

Давайте разберем по шагам, как настроить обработку для изменения видов цен в договорах контрагентов без риска создания дубликатов:

  1. Подготовка исходного файла: Сформируем таблицу Excel. В ней обязательно должны быть колонки, однозначно идентифицирующие договор в информационной базе (например, «Контрагент» и «Наименование договора»), а также колонка с новым значением реквизита («Вид цен»).
  2. Открытие обработки и выбор режима: Запустим обработку в режиме Предприятия. Перейдем на вкладку «Настройка загрузки». В поле «Режим загрузки» укажем «Справочник», а в качестве целевого объекта выберем справочник ДоговорыКонтрагентов.
  3. Настройка колонок сопоставления: В табличной части настройки сопоставим номера колонок из файла Excel с реквизитами справочника в 1С:
    • Реквизит Владелец (это наш Контрагент) — указываем номер соответствующей колонки Excel.
    • Реквизит Наименование (наименование договора) — указываем номер соответствующей колонки Excel.
    • Реквизит ВидЦен (изменяемое поле) — указываем номер колонки с новым видом цен.
  4. Определение полей поиска: Это самый важный шаг. Напротив реквизитов Владелец и Наименование необходимо установить флаги в колонке «Поле поиска». Для этих реквизитов режим загрузки должен быть установлен в значение «Искать». Для реквизита ВидЦен режим устанавливаем в значение «Заполнять».
  5. Защита от создания дублей: Чтобы система не создавала новые элементы, если договор вдруг не будет найден в базе данных, найдем в настройках обработки флаг «Не создавать новых элементов» (в некоторых версиях он называется «Запретить создание новых элементов») и обязательно установим его.
  6. Выполнение загрузки: Нажмем кнопку «Загрузить». Обработка прочитает каждую строку файла, найдет в базе данных договор по владельцу-контрагенту и наименованию, после чего перезапишет в найденном объекте только поле «Вид цен». Ненайденные позиции будут просто пропущены, о чем система выведет информационное сообщение в окно сообщений.

Метод 2. Использование встроенных событий загрузки без изменения кода обработки

Иногда стандартного сопоставления полей недостаточно. Например, когда перед записью найденного объекта требуется выполнить дополнительную проверку или преобразовать текстовое значение из Excel в ссылку на элемент другого справочника по сложному алгоритму. Для этого в обработке «Загрузка данных из табличного документа» предусмотрена возможность написания произвольного кода на встроенном языке 1С непосредственно в пользовательском режиме.

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

В контексте этих обработчиков нам доступны предопределенные переменные платформы:

Давайте проанализируем пример кода, который можно написать в обработчике «Перед записью объекта» для контроля корректности загружаемых данных:


// Проверим, заполнена ли колонка с новым видом цен (допустим, это колонка №3)
НовоеНаименованиеВидаЦен = ТекстыЯчеек[3];

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

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

Метод 3. Современная альтернатива из Библиотеки стандартных подсистем (БСП)

Если вы работаете в современных конфигурациях (таких как 1С:ERP, Управление торговлей 11, Комплексная автоматизация, УНФ или Бухгалтерия предприятия 3.0), то вам вообще не требуется искать внешние обработки. В БСП интегрирован мощный и интуитивно понятный инструмент «Загрузка данных из файла».

Выясним, как работает этот механизм для решения нашей задачи:

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

Метод 4. Программный метод обновления данных через встроенный язык 1С

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

Давайте разберем эффективный алгоритм программного обновления реквизитов справочника при чтении Excel-файла через объект ТабличныйДокумент. Этот способ гораздо быстрее и надежнее работы через COM-соединение (которое требует обязательного наличия установленного Microsoft Excel на сервере или локальной машине пользователя).


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

КоличествоСтрок = ТабДок.ВысотаТаблицы;

// Начинаем транзакцию для ускорения процесса записи большого объема данных
НачатьТранзакцию();

Попытка
    Для НомерСтроки = 2 По КоличествоСтрок Цикл // Предполагаем, что в первой строке находится шапка таблицы
        
        // Получаем текстовые значения из ячеек
        КонтрагентИмя = СокрЛП(ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C1").ТекущийТекст);
        ДоговорИмя    = СокрЛП(ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C2").ТекущийТекст);
        ВидЦенИмя     = СокрЛП(ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C3").ТекущийТекст);
        
        // 1. Ищем контрагента
        СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию(КонтрагентИмя);
        Если Не ЗначениеЗаполнено(СсылкаКонтрагент) Тогда
            Сообщить("Строка " + НомерСтроки + ": Контрагент '" + КонтрагентИмя + "' не найден в базе. Пропускаем.");
            Продолжить;
        КонецЕсли;
        
        // 2. Ищем договор, подчиненный найденному контрагенту (владельцу)
        СсылкаДоговор = Справочники.ДоговорыContragents.НайтиПоНаименованию(ДоговорИмя, Истина, , СсылкаКонтрагент);
        Если Не ЗначениеЗаполнено(СсылкаДоговор) Тогда
            Сообщить("Строка " + НомерСтроки + ": Договор '" + ДоговорИмя + "' для контрагента '" + КонтрагентИмя + "' не найден. Пропускаем.");
            Продолжить;
        КонецЕсли;
        
        // 3. Ищем новый вид цен
        СсылкаВидЦен = Справочники.ВидыЦен.НайтиПоНаименованию(ВидЦенИмя);
        Если Не ЗначениеЗаполнено(СсылкаВидЦен) Тогда
            Сообщить("Строка " + НомерСтроки + ": Вид цен '" + ВидЦенИмя + "' не найден в справочнике. Пропускаем.");
            Продолжить;
        КонецЕсли;
        
        // 4. Блокируем и обновляем объект договора
        ДоговорОбъект = СсылкаДоговор.ПолучитьОбъект();
        Если ДоговорОбъект.ВидЦен <> СсылкаВидЦен Тогда
            ДоговорОбъект.ВидЦен = СсылкаВидЦен;
            
            // Записываем объект с отключением проверок для ускорения работы, если это допустимо
            ДоговорОбъект.ОбменДанными.Загрузка = Истина; 
            ДоговорОбъект.Записать();
        КонецЕсли;
        
    КонецЦикла;
    
    ЗафиксироватьТранзакцию();
    Сообщить("Загрузка и обновление данных успешно завершены!");
    
Исключение
    ОтменитьТранзакцию();
    Сообщить("Произошла критическая ошибка при записи данных. Транзакция отменена. Описание: " + ОписаниеОшибки());
КонецПопытки;

Использование свойства ОбменДанными.Загрузка = Истина позволяет временно отключить принудительные проверки бизнес-логики при записи объекта (например, подписки на события или проверку заполнения связанных реквизитов), что ускоряет загрузку в разы. Однако применять этот параметр стоит аккуратно, будучи абсолютно уверенным в корректности заносимых данных.

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

← На главную