При обработке коллекций данных (например, таблиц частей или соответствий) часто возникает задача вывести результаты проверки пользователю. Типичная ошибка заключается в том, что метод Сообщить() вызывается внутри внутреннего цикла на каждой итерации. В результате окно сообщений загромождается множеством отдельных строк вместо одной компактной записи вида: «Контрагент - ООО Ромашка в строке - 2, 3, 4».
Рассмотрим, почему возникает эта проблема и как правильно сформировать итоговую строку для вывода информации.
Проанализируем исходную структуру кода, с которой столкнулся разработчик:
Для Каждого Элемент из Соответствие Цикл
Сообщить("Контрагент - " + Элемент.Ключ + " в строке - ");
Для Каждого Строка Из Элемент.Значение Цикл
Сообщить(Строка);
КонецЦикла;
КонецЦикла;
В данном примере функция Сообщить() вызывается сначала для вывода заголовка с именем контрагента, а затем внутри цикла — для каждого элемента коллекции Элемент.Значение. Платформа 1С выводит каждый вызов Сообщить() с нового абзаца. Из-за этого заголовок и номера строк разделяются на отдельные сообщения.
Чтобы выводить информацию единым сообщением для каждого контрагента, необходимо накапливать список номеров строк в дополнительную переменную и вызывать Сообщить() один раз после завершения внутреннего цикла.
Рассмотрим рабочее решение задачи:
Для Каждого Элемент Из Соответствие Цикл
СтрокаДоп = "";
Для Каждого Строка Из Элемент.Значение Цикл
СтрокаДоп = СтрокаДоп + ", " + Строка;
КонецЦикла;
Сообщить("Контрагент - " + Элемент.Ключ + " в строке - " + СтрокаДоп);
КонецЦикла;
Разберем по шагам, как работает этот алгоритм:
СтрокаДоп.Сообщить(), содержащий имя контрагента и полный перечень строк.При использовании прямого сложения строк в начале сформированного списка может появляться лишний разделитель (например, , 2, 3, 4). Кроме того, если платформа 8.3 позволяет использовать встроенные функции, код можно сделать значительно более чистым и производительным.
1. Использование системной функции СтрСоединить
Если коллекция Элемент.Значение представляет собой массив строк, лучшим решением будет использование встроенной функции СтрСоединить(). Она автоматически объединяет элементы массива через указанный разделитель без образования лишних запятых в начале или конце:
Для Каждого Элемент Из Соответствие Цикл
СтрокаНомеров = СтрСоединить(Элемент.Значение, ", ");
Сообщить("Контрагент - " + Элемент.Ключ + " в строке - " + СтрокаНомеров);
КонецЦикла;
2. Удаление начального разделителя при ручной сборке
Если коллекция формируется вручную в цикле, лишнюю запятую в начале можно отсечь с помощью функции Сред():
Для Каждого Элемент Из Соответствие Цикл
СтрокаДоп = "";
Для Каждого Строка Из Элемент.Значение Цикл
СтрокаДоп = СтрокаДоп + ", " + Строка;
КонецЦикла;
// Удаляем первые 2 символа (запятую и пробел)
Если ЗначениеЗаполнено(СтрокаДоп) Тогда
СтрокаДоп = Сред(СтрокаДоп, 3);
КонецЕсли;
Сообщить("Контрагент - " + Элемент.Ключ + " в строке - " + СтрокаДоп);
КонецЦикла;
3. Форматирование числовых значений
Если номера строк являются числами, при неявном приведении к строке платформа может добавлять неразрывные пробелы для разделения тысяч (например, 1 000 вместо 1000). Чтобы избежать этого, используйте функцию Формат() с параметром ЧГ=0:
СтрокаНомер = Формат(НомерСтроки, "ЧГ=0");
В управляемом приложении вместо устаревшего метода Сообщить() рекомендуется применять объект СообщениеПользователю. Это позволяет привязать вывод текста к конкретным элементам формы или полям табличной части.
Для Каждого Элемент Из Соответствие Цикл
СтрокаНомеров = СтрСоединить(Элемент.Значение, ", ");
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Контрагент - " + Элемент.Ключ + " в строке - " + СтрокаНомеров;
Сообщение.Сообщить();
КонецЦикла;
Использование правильного накопления строк и системных функций форматирования позволяет сделать сообщения понятными для пользователя и избежать засорения окна вывода информации.