BarCodeWiz Logo

Create QR Code Barcodes in TLV Format in Crystal Reports

QR Code Barcodes with TLV encoding in Crystal Reports

  • This tutorial shows how to add QR Code barcodes encoded with TLV (Tag-Length-Value) for use with E-Invoicing to your Crystal Reports.
  • This tutorial is for Crystal Reports v.9.0 or higher.

Step 1. Add a new formula

In the Field Explorer, right click Formula Fields and click New...


Enter a name for the new formula


Step 2. Verify the QR Code functions

  • Ensure the functions are installed. May be listed under one of these three locations:
    Functions > Additional Functions
    Functions > Additional Functions > Visual Basic UFLs (u2lcom.dll)
    Functions > Additional Functions > COM and .NET UFLs (u212com.dll)
  • If missing, install the User Function Library

Step 3. Copy the formula text

// Replace the following values with your own. All fields must be strings or converted to strings using ToText().
// You can use your own data fields. For example: 
// local stringVar invoiceTotal := ToText({my_data_table.invoice_total});

local stringVar sellersName := "Firoz Ashrafi";
local stringVar vatNumber := "1234567890";
local stringVar timestamp := ToText(CurrentDateTime);
local stringVar invoiceTotal := ToText(100.00);
local stringVar vatTotal := ToText(22.00);

local numberVar array tags := [1, 2, 3, 4, 5];
local stringVar array values := [sellersName, vatNumber, timestamp, invoiceTotal, vatTotal];

local numberVar valuesCt := Count(values);

local stringVar hexString := "";
numberVar v;
for v := 1 to valuesCt do
(
    // Convert text to UFT-8 bytes as hex
    local stringVar thisHex := "";
    
    local numberVar x;
    for x := 1 to Length(values[v]) do
    (
        thisHex := thisHex & CharWToUtf8Hex (ascW(Mid(values[v], x, 1)));
    );
    
    hexString := hexString + CharWToUtf8Hex(tags[v]); // add tag
    hexString := hexString + CharWToUtf8Hex(Int(Length(thisHex)/2)); // add length in bytes
    hexString := hexString + thisHex; // add the value
);

local stringVar base64Vals := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; // 65th character is = (pad)
local stringVar hexVals := "0123456789ABCDEF";

local numberVar hexLength := Int(length(hexString) / 2);

// Convert to base64 text
local stringVar base64Str := "";
local numberVar i;
for i := 1 to hexLength step 3 do
(
    local stringVar firstHex := Mid(hexString, i*2 - 1, 2);
    local stringVar secondHex := Mid(hexString, i*2 + 1, 2);
    local stringVar thirdHex := Mid(hexString, i*2 + 3, 2);

    local numberVar first1 := Int( (Instr( hexVals, Mid(firstHex, 1, 1))-1) * 16 + Instr( hexVals, Mid(firstHex, 2, 1))-1);
    local numberVar second1 := Int( (Instr( hexVals, Mid(secondHex, 1, 1))-1) * 16 + Instr( hexVals, Mid(secondHex, 2, 1))-1);
    local numberVar third1 := Int( (Instr( hexVals, Mid(thirdHex, 1, 1))-1) * 16 + Instr( hexVals, Mid(thirdHex, 2, 1))-1);

    local numberVar total := first1 * 256 * 256 + second1 * 256 + third1;

    local numberVar outFirst := Int( total / (262144) );
    local numberVar remFirst := Remainder(total, 262144);
    local numberVar outSecond := Int( remFirst / 4096 );
    local numberVar remSecond := Remainder(remFirst, 4096);
    local numberVar outThird := IIf( i+1 <= hexLength,  Int( remSecond / 64 ), 64);
    local numberVar outFourth := IIf( i+2 <= hexLength, Remainder(remSecond, 64), 64);

    base64Str := base64Str + Mid(base64Vals, outFirst+1, 1) & Mid(base64Vals, outSecond+1, 1) & Mid(base64Vals, outThird+1, 1) & Mid(base64Vals, outFourth+1, 1);
);

// Create QR Code

local stringVar barcodeInput := base64Str;

 // Minimum size of QR Code symbol.
 // Valid sizes are 1-40, where size 1 equals 21x21 modules per side and size 40 equals 177x177.
 // Note: Size of symbol will automatically increase if too small for the data.
numberVar symbolSize := 1;            
	  
 // Error correction level allows a partially damaged barcode to be scanned successfully.
 // Valid values are 1-4, representing levels of L, M, Q, and H.
numberVar errorCorrectionLevel := 1;

 // Allows input of special characters in format ^000 where 000 is decimal ASCII code. 
 // For example, ABC^009123^013^010 encodes "ABC[TAB]123[CARRIAGE RETURN][LINE FEED]".
 // To encode the actual caret ^, enter it twice: ^^
 // To encode FNC1, enter: ^F1
booleanVar allowSpecialChars := true;

 // Determines what type of QR Code barcode to create.
 // Set fnc1Mode to 0 to create "regular" QR Code barcodes (default)
 // Set fnc1Mode to 1 to create GS1-QR barcodes.
 // GS1-QR barcodes require input to be in the format: "(NN)XXXXXX(NN)XXXXXXXXX",
 // where NN is a 2, 3, or 4-digit AI and XXXXXX is alphanumeric data to be encoded.
numberVar fnc1Mode := 0; 

 // Thickness of quiet zone (space around barcode), in number of modules.
 // Note: Minimum quiet zone in QR Code is 4 modules. If you add a border (borderWidth > 0), ensure quietZoneWidth is 4 or larger.
 // Default value is 0 (no quiet zone)
numberVar quietZoneWidth := 0; 

 // Thickness of border around barcode, in number of modules.
 // If using a border, ensure quietZoneWidth is 1 or larger.
numberVar borderWidth := 0; 

 // Character encoding for data encoded in the QR Code symbol. 
 // The recommended setting is UTF-8, which is the default for the majority of barcode scanners.
 // If you change the setting, be sure the scanner understands it.
stringVar characterOutputEncoding := "UTF-8";


stringVar fullBarcode := "";
numberVar partNumber := 0;

local stringVar result;
Do 
(
    result := QrCodeEncode(partNumber, barcodeInput, symbolSize, errorCorrectionLevel, allowSpecialChars, 
                                            fnc1Mode, quietZoneWidth, borderWidth, characterOutputEncoding);
    fullBarcode := fullBarcode + result;
    partNumber := partNumber + 1;
)
While result <> "";


fullBarcode;

 


Step 4. Edit the formula:

// Replace the following values with your own. All fields must be strings or converted to strings using ToText().
// You can use your own data fields. For example:
// local stringVar invoiceTotal := ToText({my_data_table.invoice_total});

local stringVar sellersName := "Firoz Ashrafi";
local stringVar vatNumber := "1234567890";
local stringVar timestamp := ToText(CurrentDateTime);
local stringVar invoiceTotal := ToText(100.00);
local stringVar vatTotal := ToText(22.00);

 

 


Click Save and Close.


Step 5. Add a barcode to the report

Drag the formula from Field Explorer to the report.


Step 6. Edit the text field

  • Change the font to: BCW_QR and set the point size.

 NOTE:  For smaller barcodes, you can set the point size as low as 2pt

Select BCW_QR as a font and the size of 6

Right-click and select Format Field...


Select Can Grow on the Common tab


The report is now ready

Click on Preview to see or print it.