Open tormozit opened 1 year ago
Можно сделать костыльную реализацию через схему запроса без доработки платформы. Для этого ссылки можно записывать в виде &Поле<ИмяПоля>. А перед выполнением запроса вызывать конвертацию
// Выполняет подмену ссылок на выбранные поля на их выражения в выражениях выбранных полей и отборе. Они должны быть записаны в виде &Поле<ИмяВыбраногоПоля>.
// https://github.com/SeiOkami/OneS/issues/212
// Минимальная версия платформы 8.3.23
// Параметры:
// Запрос - Запрос -
Процедура ЗаменитьСсылкиПолей(Знач Запрос) Экспорт
Схема = Новый СхемаЗапроса;
Схема.УстановитьТекстЗапроса(Запрос.Текст);
Для Каждого ЗапросПакета Из Схема.ПакетЗапросов Цикл
Если ТипЗнч(ЗапросПакета) = Тип("ЗапросУничтоженияТаблицыСхемыЗапроса") Тогда
Продолжить
КонецЕсли;
Для Каждого Оператор Из ЗапросПакета.Операторы Цикл
ЗаменитьСсылкиВВыражениях(Оператор.ВыбираемыеПоля, ЗапросПакета, Оператор);
//ЗаменитьСсылкиВВыражениях(Оператор.Группировка, ЗапросПакета, Оператор); // Не работает из-за ошибки платформы https://www.hostedredmine.com/issues/994651
ЗаменитьСсылкиВВыражениях(Оператор.Отбор, ЗапросПакета, Оператор);
КонецЦикла;
КонецЦикла;
Запрос.Текст = Схема.ПолучитьТекстЗапроса();
КонецПроцедуры
// .
// Параметры:
// КоллекцияВыражений - Массив[ВыражениеСхемыЗапроса, Произвольный] -
// ЗапросПакета - ЗапросВыбораСхемыЗапроса -
// Оператор - ОператорВыбратьСхемыЗапроса -
Процедура ЗаменитьСсылкиВВыражениях(Знач КоллекцияВыражений, Знач ЗапросПакета, Знач Оператор) Экспорт
Для Каждого ВыражениеСхемыЗапроса Из КоллекцияВыражений Цикл
Если ТипЗнч(ВыражениеСхемыЗапроса) = Тип("ВыражениеСхемыЗапроса") Тогда
НовоеВыражение = ЗаменитьСсылкиПолейВыражения("" + ВыражениеСхемыЗапроса, Оператор, ЗапросПакета);
КоллекцияВыражений[КоллекцияВыражений.Индекс(ВыражениеСхемыЗапроса)] = новый ВыражениеСхемыЗапроса(НовоеВыражение);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
// .
// Параметры:
// Выражение - Строка -
// Оператор - ОператорВыбратьСхемыЗапроса -
// ЗапросПакета - ЗапросВыбораСхемыЗапроса -
// Возвращаемое значение:
// Строка -
Функция ЗаменитьСсылкиПолейВыражения(Знач Выражение, Знач Оператор, Знач ЗапросПакета) Экспорт
Ссылки = СтрНайтиВсеПоРегулярномуВыражению("" + Выражение, "&Поле(\w+)");
Для Каждого Ссылка Из Ссылки Цикл
ИмяПоля = Ссылка.ПолучитьГруппы()[0].Значение;
ПолеРезультата = ЗапросПакета.Колонки.Найти(ИмяПоля);
Если ПолеРезультата = Неопределено Тогда
ВызватьИсключение СтрШаблон("Неверная ссылка на поле (%1)", Ссылка.Значение);
КонецЕсли;
ВыражениеЗамена = "(" + Оператор.ВыбираемыеПоля[ЗапросПакета.Колонки.Индекс(ПолеРезультата)] + ")";
Выражение = СтрЗаменить(Выражение, Ссылка.Значение, ВыражениеЗамена);
КонецЦикла;
Возврат Выражение;
КонецФункции
[ОшибкаВоВремяВыполненияВстроенногоЯзыка] по причине: {(1, 1)}: Поле не найдено "Нет" <<?>>Нет + 1
Исправил
Ты забыл удаление "мусора" после использования СхемыЗапроса, который сломает текст запроса если в нем есть условия построителя с фигурными скобками "{}"
Функция УдалитьМусорПослеСхемыЗапроса(Знач ТекстЗапроса) Экспорт
Для НомерПоля = 1 По 20 Цикл
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, СтрШаблон(" КАК Поле%1", Формат(НомерПоля, "ЧН=; ЧГ=")), "");
КонецЦикла;
Возврат ТекстЗапроса;
КонецФункции
@PerlAmutor старайся сначала описывать (например в виде ссылки) проблему, а потом ее решение.
Попытка преобразовать группировки таким методом через схему запроса столкнулась в ошибкой платформы https://www.hostedredmine.com/issues/994651
https://partners.v8.1c.ru/forum/topic/2132138
Прошу добавить возможность использовать ранее определенные поля запроса в тексте запроса.
Например:
Очень часто встречаются сложные конструкции, состоящие из повторяющихся кусков, которые даже читать не возможно, не говоря уже об их программировании. Предлагаемая возможно заметно упростит как написание запроса, так и его чтение.
В реальных запросах будет возникать проблема не однозначности имен таких полей, поэтому надо добавить к началу применения такого поля какой нибудь символ, например "!", тогда текст примера запроса будет выглядеть так.
Реализация такого пожелания не сложная, по сути надо добавить препроцессор, который заменит !ИМЯ на определение этого имени.