Как изменить данные объектов конфигурации и регистров при изменении поля строки табличной части обработки в 1С 8.3?

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

При разработке сервисных обработок в платформах 1С:Предприятие 8.3 с управляемым интерфейсом («Такси») часто возникает задача группового или построчного редактирования данных. Например, требуется загрузить список элементов (номенклатуру, документы или записи регистров) в табличную часть обработки, позволить пользователю скорректировать реквизиты прямо в ячейках таблицы и сразу же отразить эти изменения в базе данных.

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

1. Получение данных измененной строки на клиенте

Разберем механику работы управляющих элементов. Когда пользователь меняет значение в ячейке табличной части обработки, срабатывает событие элемента формы ПриИзменении. Обработка этого события начинается на клиенте.

Для того чтобы получить значения реквизитов строки, в которой произошло изменение, используется свойство элемента формы ТекущиеДанные. Важно помнить, что свойство ТекущиеДанные доступно только в процедурах с директивой &НаКлиенте.

Посмотрим, как выглядит клиентский обработчик события при изменении поля «Вес» в табличной части «НоменклатураСРеквизитами»:


&НаКлиенте
Процедура НоменклатураСРеквизитамиВесПриИзменении(Элемент)
    
    // Получаем данные текущей активной строки
    ТекущаяСтрокаДанных = Элементы.НоменклатураСРеквизитами.ТекущиеДанные;
    
    Если ТекущаяСтрокаДанных = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем ссылку на редактируемый объект и новое значение реквизита
    СсылкаНаОбъект = ТекущаяСтрокаДанных.Номенклатура;
    НовоеЗначениеВеса = ТекущаяСтрокаДанных.Вес;
    
    // Передаем данные на сервер для выполнения записи
    ИзменитьРеквизитОбъектаНаСервере(СсылкаНаОбъект, НовоеЗначениеВеса);
    
КонецПроцедуры

2. Оптимизация передачи данных на сервер

Выясним, как правильно организовать серверный вызов. В 1С есть две основные директивы для работы с сервером из формы:

  1. &НаСервере — при вызове процедура передает на сервер весь контекст управляемой формы (все реквизиты и строки табличных частей). Это создает высокую нагрузку на сеть и сервер при больших таблицах.
  2. &НаСервереБезКонтекста — передает на сервер только явным образом указанные параметры, что существенно ускоряет работу интерфейса.

Для нашей задачи идеальным решением является использование контекстно-независимого вызова &НаСервереБезКонтекста. Мы передаем только ссылку на изменяемый элемент и значение, которое необходимо записать.

3. Запись изменений в объекты базы данных (Справочники и Документы)

Рассмотрим порядок действий при обновлении ссылочных типов данных (справочников, документов, планов видов характеристик). Чтобы изменить данные ссылочного объекта в базе, выполняем следующий алгоритм:

  1. Получаем объект базы данных из ссылки с помощью метода ПолучитьОбъект().
  2. Изменяем значение нужного реквизита.
  3. Вызываем метод Записать().

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


&НаСервереБезКонтекста
Процедура ИзменитьРеквизитОбъектаНаСервере(СсылкаНаОбъект, НовоеЗначениеВеса)
    
    Если Не ЗначениеЗаполнено(СсылкаНаОбъект) Тогда
        Возврат;
    КонецЕсли;
    
    Попытка
        // Получаем объект для редактирования
        ОбъектБД = СсылкаНаОбъект.ПолучитьОбъект();
        
        Если ОбъектБД <> Неопределено Тогда
            // Меняем реквизит объекта
            ОбъектБД.Вес = НовоеЗначениеВеса;
            
            // Записываем изменения в базу данных
            ОбъектБД.Записать();
        КонецЕсли;
    Исключение
        // Информируем пользователя в случае ошибки доступа или блокировки
        ВызватьИсключение СтрШаблон("Не удалось обновить объект %1. Ошибка: %2", 
            Строка(СсылкаНаОбъект), ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

4. Изменение данных в регистрах сведений

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

Рассмотрим пример обновления ресурса независимого регистра сведений:


&НаСервереБезКонтекста
Процедура ОбновитьЦенуВРегистреНаСервере(НоменклатураСсылка, НоваяЦена)
    
    // Создаем менеджер записи регистра сведений
    МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
    
    // Заполняем ключевые измерения для поиска записи
    МенеджерЗаписи.Период = ТекущаяДата();
    МенеджерЗаписи.Номенклатура = НоменклатураСсылка;
    
    // Читаем существующую запись или формируем новую
    МенеджерЗаписи.Прочитать();
    
    // Устанавливаем новое значение ресурса
    МенеджерЗаписи.Цена = НоваяЦена;
    
    // Записываем изменения
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

5. Выбор архитектурного подхода к изменению данных

Запись объекта базы данных при каждом изменении симметричной ячейки (событие ПриИзменении) имеет свои плюсы и минусы, которые важно учитывать при проектировании решений:

Мгновенная запись (по событию поля):

  1. Плюсы: Данные гарантированно сохраняются сразу после ввода; другие пользователи мгновенно видят актуальные значения.
  2. Минусы: Создаются частые транзакции записи к СУБД. При активной работе нескольких пользователей или слабом сервере возможны подвисания интерфейса и блокировки таблиц.

Отложенная групповая запись (по кнопке):

  1. Плюсы: Пользователь быстро редактирует таблицу в оперативной памяти формы. Транзакция записи выполняется единоразово для всех измененных строк.
  2. Минусы: Если пользователь закроет форму без сохранения, изменения будут утеряны.

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

← На главную