Skip to main content

Barcode printing and scanning ax 2012 | Useful links & material

I came across client's requirement to integrate barcode scanner and printer with AX in their production process. So inventory in (pick list generation) was done using barcode scanner, and at the end of each process (RAF journal) production sticker is generated with Item id and its batch number.

First of all, le tme tell you that barcode scanner is just like an external keyboard attached to system, its drive gets auto-installed in windows (I tried on windows 7). As soon as driver gets installed yoou can test the scanner by opening a notepad and scanning some barcode, which will input contained information on notepad. Same would be the case in AX. You just need to place cursor on a field and scan the barcode. No integration tool required whatsoever. So it's pretty simple and easy.


I used custom code to generate code39 barcode, and added a table field (with EDT barcodeStr) to save barcode string having item and batch number separated by % symbol, so I might be able to parse the string after scanning. So the encoded string looks like: *itemId%batchNumber*.

Following methods were written to encode barcode string and then parse it.

/// <summary>
///    Displays barcode containing item id & batch number.
/// </summary>
/// <returns>
///    A Barcode containing item id & batch number.
/// </returns>
public display IhlBarcodeStr displayBarcode()
{
    return "*" + this.itemId + "%" + this.inventBatchId + "*";
}

static void BARCODEGenerated(Args _args)
{
    //BP Deviation documented
    Barcode         barcode;
    IhlBarcodePOC   barcodeTable;
    ;

    barcode = Barcode::construct(BarcodeType::Code39);
    barcode.string(true, "ItemId%BatchNumber");
    barcode.encode();

    info(barcode.barcodeStr());
    info(barcode.barcodeStrHR());

    barcodeTable.IhlBarcodeString = barcode.barcodeStr();
    barcodeTable.IhlBarcodeNumber = barcode.barcodeStrHR();
    barcodeTable.insert();
}

private str parseBarcodeValue(str _barcodeValue, str _splitchar, int _pos)
{
    List strlist = new List(Types::String);
    ListIterator    iterator;
    container       packedList;

    strlist = strSplit(_barcodeValue, _splitchar);
    iterator = new ListIterator(strlist);
    while(iterator.more())
    {
        packedList += iterator.value();
        iterator.next();
    }
    return conPeek(packedList, _pos);
}

I wanted to generate pick list using scanner, so i wrote the code in;
* data source create() method: to set focus on item id using controlName.setFocus();
* itemId modified() method: I wanted to get quantity against the selected batch, so added a query to fetch physical quantity from on-hand inventory (InventSum) in this method.
* validate() method: I parsed the scanned value (ItemId%BatchNumber) and places item id on item id field and batch number on its respective field before the super() of validate method.
   
InventSum       localInventSum;
    real            batchQuantity = 0;
    ProdJournalBOM  localProdJournalBOM;
    str             itemValue, batchValue;
    int             found = 0;
    str             barcodeValue = this.getValue();
    DialogButton    diagBut;
    str             strMessage = "Consumption quantity exceeds proposed quantity, continue?";
    str             strTitle = "Warning!";

    found = strscan(barcodeValue, "%", 0, strlen(barcodeValue));

    if (found)
    {
        itemValue = this.parseBarcodeValue(this.getValue(), "%", 1);
        batchValue = this.parseBarcodeValue(barcodeValue, "%", 2);

        ProdJournalBOM_ds.object(fieldNum(ProdJournalBOM, tmpBatchId)).setValue(batchValue);
        this.setValue(itemValue);
    }

    if (found)
    {
        // update consumed quantity in automatically created journal line
        select forUpdate localProdJournalBOM
            where localProdJournalBOM.ProdId == ProdJournalBOM.ProdId &&
                  localProdJournalBOM.ItemId == this.getValue() &&
                  localProdJournalBOM.BOMProposal != 0;
        {
            if (localProdJournalBOM.RecId)
            {
                batchQuantity = InventSum::find(ProdJournalBOM.ItemId,
                                                InventDim::findDim(InventDim).inventDimId).physicalInventCalculated();
                ttsBegin;
                //localProdJournalBOM.delete();
                if ((localProdJournalBOM.BOMConsump - batchQuantity) >= 0)
                {
                    localProdJournalBOM.BOMConsump -= batchQuantity;
                    localProdJournalBOM.update();
                    ttsCommit;
                }
                else
                {
                    diagBut = Box::yesNoCancel(
                        strMessage,
                        DialogButton::Yes, // Initial focus is on the No button.
                        strTitle);
                    if (diagBut == DialogButton::No)
                    {
                        ttsAbort;
                        break;
                    }
                    else
                    {
                        localProdJournalBOM.BOMConsump -= batchQuantity;
                        localProdJournalBOM.update();
                        ttsCommit;
                    }
                }
            }
        }

        // create new line and set focus on item id for next scan
        ProdJournalBOM_ds.create(true);
    }


While my search on the internet regarding scanning and printing, I found some useful links, pasted below:
http://dynamicsuser.net/forums/t/49594.aspx
http://dynamicsuser.net/forums/p/33738/177385.aspx
http://kurthatlevik.wordpress.com/2012/05/24/enable-dynamics-ax-2012-bartender-integration/
http://www.andesoft.net/algorithm-get-ean13-code-ax2012/
http://erptechnician.net/2012/04/30/printing-barcodes-microsoft-dynamics-ax-2009/


To program your scanner (i was using LS-2208 motorola) to append <enter> or <tab> key visit following links or use the manual of the scanner:
http://www.barcodesinc.com/news/?p=507
http://www.manualslib.com/manual/467366/Motorola-Ls2208-7azu0100zr-Symbol-Ls2208-Wired-Handheld-Barcode-Scanner.html

It was fun working on barcode scanning and printing! :)

Comments

Popular posts from this blog

Run SSRS report using x++ code | AX 2012

This post describes how to run an SSRS report through x++ code and passing report parameters as well. Its a simple code and comments are added for further ease in code understanding! public static void runSSRSReport() {     SrsReportRunController controller;             controller = new SrsReportRunController();     controller.parmLoadFromSysLastValue(false);      // write report name and its design in quotes that you want to run     controller.parmReportName("ReportName.DesignName");      // set additional, optional properties like setting landscape to true     controller.parmReportContract().parmPrintSettings().landscape(true);          // set print destination screen/printer/file etc.     controller.parmReportContract().parmPrintSettings().printMediumType (SRSPrintMediumType::S...

Get Position and Department of an employee | AX 2012

A simple job to get position/designation and department of an employee using employee id: static void WorkerPositionDepartment(Args _args) {     HcmWorker                       hcmWorker;     HcmPositionWorkerAssignment     hcmPositionWorkerAssignment;     OMOperatingUnit                 oMOperatingUnit;     HcmPositionDetail               hcmPositionDetail;     HcmJob                          hcmJob;     HcmPosition             ...

Creating BOM journal using code AX 2012

courtesy: http://www.andesoft.net/creating-bom-journal-using-x-code-ax-2009-ax-2012/ https://community.dynamics.com/ax/f/33/t/96262.aspx http://learnax.blogspot.com/2010/01/x-code-to-create-and-post-inventory.html static void createBomJournal_working(Args _args) {     InventJournalTable      journalTable;     InventJournalTrans      journalTrans;     InventJournalTableData  journalTableData;     InventJournalTransData  journalTransData;     InventTable             inventTable;     InventDim               inventDim;     Counter                 cnt;     InventJournalCheckPost  journalCheckPost = new InventJournalCheckPost();     InventTransId           inventTransId, inventTransIdFather;     InventBat...