Logic App: Converting CSV format table into custom delimiter column separator format

Nowadays logic apps are commonly used for data integration, especially for the Microsoft product. It allows an easy way to transport data from one system to another target system or file storage.

Most systems accept Xls or CSV file to migrate data but so is not the case in all cases. Recently I came across the requirement to separate columns with Tab delimiters. Unfortunately, there is no connector out of the box in the logic app available to convert the table and separate it with a custom delimiter.

Finally, I got a hack to achieve this target: The first step creates a CSV table with the data coming from the data source

As mentioned, we do not have any standard connector to convert with custom delimiter. We will initialize a variable connector. Then we will set a value of variable with following expression:

replace(body('Create_CSV_table'), decodeUriComponent('%2c'), decodeUriComponent('%09'))

or

replace(body('Create_CSV_table'),',','    ')

In replace function I’m taking ‘create CSV table’ as input and then replacing all the “,” with the custom delimiter required.

I hope above information shared is helpful

Do share your feedback with me
Mhq_hassan@hotmail.com

Label design and printing, using Zebra Printer on D365 Fin Ops

This blog will cover, how we can design label using Zebra Printer Lable (ZPL) programming. Learning ZPL specifically for Dynamics 365/AX developer from stretch is an addionaly task. When you just want to create/design 1 label. In this article I’ll discuss how we can design label using 3rd party designer available and generate ZPL code.

Zebra printer design and printing require 3 basic things:
1. Setup printer
2. Design label
3. Printing label from AX/D365

Setup printer:
First of install zebra printer driver on system and make sure it also install zebra printer fonts.
Link setup: https://www.zebra.com/us/en/support-downloads/printers.html
After the driver is install configure printer using document routing agent, so we can give printing job/task from D365/AX.
Go to links for configuration:
Configure Printer on D365

In case printer is not available then follow link to configure zebra printer emulator.

Designing Label:

There so many Zebra label designer available, But I’ll use NiceLabel Designer 2019 for designing and generating code.

Download: https://www.nicelabel.com

Open nice label, do label page setup by clicking on create new label

Design your label as according to your requirement through designer tools available.

I have designed a demo label for this article. There are few things that needs to be taken care:

  1. When ever Textbox or barcode is use. Always select Font type starting with “Zebra” these fonts are specially for zebra printer and zebra printer programing is also easy when these special fonts are used.
  2. Set placeholder value for each textbox and barcode. This will be helpful to set values runtime on object/places on label. Placeholder can be defined by so many ways there is no specific instructions. In my case I’m defining placeholder in between “%” for e.g %placeholderName%. Example can be also seen on screenshot.

Once design is complete, we will export designer ZPL code.

Click on print icon

Print dialog will open. Select “Print to file” and click on Print. This will open “Save File” dialog. Save code in your desire folder. File with “.prn” extension will be saved.

Before jumping directly to print, we will verify code on online viewer.

Go to link: http://labelary.com/viewer.html

Open code file on this link.

You can see design is as according code. Let me explain some code objects so this will made easy to make changes directly on code.

^FT: This sets the field position on label. If you want to change position of then change values on ^FT tag.
Format: ^FTx,y,z

“x” and “y” are position on label, it will have numeric values. “Z” is use to define justification but normally we do not use it. 

Example: ^FT89,118

^FB: it is used to define field block. In this you will define width, height, alignment and character spacing.
Format: ^FBa,b,c,d,e

“a” defines width of field box.

“b” defines no of line in box.

“d” defines alignment. Values could be L (left), C (center), R(right), J (justify) and default value is L.

Example: ^FB213,1,0,C

^A: this command is use to set the font size and type in ZPL code.
Format^Afo,h,w
“f” defines font name values range from 0 – 9 or A through Z. Default values is 0

“o” defines orientation. Normally “N” is used.

“h” defines height of font.

“w” defines width of font.

Example: ^A0N,13,12

^BQ: This command is used to show QR code (For different type of bar codes code command is different).

Format: ^BQa,b,c,d,e 

“a” defines field orientation default value is “N”

“b” defines model default value is “2”

“c” defines magnification. You can enlarge your QR code by setting value here. Values range between 1 – 10. Default values are: 1 on 150 dpi printers, 2 on 200 dpi printers, 3 on 300 dpi printers and 6 on 600 dpi printers
Example: ^BQN,2,3

^FS: This command is used to define end of field definition. This will be used when every field is end.

