Запрос по уровням номенклатуры
Иногда 1С меня удивляет своей медвежьей услужливостью, т.е. делает контроль там, где он не требуется.
В одном отчете я получал иерархию номенклатуры запросом из нескольких вложенных таблиц, мне нужно было по каждой позиции иметь уровень, признак группы, и путь к этому элементу через наименования родителей.
Все работало, но я составил текст вручную для 6 уровней номенклатуры, а со временем клиент добавил уровней и попросил меня сделать доработку, чтобы работало и для 9 уровней.
В итоге я не стал заниматься copy-paste, а написал программный генератор запроса на 12 уровней (с запасом на будущее):
З = Новый Запрос( "ВЫБРАТЬ | Т.Ссылка, | Т.Наименование, | Т.Наименование КАК Порядок, | 0 КАК Уровень, | Т.ЭтоГруппа |ПОМЕСТИТЬ Т0 |ИЗ | Справочник.Номенклатура КАК Т |ГДЕ | Т.Родитель = ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) | И &УсловиеЭлементов |"); //Осипов - для 12 уровней отчета ВсегоУровней = 10; //от 0 до 11 - 12 уровней Для Инд = 1 По ВсегоУровней Цикл ТекТекст = "ВЫБРАТЬ | Т.Ссылка, | Т.Наименование, | ЕСТЬNULL(Т0.Порядок, """") + ""."" + Т.Наименование КАК Порядок, | &Уровень1 КАК Уровень, | Т.ЭтоГруппа |ПОМЕСТИТЬ Т1 |ИЗ | Справочник.Номенклатура КАК Т | ВНУТРЕННЕЕ СОЕДИНЕНИЕ Т0 КАК Т0 | ПО (Т0.Ссылка = Т.Родитель) |ГДЕ | &УсловиеЭлементов"; ИндСтрокой = XMLСтрока(Инд); ПредИндСтрокой = XMLСтрока(Инд-1); ТекТекст = СтрЗаменить(ТекТекст, "&Уровень1", ИндСтрокой); ТекТекст = СтрЗаменить(ТекТекст, "Т1", "Т" + ИндСтрокой); ТекТекст = СтрЗаменить(ТекТекст, "Т0", "Т" + ПредИндСтрокой); З.Текст = З.Текст + ";" + Символы.ПС + ТекТекст; КонецЦикла; //Осипов - для 12 уровней отчета Для Инд = 0 По ВсегоУровней Цикл ТекТекст = "ВЫБРАТЬ | Т.Ссылка КАК Номенклатура, | Т.Наименование, | ЕСТЬNULL(Т.Порядок, """") КАК Порядок, | Т.Уровень, | Т.ЭтоГруппа, | ЛОЖЬ КАК ЭтоИтого |ИЗ | Т0 КАК Т |ГДЕ | &УсловиеГруппы1"; ИндСтрокой = XMLСтрока(Инд); ПредИндСтрокой = XMLСтрока(Инд-1); ТекТекст = СтрЗаменить(ТекТекст, "&УсловиеГруппы1", "ИСТИНА"); ТекТекст = СтрЗаменить(ТекТекст, "Т0", "Т" + ИндСтрокой); З.Текст = З.Текст + ?(Инд = 0, ";", " ОБЪЕДИНИТЬ ВСЕ ") + Символы.ПС + ТекТекст; КонецЦикла; З.Текст = З.Текст + " ОБЪЕДИНИТЬ ВСЕ " + " |ВЫБРАТЬ | ""ИТОГО"", | ""ИТОГО"", | """", | 1, | ИСТИНА, | ИСТИНА |";
Однако я столкнулся с проблемой, что если делал отчет на 10 уровней, то он работал, а вот если на 12 — то уже нет.
Я долго ломал голову, что ему не нравится.
Обратил внимание, что при большом количестве уровне тип поля Порядок начинает содержать не только Строка, но и Null.
Таким образом я понял, что 1С не может соединить много строк длиной 150 символов в одну большую строку, т.к. может быть превышение 1024 символов.
В итоге я оставил 10 уровней. Т.к. я хотел использовать эту таблицу дальше, я убрал тип Null путем несложной обработки:
ТЗ = З.Выполнить().Выгрузить(); ТЗ.Колонки.Добавить("ПорядокНовый", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(1024))); М = ТЗ.ВыгрузитьКолонку("Порядок"); ТЗ.ЗагрузитьКолонку(М, "ПорядокНовый"); ТЗ.Колонки.Удалить("Порядок"); ТЗ.Колонки.ПорядокНовый.Имя = "Порядок"; ТЗ.Сортировать("ЭтоГруппа, Порядок"); Возврат ТЗ;
Причем если использовал длинную строку, например, 4096, то по ней не получалось сортировать таблицу. А вот строка до 1024 символов работала нормально.
Вот такие неявные нюансы. Из-за этой особенности потерял достаточно времени, пытаясь разобраться.
Среда: УТ10.
Объем: 1 час.
Свежие комментарии