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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.02.2012, 19:14   #1  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Добавление полей на форму в run-time
В init() формы CustTable после super() пишу следующий код (добавляю группу полей)...
X++:
void init()
{
    FormTabControl          fcContainer;
    FormGroupControl        fcGroup;
    //FormBuildTabPageControl fcContainer;
    //FormBuildGroupControl   fcGroup;
    ;

    //... some code before super() ...
    super();

    fcContainer = element.design().controlName('TabGeneral');
//    fcContainer = element.form().design().control('TabGeneral');
    fcGroup = fcContainer.addControl(FormControlType::Group, 'Vendor2');
    fcGroup.dataSource(tableStr(CustTable));
    fcGroup.dataGroup('Vendor');
//    fcGroup.autoDataGroup(true);
Форма добавляет группу без полей и не инициализирует DataSource.
Что я делаю не так?

UPD. Если вместо дизайна element.design() использовать element.form().design(), см. закомментированные части кроме последней строки, Акса падает.

UPD 2. Попробовал добавить группу полей в run() до и после super()... результат - тот же. Неужели поля из группы добавлять вручную?
За это сообщение автора поблагодарили: A-Lis-A (1).
Старый 28.02.2012, 19:48   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Ar Посмотреть сообщение
Что я делаю не так?
В принципе неправильно.

добавление - операция, требующая тщательного программирования и переписывания кучи параметров.

поступайте наоборот - скрывайте ненужные поля. всего одной строчкой на каждое поле.
в форме предусмотрите все возможные поля, а в коде - скрывайте.
__________________
полезное на axForum, github, vk, coub.
Старый 28.02.2012, 20:01   #3  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Цитата:
Сообщение от mazzy Посмотреть сообщение
В принципе неправильно.

добавление - операция, требующая тщательного программирования и переписывания кучи параметров.

поступайте наоборот - скрывайте ненужные поля. всего одной строчкой на каждое поле.
в форме предусмотрите все возможные поля, а в коде - скрывайте.
Спасибо за совет. Ваш метод известен. Прошу прощения, что сразу не дал правильное условие задачи...
Для меня важно НИКАК не модифицировать форму. На самом деле, код выше - тестовый, ибо настоящий код, модифицирующий формы, вызывается в наследниках класса FormRunListener_W.
Меня устроит только добавление элементов.
И, повторюсь, НИКАКИХ изменений форм!

Я взываю к людям, которые мне подскажут, как Вы правильно заметили, как всё тщательно запрограммировать... мне важен принцип, а не код.

UPD. Я могу написать код, который будет добавлять все поля из группы полей таблицы, но неужели это единственный путь?! Вот и интересно, что я делаю не так (при моём подходе )

Последний раз редактировалось Ar; 28.02.2012 в 20:04.
Старый 28.02.2012, 23:21   #4  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Ar Посмотреть сообщение
Если вместо дизайна element.design() использовать element.form().design(), см. закомментированные части кроме последней строки, Акса падает.
Попробовал добавить группу полей в run() до и после super()... результат - тот же. Неужели поля из группы добавлять вручную?
Использовать element.design() надо после super() в init() формы - в этом случае работа будет идти с об'ектами времени выполнения (FormDesign, FormXXControl); до super() они еще просто не инициализированы. Использовать element.form().design() надо до super() в init() - в этом случае работа будет идти с об'ектами времени дизайна (FormBuildDesign, FormBuildXXControl). Добавить группу контролов, основанную на табличной группе полей, из моего скромного опыта, можно только контролами времени дизайна, при этом не обязательно выставлять AutoDataGroup = true у FormBuildGroupControl, все поля и так появятся; более того, ядро трешки стабильно падало, если выставлять у добавляемой на лету группы AutoDataGroup = true, в 2009-й это поправили.
За это сообщение автора поблагодарили: Ar (1), A-Lis-A (1).
Старый 29.02.2012, 00:57   #5  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Использовать element.design() надо после super() в init() формы - в этом случае работа будет идти с об'ектами времени выполнения (FormDesign, FormXXControl); до super() они еще просто не инициализированы. Использовать element.form().design() надо до super() в init() - в этом случае работа будет идти с об'ектами времени дизайна (FormBuildDesign, FormBuildXXControl). Добавить группу контролов, основанную на табличной группе полей, из моего скромного опыта, можно только контролами времени дизайна
Спасибо за ответ.
Я уже успел разобраться про ДО и ПОСЛЕ super() в init().
Теперь я добавляю группу полей ДО super(). Поля в группу успешно добавляются, однако, только для существующего DataSource. Добавить новый DataSource пока не получилось
Т.е. осталось решить одну малость... ДО super() добавить источник данных, связанный с одним из уже существующих...
Старый 29.02.2012, 01:13   #6  
lvan is offline
lvan
Участник
Аватар для lvan
Лучший по профессии 2014
 
858 / 82 (4) ++++
Регистрация: 15.04.2011
Записей в блоге: 1
Цитата:
Сообщение от Ar Посмотреть сообщение
Добавить новый DataSource пока не получилось
в 2009 не получится, я уже пробовал,
если быть точнее - получится только для тех форм, на которых нет контролов с autodeclaration=yes
AX резервирует область в памяти для контролов со свойсвом autodeclaration=yes сразу после указателей на DS. при добавлении нового DS мы можем получить ссылку на контролы, вместо DS

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

В 2012 это исправили - за это можете мне плюсики поставить, за суппорт реквест вендору =)
Вложения
Тип файла: xpo Form_FormCrashTest.xpo (2.0 Кб, 510 просмотров)

