Как наиболее оптимально обращаться к табличным частям объектов ссылочного типа в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки на платформе «1С:Предприятие 8.3» перед программистом часто встает задача получения данных из табличных частей (ТЧ) документов или справочников. Традиционное обращение «через точку» от ссылки к табличной части кажется наиболее простым и интуитивным, однако за этой простотой скрываются серьезные проблемы с производительностью. Разберем детально, почему это происходит и какие альтернативные способы обращения к данным существуют.

Проблема «тяжелых» объектов и обращения через точку

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

Рассмотрим ситуацию: у вас есть документ «Реализация товаров и услуг», содержащий 5 табличных частей и 50 обычных реквизитов. Если вам нужно просто посчитать итог по одной ТЧ, обращение через точку заставит систему прочитать все 5 ТЧ и все реквизиты. Если в документе тысячи строк, это приведет к:

  1. Резкому скачку потребления оперативной памяти на сервере.
  2. Избыточной нагрузке на сеть между сервером приложений и СУБД.
  3. Деградации производительности при выполнении кода в цикле.

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

Способ 1. Использование прямого запроса к табличной части

Самый оптимальный и рекомендуемый способ получения данных табличной части — это использование языка запросов 1С. Рассмотрим пример, когда нам необходимо получить данные из табличной части Товары конкретного документа.

Посмотрим на пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Т.Номенклатура,
    |   Т.Количество,
    |   Т.Сумма
    |ИЗ
    |   Документ.РеализацияТоваровУслуг.Товары КАК Т
    |ГДЕ
    |   Т.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Обработка данных строки ТЧ
    Сообщить(Выборка.Номенклатура);
КонецЦикла;

Почему этот метод предпочтителен? Проанализируем преимущества:

Способ 2. Функции Библиотеки Стандартных Подсистем (БСП)

Для тех, кто хочет писать код быстрее, сохраняя при этом производительность, в Библиотеке Стандартных Подсистем (БСП) предусмотрены специальные механизмы. Часто программисты ошибочно полагают, что функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта работает только для простых реквизитов. На самом деле, она прекрасно справляется и с табличными частями.

Разберем, как это работает на практике:


// Получаем табличную часть в виде Таблицы Значений
ТаблицаТоваров = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаДокумент, "Товары");

// Теперь мы можем работать с данными методами ТЗ
СтрокаСНужнымТоваром = ТаблицаТоваров.Найти(НужнаяНоменклатура, "Номенклатура");
ИтоговаяСумма = ТаблицаТоваров.Итог("Сумма");

Важный нюанс: при запросе ТЧ через БСП функция внутри себя динамически формирует запрос ВЫБРАТЬ * ИЗ.... Это гораздо эффективнее, чем чтение всего объекта, так как считывается только одна конкретная таблица, относящаяся к этому объекту, а не все остальные ТЧ и реквизиты «шапки».

Если вам нужно получить сразу несколько ТЧ или ТЧ вместе с реквизитами шапки, используйте функцию ОбщегоНазначения.ЗначенияРеквизитовОбъекта. Она вернет структуру, где значениями будут таблицы значений для ТЧ и простые типы для реквизитов.

Способ 3. Когда обращение через точку оправдано?

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

  1. Работа в модуле объекта: Если вы уже находитесь «внутри» объекта (например, в процедуре ПередЗаписью модуля документа), объект уже загружен в память. В этом случае обращение ЭтотОбъект.Товары не несет дополнительных затрат на чтение из БД.
  2. Малые объекты: Если вы точно знаете, что объект содержит 2-3 строки и используется крайне редко, удобство написания кода может стоять выше микро-оптимизаций.
  3. Использование специфических методов ТЧ: Как было отмечено в обсуждении, табличная часть как объект встроенного языка обладает мощным набором методов: НайтиСтроки(), Итог(), Количество(), ВыгрузитьКолонку(). Если логика алгоритма завязана на эти методы и объект уже так или иначе будет считан, использование объектной модели упрощает код.

Технические подробности: статус «объектности» табличной части

Рассмотрим интересный теоретический вопрос, поднятый на форуме: является ли табличная часть самостоятельным объектом? С технической точки зрения 1С, ТЧ — это подчиненная сущность.

В отличие от самого Справочника или Документа, у строки табличной части нет уникального идентификатора (UUID) на уровне базы данных. Идентификация строки происходит по паре: Ссылка на владельца + Номер строки (индекс). Именно поэтому невозможно получить «ссылку на строку ТЧ», чтобы потом обратиться к ней через точку.

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

Итоги и рекомендации

Подводя итог нашему анализу, сформулируем правила «хорошего тона» при работе с данными табличных частей:

Выбор правильного метода обращения к табличным частям — это не просто вопрос стиля программирования, а залог стабильной и быстрой работы информационной системы при росте объемов данных.

← На главную