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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 29.08.2002, 10:58   #1  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Фильтрация
Ничего не понимаю.

Есть форма, в DataSource одна таблица.

В Class Declaration формы объявляю:
PHP код:
      QueryBuildRange         criteriaFirstGroup
В init() датасоурса инициализирую:

PHP код:
    criteriaFirstGroup this.query().dataSourceNo(1).addRange(fieldnum(VendTrans,AmountCur)); 
В executeQuery() накладываю значение:

PHP код:
   criteriaFirstGroup.value(variable); 
Строка variable формируется в зависимости от состояния контролов на форме.


Вопрос первый: почему установка значения моего фильтра сбивает фильтры установленные стандартным способом ? Я же устанавливаю значение поля своего QueryBuildRange.


Хорошо. Можно попробовать перед:

PHP код:
        criteriaFirstGroup.value(variable); 
смотреть какие уже наложены фильтры, сохранять их и после наложения установки значения своего фильтра накладывать их обратно. Делаю так:

PHP код:
  query2 this.query();
  
qbds query2.dataSourceNo(1);
  
rangeCount =  qbds.rangeCount();
  for (
rangeCnt=1rangeCnt<=rangeCount; ++rangeCnt)
  {
    
qbr =  qbds.range(rangeCnt);
    
field qbr.field();
    
table qbr.table();
    
fieldName fieldid2name(table,field);
  } 
Все это тоже в executeQuery().

Вопрос второй: при отладке этого кода видно, что rangeCount всегда равен 1. То есть тому фильтру, который я установил в init(), а дополнительные фильтры наложенные пользователем, как будто не замечаются ?
Старый 29.08.2002, 11:14   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
наверное...
твой код ДО или ПОСЛЕ super() стоит?

Т.е. ты свои действия делаешь ДО того, как Аксапта выполнит стандартные или ПОСЛЕ?
Старый 29.08.2002, 11:21   #3  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Сначала был мой код потом super(), теперь попробовал наоборот - результат тот же.
Старый 29.08.2002, 12:53   #4  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Для того чтобы получить query с пользовательскими фильтрами и сортировками, надо использовать _ds.QueryRun().query()
Старый 29.08.2002, 13:35   #5  
Андре is offline
Андре
Moderator
Сотрудники компании GMCS
 
2,375 / 464 (20) +++++++
Регистрация: 03.12.2001
Спасибо. Действительно работает.
Старый 27.05.2004, 17:00   #6  
Кирилл
Гость
 
n/a
В каком месте использовать _ds.QueryRun().query()?
В Init датасорса this.QueryRun().query() вместо this.query() не поместить, вылетает с ошибкой объект не инициализирован

в обработке изменения контролов фильтр добавляется, но не работает

в ExecuteQuery не работает и не добавляется


Первый подход хотя бы работает, только рушит пользовательские фильтры
Старый 28.05.2004, 10:30   #7  
Кирилл
Гость
 
n/a
Если в executeQuery() написать

info(this.queryRun().query().dataSourceNo(1).toString());
super();

то получится:
Ошибка времени выполнения. : <empty class> object не инициализирован.

Если в executeQuery() написать

super();
info(this.queryRun().query().dataSourceNo(1).toString());

То нормально выводится запрос, значит наложить свой фильтр я могу только после супера?
Но после супера он не будет отработан. В результате фильтр есть, но он не работает.
Старый 28.05.2004, 10:57   #8  
Кирилл
Гость
 
n/a
Help Mazzy
I like clocks too. I'm hungry too.
How does it (QueryRun()) work?
F^&%$#g c&@%y Axapta.
Старый 28.05.2004, 11:30   #9  
Dron AKA andy is offline
Dron AKA andy
Moderator
 