Последний раз редактировалось lvan; 29.02.2012 в 01:29.
За это сообщение автора поблагодарили: AlGol (0), Ar (0), S.Kuskov (0), A-Lis-A (0).
Старый 29.02.2012, 03:18   #7  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Цитата:
Сообщение от lvan Посмотреть сообщение
вот собственно пример - если убрать автодекларейшн - всё работает (но с учетом вышесказанного - я бы не рискнул это использовать)
На самом деле у меня совсем не работает. Убираю автодекларейшн, добавляю датасорс из кода - форма не показывается! Как только комментирую строку с созданием датасорса - отображается! Вот это уже магия...

Цитата:
Сообщение от lvan Посмотреть сообщение
В 2012 это исправили - за это можете мне плюсики поставить, за суппорт реквест вендору =)
С удовольствием поставлю... через несколько дней... как убежусь, что невозможно создать датасорс вообще.
Старый 29.02.2012, 07:49   #8  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
В подтверждение слов Ivan пост от vallys в теме Динамическое создание DataSource на форме, и добавление элементов дизайна.
Цитата:
Сообщение от vallys Посмотреть сообщение
Как-то потребовалось создавать диалоги с источниками данных и гридами. В качестве альтернативы созданию собственных форм для каждого случая, была использована одна собственная диалоговая форма (можно модифицировать стандартную форму Dialog) с заранее созданными искуственными источниками данных, которые позднее переопредилялись в RunBase.dialog(...). Динамически создавать источники данных в стандартной форме не получилось по предпологаемой причине, описанной ниже. Далее имхо.
Представьте, что экземпляры объектов, таких как DataSource, DataSource_DS, DataSource_Q, DataSource_QR, и экземпляры контролов с AutoDeclaration = Yes, хранятся некоторым списком. Сами переменные, используемые в коде формы, имеют смысл ссылок на позицию (адрес) в этом списке. При чем экземпляры объектов для источников данных хранятся перед контролами. При добавлении нового источника данных у формы "создаются новые" экземпляры объектов, которые сдвигают контролы в списке. Естественно указатели на контролы становятся неверными, поэтому и возникают ошибки при обращении к ним. В вашем случае - при обращении к StaticText.
Решение: либо добавить нужное количество источников данных на форму заранее в репозитарий, либо, если первое не возможно, как минимум отказаться от использования контролов с AutoDeclaration = Yes (данным путем не ходил, возможно потребуется ввести и другие ограничения)
За это сообщение автора поблагодарили: Ar (1).
Старый 29.02.2012, 21:35   #9  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Спасибо всем за участие.
В следствие того, что баг справлен в 2012, а мы туда обязательно придём, пока пошёл путём малой крови... и отошёл от условий - на форму добавляю новый DataSource, всё остальное получается сделать до super() в init():
X++:
    Object              fcContainer;
    FormGroupControl    fcGroup;
    int                 fDS;
    ;

    fDS = formRun.form().design().dataSource(_DSName);
    fcContainer = formRun.form().design().control(_containerName);
    fcGroup = fcContainer.addControl(FormControlType::Group, _groupName);
    fcGroup.dataSource(fDS);
    fcGroup.dataGroup(_tableGroupName);
