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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.09.2017, 09:27   #1  
vizir is offline
vizir
Участник
 
43 / 10 (1) +
Регистрация: 08.09.2017
ComboBox fields quantity, вопросы новичка
Здравствуйте, я познакомился с axapt'ой недавно, поэтому пока что вопросы очень простые. Поиском пользовался, ответа найти не смог, а на английском я даже не знаю как это гуглить. А посетители этого форума наверняка без труда смогут мне подсказать, я надеюсь
Axapta 2012 r3.

У меня есть форма-диалог, в которой я программно создаю ComboBox (точнее он сам создается каким то чудом) вот такой строчкой кода

X++:
dlgInvoice           = dialog.addFieldValue(extendedTypeStr(EDTTypeExample), edtTypeVar);
В EDT(string) у меня настроено отношение к одному полю из таблицы Table1. Но при запуске формы, когда я открываю лист бокс, там показывается сразу 3 поля из таблицы(полей в таблице много).

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

Вопрос 2: каким чудом axapta понимает что нужно создать именно ComboBox или TextField по EDT? Это какое то неписанное правило? И где можно это правило почитать, если оно написано? Как это гуглить?

Вопрос 3: я создал обработчик события на этот CobmoBox путем написанного вручную метода с названием типа Fld1_1_modified(). Я не переопределял этот метод, нигде не было никаких намеков что именно так обрабатываются события. Как я должен был догадаться что именно так обрабатывается событие вновь созданного элемента формы?


Я раньше работал с С++ и Java, там были обработчики событий и редакторы форм, где всегда можно было переопределить определенное событие, поэтому в axapt'е мне сейчас всё непонятно, но я хочу понять её логику.
Старый 08.09.2017, 10:34   #2  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Есть некоторые отличия между ComboBox и Lookup. В первом случае у вас будет выпадающий список из статических значений, определённых в перечислимом типе Base Enum (даже если это EDT, он может наследоваться от Base Enum). В другом случае значения берутся из связанной таблицы. Обычно на типе создают отношение, но, начиная с 2012 аксапты, от этого отходят и делают отношения прямо на таблице.
Цитата:
Сообщение от vizir Посмотреть сообщение
Вопрос 1: где задается количество полей, которые будут выводиться в комбо боксе? Я пробовал перенастраивать отношение на другие поля, но пара одно лишнее поле стабильно все равно выводится в результате.
В таблице Table1 найдите узел Field Groups > AutoLookup. Накидайте туда столько полей, сколько необходимо. Все они появятся в выпадающем lookup-списке.
Цитата:
Сообщение от vizir Посмотреть сообщение
Вопрос 2: каким чудом axapta понимает что нужно создать именно ComboBox или TextField по EDT? Это какое то неписанное правило? И где можно это правило почитать, если оно написано? Как это гуглить?
У EDT иногда нужно смотреть иерархию, чтобы определить, что у какого-то предка есть отношение к какой-нибудь таблице. Либо он наследуется от Base enum. Например, EDT NoYesId наследуется от NoYes.
Цитата:
Сообщение от vizir Посмотреть сообщение
Вопрос 3: я создал обработчик события на этот CobmoBox путем написанного вручную метода с названием типа Fld1_1_modified(). Я не переопределял этот метод, нигде не было никаких намеков что именно так обрабатываются события. Как я должен был догадаться что именно так обрабатывается событие вновь созданного элемента формы?
Каждый контрол имеет свое имя. Если они создаются автоматически, то они называются Fld1_1, Fld1_2 и т.д. Контролу можно дать своё имя, но в старых версиях даже это было невозможно. Поэтому создав метод Fld1_1_modified() можно перекрывать событие modified() данного контрола. Такую возможность сделали именно из-за необходимости перекрывать события для контролов в диалогах, где они создаются автоматически.

P.S. Для начала почитайте про lookup в книге Еременко-Шашкова, начиная со стр. 196, там страничек 5. Даже где-то была ссылка на электронную версию.
__________________
// no comments
За это сообщение автора поблагодарили: S.Kuskov (2).
Старый 08.09.2017, 11:04   #3  
vizir is offline
vizir
Участник
 
43 / 10 (1) +
Регистрация: 08.09.2017
Спасибо за ответ, очень помогло
Вот это немного не понял:

Цитата:
Сообщение от dech Посмотреть сообщение
У EDT иногда нужно смотреть иерархию, чтобы определить, что у какого-то предка есть отношение к какой-нибудь таблице. Либо он наследуется от Base enum. Например, EDT NoYesId наследуется от NoYes.
Пусть EDT наследуется от чего угодно, но как это влияет на то, как представится объект типа DialogField на форме? Если EDT ссылается на таблицу, то получится lookup, если просто на строку, то текстовое поле, то есть я не смогу гипотетически сделать текстовое поле, которое заполнится строками из таблицы? Система сама за меня решает как выводить информацию и только так?

Последний раз редактировалось vizir; 08.09.2017 в 11:07.
Старый 08.09.2017, 13:24   #4  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Чтобы найти, на какую таблицу настроен лукап, нужно прошерстить всю иерархию. Например у вас есть EDT SalesInvoiceId, как ни странно, у него нет ничего в узле relations. Значит следует рыть дальше. Т.к. он наследуется от CustInvoiceId, смотрим туда и видим, что там настроен relation на таблицу CustInvoiceJour. Всё.
А чтобы ответить на ваш вопрос, надо просто обратить внимание на первый параметр. Какой EDT укажете, такой лукап у вас и будет.
X++:
dlgInvoice  = dialog.addFieldValue(extendedTypeStr(EDTTypeExample), edtTypeVar);
Ещё интересный момент, если хотите просто поле для ввода без лукапа, выберите тип без relations и table references. Например тип SalesMarkupCode ссылается на таблицу MarkupTable, а чтобы не было лукапа, достаточно выбрать тип MarkupCode.
Ну а если свой особенный лукап хотите с каким-нибудь фильтром, отсекающим ненужные данные (читайте: записи), то надо перекрывать метод lookup() на контроле.
__________________
// no comments
Старый 08.09.2017, 15:02   #5  
vizir is offline
vizir
Участник
 
