here is the modified working code for the _code128() function to print GS1-128 compliant barcodes.
The function now allows insertion of FNC1 symbol (ALT+0202) both at the beginning and as a separator character:
<code>
static aCode :={"212222",;
"222122",;
"222221",;
"121223",;
"121322",;
"131222",;
"122213",;
"122312",;
"132212",;
"221213",;
"221312",;
"231212",;
"112232",;
"122132",;
"122231",;
"113222",;
"123122",;
"123221",;
"223211",;
"221132",;
"221231",;
"213212",;
"223112",;
"312131",;
"311222",;
"321122",;
"321221",;
"312212",;
"322112",;
"322211",;
"212123",;
"212321",;
"232121",;
"111323",;
"131123",;
"131321",;
"112313",;
"132113",;
"132311",;
"211313",;
"231113",;
"231311",;
"112133",;
"112331",;
"132131",;
"113123",;
"113321",;
"133121",;
"313121",;
"211331",;
"231131",;
"213113",;
"213311",;
"213131",;
"311123",;
"311321",;
"331121",;
"312113",;
"312311",;
"332111",;
"314111",;
"221411",;
"431111",;
"111224",;
"111422",;
"121124",;
"121421",;
"141122",;
"141221",;
"112214",;
"112412",;
"122114",;
"122411",;
"142112",;
"142211",;
"241211",;
"221114",;
"213111",;
"241112",;
"134111",;
"111242",;
"121142",;
"121241",;
"114212",;
"124112",;
"124211",;
"411212",;
"421112",;
"421211",;
"212141",;
"214121",;
"412121",;
"111143",;
"111341",;
"131141",;
"114113",;
"114311",;
"411113",;
"411311",;
"113141",;
"114131",;
"311141",;
"411131",;
"211412",;
"211214",;
"211232",;
"2331112"}
function _code128(cCode,cMode)
local nSum:=0, cBarra, cCar
local cTemp, n, nCAr, nCount:=0
local lCodeC := .f. ,lCodeA:= .f.
// control de errores
if valtype(cCode) !='C'
alert('Barcode c128 required a Character value. ')
return nil
end
if !empty(cMode)
if valtype(cMode)='C' .and. Upper(cMode)$'ABC'
cMode := Upper(cMode)
else
alert('Code 128 Modes are A,B o C. Character values.')
end
end
if empty(cMode) // modo variable
// an lisis de tipo de c¢digo...
if str(val(cCode),len(cCode))=cCode // s¢lo n£meros
lCodeC := .t.
cTemp:=aCode[106]
nSum := 105
else
for n:=1 to len(cCode)
#ifdef OLDOLD //
r.c. mod
: 09/11/2023
nCount+=if(substr(cCode,n,1)>31,1,0) // no cars. de control
#else
nCount += if( asc(substr( cCode, n, 1 )) > 31, 1, 0 ) // no cars. de control
#endif
end
if nCount < len(cCode) /2
lCodeA := .t.
cTemp := aCode[104]
nSum := 103
else
cTemp := aCode[105]
nSum := 104
end
end
else
if cMode =='C'
lCodeC := .t.
cTemp:=aCode[106]
nSum := 105
elseif cMode =='A'
lCodeA := .t.
cTemp := aCode[104]
nSum := 103
else
cTemp := aCode[105]
nSum := 104
end
end
//tracelog("Print Code 128",cCode,cMode,lCodeA,lCodeC)
nCount := 0 // caracter registrado
for n:= 1 to len(cCode)
nCount ++
cCar := substr(cCode,n,1)
#ifdef OLDOLD // r.c. mod. 10/11/2023
if lCodeC
#else
if cCar == "Ê" // <fnc1> ALT+0202
nCar := 103 // r.c. add: FNC1 - 10/11/2023
elseif lCodeC
#endif
if len(cCode)=n // ultimo caracter
CTemp += aCode[101] // SHIFT Code B
nCar := asc(cCar)-31
else
nCar := Val(substr(cCode,n,2))+1
n++
end
elseif lCodeA
if cCar> '_' // Shift Code B
cTemp += aCode[101]
nCar := asc(cCar)-31
elseif cCar <= ' '
nCar := asc(cCar)+64
else
nCar := asc(cCar)-31
endif
else // code B standard
if cCar <= ' ' // shift code A
cTemp += aCode[102]
nCar := asc(cCar)+64
else
nCar := asc(cCar)-31
end
endif
nSum += (nCar-1)*nCount
cTemp := cTemp +aCode[nCar]
next
nSum := nSum%103 +1
cTemp := cTemp + aCode[ nSum ] +aCode[107]
cBarra := ''
for n:=1 to len(cTemp) step 2
cBarra+=replicate('1',val(substr(cTemp,n,1)))
cBarra+=replicate('0',val(substr(cTemp,n+1,1)))
next
return cBarra
</code>
best regards
Roberto