| 
			
			 | 
		#1 | 
| 
			
			 программист 
		
			
	 | 
	
	
	
		
		
			
			 
			
			Привет, Всем! 
		
		
		
		
		
		
		
	Ответьте, пож., на маленький вопрос: При: this.query().dataSourceTable( TableNum( InventSum ) ).addRange( FieldNum( InventSum, OnOrder ) ).value( '>0' ); this.query().dataSourceTable( TableNum( InventSum ) ).addRange( FieldNum( InventSum, QuotationIssue ) ).value( '>0' ); Создается запрос: (OnOrder>0) AND ( QuotationIssue>0) Вопрос: Как получить условие по OR? Заранее спасибо...  
		 | 
| 
	
 | 
| 
			
			 | 
		#2 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
			
			
			Re: Возможности Ranges
			 
			
			s= "((inventSum.OnOrder > 0  ||  inventSum.QuotationIssue > 0))"  
		
		
		
		
		
		
		
	// Обязательное наличие скобок this.query().dataSourceTable( TableNum( InventSum ) ).addRange( FieldNum( InventSum, recId) ).value( s );  | 
| 
	
 | 
| 
			
			 | 
		#3 | 
| 
			
			 программист 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Спасибо !!! 
		
		
		
		
		
		
		
	 
		 | 
| 
	
 | 
| 
			
			 | 
		#4 | 
| 
			
			 Модератор 
		
			
	 | 
	
	
	
		
		
			
			
			Re: Re: Возможности Ranges
			 Цитата: 
	
		
			Изначально опубликовано Лютый  
s= "((inventSum.OnOrder > 0 || inventSum.QuotationIssue > 0))" // Обязательное наличие скобок Цитата: 
	
		
			The rules for Advanced query range value expressions are as follows: 
Enclose the whole expression in parentheses. Enclose all sub expressions in parentheses. Use the relational and logical operators known from X++. Use field name only for fields in the ranges data source. Use the dataSource.field notation for fields from other data sources in the query.  | 
| 
	
 | 
|
| За это сообщение автора поблагодарили: kashperuk (1). | |
| 
			
			 | 
		#5 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Вся фишка именно в этих скобках  и поле recid - 
		
		
		
		
		
		
		
	аксаптовский интерпретатор SQL уберет наружные скобки и сформирует блок "where" в sql запросе если скобок не указывать, то это будет воспиринято как то, что вы пытаетесь найти запись по recid. Внутри блока queryrange "(( ))" следуйте лучшим стандартам на здоровье  
		 | 
| 
	
 | 
| 
			
			 | 
		#6 | 
| 
			
			 Модератор 
		
			
	 | 
	
	
	
		
		
			
			
			Re: Re: Возможности Ranges
			 Цитата: 
	
		
			Изначально опубликовано Лютый  
s= "((inventSum.OnOrder > 0 || inventSum.QuotationIssue > 0))" // Обязательное наличие скобок this.query().dataSourceTable( TableNum( InventSum ) ).addRange( FieldNum( InventSum, recId) ).value( s );   У меня: 1) inventSum.OnOrder - ругнется на inventSum. надо просто "OnOrder" 2) || - понимает только OR 3) у меня ругается на лишние скобки () 4) когда в запросе появляется лишняя пара скобок, то он не выполняется   Беда....При этом пример: http://www.axforum.info/forums/showt...F7%E5%ED%E8%E5 Выполняется   Глюки...Ax 3 sp3 hf 2 С Уважением, Георгий  | 
| 
	
 | 
| 
			
			 | 
		#7 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			А можно ли пользуясь таким "расширенным" способом фильтрации датасоурсов произвести фильтрацию типа exists join? 
		
		
		
		
		
		
		
	У меня стоит задача отфильтровать один датасоурс по ИЛИ следующим образом: ИЛИ некое поле == конкретное значение, ИЛИ некое поле exists join в некоей таблице Ума не приложу как это сделать.  | 
| 
	
 | 
| 
			
			 | 
		#8 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано Alks  
ИЛИ некое поле exists join в некоей таблице почитайте руководство разработчика, ключевое слово select statement  | 
| 
	
 | 
| 
			
			 | 
		#9 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано mazzy  
exist join в Аксапте вообще не так делается. почитайте руководство разработчика, ключевое слово select statement   Реализация SQL запросов в аксапте сильно извращена, лишена динамичности, и (судя по этому форуму) так же лишена и гибкости.Перформулирую вопрос по другому: Мне нужно отфильтровать записи в InventTable специальным образом: существует некая таблица категорий (или классификатор по другому), где каждый товар может входить в одну категорию, а категория может входить в другую категорию (другими словами - дерево). Для быстрой фильтрации предусмотрена вспомогательная, в целом избыточная по данным таблица взаимосвязей между группами и их подгруппами так, что в SQL фильтр для таблицы товара выглядел бы как дополнительное условие в WHERE: (InventTable.ClassifierId = SelectedClassifId) OR EXISTS (SELECT ChildId FROM InventClassifierRelations WHERE InventClassifierRelations.ParentId = SelectedClassifId) Т.е. выражает то условие, которое я описал выше - выбрать товар, только если его родителем является "выбранный узел" классификатора, либо любой узел классификатора, одним из родителей которого является "выбранный узел". Пробовал добавить на форму InventTable датасоурс к уже заполненному классификатору и настроить датасоурс InventTable так, чтобы он фильтровал записи хотя бы просто по EXISTS JOIN на InventClassifierRelations, ничего не получилось по непонятным для меня причинам - непонятно еще по каким полям пытаются связаться эти датасоурсы. В общем думаю понятно что я мало чего понимаю, и мне нужен совет как лучше реализовать такую задачу, если оно вообще возможно в аксапте. ![]() P.S. Заранее прошу не предлагать мне использовать "Абстрактный классификатор" - он не соответствует нашим целям.  | 
| 
	
 | 
