• Microsoft Dynamics NAV Team Blog

    Example of How to use SQL Tracing Feature to Profile AL Code

    • 7 Comments

    Enabling Tracing in Microsoft Dynamics NAV 2013

    Microsoft Dynamics NAV 2013 has a feature that allows you to see the AL call stack for a SQL commands. Here I am going to describe how it can be used to profile your application code.

    There are multiple steps required to start tracing.

    First, you need to start the Session List page. This is the same page that you need to open to start the debugger. So you need to start the development environment, then go to Tools, Debugger, Debug Session. You will get the Session List page.

    This window contains Start Full SQL Tracing/Stop Full SQL Tracing buttons. As well there is a SQL Tracing editable check box on each line.

    Start Full SQL Tracing/Stop Full SQL Tracing enables/disables tracing for all new and existing sessions and the SQL Tracing check box enables/disables tracing for a given session.

    Let’s assume we want to profile one of the sessions. Then we need to enable tracing for it, for example by clicking the check box.

    Configuring SQL Profiler

    The important part here is to select appropriate events. In this case we are interested in seeing SQL statements’ text. To achieve that we need to enable SP:StmtCompleted and SQL:BatchCompleted events. The setup should be like on the following picture.

    It allows seeing SQL queries for all statements issued from the AL.

    After this if you do some operations in the client, for example open the Sales Orders page, you will see comments in SQL Server Profiler.

    This is an example of what you can get.

    All SQL statements in-between consecutive comments correspond to the AL statement from the first comment. For example in previous screenshot, CALCFIELDS issues six SQL queries.

    The SQL profiler will contain Get connection from the pool and Return connection to the pool comments.

    These comments correspond to the events when the connection is retrieved and returned to the Microsoft DynamicsNAV Server connection poll respectively. These comments are needed to separate SQL queries issues from different clients on the same SQL connection. The SQL statement that corresponds to these comments is issued by Microsoft Dynamics NAV Server but not originated from AL.

    Comments that contain only user name also correspond to SQL statements issued by Microsoft Dynamics NAV Server but not originated from AL. For example Microsoft Dynamics NAV Server executes queries to calculate calculated fields shown on the fact boxes. We need to have this type of comments because Microsoft Dynamics NAV Server might execute an SQL query without returning connection to the pool and not originated from AL.

    Filtering Your Statements

    In the SQL profiler you will see statements from the different connections. This is because you can have multiple clients running or, for example, you can have SQL reporting services or some other service enabled. It is important to filter out everything except what is coming from the client you are profiling.

    To do that for each SQL statement you need to find first previous comment with the same SPID. If this comment is Return connection to the pool then this SQL statement is not originated from the AL code of the client that is being profiled.

    User name in the comment identifies the client by which SQL statement is generated.

    Collecting the Data and Analyzing

    Before the profiler is started, the server should be "warmed up," otherwise there is going to be a lot of queries for metadata reading. The scenarios that are going to be profiled should be executed previously at least once.

    After the SQL trace is collected it should be saved into the SQL table.

    Bellow I have an example of an SQL script that finds the most expensive AL statements. The trace was saved into the NAV7_Trace table in the master database.

    SELECT * FROM [master].[dbo].[NAV7_Trace] --query the trace table content

    DECLARE @ApplicationName NVARCHAR(100)
    DECLARE @GetConnection NVARCHAR(100)
    DECLARE @ReturnConnection NVARCHAR(100)
    DECLARE @ContainsUserName NVARCHAR(100)
    DECLARE @EmptyCallStack NVARCHAR(100)

    SET @ApplicationName = 'Microsoft Dynamics NAV Service'
    SET @GetConnection = '%Get connection%'
    SET @ReturnConnection = '%Return connection%'
    SET @ContainsUserName = '%User: Your user name%'
    SET @EmptyCallStack = '/*__User: Your user name__*/'

    IF OBJECT_ID('tempdb..#ProfilerData') IS NOT NULL
     DROP TABLE #ProfilerData

    SELECT * INTO #ProfilerData FROM
    (
     SELECT
      [RowNumber] AS [SqlStatement RowNumber],
      [TextData] AS [SQL Statement],
      [Reads],
      [Writes],
      [Duration],
      [StartTime],
      [EndTime],
      [SPID]
     FROM [master].[dbo].[NAV7_Trace]
     WHERE
      [ApplicationName] = @ApplicationName and
      [TextData] not like @ContainsUserName and
      [TextData] not like @GetConnection and
      [TextData] not like @ReturnConnection and
      [TextData] not like @EmptyCallStack
    ) SqlStatement
    CROSS APPLY
    (
     SELECT TOP 1
      [RowNumber] AS [Stack RowNumber],
      [TextData] AS [Call Stack]
     FROM [master].[dbo].[NAV7_Trace]
     WHERE
      [SPID] = SqlStatement.[SPID] and
      [RowNumber] < SqlStatement.[SqlStatement RowNumber] and
      [ApplicationName] = @ApplicationName and
      [TextData] like @ContainsUserName
     ORDER BY [RowNumber] DESC
    ) AS Stack

    SELECT * FROM #ProfilerData --this table contains mapping of SQL statements to the AL call stack

    SELECT
     CAST([Call Stack] AS NVARCHAR(4000)) AS [Call Stack],
     SUM(Duration) AS [Sum Duration],
     AVG(Duration) AS [Average Duration],
     MIN(Duration) AS [Min Duration],
     MAX(Duration) AS [Max Duration],
     SUM(Reads) AS [Sum Reads],
     SUM(Writes) AS [Sum Writes]
    FROM #ProfilerData
    GROUP BY CAST([Call Stack] AS NVARCHAR(4000))
    ORDER BY [Sum Duration] DESC -- this query finds the most expensive AL statements

    Result of previous query shows the most expensive AL calls. Second and fifth rows show the total time spent in the SQL calls issued by the server and not originated from AL.

    Also you can create a query which finds SQL statements which correspond to appropriate call stacks.

    SELECT * FROM #ProfilerData
    WHERE [Call Stack] like '%"Sales-Post"(CodeUnit 80).OnRun(Trigger) line 1556%'

    SELECT * FROM #ProfilerData
    WHERE [Call Stack] like '%"Gen. Jnl.-Post Line"(CodeUnit 12).InsertGLEntry line 59%'

    SELECT * FROM #ProfilerData
    WHERE [Call Stack] like '%"Item Jnl.-Post Line"(CodeUnit 22).ApplyItemLedgEntry line 252%'

    It is also easy to create a query which will count the number of times the same call stack occurs in the trace.

    SELECT
     COUNT(CAST([TextData] AS NVARCHAR(4000))) AS Count,
     CAST([TextData] AS NVARCHAR(4000))
    FROM [master].[dbo].[NAV7_Trace]
    WHERE
     [ApplicationName] = @ApplicationName and
     [TextData] like @ContainsUserName and
     [TextData] not like @GetConnection and
     [TextData] not like @ReturnConnection and
     [TextData] not like @EmptyCallStack
    GROUP BY CAST([TextData] AS NVARCHAR(4000))
    ORDER BY COUNT(CAST([TextData] AS NVARCHAR(4000))) DESC

    -Dmytro Sitnik
     

  • Microsoft Dynamics NAV Team Blog

    Microsoft Dynamics NAV 2013 NAS Services User Credentials

    • 7 Comments

    You might wonder what user credentials are used to run the NAS services on Microsoft Dynamics NAV 2013.

    The NAS services start when Microsoft Dynamics NAV Server starts, unconditionally of any users logging in to Microsoft Dynamics NAV server.

    The credentials that are used to run the NAS services are the user account that runs Microsoft Dynamics NAV Server.

    In a default installation the following user name is used: NT AUTHORITY\NETWORK SERVICE

    Please note the security note about the credentials used to run Microsoft Dynamics NAV Server described in this How to: Create a Microsoft Dynamics NAV Server Instance (http://msdn.microsoft.com/en-us/library/hh168936(v=nav.70).aspx) help topic, where we recommend, for security reasons, that you always run Microsoft Dynamics NAV Server instances under a dedicated domain user account in production installations.

    The user credentials that are used to run the NAS services must be created as an NAV user, and that user must be assigned the necessary permissions in order to execute the C/AL code in the NAS Services.

    Example Useful in Demo Installations

    NT AUTHORITY\NETWORK SERVICE created as a NAV user and assigned the SUPER Permission set:

    If you haven’t created the NAV user, Microsoft Dynamics NAV Server will exit with this information in the event log:

    Server instance: DynamicsNAV70
    Session type: Nas
    Session ID: 0
    The Microsoft Dynamics NAV Server instance "DynamicsNAV70" did not start because the NAS session did not start. The user "NT AUTHORITY\NETWORK SERVICE" that is configured to start the NAS session was not identified as a user that has permissions for Microsoft Dynamics NAV. Set up a Microsoft Dynamics NAV user to run the NST, or create the NST user, such as NT AUTHORITY\NETWORK SERVICE, as a Microsoft Dynamics NAV user, and then start the NST again.
    Type: Microsoft.Dynamics.Nav.Types.NavDatabasePasswordException
    Message: The user ID and password are not valid. Please try again.

    When the user hasn’t the needed permissions the Microsoft Dynamics NAV Server will exit with this information in the event log..:

    Session type: Nas
    Session ID: 1
    The Microsoft Dynamics NAV Application Server session has failed. Reason:
    Type: Microsoft.Dynamics.Nav.Types.NavPermissionException
    Message: You do not have the following permissions on CodeUnit ApplicationManagement: Execute

    I hope this help you utilize the Microsoft Dynamics NAV 2013 NAS services. :-)

    Thanks,

    Hans Kierulff

  • Microsoft Dynamics NAV Team Blog

    Release Candidate for Microsoft Dynamics NAV 2013

    • 7 Comments

    Hi, everyone, I hope you are doing well and having a great day!
     
    Just this week, we cut our first release candidate (“RC1”) for NAV 2013, which means we’re very close to RTM and shipping the product to you. I can’t say enough about this product and how it’s come together. But I’ll certainly try, since it’s so much fun to talk about!

    Dynamics NAV 2013 has powerful and diverse new application functionality, ranging from charting to cash flow analysis to time sheet registration to assembly to expanded out-of-the-box RoleCenters to Unicode. Have to catch my breath for a second …  The user experience innovations range from the SharePoint and web clients to end user productivity features on the rich client to improved integrations with OneNote and Excel. From all the feedback we’ve gotten, even diehard classic client fans will be on RoleCenters very soon! The runtime investments increase performance and scalability for transactions and reporting. They’re also built to run optimally on Azure as well as to improve partner-hosted performance. To improve manageability we created a new admin console and added APIs for powerful scripting. The server also now complies with the rigorous Microsoft’s Common Engineering Criteria (CEC) server “hygiene” standards. In response to your needs for developing on pages, we’ve enhanced tooling substantially around page design and debugging (and testing!). Finally, we’ve rethought rapid deployment through the new Rapid Start module. That’s just off the top of my head! Perhaps, more than anything, this release has been about quality: NAV 2013 exceeds every quality bar for any release of NAV we’ve had thus far. I guess that’s what I’m proudest about. 

    Together, this array of functionality and capability manifests our value proposition for the release and the product – Microsoft Dynamics NAV 2013 is “A Business Solution from Microsoft.”

    I hope you go to PartnerSource later this month, download the product, and get to know it better. Then, go aggressively sell it to new customers and upgrade your existing customers!

    Thanks to all the people who’ve made NAV 2013 happen, both externally as partners and customers providing feedback through our Technical Adopter and Beta programs and internally on the Microsoft development team. Collectively, you’ve all done an amazing job getting out a great product.
     
    It’s an exciting time to be in the NAV business and for the NAV product. From the tremendous energy at a sold-out Directions EMEA in Rome to the release of NAV 2013 this month to what I expect will happen at Directions in the Phoenix later this fall, I feel the momentum growing. Perhaps that’s why it’s such a bittersweet time for me personally. As some of you already know, after four years living in Denmark, my family and I moved back to the U.S. this summer to be closer to our extended family. As a result, after four and half years as the General Manager of NAV R & D, my time has come to say farewell and thank you for all the incredible memories  I’ve had with you our partners, with the Microsoft team in Vedbaek, and with the product itself. It’s been an amazing experience! Thank you all very, very much! My successor, Erik Tiden, is a person worthy of this great community, and I welcome him warmly. (I’ll let him tell his story in the next blog.)

    Best of luck to you all, and I hope our paths cross again soon.
     
    Sincerely,

    -Dan

     

  • Microsoft Dynamics NAV Team Blog

    Announcement of new hotfix process for Microsoft Dynamics NAV 2013

    • 7 Comments

    Today we have released an update rollup that includes all application and platform hotfixes that have been released for Microsoft Dynamics NAV 2013. The update rollup includes hotfixes that apply to all countries and select local versions.

    Going forward, we will release monthly update rollups instead of individual hotfixes.

    What is an update rollup

    An update rollup is a cumulative set of files that includes all hotfixes (application and platform) and regulatory features that have been released for Microsoft Dynamics NAV 2013, including hotfixes and regulatory features released in previous update rollups.

    Where to find the update rollups

    You can download the first update rollup from KB 2829782 - Update Rollup 1 for Microsoft Dynamics NAV 2013 (Build 34587). The hotfixes that are included in this update rollup are listed in the KB article.

    You can find a list of all update rollups released for Microsoft Dynamics NAV 2013 in KB 2842257 - Released update rollups for Microsoft Dynamics NAV 2013.

    You can find a list of all hotfixes included in update rollups for Microsoft Dynamics NAV 2013 on the following CustomerSource and PartnerSource pages:

    CustomerSource

    PartnerSource

    Which countries are included in the update rollups

    The first update rollup includes hotfixes that apply to all countries (W1) and local hotfixes for Germany (DE). Future update rollups will include local hotfixes for the following countries:

    • AT – Austria (first included in Update Rollup 12)
    • AU - Australia (first included in Update Rollup 5)
    • BE - Belgium (first included in Update Rollup 12)
    • CH - Switzerland (first included in Update Rollup 12)
    • DE - Germany
    • DK - Denmark (first included in Update Rollup 2)
    • ES - Spain (first included in Update Rollup 12)
    • FI - Finland (first included in Update Rollup 12)
    • FR - France (first included in Update Rollup 2)
    • IS – Iceland (first included in Update Rollup 12)
    • IT – Italy (first included in Update Rollup 2)
    • NA – North America (first included in Update Rollup 2)
    • NL - Netherlands (first included in Update Rollup 2)
    • NO - Norway (first included in Update Rollup 12)
    • NZ - New Zealand (first included in Update Rollup 5) 
    • SE - Sweden (first included in Update Rollup 8)
    • UK – United Kingdom (first included in Update Rollup 2)

    Weekly platform rollups

    To ensure early access to platform hotfixes, weekly platform rollups will be released between monthly update rollups.

    Access to update rollups

    Please note that a CustomerSource or PartnerSource login is required to access the update rollups and all links in this blog post.

  • Microsoft Dynamics NAV Team Blog

    New finsql.exe Command Prompt Options

    • 7 Comments

    Based on partner feedback and the increasingly important goal of automating processes around a Microsoft Dynamics NAV installation, we’re pleased announce that we have added company-related and database-related command-line options to finsql.exe, in addition to the existing options. Introduced in hotfix 2791548, you can use the following commands to perform development tasks without using the Microsoft Dynamics NAV Development Environment.

    • Create company - new
    • Delete company - new
    • Rename company - new
    • Create database - new
    • Compile objects
    • Export objects
    • Import objects

    Note

    To use the new and changed command-line options, you must install hotfix 2791548 (requires access to PartnerSource/CustomerSource).

    You can start the Microsoft Dynamics NAV Development Environment by running finsql.exe at the command prompt. By default, finsql.exe is located at C:\Program Files (x86)\Microsoft Dynamics NAV\70\RoleTailored Client\. The extended full syntax is:

    Finsql.exe [command=<command> | designobject=<object type> <object ID>,] [servername=<server>,] [database=<database>,] [collationname=<collation>,] [company=<company>,] [newcompany = <new company>,] [filter=<filter>], [logfile=<logfile>,] [username=<user name>,] [password=<password>,] [ntauthentication=<yes|no|0|1>]

    The full documentation is available on the MSDN Library. Additional documentation is available at Development Environment Commands.

    Parameters

    The following list describes the parameters that you can use with finsql.exe.

    collation

    The collation to use when you create a new database. The value must be one of the following:

      • A full language culture name. For example, da-DK for Danish or hu-HU for Hungarian.
      • A SQL Server collation name without case or accent. For example, Latin1_General_100.
      • A SQL Server collation name with case and accent. For example, Danish_Greenlandic_100_CS_AI.

    Use this optional parameter when you create a database with the command=createdatabase parameter.

    command

    The development command that you want to run. The possible values include:

      • CompileObjects
      • CreateCompany
      • CreateDatabase
      • DeleteCompany
      • ExportObjects
      • ImportObjects
      • RenameCompany

    If you specify this parameter and run a command, then the development environment does not open.

    For more information, see Development Environment Commands.

    company

    The name of the company that you want to create, delete, or rename.

    A company name cannot be more than 30 characters.

    If you create, delete, or rename a company with the command parameter, then the company parameter is required.

    database

    If you use the command=CreateDatabase parameter, then the database parameter specifies the name of the new database that you want to create. In this case, the database parameter is required.

    For all other commands, the database parameter specifies the database that you want to open.

    If you do not specify both the servername and the database parameter, then the database server and database that are stored in the .zup file are used. If you do not specify the database parameter but you do specify the servername parameter, then the Open Databasewindow opens so that you can specify the database name.

    For more information, see Saving Setup Parameters in the Zup File.

    designobject

    The type and ID of the object that you want to design. The possible values of the object type include:

      • Table
      • Page
      • Report
      • Codeunit
      • Query
      • XMLport

    The possible values of the object ID are 0 and any ID of an existing object. If you specify 0 for the object ID, then you open a new object to design.

    For more information, see DesignObject.

    file

    The path and file name. Use the file parameter for the following:

      • To specify the path and file name to which you export objects if you use the command=ExportObjects parameter. The file must have a .fob or .txt file name extension.
      • To specify the path and file name from which you import objects if you use the command=ImportObjects parameter. The file must have a .fob or .txt file name extension.
      • To specify the directory for the new database file if you use the command=createdatabase parameter.

    For more information, see ExportObjects and ImportObjects.

    filter

    A filter on the Object table.

    Use this parameter if you use the command parameter to compile, export, or import objects.

    For more information, see Development Environment Commands.

    id

    Specifies the ID of the .zup file. By default, the setup parameters are stored in and retrieved from the fin.zup file. If you specify the id parameter, then the setup parameters are stored in and retrieved from a file that is named <id>.zup.

    By default, the fin.zup file is located at C:\users\<user name>\AppData\Roaming\. To change the location of the .zup file, specify the path and ID in the id parameter.

    For more information, see Saving Setup Parameters in the Zup File.

    logfile

    Specifies the path and file name for the file that contains error messages that result from running finsql.exe with the command parameter. If there are no errors, then a log file is not created.

    For more information, see Development Environment Commands.

    newcompany

    The new name of the company that you rename.

    A company name cannot be more than 30 characters.

    If you rename a company with the command parameter, then the newcompany parameter is required.

    ntauthentication

    Specifies if you want to use NT authentication. The possible values are yes, no, 1, or 0. If you specify the username and password parameters, then you must specify ntauthentication=no or ntauthentication=0.

    objectcache

    Specifies the size of the object cache, in kilobytes. Objects such as code, descriptions, and windows that are used on the computer that is running the development environment are stored in the object cache.

    The default value is 32000.

    password

    Specifies the password to use with the username parameter to authenticate to the database. If you do not specify a user name and password, then the command uses the Windows user name and password of the current user to authenticate to the database.

    servername

    Specifies the name of the database server.

    If you do not specify both the servername parameter and the database parameter, then the database server and database that are stored in the .zup file are used. If you do not specify the servername parameter but you do specify the database parameter, then the Open Database window opens so that you can specify the database server name.

    For more information, see Saving Setup Parameters in the Zup File.

    temppath

    Specifies the path of the location to store temporary files that are created while Microsoft Dynamics NAV runs. These files are automatically deleted when Microsoft Dynamics NAV is closed.

    By default, these files are put in the Temp folder for the user, such as C:\Users\user name\AppData\Local\Temp\

    username

    The user name to use to authenticate to the database. The user name must exist in the database. If you do not specify a user name and password, then the command uses the Windows user name and password of the current user to authenticate to the database.

    Warning

    If User Access Control (UAC) is turned on and you do not specify to run the Command Prompt window as Administrator, then the Command Prompt window runs as a standard user. In this case, if you do not specify the username parameter and the current Windows user is an Administrator, then the command is run as the standard user.

    If you specify the username parameter, then you must also specify the password parameter and the ntauthentication parameter must be no or 0.

    For more information about database users and permissions, see Setting Database Owner and Security Administration Permissions in the MSDN Library.

     

     

    Best regards from the NAV Management Tools team

     

     

     

  • Microsoft Dynamics NAV Team Blog

    NAV Design Pattern of the Week – the Hooks Pattern

    • 7 Comments

    A new series of NAV Design Patterns is just starting. To make a good beginning, the first one is not chosen randomly. It is indeed a very powerful pattern – the “Hooks”, by Eric Wauters. It is also different from most patterns you’ve seen so far, in that it does not exist in the core product. “How can it be? A powerful NAV pattern which is not in NAV?”, you wonder.

    This is exactly the point of the Hooks. It is a partner pattern – something you, as a partner, can use, when you implement your customization. And if done correctly, it has the potential to make the next upgrade superfast.   

    Are you having a hard time installing update after update, rollup after rollup? Does it consume more resources than you had wished? Is the customization code entangled with the core product code, in such a way that each update requires complicated merges, with the developer trying to figure out which code goes where?

    To keep it short, here it is – the Hooks pattern. Most powerful when starting a new customization, as it can be implemented fully. It will keep things simple. As for the legacy customizations... it is still possible to use it, by refactoring key areas such as areas with the most update merge issues.

    Hooks Pattern

    by Eric Wauters (waldo), Partner-Ready-Software

    Meet the Pattern

    By minimizing the code in already existing application objects, you will make the upgrade process much easier, and all customization business logic will be grouped in new objects.  When using atomic coding, it will be very readable what is being customized on a certain place in an existing part of the application.

    To minimize the impact of customizations, the idea of hooks is:

    • First of all, name the places in the already existing code where customization is needed;
    • Second, place your business logic completely outside the already existing application code.

    Know the Pattern

    When doing development over years, by different developers with different mindsets, the standard codebase gets changed a lot, adding multiple lines of code, adding local and global variants, adding or changing keys, changing existing  business logic, … .  In other terms, the standard text objects are being changed all over the place.. .

    After years, it's not clear why a change was done, and what was the place where the change was intended to be done.  And the latter is quite important in an upgrade process, when code in the base product is being refactored: if the exact place of the posting of the Customer Entry is being redesigned to a separate number, the first thing I need to know, is that I did a certain change at the place: "where the posting of the Customer Entry starts".  The definition of that place, we call a "Hook".

    I recommend to use this concept on the following:

    • All objects of the default applications that need to be changed
    • On objects that should not hold any business logic (like tables, pages, XMLPorts)

    Use the Pattern

    Step 1 - if it doesn't exist yet - you create your Hook codeunit.  As the name assumes .. this is always a codeunit.  We apply the following rules to it:

    • One Hook always hooks into one object.  Which basically means that I will only declare this new codeunit in one other object (which is its parent object)
    • The naming convention is: The_Original_Object_Name Hook.  Naming conventions are important, just to find your mapped object, and also to be able to group the Hooks.

    Step 2, you  create the hook, which is basically a method (function) in your codeunit.  The naming is important:

    • The naming of the hook should NOT describe what it is going to do (So, examples like CheckMandatoryFields, FillCustomFields should not be used as a hook)
    • The naming of the hook should describe WHERE the hook is placed, not what the hook will be doing (as nobody is able to look into the future .. :-))
    • To help with the naming, it is a good convention to use the "On"-prefix for these triggers.  This way, it's very clear what are hooks, and what aren't..

    Step 3, it's time to hook it to its corresponding object and right place in the business logic of that object.  You do this by declaring your codeunit as a global in your object, and using the created hook function on its place in the business logic.  This way, these one-liners apply:

    • A Hook codeunit is only used once in one object only (its corresponding object)
    • A Hook (function) is used only once in that object.  As a consequence, changing the parameters has no consequence: you only need to change one function-call
    • The codeunit is declared as a global.  That exact global is the only custom declaration in the existing object .. Everything else is pushed to the hook-codeunit.

    Step 4, implement your business logic in the hook.  Do this in the most atomic way, as there is a good chance that this same hook is going to be used for other business logic as well.  Best is to use a one-line-function-call to business logic, so that the Hook Function itself stays readable.

    Example

    Suppose, we want to add business logic just before posting a sales document.  In that case, we have to look for the most relevant place, which is somewhere in the "Sales-Post" codeunit.  So:

    Step 1: create codeunit Sales-Post Hook:

    Step 2: create the hook function OnBeforePostDocument:

    Step 3: declare a global in the Sales-Post codeunit, called SalesPostHook.  Then,...

    Continue reading on the NAV Patterns Wiki...

     

    Best regards,

    The NAV Patterns team

  • Microsoft Dynamics NAV Team Blog

    Cash Management in Microsoft Dynamics NAV 2013 R2 – More News!

    • 7 Comments

    You read it here first! Microsoft Dynamics NAV R2 will deliver exciting new features to support cash management for our customers and prospects.

    What it really means for customers

    The bottom line is increased productivity – for all our customers – in almost any segment! The new Cash Management features in Microsoft Dynamics NAV R2 will automate and improve the cash management processes that are vital for all our customers regardless of the business they’re in.

    Consider this:

    • New Cash Management functionality includes easy registration of payments to ensure faster business processes with fewer human errors.
    • You can import electronic payment files from banks and use them as basis for payments registrations. (In Denmark for Danish banks out of the box. Other countries will require minor configurations)
    • Bank Reconciliation is possible as both a manual and an automated process, with the option to import bank statements from banks and reconcile automatically. A simple tool can be used to set up automation, handle exceptions and complete the reconciliation process.
    • Bank Statements can be imported from 3rd party providers. The same functionality will allow partners to build their own integration to banks, meaning a free choice of providers.

    What features are introduced to enable this?

    SEPA CREDIT TRANSFER

    A new feature is introduced that enables the user to export payment data to an electronic bank file in SEPA compliant format. This gives the user the possibility to integrate electronically with any bank in the Single European Payment Area and get higher efficiency in the payment process end-to-end.

    Also, when payment instructions to the bank are managed directly in the system the user gets better control over the payment process and the ability toenhance cash flow due to SEPA rules about dates.

    SEPA DIRECT DEBIT

    A new feature called SEPA Direct Debit Collections, which provides an efficient way to handle customer’s payment collections through your preferred bank in the Single European Payment Area (SEPA) with less manual entry of data and effective mandate handling.

    The feature allows users to collect money from their customers in a seamless connected way with the invoicing process, minimizing the order to cash lead time and increasing their cash management efficiency.

    SCHEMA VIEWER

    A new tool that enables partners to import SEPA compliant schemas (ISO 20022) into Microsoft Dynamics NAV and export the desired xml tags in an xmlport ready format. This gives the partner an excellent starting point for building up new xmlport to handle SEPA format variations for its customers.

    Also, when handling the xml schema, relevant information about each tag is displayed enabling filtering mandatory tags and attributes.

    How and when you can learn more on MSDN

    We are working on a number of knowledge articles right now and plan to have these ready for you soon on MSDN

    Hear more first-hand at DIRECTIONS!

    Don’t miss the upcoming Direction events. Join us to hear how Microsoft Dynamics NAV 2013 R2 offers new cash management features in a harmonized way across country versions. We will demonstrate the new features and you will learn how you can take it to your markets - enabling you to go for volume by having more application features to offer as standard.

    Stay tuned for more info on the NAV team blog space, Yammer, MSDN, Directions and more.

    Kind regards

    Your Cash Management team

  • Microsoft Dynamics NAV Team Blog

    Creating URLs to Microsoft Dynamics NAV Clients

    • 7 Comments

    The URL builder function, GETURL, is released in Microsoft Dynamics NAV 2013 R2 to reduce coding time for developers who need to create various URL strings to run application objects in either the win client, the web client, or on web services. In addition, the GETURL function makes multitenancy features more transparent to C/AL developers.

    Details

    Ever had to construct win client URLs like the one below?

    dynamicsnav://myserver:7046/myInstance/myCompany/runpage?page=26

    Today, Microsoft Dynamics NAV also provides a web client. This means that you must update your code to construct web client URLs too. What about multitenancy? The URL Builder should know if it is running in a multitenant setup and it should know how to choose the right tenant. What about maintaining this code?

    The good news is that GETURL has been introduced to handle all URL building for you.

    GETURL automatically handles:

    • Multitenancy
    • Correct URL format for each client
    • Publicly accessible hostnames.

    Usage

    The format is:

    [String :=] GETURL(ClientType[, Company][, Object Type][, Object Id][, Record])

    Where:

    • Client Type can be: Current, Default, Windows, Web, SOAP, or OData. This enables a range of scenarios for the C/AL developer, such as moving to the web client without changing code to decide where the URL should point to. This is done either by setting Client Type to Current, and just ensuring that web is used to invoke the link creation, or by setting Client Type to Default and changing its value to Web when it is ready to move to the web platform.
    • Object Type and Object ID define the type of the application object to run (Table, Page, Report, Codeunit, Query, or XMLport) and its ID.
    • Record specifies the actual data to run the URL on, such as:

    Vendor.GET("Account No.");

    GETURL(CLIENTTYPE:WEB,COMPANYNAME, OBJECTTYPE::Page,27,Vendor)

    Note: It is currently not possible to set filters on the record that you sent as a last parameter to the GETURL function. However, it is possible to write your own code to compute and append the filter string to the URL that is created by the GETURL function.

    The server name and instance are extracted automatically by GETURL and do not need to be specified by the C/AL developer. Furthermore, the multitenancy setup is transparent to the C/AL developer. No multitenancy parameters are specified when you call GETURL, because the function knows from the server setup if it is running in a multitenant environment and if so, it will add a string like "&tenant=MyTenant" to the URL.

    When to Use

    The GETURL function can generally be used every time a URL must be created. The following are some scenarios where the function is particularly useful.

    • Document approvals. For more information, see the “NAV Usage Example” section.
    • Reports containing drill-down links. (Beware of the resource cost of adding a new URL element to the Report dataset.)
    • When planning to write code for, or migrate to, various display targets (Microsoft Dynamics NAV Windows client, Microsoft Dynamics NAV web client, Microsoft Dynamics NAV web services) without having to explicitly specify which client to use.

    Examples of Usage

    The following are examples of calls to GETURL and their corresponding return value:

    Command

    URL

    GETURL(CLIENTTYPE::Win)

    dynamicsnav://MyServer:7046/DynamicsNAV71//

    GETURL(CLIENTTYPE::Web)

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient

    GETURL(CLIENTTYPE::OData)

    http://MyServer:7048/DynamicsNAV71/OData

    GETURL(CLIENTTYPE::SOAP)

    http://MyServer:7047/DynamicsNAV71/WS/Services

    GETURL(CLIENTTYPE::Current) ie. When running this code on a Win client session

    dynamicsnav://MyServer:7046/DynamicsNAV71//

    GETURL(CLIENTTYPE::Default) ie. When the Server config key DefaultClient is set to Windows

    dynamicsnav://MyServer:7046/DynamicsNAV71//

    GETURL(CLIENTTYPE::Windows,COMPANYNAME)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/

    GETURL(CLIENTTYPE::Windows,'')

    dynamicsnav://MyServer:7046/DynamicsNAV71//

    GETURL(CLIENTTYPE::Windows,'NONEXISTING Corp')

    dynamicsnav://MyServer:7046/DynamicsNAV71/NONEXISTING Corp/

    GETURL(CLIENTTYPE::Web,COMPANYNAME)

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS

    GETURL(CLIENTTYPE::Web,'')

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient

    GETURL(CLIENTTYPE::Web,'NONEXISTING Corp')

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=NONEXISTING Corp

    GETURL(CLIENTTYPE::OData,COMPANYNAME)

    http://MyServer:7048/DynamicsNAV71/OData/Company('CRONUS')

    GETURL(CLIENTTYPE::OData,'')

    http://MyServer:7048/DynamicsNAV71/OData

    GETURL(CLIENTTYPE::OData,'NONEXISTING Corp')

    http://MyServer:7048/DynamicsNAV71/OData/Company('NONEXISTING Corp')

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME)

    http://MyServer:7047/DynamicsNAV71/WS/CRONUS/Services

    GETURL(CLIENTTYPE::SOAP,'')

    http://MyServer:7047/DynamicsNAV71/WS/Services

    GETURL(CLIENTTYPE::SOAP,'NONEXISTING Corp')

    http://MyServer:7047/DynamicsNAV71/WS/NONEXISTING Corp/Services

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Table,27)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runtable?table=27

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Page,27)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runpage?page=27

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Report,6)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runreport?report=6

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Codeunit,5065)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runcodeunit?codeunit=5065

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Query,9150)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runquery?query=9150

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::XmlPort,5150)

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runxmlport?xmlport=5150

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Page,27) ie. When the Web Service is published

    http://MyServer:7048/DynamicsNAV71/OData/Company('CRONUS')/PAG27Vendors

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Query,9150)  ie. When the Web Service is published

    http://MyServer:7048/DynamicsNAV71/OData/Company('CRONUS')/QUE9150MyCustomers

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Page,27)  ie. When the Web Service is published

    http://MyServer:7047/DynamicsNAV71/WS/CRONUS/Page/PAG27Vendors

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Codeunit,5065)  ie. When the Web Service is published

    http://MyServer:7047/DynamicsNAV71/WS/CRONUS/Codeunit/COD5065EmailLogging

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Page,27,record) List Page

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runpage?page=27&bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw

    GETURL(CLIENTTYPE::Windows,COMPANYNAME,OBJECTTYPE::Page,26,record) Card Page

    dynamicsnav://MyServer:7046/DynamicsNAV71/CRONUS/runpage?page=26&bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Page,27,record) List Page

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&page=27&bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Page,26,record) Card Page

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&page=26&bookmark=23;FwAAAAJ7/0kAQwAxADAAMwAw

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Page,27,record)

    http://MyServer:7048/DynamicsNAV71/OData/Company('CRONUS')/PAG27Vendors('IC1030')

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Page,27)

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&page=27

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Report,6)

    https://navwebsrvr:443/DynamicsNAV71_Instance1/Webclient?company=CRONUS&report=6

    If the GETURL function is called with invalid parameters, it will return an empty string. In that case, you can find the related error text by calling the GETLASTERRORTEXT function.

    Function Call

    Error Message

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Table,27)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Codeunit,5065)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::Query,9150)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::Web,COMPANYNAME,OBJECTTYPE::XmlPort,5150)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Table,27)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Page,27)

    The Page object, 27, that is specified for the GetUrl function has not been published in the Web Services table.

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Report,6)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Codeunit,5065)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::Query,9150)

    The Query object, 9150, that is specified for the GetUrl function has not been published in the Web Services table.

    GETURL(CLIENTTYPE::OData,COMPANYNAME,OBJECTTYPE::XmlPort,5150)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Table,27)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Page,27)

    The Page object, 27, that is specified for the GetUrl function has not been published in the Web Services table.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Report,6)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Codeunit,5065)

    The Codeunit object, 5065, that is specified for the GetUrl function has not been published in the Web Services table.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Query,9150)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::XmlPort,5150)

    The specified object type parameter for the GetUrl function is not valid.

    GETURL(CLIENTTYPE::SOAP,COMPANYNAME,OBJECTTYPE::Page,27,record)

    You cannot specify a record parameter for the GetUrl function when the object type is SOAP

    NAV Usage Example

    The following example shows how to use the GETURL function in codeunit 440 to ensure that the notification mail in Document Approvals can link to both the Microsoft Dynamics NAV Windows client and the Microsoft Dynamics NAV web client:

    This resulting UI looks as follows.

    The first link opens the approval document in the Microsoft Dynamics NAV Windows client. The second link (Web view) opens the same document in the Microsoft Dynamics NAV web client.

     

    Best regards,

    Mike Borg Cardona, Bogdana Botez, and the Microsoft Dynamics NAV team

  • Microsoft Dynamics NAV Team Blog

    Update Rollup 7 for Microsoft Dynamics NAV 2013 has been released

    • 7 Comments

    Today we have released update rollup 7 for Microsoft Dynamics NAV 2013 (Build 35488).

    Update rollup 7 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2013 and includes hotfixes that apply to all countries and hotfixes specific to the following local versions:

    • AU – Australia
    • DE - Germany
    • DK - Denmark
    • FR - France
    • IT - Italy
    • NA – North America
    • NL – Netherlands
    • NZ – New Zealand
    • UK - United Kingdom

    Where to find update rollup 7

    You can download update rollup 7 from KB 2892427 -  Update Rollup 7 for Microsoft Dynamics NAV 2013 (Build 35488).

    The hotfixes that have been released since update rollup 6 are listed in KB 2892427. For a full list of all hotfixes included in the update rollup, see the following CustomerSource and PartnerSource pages:

    CustomerSource:

    PartnerSource:

    More Information

    For more information about update rollups for Microsoft Dynamics NAV 2013, see Announcement of new hotfix process for Microsoft Dynamics NAV 2013.

  • Microsoft Dynamics NAV Team Blog

    Update Rollup 5 for Microsoft Dynamics NAV 2013 has been released

    • 7 Comments

    Today we have released update rollup 5 for Microsoft Dynamics NAV 2013 (Build 35201).

    Update rollup 5 includes all application and platform hotfixes and regulatory features that have been released for Microsoft Dynamics NAV 2013. Local hotfixes for Australia and New Zealand have been added to update rollup 5 and the update rollups now include hotfixes that apply to all countries and hotfixes specific to the following local versions:

    • AU – Australia (NEW)
    • DE - Germany
    • DK - Denmark
    • FR - France
    • IT - Italy
    • NA – North America
    • NL – Netherlands
    • NZ – New Zealand (NEW)
    • UK - United Kingdom

    Where to find update rollup 5

    You can download update rollup 5 from KB 2872273 - Update Rollup 5 for Microsoft Dynamics NAV 2013 (Build 35201).

    The hotfixes that have been released since update rollup 4 are listed in KB 2872273. For a full list of all hotfixes included in update rollups, see the following CustomerSource and PartnerSource pages:

    CustomerSource:

    PartnerSource:

    More Information

    For more information about update rollups for Microsoft Dynamics NAV 2013, see Announcement of new hotfix process for Microsoft Dynamics NAV 2013.

  • Microsoft Dynamics NAV Team Blog

    Get Ready for Cash Management in Microsoft Dynamics NAV 2013 R2!

    • 7 Comments

    It’s true! The coming release of Microsoft Dynamics NAV 2013 R2 delivers new exciting features to support cash management business processes for our SMB customers and prospects.

    Why Cash Management?

    Cash management is a critical part of any business operation. Business managers need to manage their cash flow, payments and debt collections quickly and efficiently to ensure the company’s financial stability, solvency and ultimately profitability.

    Our SMB customers need more support for basic cash management processes; therefore, we are increasing our focus on cash management in the coming releases of Microsoft Dynamics NAV – beginning with Microsoft Dynamics NAV 2013 R2.

    What’s new in the coming release?

    Microsoft Dynamics NAV 2013 R2 will deliver new functionality to support bank integration with two core scenarios:

    1. Bank Reconciliation
      New capabilities include the possibility to import bank statements, reconcile bank statements with automatic matching, and apply and post incoming payments to open receivables and payables.
    2. Payments
      With Microsoft Dynamics NAV 2013 R2, it will be possible to handle in and outgoing payments automatically with credit transfers and direct debit capabilities.

    What about SEPA support?

    SEPA, what?

    SEPA, or the Single Euro Payments Area (SEPA) is an EU payment-integration initiative of the European Union. Its purpose is to simplify today’s fragmented national payment systems with a single set of standards. It enables organizations and individuals to make payments or bank transfers in euro to anyone within the area through their existing bank account using standardized payment instruments. SEPA will give companies the possibility to connect with more banks and help to shorten payment transfer times. As of March 2012, SEPA consists of the 28 EU member states, the four members of the EFTA (Iceland, Liechtenstein, Norway and Switzerland), and Monaco.

    Microsoft Dynamics NAV 2013 R2 will provide support for SEPA in the following ways:

    • SEPA will be supported in all versions of Microsoft Dynamics NAV prior to Microsoft Dynamics NAV 2013 R2 in countries that already had support for SEPA or other bank formats.
    • Microsoft Dynamics NAV 2013 R2 will provide standard SEPA support in the W1 version. Tools will be provided for partners to easily make small customizations to meet local country and customer requirements.

    More information about Cash Management in Microsoft Dynamics NAV is coming soon on the NAV Team Blog, Yammer, MSDN, Directions and more. Stay tuned!

     

    Your Cash Management Team

  • Microsoft Dynamics NAV Team Blog

    NAV 2009 Tips and Tricks: Create Notifications from Task Pages

    • 7 Comments

    You can create notifications from task pages such as customer cards or sales orders. You can use notifications as reminders, or as a way to send information to other NAV users in your company.

    A notification is displayed on the recipient's Role Center. By clicking the notification, the recipeint opens the associated task page.

    1. To create a notification, open the task page from which you want to send a notification. For example, open a customer card, sales order, or other task page.

    2. In the FactBox area, scroll down to the Notes part.

    3. In the Notes part, click to create a new note.

    4. In the Enter a new note here text box, type a note.

    5. Select a recipient.

    6. Select Notify.

    7. Click Save.

    The notification is saved on the task page.

     

    The notification is also relayed to the recipient and is displayed on his/her Role Center under My Notifications.

    For more information about usability and the RoleTailored client, see the blog post Useful, Usable, and Desirable.

  • Microsoft Dynamics NAV Team Blog

    Microsoft Dynamics NAV 2009 SP1 installation moment...

    • 7 Comments

    Recently i met customer problem where NAV 2009 SP1 components didn't work after "correct installation".

    Problem is: customer installs NAV 2009 SP1 components by run msi file - for example "Microsoft Dynamics NAV SDK.msi". But this way doesn't install "Prerequisite Components" needed by NAV 2009 SP1. And it could be these installed NAV components will not work (because it missing prerequisites).


    Only supported way to Install NAV 2009 SP1 components is - run "setup.exe".

    However "setup.exe" will uninstall previous NAV version and installs new NAV 2009 SP1 version. If you need to have few NAV version installed - you need to run msi (instead of setup.exe).
    So conclusion: both ways have it strength and weakness. You can choose what you want, just you need to know about possible issues...

    Gedas Busniauskas (gediminb)
    Microsoft Customer Service and Support (CSS) EMEA

  • Microsoft Dynamics NAV Team Blog

    Updated April 2nd 2009 - How to add a Company Picture to a Report

    • 7 Comments

    UPDATED April 2nd 2009: Several people have reported to me that the first solution I posted for “How to use the Picture stored in Company Information table:” did not work for them. So I have now updated the section on how to use the picture stored in the Company Information table. The picture is now added in a slightly different way.

    /Claus

    ******

    There are several ways to do this. Either you use the existing Picture which is stored in table 79 Company Information or you can embed the image into the Report itself, or you can link to the picture externally. In this scenario I will be looking at how to use the picture already in the database and and how to embed the picture into the report itself.

    How to embed the Picture:

    1. For us to be able to embed the picture into a report we need to have the Company Picture as a file. I have exported the company picture to c:\temp\CompanyPicture.bmp

    2. Ok, now let us add this to Report 111. Design Report 111

    3. Select "View/Layout" to go into Visual Studio.

    image

    4. Select the Report and choose "Report/Embedded Images"

    image

    5. Select "New Image..." and select your company picture, in my case c:\temp\CompanyPicture.bmp

    image

    6. With that completed open the Toolbox and add a Image control to the Report.

    image

    7. With the Image Control added we need to the set correct properties for this control. Set Source=Embedded, Value=companypicutre and MIMEType=image/bmp

    image

    9. Save and import RDLC changes, and then compile report in Classic client.

    10. Run "dynamicsnav:////runreport?report=111" to open up report 111. And as you can see below company picture is displayed.

    image

    We have no looked at how to embed the Company Picture into the report. Now let us have a look on how to use the Company Picture already in the database.

    How to use the Picture stored in Company Information table:

    1. Deleted the above embedded Company Picture, if you followed the steps above.

    2. Design report 111

    3. Now we need to have a Variable with is references to the Company Information Table. Lets create a new called CompanyInfo

    image

    4. Exit C/AL Globals and ad the following code to the "OnPreReport()" trigger: CompanyInfo.CALCFIELDS(Picture);

    image

    5. Now we should add a Picture Box on the Sections with SourceExpr: CompanyInfo.Picture. We need to do this to have the element available for us in Visual Studio.

    image

    6. It is now time to open Visual Studio. Select "View/Layout"

    7. Notice that we now have an new entry in  the DataSet

    image

    8. Now lets add this to the report. We need to add the Company Picture first as a TextBox to the body of the report. This will enable us to use it in the Page Header. We add this TextBox in top of the Body.

    image

    9. We give the TextBox the following properties:

    Value: “=Convert.ToBase64String(Fields!CompanyInfo_Picture.Value)”
    Name: “CompanyPicture
    Visibility Hidden: “True
    Color: “Red

    10. Now add the following code to the Report properties.

    Shared PictureData as Object

    Public Function GetPicture() as Object
     
    Return PictureData
    End Function

    Public Function SetPicture(NewData as Object)
     
    if NewData>""
       
    PictureData = NewData
    end if
    End Function

    image

    11. Now let us add the Image control just as we did for the embedded scenario. Open the Toolbox and add a Image control to the Report.

    image

    12. With the Image Control added we need to the set correct properties for this control.

    Value: “=Convert.FromBase64String(Code.GetPicture())
    Source: “Database
    MIMEType: “image/bmp

    13. Add textbox to Page Header. Note! This textbox has to be placed above the Picture control just added

    Value: “=Code.SetPicture(ReportItems!CompanyPicture.Value)
    Visibility Hidden: “True
    Color: “Red

    image

    14. Save and import RDLC changes, and then compile report in Classic client.

    15. Run "dynamicsnav:////runreport?report=111" to open up report 111. And as you can see below company picture is displayed.

    image

    Thanks,

    Claus Lundstrøm, Program Manager, Microsoft Dynamics NAV

  • Microsoft Dynamics NAV Team Blog

    “User ID and password are invalid.try again?”

    • 7 Comments

    If you get "User ID and password are invalid.try again?" when starting RTC you need to first check that you can login to database in the classic client. Note that the database should be the same as the service tier (the service you are trying to connect with RTC) is connected to.

    1. Start "classic client with SQL"
    2. Click File->Database->Open
    3. Pick the server the database exist one
    4. Select authentication "Windows Authentication"
    5. Pick the database
    6. Press OK

    If it works in the classic client make database login synchronization.

    1. Start "classic client with SQL" and connect to the database as above
    2. Click Tools->Security->Synchronize all logins
    3. Answer yes to the question if you would like to synchronize

    If it doesn't to connect to the database start SQL server manager and verify that the windows user have permission to login and use the NAV database.

Page 5 of 43 (638 items) «34567»