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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.03.2010, 16:24   #1  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Акс 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();
}
Выдает ошибку нехватает скобки правой на 28 символе. Однако, этот же запрос через обзор таблицы работает.
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  
miklenew is offline
miklenew
Участник
Аватар для miklenew
MCBMSS
1C
Лучший по профессии 2009
 
1,688 / 433 (18) +++++++
Регистрация: 10.07.2006
Адрес: г. Ликино-Дулёво
У вас длина не умещается в отведённые типом Range 250 символов.
Или скоко там у вас стоит.
Если бы этот query использовался токо в коде проблем бы не было.
Но он у вас идёт на форму, а там есть такое ограничение.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему.
Старый 01.03.2010, 16:56   #3  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
попробуйте вот так:
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  
miklenew is offline
miklenew
Участник
Аватар для miklenew
MCBMSS
1C
Лучший по профессии 2009
 
1,688 / 433 (18) +++++++
Регистрация: 10.07.2006
Адрес: г. Ликино-Дулёво
И ещё интересно как система будет работать с 25 полями.
25 не перебор ли?
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему.
Старый 01.03.2010, 17:01   #5  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
все дело в том что вот здесь:
X++:
qbdsrange1 =  qbds1.addRange(fieldid2ext(fieldNum(CinemaSchTable,FilmCode), 1));
вы создаете range только для первого элемента в массиве, и в его условие пытаетесь добавить сфорированный вами запрос по всем элементам. вот он вас и не понимает
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 01.03.2010, 17:06   #6  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
а, ещё нюанс
в БД (Oracle, SQL) массивные поля храняться в виде нескольких полей в виде Dimension, Dimension2_, Dimension3_ ... Dimension25_
а вы в запрос вставляете Dimension[25] база не знает такого поля
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 01.03.2010, 17:15   #7  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
сорри...
погорячился, вижу что вам нужно ИЛИ, а в моем варианте подставляется И.
насчет хранения полей-массивов я написал правильно, НО аксапта отправляет запрос в виде Dimension[25]...

сейчас попробую сделать ИЛИ
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 01.03.2010, 17:24   #8  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Цитата:
Сообщение от lev Посмотреть сообщение
попробуйте вот так:
X++:
if (FindFilm.valueStr())
    {
        for (_idx=2; _idx <=25; _idx++)
        {
               qbdsrange1 = qbds1.addRange(fieldId2Ext(fieldNum(CinemaSchTable,FilmCode),_idx));
               qbdsrange1.value(QueryValue(CinemaFilmCode));
        }
        
    }
Запрос работает через And. А мне нужно ИЛИ
Старый 01.03.2010, 17:25   #9  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Цитата:
Сообщение от lev Посмотреть сообщение
а, ещё нюанс
в БД (Oracle, SQL) массивные поля храняться в виде нескольких полей в виде Dimension, Dimension2_, Dimension3_ ... Dimension25_
а вы в запрос вставляете Dimension[25] база не знает такого поля
Итак попробывала, не помогло
Старый 01.03.2010, 17:27   #10  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Цитата:
Сообщение от miklenew Посмотреть сообщение
И ещё интересно как система будет работать с 25 полями.
25 не перебор ли?
Но точно также работает Табель учета рабочего времени (31 день) и все хорошо. Точно также работают Time в зарплате и тоже все хорошо
Старый 01.03.2010, 17:30   #11  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Цитата:
Сообщение от miklenew Посмотреть сообщение
У вас длина не умещается в отведённые типом Range 250 символов.
Или скоко там у вас стоит.
Если бы этот query использовался токо в коде проблем бы не было.
Но он у вас идёт на форму, а там есть такое ограничение.
если бы не влезало в 250 символов , то он бы выдал ошибку. А он модчит и не фильтрует.
Старый 01.03.2010, 17:48   #12  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Посмотрела трассировку запроса. Там вооще нет критериев выбора

WHERE (DATAAREAID=?) и все
Старый 01.03.2010, 17:55   #13  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Вроде, к массивовым полям нельзя применять синтаксис расширенных диапазонов: 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  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Вот последнего предложения я и не прочла. Значит надо все переделывать. Т.к. дургого решения не вижу.
Старый 01.03.2010, 18:08   #15  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Arahnid Посмотреть сообщение
Вот последнего предложения я и не прочла. Значит надо все переделывать. Т.к. дургого решения не вижу.
Либо превратите FilmCode в 25 отдельных полей, либо выполните все условия по очереди, без расширенных диапазонов, наберите RecId в Set и потом через запятую вставьте значения из Set'а в range.

P.S. Ну, т.е. не по очереди конечно, а в обычный while select вставьте эти условия и запишите RecId циклом в Set. По окончании в Set'е окажутся только уникальные значения RecId. Их - в range через запятую. Если надо будет показывать запрос пользователю, то возможно еще придется делиться на несколько range по не более 250 символов в каждом.

Последний раз редактировалось Gustav; 01.03.2010 в 18:21.
Старый 01.03.2010, 18:12   #16  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
А где можно посмотреть пример такого кода?
Старый 01.03.2010, 18:28   #17  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Деления? Например, у меня здесь: Пользовательский генератор строк-перечислений...- 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;
}
Каждый элемент выходного Set - содержимое одной клеточки range. Этот метод в принципе то же самое, что в генераторе содержится в методе doProcessButton, только заточено уже под автономное использование.

Последний раз редактировалось Gustav; 01.03.2010 в 18:38.
Старый 01.03.2010, 18:49   #18  
miklenew is offline
miklenew
Участник
Аватар для miklenew
MCBMSS
1C
Лучший по профессии 2009
 
1,688 / 433 (18) +++++++
Регистрация: 10.07.2006
Адрес: г. Ликино-Дулёво
Цитата:
Сообщение от Arahnid Посмотреть сообщение
Вот последнего предложения я и не прочла. Значит надо все переделывать. Т.к. дургого решения не вижу.
Если будете переделывать структуру данных, возмите за основу не Dimension, а таблицу InventDim.
Где то давно обсуждалось что при большом количестве Dimension запросы к бд становятся долгими, и это механизм теряет свои плюсы.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему.
Старый 01.03.2010, 19:25   #19  
Arahnid is offline
Arahnid
Участник
 
880 / 60 (4) ++++
Регистрация: 09.08.2005
Адрес: Moscow
Спасибо за помощь, много нового узнала.
Решила сделать отдельные поля, т.к. по логике вещей поля равнозначны и вдальнейшем мне придется часто делать подобные выборки.

Еще раз спасибо.
Теги
query, range, dimensions

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
оптимизируем запросы. SHiSHok DAX: Программирование 18 13.09.2009 21:26
Запросы к связанным таблицам Rect DAX: Программирование 14 05.06.2007 10:16
Производство. Запросы\Развертывание\Обработка не дает нужный результат e@gle DAX: Функционал 11 11.05.2007 18:10
Сложные запросы в RLS Ruff DAX: Администрирование 12 30.08.2005 18:02
Разные запросы в 2-х и 3-х уровневой конфигурациях. Что делать?! Anais DAX: Программирование 12 04.11.2004 12:47

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

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

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