Microsoft Dynamics NAV

Team Blog

  • Microsoft Dynamics NAV Team Blog

    Control Add-In dll’s files in Microsoft Dynamics NAV 2015

    • 5 Comments

    With Microsoft Dynamics NAV 2015 there comes one feature in Add-In files area – you do not need manually to copy add-in dll to client: when client doesn’t find it, NAV copies add-in from server.

    It is very good: If you’ve installed NAV client on some computer, you don’t care about all add-ins, when user needs it, he will have it.

    When NAV client can’t find add-in in client Add-ins folder, usually it is: c:\Program Files (x86)\Microsoft Dynamics NAV\71\RoleTailored Client\Add-ins\, then NAV copies whole add-ins folder from NST computer to client computer to folder C:\Users\[username]\AppData\Local\Temp\1\Microsoft Dynamics NAV\Add-Ins\

    But here are few points you need to know when updating add-ins or have strange issues related to your updated add-in functionality.

    • NAV recognizes add-ins by:

      • Product Name (it could be not the same as file name and file properties in windows file explorer doesn’t show it. You can see it by run power cmdlet “(Get-ItemProperty [filename]).VersionInfo.ProductName”);

      • Product version (it is not the same as file version, you can see it in file properties in windows file explorer or run powershell “(Get-ItemProperty [filename]).VersionInfo.ProductVersion”);

      • Public key token (you’ve set it in VisualStudio project when compiled add-in. You can see it by run developer command prompt statement “sn –T [filename]”). Details at http://msdn.microsoft.com/en-us/library/dd983825.aspx.
        So if any of these fields are different, NAV will recognize dll as different add-in.

    • NAV fill in assembly list table with these 3 fields and when NAV looks for dll it uses these fields to recognize which dll need to be loaded. If for some reasons you have 2 files with different names, but the same mentioned properties then for NAV there is only one add-in.

    • When NAV is looking for add-in, it looks in NAV add-ins folder, then in Temp folder and if hasn’t found then download from server add-ins folder. If you updated add-in on server and deleted it in client folder, it could be that old add-in version still remains in temp folder and NAV client will use it for work.

    • If you recompiled your add-in and have changed something, but you haven’t modified add-in properties, then you need to replace add-in files on server and on client computer (in NAV folder). It is not enough to replace file on server only, because NAV doesn’t recognize that new add-in needed to use and do not download add-in file from server. But it is also not enough to delete add-in file on client computer in NAV folder, just because old version could remain in temp folder too. Of course you can delete add-in file in both folders (in NAV and in Temp). But if computer is used by few users, then you need to delete files from every user temp folder, then maybe easier way is replace add-in file only in NAV folder. As soon as add-in file exists in folder, NAV doesn’t look it in temp folder.

     

    These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.

    Gedas Busniauskas

    Microsoft Lithuania
    Microsoft Customer Service and Support (CSS) EMEA

  • Microsoft Dynamics NAV Team Blog

    How to control keyboards events in Add-in

    • 3 Comments

    With Microsoft Dynamics NAV Role Tailored Client we’ve received possibility to add ControlAddIn to any field on page. This opens huge possibilities to extend functionality with own controls.
    We can create any .Net control with Visual Studio, register it in NAV controls and add it to any field on page by describe control name in field “ControlAddIn” property.
    Then whenever user put focus on this field, NAV forwards full control to AddIn and now AddIn does whatever it wants.

    And here comes first issue: if AddIn controls everything then all NAV shortcuts are not active and then what to keyboard key to click if want to go on page to next field/control? Only way is to use mouse and click on another control. This is not best way for UX, especially if you want to do that fast.

    Issue was resolved with Cumulative Update 9 for Microsoft Dynamics NAV 2013 R2 (Build 37221) released in July 2014.
    https://mbs.microsoft.com/partnersource/global/deployment/downloads/hot-fixes/NAV2013R2PlatformHotfixOverview
    With this update NAV keyboard events are left for NAV – user can scroll per controls like in any other page.

    But here comes another issue: what to do if we want to leave some keyboard events to AddIn? For example we are using RichTextBox in AddIn for text managing, here <enter> key splits line and jumps to new line. But with CU9 cursor jumps to next page control as <enter> is used by NAV. What to do? We need something flexible: leave event to NAV or to AddIn depends what addin does.

    Here comes Cumulative Update 14 for Microsoft Dynamics NAV 2013 R2 (Build 38801) released in December 2014. It allows us to choose where <enter> must to be: in NAV or in Addin.

    With this update new interface is implemented in Microsoft.Dynamics.Framework.UI.Extensibility, it is “IControlAddInEnterKeyHandler”. And now we can decide how <enter> key is acting,
    will cursor stay in AddIn control

    public class ControlAddInWithKeyboardFilter : StringControlAddInBase, IControlAddInEnterKeyHandler

        {

            private RichTextBox rtb;

                     public override bool AcceptsEnterKey

            {

                //get { return false; }

                get { return true; }

            }

      

            protected override Control CreateControl()

            {

                rtb = new RichTextBox();

                rtb.Multiline = true;

                return rtb;

     

            }

     

    Or cursor jumps to next NAV control:
      public class ControlAddInWithKeyboardFilter : StringControlAddInBase, IControlAddInEnterKeyHandler

        {

            private RichTextBox rtb;

     

                    public override bool AcceptsEnterKey

            {

                //get { return true; }

                get { return false; }

            }

     

           

     

            protected override Control CreateControl()

            {

                rtb = new RichTextBox();

                rtb.Multiline = true;

                return rtb;

             }

     

     

    These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.

    Gedas Busniauskas

    Microsoft Lithuania
    Microsoft Customer Service and Support (CSS) EMEA

  • Microsoft Dynamics NAV Team Blog

    Memory usage when is used .NET components

    • 5 Comments
    We already had few support request where NAV developers see big memory consumption increase when using .NET component.
    Especially when method is inside some loop.
    Like in this sample:

      FOR count := 1 TO 10000000 DO BEGIN
            varDOTNET :=varDOTNET.DotNetObject();
            varDOTNET.SetValue('par');
            CLEAR(varDOTNET);
       END;

     

    Even it looks like we create variable and then clear it – we can see continues memory usage increase in windows task manager.
    But this is not “memory leak” this is how NAV is managing memory. If you start process again then memory usage decrease and increase to the same number.
    So only during processing there could be issue that few users running the same code comes to memory limits.
    Resolution is to transfer .NET method execution to local function

     FOR count := 1 TO 10000000 DO 
     CallToFunction(‘par’);
    …………

    PROCEDURE CallToFunction@1(parameter@1170000001 : Text);
    VAR
      varDOTNET@1170000000 : DotNet "'MemoryExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.MemoryExample.DotNetObject";

            varDOTNET :=varDOTNET.DotNetObject();
            varDOTNET.SetValue(parameters);
            CLEAR(varDOTNET);

     

    Also here are other coding ways where you can transfer part DotNet variable execution to functions. But it is always more effective transfer execution to function where "garbage collector" can make his job faster and more effective.

     

    These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.

    Gedas Busniauskas

    Microsoft Lithuania
    Microsoft Customer Service and Support (CSS) EMEA


  • Microsoft Dynamics NAV Team Blog

    “Timer” usage in Microsoft Dynamics NAV 2013

    • 2 Comments

    Last time we have seen our “old” NTimer.dll was Microsoft Dynamics NAV 2009. It was placed in  ..\Common\Microsoft Dynamics NAV\Timer\.. folder.
    Usually we have used it for NAS or other looping tasks.

    We want to have the same in Microsoft Dynamics 2013 and later, however we see that the same doesn’t work anymore.
    So how it is now?

    Since Microsoft Dynamics NAV 2013 timer becomes “.NET” type in add-in’s folder. Now it is named “Microsoft.Dynamics.Nav.Timer.dll” and placed on server in C:\Program Files\Microsoft Dynamics NAV\70\Service\Add-ins\Timer.. folder.
    Usage, manage and expected results are now different.

    First of all this is server side timer.

    We use timer as DotNet type variable like:
    Timer@1000 : DotNet "'Microsoft.Dynamics.Nav.Timer, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.Microsoft.Dynamics.Nav.Timer" WITHEVENTS;

    Use variable in code like:
    IF ISNULL(Timer) THEN BEGIN
                  Timer := Timer.Timer;
                  Timer.RedirectExceptions := TRUE;
                  Timer.Interval := 10000; // 10 seconds
                  Timer.Start();
                END;

    It has two events “Elapsed” and “ExceptionOccurred” (if RedirectExceptions = TRUE).
    Event “Elapsed” is executed when we want with code we want.
    If we use “Timer” in NAS then code in “Elapsed” event is code we want to be executed by NAS.

    And here comes big point:
    If error in our C\AL code occurs then error is logged to events, NAS stops and session is terminated. We have option in NAV service config – “Retry Attempts Per Day”. Default value is 3. It means that after error occurs and NAS stops, there will be NAS restart and this will be done 3 times. If we have started NAS first time manually then after error occurs there will be 3 attempts to restart NAS. Finally we’ll have 4 errors in event viewer and need to restart NAS manually.
    To avoid such situations we need move all our c\al code to codeunit and catch all errors with c\al code like:
    …….
    IF NOT CODEUNIT.Run(xxx) THEN
      InsertError(“A business logic error occurred: “ + GETLASTERRORTEXT);
    ……..
    Here in “Elapsed” event we execute some codeunit and if error during execution occurs, it is logged with some function InsertError.

    Event “ExceptionOccurred” is executed when unknown exceptions like polling data from http stream causing io/timeout etc. exception comes to timer. So in this event we can log some network issues with code like:
    InsertError(“A .NET exception occurred: “ + e.Exception.Message);
    Where “e.Exception.Message” is error message text received by timer. This error is logged to events and, NAS stops and session is terminated. We have the same situation like in “Elapsed” event: NAS will be restarted as many times as described in config settings.

    These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.

    Gedas Busniauskas

    Microsoft Lithuania
    Microsoft Customer Service and Support (CSS) EMEA

  • Microsoft Dynamics NAV Team Blog

    Cumulative Update 22 for Microsoft Dynamics NAV 2013 has been released

    • 1 Comments

    Cumulative Update 22 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2013.

    The cumulative update includes hotfixes that apply to all countries and hotfixes specific to the following local versions: 

    • AU - Australia
    • AT - Austria
    • BE - Belgium
    • CH - Switzerland
    • DE - Germany
    • DK - Denmark
    • ES - Spain
    • FI - Finland
    • FR - France
    • IS - Iceland
    • IT - Italy
    • NA - North America
    • NL - Netherlands
    • NO - Norway
    • NZ - New Zealand
    • SE - Sweden
    • UK - United Kingdom

    Where to find Cumulative Update 22

    You can download the cumulative update from KB 3024895 - Cumulative Update 22 for Microsoft Dynamics NAV 2013 (Build 39369).

    Additional Information

    For a list of all cumulative updates for this version, see Released Cumulative Updates for Microsoft Dynamics NAV 2013

    For a list of all hotfixes included in cumulative updates for this version, see the following CustomerSource and PartnerSource pages:

    CustomerSource:

    PartnerSource:

  • Microsoft Dynamics NAV Team Blog

    Cumulative Update 15 for Microsoft Dynamics NAV 2013 R2 has been released

    • 0 Comments

    Cumulative Update 15 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2013 R2.

     The cumulative update includes hotfixes that apply to all countries and hotfixes specific to the following local versions:

    •   AU - Australia
    •   AT - Austria
    •   BE - Belgium
    •   CH – Switzerland
    •   CZ – Czech Republic
    •   DE - Germany
    •   DK - Denmark
    •   ES - Spain
    •   FI  - Finland
    •   FR - France
    •   IS - Iceland
    •   IT - Italy
    •   NA - North America
    •   NL - Netherlands
    •   NO - Norway
    •   NZ - New Zealand
    •   RU – Russia
    •   SE - Sweden
    •   UK - United Kingdom

    Where to find Cumulative Update 15

    You can download the cumulative update from KB 3024898  – Cumulative Update 15 for Microsoft Dynamics NAV 2013 R2 (Build 39354). 

    Additional Information

    For more information about cumulative updates for this version, see Announcement of update rollups for Microsoft Dynamics NAV 2013 R2.

    For a list of all cumulative updates for this version, see Released Cumulative Updates for Microsoft Dynamics NAV 2013 R2

    For a list of all hotfixes included in cumulative updates for this version, see the following CustomerSource and PartnerSource pages:

    CustomerSource:

    PartnerSource

  • Microsoft Dynamics NAV Team Blog

    Cumulative Update 3 for Microsoft Dynamics NAV 2015 has been released

    • 8 Comments

    Cumulative Update 3 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2015. 

     The cumulative update includes hotfixes that apply to all countries and hotfixes specific to the following local versions:

    •   AU - Australia
    •   AT - Austria
    •   BE - Belgium
    •   CH – Switzerland
    •   CZ – Czech Republic
    •   DE - Germany
    •   DK - Denmark
    •   ES - Spain
    •   FI  - Finland
    •   FR - France
    •   IS - Iceland
    •   IT - Italy
    •   NA - North America
    •   NL - Netherlands
    •   NO - Norway
    •   NZ - New Zealand
    •   RU – Russia
    •   SE - Sweden
    •   UK - United Kingdom

    Where to find Cumulative Update 3

    You can download the cumulative update from KB 3024901  – Cumulative Update 3 for Microsoft Dynamics NAV 2015 (Build 39368). 

    Additional Information

    For information about how to install the cumulative update, see How to Install a Microsoft Dynamics NAV 2015 Cumulative Update

    For information about how to work around a recent process change, see How to Get Back the 'Hotfix Directories' from NAV 2015 Cumulative Update 1.

    For a list of all cumulative updates for this version, see Released Cumulative Updates for Microsoft Dynamics NAV 2015.  

  • Microsoft Dynamics NAV Team Blog

    Using SQL Server Extended Events to produce a Blocked Process Report

    • 1 Comments

    Blocking in SQL Server is a mixed blessing! It is a SQL Server’s way of ensuring data integrity which is a basic requirement for any database management system but when users encounter a lot of blocking it makes the application appear slow and sometimes unusable. Therefore, system administrators need to be able to analyse SQL Server blocking and take action to minimise it in order to get the best database performance possible.

    A traditional approach to blocking analysis is to use Windows Performance Monitor. The “SQL Server:Locks” counters gives you a graphical view of lock activity, e.g:

    • How many locks are being requested per second
    • How long SQL queries are waiting due to blocking.
    • How many locks requests are timing out.

    You can then use SQL Server Agent to configure alerts on these performance counters and be notified, for example, when lock wait times exceed whatever threshold you deem acceptable.

    Troubleshooting blocking using Performance Monitor (or SQL Server Profiler) is all very well but can impose a performance hit which may not be practical for a busy, resource intensive live environment. Also, it may not provide all of the details you need to understand the cause of the blocking. If only there was a lightweight way of monitoring SQL Server blocking problems which would be suitable for a busy live environment!

    You might be surprised to find out that just such a lightweight monitoring mechanism has existed since SQL Server 2008 was released. Ladies and gentlemen, allow me to introduce my good friend, the “Extended Events” feature of SQL Server! Several key performance indicators can be monitored using SQL Server Extended Events. The following steps show in detail how you can create a “Blocked Process Report” for your SQL Server environment to capture relevant blocking details without incurring much of a performance penalty.

    First, you need to decide how many seconds a process should be blocked for in order for it to be included in the report, i.e. the blocked process threshold. If you set this value too low you may generate too much noise in the report. If you set it too high you might not get any processes waiting long enough to appear in the report. For Microsoft Dynamics NAV environments, the value should be less than any “Lock Timeout” setting which may be enabled (as set in the NAV Development Environment, see File -> Database -> “Alter Database” -> “Advanced” tab). For this exercise I will only include processes which are blocked for more than 5 seconds in my Blocked Process Report.

    So, I need to run some TSQL statements in order to configure 5 seconds as the blocked process threshold. The following will do the trick:

    exec sp_configure 'show advanced options',1;
    go
    reconfigure
    go
    exec sp_configure 'blocked process threshold',5;
    go
    reconfigure
    go

    NB: After running the above, you may want to consider setting the ‘show advanced options’ value back to ‘0’ if your SQL Server administrator prefers this.

    Now, to create and test the Blocked Process Report. The following are the steps required (examples are based on SQL Server 2012 SP1):

    1. Start SQL Server Management Studio (SSMS) and open the “Extended Events” folder as shown below:

    clip_image001

    2. Right click on the “Sessions” folder and select “New Session Wizard”. Click “Next” on the Introduction page.

    3. When prompted, provide a “Session Name”, e.g. My Blocked Process report.

    4. For the “Choose Template” page select “Do not use template”

    5. In the “Select Events To Capture” enter the word “blocked” in the “Event Library” text box. This will limit the events listed so you can easily identify the “blocked_process_report”. Select this report and then click on the ‘>’ button in order to move this into the “Selected events” pane. Then click “Next”.

    6. In the “Capture Global Fields” page, click on the “Finish” button.

    7. On the “Success” page, click on the “Close” button.

    8. At this stage you have created a Blocked Process Report and should be able to see it shown as an “Extended Report” Session, like this:

    clip_image002

    9. For our requirements, we want to store the report session data into a file as this will be more convenient to work with, especially if you want to send it to a Microsoft Support Engineer! To do this, right click on the “My Blocked Process Report” and select “Properties”.

    10. In the left pane of the “Session Properties” widow select the “Data Storage” page (see screenshot in the step below:

    11. Click on the “Add” button to add a new storage type. In the “Type” column select “event_file” as shown here:

    clip_image003

    12. Now fill out the “Properties” to specify a where you want the report file to be placed and what space values you want to allow. Then click “OK”

    Of course, there are many other options you can configure and additional information you can capture but for this exercise we will just create a simple report in order to try out the feature. You can right-click on the “My Blocked Process” report and change other properties later if you like.

    So, let’s start our report session and then cause some blocking so you can see how the report looks. The following steps can achieve this:

    1. To start the session simply right click on “My Blocked Process Report” and select “Start Session”.

    2. To create some blocking, first run the following TSQL commands in a SSMS Query window:

    use tempdb
    go
    create table Table1 (a1 int)
    go
    begin tran
    insert into Table1 values(1)
    go

    3. Now start a 2nd TSQL Query Window and run the following command which will be blocked behind the connection running the above statements:

    use tempdb
    go
    select * from table1

    4. Leave the 2nd TSQL Query Windows running in a blocked state for a few moments so that the blocking report can start to accumulate blocking events. After about a minute, enter the following TSQL statement in the 1st SSMS Query Window to remove the cause of this blocking incident:

    rollback tran

    5. Now right-click on the “My Blocked Process Report” in SSMS and select “Stop Session”.

    6. To review the details in the blocked process report go to the file location you specified for the “event-file” you stipulated earlier (see step 11 above). In the folder you specified you should see a file with a name like this:

    “My Blocked Process Report_0_130651143384850000.xel”

    7. Double click on this report and it will open it in SSMS. It should contains some events related to the blocking we created above and will look like this:

    clip_image004

    8. As you can see, there are multiple events recorded. This is because we had a single blocked process which was waiting for over 5 seconds (but it was blocked for a minute so it was reported multiple times). Double-click on the first of these events and you will see some more detail about the blocking incident, like this:

    clip_image005

    9. At first glance, the fields shown above may appear only mildly interesting. The duration value is in microseconds so the above event records a blocking process which had been in a blocked state for just over 5 seconds. You can see that the block occurred in the tempdb database along with some other details. You could be forgiven for being underwhelmed by the information displayed here but before giving up take a closer look at the “blocked_process” field which contains some xml content. This is the good stuff we are looking for. Double-click on the xml value in this field to open it up in SSMS. You will see something like the following:

    image

    10. This information can be extremely useful for understanding the blocking problem. Notice that it contains the following details (and more):

    For the Blocked Process:

    • Object ID
    • Wait time (in milliseconds this time)
    • When the transaction started
    • Lock Mode
    • Transaction status (e.g. suspended)
    • Connection ID (SPID)
    • Client application name
    • Machine name (Hostname)
    • Login name
    • Isolation level
    • Input buffer, i.e. the actual SQL statement which was blocked.

    For the Blocking process:

    • Object ID
    • Wait time
    • Connection ID
    • Input buffer, i.e. the SQL statement which caused the blocking. Please note that this only appears on the first event record for each distinct blocking incident.

    Hopefully you will find this approach to diagnosing blocking problems helpful. As you may have noticed, Extended Event Sessions can be used to collect all sorts of other system information from SQL Server but in this blog we have only been concerned with blocking analysis. The fact that these Extended Event Sessions are fully integrated with the SQL Server engine means that they have very little impact on performance making this approach ideal for monitoring live environments.

    Gerard Conroy
    Dynamics NAV Support EMEA

    P.S: Have you ever wondered “How do I Profile Application Code in Microsoft Dynamics NAV 2013 R2”? If so, you need look no further: http://msdn.microsoft.com/en-US/dynamics/nav/dn858631

  • Microsoft Dynamics NAV Team Blog

    C/AL Coding Guidelines used at Microsoft Development Center Copenhagen

    • 4 Comments

    Recently, the NAV Design Patterns team published the C/AL Coding Guidelines that we use at Microsoft Development Center Copenhagen to the Dynamics NAV Community Wiki site. Please join us there if you want to read and discuss the guidelines. 

    However, we've been asked for a printable version of the guidelines as well, so we attached a PDF file with the current version to this blog post. This PDF file will not be updated if and when the guidelines change, so please consider them a snapshot as of January 2015. For more information, see the Dynamics NAV Community Wiki.

     

    Best regards,

    The NAV Design Patterns team

  • Microsoft Dynamics NAV Team Blog

    NAV Design Pattern - the Released Entity Pattern

    • 0 Comments

    Happy New Year, everyone!

    With the new year, here's a new pattern to warm us up. Coming from a Danish partner, this pattern describes how to handle data entities when they need to be in a consistent or in a certain state before further processing can be allowed. Thank you Henrik Langbak and Kim Ginnerup from Bording Data for sharing this knowledge with the NAV developers community.

    Best regards,

    The NAV Patterns team

    Meet the Pattern

    This pattern prevent data from being used elsewhere before it is in a system consistent state.
    Microsoft Dynamics NAV inserts a record as soon as the primary key has been set. But the record may not be in a valid state at this point in time. How do you know if a newly inserted record is ready for use?

    Know the Pattern

    Whenever you need to stall the release of data, you can use this pattern.

    Because Microsoft Dynamics NAV decides when a record is written to the database, it may not be in a system consistent state. Nobody should use the record before everything is in place and the record is valid. An inserted record may even have data in other tables that needs to be inserted and in a valid state before other parts of the system can use the data without running into a problem.

    Data entered into the system may have to be approved by a second person before it can be used.

    Data requires different parties (e.g. Departments) to add information before data is valid.

    The solution is an Option Field with two or three values:
    (Open, Released) or (Open, Pending, Released)

    The states should be interpreted as:

    State

    Description

    Open

    Not all data is in place. The record is system inconsistent. The record or record hierarchy is invisible for all other parts of the system.

    Pending

    The record is system consistent. But is awaiting someone to manually raise the state to Released.
    The record is still invisible.

    Released

    All data is in place and the record is system consistent, and ready for use. It is now visible for the rest of the system. The state can never be reversed.

    The option field name: Release State.

    This pattern is very similar to the Blocked Entity pattern, but it has one significant difference.
    The record is not visible to any part of the system, before it is in the Released state.
    There is no going back. When the Released state is reached, it will stay that way for the life of the record. In case of a tri-state, it is ok to bypass Pending seen from a system state perspective.

    If there is a hierarchy, e.g. Header and Lines, then the Release State field resides on the Header. As long as the Header remains unreleased, the lines are considered inconsistent and must not be used.

    The important and critical part of this pattern is that the whole application needs to obey the “Release State”-contract or the system will fail. 

    Use the Pattern

    To use this pattern you need to create an Option Field named: “Release State” with at least the two states: Open, Released. 

    Read more about this pattern on the NAV Design Patterns Wiki community page...

  • Microsoft Dynamics NAV Team Blog

    Code Upgrade: Merging Version Lists

    • 2 Comments

    Merging cumulative updates into your own Microsoft Dynamics NAV solutions has become a lot easier with the new merge utilities. They are based on the concept of three-way merge to reconcile two sets of changes made (independently) to a given base version. For example, when applying Microsoft Dynamics NAV 2015 Cumulative Update 1 to a customized database, the customized database and the cumulative update are both derived from Microsoft Dynamics NAV 2015 RTM, which is the shared based version in that case.

    There is one aspect, though, that raised quite a few questions from the community and that is merging of the Version List object property.  Out-of-the-box the merge command offers only very limited support to handle this. You can either choose to clear the version list or take the version list from the modified or target object. Since the Version List is just text, we couldn't really assume how it is used generically and provide corresponding merge capabilities. However, the Merge-NAVApplicationObject Windows PowerShell cmdlet provides very rich output, and in combination with the command for setting object properties it is possible to deal with version lists any way you like.

    What appears in the PowerShell console when the Merge-ApplicationObject cmdlet completes is just a summary. The cmdlet actually returns a collection of objects that each contain information about a merge. To inspect what information is available, you can assign the result to a variable and use the Get-Member comman, as shown in the following code snippet:

    $m = Merge-NAVApplicationObject ...

    $m | Get-Member -MemberType Properties

     

       TypeName: Microsoft.Dynamics.Nav.Model.Tools.MergeInfo

     

    Name        MemberType   Definition

    ----        ----------   ----------

    PSPath      NoteProperty System.String PSPath=

    Conflict    Property     Microsoft.Dynamics.Nav.Model.Tools.ApplicationObjectFileInfo Conflict {get;}

    Error       Property     Microsoft.Dynamics.Nav.Model.Tools.ErrorInfo Error {get;}

    Id          Property     int Id {get;}

    MergeResult Property     Microsoft.Dynamics.Nav.Model.Tools.MergeResult MergeResult {get;}

    Modified    Property     Microsoft.Dynamics.Nav.Model.Tools.ApplicationObjectFileInfo Modified {get;}

    ObjectType  Property     string ObjectType {get;}

    Original    Property     Microsoft.Dynamics.Nav.Model.Tools.ApplicationObjectFileInfo Original {get;}

    Result      Property     Microsoft.Dynamics.Nav.Model.Tools.ApplicationObjectFileInfo Result {get;}

    Target      Property     Microsoft.Dynamics.Nav.Model.Tools.ApplicationObjectFileInfo Target {get;}

     

    The output of the merge is a collection of MergeInfo objects. Each MergeInfo object represents a merge operation for an application object and contains information about the original, modified, target and result objects. As such, the MergeInfo objects give us access to the original, modified, and target version list, such as:

    $minfo = $m | select -first 1

    $minfo.Modified.VersionList

    Assuming that given the three input version lists we can determine the desired version list for the merge result, we can define a function that takes such a MergeInfo object to calculate the resulting version list:

    function New-NAVVersionList($MergeInfo)

    {

    ...

    }

     

    Before we implement this function, let's first see how we could use it. The Set-NAVApplicationObjectProperty cmdlet updates the object properties (including the version list) for all application objects in a text file:

    Set-NAVApplicationObjectProperty -TargetPath objects.txt -VersionListProperty 'v1'

    When we iterate over all MergeInfo objects, we can use this command together with the New-NAVVersionList function to update the version list for each object in the merge result:

    foreach($mInfo in $m)

    {

      $versionList = New-NAVVersionList $mInfo

      Set-NavApplicationObjectProperty -TargetPath $mInfo.Result -VersionListProperty $versionList

    }

    What remains is the implementation of the function that actually calculates the new version list based on the version list of the three inputs (original, modified, and target). For instance, to simply concatenate modified to target:

    function New-NAVVersionList($MergeInfo)

    {

      # MyCustomVersion,TheirModifiedVersion

      "$($MergeInfo.Target.VersionList),$($MergeInfo.Modified.VersionList)"

    }

    How version lists are often used is that for each add-on or customization for which an application object is changed a version tag is added (separated by comma). In turn, each version tag typically consists of some product code and a version number. For example a Microsoft Dynamics NAV 2015 W1 object that was customized for my add-on (MY) and their add-on (THEIR) could get version list: NAVW18.00.00,MY1.1,THEIR6.2. Note that the version number for the NAV version tag is composed of a major, minor, and build number. The build number is typically updated in the case of cumulative updates.

    When merging an update into your code any version tag might be updated or new version tags might be added. The result of merging version lists should contain one tag for each product code that occurs in the modified and target version lists and it should be the tags with the highest version number for that product code. With these requirements our New-NAVVersionList function becomes this:

    function New-NavVersionList($MergeInfo, [string[]]$ProductCode = 'NAVW1')

    {

        $allVersions = @() + $MergeInfo.modified.versionlist -split ','

        $allVersions += $mergeInfo.target.versionlist -split ','

     

        $mergedVersions = @()

        foreach ($code in $ProductCode)

        {

            # keep the "highest" version tag for $code

            $mergedVersions += $allVersions | where { $_ -like "$code*" } | sort | select -last 1

     

            # remove all $code version tags

            $allVersions = $allVersions | where { $_ -notlike "$code*" }

        }

     

        # return a ,-delimited string consisting of the "highest" versions for each $ProductCode and any other tags

        $mergedVersions += $allVersions

        $mergedVersions -join ','

     

    This function was brought to you by Bas Graaf.

    On behalf of him and the rest of the Dynamics NAV team, your blog editor wishes you all Happy Holidays!

  • Microsoft Dynamics NAV Team Blog

    Welcome to Dynamics NAV App Update Version 1.1

    • 5 Comments

    An update to Microsoft Dynamics NAV for tablets is now available. Update to version 1.1. from your preferred store; Windows Store, or Google play. The update to version 1.1 will soon be available on the App Store as well.

    Note that the minimum requirement for installing the Dynamics NAV for tablets update is that Microsoft Dynamics NAV 2015 CU1 is installed, if you use Microsoft Azure Active Directory (Azure AD) as the authentication mechanism. For more information, please see our earlier blog post Important Note Regarding the Soon-To-Be-Released Dynamics NAV App Update Version 1.1.

    The changes and fixes in this version are:

    • Fixed security vulnerability on Android.
    • Support for iOS 8.x
    • When starting the app, the Service name field contains a hint to the expected format of the URL.
    • Avoid connection issues on some active directory domains.
    • Adjusting the service URL is easier, because the Service name already contains the value entered the first time.
    • Added language support for Dynamics NAV for Android. The list now includes: Danish (Denmark), Dutch (Belgium), Dutch (Netherlands), English (Australia), English (Canada), English (India), English (New Zealand), English (United Kingdom), English (United States), Finnish (Finland), French (Belgium), French (Canada), French (France), French (Switzerland), German (Austria), German (Germany), German (Switzerland), Icelandic (Iceland), Italian (Italy), Italian (Switzerland), Norwegian (Bokmål) (Norway), Russian (Russia), Spanish (Mexico), Spanish (Spain), and Swedish (Sweden).
    • Added language support for Dynamics NAV for iPad. The list now includes: Danish (Denmark), Dutch (Belgium), Dutch (Netherlands), English (Australia), English (Canada), English (India), English (New Zealand), English (United Kingdom), English (United States), Finnish (Finland), French (Belgium), French (Canada), French (France), French (Switzerland), German (Austria), German (Germany), German (Switzerland), Icelandic (Iceland), Italian (Italy), Italian (Switzerland), Norwegian (Bokmål) (Norway), Russian (Russia), Spanish (Mexico), Spanish (Spain), and Swedish (Sweden).

    Additionally, Dynamics NAV for tablets will include the following changes if your administrator has deployed Microsoft Dynamics NAV 2015 Cumulative Update 2:

    • Getting a "The tenant 'myTenant' was not found." error message when you try to connect to a server configured with Azure AD authentication and hostname-based tenant resolution.
    • Getting a "The tenant 'myTenant' was not found." error message when you try to connect to a server configured with Azure AD authentication and the tenant was specified as a URL parameter.
    • Microsoft Dynamics NAV for tables can now connect to a server on localhost using HTTP. This is intended for one-box demo deployments such as demoing on Surface Pro 3.

    For more information on Microsoft Dynamics NAV 2015 Cumulative Update 2, see http://go.microsoft.com/fwlink/?LinkId=522094 (login to PartnerSource is needed).

  • Microsoft Dynamics NAV Team Blog

    Understanding Error Code 85132273 in Connection with GETLASTERRORCODE Statements

    • 5 Comments

    We recently received a few interesting requests about an error code appearing under particular circumstances: 85132273. This error might typically arise with the Windows Client but also with Web Services and NAS Services as well.

    Digging under the hood, this error message is related to a Primary Key violation in SQL Server tables.

    In most of cases, this could be due to C/AL code such as the following:

    IF NOT MyTable.INSERT THEN …

    This is quite an easy and diffuse syntax that looks innocent and clean (admittedly, we even have a few instances of it in the CRONUS demonstration database). However, it is a problematic use of code because it forces an INSERT into a table and if the record already exists, an implicit error is thrown. That gives us that violation of the primary key.

    From a development perspective, we recommend that you refactor the code, where possible, in the following way (under a LOCKTABLE):

    IF NOT MyTable.GET THEN MyTable.INSERT …

    This code is preferable for at least two reasons:

    1. More logically correct

      It does not throw an implicit error caused by a primary key violation. Therefore developers could use GETLASTERRORCODE statement family in a more logical way. This statement family may catch, then, the violation of the primary key server side even though no visible runtime error would ever be show to the user. As short example, this code:

      CLEARLASTERROR;

      SalesPost.RUN;

      MESSAGE(GETLASTERRORTEXT);

      might display the error code 85132273 if there are nested statements like IF NOT INSERT THEN in the SalesPost codeunit.

      Please, be aware that this type of trapped error will not be displayed if also codeunit.RUN has a C/AL exception handling such as:

      CLEARLASTERROR;

      IF NOT SalesPost.RUN THEN

        MESSAGE(GETLASTERRORTEXT);

      In this case, any nested trapped error that might arise from IF NOT INSERT THEN will not be intercepted and no error text will be shown for this kind of violation of primary key.

    2. More efficient in some cases.

      INSERT statements with an implicit violation of the primary key are costly and if the code is typically something like IF NOT INSERT THEN MODIFY and the number of MODIFY statements is high, the statement with IF NOT GET THEN INSERT ELSE MODIFY or, better, IF GET THEN MODIFY ELSE INSERT would be typically faster in terms of performance.

    If you intend to implement error statement like GETLASTERRORMESSAGE, GETLASTERRORCODE and GETLASTERRORCALLSTACK, then you might notice that C/SIDE error code refers to a DB:RecordExists. Attached to this blog post, you will find a simple page object as proof of concept to demonstrate when and how this error might arise for a better understanding.

    Please use the attached page object only for testing and understanding, and do not use it on a live environment. It is just to demonstrate the error code in a standard CRONUS demonstration database.

    These postings are provided "AS IS" with no warranties and confer no rights. You assume all risk for your use.

     

    Duilio Tacconi                                      Microsoft Dynamics Italy         

    Microsoft Customer Service and Support (CSS) EMEA

    Special thanks to Peter Elmqvist from nabsolution.se 

  • Microsoft Dynamics NAV Team Blog

    Cumulative Update 21 for Microsoft Dynamics NAV 2013 has been released

    • 0 Comments

    Cumulative Update 21 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2013.

    The cumulative update includes hotfixes that apply to all countries and hotfixes specific to the following local versions: 

    • AU - Australia
    • AT - Austria
    • BE - Belgium
    • CH - Switzerland
    • DE - Germany
    • DK - Denmark
    • ES - Spain
    • FI - Finland
    • FR - France
    • IS - Iceland
    • IT - Italy
    • NA - North America
    • NL - Netherlands
    • NO - Norway
    • NZ - New Zealand
    • SE - Sweden
    • UK - United Kingdom

    Where to find Cumulative Update 21

    You can download the cumulative update from KB 3020883 - Cumulative Update 21 for Microsoft Dynamics NAV 2013 (Build 38800).

    Additional Information

    For a list of all cumulative updates for this version, see Released Cumulative Updates for Microsoft Dynamics NAV 2013

    For a list of all hotfixes included in cumulative updates for this version, see the following CustomerSource and PartnerSource pages:

    CustomerSource:

    PartnerSource:

  • Microsoft Dynamics NAV Team Blog

    Cumulative Update 14 for Microsoft Dynamics NAV 2013 R2 has been released

    • 2 Comments

    Cumulative Update 14 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2013 R2.

     The cumulative update includes hotfixes that apply to all countries and hotfixes specific to the following local versions:

    •   AU - Australia
    •   AT - Austria
    •   BE - Belgium
    •   CH – Switzerland
    •   CZ – Czech Republic
    •   DE - Germany
    •   DK - Denmark
    •   ES - Spain
    •   FI  - Finland
    •   FR - France
    •   IS - Iceland
    •   IT - Italy
    •   NA - North America
    •   NL - Netherlands
    •   NO - Norway
    •   NZ - New Zealand
    •   RU – Russia
    •   SE - Sweden
    •   UK - United Kingdom

    Where to find Cumulative Update 14

    You can download the cumulative update from KB 3020884  – Cumulative Update 14 for Microsoft Dynamics NAV 2013 R2 (Build 38801). 

    Additional Information

    For more information about cumulative updates for this version, see Announcement of update rollups for Microsoft Dynamics NAV 2013 R2.

    For a list of all cumulative updates for this version, see Released Cumulative Updates for Microsoft Dynamics NAV 2013 R2

    For a list of all hotfixes included in cumulative updates for this version, see the following CustomerSource and PartnerSource pages:

    CustomerSource:

    PartnerSource

Page 5 of 51 (763 items) «34567»