Skip to main content

Posts

Send message to online user in Dynamics AX 4.0 (quick & dirty)

I am missing the functionality to send messages to online users that existed in Axapta 3.0 and is now gone. Well, I thought you could use the "Alert" functionality introduced in DAX 4.0. What to do: 1. make sure the user options are configured correctly (that means: set "Time poll interval" to 1 minute, set "Show popup" to "For all event rules") 2. make a button in the online user form that will open a dialog where you could enter your text 3. send the message to all users selected in the online user form datasource Here is a little job that creates an alert for a user. Remember this is a quick & dirty solution, so there are some drawbacks: * you will get an error in the alert form on the second tab * the message will only be displayed about 15 sec and disappears afterwards (you can check FRM EventAttentionGrabber to change that. Check methods fadeIn and fadeOut for variable opacity. This should give you a hint on how to display the f...

Be careful when resetting your usage data

in Dynamics AX 4.0, a "Favorites" menu was introduced. You can drag a form to your favorites pane. Then you will be asked to give it a name, and: you can add a saved query to it. With that, you can easily make favorites the open the forms filtered on the data you just need. But there's another thing: as long as your system is still in change, everybody recommends that you delete your usage data from time to time (in User/Options). But what happens to your favorites if you delete all your usage data? The answer is: you'll get an error message. The system will tell you that it cannot find your saved query anymore. So, the whole work saving your queries and making your favorites is lost. A small little addition to the method " reset " in the form " SysLastValue " will help you avoid that. Add the line && _sysLastValue.recordType != UtilElementType::UserSetupQuery; in the "delete_from" statement. So, the deletion will not delete your ...

Activating query tracing for all users

Sometimes when you are tracking performance (or other) problems, you may want to activate the long running query tracing for all users. Here is a little job that will do that. Beware: you have to activate trace settings on your AOS server, unless most of the queries will not be caught. static void Set_SQLTrace_AllUsers(Args _args) { #LOCALMACRO.FLAG_SQLTrace (1 << 8) #ENDMACRO #LOCALMACRO.FLAG_TraceInfoQueryTable (1 << 11) #ENDMACRO boolean set; UserInfo userInfo; ; set = true; ttsbegin; while select forupdate userinfo { userinfo.querytimeLimit = 1000; if (set) { userInfo.DebugInfo = userInfo.DebugInfo | #FLAG_SQLTrace; userInfo.TraceInfo = userInfo.TraceInfo | #FLAG_TraceInfoQueryTable; } else { userInfo.DebugInfo = userInfo.DebugInfo ^ #FLAG_SQLTrace; userInfo.TraceInfo = userInfo.TraceInfo ^ #FLAG_Trac...

Executing direct SQL on an external database using ODBC

public static server void main ( Args _args ) {     Statement             statement;     str                         query;     Resultset              resultSet;     LoginProperty      loginProperty;     OdbcConnection  odbcConnection;     ;     loginProperty = new LoginProperty ( ) ;     loginProperty. setDSN ( 'YOURDSN' ) ;     odbcConnection = new OdbcConnection ( loginProperty ) ;     // Create new Statement instance     statement = odbcConnection. CreateStatement ( ) ;     // Set the SQL statement     query = 'select name from CustTable' ;     // assert SQL statement execute permission     new Sql...

Executing direct SQL on the current AX database

When you execute a SQL statement, there are two options: - either you did a select and you expect a result to be returned - or you did insert/update/delete and you don’t expect a result. The first sample is for a SQL statement that returns a result: public static server void main ( Args _args ) {     Connection    connection;     Statement      statement;     str                  query;     Resultset       resultSet;     ;     // create connection object     connection = new Connection ( ) ;     // create statement     statement = connection. createStatement ( ) ;     // Set the SQL statement     query = 'select name from CustTable' ;     // assert SQL statement execute permission     new SqlStatementExecuteP...

Linked server sql statements

Some time ago, I talked about executing direct sql statements , and now I want to share some sql statements that I used to manage linked server connections. What follows are 4 sql statements that allow you to add en remove linked servers on a database at runtime. Some assumptions: - There is a str variable named “query” that will contain the query - there is a parm method on the class that return the sql server (“server” or “server\instance”) - there is a parm method that returns a username - there is a parm method that returns a password Check if linked server exist First check if the linked server doesn’t exist yet, or you will get an error when you try to add one that already exists. query = strfmt ( "select top 1 * from sys.servers where name = '%1'" , this. parmServer ( ) ) ; Add linked server When the linked server doesn’t exist, add it. query = strfmt ( "EXEC sp_addLinkedServer @server = '%1', @srvproduct=N'SQL Server'...

Remove duplicate key entry from a table

Sometimes, you can’t synchronize a table because is contains duplicate records. This can occur when you change field lengths on a extended data type for example. I’ve seen people write huge SQL statements, and even jobs that create these SQL statements to remove these duplicates from a table, but there’s actually a easy way to do this in AX. Say you have a table KLFTestDuplicates that contains duplicates, then simple run the following job to remove them. static void KLFRemoveDuplicates ( Args _args ) {     Set fieldSet = new set ( Types :: Integer ) ;     DictIndex  dictIndex = new DictIndex (         tablenum ( KLFTestDuplicates ) ,         indexnum ( KLFTestDuplicates , AUniqueIdx ) ) ;     int i;     ;     if ( dictIndex. numberOfFields ( ) )     {         for ( i = 1 ;i <= dictIndex. numberOfFields ( ) ;i ++ )       ...