It’s all about Dynamics

Microsoft Dynamics NAV, Microsoft Dynamics CRM and .NET: Code samples, tips & tricks, news, …

Setting the crmForm or a Field to Dirty

Posted by Kenny Vaes on December 2, 2009

CRM 4.0 does not allow you to change the IsDirty property of a field or the crmForm. These properties are calculated.
The way CRM calculates this value is by checking the fields DataValue against the fields defaultValue.

It might be nessecary to set the form to Dirty from an IFRAME or another source. To do this you could change the default value of one of the fields on the form.
In my case I always use the 2nd control on the form (which is actually the first field in all crmForms).

crmForm[1].defaultValue = “something nobody will ever enter in the field”;
(In my case I put a GUID in there)

NOTE: The defaultValue property is NOT documented in the SDK so I’m pretty sure this code is unsupported!

Posted in CRM 4 | Tagged: , | Leave a Comment »

Pre-Loading IFRAMES in CRM 4.0

Posted by Kenny Vaes on December 1, 2009

When you are using IFRAMES in CRM that are displayed in another tabpage than the default tab, the IFRAMES will load only when the user clicks on this tabpage.

It might be required that the pages displayed in these IFRAMES display their content as soon as the user activates this tab.

To do this you can preload the iframes in the load event of the crmForm like this:

crmForm.all.IFRAME_myiframe.src = crmForm.all.IFRAME_myiframe.url;

Posted in CRM 4 | Tagged: , | Leave a Comment »

WPF Controls do not resize inside container

Posted by Kenny Vaes on October 19, 2009

When you try to put a WPF User Control or a Page inside of a container you will notice the control is not resizing to the parent it is hosted in. Example, a page that is hosted in a frame.

This is due to the size you have set to the control or page.

 <Page x:Class=”LAD_Project_Planning_WPF.pProjectCard” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”  Title=”pProjectCard” Loaded=”Page_Loaded” Height=”382″ Width=”789″>
<Page.Resources>

 

As you can see the page’s height and width are set to 382 and 789 pixels. This will cause the control to always have these dimensions. It doesn’t matter if it is set to strech inside of a container or not.

Removing the dimensions from the control will solve this issue at runtime, but you won’t be able to see the control in design time.

The only solution I found until now was to change the dimensions in the OnLoad event.

if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
{
    this.Width = double.NaN; 
    this.Height = double.NaN;
}

Posted in .NET | Tagged: , | Leave a Comment »

Could not find GUID for server when opening CRM

Posted by Kenny Vaes on September 8, 2009

The following error occured with one of our clients when they opened CRM.

Error while finding AD GUID for ServerName HB1781$

Crm Exception: Message: Could not find GUID for server: HB1781$, ErrorCode: -2147214038, InnerException: System.Runtime.InteropServices.COMException (0×800703FA): Retrieving the COM class factory for component with CLSID {080D0D78-F421-11D0-A36E-00C04FB950DC} failed due to the following error: 800703fa.

After doing some googling I found this post telling me to change some settings in IIS.

Set “Load User Profile” to True for the IIS Application Pool “Microsoft Team Foundation Server Application Pool”

To my surprise it seemed to solve the problem. I changed it for the CrmAppPool and all users could now login without any problems.
I still don’t know how this problem could occur, but changing this settings seems to do the trick.

Posted in CRM 4 | Tagged: , , | Leave a Comment »

Get the name of a lookup that is not resolved

Posted by Kenny Vaes on September 7, 2009

I often have to check the name value of a lookup field.
In normal cases one would use the code crmForm.all.new_lookupfield.DataValue[0].name to retrieve this value.

In case of an ambiguous or failed lookup, this datavalue will be null.

Ambiguous lookup
LookupAmbiguous

What I found out using the IE Developer toolbar was that this kind of lookups used a <span> element to display this “unresolved” state of a lookup.
Both resolved and unresolved lookups have this Span. The only difference will be the classname. So if you like, you can also filter on the className.

LookupAmbiguousHTML

So, to access the Text of this Lookup I could use crmForm.all.metris_blueprintid_d.getElementsByTagName(“span”)[0].outerText

Posted in CRM 4 | Tagged: , | Leave a Comment »