Example: ^FT15,27^A0N,13,12^FB213,1,0,C^FH\^FD%LabelTitle%^FS

Line break:
There is no specific command which can help you in giving line break between the lines in large string. To achieve this, you need to add new Field command between the text at runtime. You have to find the place on string which needs to be on new line then you have to calculate the “Y“ position (position on label, where new line will start otherwise it will overwrite current line). 

For example: I have two lines which I want to print on label. After each sentence I want to give line break. “Hi, my name is Hassan.I’m a dynamics Ax/D365 technical consultant. “

In ZPL code:

^FO16,100^A0N,20,19^FB530,12,0,J,0^FDHi, my name is hassan.^FS^FO16,120^A0N,20,19^FB530,12,0,J,0^FDI’m a dynamics Ax/D365 technical consultant^FS

before 2nd sentence there is a code/command “.^FS^FO16,120^A0N,20,19^FB530,12,0,J,0^FD”
In which ^FO16,120: 120 is Y position, where for first sentence Y position was 100
This thing can be manage through x++ coding, write a logic which iterate string and add new line command where it is need and calculate Y position based on number of lines. In my case 1 line take 20 points.

Printing label from AX/D365

Last thing is calling printing job from AX/D365 because end user will perform printing activity on from Dynamics. Zebra printing task require runtime resolution over the internet. On FinOps out of the box it only works for advance warehouse module. But you don’t need to care about this because we just need to call one method.

Code:

str labelLayout = "CT~~CD,~CC^~CT~^XA~TA000~JSN^LT0^MNW^PON^PMN^LH0,0^JMA^PR5,5~SD15^JUS^LRN^CI^XZ^XA^MMT^PW240^LL0240^LS0^FO8,4^GB225,141,2^FS^FO9,40^GB221,0,2^FS^FT89,118^BQN,2,3^FH\^FDLA,%barCode%^FS^FT15,27^A0N,13,12^FB213,1,0,C^FH\^FD%LabelTitle%^FS^FO9,114^GB221,0,2^FS^FT15,133^A0N,13,12^FB213,1,0,C^FH\^FD%Instructions%^FS^PQ1,0,1,Y^XZ";

labelLayout = strreplace(labelLayout, "%LabelTitle%", "Test Label");
labelLayout = strreplace(labelLayout, "%barCode%", "123456");
labelLayout = strreplace(labelLayout, "%Instructions%", "My label printing blog");
WHSDocumentRouting::printLabelToPrinter("Zebra Test Emulator", labelLayout);

I initialize string variable with ZPL code. Then replace placeholder set on printing objects with the actual values that need to be print on label. In last we call print label task by calling “printLabelToPrinter” in WHSDocumentRouting framework class. It takes two parameter first printer name and second label code.

I hope this blog will be helpful.

Do give your feedback and feel free to contact me on:
Email: mhq_hassan@hotmail.com
LinkedIn: https://www.linkedin.com/in/muhammadhassannaviwala/

Special thanks to my colleagues
Muhammad Usama Yameen (Usama.Yameen@mazikglobal.com)
Mustafa Ali Asghar (mustafa.ali@mazikglobal.com)

Generate invent batch Id programmatically in d365/x++

Following code can be used to create invent batch id for production order.

static InventBatchId generateActiveInventBatch(
        ProdTable     _prodTable)
    {
        InventBatchId  inventBatchId;
        InventBatch    inventBatch;
        NoYes          isBatchActive;
        InventNumGroup inventNumGroup;

        FieldId checkInventBatch = fieldNum(InventDim, InventBatchId);

        try
        {
            isBatchActive   = ecoResTrackingDimensionGroupFldSetup::findByDimensionGroupFieldId(InventTable::find(_prodTable.ItemId).trackingDimensionGroup(), checkInventBatch).IsActive;

            if (isBatchActive)
            {
                inventNumGroup = InventNumGroup::find(InventTable::find(_prodTable.ItemId).BatchNumGroupId);

                inventbatchId  = inventNumGroup.buildNumberParameters(DateTimeUtil::date(_prodTable.CreatedDateTime), _prodTable.ProdId, _prodTable.InventTransId, extendedTypeNum(InventBatchId));

                inventBatch    = InventBatch::findOrCreate(inventbatchId, _prodTable.ItemId);
            }
        }
        catch (Exception::Error)
        {
            inventBatchId = "";
        }

        return inventBatchId;
    }
Design a site like this with WordPress.com
Get started