При конкатенации нескольких реквизитов или текстовых полей (например, адреса, комментариев, контактных данных) через запятую часто возникает проблема: если одно или несколько полей не заложены или содержат пустые строки, итоговый результат превращается в набор бессмысленных разделителей вида ", , , ". Рассмотрим, как правильно формировать строки в 1С, избегая появления фантомных запятых и пробелов.
Самым красивым и современным решением в платформе 1С:Предприятие 8.3 является использование массива для накопления заполненных значений с последующей склейкой через функцию СтрСоединить().
Разберем по шагам этот подход:
ЗначениеЗаполнено() или ПустаяСтрока(). Если поле заполнено, добавляем его в массив.
МассивСтрок = Новый Массив;
Если ЗначениеЗаполнено(стр.Комментарий) Тогда
МассивСтрок.Добавить(СокрЛП(стр.Комментарий));
КонецЕсли;
Если ЗначениеЗаполнено(стр.АД) Тогда
МассивСтрок.Добавить(СокрЛП(Строка(стр.АД)));
КонецЕсли;
Если ЗначениеЗаполнено(стр.ТФ) Тогда
МассивСтрок.Добавить(СокрЛП(Строка(стр.ТФ)));
КонецЕсли;
Если ЗначениеЗаполнено(СтрокаДоставки) Тогда
МассивСтрок.Добавить(СокрЛП(СтрокаДоставки));
КонецЕсли;
Результат = СтрСоединить(МассивСтрок, ", ");
Важное примечание: функция СтрСоединить() сама по себе не исключает пустые элементы массива, поэтому проверку ЗначениеЗаполнено() необходимо делать именно перед добавлением элемента в массив.
В типовых конфигурациях на базе Библиотеки Стандартных Подсистем (БСП) для аналогичных целей можно использовать функцию СтроковыеФункцииКлиентСервер.ПолучитьСтрокуИзМассиваПодстрок(МассивСтрок, ", ").
Если подстрок много, чтобы не писать множественные условия Если, можно поместить все проверяемые реквизиты в коллекцию (структуру или массив) и обработать их в цикле.
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("Комментарий", СокрЛП(стр.Комментарий));
СтруктураДанных.Вставить("Адрес", СокрЛП(стр.АД));
СтруктураДанных.Вставить("Телефон1", СокрЛП(стр.ТФ));
СтруктураДанных.Вставить("Телефон2", СокрЛП(стр.ТФ2));
СтруктураДанных.Вставить("Доставка", СокрЛП(СтрокаДоставки));
РезультатЗапись = "";
Для Каждого КлючИЗначение Из СтруктураДанных Цикл
Значение = СокрЛП(КлючИЗначение.Значение);
Если ЗначениеЗаполнено(Значение) Тогда
РезультатЗапись = РезультатЗапись + ?(ПустаяСтрока(РезультатЗапись), "", ", ") + Значение;
КонецЕсли;
КонецЦикла;
В данном примере проверка ?(ПустаяСтрока(РезультатЗапись), "", ", ") гарантирует, что разделитель будет подставляться только начиная со второго заполненного элемента.
Для частой склейки строк в модулях можно вынести логику в отдельную процедуру или функцию. Проанализируем пример такой функции:
Процедура ДобавитьКСтроке(ИсходящаяСтрока, ДобавляемоеЗначение, Разделитель = ", ")
ТекстДобавки = СокрЛП(Строка(ДобавляемоеЗначение));
Если ПустаяСтрока(ТекстДобавки) Тогда
Возврат;
КонецЕсли;
Если ПустаяСтрока(ИсходящаяСтрока) Тогда
ИсходящаяСтрока = ТекстДобавки;
Иначе
ИсходящаяСтрока = ИсходящаяСтрока + Разделитель + ТекстДобавки;
КонецЕсли;
КонецПроцедуры
Использование функции в основном коде выглядит лаконично и читаемо:
ИтоговыйТекст = "";
ДобавитьКСтроке(ИтоговыйТекст, стр.Комментарий);
ДобавитьКСтроке(ИтоговыйТекст, стр.АД);
ДобавитьКСтроке(ИтоговыйТекст, стр.ТФ);
ДобавитьКСтроке(ИтоговыйТекст, СтрокаДоставки);
ДобавитьКСтроке(ИтоговыйТекст, МО);
ДобавитьКСтроке(ИтоговыйТекст, стр.ИН);
Если строка уже сформирована с ошибками или поступает из внешнего источника, ее можно очистить постфактум. Однако стандартная функция СтрЗаменить() не всегда справляется с висячими запятыми по краям строки или двойными пробелами между разделителями.
Для глубокой очистки строки от повторяющихся запятых и пробелов можно применить следующий алгоритм:
// Пример очистки строки с разделителями
ВременнаяСтрока = СтрЗаменить(ИсходнаяСтрока, ", ", Символы.ПС);
ИтоговаяСтрока = "";
Для х = 1 По СтрЧислоСтрок(ВременнаяСтрока) Цикл
ТекущаяСтрока = СтрПолучитьСтроку(ВременнаяСтрока, х);
Если НЕ ПустаяСтрока(ТекущаяСтрока) Тогда
ИтоговаяСтрока = ИтоговаяСтрока + ?(ПустаяСтрока(ИтоговаяСтрока), "", ", ") + ТекущаяСтрока;
КонецЕсли;
КонецЦикла;
Если строка уже получена в формате ", Текст1, , Текст2, ", этот алгоритм разберет её по строкам, пропустит пустые фрагменты и соберет заново без лишних запятых в начале, середине и конце.
Резюме: Чтобы код оставался поддерживаемым и читаемым, избегайте громоздких конструкций из тернарных операторов ?() в одну строку. Наиболее предпочтительный подход — использование массива и платформенного метода СтрСоединить() либо вспомогательной процедуры добавления подстрок.