Inserting Japanese characters into a NAV database from outside NAV

Posted by Kenny Vaes on June 15, 2009

In a previous post I described some steps on how to enable you NAV environment to support DBCS. Read more about it here: http://kennyvaes.wordpress.com/2009/06/08/nav-vs-dbcs/

Now, the next challange we faced was inserting Japanese characters from an external system into the NAV database.

In other countries we mangage this by running a webservice which insert the information into the SQL database. This webservice is built in C#.

The problem now on the Japanese system was that the strings passed on to the webservice are all Unicode, because .NET handles all strings as Unicode.

Just inserting these Unicode bytes in NAV without conversion will result in a string like “日本 アンユージュアル エスケープ” to be inserted as “???? ??? ????? ???”.

What Navision does is convert this string to a series of Non-Unicode bytes like “ƒAƒ“ƒ†[ƒWƒ…ƒAƒ‹@ƒGƒXƒP[ƒv"

After some time figuring out how to insert these Unicode strings into NAV we came up with the following.

Step 1: Determine the codepages

First of all you need to determine the codepages the server and NAV use. In my case the server was running codepage 1252 Latin encoding. And NAV, because of the Non-Unicode settings, was running under codepage Japanese Shift-JIS (932).

Step 2: Convert your strings

So now you know what codepages you use, the solution is actually pretty straight-forward. What does NAV do? Well, when you input this Japanese string 日本 アンユージュアル エスケープ in NAV. Navision is running codepage 932 and gets the Bytes for this string in 932 encoding. The OS is running codepage 1252 so the SQL server also uses this codepage. What you need to do is convert these 932 bytes into a 1252 encoded string.

The following C# code will do this for you. Remeber to replace the 932 and 1252 encodings with your encoding.

string JapString = "日本 アンユージュアル エスケープ";
string NavString = "";
Encoding nav = Encoding.GetEncoding(1252);
Encoding unicode = Encoding.GetEncoding(932);
byte[] unicodeBytes = unicode.GetBytes(JapString);
NavString = nav.GetString(unicodeBytes);

now the NavString variable contains “ƒAƒ“ƒ†[ƒWƒ…ƒAƒ‹@ƒGƒXƒP[ƒv”.

Great!!

Posted in .NET, NAV | Tagged: , , | Leave a Comment »

NAV vs DBCS

Posted by Kenny Vaes on June 8, 2009

We recently faced a challange to setup bussiness in Japan. We all know that NAV is NOT Unicode and therefore it does not support the Japanese characterset which is a DBCS.

How do we proceed in this case? What are the steps needed to get the NAV database up and running?
These were just some of the questions I had. There wasn’t much information I could find on the net regarding this issue. Having some support calls logged with MS helped solve alot of issues.

Anyway, in this post I will share with you all how we were able to make this installation successfull.

What is DBCS?

DBCS stands for Double Byte Character Set. In CJK (Chinese, Japanese and Korean) computing, the term “DBCS” traditionally means a character set in which every graphic character not representable by an accompanying SBCS is encoded in two bytes; Han characters would generally comprise most of these two-byte characters.

The NAV STX file:

The first thing you need is a new stx file which has been sealed with the “Allow DBCS” switch on.

// The following entry is for double-byte character set (DBCS) clients (code  pages 932, 936, 949, 950)   
// A value of 0 indicates that a client DBCS is disallowed   
// A value of 1 indicates that a client DBCS is allowed, provided that the database code page is a non-DBCS code page   
00093-00400-010-2: 1 

Sealing this stx file can only be done by microsoft. Send them your STX file and you will receive a new one with DBCS enabled.

The Japanese Language pack:

The next step will be to install the Japanese language pack. There is NO official language pack from Microsoft available. You will need to contact a local solution center in Japan to obtain it. This language Pack will have all the menu items, forms and tables translated.

Now you can try and open NAV. If the database server is running on a English OS using the 1252 latin codepage, you will NOT see any japanese characters. The only thing you will see are meaningless ASCII sings. To be able to see the Japanese text, you will need to set the regional settings for the server.

Regional Settings:

Go into the control panel > Regional and Language Options.
In here you need to Install Files for East Asian Languages in the Languages tab. (This will enable the OS to display Japanese text in menus)
Next up is setting the language used in Non-Unicode applications, such as Navision.
Set this selection to the Language needed for the NAV database. In my case this was Japanese.

Finished!

After this you will be able to display the Japanese characters in NAV.
The data which is in SQL however, is still displayed in this ASCII sequences. It is Windows who actually converts these ASCII characters into the correct Japanese character because of this Non-Unicode app setting.

Posted in NAV | Tagged: , | 1 Comment »

Tip: Missing a namespace?

Posted by Kenny Vaes on March 17, 2009

When using classes in certain namespaces of .NET you need to include the using statement at the top of you code.
If you fail to do so the compiler won’t be able to find the class.

Example:

XmlDoc.Load(Path.GetDirectoryName(Assembly.GetAssembly(typeof(OCIForm)).CodeBase) + “SampleXMLFile.xml”);

Here the Path and Assembly classes will not be found because I haven’t included the System.IO and System.Reflection namespaces.

You can add them manually if you know by hard which namespace to use for this class. But if your memory fails you, you could simply right clich the classname and select Resolve > Using System.IO;
The using statement will be added automatically.

Resolve function in VS

Resolve function in VS

Visual studio will automatically search for the namespace. ;)

Posted in .NET | Tagged: , | Leave a Comment »

Left padding for strings in NAV

Posted by Kenny Vaes on March 16, 2009

The C/AL function PADSTR will only work for padding strings to the right.

Example:
String AA needs to be 10 chatacters long with a padding of zeros.
If the zeros need to be added to the right of the string you could use the PADSTR function like this:

mystring := PADSTR(mystring, 10, ‘0′);

If you need padding to the left you can do the following:

Use an empty string and fill it with the number of zeros needed to fill the whole string.
In our example this would be 8 zeros. This is equal to 10 – STRLEN(‘AA’).

So using the PADSTR function this can be:

mystring := PADSTR(”, 10- STRLEN(‘AA’), ‘0′) + ‘AA’;

Which results in: 00000000AA.

Posted in NAV | Tagged: , | Leave a Comment »

Show a Modal Dialog and return a lookup

Posted by Kenny Vaes on March 10, 2009

The following code snippet shows you how to return a lookup from a modal dialog.
I used this code to replace a standard CRM 4 Lookup and display my own custom made lookup screen. When clicking OK in this custom screen a lookup should be returned with the Entity the user has selected in the Custom Lookup.

 

Place this function in the CRM Form. 

 
document.CustomLookup = function ()
{
  var url = “/ISV/<yourapp>/CustomLookup.aspx?orgname=” + ORG_UNIQUE_NAME;
        var selectedItems = window.showModalDialog(url, null, ‘dialogWidth:600px;dialogHeight:400px;resizable:yes’);                    
        if (selectedItems != null)

        {
            crmForm.all.myField.DataValue = selectedItems ; 
            crmForm.all. myField.FireOnChange();    // If you also need to fire the onchange event
        }
}

Then use this function as the onclick event of the Lookup.

try
{
    crmForm.all.mylookup.onclick = document. CustomLookup;
} catch (e) {}

In the CustomLookup.aspx page add a Gridview that is populated with the entities you need. And add a JavaScript function that will retrieve the selected item in the grid. (I usually work with a SelectedRow style)

<script type=”text/javascript”>    
        function applychanges()
        {                    
            var Entities = document.getElementById(‘<%= ComponentsGrid.ClientID %>’).getElementsByTagName(“TR”);  // ComponentsGrid is the name of the gridview            
                     
            var EntityID = “”;
            var EntityName = “”;
            for (var i=1;i< Entities .length;i++)
            {
                if (Entities [i].className == “SelectedRow”)
                {                                      
                    EntityID  = Entities [i].getAttribute(“oid”);         
                    EntityName  = Entities [i].getAttribute(“oname”);                            
                    break;
                }
            }

            var lookup = new Array();
            lookup[0] = new LookupControlItem();
            lookup[0].id = EntityID  ;
            lookup[0].typename = “myentityname”;
            lookup[0].name= EntityName  ;
 
            window.returnValue = lookup;
            window.close();                      
        }
    </script>

Posted in CRM 4 | Tagged: , | Leave a Comment »