15.04.2013, 12:34 | #21 |
Участник
|
Цитата:
А самое интересное, что даже если в переменной строковой 1 значение - условие всё равно не отрабатывает... Пробовал построить qeury на 5 источников - не ахти получилось, если честно... Учитывая, что каждый источник связан с предыдущим по своим связям, которые через relations(true) не активируешь, делал их через addLink , не сработало. А если разбить пришедшую строку на элементы в контейнер и сравнивать элементы контейнера? Возможно бред написал, но пришла в голову такая мысль Последний раз редактировалось user_ax; 15.04.2013 в 12:36. |
|
15.04.2013, 12:55 | #22 |
Участник
|
Брр... чего-то вы далеко куда-то полезли.
Вам просто нужно реализовать это условие не через один LIKE, а через несколько через ИЛИ. Странно. А дополнительных символов никаких не оставили в условии? Никакие дополнительные символы (типа скобок) не нужны. Последний раз редактировалось S.Kuskov; 15.04.2013 в 12:58. |
|
15.04.2013, 13:20 | #23 |
Участник
|
Цитата:
В смысле через несколько или ? В смысле?) Строка имеет такой вид X++: <"Отдел продаж трансф.", "БП", "ДЗАТ", "ДЗБВА", "ДЗЕА", "РФ", "СРАЗ", "УБМ"> X++: <"БП."> |
|
15.04.2013, 13:28 | #24 |
Участник
|
попробуйте просто
X++: like "БП" Кстати а вам точно нужно сравнение по маске? Или возможно подойдёт равенство? Если вы хотите выбрать данные которые содержат подстроку "БП" тогда нужно X++: like "*БП*" |
|
15.04.2013, 13:33 | #25 |
Участник
|
Цитата:
Кавычки эти беруться из List насколько я понимаю, он их обрамляет в них. А лист я сделал для того, чтобы если будут добавлены ещё ветки, чтобы не переписывать запрос. |
|
15.04.2013, 13:44 | #26 |
Участник
|
|
|
15.04.2013, 13:53 | #27 |
Участник
|
Цитата:
Я так понимаю нужно их итерировать(ListIterator) для разбития и корректного отображения ? |
|
15.04.2013, 15:14 | #28 |
Участник
|
У-у-ух... Чего-то вы замудрили... запутался пока читал...
В каком виде Вам необходимо представить это все в Excel? Если в виде дерева с корнем выбранного Вами узла? Метод, который рекурсивно будет вызвывать сам себя в каждом узле - параллельно выводя все необходимые данные в Excel в случае их обнаружения. То есть их можно и не собирать в Листы и Мапы - если вывод будет производится сразу. Например: X++: public void WildRunning(str NameNode) { Table TableLocal; ; select while TableLocal where TableLocal.ParentNodeId == NameNode { ... //вывод в Excel this.WildRunnig(TableLocal.NameNode); } } |
|
15.04.2013, 15:38 | #29 |
Участник
|
Цитата:
Сообщение от LeonDerCom
У-у-ух... Чего-то вы замудрили... запутался пока читал...
В каком виде Вам необходимо представить это все в Excel? Если в виде дерева с корнем выбранного Вами узла? Метод, который рекурсивно будет вызвывать сам себя в каждом узле - параллельно выводя все необходимые данные в Excel в случае их обнаружения. То есть их можно и не собирать в Листы и Мапы - если вывод будет производится сразу. На первом входе скормить имя вашего узла... Да, с объяснениями туговато, согласен. Нет, не в виде дерева. Поле Отдел продаж - это дерево. Нужно выдать в отчёт те строки, в которых есть дочерний элемент данного дерева в зависимости от выбранного в нём элемента. там 3 уровня, если выбран второй уровень, у него есть подуровни. И если выбран 2 уровень, нужно вывести в отчёт все строки, в которых есть 3 подуровень. То есть, если выбрать БП - в отчёт попадут только строки, salesunitid в которых равен БП, а если выбрать Отдел продаж, в который входят БП,РФ, и т.д., то в отчёт попадут строки, salesunitid которых равен БП, РФ и т.д. Надеюсь боеле понятно объяснил. |
|
15.04.2013, 16:23 | #30 |
Участник
|
Разобьём задачу на две
1) определить список отделов для фильтрации 2) задать фильтр по списку отделов С первым пунктом я так понял вы справились. По второму пункту есть несколько решений: - использовать класс Query. Он поддерживает условие по списку значений. Хороший способ если список отделов не слишком велик. - использовать временную таблицу. Вместо фильтра по выбранным отделам сделать цикл по выбранным отделам. Результат поместить во временную таблицу, которую использовать для вывода отчёта. Если у вас уже используется временная таблица, то так возможно будет даже проще. - использовать вспомогательную постоянную таблицу. Поместить список отделов во вспомогательную таблицу. Присоеденить эту таблицу к источнику данных с целью его фильтрации. Хороший способ если число отделов велико. Выборка произвольных записей одним запросом |
|
|
За это сообщение автора поблагодарили: user_ax (1). |
15.04.2013, 16:36 | #31 |
Участник
|
user_ax
Теперь понятно. То что необходимо сделать для дерева - Вам подсказал plumbum. Далее ListIterator (поскольку у Вас все подразделения загоняются в List) - и вот уже то, что возвращает ListIterator гоним в запрос. X++: ListIterator Liter = new ListIterator('Ваш полученный лист'); String50 ( Ex. Type - ) lValue; ; while (Liter.more()) { lValue = Liter.value(); while select Table where Table.Field like +'*'+lValue+'*' // while select Table where Table.Field == lValue { ...//делаем что нужно } Liter.next(); } Последний раз редактировалось LeonDerCom; 15.04.2013 в 17:02. Причина: Очепятки + добавил случайно удаленную строчку=(( |
|
|
За это сообщение автора поблагодарили: user_ax (1). |
15.04.2013, 16:43 | #32 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Разобьём задачу на две
1) определить список отделов для фильтрации 2) задать фильтр по списку отделов С первым пунктом я так понял вы справились. По второму пункту есть несколько решений: - использовать класс Query. Он поддерживает условие по списку значений. Хороший способ если список отделов не слишком велик. - использовать временную таблицу. Вместо фильтра по выбранным отделам сделать цикл по выбранным отделам. Результат поместить во временную таблицу, которую использовать для вывода отчёта. Если у вас уже используется временная таблица, то так возможно будет даже проще. - использовать вспомогательную постоянную таблицу. Поместить список отделов во вспомогательную таблицу. Присоеденить эту таблицу к источнику данных с целью его фильтрации. Хороший способ если число отделов велико. Выборка произвольных записей одним запросом Цитата:
Сообщение от LeonDerCom
user_ax
Теперь понятно. То что необходимо сделать для дерева - Вам подсказал plumbum. Далее ListIterator (поскольку у Вас все подразделения загоняются в List) - и вот уже то, что возвращает ListIterator гоним в запрос. X++: ListIterator Lier = new ListIterator('Ваш полученный лист'); String50 ( Ex. Type - ) lValue; ; while (Liter.more()) { while select Table where Table.Field like +'*'+lValue+'*' // while select Table where Table.Field == lValue { ...//делаем что нужно } Liter.next(); } |
|
15.04.2013, 17:04 | #33 |
Участник
|
Вы получили список дочерних подразделений и записали их в Лист - так вот вытягнивайте с помощью Итератора поочередно элементы Листа и кидайте их в запрос.
По поводу Excel - почему нет? |
|
15.04.2013, 17:20 | #34 |
Участник
|
Цитата:
Но попробую в любом случае |
|
15.04.2013, 23:40 | #35 |
Участник
|
Можно в запросе сортировать и загружать в Лист. Можно загружать в контейнер и сортировать там следующим алгоритмиком.
X++: container cList; str sBufi, sBufj; int i,j; ; //данные загрузили в cList i=1; while (i<=conlen(cList)) { j=1; while (j<=conlen(cList)) { sBufi = conpeek(cList, i); sBufj = conpeek(cList, j); if (sBufi<sBufj) { cList = condel(cList, i, 1); cList = conins(cList, i, sBufj); cList = condel(cList, j, 1); cList = conins(cList, j, sBufi); } j++; } i++; } conview(cList); |
|
16.04.2013, 08:06 | #36 |
Участник
|
LeonDerCom, проблема возникает когда в отчёте не нужно разбивать данные по каждому отделу (а фильтровать надо). Ну т.е. например данные в выбранных отделах нужно сгрупировать по какой-нибудь финансовой аналитике. В этом случае для вывода каждой строки отчёта мы должны агрегировать данные по всем отделам сразу. В случае пошагового обхода отделов нам прийдётся либо сохранять предварительные данные во временную таблицу либо в ещё какой-нибудь промежуточный буфер. Если же сделать запрос по данным сразу с нужной группировкой, то промежуточный буфер не понадобится, но в таком случае неообходимо будет в запросе задать фильтр только по нужным отделам.
|
|
16.04.2013, 09:21 | #37 |
Участник
|
Цитата:
Сообщение от user_ax
Ваш способ конечно очень привлекателен, но , допустим у меня будет сортировка по необходимым мне полям, а есди делать через listiterator, он возьмёт первое значение из листа, выберет все строки согласно нему, возьмёт второе , выберет все строки согласно второму, при этом заданная мною группировка не будет учитываться уже...
Но попробую в любом случае X++: static void Job45(Args _args) { SMMSalesUnitId salesUnitId; RecordSortedList salesUnitList = new RecordSortedList(tablenum(SMMSalesUnit)); SMMSalesUnit su; boolean x; void getChildSalesUnit(SMMSalesUnitId _salesUnitIdParent) { SMMSalesUnit salesUnit; ; //Add current sales unit to list salesUnit = SMMSalesUnit::find(_salesUnitIdParent); salesUnitList.ins(salesUnit); //Check for child records select count(RecId) from salesUnit where salesUnit.ParentId == _salesUnitIdParent; if (salesUnit.RecId != 0) { //Go through child records and call recurent function while select SalesUnitId from salesUnit where salesUnit.ParentId == _salesUnitIdParent { getChildSalesUnit(salesUnit.SalesUnitId); } } } ; salesUnitId = "Отдел продаж трансф."; salesUnitList.sortOrder(fieldnum(SMMSalesUnit, SalesUnitId)); getChildSalesUnit(salesUnitId); for (x = salesUnitList.first(su); x; x = salesUnitList.next(su)) { print su.SalesUnitId; } pause; }
__________________
// no comments Последний раз редактировалось dech; 16.04.2013 в 09:35. |
|
16.04.2013, 09:34 | #38 |
Участник
|
S.Kuskov
Угу, об этом и говорю. Проще использовать временную таблицу - удобней заносить данные и пользоваться уже привычными запросами. Можно создать двумерный массив из контейнеров и уже группировать и фильтровать данные проходя по нему. Можно двумерный массив из обычных. И все же вариантов куча. X++: container cList, cListLine, cListLineBuf; int sBufi, sBufj; int i,j, iLength; ; cListLine = ['Яблоки, кг','Груши, кг','Сливы, кг','Батон, 1 шт']; cList = conins(cList, 1, cListLine); cListLine = [20,40,90,30]; cList = conins(cList, 2, cListLine); cListLine = [13,55,85,25]; cList = conins(cList, 2, cListLine); cListLine = [05,100,100,100]; cList = conins(cList, 2, cListLine); cListLine = [25,19,13,15]; cList = conins(cList, 2, cListLine); cListLine = [12,10,55,1000]; cList = conins(cList, 2, cListLine); i = 3; while (i<=conlen(cList)) { j=1; while (j<=conlen(cList)) { cListLine = conpeek(cList, i); cListLineBuf = conpeek(cList, j); sBufi = conpeek(cListLine, 1); sBufj = conpeek(cListLineBuf, 1); if (sBufi<sBufj) { cList = condel(cList, i, 1); cList = conins(cList, i, cListLineBuf); cList = condel(cList, j, 1); cList = conins(cList, j, cListLine); } j++; } i++; } i = 1; while (i<=conlen(cList)) { cListLine = conpeek(cList, i); sBufi = conpeek(cListLine, 1); sBufj = conpeek(cListLine, 4); if (sBufi<21 && sBufj<101) { if (i==1) { info('<'+conpeek(cListLine, 1)+'> <'+conpeek(cListLine, 2)+'> <'+conpeek(cListLine, 3)+'> <'+conpeek(cListLine, 4)+'>'); } else { info('<'+int2Str(conpeek(cListLine, 1))+'> <'+int2Str(conpeek(cListLine, 2))+'> <'+int2Str(conpeek(cListLine, 3))+'> <'+int2Str(conpeek(cListLine, 4))+'>'); } } i++; } |
|
16.04.2013, 10:00 | #39 |
Участник
|
Простите, но это уже извращение. Контейнер подходит только чтобы хранить в одном месте данные разных типов. Для сортировки, фильтрации и группировки есть другие способы. Например, RecordSortedList - оптимальное решение для сортировки. Сюда же подойдет и Map в принципе.
__________________
// no comments |
|
16.04.2013, 11:16 | #40 |
Участник
|
dech
Извращение или нет - дело привычки. Хранит он разные типы данных, вот и воспользовался его всеядностью, а сортировка - так и для других классов писали методы сортировок и т.д., почему мне нельзя написать свой удобный способ для определенных частных случаев (а если универсален, так можно и классом отдельным оформить)? |
|