| 
			
			 | 
		#10 | 
| 
			
			 Модератор 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано Alks  
Да читал, читал, пуская скупую мужскую слезу.   Реализация SQL запросов в аксапте сильно извращена, лишена динамичности, и (судя по этому форуму) так же лишена и гибкости.
		
	![]() Цитата: 
	
		
			Мне нужно отфильтровать записи в InventTable специальным образом: 
существует некая таблица категорий (или классификатор по другому), где каждый товар может входить в одну категорию, а категория может входить в другую категорию (другими словами - дерево). Для быстрой фильтрации предусмотрена вспомогательная, в целом избыточная по данным таблица взаимосвязей между группами и их подгруппами так, что в SQL фильтр для таблицы товара выглядел бы как дополнительное условие в WHERE: (InventTable.ClassifierId = SelectedClassifId) OR EXISTS (SELECT ChildId FROM InventClassifierRelations WHERE InventClassifierRelations.ParentId = SelectedClassifId) PHP код: 
	
			
	все у Вас получится  
		 | 
| 
	
 | 
| 
			
			 | 
		#11 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано Alks  
Да читал, читал, пуская скупую мужскую слезу.   Реализация SQL запросов в аксапте сильно извращена, лишена динамичности, и (судя по этому форуму) так же лишена и гибкости.
		
	Цитата: 
	
		
			Изначально опубликовано Alks  
другими словами - дерево Alks, нет у вас Аксапты, нет у вас компьютера. Пожалуйста, объясните мне на пальцах или на бумажке что же вы хотите! Для начала попробуйте выполнить руками то, что вы написали в своем сообщении. Сколько времени у вас это занимает? Почему? Где самая трудоемкая операция? Почему?  | 
| 
	
 | 
| 
			
			 | 
		#12 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано mazzy  
Эк, вас колбасит то... 1. тут в каких то топиках выяснили что по настоящему сложные запросы в axapta построить нельзя из-за неправильной расстановки скобок в получающихся SQL-селектах, да и нет полного соответствия и той гибкости запросов, который доступен в стандартном SQL 2. нет возможности просто и естественно создать и выполнить "динамически конструируемый" запрос .executeQuery( str SelectStatement ), что меня один раз уже сильно угнетало Впрочем к сути дела это не относится. Цитата: 
	
		
			Боже мой! Опять дерево.
		
	 
  С этим ничего не поделать, и несмотря на то что реляционные СУБД не могут решать задачу поддержки древовидных структур произвольной сложности одновременно соблюдая и эффективность и целостность/неизбыточность данных, деревья нужны и деревья важны. ![]() Цитата: 
	
		
			Alks, нет у вас Аксапты, нет у вас компьютера. 
Пожалуйста, объясните мне на пальцах или на бумажке что же вы хотите! Рассказывать чем являлся старый подход не буду, т.к. смысла не имеет. Новый подход заключается в ведении таблицы InventClassifier ( ClassifId, ParentId, прочие атрибуты... ), а в таблицу InventTable добавлено поле (ClassifId). Цель изначально стояла в том, чтобы при выделении группы (элемента классификатора) в таблице товаров отфильтровывались все записи, принадлежащие выделенному элементу, либо какому либо из его подэлементов (подчиненных ему групп). Да и каскадное удаление элементов классификатора тоже сталкивалось бы с многочисленными select-запросами. В старом варианте решения это было просто сделать (даже очень просто), а в новом по понятным причинам - совершенно геморройное это дело становится. Для решения этой задачи я ввожу дополнительную таблицу InventClassifierRelations, тем самым внося в базу избыточность (но уже избыточность в строках, а не столбцах, как ранее), где для каждого элемента классификатора храню сопоставление ( ParentId, ChildId, int Level ) для всех его родителей, на каком бы уровне он внутри них не находился, модифицирую методы insert и delete для InventClassifier. Теперь можно очень быстро - за один запрос отобрать все подгруппы для заданной на любом уровне вложенности. Каскадное удаление резко упрощается. И фильтрация классно бы решалась тем запросом про который я говорил... В скором времени проверю сообщение Vadik-а и если получится, будет ему тысяча благодарностей.  
		 | 
| 
	
 | 
| 
			
			 | 
		#13 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано Vadik  
попробуйте переписать запрос как PHP код: 
	
			
	 | 
| 
	
 | 
