Database log error on AX 2009 with SQL Server 2008
25 November 09 01:39 PM | czdaxsup | 0 Comments   

On a database that is upgraded from AX 4.0 to AX 2009 running on SQL 2008 you may get following error while using database log:

The target table 'SYSDATABASELOG' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.. The SQL statement was:

INSERT INTO SYSDATABASELOG (DATA,USERNAME,DESCRIPTION,LOGTYPE,TABLE_,LOGRECID,CREATEDBY,CREATEDTRANSACTIONID, DATAAREAID,RECVERSION,RECID) OUTPUT INSERTED.CREATEDDATETIME VALUES (?,?,?,?,?,?,?,?,?,?,?)

To solve this issue you need to drop the onSYSDATABASELOGinsert trigger by executing this statement in SQL Server Management Studio:

USE <ax_database_name>;
GO

DROP TRIGGER [onSYSDATABASELOGinsert];
GO

You may also need to modify the default constraint for CreatedDateTime field to replace the default value ‘1900-01-01 00:00:00.000’ coming from AX 4.0 with ‘dateadd(millisecond, -datepart(millisecond,getutcdate()),getutcdate())’. To do this you can execute following code:

 

ALTER TABLE dbo.SYSDATABASELOG
	DROP CONSTRAINT <constraint_name>
GO
ALTER TABLE dbo.SYSDATABASELOG ADD CONSTRAINT
	<constraint_name> DEFAULT dateadd(millisecond, -datepart(millisecond,getutcdate()),getutcdate()) FOR CREATEDDATETIME
GO

Martin F

How to move Demand Planner database to another server
15 October 09 01:36 PM | czdaxsup | 0 Comments   

Sometimes you need to move your existing Demand Planner database to another server. If you do this just using backup/restore, you will run into the issue while synchronizing the Demand Planner. The error you get is:

Could not find ‘server name’ in sys.sysservers

This is because Demand Planner uses fully qualified object names in some stored procedures and functions, what results in original server name to be used.

Follow these steps to change the server name in existing functions and stored procedures:

1. Open SQL Server Management Studio and expand Databases

2. Right-click the Demand Planner database and select Tasks –> Generate Scripts

image

3. Click Next on the welcome screen

4. Select the Demand Planner database on Select Database screen and click Next.
Do not check the “Script all objects in the selected database” check box!

5. On the Choose Screen Options screen change value for Script Drop to True and click Next

image

6. On the Select Object Types screen select Stored procedures, Functions and Views and click Next

7. On the Choose Stored Procedures screen click Select All and then Next. Repeat this also to select all functions and views

8. On the Output Option screen keep the default selection and click Finish

image

9. On the summary page click Finish

10. In the query window press CTRL+H to open Find and replace window and type name of the original server into Find what field and name of the new server into Replace with field and click Replace All.

image

11. Press F5 to execute the script when all occurrences are replaced.

Now you should be able to synchronize Demand Planner.

Martin F

Filed under: ,
Conflict error when list of fields is used in select during update transaction
14 October 09 10:32 AM | czdaxsup | 0 Comments   

If you use this code, you will get an error on the line 29. The error message is following:

Cannot edit a record in Table1 (Table1).
An update conflict occurred due to another user process deleting the record or changing one or more fields in the record.

 1: static void updateTable1(Args _args)
 2: {
 3:    Table1 tbl;
 4:    ;
 5:
 6:    ttsbegin;
 7:    select firstonly forupdate tbl;
 8:
 9:    if (tbl.RecId)
10:    {
11:        tbl.InfoText = "Reset";
12:        tbl.update();
13:    }
14:    else
15:    {
16:        tbl.InfoText = "Reset";
17:        tbl.IntField = 1;
18:        tbl.insert();
19:    }
20:    ttscommit;
21:
22:    tbl.clear();
23:
24:    select firstonly RecId, InfoText from tbl;
25:
26:    ttsbegin;
27:    tbl.selectForUpdate(true);
28:    tbl.InfoText = "Table1 - field select";
29:    tbl.update();
30:    ttscommit;
31: }

The reason for this is that each time the table is updated the field RecVersion is updated with a random number that is saved by kernel. That why when you try to update the record, kernel cannot update record partly, what results in update conflict.

There are two ways to avoid this issue:

1. Add RecVersion field into the selection

24:    select firstonly RecId, InfoText, RecVersion from tbl;

2. Use selectforupdate keyword

24:    select firstonly forupdate RecId, InfoText from tbl;

Martin F

Filed under:
Error while calling Win API function on x64
13 October 09 08:47 AM | czdaxsup | 0 Comments   

When you are calling Win API function (or function from a native DLL) on x64 you get this error:

An exception occurred when calling Function in Library name DLL library

This happens only if the code calling the DLL function is running on server. The reason for this is that the DLLFunction class is not supported on x64.

Martin F

Filed under: ,
Rename object in TFS
10 September 09 03:23 PM | czdaxsup | 0 Comments   

You can get this error message while renaming object that is checked out from TFS.

Unable to import
Trying to import Table MFATable_test1 with ID 50003
ID already held by Table MFATable1

