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