При активной работе с базами данных 1С пользователи и администраторы регулярно сталкиваются с необходимостью массового обновления информации. Типичный пример: у вас есть огромный файл Excel, содержащий список контрагентов, их договоров и новые виды цен, которые необходимо привязать к этим договорам. Стандартная реакция многих специалистов, не до конца изучивших типовой инструментарий, — начать писать собственную обработку или заказывать доработку у программистов. Однако платформа 1С и Библиотека стандартных подсистем (БСП) предоставляют мощные встроенные механизмы, позволяющие решать такие задачи быстро и без программирования.
В этой статье мы подробно разберем, как обновить существующие реквизиты объектов в 1С на основе данных из табличного документа Excel. Мы рассмотрим стандартную обработку загрузки, научимся использовать встроенные обработчики событий для гибкой настройки логики и разберем современный механизм загрузки из БСП.
Существует устойчивое заблуждение, что внешняя обработка «Загрузка данных из табличного документа» (поставляемая на диске ИТС и в составе инструментов разработчика) предназначена исключительно для создания новых элементов справочников. Это не так. Она прекрасно справляется с обновлением существующих записей. Секрет кроется в правильной настройке полей поиска.
Давайте разберем по шагам, как настроить обработку для изменения видов цен в договорах контрагентов без риска создания дубликатов:
ДоговорыКонтрагентов.Владелец (это наш Контрагент) — указываем номер соответствующей колонки Excel.Наименование (наименование договора) — указываем номер соответствующей колонки Excel.ВидЦен (изменяемое поле) — указываем номер колонки с новым видом цен.Владелец и Наименование необходимо установить флаги в колонке «Поле поиска». Для этих реквизитов режим загрузки должен быть установлен в значение «Искать». Для реквизита ВидЦен режим устанавливаем в значение «Заполнять».Иногда стандартного сопоставления полей недостаточно. Например, когда перед записью найденного объекта требуется выполнить дополнительную проверку или преобразовать текстовое значение из Excel в ссылку на элемент другого справочника по сложному алгоритму. Для этого в обработке «Загрузка данных из табличного документа» предусмотрена возможность написания произвольного кода на встроенном языке 1С непосредственно в пользовательском режиме.
Рассмотрим ситуацию, когда нам нужно программно переопределить поведение системы в момент записи найденного договора. Перейдем на вкладку настроек обработчиков событий. Нам доступны несколько ключевых точек интеграции:
В контексте этих обработчиков нам доступны предопределенные переменные платформы:
Объект — ссылка на готовый к записи объект справочника, найденный в базе данных. Мы можем напрямую обращаться к его свойствам и изменять их.Отказ — булевая переменная. Если в процессе анализа данных мы присвоим ей значение Истина, текущий объект записан не будет.ТекстыЯчеек — массив текстовых значений текущей строки импортируемого файла, где индекс соответствует номеру колонки (начиная с 1).Давайте проанализируем пример кода, который можно написать в обработчике «Перед записью объекта» для контроля корректности загружаемых данных:
// Проверим, заполнена ли колонка с новым видом цен (допустим, это колонка №3)
НовоеНаименованиеВидаЦен = ТекстыЯчеек[3];
Если ЗначениеЗаполнено(НовоеНаименованиеВидаЦен) Тогда
// Пытаемся найти ссылку на справочник ВидыЦен в базе
НайденныйВидЦен = Справочники.ВидыЦен.НайтиПоНаименованию(НовоеНаименованиеВидаЦен);
Если ЗначениеЗаполнено(НайденныйВидЦен) Тогда
// Устанавливаем новое значение реквизита в объекте
Объект.ВидЦен = НайденныйВидЦен;
Иначе
// Если вид цен не найден в базе, выводим предупреждение и отменяем запись договора
ОбщееОписаниеОшибки = "Для договора " + Объект.Наименование + " указан несуществующий вид цен: " + НовоеНаименованиеВидаЦен;
ВызватьИсключение ОбщееОписаниеОшибки;
КонецЕсли;
КонецЕсли;
Этот подход позволяет гибко настраивать логику загрузки «на лету» без необходимости открывать конфигуратор, снимать конфигурацию с поддержки или плодить дубликаты внешних обработок на диске компьютера.
Если вы работаете в современных конфигурациях (таких как 1С:ERP, Управление торговлей 11, Комплексная автоматизация, УНФ или Бухгалтерия предприятия 3.0), то вам вообще не требуется искать внешние обработки. В БСП интегрирован мощный и интуитивно понятный инструмент «Загрузка данных из файла».
Выясним, как работает этот механизм для решения нашей задачи:
Бывают ситуации, когда объем данных исчисляется сотнями тысяч строк, а структура связей настолько сложна, что интерактивные обработки начинают зависать или не справляются с логикой поиска. В таком случае программисту проще написать быструю одноразовую обработку.
Давайте разберем эффективный алгоритм программного обновления реквизитов справочника при чтении Excel-файла через объект ТабличныйДокумент. Этот способ гораздо быстрее и надежнее работы через COM-соединение (которое требует обязательного наличия установленного Microsoft Excel на сервере или локальной машине пользователя).
// Создаем объект табличного документа для чтения файла
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлуExcel, СпособИмпортаТабличногоДокумента.Excel);
Исключение
ЗаписьЖурналаРегистрации("ЗагрузкаДанных", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка чтения файла: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КоличествоСтрок = ТабДок.ВысотаТаблицы;
// Начинаем транзакцию для ускорения процесса записи большого объема данных
НачатьТранзакцию();
Попытка
Для НомерСтроки = 2 По КоличествоСтрок Цикл // Предполагаем, что в первой строке находится шапка таблицы
// Получаем текстовые значения из ячеек
КонтрагентИмя = СокрЛП(ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C1").ТекущийТекст);
ДоговорИмя = СокрЛП(ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C2").ТекущийТекст);
ВидЦенИмя = СокрЛП(ТабДок.ПолучитьОбласть("R" + НомерСтроки + "C3").ТекущийТекст);
// 1. Ищем контрагента
СсылкаКонтрагент = Справочники.Контрагенты.НайтиПоНаименованию(КонтрагентИмя);
Если Не ЗначениеЗаполнено(СсылкаКонтрагент) Тогда
Сообщить("Строка " + НомерСтроки + ": Контрагент '" + КонтрагентИмя + "' не найден в базе. Пропускаем.");
Продолжить;
КонецЕсли;
// 2. Ищем договор, подчиненный найденному контрагенту (владельцу)
СсылкаДоговор = Справочники.ДоговорыContragents.НайтиПоНаименованию(ДоговорИмя, Истина, , СсылкаКонтрагент);
Если Не ЗначениеЗаполнено(СсылкаДоговор) Тогда
Сообщить("Строка " + НомерСтроки + ": Договор '" + ДоговорИмя + "' для контрагента '" + КонтрагентИмя + "' не найден. Пропускаем.");
Продолжить;
КонецЕсли;
// 3. Ищем новый вид цен
СсылкаВидЦен = Справочники.ВидыЦен.НайтиПоНаименованию(ВидЦенИмя);
Если Не ЗначениеЗаполнено(СсылкаВидЦен) Тогда
Сообщить("Строка " + НомерСтроки + ": Вид цен '" + ВидЦенИмя + "' не найден в справочнике. Пропускаем.");
Продолжить;
КонецЕсли;
// 4. Блокируем и обновляем объект договора
ДоговорОбъект = СсылкаДоговор.ПолучитьОбъект();
Если ДоговорОбъект.ВидЦен <> СсылкаВидЦен Тогда
ДоговорОбъект.ВидЦен = СсылкаВидЦен;
// Записываем объект с отключением проверок для ускорения работы, если это допустимо
ДоговорОбъект.ОбменДанными.Загрузка = Истина;
ДоговорОбъект.Записать();
КонецЕсли;
КонецЦикла;
ЗафиксироватьТранзакцию();
Сообщить("Загрузка и обновление данных успешно завершены!");
Исключение
ОтменитьТранзакцию();
Сообщить("Произошла критическая ошибка при записи данных. Транзакция отменена. Описание: " + ОписаниеОшибки());
КонецПопытки;
Использование свойства ОбменДанными.Загрузка = Истина позволяет временно отключить принудительные проверки бизнес-логики при записи объекта (например, подписки на события или проверку заполнения связанных реквизитов), что ускоряет загрузку в разы. Однако применять этот параметр стоит аккуратно, будучи абсолютно уверенным в корректности заносимых данных.
Таким образом, мы детально разобрали несколько надежных способов изменения реквизитов справочников 1С на основании внешних файлов Excel. Выбор конкретного метода зависит от версии используемой конфигурации, сложности сопутствующей бизнес-логики и объема обрабатываемых данных. Использование штатных инструментов экономит время разработчика и страхует базу данных от появления дублей и логических ошибок.