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

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

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

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

Определение позиции строки на обычной форме

Рассмотрим ситуацию: на обычной форме размещено табличное поле с именем тз, связанное с одноименной таблицей значений в качестве источника данных. Если мы попытаемся выполнить код ЭлементыФормы.тз.ТекущаяСтрока, то платформа вернет нам объект типа СтрокаТаблицыЗначений. У этого объекта на обычных формах нет стандартного свойства НомерСтроки (в отличие от табличных частей документов или обработок).

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

Шаг 1. Получение индекса строки (отсчет с 0)

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


// Получаем индекс текущей строки (индексация начинается с нуля)
ИндексСтроки = ТЗ.Индекс(ЭлементыФормы.тз.ТекущиеДанные);

Шаг 2. Получение человекочитаемого номера строки (отсчет с 1)

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


// Получаем реальный номер строки таблицы значений
НомерСтроки = ТЗ.Индекс(ЭлементыФормы.тз.ТекущиеДанные) + 1;

Шаг 3. Обеспечение безопасности кода

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


ТекущаяСтрокаДанных = ЭлементыФормы.тз.ТекущиеДанные;

Если ТекущаяСтрокаДанных <> Неопределено Тогда
    ИндексСтроки = ТЗ.Индекс(ТекущаяСтрокаДанных);
    НомерСтроки = ИндексСтроки + 1;
    Сообщить("Выбрана строка № " + НомерСтроки + " с индексом " + ИндексСтроки);
Иначе
    Сообщить("В таблице нет активных строк!");
КонецЕсли;

Разница между свойствами ТекущаяСтрока и ТекущиеДанные

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

Получение активной колонки и значения ячейки

Теперь разберем вторую часть задачи — определение колонки, в которой находится курсор. Свойство ЭлементыФормы.тз.ТекущаяКолонка возвращает объект типа КолонкаТабличногоПоля. Этот объект содержит метаданные о колонке на форме.

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


ТекущаяКолонкаФормы = ЭлементыФормы.тз.ТекущаяКолонка;

Если ТекущаяКолонкаФормы <> Неопределено Тогда
    // Имя колонки в элементе управления на форме
    ИмяКолонкиНаФорме = ТекущаяКолонкаФормы.Имя;
    
    // Имя колонки (реквизита) в исходной Таблице Значений
    ИмяКолонкиВТЗ = ТекущаяКолонкаФормы.Данные;
    
    Сообщить("Курсор находится в колонке: " + ИмяКолонкиВТЗ);
КонецЕсли;

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


ТекущиеДанныеСтроки = ЭлементыФормы.тз.ТекущиеДанные;
АктивнаяКолонка = ЭлементыФормы.тз.ТекущаяКолонка;

Если ТекущиеДанныеСтроки <> Неопределено И АктивнаяКолонка <> Неопределено Тогда
    ИмяСвойства = АктивнаяКолонка.Данные;
    
    // Получаем значение непосредственно из ячейки таблицы значений
    ЗначениеЯчейки = ТекущиеДанныеСтроки[ИмяСвойства];
    
    Сообщить("Значение в активной ячейке: " + ЗначениеЯчейки);
КонецЕсли;

Как аналогичная задача решается на Управляемых формах?

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

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

Посмотрим на пример клиентского кода для управляемой формы:


&НаКлиенте
Процедура ОпределитьПозициюНаУправляемойФорме()
    
    // Получаем числовой идентификатор строки формы
    ИдентификаторСтроки = Элементы.тз.ТекущаяСтрока;
    
    Если ИдентификаторСтроки <> Неопределено Тогда
        // Находим строку в коллекции данных формы по её идентификатору
        СтрокаКоллекции = Объект.тз.НайтиПоИдентификатору(ИдентификаторСтроки);
        
        // Теперь можем получить индекс строки в таблице
        ИндексСтроки = Объект.тз.Индекс(СтрокаКоллекции);
        НомерСтроки = ИндексСтроки + 1;
        
        // Получаем активный элемент (колонку)
        ТекущийЭлементФормы = Элементы.тз.ТекущийЭлемент;
        ИмяКолонки = ТекущийЭлементФормы.Имя;
        
        // Вычисляем значение ячейки
        ИмяПутиКДанным = ТекущийЭлементФормы.ПутьКДанным; // содержит например "Объект.тз.Номенклатура"
        ЗначениеЯчейки = СтрокаКоллекции[ТекущийЭлементФормы.Имя];
        
        ПоказатьПредупреждение(, "Строка: " + НомерСтроки + ", Колонка: " + ИмяКолонки);
    КонецЕсли;
    
КонецПроцедуры

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

← На главную