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