To rename the object you need to follow these steps:

  • Right click the object in AOT and select Rename (without checking out the object)
  • Type a new name of the object. New object with the new name will be created
  • Select Tools –> Development tools –> Version control in AX menu and click Pending objects
  • Check in both objects

To update all objects that reference the renamed object, you need to check out all objects that refer to the object you want to rename. When you rename an object, two copies of the object are created: one with the old name and one with the new name. When you check in these objects (for delete and add, respectively), the system integrates both objects to maintain the history.

Martin F

AX 2009 .NET Business Connector fails while creating instance of XmlDocument
09 September 09 01:33 PM | czdaxsup | 0 Comments   

RTM version (5.0.593.0) of .NET Business Connect fails with following exception while creating instance of XmlDocument class in X++ code.

System.Runtime.InteropServices.SEHException: External component has thrown an exception.
at AxCore_CallStatic(Char* , Char* , tagVARIANT* , Int32 , tagVARIANT* )
at Microsoft.Dynamics.BusinessConnectorNet.Axapta.CallStaticClassMethod(String className, String methodName, Object[] paramList)
at Microsoft.Dynamics.BusinessConnectorNet.Axapta.CallStaticClassMethod(String className, String methodName)
at BusinessLogic.DocumentationManager.GetXml() in D:\Development\AX\BC.NET Sample Test\BusinessLogic\DocumentationManager.cs:line 13
at ConsoleTest.Program.Main() in D:\Development\AX\BC.NET Sample Test\Console Test\Program.cs:line 15

To avoid this issue you need to install SP1 for AX 2009 (you need to have access to Partnersource).

Martin F

HOWTO: Print Word document from X++
08 September 09 10:42 AM | czdaxsup | 0 Comments   

You might need to print Word document directly from X++. Here’s a short sample how to do this:

{
    str     document = "C:\\test.doc";
    COM     wordApplication;
    COM     wordDocuments;
    COM     wordDoc;
    ;

    // Create instance of Word application
    wordApplication = new COM("Word.Application");

    // Get documents property
    wordDocuments = wordApplication.Documents();

    // Open document
    wordDoc = wordDocuments.Open(document);

    // Activate the document - this is necessary to print it
    wordDoc.Activate();

    // Print the document
    wordDoc.PrintOut();

    // Close document
    wordDoc.Close();

    // Close Word application
    wordApplication.Quit();
}

Martin F

Filed under: ,
Error ‘Invalid object name #ax_tmp_’
07 September 09 04:43 PM | czdaxsup | 0 Comments   

You may see similar error while posting ledger journal:

Posting - Journal
Journal: 000004_061
Voucher: 8004_062
Cannot select a record in ().
The SQL database has issued an error.
The journal is not posted and the update is canceled.
SQL error description: [Microsoft][SQL Native Client][SQL Server]Invalid object name '#ax_tmp_dmo3_52_0'.

This error is caused by collecting Query plans while doing SQL tracing. To avoid this error you need to disable Query plan collection in Tools | Options on SQL tab.

image

Martin F

Filed under:
Importing addresses with RecID compression enabled
04 September 09 03:24 PM | czdaxsup | 0 Comments   

Sometimes you need to import addresses into AX 2009 and enable RecID compression. This import might result in an error:

 Update of RecID-key xxxxxxxx failed for the register DirPartyAddressRelationshipMapping.

To solve this you need to follow these steps:

  1. Restore the database
  2. Disable RecID unique index on the table affected by this issue
  3. Synchronize
  4. Import data
  5. Enable RecID unique index
  6. Synchronize

Martin F

Filed under: ,
HOWTO: Dynamicaly load picture from base64 string into image on form in X++
28 May 09 09:49 AM | czdaxsup | 1 Comments   

You may want to load an image from base64 coded string. Then there is a code sample how to achieve it. First is needed to put an "Window" controll on the form with name ex. "imageWindow" and then modify "run()" method of Form. String then could be loaded from database, generated by .NET (for example dynamicaly generate picture) etc.

public void run()
{
    container                           baseContainer;
    BinData                             binData;
    Image                               img;

    ;
    super();

    // create container from base64
    baseContainer =  BinData::loadFromBase64(".... BASE64 STRING....");
    
    // create bindata from container.
    binData = new BinData();
    binData.setData(baseContainer);

    // lock element
    element.lock();

    // create Image from bindata
    img = new Image();
    img.setData(binData.getData());

    // show and update image.
    imageWindow.image(img);
    imageWindow.widthValue(img.width());
    imageWindow.heightValue(img.height());
    imageWindow.update();

    // unlock elements.
    element.resetSize();
    element.unLock();
}
Karel F
Filed under: ,
Sending reports per e-mail from batch
22 May 09 11:03 AM | czdaxsup | 1 Comments   

I was facing an issue that no mails were arrived while sending invoices in PDF from a batch. Sending e-mails from a client worked fine. The reason is in enabled SMTP relaying on customer's mail server and in \Classes\RunbaseReportStd\serverSendMail method. This method calls quickSend() method from SysMailer class. The first parameter of this method is fromAddress. In this method this parameter is filled with same value as toAddress. This may cause that no mail will be delivered when SMTP server is configured to drop relayed mails.