Всяческие проверки я опустил. Думаю, кому надо, добавить - не проблема.
Старый 29.02.2012, 23:53   #10  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
К слову сказать датасурс на форме не обязательно жёстко привязывать к конкретной таблице. При создании в свойствах в качестве таблицы можно указать Common, а в run-time уже заменить на реальное значение. Таким образом можно создав заранее некоторое количество "не типизированных" источников данных в run-time получить любую комбинацию таблиц. Связи между источниками данных естественно тоже можно настраивать в run-time.
Старый 01.03.2012, 07:39   #11  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
К слову сказать датасурс на форме не обязательно жёстко привязывать к конкретной таблице. При создании в свойствах в качестве таблицы можно указать Common, а в run-time уже заменить на реальное значение.
Тут есть "нюанс" с правами доступа: вроде как права доступа на таблицу datasource'а проверяются ядром до init(). При этом, с одной стороны, на Common висит ключ AdminTables, так что либо надо будет отключать AllowCheck на таком datasource'е, либо всем потенциальным пользователям как-то подкручивать права (не помню, видна ли Common в настройке прав доступа), иначе форма не откроется. А с другой стороны, после подмены таблицы в datasource'е права доступа на нее проверены ядром на открытии формы уже не будут.
За это сообщение автора поблагодарили: mazzy (2), lev (2), S.Kuskov (5).
Старый 01.03.2012, 07:54   #12  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от gl00mie Посмотреть сообщение
после подмены таблицы в datasource'е права доступа на нее проверены ядром на открытии формы уже не будут.
Это уже серьёзное ограничение. Интересно а можно ли как-нибудь после подмены таблицы повторно принудительно запустить отработку прав?
Старый 01.03.2012, 01:22   #13  
lvan is offline
lvan
Участник
Аватар для lvan
Лучший по профессии 2014
 
858 / 82 (4) ++++
Регистрация: 15.04.2011
Записей в блоге: 1
ну так сделано в TableBrowser собственно
я туда первым делом полез смотреть, когда у меня эта задача возникла
Старый 01.03.2012, 08:41   #14  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Как повторно запустить неявную проверку прав, выполняемую ядром, не знаю - я в таких случаях явно проверяю права доступа на таблицу таким вот методом вспомогательного класса DEV_Assert:
X++:
// если у текущего пользователя нет доступа к указанной таблице, выбрасывает исключение
public static client server void hasTableAccess(tableId _tableId, AccessType _accessType = AccessType::View)
{;
    DEV_Assert::tableIdIsInValidRange(_tableId);
    if (!isTableUserEnabled(_tableId, _accessType))
    {
        throw error(strfmt("@SYS76214", tableid2pname(_tableId)));
    }
}
Старый 01.03.2012, 09:41   #15  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Как повторно запустить неявную проверку прав, выполняемую ядром, не знаю - я в таких случаях...
это еще не все программирование.
права нужно проверять не только на таблицу, но и на отдельные поля.

также нужно:
  • учитывать пользовательску настройку форм (разрешить и учесть при открытии, хотя бы порядок колонок!!!!, не говоря уже о ширине колонок, не говоря уже о названии полей. о возможности добавления и скрытия полей даже не напоминаю),
  • учитывать пользовательскую настройку датасорсов (разрешить и учесть наложенные пользователем фильтры и сортировки, а также добавленные пользователем таблицы),
  • учитывать диналинк, когда данная форма открывается из других форм
  • продумать как открывать на основании этой формы новые, не потеряв диналинк с новыми формами
  • разрешить вопросы с автоотчетом,
  • решить вопросы с нормальной выгрузкой в эксель
  • и прочее