944 / 253 (10) ++++++
Регистрация: 27.03.2002
Адрес: Москва
При первом вызове executeQuery() объект QueryRun еще не создан, как раз здесь он и создается. Поэтому перед наложением фильтра надо проверить, создан ли уже QueryRun, и если создан - использовать его, а нет - Query. На эту тему массу примеров можно найти, например, по перекрестным ссылкам.
Значения ranges присваиваются до супера, здесь все как обычно.
__________________
Андрей.
Старый 28.05.2004, 12:50   #10  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Что то мне подсказывает, что Dron AKA andy прав.
но, видимо, надо проверить?
проверю ближе к вечеру. Хорошо?
Старый 28.05.2004, 13:06   #11  
Кирилл
Гость
 
n/a
Хорошо
Этот код фильтр ставит, но все равно рушит пользовательские

public void executeQuery()
{
if (TmpWmsAvail_M047_DS.queryRun())
{
info('if (TmpWmsAvail_M047_DS.queryRun())');
if (ShowFree)
{
if (!criteriaShowFree) criteriaShowFree = TmpWmsAvail_M047_DS.queryRun().query().dataSourceNo(1).addRange(fieldnum(TmpWmsAvail_M047,Occupied_M047));
criteriaShowFree.value('Нет');
}
else
{
if (!criteriaShowFree) criteriaShowFree = TmpWmsAvail_M047_DS.queryRun().query().dataSourceNo(1).FindRange(fieldnum(TmpWmsAvail_M047,Occupied_M047));
criteriaShowFree.value('');
}
} // if (TmpWmsAvail_M047_DS.queryRun())
else
{
info('нету (TmpWmsAvail_M047_DS.queryRun())');
if (ShowFree)
{
if (!criteriaShowFree) criteriaShowFree = this.query().dataSourceNo(1).addRange(fieldnum(TmpWmsAvail_M047,Occupied_M047));
criteriaShowFree.value('Нет');
}
else
{
if (!criteriaShowFree) criteriaShowFree = this.query().dataSourceNo(1).AddRange(fieldnum(TmpWmsAvail_M047,Occupied_M047));
criteriaShowFree.value('');
}
}

super();
Старый 29.05.2004, 15:29   #12  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Кирилл. Дело в том, что вы совсем не следуете рекомендациям для разработчиков.
См. руководство разработчика. Глава "To access and modify a system generated query"
А также все что есть в хелпе по ключевому слову executeQuery.

Ваши проблемы возникают из-за того, что вы пытаетесь в executeQuery пересоздать query. А на самом деле executeQuery предназначен только для того, чтобы изменить параметры текущего query

Создавать query надо в init-методе. В excecuteQuery только изменять range.value.
Если вы будете следовать рекомендациям, то вы избежите ваших проблем.

Обратите внимание, что добавленный в init'е range можно сделать hidden или locked.
Тогда ваш range пользователь не сможет увидеть или не сможет изменить.

Чистый и очень наглядный пример правильного использования этой методики в Аксапте - форма KMKnowledgeCollectorCollection. См. datasource KMCollection

обратите также внимание, что rangeCriteria можно и не запоминать в форме, а пользоваться методом Datasource.findValue().
Старый 31.05.2004, 10:21   #13  
Кирилл
Гость
 
n/a
;-(
Уважаемый Сергей,
как раз следование примеру KMKnowledgeCollectorCollection и приводит к обрушению фильтров пользователя при изменении запроса в зависимости от состояния контролов на форме.

В форме KMKnowledgeCollectorCollection используется стандартный подход:
PHP код:
void init()
{
    
super();
    
queryBuildRange this.query().datasourceNo(1).addRange(fieldNum(KMCollectionkmCollectionId));
    
queryBuildRange.status(RangeStatus::HIDDEN);
}

и

void executeQuery
()
{
    ;
    
queryBuildRange.value(queryValue(KMCollectionId));
    
super();

Если Вы начнете читать эту тему с первого постинга, то обнаружите, что у Андре как и у меня, как и у других разработчиков этот метод вызывает нарекания.
Причина нареканий: если в форме установлен фильтр пользователем и мы пытаемся программно установить queryBuildRange, то действие фильтра пользователя будет отменено.

Для решения данной проблемы Wamr предложил использовать
не this.query().datasourceNo(1), а this.QueryRun().query().datasourceNo(1).
Мой вопрос как раз и заключается в том, как грамотно использовать this.QueryRun().query().datasourceNo(1).
Все чего я добился в этом направлении, это полное совпадение поведения моего кривого кода с поведением кода чистого и очень наглядного примера.
А это поведение меня не устраивает по изложенным выше причинам.

Обсуждение это было давно, значит, как минимум, Wamr и Андре решили проблему.
Старый 31.05.2004, 11:11   #14  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
как скажете. решили, так решили

Цитата:
Причина нареканий: если в форме установлен фильтр пользователем и мы пытаемся программно установить queryBuildRange, то действие фильтра пользователя будет отменено.
У меня не отменяются.

Выложите или пришлите проект, который можно загрузить в стандартное приложение. Постараюсь посмотреть ближе к вечеру и понять. Может быть, я ошибаюсь и отвечаю совсем не на заданный вопрос.
Старый 31.05.2004, 11:58   #15  
Кирилл
Гость
 
n/a
Выслал
на mazzy@mazzy.ru
Старый 31.05.2004, 12:12   #16  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
А фильтр теряется по всем полям или только по изменяемому в executeQuery?
Старый 31.05.2004, 13:25   #17  
Кирилл
Гость
 
n/a
По всем
Все фильтры исчезают как только я задаю этот QueryBuildRange.
Остается лишь тот, который я задал программно.

Кроме того, когда фильтр ставится программно, то в форме фильтров он появляется, а кнопка удалить фильтры остается недоступной.
Старый 14.11.2007, 15:23   #18  
gefr is offline
gefr
Участник
Аватар для gefr
MCBMSS
 
147 / 17 (1) ++
Регистрация: 01.11.2004
Адрес: МО, Котельники
Цитата:
Сообщение от Кирилл Посмотреть сообщение
Если в executeQuery() написать

info(this.queryRun().query().dataSourceNo(1).toString());
super();

то получится:
Ошибка времени выполнения. : <empty class> object не инициализирован.

Если в executeQuery() написать

super();
info(this.queryRun().query().dataSourceNo(1).toString());

То нормально выводится запрос, значит наложить свой фильтр я могу только после супера?
Но после супера он не будет отработан. В результате фильтр есть, но он не работает.
Он вылетает в первый раз, т.к. queryrun действительно еще не инициализирован. я делал так:
X++:
    if(this.queryRun()){
     if(this.queryRun().query().dataSourceNo(1).findRange(fieldnum(LedgerJournalTable, OffsetAccount))){
      this.query().dataSourceNo(1).clearRange(fieldnum(LedgerJournalTable, OffsetAccount));
      this.query().dataSourceNo(1).addRange(fieldnum(LedgerJournalTable, OffsetAccount)).value(
       this.queryRun().query().dataSourceNo(1).findRange(fieldnum(LedgerJournalTable, OffsetAccount)).value());
      } else {
      this.query().dataSourceNo(1).clearRange(fieldnum(LedgerJournalTable, OffsetAccount));
      }
     }

      super();

Последний раз редактировалось gefr; 14.11.2007 в 15:41.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Фильтрация в Lookup'е IvanS DAX: Программирование 18 16.08.2006 09:57
Фильтрация в 2.5 if_maks DAX: Программирование 10 10.03.2006 11:04
Фильтрация записей Лиса* DAX: Функционал 0 08.09.2004 11:07
Расширенная фильтрация Андре DAX: Программирование 3 22.07.2002 18:25
Фильтрация в Lookup-форме Rem DAX: Программирование 5 27.04.2002 08:27

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 07:54.