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

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

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

Получение текущих данных и имени колонки в Обычных формах

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

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

  1. Получение данных строки: ТабличноеПолеОбъекта.ТекущиеДанные — возвращает структуру с данными текущей выделенной строки.
  2. Получение имени колонки: ТабличноеПолеОбъекта.ТекущаяКолонка.Имя — возвращает строковое представление имени колонки, в которой стоит курсор.

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


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

Защита от ошибок при пустой табличной части

Рассмотрим подробнее уязвимость приведенного выше базового кода. Если пользователь запустит обработку в пустой табличной части (где нет ни одной строки) или фокус вообще не установлен на элемент таблицы, свойство ТабличноеПолеОбъекта.ТекущиеДанные вернет значение Неопределено. Попытка получить данные по индексу колонки из значения Неопределено приведет к критической ошибке.

Чтобы избежать аварийного завершения работы обработки, добавим проверку наличия текущих данных:


Если ТабличноеПолеОбъекта.ТекущиеДанные = Неопределено Тогда
    Сообщить("Не выбрана строка для получения значения!");
    Возврат;
КонецЕсли;

Интерактивное подтверждение заполнения

При массовом заполнении данных всегда есть риск того, что пользователь нажал кнопку случайно и испортил существующие данные во всей колонке. Хорошей практикой является запрос подтверждения.

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


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

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

Отсутствие вызова событий формы при программном заполнении

Проанализируем еще одну важную деталь. При программном заполнении значений через прямое присвоение (например, нСтрока[ИмяКолонки] = нЗначение;) стандартные события элементов управления формы не отрабатывают. Событие ПриИзменении для колонки не будет вызвано.

Что это значит на практике? Если в документе есть логика пересчета (например, при изменении количества должна автоматически пересчитываться сумма строки), то при использовании внешней обработки суммы останутся старыми. Вам необходимо самостоятельно прописывать вызов нужных процедур или дублировать логику пересчета внутри цикла обработки.

Специфика Управляемых Форм (УФ)

Рассмотрим, как обстоят дела в Управляемых формах (УФ). Для них конструкция получения текущего элемента выглядит иначе:


// Получение имени колонки в УФ на клиенте:
ИмяТекущейКолонки = Элементы.ИмяТаблицыФормы.ТекущийЭлемент.Имя;

Однако в современных конфигурациях на базе Библиотеки Стандартных Подсистем (БСП) для внешних обработок заполнения процедура Инициализировать больше не используется. Вместо этого применяется функция СведенияОВнешнейОбработке, а само выполнение происходит в серверной процедуре ВыполнитьКоманду.

Поскольку процедура ВыполнитьКоманду выполняется на сервере, у нас нет прямого доступа к клиентским элементам формы (Элементы) и мы не знаем, на какой ячейке стоял курсор. Чтобы реализовать подобный функционал в УФ, потребуется вносить изменения в код самой конфигурации, передавая данные о текущей колонке с клиента на сервер при вызове команды обработки. Описанный выше универсальный и простой механизм работает "из коробки" только для Обычных форм.

← На главную