если всего этого не сделать, то получится отдельно стоящая форма, не связанная с остальным функционалом. И ни на что не похожая. В которой НЕ работают большинство стандартных и таких привычных пользователю инструментов. (Даже порядок колонок не запоминается!)

повторюсь:
Цитата:
Сообщение от mazzy Посмотреть сообщение
добавление - операция, требующая тщательного программирования и переписывания кучи параметров.

поступайте наоборот - скрывайте ненужные поля. всего одной строчкой на каждое поле.
в форме предусмотрите все возможные поля, а в коде - скрывайте.
__________________
полезное на axForum, github, vk, coub.
Старый 01.03.2012, 10:27   #16  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Цитата:
Сообщение от mazzy Посмотреть сообщение
это еще не все программирование
Позволю сделать одно маленькое замечание: дополнительное программирование может потребоваться в случае, если дабавлять Common, в противном случае, дорабатывать не надо, всё и так работает.
Кстати, в большинстве случаев (для подобных модификаций) всего описанного Вами функционала не требуется. Но, согласен, разработчик должен знать, к чему ведёт такой подход...
За это сообщение автора поблагодарили: mazzy (2).
Старый 01.03.2012, 11:28   #17  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Ar Посмотреть сообщение
дорабатывать не надо, всё и так работает.
а вы попробуйте

Цитата:
Сообщение от Ar Посмотреть сообщение
Кстати, в большинстве случаев (для подобных модификаций) всего описанного Вами функционала не требуется.
начинается...
вот так всегда - сначала громкие заявления про "универсальность", а потом(!) выясняется...
__________________
полезное на axForum, github, vk, coub.
Старый 01.03.2012, 18:26   #18  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Цитата:
Сообщение от mazzy Посмотреть сообщение
а вы попробуйте
Собственно, я и писАл на форум именно после того, как попробовал.
В моём случае всё в порядке, т.е. все пункты Вашего списка работают так, как надо, ибо я свой источник (не Common) линковал к уже существующему.
Разумеется, возможно найти пример, где некоторые или даже (о, ужас!) все пункты не будут работать... Думаю, искать и не требуется.
Цитата:
Сообщение от mazzy Посмотреть сообщение
начинается...
вот так всегда - сначала громкие заявления про "универсальность", а потом(!) выясняется...
Ну а что поделать?! К сожалению, мы вынуждены адаптироваться под условия... При наличии багов в 2009 и зная, что их исправили в 2012, можно и отступить на время... Вряд ли стОит тратить на задачу больше сил, чем это необходимо.
За это сообщение автора поблагодарили: sukhanchik (2).
Старый 02.03.2012, 00:14   #19  
Ar is offline
Ar
Участник
Аватар для Ar
Злыдни
 
21 / 20 (1) +++
Регистрация: 27.06.2005
Адрес: Москва
Так я ж говорю, я не хочу искать слишком сложных путей - иначе выше вероятность ошибок.
Однако, отсутствие изменений на формах - была приоритетной задачей. Поэтому я ограничился только добавлением источника данных. Всё остальное делаю вне формы в наследнике класса FormRunListener_W. Я не раз говорил, что Common не использую, и не собираюсь, - это сильно усложнит проект.
В любом случае, очень много интересного узнал из этой ветки. Спасибо!
Теги
autodatagroup, autodeclaration, datasource, run-time, добавление группы полей, как правильно, форма

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
sumitsaxfactor: Dimension Provider Class and Run-time dimension ranges [AX 2012] Blog bot DAX Blogs 1 28.08.2013 12:42
Динамическое добавление контролов на форму erudit DAX: Программирование 14 28.02.2013 07:05
axaptapedia: Current Time Blog bot DAX Blogs 1 29.11.2010 22:11
Добавление таблицы на форму PurchTable Rect DAX: Программирование 3 21.09.2008 17:54
Malaysia: How to Run Time Add Code to AOT Blog bot DAX Blogs 0 18.09.2007 15:00

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

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

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