Martin F

Filed under: ,
How to execute an external process from a batch
23 April 09 10:56 AM | czdaxsup | 1 Comments   

You might need to execute an external process in a batch and you’re thinking about using WinApi::shellExecute() method. Unfortunately the whole WinApi class is set to run on client. Also the method WinApi::shellExecute() is marked as client method. That why you can’t use this method to execute an external process from batch. How to execute external process then? One option is to use System.Diagnostics.Process .NET class. Here’s a short sample how to use System.Diagnostics.Process to execute an external process:

{
    System.Diagnostics.Process              process;
    System.Diagnostics.ProcessStartInfo     processStartInfo;
    ;

    new InteropPermission(InteropKind::ClrInterop).assert();

    process = new System.Diagnostics.Process();

    processStartInfo = new System.Diagnostics.ProcessStartInfo();
    processStartInfo.set_FileName("C:\\temp\\test.bat");
    processStartInfo.set_Arguments("Value1 Value2 Value3");

    process.set_StartInfo(processStartInfo);

    process.Start();

    process.WaitForExit();

    info("Finished");
}


Martin F

Filed under: ,
HOWTO: Open AX form from custom help file.
21 April 09 03:05 PM | czdaxsup | 1 Comments   

There is one interesing feature available in help file. You could link AX Form directly from help file. There is an example in standard AX 2009 installation.

  • Open form Accounts receivable / Setup / Customer groups.
  • Press F1
  • Open file will be opened as on following picture

image

  • There are a links in text as Customers or Term of payments.
  • When you click on those links then coresponding AX Form will be opened directly.

How to achieve same function

With creating help file it will be necesary use a Help Kit for Microsoft Dynamics AX. Next tool which I will recommand you is a HTML Help Workshop and Documentation. For linking AX Form into code there is a special function located in script_main.js file located in folder local of help kit. Syntax of this function is following:

function AxMenuItemExecute(MIType, MenuItem)
{
    try
    {
	var intMenuItemType;
	
    switch (MIType)
    {
        case "Display":
             intMenuItemType=0;
             break;
        
        case "Output":
             intMenuItemType=1;
             break;
        
        case "Report":
             intMenuItemType=2;
             break;
        
        default:
             return;  // Take no action.
             break;
    }
    
    AxLabel.RunMenuItem(intMenuItemType, MenuItem);	
    }
    catch (e) {
    //window.alert("Failed to execute menu item.");
    }
}

Using of this function is quite simple, there is an example of opening Term of payments.

<a onclick="AxMenuItemExecute('Display','paymterm')">Terms of payment</a>

To be able call this function successfull you have to add a reference to AxLabel object in each html page in your help file.

<OBJECT ID="AxLabel" CLASSID="CLSID:F5DD8727-673F-4523-869A-35AAA05AE782"></OBJECT>
Karel F
Blocked queries on any change in AOT
16 April 09 03:02 PM | czdaxsup | 1 Comments   

You may face a blocking issue on SQL Server each time you do any change in AOT. And you’re using database log. This is the problem. While using database log an insert trigger on SysDatabaseLog table is always dropped and recreated what is causing blocking issues on SysDatabaseLog table. There are 2 options how to solve this issue:

1. Do not use database log

2. Modify createDateTimeTrigMSSQLOnTable method in SysSQLinitDBTriggers class as follows:

...
     // Drop trigger if it exists
     if (resultSet.next() && (resultSet.getString(1) == '1'))
     { // ADDED - This should avoid dropping and recreating trigger for SysDatabaseLog table
         if (tableName == 'SYSDATABASELOG')
         {
             return;
         }
        // ADDED - This should avoid dropping and recreating trigger for SysDatabaseLog table - END

        sqls = 'DROP TRIGGER ' + dbSchema + "." + triggerName;
        ssep2 = new SqlStatementExecutePermission ( sqls );
        ssep2.assert();

        //BP Deviation Documented
        statement.executeUpdate(sqls);
        CodeAccessPermission::revertAssert();
     }

Martin F

Filed under:
HOWTO: Using WinAPI FindFirstFile, FindNextNext in Batch Jobs.
13 March 09 02:56 PM | czdaxsup | 1 Comments   

In batch job is not posible to call WinAPI functions WINAPI::FindFirstFile(..) and WINAPI::FindNextFile(...). This is limited only for code running on client. Sometimes is necesary have similar function for code running on server (or in batches). There is a code sample which is using .NET Framework.

static void Job1(Args _args)
{
    FilePath sFilePath;
    
    System.IO.DirectoryInfo di;
    System.IO.FileInfo[] fis;
    System.IO.FileInfo fi;
    int i;
    int l;
    ;

    sFilePath;= "C:\\temp\\test\\";
    di = new System.IO.DirectoryInfo(sFilePath;);
    fis = di.GetFiles();
    l = fis.get_Length();
    for (i = 0; i < l; i++)
    {
        fi = fis.GetValue(i);
        info(fi.get_FullName());
    }
}

Karel F

More Posts Next page »

Search

This Blog

Syndication

Page view tracker