I wasn’t willing to pay $49, $99, or $199 to add barcodes to my databases. Luckily, we don’t have to pay for something that we can do ourselves for free!
The first step will be to insert a custom function the converts ASCII text into Code 128, which requires both a check sum and character conversion. I have supplied the necessary code at the bottom of this post, and even though it’s not my code, it’s quite awesome. Just save it as a custom function in your database with the name “cfCode128” and with inputs “pString” and “pCodeSet”.
So once you have the function setup, use it to convert data in a field and apply a Code 128 font, like this one.
Advanced Code 128 Specifications
Code 128 has three different “flavors” to choose from: A, B and C.
- A: Numbers and only uppercase ASCII, but can use ASCII control chars (TAB, CR/LF etc.)
- B: Numbers and full ASCII, but no ASCII control chars
- C: Only numbers 0-9, but encoded so very compact!
If you chose type “A” then you will have access to special operators within your barcode. This is useful if you know exactly how and where the barcode will be used (like data entry), so you can prepare barcodes that are almost like mini programs to increase your productivity. The three most commonly accepted inputs are:
- i – Tab (horizontal tab)
- j – New Line (line feed)
- m – Return (carriage return)
You can find the whole list on Wikipedia.
We have two sets of data, product ID and quantity, and we want to put a tab character between the two sets of data. In FileMaker our base code would look like this:
product ID & "i" & quantity
But, we want to make sure product ID and quantity are always in uppercase:
Upper (product ID) & "i" & Upper (quantity)
I also like to remove all formatting before converting, just in case. If your data is already clean, you won’t need this:
Upper (TextFormatRemove (product ID)) & "i" & Upper (TextFormatRemove (quantity))
Then convert it all to a Code 128 string through the custom function:
cfCode128 (Upper (TextFormatRemove (product ID)) & "i" & Upper (TextFormatRemove (quantity)) ; "A")
Your output code should now be useable with a Code 128 barcode font. Just adjust the font size, apply and print!
/* cfCode128 ( pString; pCodeSet ) ---use with FM version >= 10--- composes the final barcode Code128 of symbology A,B or C from a given alphanumeric string. includes the checksum of the string (modulo 103) as well as start/stop characters. this CF is meant to be used with barcode font "IDAutomationC128..." http://www.advancemeants.com/code128fonts/download.htm automatic switching between variants A,B,C within a single barcode is not yet supported. pString: string to be used as a barcode. pCodeSet: "A" or "B" or "C" are expected. local var $i stores the actual count of loops. be careful, $i var should not be used in a script running at the same time. all vars (although locally stored) should be destroyed when the process is done. author: tammo fornalik / felix hausberner, dbyte solutions, 01.06.2008 changes: 10.01.2009, Code() and Char() are now native functions in FM10, replaced references to CFs which did that job. type: recursive dependencies: none call like: cfCode128( "SBM16672_2008_08_25"; "B" ) */ //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> String is empty -> no output Case( IsEmpty( pString ); "" //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CodeSet A, B ; pCodeSet = "A" or pCodeSet = "B"; Let( [ vInitOnce = Case( IsEmpty( $i ); //the following inits are only processed during initial call Let( [ $C128_Start = Char( Case( pCodeSet = "A"; 203; pCodeSet = "B"; 204; 0 ) ); //defined by C128 specs $C128_Stop = Char( 206 ); //defined by C128 specs $DataToEncode = Trim( pString ); $WeightedTotal = Code( $C128_Start ) -100; //font specific $C128_CheckDigit = "w"; //font specific, on internal error $i = 0 ]; "" ); //end let "" ); //end case $i = $i +1; //get the value of each character. calculate the WeightedTotal for modulo 103 checksum. vCurrentChar = Code( Middle( $DataToEncode; $i; 1 ) ); vCurrentVal = Case( vCurrentChar < 135; vCurrentChar -32; vCurrentChar > 134; vCurrentChar -100 ); vCurrentVal = vCurrentVal * $i; $WeightedTotal = $WeightedTotal + vCurrentVal ]; Case( $i < Length( $DataToEncode ); cfCode128( $DataToEncode; pCodeSet ); //recursion Let( [ //divide the WeightedTotal by 103 and get the remainder, this is the CheckDigitValue vChkDigitVal = Mod( $WeightedTotal; 103 ); //map CheckDigit to font specific chars $C128_CheckDigit = Char( Case( vChkDigitVal = 0; 194; vChkDigitVal < 95 and vChkDigitVal > 0; vChkDigitVal +32; vChkDigitVal > 94; vChkDigitVal +100 ) ); $DataToEncode = Substitute ( $DataToEncode; Char( 32 ); Char( 194 ) ); //replace the spaces with the 194 character, font specific vPrintableString = $C128_Start & $DataToEncode & $C128_CheckDigit & $C128_Stop; $C128_Start=""; $C128_Stop=""; $DataToEncode=""; $C128_CheckDigit=""; $WeightedTotal=""; $i="" //kill vars ]; vPrintableString ) //end let ) //end case ) //end let //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CodeSet C ; pCodeSet = "C"; Let( [ vInitOnce = Case( IsEmpty( $i ); Let( [ $C128_Start = Char( 205 ); $C128_Stop = Char( 206 ); $DataToEncode = Filter( pString ; "0123456789" ); vCountOfDigitsIsOdd = Mod( Length( $DataToEncode ); 2 ) = 1; $DataToEncode = Case( vCountOfDigitsIsOdd; "0"; "" ) & $DataToEncode; $DataToPrint = ""; $WeightValue = 0; $WeightedTotal = Code( $C128_Start ) -100; $C128_CheckDigit = "w"; $i = -1 //...so the first used value will be 1 ]; "" ); //end let "" ); //end case $i = $i +2; $WeightValue = $WeightValue +1; vCurrentChar = Middle( $DataToEncode; $i; 2 ); $DataToPrint = $DataToPrint & Case( vCurrentChar < 95 and vCurrentChar > 0; Char( vCurrentChar +32 ); vCurrentChar > 94; Char( vCurrentChar +100 ); vCurrentChar = 0; Char( 194 ) ); $WeightedTotal = $WeightedTotal + (vCurrentChar * $WeightValue) ]; Case( $i < Length( $DataToEncode ); cfCode128( $DataToEncode; pCodeSet ); //recursion Let( [ vChkDigitVal = Mod( $WeightedTotal; 103 ); $C128_CheckDigit = Char( Case( vChkDigitVal < 95 and vChkDigitVal > 0; vChkDigitVal +32; vChkDigitVal > 94; vChkDigitVal +100; vChkDigitVal = 0; 194 ) ); vPrintableString = $C128_Start & $DataToPrint & $C128_CheckDigit & $C128_Stop; $C128_Start=""; $C128_Stop=""; $DataToEncode=""; $DataToPrint=""; $WeightValue=""; $C128_CheckDigit=""; $WeightedTotal=""; $i="" ]; vPrintableString ) //end let ) //end case ) //end let ) //end case