01.03.2010, 16:24 | #1 |
Участник
|
Акс 3.0 Запросы на источнике с или
Создан EDT FilmCode по примеру Dimension, но состоит из 25 элементов. Тип данных в нем int.
Затем сделана форма и одна из группы полей на grid FilmCode. Задача отфильтровать те строки, где в группе FilmCode хотя бы в одном элементе указано выбранное значение. Значение указывается через специальное поле StringEdit на форме. Пишу запрос X++: public void executeQuery() { QueryBuildRange qbdsrange1; QueryBuildDataSource qbds1; Integer _idx; str 10000 strFilter; str 10 CinemaFilmCode; ; qbds1 = this.query().dataSourceTable(tableNum(CinemaSchTable)); CinemaFilmCode = int2str(CinemaFilmTable::findName(FindFilm.valueStr()).FilmCode); qbds1.clearRange(fieldId2Ext(fieldNum(CinemaSchTable,FilmCode),1)); if (FindFilm.valueStr()) { qbdsrange1 = qbds1.addRange(fieldNum(CinemaSchTable,FilmCode)); strFilter = '((CinemaSchTable.FilmCode[1] == '+CinemaFilmCode+')'; for (_idx=2; _idx <=25; _idx++) { strFilter += ' || (CinemaSchTable.FilmCode['+ int2str(_idx)+'] == '+ CinemaFilmCode+')'; } strFilter += ')'; qbdsrange1.value(strFmt(strFilter)); } super(); } SELECT * FROM CinemaSchTable WHERE ((((CinemaSchTable.FilmCode[1] == 437) || (CinemaSchTable.FilmCode[2] == 437) || (CinemaSchTable.FilmCode[3] == 437) || (CinemaSchTable.FilmCode[4] == 437) || (CinemaSchTable.FilmCode[5] == 437) || (CinemaSchTable.FilmCode[6] == 437) || (CinemaSchTable.FilmCode[7] == 437) || (CinemaSchTable.FilmCode[8] == 437) || (CinemaSchTable.FilmCode[9] == 437) || (CinemaSchTable.FilmCode[10] == 437) || (CinemaSchTable.FilmCode[11] == 437) || (CinemaSchTable.FilmCode[12] == 437) || (CinemaSchTable.FilmCode[13] == 437) || (CinemaSchTable.FilmCode[14] == 437) || (CinemaSchTable.FilmCode[15] == 437) || (CinemaSchTable.FilmCode[16] == 437) || (CinemaSchTable.FilmCode[17] == 437) || (CinemaSchTable.FilmCode[18] == 437) || (CinemaSchTable.FilmCode[19] == 437) || (CinemaSchTable.FilmCode[20] == 437) || (CinemaSchTable.FilmCode[21] == 437) || (CinemaSchTable.FilmCode[22] == 437) || (CinemaSchTable.FilmCode[23] == 437)))) Если писать без указания таблицы FilmCode[24] = 541..., то тоже не работает. Если писать = или вместо || поставить or, то тоже не работает. Если в qbdsrange1.value(strFmt(strFilter)); записать просто 541, то по первому полю в группе работает. Не могу понять где ошиблась. Если X++: if (FindFilm.valueStr()) { qbdsrange1 = qbds1.addRange(fieldid2ext(fieldNum(CinemaSchTable,FilmCode),1)); strFilter = ' == 1)||(CinemaSchTable.FilmCode[1] == '+CinemaFilmCode+')'; for (_idx=2; _idx <=2; _idx++) { strFilter += ' || (CinemaSchTable.FilmCode['+ int2str(_idx)+'] == '+ CinemaFilmCode+')'; } strFilter += ''; qbdsrange1.value(strFmt(strFilter)); } Такое впечатление, что он пытается зачем-то поставить FilmCode[1] = Последний раз редактировалось Arahnid; 01.03.2010 в 17:07. |
|
01.03.2010, 16:54 | #2 |
Участник
|
У вас длина не умещается в отведённые типом Range 250 символов.
Или скоко там у вас стоит. Если бы этот query использовался токо в коде проблем бы не было. Но он у вас идёт на форму, а там есть такое ограничение.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.03.2010, 16:56 | #3 |
Ищущий знания...
|
попробуйте вот так:
X++: if (FindFilm.valueStr()) { for (_idx=2; _idx <=25; _idx++) { qbdsrange1 = qbds1.addRange(fieldId2Ext(fieldNum(CinemaSchTable,FilmCode),_idx)); qbdsrange1.value(QueryValue(CinemaFilmCode)); } }
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
01.03.2010, 16:59 | #4 |
Участник
|
И ещё интересно как система будет работать с 25 полями.
25 не перебор ли?
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.03.2010, 17:01 | #5 |
Ищущий знания...
|
все дело в том что вот здесь:
X++: qbdsrange1 = qbds1.addRange(fieldid2ext(fieldNum(CinemaSchTable,FilmCode), 1));
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
01.03.2010, 17:06 | #6 |
Ищущий знания...
|
а, ещё нюанс
в БД (Oracle, SQL) массивные поля храняться в виде нескольких полей в виде Dimension, Dimension2_, Dimension3_ ... Dimension25_ а вы в запрос вставляете Dimension[25] база не знает такого поля
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
01.03.2010, 17:15 | #7 |
Ищущий знания...
|
сорри...
погорячился, вижу что вам нужно ИЛИ, а в моем варианте подставляется И. насчет хранения полей-массивов я написал правильно, НО аксапта отправляет запрос в виде Dimension[25]... сейчас попробую сделать ИЛИ
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
01.03.2010, 17:24 | #8 |
Участник
|
|
|
01.03.2010, 17:25 | #9 |
Участник
|
|
|
01.03.2010, 17:27 | #10 |
Участник
|
|
|
01.03.2010, 17:30 | #11 |
Участник
|
если бы не влезало в 250 символов , то он бы выдал ошибку. А он модчит и не фильтрует.
|
|
01.03.2010, 17:48 | #12 |
Участник
|
Посмотрела трассировку запроса. Там вооще нет критериев выбора
WHERE (DATAAREAID=?) и все |
|
01.03.2010, 17:55 | #13 |
Moderator
|
Вроде, к массивовым полям нельзя применять синтаксис расширенных диапазонов: http://www.axaptapedia.com/Expressio...es#Limitations
Цитата:
Unfortunately, if you wish to filter on array fields in an Axapta table, such as the Dimensions field, there is no way to do so using the Query Expressions syntax.
|
|
01.03.2010, 18:00 | #14 |
Участник
|
Вот последнего предложения я и не прочла. Значит надо все переделывать. Т.к. дургого решения не вижу.
|
|
01.03.2010, 18:08 | #15 |
Moderator
|
Цитата:
P.S. Ну, т.е. не по очереди конечно, а в обычный while select вставьте эти условия и запишите RecId циклом в Set. По окончании в Set'е окажутся только уникальные значения RecId. Их - в range через запятую. Если надо будет показывать запрос пользователю, то возможно еще придется делиться на несколько range по не более 250 символов в каждом. Последний раз редактировалось Gustav; 01.03.2010 в 18:21. |
|
01.03.2010, 18:12 | #16 |
Участник
|
А где можно посмотреть пример такого кода?
|
|
01.03.2010, 18:28 | #17 |
Moderator
|
Деления? Например, у меня здесь: Пользовательский генератор строк-перечислений...- 2: Доп.вкладка для SysQueryForm
P.S. Еще вот такую "статику" у себя отыскал: X++: // Created on 01 Сен 2008 at 15:04:08 by KKU static Set choppedQueryRanges( Set _conditions = new Set(Types::String), str _separator = '||' ) { // "Нашинкованные диапазоны критериев" // на входе - множество условий (каждая строка существенно короче EDT Range) // на выходе - множество диапазонов (каждый максимально впихнут в длину EDT Range) // примеры элементов множества условий (_conditions): // (CenterId=="09000") или (RequestTable.ReasonId=="ВЫБ_Ф") Set setRanges = new Set(Types::String); SetEnumerator enumerator; str curr; str currElem; str currCrit = ''; str prevCrit = ''; int edtRangeSize = new DictField( tableNum(TmpSysQuery), fieldNum(TmpSysQuery, RangeValue) ).stringLen(); ; enumerator = _conditions.getEnumerator(); while (enumerator.moveNext()) { curr = enumerator.current(); currElem = strLTrim( strRTrim (strFmt(curr))); if (currElem) { currCrit = prevCrit + currElem + _separator; if ( strLen(currCrit) > (edtRangeSize + strLen(_separator)) ) { setRanges.add( subStr(prevCrit, 1, strLen(prevCrit)-strLen(_separator)) ); prevCrit = currElem + _separator; } else { prevCrit = currCrit; } } } if (prevCrit) { setRanges.add( subStr(prevCrit, 1, strLen(prevCrit)-strLen(_separator)) ); } return setRanges; } Последний раз редактировалось Gustav; 01.03.2010 в 18:38. |
|
01.03.2010, 18:49 | #18 |
Участник
|
Цитата:
Где то давно обсуждалось что при большом количестве Dimension запросы к бд становятся долгими, и это механизм теряет свои плюсы.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.03.2010, 19:25 | #19 |
Участник
|
Спасибо за помощь, много нового узнала.
Решила сделать отдельные поля, т.к. по логике вещей поля равнозначны и вдальнейшем мне придется часто делать подобные выборки. Еще раз спасибо. |
|