В практике разработки на платформе 1С:Предприятие часто возникают задачи, когда стандартный цикл перебора строк табличной части не подходит. Например, когда дизайн печатной формы строго регламентирован и требует вывода данных из первой, второй и третьей строк в строго определенные, разрозненные поля макета. В этой статье мы подробно разберем, как реализовать такой механизм, обеспечив при этом отказоустойчивость кода.
Самый простой и логичный способ получить данные из конкретной строки — это обращение к ней по индексу. Важно помнить фундаментальное правило разработки в 1С: индексация коллекций (включая табличные части) всегда начинается с 0. Таким образом:
012Рассмотрим пример кода, где мы получаем данные из объекта и передаем их в параметры области макета. Предположим, что у нас есть табличная часть Товары и макет с областью ДанныеШапки, в которой созданы параметры Поле1, Поле2 и Поле3.
// Получаем макет и область
Макет = ПолучитьМакет("Печать");
Область = Макет.ПолучитьОбласть("ДанныеШапки");
// Обращаемся напрямую к строкам (без проверок на количество)
Область.Параметры.Поле1 = СсылкаНаОбъект.Товары[0].Номенклатура;
Область.Параметры.Поле2 = СсылкаНаОбъект.Товары[1].Номенклатура;
Область.Параметры.Поле3 = СсылкаНаОбъект.Товары[2].Номенклатура;
ТабДок.Вывести(Область);
Внимание: Прямое обращение, как в примере выше, крайне опасно. Если в документе окажется меньше трех строк, система выдаст фатальную ошибку: "Индекс находится вне границ массива". Чтобы этого избежать, необходимо всегда проверять количество строк.
Проанализируем ситуацию, когда количество строк в документе динамическое. Мы должны гарантировать, что программа не "упадет", если пользователь заполнил только одну строку. Разберем алгоритм безопасного вывода:
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("ВашМакет");
Область = Макет.ПолучитьОбласть("СекцияСПолями");
ТЧ = СсылкаНаОбъект.Товары;
КолВоСтрок = ТЧ.Количество();
// Проверяем наличие первой строки
Если КолВоСтрок > 0 Тогда
Область.Параметры.Поле1 = ТЧ[0].Наименование;
Иначе
Область.Параметры.Поле1 = "---"; // Оформление пустой строки
КонецЕсли;
// Проверяем наличие второй строки
Если КолВоСтрок > 1 Тогда
Область.Параметры.Поле2 = ТЧ[1].Наименование;
КонецЕсли;
// Проверяем наличие третьей строки
Если КолВоСтрок > 2 Тогда
Область.Параметры.Поле3 = ТЧ[2].Наименование;
КонецЕсли;
ТабДок.Вывести(Область);
Этот метод позволяет гибко управлять визуализацией: если данных нет, мы можем оставить поле пустым или заполнить его прочерком для эстетичности печатной формы.
Часто поля для первой, второй и третьей строки находятся не в одной секции, а "раскиданы" по всему документу. Например, первая строка должна попасть в "Шапку", вторая — в "Центральную часть", а третья — в "Подвал". В этом случае нам нужно получать области последовательно и выводить их в ТабличныйДокумент методом Вывести().
Проанализируем пример реализации:
// 1. Выводим первую строку в область Шапка
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
Если СсылкаНаОбъект.Товары.Количество() > 0 Тогда
ОбластьШапка.Параметры.ДанныеПервойСтроки = СсылкаНаОбъект.Товары[0].Номенклатура;
КонецЕсли;
ТабДок.Вывести(ОбластьШапка);
// 2. Выводим вторую строку в область Тело
ОбластьТело = Макет.ПолучитьОбласть("Тело");
Если СсылкаНаОбъект.Товары.Количество() > 1 Тогда
ОбластьТело.Параметры.ДанныеВторойСтроки = СсылкаНаОбъект.Товары[1].Номенклатура;
КонецЕсли;
ТабДок.Вывести(ОбластьТело);
// 3. Выводим третью строку в область Подвал
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
Если СсылкаНаОбъект.Товары.Количество() > 2 Тогда
ОбластьПодвал.Параметры.ДанныеТретьейСтроки = СсылкаНаОбъект.Товары[2].Номенклатура;
КонецЕсли;
ТабДок.Вывести(ОбластьПодвал);
Если печатная форма сложная или данных в табличной части очень много, обращение к объекту в памяти может быть неэффективным. Рассмотрим, как сделать это профессионально с помощью языка запросов 1С. Мы выберем только первые три строки, что ускорит работу системы.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 3
| Товары.Номенклатура.Наименование КАК Название,
| Товары.Количество КАК Кол
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка = &Ссылка
|УПОРЯДОЧИТЬ ПО
| Товары.НомерСтроки";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);
РезультатЗапроса = Запрос.Выполнить();
// Выгружаем в таблицу для удобного доступа по индексам
ТаблицаДанных = РезультатЗапроса.Выгрузить();
Область = Макет.ПолучитьОбласть("ФиксированнаяСекция");
// Заполняем параметры из таблицы значений
Если ТаблицаДанных.Количество() > 0 Тогда
Область.Параметры.Стр1 = ТаблицаДанных[0].Название;
КонецЕсли;
Если ТаблицаДанных.Количество() > 1 Тогда
Область.Параметры.Стр2 = ТаблицаДанных[1].Название;
КонецЕсли;
Если ТаблицаДанных.Количество() > 2 Тогда
Область.Параметры.Стр3 = ТаблицаДанных[2].Название;
КонецЕсли;
ТабДок.Вывести(Область);
Для создания качественной печатной формы воспользуйтесь следующими рекомендациями:
Область.Параметры.Заполнить(ТЧ[0]). Это сократит объем кода.ПараметрРасшифровки для ячеек. Это позволит пользователю кликнуть на название товара в печатной форме и сразу открыть карточку этой номенклатуры.Область.Видимость = Ложь или просто не выводите область в ТабличныйДокумент.ТабДок.АвтоМасштаб = Истина; перед отображением пользователю.Таким образом, задача вывода конкретных строк решается либо прямым обращением к коллекции через индекс с обязательной проверкой границ массива, либо с помощью специализированного запроса. Выбор метода зависит от сложности структуры вашего макета и требований к производительности системы.