Как обратиться к значениям таблицы на форме 1С 8.3 и объединить их в строку для вывода в макет?

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

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

Разбор типичной ошибки: почему возникает «Преобразование к типу Число не может быть выполнено»?

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

Проанализируем ошибочный код:


Для каждого Стр Из Учёт Цикл
    Номерок = Номерок + Стр.Пломба + ",";
КонецЦикла;

Если переменная Номерок не была инициализирована перед циклом или была инициализирована нулем (по умолчанию для некоторых типов), то при выполнении первой итерации система видит: 0 + "ЗначениеПломбы". Поскольку 0 — это число, 1С пытается превратить строку в число, что и вызывает критическую ошибку. Чтобы этого избежать, мы должны явно указать системе, что работаем со строками.

Решение 1: Правильная инициализация и конкатенация строк

Самый простой способ исправить ситуацию — это инициализировать переменную пустой строкой. Рассмотрим, как это сделать правильно:


// Инициализируем переменную как пустую строку
Номерок = ""; 

Для каждого Стр Из Учёт Цикл
    // Добавляем значение колонки, принудительно преобразуя его в строку
    Номерок = Номерок + Строка(Стр.Пломба) + ", ";
КонецЦикла;

// Убираем последнюю лишнюю запятую и пробел
Если ЗначениеЗаполнено(Номерок) Тогда
    Номерок = Лев(Номерок, СтрДлина(Номерок) - 2);
КонецЕсли;

В этом примере мы используем функцию Строка(). Это хорошая практика, так как в колонке таблицы может оказаться Null, число или ссылка, и прямое сложение может привести к ошибке. Также мы добавили блок удаления последнего разделителя, чтобы строка выглядела аккуратно.

Решение 2: Использование функции СтрСоединить (современный подход)

Начиная с версии платформы 8.3.6, разработчикам доступен более элегантный и быстрый способ объединения строк — функция СтрСоединить. Проанализируем, почему этот метод лучше:

  1. Производительность: При больших объемах данных (тысячи строк) оператор + работает медленно, так как каждый раз создает новую строку в памяти. СтрСоединить работает с массивом и делает это значительно быстрее.
  2. Чистота кода: Вам не нужно вручную удалять последнюю запятую.

Посмотрим на пример реализации этого метода для таблицы на форме:


// Создаем массив для хранения значений
МассивПломб = Новый Массив;

// Заполняем массив значениями из таблицы
Для каждого Стр Из Учёт Цикл
    Если ЗначениеЗаполнено(Стр.Пломба) Тогда
        МассивПломб.Добавить(Строка(Стр.Пломба));
    КонецЕсли;
КонецЦикла;

// Объединяем массив в одну строку с разделителем
Номерок = СтрСоединить(МассивПломб, ", ");

Особенности работы с данными формы: ДанныеФормыКоллекция vs ТаблицаЗначений

Важно понимать разницу между объектами, с которыми мы работаем. Таблица на управляемой форме — это не ТаблицаЗначений, а объект типа ДанныеФормыКоллекция.

Рассмотрим нюансы использования метода РеквизитФормыВЗначение. Многие разработчики по привычке пишут:

ТаблицаОбъект = РеквизитФормыВЗначение("Учёт");

Это действие переводит данные из легкого экранного объекта в тяжелый объект сервера. Делать это нужно только в том случае, если вам требуются специфические методы таблицы значений, такие как Свернуть(), НайтиСтроки() (с использованием структуры) или ВыгрузитьКолонку(). Если вам нужно просто перебрать строки циклом Для каждого, используйте Учёт напрямую — это сэкономит ресурсы сервера и ускорит работу программы.

Разбор ситуации: заполнение макета

Теперь объединим всё вышесказанное в контексте задачи заполнения макета, которую решал автор. Разберем полный цикл действий программиста:


&НаСервере
Процедура ПечатьНаСервере(ТабДок)
    
    Макет = ПолучитьМакет("МойМакет"); // Замените на имя вашего макета
    ОбластьНомер = Макет.ПолучитьОбласть("Номер");
    
    // Собираем данные из таблицы формы "Учёт"
    МассивЗначений = Новый Массив;
    Для каждого СтрокаТаблицы Из Учёт Цикл
        Если ЗначениеЗаполнено(СтрокаТаблицы.Пломба) Тогда
            МассивЗначений.Добавить(Строка(СтрокаТаблицы.Пломба));
        КонецЕсли;
    КонецЦикла;
    
    // Заполняем параметр области
    ОбластьНомер.Параметры.Номер = СтрСоединить(МассивЗначений, ", ");
    
    // Выводим область в табличный документ
    ТабДок.Вывести(ОбластьНомер);
    
КонецПроцедуры

Обратите внимание: если ваш код находится не в модуле формы, а в общем модуле или модуле объекта, вам придется передать таблицу формы как параметр или предварительно преобразовать её. Но в рамках модуля формы обращение к Учёт (имени реквизита) происходит напрямую.

Дополнительные советы по оптимизации

Выясним, на что еще стоит обратить внимание при работе с такими задачами:

  1. Проверка на пустые значения: Всегда проверяйте ЗначениеЗаполнено() перед добавлением в строку, чтобы не получить строку вида "Пломба1, , Пломба3".
  2. Типизация в макете: Убедитесь, что параметр в макете (в свойствах ячейки) имеет тип Текст, а не Число, иначе длинная строка с запятыми может отображаться некорректно.
  3. Безопасность: Если данные в колонке "Пломба" могут содержать символы переноса строк, используйте СокрЛП() для очистки лишних пробелов: МассивЗначений.Добавить(СокрЛП(Строка(СтрокаТаблицы.Пломба)));.

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

← На главную