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! :)
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
Post a Comment