AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.03.2021, 14:39   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
element.args().caller() - хорошая мысль. но очень грубо
element.args().lookup*() - прекрасно. спасибо.

но я пошел уже другим путем и отрефакторил.
принцип по которому я пошел:
  1. я не добавляю свой датасорса в форму. что делает модификацию сильно легче - один edit-метод на форме + 1 контрол на форме
  2. я использую тот факт, что после super() в инициализации есть только Query, а QueryRun == null
  3. я работаю только с queryrun().query(), использую research(). И никогда сам не вызываю executeQuery(), который пересоздает queryRun из АОТ
  4. в частности, я добавляю свой датасорс только после того, как пользователь выбрал какой-то пункт в переключателе
  5. я отрефакторил код и трактую отсутствие моего датасорса как вполне валидное состояние "Все записи"

получился вот такой код:

X++:
protected static MdmViewMode get(FormDataSource fdsMain, TableId shadowTableId)
{
    MdmViewMode             ret;

    EnumId                  enumId      = enumnum(MdmType);
    QueryRun                qr          = fdsMain ? fdsMain.queryRun() : null;
    QueryBuildDataSource    qbds        = qr      ? qr.query().dataSourceTable(shadowTableId, 1) : null;
    SysDictField            field       = qbds    ? SysDictTable::fieldWithEnum(qbds.table(), enumId) : null;
    QueryBuildRange         qbr         = field   ? qbds.findRange(field.id()) : null;
    str                     rangeValue  = qbr     ? qbr.value() : '';
    ;

    if( !qbds || !qbds.enabled() )
    {
        ret = MdmViewMode::All;
    }
    else if( qbds && qbds.joinMode() == JoinMode::NoExistsJoin && rangeValue == SysQuery::value(MdmEnumViewMode::completed()) )
    {
        ret = MdmViewMode::InProcess;
    }
    else if( qbds && qbds.joinMode() == JoinMode::NoExistsJoin && rangeValue == SysQuery::value(MdmType::StopProcessing) )
    {
        ret = MdmViewMode::Active;
    }
    else if( qbds && qbds.joinMode() == JoinMode::ExistsJoin && rangeValue == SysQuery::value(MdmType::StopProcessing) )
    {
        ret = MdmViewMode::Stopped;
    }
    else if( qbds && qbds.joinMode() == JoinMode::ExistsJoin && rangeValue == SysQuery::value(MdmType::Error) )
    {
        ret = MdmViewMode::Error;
    }
    else
    {
        ret = MdmViewMode::UserDefined;
    }

    return ret;
}
X++:
// предполагаем, что в запросе только один range по полю mdmType
protected static boolean set(
    FormDataSource  fdsMain,
    TableId         shadowTableId,
    MdmViewMode     viewMode)
{
    EnumId                  enumId      = enumnum(MdmType);
    QueryRun                qr          = fdsMain ? fdsMain.queryRun() : null;
    QueryBuildDataSource    qbds        = qr      ? SysQuery::findOrCreateDataSource(qr.query(), shadowTableId, fdsMain.table()) : null;
    SysDictField            field       = qbds    ? SysDictTable::fieldWithEnum(qbds.table(), enumId) : null;
    str                     rangeValue;
    ;

    if( qbds && field )
    {
        startLengthyOperation();

        switch( viewMode )
        {
            case MdmViewMode::UserDefined:
                qbds.enabled(true);
                qbds.relations(true);
                qbds.joinMode(JoinMode::InnerJoin);
                rangeValue = SysQuery::valueUnlimited();
                break;

            case MdmViewMode::All:
                qbds.enabled(false);
                qbds.relations(true);
                qbds.joinMode(JoinMode::ExistsJoin);
                rangeValue = SysQuery::valueUnlimited();
                break;

            case MdmViewMode::InProcess:
                qbds.enabled(true);
                qbds.relations(true);
                qbds.joinMode(JoinMode::NoExistsJoin);
                rangeValue = SysQuery::value(MdmEnumViewMode::completed());
                break;

            case MdmViewMode::Active:
                qbds.enabled(true);
                qbds.relations(true);
                qbds.joinMode(JoinMode::NoExistsJoin);
                rangeValue = SysQuery::value(MdmType::StopProcessing);
                break;

            case MdmViewMode::Stopped:
                qbds.enabled(true);
                qbds.relations(true);
                qbds.joinMode(JoinMode::ExistsJoin);
                rangeValue = SysQuery::value(MdmType::StopProcessing);
                break;

            case MdmViewMode::Error:
                qbds.enabled(true);
                qbds.relations(true);
                qbds.joinMode(JoinMode::ExistsJoin);
                rangeValue = SysQuery::value(MdmType::Error);
                break;

            default:
                throw error(Error::unsupportedEnum(funcname(), viewMode));
        }

        qbds.fetchMode(QueryFetchMode::One2One);
        qbds.firstOnly(true);

        SysQuery::findOrCreateRange(qbds, field.id()).value(rangeValue);

        fdsMain.research();

        endLengthyOperation();
        return true;
    }

    return false;
}
таким образом я совсем не вмешиваюсь в работу формы до тех пор, пока пользователь не жамкнет переключатель. после того, как жамкнет, в queryrun формы будет добавлен датасорс.

