Запрос по уровням номенклатуры
Иногда 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 час.




Свежие комментарии