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

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

В процессе сопровождения баз данных 1С часто возникают задачи по массовому изменению реквизитов. Одной из типичных ситуаций является необходимость привести номера подчиненных документов (например, СчетФактураВыданный) в соответствие с номерами документов-оснований (например, РеализацияТоваровУслуг). Рассмотрим, какими способами можно решить эту задачу, разберем типичные ошибки программирования и выясним, как правильно работать с объектами метаданных для записи изменений.

Ограничения стандартной обработки «Групповое изменение реквизитов»

Стандартная типовая обработка «Групповое изменение реквизитов» (входящая в состав БСП) — это мощный инструмент, но он имеет свои пределы. Зачастую в ней невозможно напрямую прописать обращение через точку к реквизитам другого документа, например: Объект.ДокументОснование.Номер. Это происходит потому, что обработка ориентирована на прямую замену значений простыми типами или ссылками.

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

  1. Режим разработчика в типовой обработке: В некоторых версиях БСП можно включить возможность выполнения произвольного алгоритма в «Дополнительных параметрах». Это позволит написать небольшой фрагмент кода, который будет выполнен для каждого отобранного объекта.
  2. Собственная обработка: Написание внешнего скрипта или обработки, что дает полный контроль над процессом, позволяет гибко настроить условия отбора через запрос и корректно обработать ошибки.

Разбор программного решения: от запроса до записи

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

Шаг 1. Формирование запроса. Сначала нам нужно получить данные. Использование запроса — самый эффективный способ, так как он минимизирует нагрузку на сервер. Нам необходима ссылка на документ и номер его основания.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СчетФактураВыданный.Ссылка КАК Ссылка,
    |	СчетФактураВыданный.ДокументОснование.Номер КАК ДокументОснованиеНомер
    |ИЗ
    |	Документ.СчетФактураВыданный КАК СчетФактураВыданный
    |ГДЕ
    |	СчетФактураВыданный.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
    |	И СчетФактураВыданный.Проведен = ИСТИНА
    |	И СчетФактураВыданный.ПометкаУдаления = ЛОЖЬ";

Запрос.УстановитьПараметр("ДатаНачала", '20230101');
Запрос.УстановитьПараметр("ДатаОкончания", '20231231');

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

Шаг 2. Обход результатов и изменение данных. Здесь важно помнить о ключевом отличии Ссылки от Объекта. Попытка изменить реквизит непосредственно у переменной, полученной из запроса (ссылки), приведет к ошибке «Метод объекта не обнаружен (Записать)». Ссылка предназначена только для чтения. Для изменения данных необходимо получить объект документа.

Проанализируем правильный цикл обработки:


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

Важные нюансы при записи объектов

При массовом изменении документов мы часто сталкиваемся с тем, что стандартные проверки в модуле объекта (например, проверка заполнения обязательных полей, которые были добавлены в конфигурацию позже создания документа) мешают записи. Чтобы обойти это и изменить только нужный нам реквизит «малой кровью», рекомендуется использовать свойство ОбменДанными.Загрузка.

Разберем, как это работает: установка флага ОбменДанными.Загрузка = Истина сообщает системе, что объект записывается в режиме загрузки данных, и большинство подписок на события и встроенных проверок будет пропущено. Это значительно ускоряет процесс и позволяет избежать блокирующих ошибок.


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

Использование инструментов разработчика (DevTools)

Если задача разовая и писать код в конфигураторе долго, профессионалы часто используют сторонние консоли кода и инструменты, такие как Инструменты разработчика (автор ТормозИТ). Это универсальный набор обработок, который позволяет:

Это значительно экономит время при поиске и исправлении ошибок в данных.

Проблема отладки на сервере

Часто программисты сталкиваются с тем, что при запуске обработки код выполняется, но точки останова внутри процедур &НаСервере или &НаСервереБезКонтекста не срабатывают. Это означает, что на сервере 1С не включен режим отладки.

Выясним, как это исправить. Для включения отладки в клиент-серверном варианте необходимо:

  1. Зайти в реестр Windows на сервере, где установлен агент сервера 1С.
  2. Найти ветку службы 1C:Enterprise 8.3 Server Agent.
  3. В параметре ImagePath добавить ключ -debug.
  4. Обязательно перезапустить службу сервера 1С.

Только после этих действий конфигуратор сможет «подцепиться» к серверному процессу и позволить вам проанализировать значения переменных в момент выполнения кода.

Рекомендации по безопасности при массовых изменениях

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

Рассмотрим пример ограничения запроса для теста:


// Добавьте это условие в запрос для проверки на одном документе
// | ГДЕ СчетФактураВыданный.Ссылка = &ТестоваяСсылка

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

← На главную