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