Как отменить запись документа при обмене данными и настроить выделение цветом в форме списка?

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

При настройке обмена данными между конфигурациями (например, между «Бухгалтерия предприятия 2.0» и «Управление торговлей 10.3») часто возникает задача защитить определенные документы в базе-приемнике от перезаписи. Типичный сценарий: если документу в базе-приемнике присвоена категория (например, «Не редактировать»), его данные не должны обновляться при повторных выгрузках из базы-источника. Рассмотрим, в каких обработчиках Конвертации данных следует выполнять проверку, как составить оптимальный запрос и как правильно раскрасить такие документы в форме списка.

Выбор обработчика в правилах конвертации объектов (ПКО)

Разберем последовательность работы механизмов загрузки в «Конвертации данных 2.0»:

  1. «Перед загрузкой» — на этом этапе выполняется только подготовка данных для поиска. Ссылка на существующий в базе объект еще не получена по полям поиска, поэтому проверить категории текущего документа в базе-приемнике здесь нельзя.
  2. «После загрузки» или «Перед записью объекта» — эти события идеально подходят для решения задачи. К моменту их вызова поиск объекта в информационной базе уже завершен, в переменной СсылкаНаОбъект (или Объект.Ссылка) доступна ссылка на существующий документ.

Если мы установим флаг Отказ = Истина; в обработчике «После загрузки», запись текущего объекта будет корректно пропущена, при этом загрузка остальных объектов из пакета обмена продолжится без прерывания транзакции.

Реализация проверки категории и оптимизация запроса

Проанализируем структуру регистра сведений КатегорииОбъектов. В типовых конфигурациях на обычных формах составной кластерный индекс СУБД строится по измерениям в порядке их следования: сначала Объект, затем Категория.

Если в запросе указать условие только по объекту, СУБД выполнит сканирование диапазона (Index Scan / Seek по первому полю) среди всех категорий, привязанных к объекту. Если же мы сразу укажем и конкретную категорию, запрос выполнит точечный поиск по полному ключу индекса (Exact Match Seek), что обеспечивает максимальное быстродействие.

Посмотрим на реализацию проверки в обработчике «После загрузки» нужного ПКО:


Если ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    1
    |ИЗ
    |    РегистрСведений.КатегорииОбъектов КАК КатегорииОбъектов
    |ГДЕ
    |    КатегорииОбъектов.Объект = &Объект
    |    И КатегорииОбъектов.Категория = &Категория";
    
    Запрос.УстановитьПараметр("Объект", СсылкаНаОбъект);
    Запрос.УстановитьПараметр("Категория", Параметры.КатегорияНеРедактировать);
    
    Если НЕ Запрос.Выполнить().Пустой() Тогда
        Отказ = Истина;
    КонецЕсли;
КонецЕсли;

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

Также вместо полного отказа от записи через Отказ = Истина; можно программно взвести флаг НеЗамещать = Истина;, если требуется оставить объект в базе нетронутым стандартными механизмами конвертации.

Оптимальная раскраска строк в форме списка документа

Выясним причину, почему нельзя выполнять запросы к базе данных в обработчике ПриВыводеСтроки. Это событие вызывается для каждой отдельной строки, что приводит к множественным одиночным запросам к СУБД и критическому падению производительности при прокрутке списка.

В обычном приложении для оформления списков правильно использовать обработчик ПриПолученииДанных табличного поля. Он принимает сразу массив оформлений для всех видимых на экране строк, что позволяет обработать данные одним пакетным запросом.

Разберем по шагам реализацию раскраски строк:

  1. Обходим переданную коллекцию ОформленияСтрок и собираем массив ссылок документов.
  2. Выполняем один запрос к регистру сведений КатегорииОбъектов с условием В (&МассивСсылок).
  3. Заполняем соответствие или массив найденных документов.
  4. Повторно проходим по коллекции ОформленияСтрок и устанавливаем цвет фона или текста для тех строк, документы которых присутствуют в выборке.

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


Процедура ДокументСписокПриПолученииДанных(Элемент, ОформленияСтрок)
    
    МассивСсылок = Новый Массив;
    Для Каждого Оформление Из ОформленияСтрок Цикл
        МассивСсылок.Добавить(Оформление.ДанныеСтроки.Ссылка);
    КонецЦикла;
    
    Если МассивСсылок.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    КатегорииОбъектов.Объект КАК Объект
    |ИЗ
    |    РегистрСведений.КатегорииОбъектов КАК КатегорииОбъектов
    |ГДЕ
    |    КатегорииОбъектов.Объект В(&МассивСсылок)
    |    И КатегорииОбъектов.Категория = &Категория";
    
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    Запрос.УстановитьПараметр("Категория", Справочники.КатегорииОбъектов.НайтиПоНаименованию("Не редактировать"));
    
    Выборка = Запрос.Выполнить().Выбрать();
    СоответствиеОбъектов = Новый Соответствие;
    Пока Выборка.Следующий() Цикл
        СоответствиеОбъектов.Вставить(Выборка.Объект, Истина);
    КонецЦикла;
    
    Для Каждого Оформление Из ОформленияСтрок Цикл
        Если СоответствиеОбъектов[Оформление.ДанныеСтроки.Ссылка] <> Неопределено Тогда
            Оформление.ЦветФона = WebЦвета.СветлоСерый;
            Оформление.ЦветТекста = WebЦвета.ТемноКрасный;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

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

← На главную