Каталог решений - Исправление UChoice для корректной работы с SQL

Исправление UChoice для корректной работы с SQL

Исправление UChoice для корректной работы с SQL

В наличии

Рассказывается как исправить типовой универсальный отчет: "Подбор объектов", что бы он работал с SQL.
В текущей реализации, которая лежит на ИТС без изменений много лет, в SQL базе отобрать объекты по вхождению в группу справочника невозможно, при этом в DBF варианте все работает.

Категория:

Описание

Проиллюстрирую сначала проблему на небольшом простом примере:

Создайте внешний отчет с единственным реквизитом на форме типа: «Справочник.Контрагенты», пусть идентификатор этого реквизита будет «Группа».

В процедуру Сформировать вставьте код:

Процедура Сформировать()
    Перем гУсл1;
    гУсл1 = СоздатьОбъект(«СписокЗначений»);
    гУсл1.ДобавитьЗначение(Группа.ТекущийЭлемент());

    ТекстЗапроса = «
    |ПеремОбъект = Справочник.Контрагенты.ТекущийЭлемент;
    |Группировка ПеремОбъект Без Групп;
    |Перем1 = Справочник.Контрагенты.Родитель;
    |Условие (Перем1 В гУсл1);
    |»;

    Запрос = СоздатьОбъект(«Запрос»);

    Если Запрос.Выполнить(ТекстЗапроса) = 0 тогда
        Предупреждение(«Запрос не выполнен!»);
        Возврат;
    КонецЕсли;

    Пока Запрос.Группировка(1, 1) = 1 Цикл
        Сообщить(Запрос.ПеремОбъект);
    КонецЦикла;

КонецПроцедуры

 

Попробуйте выполнить это в SQL базе и в DBF. В DBF, как и должно быть, выведет содержимое группы справочника, а вот в SQL не выведет ничего, — это и есть проблема.

 

Из-за этого в SQL базах не работает и отбор по группе справочника в известной универсальной обработке: UChoice.ert

Попробуйте отобрать ей в SQL базе объекты любого справочника по условию вхождения в группу — список будет пуст. В DBF базе, наоборот, все сработает.

Кроме того в ТиС эта универсальная обработка вставлена в саму конфигурацию под именем: «ПодборОбъектов», — проблемы те же.

 

Меня давно нервировало такое поведение системы, но все время не доходили руки разобраться, почему то работает, то нет. Но наконец руки дошли и вот, что я предлагаю.

Заставить в SQL базе запрос работать так же как в DBF можно как минимум 2-мя путями:

 

1. Перед Запрос.Выполнить(ТекстЗапроса); поставить строку: Запрос.ВключитьSQL(0);

Это недокументированная функция, в случае DBF ничего не делает, а влучае SQL как то меняет внутренню обработку запросов 1С. Запрос начинает работать правильно, но ОЧЕНЬ медленно.

 

2. Изменить текст запроса и вместо:

Условие (Перем1 В гУсл1);

написать:

Условие (гУсл1.Принадлежит(Перем1) = 1);

Согласно теории это тоже должно замедлить выполнение запроса, но на справочниках порядка 100 тыс позиций замедление у меня было в пределах погрешности измерения.

 

Соответственно для исправления UChoice будем использовать второй способ.

 

За формирование текста и выполнение запроса в отчете отвечает:

Процедура Запрос(ВидОбъекта)

В ней нас интересуют буквально самые последние строки перед Запрос.Выполнить():

            Если СокрЛП(ТабУсловия.КолУсловие) = «<>» Тогда
                ТекстЗапроса = ТекстЗапроса + «
                               |Перем» + НомСтр + » = «  + гТипОбъекта + стрТочка + ВидОбъекта + «.»
                                                      + ИмяПерем + «;»
                              «Условие (Не(Перем» + НомСтр + » В гУсл» + НомСтр + «));»;
            Иначе
                ТекстЗапроса = ТекстЗапроса + «
                               |Перем» + НомСтр + » = «  + гТипОбъекта + стрТочка + ВидОбъекта + «.»
                                                      + ИмяПерем + «;»
                              «Условие (Перем» + НомСтр + » « + ТабУсловия.КолУсловие + » гУсл» + НомСтр + «);»;
            КонецЕсли;

Их надо исправить на:

            Если СокрЛП(ТабУсловия.КолУсловие) = «<>» Тогда
                ТекстЗапроса = ТекстЗапроса + «
                               |Перем» + НомСтр + » = «  + гТипОбъекта + стрТочка + ВидОбъекта + «.»
                                                      + ИмяПерем + «;»
                              «Условие (гУсл» + НомСтр + «.Принадлежит(Перем» + НомСтр + «) = 0);»;
            ИначеЕсли СокрЛП(ТабУсловия.КолУсловие) = «В» Тогда
                ТекстЗапроса = ТекстЗапроса + «
                               |Перем» + НомСтр + » = «  + гТипОбъекта + стрТочка + ВидОбъекта + «.»
                                                      + ИмяПерем + «;»
                              «Условие (гУсл» + НомСтр + «.Принадлежит(Перем» + НомСтр + «) = 1);»;
            Иначе
                ТекстЗапроса = ТекстЗапроса + «
                               |Перем» + НомСтр + » = «  + гТипОбъекта + стрТочка + ВидОбъекта + «.»
                                                      + ИмяПерем + «;»
                              «Условие (Перем» + НомСтр + » « + ТабУсловия.КолУсловие + » гУсл» + НомСтр + «);»;

            КонецЕсли;

Собственно и все 🙂

Сохраняйте, пробуйте.

А тем, кто еще пишет под 7.7. стоит запомнить такое поведение SQL движка, — может пригодится.

has been added to your cart:
Оформление заказа