К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как найти колонку в таблице значений 1С

Как найти колонку в таблице значений 1С: метод Найти коллекции Колонки, поиск по имени и заголовку, проверка существования колонки, примеры кода и типичные ошибки.

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

Для поиска колонки у таблицы значений есть коллекция Колонки (Columns) с методами Найти и Индекс, а также обращение по индексу. Важно понимать разницу между поиском колонки и поиском строки: метод Найти у самой таблицы ищет значения в строках, а не колонки — это одна из самых частых путаниц у начинающих разработчиков.

Ниже разобраны все рабочие способы найти колонку: по имени, по заголовку, по индексу, с проверкой существования и обработкой ситуации, когда колонки нет. Примеры приведены на встроенном языке 1С и подходят как для тонкого клиента, так и для сервера.

Как устроена коллекция колонок таблицы значений

У каждой таблицы значений есть свойство Колонки — это объект типа «КоллекцияКолонокТаблицыЗначений». Каждый элемент коллекции — объект «КолонкаТаблицыЗначений» со свойствами: Имя, Заголовок, ТипЗначения, Ширина, Точность и другими.

Коллекция поддерживает три основных способа доступа к элементу: метод Найти(Имя), обращение по индексу через квадратные скобки Колонки[0] и перебор в цикле Для Каждого Колонка Из ТЗ.Колонки Цикл. Метод Индекс(Колонка) работает в обратную сторону — возвращает позицию известного объекта колонки.

Индексация начинается с нуля, а количество колонок возвращает метод Количество() или свойство Количество в зависимости от версии платформы — безопаснее использовать метод Количество(), он работает везде.

Поиск колонки по имени через метод Найти

Основной способ — метод Найти коллекции колонок. Он принимает строку с именем колонки и возвращает объект колонки либо Неопределено, если такой колонки нет:

ТЗ = Новый ТаблицаЗначений;

ТЗ.Колонки.Добавить("Номенклатура");

ТЗ.Колонки.Добавить("Количество");

Колонка = ТЗ.Колонки.Найти("Количество");

Если Колонка <> Неопределено Тогда

Сообщить("Колонка найдена, тип: " + Колонка.ТипЗначения);

Иначе

Сообщить("Колонка не найдена");

КонецЕсли;

Поиск по имени регистронезависим: Найти("количество") и Найти("КОЛИЧЕСТВО") найдут одну и ту же колонку. Это удобно, но одновременно означает, что нельзя создать две колонки, отличающиеся только регистром букв.

Имя колонки должно быть корректным идентификатором: начинаться с буквы, не содержать пробелов и спецсимволов. Если вы ищете колонку по строке с пробелом — скорее всего, вы ищете по заголовку, а не по имени, и метод Найти вернёт Неопределено.

bsl
Колонка = ТЗ.Колонки.Найти("Сумма");
Если Колонка = Неопределено Тогда
    ВызватьИсключение "В таблице нет колонки Сумма";
КонецЕсли;

Проверка существования колонки перед обращением

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

Типовой приём — обернуть проверку в функцию и использовать её по всему коду:

Функция ЕстьКолонка(ТЗ, ИмяКолонки)

Возврат ТЗ.Колонки.Найти(ИмяКолонки) <> Неопределено;

КонецФункции

// Использование

Если ЕстьКолонка(ТаблицаДанных, "Скидка") Тогда

ИтогСкидок = ТаблицаДанных.Итог("Скидка");

КонецЕсли;

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

Поиск колонки по заголовку и по индексу

Метод Найти работает только с именем колонки. Если известен только заголовок — например, пользователь выбрал колонку в интерфейсе по видимому названию — коллекцию придётся перебрать вручную:

Функция НайтиКолонкуПоЗаголовку(ТЗ, ИскомыйЗаголовок)

Для Каждого Колонка Из ТЗ.Колонки Цикл

Если Колонка.Заголовок = ИскомыйЗаголовок Тогда

Возврат Колонка;

КонецЕсли;

КонецЦикла;

Возврат Неопределено;

КонецФункции;

Учтите: заголовки не обязаны быть уникальными — две колонки могут иметь одинаковый заголовок. Перебор вернёт первую попавшуюся. Кроме того, если заголовок не задан явно, платформа формирует его автоматически из имени, и он может не совпадать с тем, что вы ожидаете.

Обращение по индексу

Если колонка ищется по позиции — например, «третья колонка выгрузки из Excel» — используйте индекс:

ТретьяКолонка = ТЗ.Колонки[2]; // индексация с нуля

ИмяТретьей = ТретьяКолонка.Имя;

При выходе за границы коллекции возникнет ошибка, поэтому перед обращением проверяйте ТЗ.Колонки.Количество().

Сравнение вариантов

Колонки.Найти(Имя)

Быстрый поиск по имени, регистронезависим. Не ищет по заголовку и не принимает индекс.

Перебор в цикле

Подходит для поиска по заголовку, типу значения или любому другому свойству. Медленнее на большом числе колонок, но их обычно немного.

Колонки[Индекс]

Когда известна позиция колонки. Требует проверки границ, иначе ошибка обращения за пределы коллекции.

Что делать с найденной колонкой

