We have had some partner suggestion for adding Unicode capabilities to the existing Microsoft Dynamics NAV File functions. What we recommend is to use .NET Interop to achieve this functionality.
For example, you can use an instance of the System.IO.StreamWriter class to write to an OutStream or the System.IO.StreamReader class to read from an InStream. You control the encoding by using the System.Text.Encoding class where you select between Default, Unicode or UTF8 encoding.
Let’s start with a small example on writing some text to a file in Unicode format.
Declare the following variables:
Then write this code, using a suitable path for the outFile:
streamWriter := streamWriter.StreamWriter(outStream, encoding.Unicode);
Run the code and verify the file is in Unicode.
Try change the above example to use encoding.Default and verify the file is in ANSI (codepage) format (for example using Notepad as above).
Please note that if you use C/AL to write directly to the outStream, like this:
this is still handled using MS-DOS encoding and is compatible with previous versions of Microsoft Dynamics NAV.
In Microsoft Dynamics NAV 2013, all normal text handling are done in Unicode, so the data that are entered on the pages – like customer names one on the Customer Card – can utilize the Unicode character set, the data can be stored in the database and used in C/AL code.
Let’s see how you can extend the above example with data from the Customer table:
Add the customer variable:
And write this code – you can set a filter if needed:
UNTIL customer.NEXT = 0;
If you open the Customers.txt file with a Unicode file viewer it should contain all the Unicode details you have used for your customer names.
Similar to the above you can read Unicode text files by using the System.IO.StreamReader class to read from an InStream as you can see in the small example below:
Then write this code, using a suitable path for the inFile:
streamReader := streamReader.StreamReader(inStream,encoding.Unicode);
txt := streamReader.ReadToEnd();
Create the Infile.txt as a Unicode file and add some Unicode characters to it. You should see them in the message box when you run the C/AL code.
I hope these simple examples can get you started with Unicode file handling in C/AL.
Thanks and best regards!
A unit is any code that encapsulates an implementation. It could be one or a combination of individual functions or triggers.Thus, a unit could also refer to a local function. A unit, from the C/AL perspective, has the following:
A unit test must pass an input to the unit and verify that the output is as expected. It should be coded as a procedure in a codeunit of Test subtype.
Since unit tests are written to safeguard the implementation contract, they are not necessarily tests for functional requirements. The latter is the domain of functional tests. A successful refactoring project may result in changing some unit tests, but must not make any functional tests fail.
Since unit tests are quick low-level tests, it is affordable to have many of them. A larger number of unit tests make it possible to have a smaller number of functional tests, as the base behavior already gets tested as one goes towards higher-level tests.
Typically a unit test consists of the following sections.
In some cases, unit tests may also be used as an alternative to full functional tests, because:
With the perspective of the above objectives, a list of best practices has been drafted, which may serve as a guideline to those who create unit tests. The list should be treated as an addition to already existing best practices for writing good C/AL test code.
LOCAL PROCEDURE CreateItemWithBaseUOM@1(VAR Item@1000 : Record 27);
ItemUnitOfMeasure@1001 : Record 5404;
ItemUnitOfMeasure.Code := 'NewCode';
Item."Base Unit of Measure" := ItemUnitOfMeasure.Code;
ItemUnitOfMeasure.Code := 'NewCode';
Item."Base Unit of Measure" := ItemUnitOfMeasure.Code;
The EXERCISE step:
BinContent.SETRANGE("Item No.",BinContent."Item No.");
// The next line tests the InsertPickOrMoveBinWhseActLine procedure
Examples are based on the W1 application code in Microsoft Dynamics NAV 2013.
Test that changing the Costing Method on an item to Specific leads to an error if the tracking code is not Serial number specific.
OnValidate trigger of the Costing Method field on the Item table:
...IF "Costing Method" = "Costing Method"::Specific THEN BEGIN
IF NOT ItemTrackingCode."SN Specific Tracking" THEN
[Test] PROCEDURE VerifyErrorRaisedOnChangingCostingMethodToSpecific@1(); VAR ItemTrackingCode@1001 : Record 6502; Item@1000 : Record 27; BEGIN // Changing the Costing Method on an Item card to Specific // leads to an error if the tracking code is not Serial number specific
// SETUP : Make item tracking code without SN Specific Tracking ItemTrackingCode.INIT; ItemTrackingCode.Code := 'MyITCode'; ItemTrackingCode."SN Specific Tracking" := FALSE; ItemTrackingCode.INSERT;
// SETUP : Make item with above item tracking code Item.INIT; Item."No." := 'MyItem'; Item."Item Tracking Code" := ItemTrackingCode.Code;
// EXERCISE : Validate Costing method to Specific ASSERTERROR Item.VALIDATE("Costing Method",Item."Costing Method"::Specific);
// VERIFY : error message IF STRPOS(GETLASTERRORTEXT,'SN Specific Tracking must be Yes') <= 0 THEN ERROR('Wrong error message'); END;
The target unit was a very specific line and the above test was therefore short and precise.
Test that posting a sales order creates a posted shipment line with the correct quantity.
The OnRun trigger in Sales-Post codeunit.
[Test] PROCEDURE TestPostedSalesQuantityAfterPosting@2(); VAR Item@1001 : Record 27; SalesHeader@1000 : Record 36; SalesLine@1002 : Record 37; SalesShipmentLine@1003 : Record 111; ItemUnitOfMeasure@1005 : Record 5404; Quantity@1004 : Decimal; BEGIN // Post a sales order and verify the posted shipment line quantity.
// SETUP : Make item with above item tracking code Item.INIT; Item."No." := 'MyItem'; // Create unit of measure ItemUnitOfMeasure."Item No." := Item."No."; ItemUnitOfMeasure.Code := 'PCS'; ItemUnitOfMeasure.INSERT; Item."Base Unit of Measure" := ItemUnitOfMeasure.Code; Item."Inventory Posting Group" := 'RESALE'; Item.INSERT;
// SETUP : Create sales header with item and quantity SalesHeader."Document Type" := SalesHeader."Document Type"::Order; SalesHeader."No." := 'MySalesHeaderNo'; SalesHeader."Sell-to Customer No." := '10000'; SalesHeader."Bill-to Customer No." := SalesHeader."Sell-to Customer No."; SalesHeader."Posting Date" := WORKDATE; SalesHeader."Document Date" := SalesHeader."Posting Date"; SalesHeader."Due Date" := SalesHeader."Posting Date"; SalesHeader.Ship := TRUE; SalesHeader.Invoice := TRUE; SalesHeader."Shipping No. Series" := 'S-SHPT'; SalesHeader."Posting No. Series" := 'S-INV+'; SalesHeader."Dimension Set ID" := 4; SalesHeader.INSERT;
// SETUP : Create the sales line SalesLine."Document Type" := SalesHeader."Document Type"; SalesLine."Document No." := SalesHeader."No."; SalesLine.Type := SalesLine.Type::Item; SalesLine."No." := Item."No."; Quantity := 7; SalesLine.Quantity := Quantity; SalesLine."Quantity (Base)":= Quantity; SalesLine."Qty. to Invoice" := Quantity; SalesLine."Qty. to Invoice (Base)" := Quantity; SalesLine."Qty. to Ship" := Quantity; SalesLine."Qty. to Ship (Base)" := Quantity; SalesLine."Gen. Prod. Posting Group" := 'RETAIL'; SalesLine."Gen. Bus. Posting Group" := 'EU'; SalesLine."VAT Bus. Posting Group" := 'EU'; SalesLine."VAT Prod. Posting Group" := 'VAT25'; SalesLine."VAT Calculation Type" := SalesLine."VAT Calculation Type"::"Reverse Charge VAT"; SalesLine.INSERT;
// EXERCISE : Call the codeunit to post sales header CODEUNIT.RUN(CODEUNIT::"Sales-Post",SalesHeader);
// VERIFY : A Posted Shipment Line is created with the same quantity SalesShipmentLine.SETRANGE("Order No.",SalesHeader."No."); SalesShipmentLine.FINDLAST; SalesShipmentLine.TESTFIELD(Quantity,Quantity); END;
The targeted unit is large and there are many lines before the code to set the quantity on the Sales Shipment Line is reached. In order to reach this line a large setup is needed in the test as well, which makes the unit test bulky. It may be better to write a functional test in this case.
- Soumya Dutta from the NAV team
The Microsoft Dynamics NAV support team have posted videos on YouTube that illustrate various aspects of deployment and configuration of Microsoft Dynamics NAV 2013, including tips for how to extend the core product. You can share the videos with other partners, and with your customers - they are the same videos that our internal supporters have been able to consume for a while, and we hope you will enjoy them as much as we do.
The following table lists the videos that are currently available - note that more videos may be made available later, so make sure you check to see later!
Microsoft Dynamics NAV 2013 – Technical – NAV Cluster
This video shows how Microsoft Dynamics NAV 2013 behaves with NLB Clustering in a three-tier setup.
Microsoft Dynamics NAV 2013 – Technical – Unicode
This Video shows what’s new in Microsoft Dynamics NAV 2013 for Unicode and how it works for Unicode data.
Microsoft Dynamics NAV 2013 – Technical – SharePoint
This video explains how-to set up, configure and use the new Microsoft Dynamics NAV 2013 SharePoint client. It also highlights some of the client’s features as well as tips to debug the client using commonly used SharePoint debug methods.
Microsoft Dynamics NAV 2013 – Technical – SQL Filtering
This video demonstrates the different options for filtering data that are available in the Microsoft Dynamics NAV 2013 query object.
Microsoft Dynamics NAV 2013 – Technical – SQL Query Object
This video demonstrates creating and executing a typical Query object in Microsoft Dynamics NAV 2013.
Microsoft Dynamics NAV 2013 – Technical – SQL Queries with C/AL Code
This video demonstrates how to use a Microsoft Dynamics NAV 2013 query object in your C/AL code, including best practices tips.
Microsoft Dynamics NAV 2013 – Technical – SQL Joining Tables
This video demonstrates how to join multiple data items (tables) and filter results with a Microsoft Dynamics NAV 2013 query object.
Microsoft Dynamics NAV 2013 – Technical – Charts
This video shows how to create and modify a generic chart, and how to make a simple extended chart.
The Microsoft Dynamics NAV support team
“Our setup time is down from more than a week to only a few hours using RapidStart Services for Microsoft Dynamics NAV”
RapidStart Services for Microsoft Dynamics NAV has helped Microsoft partner, Abakion, deploy their Purchase Order Management solution much faster. A standard setup used to take them over a week. With RapidStart Services, implementation time is only a few hours.
RapidStart Services for Microsoft Dynamics NAV was introduced in response to customer demand for faster implementation. “Customers want to hear that it’s easy to convert data, so their transition to their new ERP system will be smooth,” says Claus Lundstrøm, Senior Product Manager at Abakion.
What’s the big idea?
The idea behind RapidStart Services was to enable companies to complete a setup with minimal training and to use ready-to-use data templates. This shortens the implementation time and allows customers to focus on their business, rather than getting caught up in a time-consuming system switch.
RapidStart Services, an integrated part of Microsoft Dynamics NAV, comes with standardized Configuration Packages and Questionnaires that make the Whole process faster. It also provides customers with a project overview and the ability to automate importing data from their old system using Master Data Import.
Data import is no longer a hassle
Abakion started using RapidStart Services for Microsoft Dynamics NAV to shorten their setup process and respond to the competitive situation.
“We learned how to use it quickly, and it has decreased our implementation time dramatically. Our Purchase Order Management add-on is now installed and configured at a customer site in only a few hours,” says Lundstrøm.
Abakion now uses Master Data Import to configure and set up their solution. Not only is the data imported, but all the details are taken care of as well. The company-specific imported data includes both user access rights and roles to determine what users have access to according to the role assigned to them.
“If the data could not be imported with RapidStart, it would take at least a week to setup manually,” Lundstrøm says.
Configuration templates save a lot of time
Companies can use out-of-the-box Configuration Packages in RapidStart Services in order to save time. This makes it fast and easy to configure generic data, such as currency codes, posting groups, VAT templates, chart of accounts, payment terms, and countries.
Existing Configuration Packages can always be extended later on, if needed. Companies can also choose to import their own customized Configuration Packages using Master Data Import.
Abakion used their own customized text templates and specific text for multiple languages, importing 30 different text templates in multiple languages.
About Abakion’s Purchase Order Management solution
Abakion’s Purchase Order Management is an add-on solution built on Microsoft Dynamics NAV, which allows for control over the changes in purchase orders within the environment of a portal hosted on Microsoft Azure.
Once the quotes/orders are created by the purchaser, they are then available in the portal, where vendors can update the information about a quote/order.
“Then, via the portal, the vendor can inform the purchaser if he can deliver on time. If he can only partially deliver, he can make changes to the order or quote,” says Lundstrøm,
The purchaser is automatically informed about all changes in Microsoft Dynamics NAV and can take necessary actions by looking at the overview of outstanding quotes and orders.
Assembly Management was released as part of Microsoft Dynamics NAV 2013, and it includes a set of features designed for companies that supply products to their customers bycombining components in simple processes, such as assembly, light manufacturing, and kitting.
Before the Microsoft Dynamics NAV 2013 release, customers and partners in selected regions and countries, such as North America, France, and Australia, may have been familiar with a similar local functionality called Kitting. The uptake of Kitting in those geographies has been both the driver and inspiration behind the global Assembly Management feature. Its value proposition and the functional breadth have been closely investigated and appreciated by the NAV core development team, resulting in Kitting’s key business and user requirements laying the conceptual foundation for the new Assembly Management feature.
To ensure the quality of the new global Assembly Management feature as well as its solid integration into the existing supply chain suite, the core development team produced aphysical and conceptual design that differed significantly from the one in Kitting. The differences are many. While Kitting used the BOM journal to manage the assembly process, Assembly Management operates with the concept of assembly order, which offers more functional flexibility, better user interface and extensibility. Last, but not least, assembly order offers more superior integration points to the rest of inventory, such as availability calculations and order promising, item tracking, supply planning, warehousing, and costing. This is understandable because the BOM journal, like any other journal in the application, is different from an order in its flexibility and scope, with the BOM Journal’s main goal being to support users in quick data entry for a subset of specialized transactions, while bypassing any auxiliary inventory processes.
With the introduction of the assembly order, the BOM journal was deemed unnecessary. This also meant that a disassembly process, which the BOM journal partially supported, wouldhave to be redesigned in Assembly Management along the same principles as the common assembly process. More specifically, a disassembly order to manage a reverse conversion process, i.e. from one item to many, would need to be added and integrated to the same supply chain features that the assembly order integrates to (see above). The disassembly order was not included in Microsoft Dynamics NAV 2013.Customers, who assemble their items themselves (as opposed to purchasing them from outside or getting them back through returns), and who need to reverse the previously made assembly, can use the new Undo Assembly function.
The option of keeping the BOM journal in the application for the sake of disassembly was rejected for several reasons:
a) Though useful in some scenarios, the actual BOM journal support for a disassembly process was limited to automatic creation of negative and positive adjustments for finished items and components respectively.
b) Its handling of cost flows required serious improvement.
c) As pointed out earlier, a journal line offers no integration to other parts of the inventory processes.
The core development team will be evaluating the possibility of including a properly designed disassembly feature in the future NAV releases. Kitting customers that used the BOM journal for their disassembly tasks should approach their partners for a discussion of reintroducing a journal for disassembly scenarios. The core development team will make no design recommendations in this regard.
For more information, see Assemble Items in the MSDN Library.
The NAV Supply Chain team