Как обратиться к реквизиту табличной части в 1С:Зарплата и Управление Персоналом

Программист 1С v8.3 (Обычные формы) 1С:Зарплата и Управление Персоналом
← На главную

При разработке в среде 1С, особенно в конфигурациях на обычных формах (таких как ЗУП 2.5), начинающие программисты часто сталкиваются с ошибкой "Поле объекта не обнаружено" при попытке получить данные из табличной части документа. Ситуация осложняется тем, что видимые названия закладок на форме могут не совпадать с реальными именами табличных частей в метаданных. В этой статье мы подробно разберем, как правильно обращаться к данным строк, как находить нужные имена реквизитов и как отслеживать изменения значений.

Понимание структуры: Коллекция vs Строка

Разберем типичную ошибку. Программист пытается обратиться к реквизиту напрямую через точку от табличной части, например: СсылкаНаОбъект.РаботникиОрганизации.Подразделение. Это действие всегда приводит к ошибке. Почему так происходит? Проанализируем ситуацию: табличная часть — это коллекция строк. У всей коллекции в целом нет реквизита Подразделение; этот реквизит есть у каждой конкретной строки этой коллекции.

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

Способ 1: Перебор всех строк табличной части

Если нам нужно проанализировать все строки документа (например, чтобы проверить подразделения у всех сотрудников), мы используем цикл Для каждого. Рассмотрим пример кода, который корректно обращается к реквизитам каждой строки:


// Док - это ссылка на документ или сам объект документа
Для каждого СтрокаТЧ Из Док.РаботникиОрганизации Цикл
    ТекущееПодразделение = СтрокаТЧ.Подразделение;
    // Здесь можно выполнять проверку или условия
    Сообщить("Сотрудник: " + СтрокаТЧ.Сотрудник + ", Подразделение: " + ТекущееПодразделение);
КонецЦикла;

В данном примере СтрокаТЧ на каждой итерации цикла становится объектом типа СтрокаТабличнойЧасти, у которого уже доступны все реквизиты, заданные в конфигураторе (Подразделение, Сотрудник, ТабельныйНомер и т.д.).

Способ 2: Обращение к текущей строке на форме

Если задача стоит в контексте работы пользователя с формой (например, при нажатии кнопки на форме или в событии изменения ячейки), нам нужно получить строку, на которой в данный момент установлен курсор. В обычных формах для этого используется объект ЭлементыФормы.

Проанализируем шаги для получения данных:

  1. Выясним имя элемента управления (табличного поля) на форме. Важно: оно может отличаться от имени ТЧ в метаданных.
  2. Используем свойство ТекущиеДанные.

// Код внутри модуля формы
ДанныеСтроки = ЭлементыФормы.ТабличноеПолеРаботники.ТекущиеДанные;

Если ДанныеСтроки <> Неопределено Тогда
    Подразделение = ДанныеСтроки.Подразделение;
    // Дальнейшая логика
КонецЕсли;

Важный момент: всегда проверяйте ТекущиеДанные на Неопределено. Если табличная часть пуста или ни одна строка не выбрана, попытка обращения к реквизиту вызовет аварийное завершение программы.

Способ 3: Особенности именования в ЗУП (Метаданные)

Часто программисты не могут найти реквизит из-за путаницы в именах. Например, в документе "Прием на работу в организацию" закладка может называться "Сотрудники", а в дереве метаданных эта табличная часть называется РаботникиОрганизации. Реквизит подразделения также может называться ПодразделениеОрганизации.

Чтобы выяснить точное имя, проделаем следующее:

  1. Откроем Конфигуратор.
  2. Найдем нужный документ в дереве объектов.
  3. Развернем ветку "Табличные части" и увидим реальное имя (синоним на форме часто вводит в заблуждение).
  4. Если доступа к конфигуратору нет, воспользуемся программным способом вывода имен через Метаданные():

// Проверим, какие реквизиты есть в ТЧ "РаботникиОрганизации"
Для каждого Реквизит Из Метаданные.Документы.ПриемНаРаботуВОрганизацию.ТабличныеЧасти.РаботникиОрганизации.Реквизиты Цикл
    Сообщить(Реквизит.Имя);
КонецЦикла;

Этот метод позволяет точно определить, к какому полю нужно обращаться, и избежать ошибки "Поле объекта не обнаружено".

Отслеживание изменений в подразделении

Рассмотрим ситуацию, когда необходимо узнать, изменилось ли подразделение у сотрудника. Для этого нам нужно сравнить текущее значение в оперативной памяти (в объекте формы) со значением, которое сохранено в базе данных.

Выполним сравнение по следующему алгоритму:


// Предположим, ТекущаяСтрока - это строка, которую мы сейчас редактируем
// Ссылка - это состояние документа в базе данных до записи изменений

Если ЗначениеЗаполнено(Ссылка) Тогда
    // Ищем ту же строку в базе по уникальному идентификатору или сотруднику
    ПараметрыОтбора = Новый Структура("Сотрудник", ТекущаяСтрока.Сотрудник);
    НайденныеСтроки = Ссылка.РаботникиОрганизации.НайтиСтроки(ПараметрыОтбора);
    
    Если НайденныеСтроки.Количество() > 0 Тогда
        СтароеПодразделение = НайденныеСтроки[0].Подразделение;
        
        Если ТекущаяСтрока.Подразделение <> СтароеПодразделение Тогда
            Сообщить("Подразделение изменилось с " + СтароеПодразделение + " на " + ТекущаяСтрока.Подразделение);
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Работа через массив или выгрузку колонки

Иногда требуется проверить, встречается ли конкретное подразделение хотя бы в одной строке таблицы. Вместо полного цикла можно использовать метод ВыгрузитьКолонку(). Это более лаконичный способ работы с данными табличной части.


// Получаем массив всех подразделений из ТЧ
МассивПодразделений = ЭтотОбъект.РаботникиОрганизации.ВыгрузитьКолонку("Подразделение");

// Ищем конкретное подразделение в массиве
Индекс = МассивПодразделений.Найти(НужноеПодразделение);
Если Индекс <> Неопределено Тогда
    // Подразделение найдено в таблице
КонецЕсли;

Подведение итогов

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

Соблюдение этих правил позволит вам писать надежный код и быстро находить причины ошибок при работе с табличными частями в любых конфигурациях 1С.

← На главную