Найденный объект колонки даёт доступ к её свойствам и позволяет выполнять типовые операции. Частые сценарии:

  • узнать тип данных: Колонка.ТипЗначения — вернуть объект «ОписаниеТипов», например чтобы проверить, числовая ли колонка перед суммированием;
  • получить имя по индексу или заголовку для дальнейшего обращения к строкам: СтрокаТЗ[Колонка.Имя];
  • прочитать или изменить заголовок перед выводом таблицы на форму: Колонка.Заголовок = "Кол-во";
  • проверить ширину и точность для числовых полей при подготовке печатных форм.

Обращение к значению через переменную с именем колонки — стандартный приём динамического кода:

ИмяКолонки = "Сумма";

Если ТЗ.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда

Для Каждого СтрокаТЗ Из ТЗ Цикл

Значение = СтрокаТЗ[ИмяКолонки]; // квадратные скобки, не точка

КонецЦикла;

КонецЕсли;

Порядок действий
  1. 1
    Определите, что известно о колонке: имя, заголовок или позиция
  2. 2
    Для имени используйте ТЗ.Колонки.Найти(Имя) и проверьте результат на Неопределено
  3. 3
    Для заголовка переберите коллекцию циклом со сравнением свойства Заголовок
  4. 4
    Для позиции проверьте ТЗ.Колонки.Количество() и обратитесь по индексу
  5. 5
    Используйте найденный объект колонки или его имя для доступа к данным строк

Типичные ошибки при поиске колонок

Первая и самая распространённая ошибка — попытка найти колонку методом Найти самой таблицы значений: ТЗ.Найти("Сумма"). Этот метод ищет строку по значению в указанной колонке, а не колонку. Для колонок существует отдельная коллекция — ТЗ.Колонки.Найти(...).

Вторая ошибка — поиск по заголовку через Колонки.Найти. Если колонка называется Количество, а заголовок у неё «Кол-во по документу», поиск строки «Кол-во по документу» вернёт Неопределено. Имя и заголовок — разные свойства.

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

Типичные ошибки
01
Вызов ТЗ.Найти("ИмяКолонки") вместо ТЗ.Колонки.Найти — ищется строка, а не колонка
02
Поиск по заголовку через Колонки.Найти — метод работает только с именем
03
Обращение СтрокаТЗ.Имя без проверки существования колонки — ошибка «Поле объекта не обнаружено»
04
Обращение по индексу без проверки Количество() — выход за границы коллекции
05
Отсутствие псевдонимов в запросе — автоматические имена колонок не совпадают с ожидаемыми

Проверка результата и отладка

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

Для Каждого Колонка Из ТЗ.Колонки Цикл

Сообщить(Строка(ТЗ.Колонки.Индекс(Колонка)) + ": "

+ Колонка.Имя + " | " + Колонка.Заголовок);

КонецЦикла;

Этот приём особенно полезен при разборе чужого кода или таблиц, полученных из внешних источников: вы сразу видите фактические имена, индексы и заголовки и можете сопоставить их с тем, что ищет код.

Контрольные точки

Как проверить результат

Результат Колонки.Найти
Норма

Возвращён объект колонки, его свойство Имя совпадает с искомым (без учёта регистра)

Тревожный признак

Возвращено Неопределено — колонки с таким именем нет или вы ищете по заголовку

Обращение к строке по имени колонки
Норма

СтрокаТЗ[ИмяКолонки] возвращает значение без исключения

Тревожный признак

Ошибка «Поле объекта не обнаружено» — колонки нет или имя содержит опечатку

Таблица из запроса
Норма

Имена колонок совпадают с псевдонимами полей запроса

Тревожный признак

Появились автоматические имена вида Поле1 — в запросе нет псевдонимов

FAQ: частые вопросы о поиске колонок

Чем отличается ТЗ.Найти от ТЗ.Колонки.Найти?

ТЗ.Найти(Значение, ИмяКолонки) ищет строку, в которой указанная колонка содержит заданное значение, и возвращает строку таблицы. ТЗ.Колонки.Найти(Имя) ищет саму колонку по имени и возвращает объект колонки. Это разные методы разных объектов с разным назначением.

Учитывается ли регистр при поиске колонки по имени?

Нет, поиск регистронезависим: «Сумма», «сумма» и «СУММА» найдут одну колонку. По той же причине нельзя добавить две колонки, различающиеся только регистром букв.

Как найти колонку, если известен только её заголовок на форме?

Метод Найти здесь не поможет — он работает с именами. Переберите коллекцию ТЗ.Колонки в цикле и сравнивайте свойство Заголовок каждой колонки с искомой строкой. Помните, что заголовки могут повторяться, и будет найдена первая подходящая колонка.

Можно ли искать колонку по части имени?

Штатного метода поиска по подстроке нет. Используйте перебор коллекции с функцией СтрНайти(Колонка.Имя, Подстрока) — так можно найти, например, все колонки, начинающиеся с префикса «Сумма».

Что вернёт Колонки.Найти, если колонок с таким именем несколько?

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

Как получить список имён всех колонок одной строкой?

Переберите коллекцию в цикле и соберите имена через запятую в строковую переменную, либо используйте ТЗ.Колонки.Количество() с обращением по индексу. Готового свойства «список имён» у таблицы значений нет.

Итог

Что важно запомнить

Колонки ищутся через коллекцию ТЗ.Колонки: Найти(Имя) — по имени, перебор циклом — по заголовку или другому свойству, квадратные скобки — по индексу. Всегда проверяйте результат на Неопределено перед обращением к колонке и задавайте псевдонимы полей в запросах, чтобы имена колонок были предсказуемыми.