Как ограничить выполнение процедуры конкретной колонкой в Таблице Значений 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Анализ механизма работы формулы в Таблице Значений

Для начала разберем, как устроено событие выбора в «клюшках» (1С 7.7). Когда мы открываем свойства элемента формы ТаблицаЗначений и на вкладке «Дополнительно» прописываем имя процедуры в поле «Формула», эта процедура становится обработчиком события выбора для всего объекта целиком. Платформа не предоставляет штатной возможности назначить отдельную формулу для каждой колонки в визуальном редакторе. Следовательно, вся ответственность за фильтрацию действий ложится на плечи программиста внутри текста самой процедуры.

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

Использование метода ТекущаяКолонка()

Основным инструментом для решения нашей задачи является метод ТекущаяКолонка(). Давайте рассмотрим его возможности подробнее. Этот метод может возвращать два типа данных в зависимости от того, как мы его вызываем:

  1. Номер колонки (число) — порядковый номер столбца в таблице (начиная с 1).
  2. Идентификатор колонки (строка) — текстовое название, заданное при создании колонки.

Рассмотрим первый, наиболее очевидный вариант решения, который был предложен в обсуждении. Если мы точно знаем, что справочник должен открываться только в 9-й колонке, код будет выглядеть следующим образом:


Процедура Формула()
    // Проверяем, в той ли колонке находится пользователь
    Если ТаблицаЗначений.ТекущаяКолонка() = 9 Тогда
        Спр = СоздатьОбъект("Справочник.Работники");
        // Открываем форму выбора справочника
        Если Спр.ВыбратьЭлемент() = 1 Тогда
            // Записываем выбранное значение в текущую строку, в 9-ю колонку
            ТаблицаЗначений.УстановитьЗначение(ТаблицаЗначений.ТекущаяСтрока(), 9, Спр.ТекущийЭлемент());
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Почему обращение по номеру колонки — это «мина замедленного действия»

Проанализируем риски использования жесткого кодирования номера колонки (число 9). В реальной разработке конфигурация постоянно меняется. Если завтра заказчик попросит добавить новую колонку в начало таблицы, ваша 9-я колонка станет 10-й. При этом код останется привязанным к номеру 9, и логика выбора сотрудников начнет срабатывать в совершенно неподходящем месте.

Рекомендуемый подход — использование идентификаторов колонок. При создании колонок программно (метод НоваяКолонка()) или в конфигураторе, всегда задавайте им осмысленные имена. Выясним, как изменится наш код, если мы назовем колонку "Сотрудник":


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

Разбор нюансов работы со справочниками в 1С 7.7

Обратим внимание на важную деталь в коде, которую новички часто упускают. Метод ВыбратьЭлемент() возвращает 1, если пользователь выбрал объект, и 0, если он закрыл справочник или нажал «Отмена». Если не использовать условие Если ... = 1 Тогда, программа может попытаться записать пустое значение или вызвать ошибку, если пользователь передумал выбирать сотрудника.

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

Оптимизация визуального обновления

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


Процедура Формула()
    Если ТаблицаЗначений.ТекущаяКолонка() = "Сотрудник" Тогда
        Спр = СоздатьОбъект("Справочник.Работники");
        Если Спр.ВыбратьЭлемент() = 1 Тогда
            ТаблицаЗначений.УстановитьЗначение(ТаблицаЗначений.ТекущаяСтрока(), "Сотрудник", Спр.ТекущийЭлемент());
            // Обновляем форму, чтобы значение появилось в ячейке
            Форма.Обновить(0); 
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Дополнительные возможности: работа с несколькими колонками

Часто задача усложняется: нужно, чтобы в одной колонке выбирались сотрудники, а в другой, например, подразделения. Теперь, когда мы знаем принцип работы с ТекущаяКолонка(), мы можем легко расширить нашу процедуру, используя конструкцию Если ... ИначеЕсли или ВыбратьОператор (в 7.7 это реализуется через последовательные условия):


Процедура Формула()
    ТекКол = ТаблицаЗначений.ТекущаяКолонка();
    ТекСтр = ТаблицаЗначений.ТекущаяСтрока();

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

Подведение итогов

Мы проанализировали проблему ограничения действий в таблице и выяснили, что ключ к решению лежит в использовании метода ТекущаяКолонка(). Важно помнить: для стабильной работы кода всегда отдавайте предпочтение строковым идентификаторам колонок вместо их порядковых номеров. Это убережет вашу разработку от поломок при изменении структуры таблицы в будущем. Использование Синтакс-помощника (ветка «Объекты» -> «ТаблицаЗначений») позволит вам всегда держать под рукой список доступных методов для управления данными на форме.

← На главную