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