prasad's profilePRASADZPhotosBlogListsMore ![]() | Help |
PRASADZEvery block of stone has a statue inside it and it is the task of the sculptor to discover it. May 26 Local DAX installation method also works for Dynamics Ax 5.0 Build 366 The 'near-domainless' installation method I outlined in About local Dynamics Ax 4.0x installations on Windows XP works for Dynamics Ax 5.0 Build 366 too! +5 to Marc for testing it out.
Editing the registry as outlined at the end of the post referenced above and originally here (http://axforum.info/forums/showthread.php?t=17711) also works, both on Ax 4.0 and Ax 5.0. Thanks to an AxForum.info member for providing me with this alternative and Don for testing it out on Ax 5.0! From :http:// http://gatesasbait.spaces.live.comrom Data dictionary synchronization errorsEvery object related to the SQL Database (tables, table fields,
table indexes) is identified by 'name' in the Database, but identified
by a 'unique id' in Dynamics Ax. This unique id is kept in code, in its
respective layer file (*.aod). This unique id is a constant; SalesTable
for example has had the table id '366' since forever. The object id
found in the layer is matched with the Database object name through a
table called 'SQLDictionary'. This table maps DAX table ids to SQL
table names, and DAX field ids to SQL field names. This means that in
theory and practice, a field could have a certain name under DAX, and a
different name under the SQL Databse; this happens for example when the
object name under the DAX AOT is longer than 30 characters.
During synchronization of the dictionnary under the DAX AOT, DAX
looks through the SQLDictionary table and verifies that all tables and
fields can be found, that they have the proper id and that the
corresponding SQL object exists with the proper name and proper type.
Possible scenarios at synchronization
Diagnosing synchronization errors
Sometimes, DAX will fail to synchronize a table and give you an
error message that does not identify the problematic table. This x++
job will help you determine where the cause of the error is:
public static void manualSync(Args _args)
{ #define.unknown("UNKNOWN") #define.tableIdMax(65536) int i = 1; ; while (i < #tableIdMax)
{ if (tableid2name(i) != #unknown) { print(tableid2name(i)); try
{ if (!appl.dbSynchronize(i, false, true)) throw Exception::Error; } catch { error(tableid2name(i)); } } i++;
} } When ids don't match...
Generally you will have table id and field id mismatches upon
re-attaching a database when objects where moved across different
layers. The reason for this is that of the 65 536 available tables ids,
ids [0, 10 000] are reserved for SYS, ids [20 000, 30 000] are reserved
for BUS, ids [40 000, 50 000] are reserved for CUS, etc; with no
overlap between the grops of ids (I may be slightly off, this is from
memory).
While migrating a customer from Ax 2.5 to Ax 4.0, they revised
they're customization strategy to bring mods onto the CUS layer, when
originally they were on the USR layer. We didn't want to spend hours
importing data using the data import-export tool, so I ran jobs to fix
the SQLDictionary table (you would also need to fix the data in any
RefTableId field). This was the basic idea:
(NEVER RUN THIS CODE IN A PRODUCTION ENVIRONMENT)
/*
* Warning, this code does not work 'as-is', it is only given as example * This will completely destroy an environment if run 'as-is'! */ public static void fixSQLDictionary(Args _args) { SQLDictionary sqlDictionary; #Define.CUSLAYERSTART(40000)
#Define.USRLAYEREND (60000) boolean validate()
{ if(sqlDictionary.FieldId == 0 && sqlDictionary.Name != tableid2name(sqlDictionary.TabId)) { return false; } else if(sqlDictionary.FieldId != 0 && sqlDictionary.Name != fieldid2name(sqlDictionary.TabId, sqlDictionary.FieldId)) { return false; } return true; } ;
try
{ ttsbegin; //FIX CUSTOM TABLES AND THEIR FIELDS
while select forupdate sqlDictionary where sqlDictionary.TabId >= #CUSLAYERSTART && sqlDictionary.TabId < #USRLAYEREND { sqlDictionary.TabId = tablename2id(sqlDictionary.Name); if (sqlDictionary.orig().FieldId != 0)
sqlDictionary.FieldId = fieldname2id(sqlDictionary.TabId, sqlDictionary.Name); if (!validate())
{ //TODO: Need to deal with DEL_* objects and objects with names > 30 chars continue; } //TODO: Uncomment
//sqlDictionary.doUpdate(); } //FIX CUSTOM FIELDS ON STD TABLES
while select forupdate sqlDictionary where (sqlDictionary.FieldId >= #CUSLAYERSTART && sqlDictionary.FieldId < #USRLAYEREND) && (sqlDictionary.Tabid < #CUSLAYERSTART) { sqlDictionary.FieldId = fieldname2id(sqlDictionary.TabId, sqlDictionary.Name); if(!validate()) { //TODO: Need to deal with DEL_* objects and objects with names > 30 chars continue; } //TODO: Uncomment //sqlDictionary.doUpdate(); } July 16 Index and Index hint In the Axapta community, there is still a big confusion about the "index" and "index hint" statements used in connection with selects. So, what is the Axapta kernel *really* doing: Using "index": when you add the statement "index MyIndex", the Axapta kernel will add an "ORDER BY" with all the fields of the index. Example: select * from InventTable index GroupItemIdx will generate the following SQL statement to the database: SELECT A.ITEMGROUPID, A.ITEMID, A.ITEMNAME,.... FROM INVENTTABLE A ORDER BY A.ITEMGROUPID, A.ITEMID The Index ItemGroupIdx of the InventTable exactly contains the two fields ItemGroupID and ItemId (in that order). Using "index", you still give the control of which index to use to the database optimizer. So, if the optimizer finds a better index to use, it will use it. Using "index hint": when you add the statement "index hint MyIndex", the Axapta kernel will add a statement to instruct the database to use that index and no other one. Example: select * from InventTable index hint GroupItemIdx will generate the following SQL statement to the database: SELECT /*+ INDEX(A I_175GROUPITEMIDX) */ A.ITEMGROUPID, A.ITEMID, A.ITEMNAME,.... FROM INVENTTABLE A Using "index hint", you take away the control of which index to use from the database optimizer. So, if there may be a better index, the database will not use it. Conclusion: Adding the "index" statement to an Axapta select, it does NOT mean that this index will be used by the database. What it DOES mean is that Axapta will send an "order by" to the database. Adding the "index hint" statement to an Axapta select, it DOES mean that this index will be used by the database (and no other one). This rule applies to both the MSSQL and Oracle databases. Tip: On the Axapta 3.0 installation CD, you will find a document called "Performance enhancements using the Cost-Based optimizer" (file name: AX-300-TIP-024-v01.00-ENUS.doc) that will tell you some more things about Axapta and database optimizers. From : http://axaptafreak.blogspot.com Enterprise portal bloghttp://blogs.msdn.com/epblog/ June 24 Performance check list for Axapta installationsPerformance check list for Axapta installations This
checklist is intended to be a guide on how to determine the causes of
perceived data access performance problems in Axapta. It is not a
guide on how to tune an Oracle or SQL server installation.
For
each long-running update SQL statements, think about:
June 12 Creating a active directory in windows 2003 server How to create an active directory on a windows server 2003 OS http://www.visualwin.com/AD-Controller June 11 Whatz new in Dynamics AX_2009 You need a partner source login https://mbs.microsoft.com/downloads/customer/Ax2009/AX50_ENUS_WN_Tech.pdf June 06 Number Sequence details Number sequences handle the automatic allocation of ID numbers, vouchers, andjournal numbers. A number sequence is created under MAIN MENU->BASIC->SETUP->NUMBERSEQUENCES->NUMBER SEQUENCE. From a developers point of view, these are the tables which are important. • NumberSequenceTable contains the definitions of each number sequence. • NumberSequenceList holds numbers for continuous number sequences that have not been completed or are currently reserved. • NumberSequenceReference holds which number sequence is used for which function. • NumberSequenceGroup is a list of number sequence groups. • NumberSequenceGroupRef contains the number sequence references specific to a group. • NumberSequenceTTS holds the transaction id of a number before it has been completely assigned. It is used during the clean up process, in case of a system crash. • NumberSequenceHistory holds a log of all changes made to the number sequence. • NumberSeq assigns numbers and vouchers, handles continuous number sequences, and calls clean up when appropriate. • NumberSeq_Fast is used for number sequences that are not continuous. It does not keep a record of the status or store transaction ids for later clean up, and is better performance wise. • NumberSeqCleanUp looks for numbers in the list that have not been completed, looks for the session that created them, and, if the session is no longer active, frees up the number for later use. • NumberSeqDataArea is used in the clean up process. • NumberSeqFormHandler is used whenever a number sequence assigns a number in a form. It handles records being deleted and ensures that two users cannot use the same number. • NumberSeqReference creates the link between the function and the number sequence. NumberSeqReference is the super class used, and there is a sub class for each module. • NumberSeqNumCache contains the method to manipulate the cache of reserved numbers. Using MacrosUsing Macros http://www.axaptapedia.com/Abstract_macro Posting entry in GLHow to create a posting entry in General Ledger (GL) module of Dynamics AX? Answer: There are many ways to create posting entries in to General Ledger module. In my experience the simplest way is to use the Journal classes. There are two parts of posting create a heade entry and then create the add lines to it. To create a header entry use the LedgerJournalTable table and use the LedgerJournalTrans table. Finally use the ledgerJournalCheckPost class object to post these entries into the system. Below is a job explaing the Posting process in a simple way. static void postVoucherThroughJournal(Args _args) From the blog http://msdax.blogspot.com/ June 05 Functional Production helpHow would I go about setting up the following. A specific product can be manufactured on machine 1. (this being the preferred What I would like to be able to do if the Machine 1 has reached capacity, Is there a way of doing this? ------------------------------------------------------------------ Answer: Yes, this can be achieved using task groups by assigning one of them to the production order's operation. A task group has a list of work centers which should be used when the best possible work center is being searched for performing the operation. The best work center means - the one that can do job faster(earlier). Each line in the task group has a sorting criteria (it is called Requirement) where you can specify a number which will be used if there are equaly fast work centers and you need to define which one should be used first. The lowest number is used first. Here is how you can set this up in AX: 1) Create an item of type BOM 2) Add one operation to the route (Items > Route button) and set the Work center field to e.g. "Machine 1". 3) Go to tab page Setup, do right click on the Task group field and go to the Main table form. 4) Create a new task group and on the tab page Work centers add two lines for the two alternative work centers - "Machine 2" and "Machine 3". Set the Requirement field to 10 for "Machine 2" and to 20 for "Machine 3". This will assure the sequence of how the machines will be used. 5) Assign the newly created task group to the operation. 6) Make sure all machines (1, 2, 3) have parameter "Finite capacty" set. (Work centers - tab page General). 7) Create a production order for the item created at the step 1 and do Update > Job scheduling. Check results in the Production > Jobs form. You can see that the selected work center is "Machine 1". 8) Do the same as on the step 7 (create another production order and run job scheduling for it) and you will see that now system has selected the work center - "Machine 2" for the same time interval (because "Machine 1" is booked). 9) If you repeat the step 7 again (create the third production order and job schedule it), then the time interval will be the same, but the selected work center will be - "Machine 3"(because "Machine 2" was booked on the step 8). 10) If you do it one more time, then there is no more alternative work centers and system will book a later time and the selected work center will be "Machine 1" again and if you continue creating production orders you will get the same results - all alternative work centers will be used. Graphically it looks like below: Figure 1. Production job scheduling on alternative work centers. For simplicity production orders on the figure have only one operation and only one job of type Process, so they look like one bar. Can find the same on : http://daxfaq.studioerudit.com/ June 03 Links could be helpfulSolving the ELEMENT ID problem http://blogs.msdn.com/mfp/archive/2008/05/21/solving-the-element-id-problem.aspx New Layers in AX2009 http://blogs.msdn.com/mfp/archive/2008/04/22/new-layers-in-dynamics-ax-2009.aspx Writing highly secure code http://download.microsoft.com/documents/uk/msdn/security/The%20Developer%20Highway%20Code.pdf Writing less code :"The else statement" http://blogs.msdn.com/mfp/archive/2008/02/23/writing-less-code-the-else-statement.aspx Anyone can try to write developer documentation of X++ code http://blogs.msdn.com/mfp/archive/2008/01/31/anyone-interested-in-developer-documentation-for-x-code.aspx Dynamics AX 4.0 Meta Model http://blogs.msdn.com/mfp/archive/2007/12/12/dynamics-ax-4-0-meta-model.aspx Compiler Warnings http://blogs.msdn.com/x/archive/2007/08/21/correction-guide-compiler-warnings.aspx AOT MEtrics http://blogs.msdn.com/mfp/archive/2006/10/06/AOT-Metrices.aspx Compiler Warnings http://blogs.msdn.com/mfp/archive/2007/09/12/compiler-warnings-and-so-what.aspx How to use a form tree control http://blogs.msdn.com/mfp/pages/how-to-use-a-formtreecontrol.aspx Articles on X++ development http://blogs.msdn.com/mfp/archive/2007/08/23/articles-on-x-development.aspx Right to left support in Dynamics AX5.0 http://blogs.msdn.com/mfp/archive/2007/05/08/right-to-left-support-in-dynamics-ax-5-0.aspx May 28 Look upLookup Form From AxaptapediaAxapta usually creates required lookup forms on the fly, but it also allows the developer to create a custom lookup form and assign it as "FormHelp" to an extended datatype, so that it is automatically used. Why would you do that? There might be many reasons. Typically you need to display the data in a non standard order or you want to show only a subset of the data depending on some criteria. Here are the steps needed to create a proper lookup form.In the following example I assume you create a lookup for table "xyz" and the ID field of that table is called "id". Create the formFirst create a basic form. Usually this form contains not much more than a grid. But you might add additional controls. Then set the following properties on the datasource, so that the form can not be used for editing: AllowCheck: No Additionally set for the design the following properties to make it look like a proper lookup: AlwaysOnTop: Yes
[edit] Make it selectableNow we need to tell the lookup form, which control will return the selected value. Lets assume you have a form with a grid and in that grid you have a control called "xyz_id". In this case you overwrite the init method of the form as shown below. Note that if you are using Axapta v3.0 or higher, then you can set the control's AutoDeclaration property to Yes and use the control name directly in the selectMode() call.
public void init() [edit] Make sure the form opens with the previously selected valueStrange enough the following is missing in most/all custom lookup forms, which you find in Axapta Standard. But it is required, if you want your lookup to mark the previously selected value as active record. Therefore overwrite the ExecuteQuery method of your datasource:
public void executeQuery() With a lot of pain I had top learn that the above will not work, if you use the standard query, which is automatically created by Axapta. This might be due to existing Dynalinks or other reasons, which I am not aware of. But it will work fine, if you create your own query for example in the Init method of the datasource. Here you can also define your custom sort or range criteria:
public void init() [edit] Make lookup react to search by wild cardThe following you will find in the official documentation and also in a lot of Axapta examples. If you type in a standard Axapta StringEdit Control something like "abc*", then automatically the lookup will open and only the matching subset of records will be shown. You achieve this by overwriting the run method of the form:
public void run() [edit] Make Form Default lookup for an Extended Data TypeTo have Axapta use your form by default every time a lookup is performed, you can set your form's name in the Extended Data Type's property called 'FormHelp'. You do not ncessarily need a display menu item, the property is your actual form's name. So that's it. Now you have a wonderfully working custom lookup.
Retrieved from Axaptapedia
May 21 How to be a Programmer: A Short, Comprehensive, and Personal Summary How to be a Programmer: A Short, Comprehensive, and Personal Summary http://samizdat.mines.edu/howto/HowToBeAProgrammer.html#id2790277 Dynamics AX related sites Dynamics AX Temporary tables http://msdn.microsoft.com/en-us/library/bb314749.aspx\ Dynamics AX system requirements http://www.microsoft.com/dynamics/ax/product/systemrequirements.mspx Microsoft Dynamics AX 4.0 Service Pack 1 (SP1) Release Notes http://www.trucosax.com/htmldocs/ax40_sp1/ReleaseNotes.htm?NSNST_Flood=63a05617d14e7665cc23fcfdddc3f1dc Technical Best Practices for Dynamics AX - Shared and AOT Object Standards http://www.packtpub.com/article/technical-best-practices-for-dynamics-ax-shared-and-aot-object-standards Mulitdivisional companies: Integrate systems across your enterprise http://www.microsoft.com/dynamics/ax/product/hubandspoke.mspx March 31 Containers http://msdn2.microsoft.com/en-us/library/aa882886.aspx http://www.eggheadcafe.com/software/aspnet/31749113/what-is-the-difference-be.aspx Debugging Ax Kernelhttp://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx March 25 Useful links http://axgeek.spaces.live.com/ http://axapta.blogcu.com/1947360/ http://ax.nom.es/uncategorized/axapta-comman-line-parameters-2 How to enable single user mode USE master EXEC sp_dboption 'database name, 'single user', 'TRUE' use database name dbcc checktable ('LedgerTrans', REPAIR_ALLOW_DATA_LOSS) Axapta Performance Test links http://blogs.msdn.com/axperf/ |
||||||
Public folders
|
||||||
|
|