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

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

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

Поиск документа по номеру: важные нюансы

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

Для поиска мы будем использовать метод НайтиПоНомеру(). Рассмотрим пример кода, который часто используется в подобных обработках:


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

Проанализируем метод НайтиПоНомеру(Номер, Дата). Если в конфигурации для данного типа документа установлено свойство Периодичность (например, "Год"), то поиск без указания второго параметра может вернуть пустую ссылку, даже если документ с таким номером существует. Параметр Дата указывает системе, в каком интервале времени (периоде уникальности номеров) искать документ. Если номера уникальны в пределах года, достаточно передать любую дату из нужного года.

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

Изменение реквизитов: от ссылки к объекту

Найденная переменная ДокументСсылка является ссылкой. Ссылки в 1С предназначены только для чтения данных. Чтобы изменить значение реквизита, нам необходимо получить объект документа. Рассмотрим, как правильно это сделать и изменить торгового представителя:


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

Выясним причину использования блока Попытка...Исключение. Проведение документа — это сложная операция, которая может сорваться из-за отсутствия остатков на складе, превышения лимита задолженности или блокировок со стороны других пользователей. Использование "попытки" гарантирует, что ваша обработка не остановится на середине списка из-за одной ошибки, а продолжит работу с остальными документами.

Оптимизация: работа через запросы

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

  1. Выгружаем все номера из таблицы значений в массив.
  2. Передаем массив в запрос.
  3. В запросе соединяем наш список номеров с таблицей документов.
  4. Обходим результат запроса и меняем данные.

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

Лучшие практики и безопасность

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

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


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

Это позволит изменить реквизит даже в тех документах, которые "не хотят" проводиться в текущем периоде из-за изменившихся настроек учета.

2. Проверка на идентичность. Перед записью всегда проверяйте, действительно ли новое значение отличается от старого. Нет смысла записывать и перепроводить документ, если в нем уже указан правильный торговый представитель. Это сэкономит время и уменьшит размер логов транзакций.


Если ДокументОбъект.ТорговыйПредставитель <> ТТ_Ссылка Тогда
    ДокументОбъект.ТорговыйПредставитель = ТТ_Ссылка;
    ДокументОбъект.Записать();
КонецЕсли;

3. Типизация данных. Помните, что реквизиты в 1С имеют строгую типизацию. Если реквизит ТорговыйПредставитель имеет тип СправочникСсылка.ФизическиеЛица, вы не можете присвоить ему просто строку из Excel. Обязательно выполните поиск ссылки в справочнике, прежде чем присваивать значение объекту документа.

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

← На главную