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