Разработка и Конфигурация · 11 мин
Как найти колонку в таблице значений 1С
Как найти колонку в таблице значений 1С: метод Найти коллекции Колонки, поиск по имени и заголовку, проверка существования колонки, примеры кода и типичные ошибки.
Таблица значений — один из самых используемых объектов встроенного языка 1С: в неё выгружаются результаты запросов, в ней готовятся данные для отчётов и обменов. Прежде чем обращаться к данным, разработчику часто нужно убедиться, что нужная колонка существует, или получить сам объект колонки, чтобы прочитать её тип, заголовок или ширину.
Для поиска колонки у таблицы значений есть коллекция Колонки (Columns) с методами Найти и Индекс, а также обращение по индексу. Важно понимать разницу между поиском колонки и поиском строки: метод Найти у самой таблицы ищет значения в строках, а не колонки — это одна из самых частых путаниц у начинающих разработчиков.
Ниже разобраны все рабочие способы найти колонку: по имени, по заголовку, по индексу, с проверкой существования и обработкой ситуации, когда колонки нет. Примеры приведены на встроенном языке 1С и подходят как для тонкого клиента, так и для сервера.
Как устроена коллекция колонок таблицы значений
У каждой таблицы значений есть свойство Колонки — это объект типа «КоллекцияКолонокТаблицыЗначений». Каждый элемент коллекции — объект «КолонкаТаблицыЗначений» со свойствами: Имя, Заголовок, ТипЗначения, Ширина, Точность и другими.
Коллекция поддерживает три основных способа доступа к элементу: метод Найти(Имя), обращение по индексу через квадратные скобки Колонки[0] и перебор в цикле Для Каждого Колонка Из ТЗ.Колонки Цикл. Метод Индекс(Колонка) работает в обратную сторону — возвращает позицию известного объекта колонки.
Индексация начинается с нуля, а количество колонок возвращает метод Количество() или свойство Количество в зависимости от версии платформы — безопаснее использовать метод Количество(), он работает везде.
Поиск колонки по имени через метод Найти
Основной способ — метод Найти коллекции колонок. Он принимает строку с именем колонки и возвращает объект колонки либо Неопределено, если такой колонки нет:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("Количество");
Колонка = ТЗ.Колонки.Найти("Количество");
Если Колонка <> Неопределено Тогда
Сообщить("Колонка найдена, тип: " + Колонка.ТипЗначения);
Иначе
Сообщить("Колонка не найдена");
КонецЕсли;
Поиск по имени регистронезависим: Найти("количество") и Найти("КОЛИЧЕСТВО") найдут одну и ту же колонку. Это удобно, но одновременно означает, что нельзя создать две колонки, отличающиеся только регистром букв.
Имя колонки должно быть корректным идентификатором: начинаться с буквы, не содержать пробелов и спецсимволов. Если вы ищете колонку по строке с пробелом — скорее всего, вы ищете по заголовку, а не по имени, и метод Найти вернёт Неопределено.
Колонка = ТЗ.Колонки.Найти("Сумма");
Если Колонка = Неопределено Тогда
ВызватьИсключение "В таблице нет колонки Сумма";
КонецЕсли;Проверка существования колонки перед обращением
Обращение к несуществующей колонке через точку у строки таблицы (СтрокаТЗ.Сумма) вызывает ошибку «Поле объекта не обнаружено». Поэтому при работе с таблицами, структура которых не гарантирована — например, загруженными из внешнего источника или сформированными динамически, — существование колонки нужно проверять заранее.
Типовой приём — обернуть проверку в функцию и использовать её по всему коду:
Функция ЕстьКолонка(ТЗ, ИмяКолонки)
Возврат ТЗ.Колонки.Найти(ИмяКолонки) <> Неопределено;
КонецФункции
// Использование
Если ЕстьКолонка(ТаблицаДанных, "Скидка") Тогда
ИтогСкидок = ТаблицаДанных.Итог("Скидка");
КонецЕсли;
Такая проверка особенно важна в универсальных обработках: обменах данными, печатных формах с настраиваемым набором полей, отчётах на СКД, где состав колонок результата зависит от настроек пользователя.
Поиск колонки по заголовку и по индексу
Метод Найти работает только с именем колонки. Если известен только заголовок — например, пользователь выбрал колонку в интерфейсе по видимому названию — коллекцию придётся перебрать вручную:
Функция НайтиКолонкуПоЗаголовку(ТЗ, ИскомыйЗаголовок)
Для Каждого Колонка Из ТЗ.Колонки Цикл
Если Колонка.Заголовок = ИскомыйЗаголовок Тогда
Возврат Колонка;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции;
Учтите: заголовки не обязаны быть уникальными — две колонки могут иметь одинаковый заголовок. Перебор вернёт первую попавшуюся. Кроме того, если заголовок не задан явно, платформа формирует его автоматически из имени, и он может не совпадать с тем, что вы ожидаете.
Обращение по индексу
Если колонка ищется по позиции — например, «третья колонка выгрузки из Excel» — используйте индекс:
ТретьяКолонка = ТЗ.Колонки[2]; // индексация с нуля
ИмяТретьей = ТретьяКолонка.Имя;
При выходе за границы коллекции возникнет ошибка, поэтому перед обращением проверяйте ТЗ.Колонки.Количество().
Сравнение вариантов
Быстрый поиск по имени, регистронезависим. Не ищет по заголовку и не принимает индекс.
Подходит для поиска по заголовку, типу значения или любому другому свойству. Медленнее на большом числе колонок, но их обычно немного.
Когда известна позиция колонки. Требует проверки границ, иначе ошибка обращения за пределы коллекции.
Что делать с найденной колонкой
Найденный объект колонки даёт доступ к её свойствам и позволяет выполнять типовые операции. Частые сценарии:
- узнать тип данных:
Колонка.ТипЗначения— вернуть объект «ОписаниеТипов», например чтобы проверить, числовая ли колонка перед суммированием; - получить имя по индексу или заголовку для дальнейшего обращения к строкам:
СтрокаТЗ[Колонка.Имя]; - прочитать или изменить заголовок перед выводом таблицы на форму:
Колонка.Заголовок = "Кол-во"; - проверить ширину и точность для числовых полей при подготовке печатных форм.
Обращение к значению через переменную с именем колонки — стандартный приём динамического кода:
ИмяКолонки = "Сумма";
Если ТЗ.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда
Для Каждого СтрокаТЗ Из ТЗ Цикл
Значение = СтрокаТЗ[ИмяКолонки]; // квадратные скобки, не точка
КонецЦикла;
КонецЕсли;
- 1Определите, что известно о колонке: имя, заголовок или позиция
- 2Для имени используйте ТЗ.Колонки.Найти(Имя) и проверьте результат на Неопределено
- 3Для заголовка переберите коллекцию циклом со сравнением свойства Заголовок
- 4Для позиции проверьте ТЗ.Колонки.Количество() и обратитесь по индексу
- 5Используйте найденный объект колонки или его имя для доступа к данным строк
Типичные ошибки при поиске колонок
Первая и самая распространённая ошибка — попытка найти колонку методом Найти самой таблицы значений: ТЗ.Найти("Сумма"). Этот метод ищет строку по значению в указанной колонке, а не колонку. Для колонок существует отдельная коллекция — ТЗ.Колонки.Найти(...).
Вторая ошибка — поиск по заголовку через Колонки.Найти. Если колонка называется Количество, а заголовок у неё «Кол-во по документу», поиск строки «Кол-во по документу» вернёт Неопределено. Имя и заголовок — разные свойства.
Третья группа ошибок связана с динамически созданными таблицами: после Выгрузить() из результата запроса имена колонок совпадают с псевдонимами полей запроса. Если в запросе поле без псевдонима, платформа сгенерирует имя автоматически (например, Поле1), и поиск по ожидаемому имени не сработает. Всегда задавайте псевдонимы в запросе явно.
Проверка результата и отладка
Убедиться, что колонка найдена правильно, помогает вывод структуры таблицы в отладчике или через простой цикл:
Для Каждого Колонка Из ТЗ.Колонки Цикл
Сообщить(Строка(ТЗ.Колонки.Индекс(Колонка)) + ": "
+ Колонка.Имя + " | " + Колонка.Заголовок);
КонецЦикла;
Этот приём особенно полезен при разборе чужого кода или таблиц, полученных из внешних источников: вы сразу видите фактические имена, индексы и заголовки и можете сопоставить их с тем, что ищет код.
Как проверить результат
Возвращён объект колонки, его свойство Имя совпадает с искомым (без учёта регистра)
Возвращено Неопределено — колонки с таким именем нет или вы ищете по заголовку
СтрокаТЗ[ИмяКолонки] возвращает значение без исключения
Ошибка «Поле объекта не обнаружено» — колонки нет или имя содержит опечатку
Имена колонок совпадают с псевдонимами полей запроса
Появились автоматические имена вида Поле1 — в запросе нет псевдонимов
FAQ: частые вопросы о поиске колонок
Чем отличается ТЗ.Найти от ТЗ.Колонки.Найти?
ТЗ.Найти(Значение, ИмяКолонки) ищет строку, в которой указанная колонка содержит заданное значение, и возвращает строку таблицы. ТЗ.Колонки.Найти(Имя) ищет саму колонку по имени и возвращает объект колонки. Это разные методы разных объектов с разным назначением.
Учитывается ли регистр при поиске колонки по имени?
Нет, поиск регистронезависим: «Сумма», «сумма» и «СУММА» найдут одну колонку. По той же причине нельзя добавить две колонки, различающиеся только регистром букв.
Как найти колонку, если известен только её заголовок на форме?
Метод Найти здесь не поможет — он работает с именами. Переберите коллекцию ТЗ.Колонки в цикле и сравнивайте свойство Заголовок каждой колонки с искомой строкой. Помните, что заголовки могут повторяться, и будет найдена первая подходящая колонка.
Можно ли искать колонку по части имени?
Штатного метода поиска по подстроке нет. Используйте перебор коллекции с функцией СтрНайти(Колонка.Имя, Подстрока) — так можно найти, например, все колонки, начинающиеся с префикса «Сумма».
Что вернёт Колонки.Найти, если колонок с таким именем несколько?
Такая ситуация невозможна: имена колонок в таблице значений уникальны (без учёта регистра). Попытка добавить колонку с уже существующим именем вызовет ошибку, поэтому Найти всегда возвращает либо одну колонку, либо Неопределено.
Как получить список имён всех колонок одной строкой?
Переберите коллекцию в цикле и соберите имена через запятую в строковую переменную, либо используйте ТЗ.Колонки.Количество() с обращением по индексу. Готового свойства «список имён» у таблицы значений нет.
Что важно запомнить
Колонки ищутся через коллекцию ТЗ.Колонки: Найти(Имя) — по имени, перебор циклом — по заголовку или другому свойству, квадратные скобки — по индексу. Всегда проверяйте результат на Неопределено перед обращением к колонке и задавайте псевдонимы полей в запросах, чтобы имена колонок были предсказуемыми.