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

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

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

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

Разбор проблемы: идентификаторы против данных

Первое, с чем сталкивается разработчик — это понимание того, что именно возвращает платформа при обращении к выделенным строкам. Рассмотрим ситуацию: у нас есть таблица на форме, связанная с табличной частью объекта (Объект.Товары). Когда мы обращаемся к свойству Элементы.Товары.ВыделенныеСтроки, мы получаем массив.

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

Проанализируем ситуацию, описанную в сообщениях форума. Пользователь пытался передать эти строки в типовую обработку «Групповое изменение реквизитов». Это не сработало, так как типовая обработка ожидает массив ссылок (AnyRef), которые существуют в базе данных постоянно. Строки же внешней обработки живут только «в памяти» формы и ссылок в понимании объектов БД не имеют.

Алгоритм изменения данных в выделенных строках

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

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

Посмотрим на пример кода, который реализует эту логику на стороне клиента:


&НаКлиенте
Процедура ИзменитьВыделенные(Команда)

    // 1. Получаем массив идентификаторов выделенных строк
    МассивИдентификаторов = Элементы.СписокНоменклатуры.ВыделенныеСтроки;

    // 2. Организуем цикл по всем выделенным элементам
    Для Каждого ИдентификаторСтроки Из МассивИдентификаторов Цикл

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

        // 4. Проверяем, что строка была найдена (защита от ошибок)
        Если СтрокаДанных <> Неопределено Тогда
            // Изменяем нужные нам реквизиты
            СтрокаДанных.Цена = 100;
            СтрокаДанных.СтавкаНДС = ПредопределенноеЗначение("Перечисление.СтавкиНДС.НДС20");
        КонецЕсли;

    КонецЦикла;

КонецПроцедуры

В данном примере мы используем метод НайтиПоИдентификатору, который является ключевым инструментом. Он позволяет связать визуальный элемент (строку в таблице на экране) с программным объектом (строкой в оперативной памяти).

Разница между ДанныеСтроки() и НайтиПоИдентификатору()

Часто возникает вопрос: почему нельзя использовать метод Элементы.Таблица.ДанныеСтроки(Идентификатор)? Давайте выясним причину. Метод ДанныеСтроки возвращает структуру, предназначенную в основном для чтения данных на клиенте. Хотя в некоторых случаях через него можно попытаться что-то изменить, правильным и надежным способом изменения данных в 1С считается работа непосредственно с коллекцией Объект.ТабличнаяЧасть.

При использовании НайтиПоИдентификатору вы получаете объект типа ДанныеФормыЭлементКоллекции. Любые изменения в этом объекте мгновенно отражаются в интерфейсе пользователя без дополнительных команд обновления формы. Это происходит благодаря механизму связей (биндингу) между реквизитами формы и элементами управления.

Перенос логики на сервер

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

Рассмотрим, как это реализовать:


&НаКлиенте
Процедура КомандаИзменитьНаСервере(Команда)
    // Собираем идентификаторы в массив
    Выделенные = Элементы.ТаблицаТовары.ВыделенныеСтроки;
    
    // Вызываем серверный метод
    ИзменитьРеквизитыНаСервере(Выделенные);
КонецПроцедуры

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

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

Особенности работы с Динамическим списком

Стоит отметить, что поведение свойства ВыделенныеСтроки меняется, если ваша таблица на форме — это не Табличная часть, а Динамический список. В случае с динамическим списком (например, если вы вывели список документов во внешней обработке), массив ВыделенныеСтроки будет содержать Ссылки (уникальные идентификаторы из БД), а не числовые идентификаторы строк формы.

Проанализируем разницу в коде для Динамического списка:

  1. Для ТЧ: Идентификатор (Число) -> Объект.ТЧ.НайтиПоИдентификатору().
  2. Для Динамического списка: Ссылка (ДокументСсылка/СправочникСсылка) -> Работа через ПолучитьОбъект() (если нужно менять данные в базе) или использование ссылки в запросах.

Нюансы интерфейса и завершение работы

Когда мы программно меняем данные в таблице внешней обработки, система автоматически устанавливает признак Модифицированность для формы. Это означает, что при попытке закрыть обработку 1С может спросить: «Данные были изменены. Сохранить изменения?». Однако у внешней обработки нет встроенной кнопки «Записать», как у документа. Если вы не предполагаете сохранение этих данных в какой-то файл или внешнюю базу, после выполнения цикла изменений можно программно сбросить этот флаг:

ЭтаФорма.Модифицированность = Ложь;

Также убедитесь, что в свойствах таблицы на форме установлен режим выделения Множественный. Если там стоит Одиночный, пользователь просто не сможет выделить несколько строк зажатой клавишей Ctrl или Shift, и ваш массив всегда будет содержать только один элемент.

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

← На главную