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

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

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

Базовый алгоритм замены через цикл

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

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


Для Каждого Стр Из Объект.Товары Цикл
    Если Стр.Номенклатура = СтароеЗначение Тогда
        Стр.Номенклатура = НовоеЗначение;
    КонецЕсли;
КонецЦикла;

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

Выбор подходящего события для выполнения замены

Выясним, на какое событие формы лучше всего «повесить» логику замены. Пользователь в теме предлагал использовать флажок типа Булево для отметки строк. Если мы идем по этому пути, то наиболее логичным местом для вызова процедуры замены будет событие ПриИзменении того поля, которое выбирает пользователь для массового заполнения.

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


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

Оптимизация работы через штатное выделение строк

Давайте проанализируем более современный подход. В управляемом интерфейсе 1С 8.3 добавлять специальный реквизит Выбрано (флажок) часто бывает излишним. Платформа уже предоставляет пользователю возможность выделять строки с помощью клавиш Shift или Ctrl.

Для реализации такой замены нам потребуется коллекция ВыбранныеСтроки элемента формы «Таблица». Рассмотрим, как программно обработать только те строки, которые пользователь выделил мышкой:


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

Этот метод значительно повышает удобство работы пользователя (UX), так как избавляет его от необходимости проставлять галочки в каждой строке вручную.

Использование команды на панели инструментов

Разберем важный нюанс: использование события ПриИзменении для массовой замены может привести к случайным ошибкам. Если пользователь случайно изменит значение в строке, когда у него «зависли» выделенными другие строки, код сработает автоматически. Чтобы избежать такой ситуации, рекомендуется выносить функцию замены в отдельную кнопку на командной панели табличной части.

Посмотрим на алгоритм создания такой команды:

  1. Создайте новую команду формы, например, ЗаполнитьВыделенные.
  2. Перетащите её на командную панель таблицы Товары.
  3. В обработчике команды вызовите серверную процедуру для обработки данных.

Перенос обработки на сервер для повышения производительности

Если табличная часть документа содержит сотни строк, обработка на клиенте может привести к кратковременному замиранию интерфейса. Правильнее выполнять расчеты на стороне сервера. Проанализируем, как передать управление на сервер и обратно:


&НаКлиенте
Процедура КомандаЗаполнить(Команда)
    ВыбранныеСтроки = Элементы.Товары.ВыбранныеСтроки;
    Если ВыбранныеСтроки.Количество() = 0 Тогда
        ПоказатьПредупреждение(, "Пожалуйста, выделите строки для замены!");
        Возврат;
    КонецЕсли;
    
    ЗаполнитьНаСервере(ВыбранныеСтроки);
КонецПроцедуры

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

Обратите внимание на свойство Модифицированность. Установка его в значение Истина гарантирует, что система предложит сохранить документ при закрытии, так как изменения были внесены программно на сервере.

Важные аспекты: пересчет итогов и логические проверки

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

Во-первых, пересчет сумм. Если вы заменяете реквизит, от которого зависят другие поля (например, замена Номенклатуры должна менять Цену, Сумму и НДС), простого присваивания значения недостаточно. Вам необходимо вызвать те же экспортные процедуры из модулей документа или менеджера, которые вызываются при ручном вводе данных. Чаще всего это процедуры вида РассчитатьСуммуТЧ.

Во-вторых, связи параметров выбора. Если новый реквизит зависит от настроек в шапке документа (например, выбор Договора зависит от Контрагента), обязательно добавьте проверку соответствия. В противном случае программная замена позволит установить некорректные данные, что приведет к ошибкам при проведении документа.

В-третьих, метод ЗаполнитьЗначенияСвойств. Если вам нужно скопировать сразу несколько полей из одной «эталонной» строки в другие, используйте ЗаполнитьЗначенияСвойств(Приемник, Источник). Это работает быстрее и делает код чище.

Мы рассмотрели различные способы реализации массовой замены реквизитов. Выбор конкретного метода зависит от требований к интерфейсу и объема данных в ваших документах.

← На главную