|
![]() |
#1 |
Участник
|
Цитата:
Исходная постановка задачи после всех уточнений, замечаний, разных "но" и "если" выглядит довольно странно. Примерно так: Необходимо обеспечить запись некой "матрицы" (таблицы) значений с возможностью их последующей модификации. При этом предполагается, что возможно абсолютно произвольное изменение любой характеристики этой матрицы. Может измениться количество строк, количество столбцов, типы и расположение отдельных элементов и т.д. и т.п. И что здесь можно ответить? Да любой объект, который может хранить списки подходит для этого! Хоть обычные массивы. Другой вопрос, а подходит ли выбранное решение для конкретной ситуации? Другими словми, в исходной постановке задача решения не имеет, поскольку сводится к перечню всех возможных инструментов Axapta. Нужно четко обозначить границы задачи. Для каких целей будет использован статический набор? |
|
![]() |
#2 |
Участник
|
Цитата:
На ваш взгляд: 1. В Аксапте нет универсального способа хранения статических данных 2. для Query лучше хранить сам query в AOT. Владимир Максимов, я отключюсь в этой ветке от общения с вами. Извините. Другие мнения/дополнения будут? |
|
|
За это сообщение автора поблагодарили: Владимир Максимов (0). |
![]() |
#3 |
Участник
|
Я думаю важнее иметь контроль типов не в смысле контроля атомарных типов данных, а в смысле контроля самой структуры данных. Поясню. Например, если форматом хранения является контейнер сложной структуры (контейнер контейнеров), то очень просто можно запутаться в количестве параметров и порядке их включения во вложенные контейнеры. Здесь контроль типов данных нужен для того чтобы помочь разработчику сопоставить значение соответствующему параметру, а не для того чтобы предотвратить потерю точности при преоброзовании real в int.
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#4 |
Участник
|
Цитата:
Ну скажем так, игнорировать имена я уж точно не буду. Если я знаю что мне нужно указать пару "id столбца" - "значение", то Id поля я запишу в поле с именем FieldId а значение в поле с именем Value, а не наоборот. В случае с контейнером это совсем не очевидно. |
|
![]() |
#5 |
Участник
|
Цитата:
Получается, что если элементов структуры мало, то ориентироваться в них достаточно просто вне зависимости от того, есть имя или нет. А если элементов структуры много, то ориентироваться в них сложно, опять же, вне зависимости от того, есть имя или нет. |
|
![]() |
#6 |
Участник
|
Цитата:
![]() Цитата:
P.S.: по-мойму оффтоп получается |
|
![]() |
#7 |
Участник
|
К слову
Цитата:
В Ax2012 как MFP уже рассказывал все ID выделяються отдельной инсталяцией. То есть tableNum(InventTable) != tableNum(InventTable) на разных машинах в числовых значениях. Это я к тому что в мета данных вне Ах хранить числовые значений не стоит.
__________________
Thx, Ievgenii Korovin| Dynamics Ax SCM| Microsoft Corp| http://blogs.msdn.com/DynamicsAxSCM/ ![]() |
|
![]() |
#8 |
Участник
|
Цитата:
Ок. Тогда попробую подвести итоги: 1. контейнер значений (в т.ч. контейнер контейнеров) плюсы: = очень просто инициализировать значения, легко добавлять/изменять значений = стандартный функционал работает с контейнерами, поэтому проблем с примером использования не будет = единственный способ сериализации, приемлемый для передачи параметров между клиентом и сервером (за таблиц, конечно) минусы: = контейнер - константа. ВСЕГДА. любая попытка изменить контейнер приводит к пересозданию контейнера. что чревато проблемами производительности для больших наборов = контейнер - содержит только константы. не содержит ссылки. поэтому хранить ссылку на класс внутри контейнера нельзя = никакой встроенной проверки типов. нужно писать самому = никакой встроенной проверки количества данных. нужно писать самому. или надеятся на добросовестность программиста пример инициализации: container parm = [['<html>','</html>'],['<body>','</body>']]; container parm = [[myTable1, myField1], [myTable2, myField2]]; пример использования: = pack/unpack = класс keySum 2. класс (set, list, map и т.п.) плюсы: = контроль типов присутствует (хоть и минимальный) = класс не пересоздается в памяти при изменении минусы: = писать нужно гораздо больше кода чем с контейнерами примеры использования: ??? 2.1. класс (set, list, map и т.п.), хранящий экземпляры специально написанного класса плюсы: = полный контроль над значениями минусы: = писать надо очень много пример инициализации: set mySet = new Set(Types:Class); mySet.add(new MyParm(myTable1, field1)); mySet.add(new MyParm(myTable2, field2)); пример использования: ??? 2.2. класс (set, list, map и т.п.), хранящий struct: плюсы: = не надо писать собственного класса минусы: = struct не делает контроля обязательности = очень многословная запись пример инициализации: set mySet = new Set(Types:Class); struct myStruct = new Struct(Types::Integer, "age", Types::String, "name"); myStruct.value("name","Jane Dow"); myStruct.value("age", 34); mySet.add(myStruct); myStruct.value("name","Tom Gun"); myStruct.value("age", 45); mySet.add(myStruct); пример использования: ??? 2.3. класс (set, list, map и т.п.), хранящий контейнеры: = даже не знаю минусы: = бу-э-э-э... способ объединяет минусы всех способов пример инициализации: set mySet = new Set(Types:Class) mySet.add([myTable1, field1]); mySet.add([myTable2, field2]); пример использования: FactureCalcBalances_RU 3. таблицы плюсы: = полный контроль = эффективная передача клиент/сервер = достаточно очевидно для любого програмиста минусы: = нужно писать кода не меньше, чем в случае 2.1 "класс собственных классов" пример использования: NumberSeqReference.loadModule() NumberSeqReference_Ledger.loadModule() 4. xml-файл в ресурсе плюсы: = удобно передавать вместе с приложением. особенно большие наборы данных минусы: = очень неочевидно для программистов = работа с xml ресурсоемка пример использования: \Data Dictionary\Tables\BITimePeriodsMDX\Methods\importFromAOT так? вроде ничего не забыл? |
|
![]() |
#9 |
Administrator
|
По п. 2.1 пример - разноска в ГК: класс LedgerVoucherList - обертка Map, состоящий из объектов LedgerVoucherObject. Здесь формируется список проводок в ГК по ваучеру. (см. класс LedgerVoucher и метод addVoucher)
Другой пример: Объекты List и Map, хранящие в себе список контролек диалога. List хранит упорядоченный список (см Dialog.addCtrlDialogField()), а Map - ссылки на объекты (Dialog.addFieldCon() и Dialog.addDialogClass()) Struct (согласно перекрестным ссылкам) используется для задания свойств объекта. В частности у контрольки в DialogField и в классе WebApplication (тут есть типизация, а не только String)
__________________
Возможно сделать все. Вопрос времени |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#10 |
MCTS
|
Если честно, не совсем понимаю смысл создания отдельного динамического хранилища для статичных начальных данных (данных по умолчанию).
Зачем придумывать и создавать коллекцию для этих данных, что бы потом тратить время (и свое и процессорное ![]()
Поясню на примере. Что подразумевает использование отдельно-выделенного хранилища данных? Использование как-минимум двух методов. 1. Метод, в котором коллекция заполняется данными. X++: void initDataCollection() { ; dataCollection = new DataCollection(Type); dataCollection.append(data1); dataCollection.append(data2); dataCollection.append(data3); dataCollection.append(data4); ..... } X++: void processDataCollection() { while(dataCollection.more()) { processData(dataCollection.getData()); dataCollection.next(); } } 3. Метод, в котором сразу обрабатываются статические данные без заморочек со всякими коллекциями-хранилищами. X++: void processDefaultData()
{
;
processData(data1);
processData(data2);
processData(data3);
processData(data4);
....
} ![]()
__________________
Dynamics AX Experience Последний раз редактировалось CDR; 12.04.2011 в 23:37. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#11 |
Участник
|
Цитата:
Сообщение от CDR
![]() X++: void processDefaultData()
{
;
processData(data1);
processData(data2);
processData(data3);
processData(data4);
....
} ![]() во-первых, я забыл записать этот способ. а он обсуждался. это будет способ 5. во-вторых, чтобы так написать нужно чтобы processData был реентерабельным. в принципе, не такое уж усложняющее требование. но все-таки. в-третьих, я не зря упомянул в теме про классы. при таком подходе, класс-потомок сможет только добавлять начальные данные, но не изменять начальные данные родителя. X++: class foo { void processDefaultData() { ; processData(data1); processData(data2); processData(data3); processData(data4); .... } .... } class fooBar extends foo { void processDefaultData() { ; // как в этом методе изменить/убрать из списка data3? super(); processData(data5); .... } } в общем, бывают случаи, когда совсем статический подход не работает. но согласен - это очень хороший подход в большинстве случаев. |
|
![]() |
#12 |
MCTS
|
Цитата:
Цитата:
Цитата:
![]()
__________________
Dynamics AX Experience |
|
![]() |
#13 |
Участник
|
Чем объект AOT отличается от статического набора?
|
|
|
За это сообщение автора поблагодарили: S.Kuskov (0). |
![]() |
#14 |
Участник
|
можно и в AOT.
об этом был способ №4 "xml-файл в ресурсе" и способ №5 "Метод, в котором сразу обрабатываются статические данные без заморочек со всякими коллекциями-хранилищами" "query в AOT" - частный случай для инициализации с query. мало того, именно такой способ я и рекомендовал всегда для работы с кверями. ищите по ключевому слову "querystr" просто тема не о кверях. |
|
![]() |
#15 |
Участник
|
Вот, кстати, вспомнилось. Не совсем начальные данные, правда, но всё равно показательно.
Пример использования контейнеров в системе когда не надо использовать контейнеры, а надо таблицы: RTax25RegisterTrans.RegsiterValues. там хранится около дюжины самых разнотипных полей. См. например LedgerJournalCreate_Tax25AmountDiff_RU Код: ledgerJournalTrans.DocumentNum = conpeek(registerTrans.RegisterValues, #Value3); ledgerJournalTrans.DocumentDate = conpeek(registerTrans.RegisterValues, #Value4); Код: taxPay += (this.round(conpeek(_trans.RegisterValues, #Value10)) - this.round(conpeek(_trans.RegisterValues, #Value13))); Надеюсь, когда нибудь проверка BP научится бить по рукам за #define.Value13(13) от которого толку - ноль. Ещё один плюс таблиц перед containerами: фильтры. Помню была доработка по этим RTax25* где надо было выбирать определенные RegisterValues. Так как делать joinы и фильтры на container'ы внутри таблиц нельзя, то приходилось перебирать все RTax25RegisterTrans принадлежащие RTax25RegisterTable'у. Последний раз редактировалось mayk; 14.04.2011 в 12:13. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
Теги |
как правильно |
|
![]() |
||||
Тема | Ответов | |||
Загрузка начальных данных | 1 | |||
Набор данных на лету | 15 | |||
Прогноз роста базы данных и выбор топологии системы, Как правильно расчитать возможный рост | 0 | |||
Введение в Аксапту | 0 |
Опции темы | Поиск в этой теме |
Опции просмотра | |
|