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