до жамка:
Название: before.PNG
Просмотров: 617

Размер: 7.8 Кб

после жамка:
Нажмите на изображение для увеличения
Название: after.PNG
Просмотров: 394
Размер:	14.6 Кб
ID:	13131

спасибо за советы и помощь.
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: sukhanchik (2), Raven Melancholic (2).
Старый 10.03.2021, 11:11   #2  
TasmanianDevil is offline
TasmanianDevil
Мрачный тип
Аватар для TasmanianDevil
Злыдни
 
885 / 389 (14) ++++++
Регистрация: 24.01.2005
Адрес: Томск
Цитата:
Сообщение от mazzy Посмотреть сообщение
никогда сам не вызываю executeQuery(), который пересоздает
queryRun из АОТ
Я таки уже и дико извиняюсь, что влезаю в дискуссию, но оно не из AOT, а из текущего экземпляра query() источника данных текущего экземпляра формы создается с учетом уже сделанных ранее на этом query() изменений - в противном случае тупо не работали бы фильтры (которые делают через query() источника данных, как например фильтры по разнесенности,неразнесенности в журнальном фреймворке)
К томе же реализация фильтров через queryRun().query() - не самый лучший вариант.
Кто мешает пользователю в такой форме поиграться с запросом и вызвать стандартными средствами executeQuery(), похоронив все созданное непосильным трудом в queryRun().query() ?
__________________
Мы летаем, кружимся, нагоняем ужасы ...

Последний раз редактировалось TasmanianDevil; 10.03.2021 в 11:15.
Старый 10.03.2021, 11:22   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от TasmanianDevil Посмотреть сообщение
Я таки уже и дико извиняюсь, что влезаю в дискуссию, но оно не из AOT, а из текущего экземпляра query() источника данных
угу. я там вообще коряво сформулировал. но править уже нет желаения.

Цитата:
Сообщение от TasmanianDevil Посмотреть сообщение
К томе же реализация фильтров через queryRun().query() - не самый лучший вариант.
Кто мешает пользователю в такой форме поиграться с запросом и вызвать стандартными средствами executeQuery(), похоронив все созданное непосильным трудом в queryRun().query() ?
Именно! никто не мешает пользователю поиграться. В том числе и я не мешаю.

если пользователь "сломает" мои фильтры,
то метод get вернет MdmViewMode::UserDefined
для моего кода это вполне штатная ситуация.

Именно с queryRun!
Это самый лучший вариант.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 10.03.2021 в 11:25.
Теги
reffield

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Фильтрование записей при "переходе к основной таблице" demID DAX: Программирование 10 18.11.2015 12:52
Баг на форме "Проводки по сопоставлению" S.Kuskov DAX: Программирование 12 29.04.2009 19:19
Через map узнать fieldId Dron AKA andy DAX: Программирование 6 20.02.2004 18:18
Объединить несколько полей таблицы в одном поле Grid-а на форме? storer DAX: Программирование 2 12.11.2003 14:08
"Пустое" значение Enum в веб-форме LedgerVoucher DAX: Программирование 4 25.07.2002 12:35

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 04:27.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.