В процессе разработки на платформе «1С:Предприятие 8.3» перед программистом часто встает задача получения данных из табличных частей (ТЧ) документов или справочников. Традиционное обращение «через точку» от ссылки к табличной части кажется наиболее простым и интуитивным, однако за этой простотой скрываются серьезные проблемы с производительностью. Разберем детально, почему это происходит и какие альтернативные способы обращения к данным существуют.
Проанализируем механику работы платформы при выполнении кода вида Ссылка.ИмяТабличнойЧасти. Когда мы обращаемся к реквизиту объекта или его табличной части через точку от ссылки, платформа 1С инициирует считывание всего объекта целиком из базы данных в оперативную память сервера приложений.
Рассмотрим ситуацию: у вас есть документ «Реализация товаров и услуг», содержащий 5 табличных частей и 50 обычных реквизитов. Если вам нужно просто посчитать итог по одной ТЧ, обращение через точку заставит систему прочитать все 5 ТЧ и все реквизиты. Если в документе тысячи строк, это приведет к:
Выясним причину, почему это происходит. Платформа 1С использует объектную модель доступа к данным. При первом обращении через точку объект помещается в кэш. Если объект «тяжелый», он остается в памяти до завершения транзакции или до вытеснения из кэша, что может негативно сказаться на других процессах системы.
Самый оптимальный и рекомендуемый способ получения данных табличной части — это использование языка запросов 1С. Рассмотрим пример, когда нам необходимо получить данные из табличной части Товары конкретного документа.
Посмотрим на пример кода:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Т.Номенклатура,
| Т.Количество,
| Т.Сумма
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Т
|ГДЕ
| Т.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Обработка данных строки ТЧ
Сообщить(Выборка.Номенклатура);
КонецЦикла;
Почему этот метод предпочтителен? Проанализируем преимущества:
Номенклатура и Сумма), а не всю структуру объекта.Ссылка, что делает поиск строк ТЧ мгновенным даже в огромных таблицах.Для тех, кто хочет писать код быстрее, сохраняя при этом производительность, в Библиотеке Стандартных Подсистем (БСП) предусмотрены специальные механизмы. Часто программисты ошибочно полагают, что функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта работает только для простых реквизитов. На самом деле, она прекрасно справляется и с табличными частями.
Разберем, как это работает на практике:
// Получаем табличную часть в виде Таблицы Значений
ТаблицаТоваров = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаДокумент, "Товары");
// Теперь мы можем работать с данными методами ТЗ
СтрокаСНужнымТоваром = ТаблицаТоваров.Найти(НужнаяНоменклатура, "Номенклатура");
ИтоговаяСумма = ТаблицаТоваров.Итог("Сумма");
Важный нюанс: при запросе ТЧ через БСП функция внутри себя динамически формирует запрос ВЫБРАТЬ * ИЗ.... Это гораздо эффективнее, чем чтение всего объекта, так как считывается только одна конкретная таблица, относящаяся к этому объекту, а не все остальные ТЧ и реквизиты «шапки».
Если вам нужно получить сразу несколько ТЧ или ТЧ вместе с реквизитами шапки, используйте функцию ОбщегоНазначения.ЗначенияРеквизитовОбъекта. Она вернет структуру, где значениями будут таблицы значений для ТЧ и простые типы для реквизитов.
Несмотря на рекомендации использовать запросы, существуют ситуации, когда обращение через точку (использование объектной модели) вполне допустимо и даже удобно.
ПередЗаписью модуля документа), объект уже загружен в память. В этом случае обращение ЭтотОбъект.Товары не несет дополнительных затрат на чтение из БД.НайтиСтроки(), Итог(), Количество(), ВыгрузитьКолонку(). Если логика алгоритма завязана на эти методы и объект уже так или иначе будет считан, использование объектной модели упрощает код.Рассмотрим интересный теоретический вопрос, поднятый на форуме: является ли табличная часть самостоятельным объектом? С технической точки зрения 1С, ТЧ — это подчиненная сущность.
В отличие от самого Справочника или Документа, у строки табличной части нет уникального идентификатора (UUID) на уровне базы данных. Идентификация строки происходит по паре: Ссылка на владельца + Номер строки (индекс). Именно поэтому невозможно получить «ссылку на строку ТЧ», чтобы потом обратиться к ней через точку.
Важный совет: Если вам необходимо обеспечить жесткую связь между строками разных табличных частей (например, между списком товаров и списком серийных номеров), используйте в обеих ТЧ реквизит КлючСвязи с типом УникальныйИдентификатор. Это стандартная практика для современных конфигураций 1С.
Подводя итог нашему анализу, сформулируем правила «хорошего тона» при работе с данными табличных частей:
ОбщегоНазначения.ЗначениеРеквизитаОбъекта().БезБлокировок позволяет системе работать более параллельно, в то время как чтение объекта может накладывать избыточные ограничения на данные на уровне СУБД.Выбор правильного метода обращения к табличным частям — это не просто вопрос стиля программирования, а залог стабильной и быстрой работы информационной системы при росте объемов данных.