Работа с табличными частями в управляемом интерфейсе 1С 8.3 существенно отличается от того, как это происходило в обычных формах или версии 7.7. Основная сложность заключается в разделении данных (объекта) и их визуального представления на форме. Особенно остро этот вопрос встает при работе со сложными документами, такими как Табель учета рабочего времени в ЗУП 3.1, где колонки могут формироваться динамически.
В этой статье мы подробно разберем несколько способов получения значения ячейки, проанализируем, когда стоит обращаться к элементам формы, а когда — напрямую к данным объекта, и выясним, как правильно работать с динамическими именами колонок.
Если нам нужно получить значение из строки, на которой в данный момент сфокусирован пользователь, мы будем использовать свойство ТекущиеДанные элемента формы (таблицы). Этот метод наиболее удобен, когда код вызывается в обработчиках событий самой таблицы или кнопок командной панели, связанных с этой таблицей.
Рассмотрим пример, когда нам нужно получить значение конкретной колонки в текущей строке. Допустим, наша таблица на форме называется ДанныеОВремени, а колонка — Время1. Проанализируем следующий код:
// Получаем доступ к данным текущей строки
ТекущаяСтрока = ЭтаФорма.Элементы.ДанныеОВремени.ТекущиеДанные;
Если ТекущаяСтрока <> Неопределено Тогда
// Обращаемся к значению конкретной колонки
ЗначениеЯчейки = ТекущаяСтрока.Время1;
Сообщить("Значение в ячейке: " + ЗначениеЯчейки);
КонецЕсли;
Важно понимать, что ТекущиеДанные имеют тип ДанныеФормыЭлементКоллекции. Это не сама строка объектной табличной части, а её проекция на форму. Изменения в этих данных сразу отображаются в интерфейсе.
В сложных конфигурациях, таких как ЗУП 3.1, имена колонок часто содержат порядковый номер дня (например, Часов1, Часов2... Часов31). Если имя колонки заранее неизвестно и формируется в коде, мы не можем обратиться к нему через точку. В этом случае на помощь приходит метод Свойство() или обращение через квадратные скобки.
Разберем ситуацию, когда нам нужно вычислить номер дня из имени текущего элемента и получить значение соответствующей ячейки:
// Определяем имя текущей колонки, в которой находится курсор
ИмяТекущегоЭлемента = ЭтаФорма.ТекущийЭлемент.Имя;
// Допустим, имя элемента "ДанныеОВремениВремя1Представление"
// Извлечем из него индекс, чтобы обратиться к данным
ИндексДня = СтрЗаменить(ИмяТекущегоЭлемента, "ДанныеОВремениВремя", "");
ИндексДня = СтрЗаменить(ИндексДня, "Представление", "");
// Теперь получим значение через ТекущиеДанные
НайденноеЗначение = Неопределено;
Если ЭтаФорма.Элементы.ДанныеОВремени.ТекущиеДанные.Свойство("Часов" + ИндексДня, НайденноеЗначение) Тогда
// Теперь НайденноеЗначение содержит данные из ячейки "Часов1", "Часов2" и т.д.
Сообщить("Количество часов: " + НайденноеЗначение);
КонецЕсли;
Альтернативный, более лаконичный вариант обращения к динамической колонке выглядит так:
ИмяКолонки = "Часов" + ИндексДня;
Значение = ЭтаФорма.Элементы.ДанныеОВремени.ТекущиеДанные[ИмяКолонки];
Иногда задача требует перебора всех строк табличной части, а не только текущей. В этом случае использование элементов формы (Элементы.Таблица...) может быть избыточным и менее производительным. Правильнее будет обратиться напрямую к реквизиту формы Объект.
Проанализируем ситуацию: нам нужно рассчитать сумму всех часов в табличной части документа. Мы проигнорируем визуальное состояние таблицы и обратимся к данным:
// Перебираем всю табличную часть объекта
Для Каждого СтрокаТЧ Из Объект.ДанныеОВремени Цикл
Для День = 1 По 31 Цикл
ИмяПоля = "Часов" + Формат(День, "ЧГ=0");
ЗначениеЧасов = СтрокаТЧ[ИмяПоля];
Если ЗначениеЧасов > 8 Тогда
// Выполняем какую-либо логику
КонецЕсли;
КонецЦикла;
КонецЦикла;
Этот способ работает быстрее и надежнее, если логика не зависит от того, какую именно ячейку выделил пользователь. Помните, что Объект.ИмяТЧ на управляемой форме — это ДанныеФормыКоллекция, и работа с ней во многом похожа на работу с обычной табличной частью на сервере.
В конфигурации Зарплата и Управление Персоналом документ Табель реализован весьма специфично. Поля, которые мы видим на форме (например, Время1Представление), часто являются вычисляемыми строковыми представлениями. Они показывают пользователю текст (например, "Я 8" — явка 8 часов), в то время как сами данные хранятся в числовых или ссылочных полях.
При получении значения важно различать:
ТекущиеДанные или Объект.Если вы хотите программно запретить редактирование ячейки в зависимости от её значения, рассмотрим использование Условного оформления. Это более правильный архитектурный подход для управляемых форм. Мы можем задать правило: если значение ячейки равно определенному числу, то установить свойство ТолькоПросмотр для этой строки или колонки. Это делается без единой строчки кода в обработчике нажатия, что значительно повышает стабильность системы.
Выясним, какой метод лучше использовать в конкретных ситуациях:
Элемент.ТекстРедактирования или ЭтаФорма.Элементы.ИмяТаблицы.ТекущиеДанные.Объект.ТабличнаяЧасть.ПриАктивизацииЯчейки или механизм УсловноеОформление.Использование метода Свойство(), описанного в сообщениях форума, является отличным способом избежать ошибок "Поле объекта не обнаружено" при работе с динамическими структурами данных, которые характерны для сложных типовых решений 1С.