| 
			
			 | 
		#14 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Дерево... Да... Думаю mazzy Вас пошлет... надеюсь по ссылке...  
		
		
		
		
		
		
		
	  Я с AXAPTA работаю всего полгода, но даже с таким опытом вижу, что Вы себе нажили гемморой на долгие годы вперед. Коламбус, конечно, молодцы, но их цель - это зарабатывание денег, а не объяснение клиентам почему так делать нельзя. И денег на Вас они заработают много... Ладно, если опустить эмоции, то попробуйте в Вашей таблице InventClassifierRelations для каждого узла дерева делать ссылку на самого себя. Т.е. это будут строки у которых ParentId=ChildId и Level=0 Тогда запрос будет элементарен: PHP код: 
	
			
	 | 
| 
	
 | 
| 
			
			 | 
		#15 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 Цитата: 
	
		
			Изначально опубликовано Владимир Максимов  
Дерево... Да... Думаю mazzy Вас пошлет... надеюсь по ссылке...   
		
	  Да знаю, знаю.   Неоднократно видел его мнение по данному вопросу, и... даже уважаю его.   Цитата: 
	
		
			Я с AXAPTA работаю всего полгода, но даже с таким опытом вижу, что Вы себе нажили гемморой на долгие годы вперед. Коламбус, конечно, молодцы, но их цель - это зарабатывание денег, а не объяснение клиентам почему так делать нельзя. И денег на Вас они заработают много...
		
	 
  Я к сожалению точно так же как и коламбус не могу влиять на требования начальства и бизнес-процессы нашей фирмы, приходится выполнять то что приказывают выполнять.Цитата: 
	
		
			Ладно, если опустить эмоции, то попробуйте в Вашей таблице InventClassifierRelations для каждого узла дерева делать ссылку на самого себя. Т.е. это будут строки у которых ParentId=ChildId и Level=0 
Тогда запрос будет элементарен... Цитата: 
	
		
			PS: Мне интересно, как с такой (...) структурой таблицы InventClassifierRelations Вы делаете перемещение узла? Удаление и вставка - это легко, а вот передвинуть ветку со всеми узлами при такой структуре ...
		
	 
У нас размер этого классификатора где то 15 элементов на 1-ом уровне и в среднем по 5-10 элементов на остальных подуровнях, так что не всё так уж и плохо.   А вообще то операция перемещения групп настолько редкая штука, что я её даже не реализовывал еще.  | 
| 
	
 | 
| 
			
			 | 
		#16 | 
| 
			
			 программист 
		
			
	 | 
	
	
	
		
		
			
			
			Этот ранджес меня доканает...
			 
			
			Подскажите, пжалуста, как реализовать на ранджесах такой запрос: 
		
		
		
		
		
		
		
	NOT((SalesLine.SalesType==3)AND (SalesLine.Information==0)) или NOT(SalesLine.SalesType==3) OR ((SalesLine.SalesType==3)AND (SalesLine.Information==1)) или хотябы так (SalesLine.SalesType==1) OR ((SalesLine.SalesType==3)AND (SalesLine.Information==1)) и т.д. Заранее спасибо...  | 
| 
	
 | 
| 
			
			 | 
		#17 | 
| 
			
			 Программер 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Подскажите что может быть за ошибка? Следующий код 
		
		
		
		
		
		
		
	X++: while (qr.next()) { setupAccount = qr.get(tableNum(setupAccount)); rangeStr = ' || ((AccountNum='+setupAccount.oldAccount+'))'; } rangeStr = '((AccountNum='+qbr.value()+'))'+rangeStr; qbr.value(queryValue(rangeStr)); Код: SELECT FROM LedgerTrans WHERE ((TransDate<=31.01.2006)) AND ((Dimension[2] = 13)) AND ((((AccountNum=6059)) OR ((AccountNum=6011)))) AND ((OperationsTax = Обычн.))  
		 | 
| 
	
 | 
| 
			
			 | 
		#18 | 
| 
			
			 Программер 
		
			
	 | 
	
	
	
		
		
			
			 
			
			Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 21 
		
		
		
		
		
		
		
	Поясните убогому, что такое 21?  
		 | 
| 
	
 | 
| 
			
			 | 
		#19 | 
| 
			
			 Участник 
		
			
	 | 
	
	
	
		
		
		
		 
			
			Попробуйте еще пару открывающих/закрывающих скобок использовать. И не стоит в данном случае использовать функцию queryValue. 
		
		
		
		
		
		
		
	X++: while (qr.next()) { setupAccount = qr.get(tableNum(setupAccount)); rangeStr = ' || ((AccountNum='+setupAccount.oldAccount+'))'; } rangeStr = '((AccountNum='+qbr.value()+'))'+rangeStr; qbr.value("(" + rangeStr + ")"));  | 
| 
	
 | 
| 
			
			 | 
		#20 | 
| 
			
			 Administrator 
		
			
	 | 
	
	
	
		
		
		
		 
			
			В кавычки номер счета возьмите
		 
		
		
		
		
		
		
			
				__________________ 
		
		
		
		
	Not registered yet? Register here! Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me  | 
| 
	
 |