43 / 10 (1) +
Регистрация: 08.09.2017
Цитата:
Сообщение от dech Посмотреть сообщение
Ну а если свой особенный лукап хотите с каким-нибудь фильтром, отсекающим ненужные данные (читайте: записи), то надо перекрывать метод lookup() на контроле.
Я попробовал так сделать, но столкнулся с новой проблемой: как преобразовать результат запроса в формат, который покажется в lookup'е на форме?

X++:
public void Fld12_1_lookup()
{
    Table1 tableOne;
    ;
    
    select Field1, Field2, Field3 from tableOne
        where tableOne.Field1 == dlgFromThere.value();
    
    // ?
    
    dlgNeeded.value('?');
    
}
Или под словами "лукап хотите с каким-нибудь фильтром" вы имели в виду не запрос к таблице?
Старый 08.09.2017, 15:35   #6  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Надо работать с классом SysTableLookup и создавать запрос динамически.
Вот вам пример. В параметр _formControl передаётся элемент ввода, чтобы связать с ним форму выпадающего списка, т.е. лукап. добавляется 2 фильтра по полям JournalType и BlockUserGroupId. А поля JournalName и Name будут показаны в лукапе.
X++:
private void journalName_Lookup(FormControl _formControl)
{
    SysTableLookup          sysTableLookup  = SysTableLookup::newParameters(tablenum(LedgerJournalName),_formControl);
    Query                   query           = new Query();
    QueryBuildDataSource    queryBuildDataSource        = query.addDataSource(tablenum(LedgerJournalName));
    QueryBuildRange         queryBuildRangeJournalType  = queryBuildDataSource.addRange(fieldnum(LedgerJournalName, JournalType));
    QueryBuildRange         queryBuildRangeUserGroupId  = queryBuildDataSource.addRange(fieldnum(LedgerJournalName, BlockUserGroupId));

    sysTableLookup.addLookupfield(fieldnum(LedgerJournalName, JournalName));
    sysTableLookup.addLookupfield(fieldnum(LedgerJournalName, Name));

    queryBuildRangeJournalType.value(queryValue(LedgerJournalType::Daily));
    queryBuildRangeUserGroupId.value(UserGroupList::groupsForUser());

    sysTableLookup.parmQuery(query);
    sysTableLookup.performFormLookup();
}
__________________
// no comments
Старый 11.09.2017, 13:14   #7  
vizir is offline
vizir
Участник
 
43 / 10 (1) +
Регистрация: 08.09.2017
Цитата:
Сообщение от dech Посмотреть сообщение
Надо работать с классом SysTableLookup и создавать запрос динамически
Второй день мучаюсь с этим классом и другими из аналогичных примеров, но пока не заработал запрос. Ну да ладно, буду пока что делать другое задание.

Очевидный вопрос: почему нельзя в while прогнать запрос к таблице, как я выше в примере показывал, и вывести необходимые строки(если можно, то скажите как, я не нашел способа), вместо того чтобы использовать вереницу классов?
Старый 11.09.2017, 14:43   #8  
MazZzDaI is offline
MazZzDaI
Участник
Аватар для MazZzDaI
 
44 / 35 (2) +++
Регистрация: 19.09.2013
Алгоритм работы примера с SysTableLookup включает в себя построение запроса к данным используя Query Framework, который впоследствии передаётся в SysTableLookup, ответственный за работу с выпадающим списком.
Если есть желание или необходимость использовать while select, то всё равно придётся использовать SysTableLookup но ко временной таблице

Последний раз редактировалось MazZzDaI; 11.09.2017 в 14:48.
Старый 18.09.2017, 15:49   #9  
vizir is offline
vizir
Участник
 
43 / 10 (1) +
Регистрация: 08.09.2017
Вернувшись к вопросу, с помощью коллег, таки нашелся рабочий вариант.

Переопределить lookup удалось только путем написания метода с именем примерно таким - Fld1_1_lookup().
В этом методе как раз и использовались классы из примера dech. Только вместо _formControl, приходящего снаружи, я использовал dialog.formRun().controlCallingMethod().

Почему то так и не получилось переопределить лукап путем вызова метода registerOverrideMethod. Прописал всё как надо, ошибок не было, но метод просто игнорировался(смотрел в отладчике, заходов в него просто не было), неизвестно почему. Если кто знает почему один лукап работает, а другой с аналогичным кодом - нет - пишите, мне очень интересно
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
emeadaxsupport: Inconsistency between quantity in purchase order and quantity in inventory transaction. Blog bot DAX Blogs 0 31.01.2015 23:11
emeadaxsupport: AX for Retail 2012 R2: Working with Custom Fields for Receipts Blog bot DAX Blogs 0 16.02.2013 23:12
Вопросы новичка - взаимодействие2 форм Dona DAX: Программирование 2 12.07.2011 17:30
Navision Axapta 3.0 - Вопросы новичка Igor Beeone DAX: Программирование 2 01.10.2007 10:13
Вопросы от новичка CTAX DAX: Функционал 4 13.08.2002 13:25

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:17.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.