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

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

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

Особенности работы со свойством ВыделенныеСтроки

Для реализации такой задачи необходимо учитывать контекст выполнения и модель работы управляемой формы в платформе 1С:Предприятие 8.3:

  1. Свойство ВыделенныеСтроки принадлежит элементу интерфейса (ТаблицаФормы) и доступно исключительно на клиенте. Попытка обратиться к коллекции Элементы.Сотрудники.ВыделенныеСтроки в процедуре с директивой &НаСервере или &НаСервереБезКонтекста вызовет исключение.
  2. Значением свойства ВыделенныеСтроки является массив числовых идентификаторов строк, а не сами ссылки на строки или прикладные объекты.
  3. Метод поиска по идентификатору НайтиПоИдентификатору() доступен только у объекта ДанныеФормыКоллекция (реквизит формы, например, Объект.Сотрудники). У табличной части прикладного объекта ДокументОбъект такого метода нет.

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

Оптимальное решение: групповое изменение строк в контексте формы

Рассмотрим правильный алгоритм обновления данных. Если документ открыт пользователем и требуется обновить значения прямо в форме (чтобы пользователь увидел результат и сам нажал кнопку записи), переводить данные в прикладной объект через РеквизитФормыВЗначение не требуется. Достаточно изменить данные в реквизите формы Объект.Сотрудники.

Посмотрим на пример клиентского обработчика команды:


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

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


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

Обратите внимание: перед присвоением значения реквизиту обязательно проверяется условие СтрокаДанных <> Неопределено, так как в момент вызова строка могла быть удалена или идентификатор мог стать невалидным.

Как сопоставить выделенные строки с ДокументОбъект (для записи без интерактивного сохранения)

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

Так как у коллекции ДокументОбъект.<Имя>.Сотрудники отсутствует метод НайтиПоИдентификатору, сопоставление можно выполнить следующими способами:

  1. По индексу строки: на сервере формы перед конвертацией получаем строку через НайтиПоИдентификатору(ИД), затем берем ее индекс с помощью метода Объект.Сотрудники.Индекс(СтрокаДанных). В прикладном объекте строка будет находиться по точно такому же индексу: ДокОбъект.Сотрудники[Индекс].
  2. По номеру строки: у каждой строки в данных формы есть реквизит НомерСтроки. В табличной части объекта поиск выполняется стандартным методом: ДокОбъект.Сотрудники.Найти(НомерСтроки, "НомерСтроки").
  3. По ключевым реквизитам: если табличная часть содержит гарантированно уникальное поле (например, ссылку на элемент справочника Сотрудники), поиск в объекте выполняется методом ДокОбъект.Сотрудники.Найти(ЗначениеСотрудника, "Сотрудник").

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


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

Настройка множественного выбора в интерфейсе

Чтобы пользователь мог выбирать сразу несколько строк с помощью клавиш Shift или Ctrl, необходимо проверить параметры элемента таблицы на форме:

  1. Откройте форму документа в конфигураторе.
  2. Выделите элемент управления таблицы (в нашем примере Сотрудники).
  3. В палитре свойств найдите параметр РежимВыделенияСтроки или свойство МножественныйВыбор и установите его значение в Истина.

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

← На главную