ModulDataMatrix

Attribute VB_Name = „ModulDataMatrix“
Option Explicit

‚ creates Data Matrix barcode symbol as shape in Excel cell.
‚ param text to encode
‚ param rectangle boolean, default autodetect on cell dimension
‚ Data Matrix symbol creation according ISO/IEC 16022:2006
Public Function DataMatrix(text As String, Optional rectangle As Integer = -2) As String
Attribute DataMatrix.VB_Description = „Draw DataMatrix barcode“
Attribute DataMatrix.VB_ProcData.VB_Invoke_Func = “ \n18″
On Error GoTo failed
If Not TypeOf Application.Caller Is Range Then Err.Raise 513, „DataMatrix“, „Call only from sheet“
Dim enc As String, en As String, el As Long, k As Variant, l As Long
Dim h As Long, w As Long, nc As Byte, nr As Byte, shp As Shape
Dim fw As Integer, fh As Integer, i As Long, j As Long, b As Double
Dim c As Long, r As Double, s As Long, x As Long, y As Long, txt As String
Dim fColor As Long, bColor As Long, line As Long
fColor = vbBlack: bColor = vbBlack: line = xlHairline ‚ redraw graphic ?
For Each shp In Application.Caller.Parent.Shapes
If shp.Name = Application.Caller.Address Then
If shp.Title = text Then Exit Function ‚ same as prev ?
fColor = shp.Fill.ForeColor.RGB ‚ remember format
bColor = shp.line.ForeColor.RGB
line = shp.line.Weight
shp.Delete
End If
Next shp
txt = IIf(text = „“, “ „, utf16to8(text)): l = Len(txt)
For i = 1 To l ‚ ASCII mode encoding
c = Asc(Mid(txt, i, 1)): r = 0
If i < l Then r = Asc(Mid(txt, i + 1, 1))
If c > 47 And c < 58 And r > 47 And r < 58 Then
enc = enc + Chr((c – 48) * 10 + r – 48 + 130) ‚ 2 digits
i = i + 1
ElseIf (c > 127) Then ‚ extended char
enc = enc + Chr(235) + Chr(c – 127)
Else
enc = enc + Chr(c + 1)
End If
Next i
For x = 0 To 2 ‚ C40, TEXT and X12 modes encoding
k = Array(Array(230, 31, 0, 0, 32, 9, 32 – 3, 47, 1, 33, 57, 9, 48 – 4, 64, 1, 58 – 15, 90, 9, 65 – 14, 95, 1, 91 – 22, 127, 2, 96, 255, 1, 0), _
Array(239, 31, 0, 0, 32, 9, 32 – 3, 47, 1, 33, 57, 9, 48 – 4, 64, 1, 58 – 15, 90, 2, 64, 95, 1, 91 – 22, 122, 9, 97 – 14, 127, 2, 123 – 27, 255, 1, 0), _
Array(238, 12, 8, 0, 13, 9, 13, 31, 8, 0, 32, 9, 32 – 3, 41, 8, 0, 42, 9, 42 – 1, 47, 8, 0, 57, 9, 48 – 4, 64, 8, 0, 90, 9, 65 – 14, 255, 8, 0))(x)
b = 0: h = 0
en = Chr(k(0)) ‚ start switch
For i = 1 To l
If h = 0 And i = l Then Exit For
c = Asc(Mid(txt, i, 1))
If c > 127 And k(0) <> 238 Then
b = b * 40 + 1: b = b * 40 + 30
h = h + 2: c = c – 128 ‚ hi bit in C40 & TEXT
End If
For j = 1 To 90 Step 3 ‚ select char set
If c <= k(j) Then Exit For
Next j
s = k(j + 1) ‚ set
If s = 8 Or (s = 9 And h = 0 And i = l) Then
en = txt + txt
Exit For ‚ char not in set, next mode
End If
If s < 5 And h = 2 And i = l Then ‚Exit For ‚ last char in ASCII
b = b * 40: h = 3 ‚ add padding
i = i – 1
Else
If s < 5 Then b = b * 40 + s: h = h + 1 ‚ set
b = b * 40 + c – k(j + 2): h = h + 1 ‚ char offset
If h Mod 3 = 2 And k(0) <> 238 And i = l Then b = b * 40: h = h + 1 ‚ add padding
End If
Do While h > 2 ‚ pack 3 chars in 2 bytes
h = h – 3: r = 40& ^ h
c = Int(b / r) + 1
en = en + Chr((c \ 256) And 255) + Chr(c And 255)
b = b – c * r + r
Loop
Next i
en = en + Chr(254) ‚ return to ASCII
For i = i – h To l ‚ add last chars
c = Asc(Mid(txt, i, 1))
If (c > 127) Then en = en + Chr(235)
en = en + Chr((c And 127) + 1)
Next i
If Len(en) < Len(enc) Then enc = en ‚ take shorter
Next x

j = (l + 1) And -4: b = 0: en = Chr(240) ‚ switch to Edifact
For i = 1 To j
If i < j Then ‚ encode char
c = Asc(Mid(txt, i, 1))
If c < 32 Or c > 94 Then Exit For ‚ not in set
Else
c = 31 ‚ return to ASCII
End If
b = b * 64 + (c And 63)
If (i And 3) = 0 Then ‚ 4 data in 3 bytes
en = en + Chr(b \ 65536) + Chr((b \ 256) And 255) + Chr(b And 255)
b = 0
End If
Next i
If j > 0 And i > j Then
For i = i – 1 To l ‚ add last chars
c = Asc(Mid(txt, i, 1))
If (c > 127) Then en = en + Chr(235)
en = en + Chr((c And 127) + 1)
Next i
If Len(en) < Len(enc) Then enc = en ‚ take shorter
End If

en = Chr(231) ‚ Base256 encoding
If l > 250 Then en = en + Chr((l \ 250 + 37) And 255) ‚ len high byte
en = en + Chr((l Mod 250 + (149 * (Len(en) + 1)) Mod 255 + 1) And 255) ‚ low
For i = 1 To l ‚ data in 255 state algo
en = en + Chr((Asc(Mid(txt, i, 1)) + (149 * (Len(en) + 1)) Mod 255 + 1) And 255)
Next i
If Len(en) < Len(enc) Then enc = en ‚ take shorter

‚ compute symbol size
nc = 1: nr = 1: j = -1: b = 1: el = Len(enc) ‚ symbol size, regions, region size
If (rectangle = -1 Or (rectangle = -2 And (Application.Caller.MergeArea.Width * 3 > Application.Caller.MergeArea.Height * 4))) And el < 50 Then ‚ rectangular pattern ?
k = Array(16, 7, 28, 11, 24, 14, 32, 18, 32, 24, 44, 28) ‚ symbol width, checkwords
Do
j = j + 1: w = k(j) ‚ width w/o finder pattern
h = 6 + (j And 12) ‚ height
l = w * h / 8: j = j + 1 ‚ # of bytes in symbol
Loop While l – k(j) < el ‚ data fit in symbol ?
If w > 25 Then nc = 2 ‚ column regions
Else ‚ square symbol
w = 6: h = w
i = 2 ‚ size increment
k = Array(5, 7, 10, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 68, 84, _
112, 144, 192, 224, 272, 336, 408, 496, 620) ‚ checkwords
Do
If j = UBound(k) Then Err.Raise 514, „DataMatrix“, „Message too long“
j = j + 1
If w > 11 * i Then i = 4 + i And 12 ‚ advance increment
w = w + i: h = w
l = (w * h) \ 8
Loop While l – k(j) < el
If w > 27 Then nr = 2 * (w \ 54) + 2: nc = nr ‚ regions
If l > 255 Then b = 2 * (l \ 512) + 2 ‚ blocks
End If
s = k(j) ‚ checkwords
fw = w / nc: fh = h / nr ‚ region size

If el < l – s Then enc = enc + Chr(129): el = el + 1 ‚ first padding
Do While el < l – s ‚ add more padding
el = el + 1
enc = enc + Chr((((149 * el) Mod 253) + 130) Mod 254)
Loop

enc = enc + Space(s) ‚ compute Reed Solomon error detection and correction
Dim rs(70) As Integer, rc(70) As Integer ‚ RS code
Dim lg(256) As Integer, ex(255) As Integer ‚ log/exp table
s = s / b: j = 1
For i = 0 To 254
ex(i) = j: lg(j) = i ‚ compute log/exp table of Galois field
j = j + j: If j > 255 Then j = j Xor 301 ‚ GF polynomial a^8+a^5+a^3+a^2+1 = 100101101b = 301
Next i
rs(s + 1) = 0 ‚ compute RS generator polynomial
For i = 0 To s
rs(s – i) = 1
For j = s – i + 1 To s
rs(j) = rs(j + 1) Xor ex((lg(rs(j)) + i) Mod 255)
Next j
Next i
For c = 1 To b ‚ compute RS correction data for each block
For i = 0 To s: rc(i) = 0: Next i
For i = c To el Step b
x = rc(0) Xor Asc(Mid(enc, i, 1))
For j = 1 To s
rc(j – 1) = rc(j) Xor IIf(x, ex((lg(rs(j)) + lg(x)) Mod 255), 0)
Next j
Next i
For i = 0 To s – 1 ‚ add interleaved correction data
Mid(enc, el + c + i * b, 1) = Chr(rc(i))
Next i
Next c

With Application.Caller.Parent.Shapes
b = .Count + 1 ‚ layout DataMatrix barcode
For i = 0 To h + 2 * nr – 1 Step fh + 2 ‚ finder horizontal
For j = 0 To w + 2 * nc – 1
.AddShape(msoShapeRectangle, j, i + fh + 1, 1, 1).Name = Application.Caller.Address
If (j And 1) = 0 Then .AddShape(msoShapeRectangle, j, i, 1, 1).Name = Application.Caller.Address
Next j
Next i
For i = 0 To w + 2 * nc – 1 Step fw + 2 ‚ finder vertical
For j = 0 To h – 1
.AddShape(msoShapeRectangle, i, j + (j \ fh) * 2 + 1, 1, 1).Name = Application.Caller.Address
If (j And 1) = 1 Then .AddShape(msoShapeRectangle, i + fw + 1, j + (j \ fh) * 2, 1, 1).Name = Application.Caller.Address
Next j
Next i
‚layout data
s = 2: c = 0: r = 4 ‚ step,column,row of data position
For i = 1 To l
If (r = h – 3 And c = -1) Then ‚ corner A
k = Array(w, 6 – h, w, 5 – h, w, 4 – h, w, 3 – h, w – 1, 3 – h, 3, 2, 2, 2, 1, 2)
ElseIf r = h + 1 And c = 1 And (w And 7) = 0 And (h And 7) = 6 Then ‚ corner D
k = Array(w – 2, -h, w – 3, -h, w – 4, -h, w – 2, -1 – h, w – 3, -1 – h, w – 4, -1 – h, w – 2, -2, -1, -2)
Else
If r = 0 And c = w – 2 And (w And 3) Then i = i – 1: GoTo continue ‚ corner B
If r < 0 Or c >= w Or r >= h Or c < 0 Then ‚ outside
s = -s: r = r + 2 + s / 2: c = c + 2 – s / 2 ‚ turn around
Do While r < 0 Or c >= w Or r >= h Or c < 0
r = r – s: c = c + s
Loop
End If
If r = h – 2 And c = 0 And (w And 3) Then ‚ corner B
k = Array(w – 1, 3 – h, w – 1, 2 – h, w – 2, 2 – h, w – 3, 2 – h, w – 4, 2 – h, 0, 1, 0, 0, 0, -1)
ElseIf r = h – 2 And c = 0 And (w And 7) = 4 Then ‚ corner C
k = Array(w – 1, 5 – h, w – 1, 4 – h, w – 1, 3 – h, w – 1, 2 – h, w – 2, 2 – h, 0, 1, 0, 0, 0, -1)
ElseIf r = 1 And c = w – 1 And (w And 7) = 0 And (h And 7) = 6 Then ‚ omit corner D
i = i – 1: GoTo continue
Else
k = Array(0, 0, -1, 0, -2, 0, 0, -1, -1, -1, -2, -1, -1, -2, -2, -2) ‚ nominal layout
End If
End If
el = Asc(Mid(enc, i, 1))
For j = 0 To 15 Step 2 ‚ layout each bit
If el And 1 Then
x = c + k(j): y = r + k(j + 1)
If x < 0 Then x = x + w: y = y + 4 – ((w + 4) And 7) ‚ wrap around
If y < 0 Then y = y + h: x = x + 4 – ((h + 4) And 7)
.AddShape(msoShapeRectangle, x + 2 * (x \ fw) + 1, y + 2 * (y \ fh) + 1, 1, 1).Name = Application.Caller.Address
End If
el = el \ 2
Next j
continue:
r = r – s: c = c + s ‚ diagonal step
Next i
For i = (w And -4) + 1 To w ‚ unfilled corner
.AddShape(msoShapeRectangle, i, i, 1, 1).Name = Application.Caller.Address
Next i
b = .Count – b
ReDim shps(b) As Integer ‚ group all shapes
For i = .Count To 1 Step -1
If .Range(i).Name = Application.Caller.Address Then
shps(b) = i: b = b – 1
If b < 0 Then Exit For
End If
Next i
s = 2 ‚ padding around symbol
x = Application.Caller.MergeArea.Width * w / (w + s)
y = Application.Caller.MergeArea.Height * h / (h + s) * (w + s) / (h + s)
If x > y Then x = y
With .Range(shps).Group
.Fill.ForeColor.RGB = fColor ‚ format barcode shape
.line.ForeColor.RGB = bColor
.line.Weight = line
.Width = x ‚ fit symbol in excel cell
.Height = .Width * (h + s) / (w + s)
.Left = Application.Caller.Left + (Application.Caller.MergeArea.Width – .Width) / 2
.Top = Application.Caller.Top + (Application.Caller.MergeArea.Height – .Height) / 2
.Name = Application.Caller.Address ‚ link shape to data
.Title = text
.AlternativeText = „DataMatrix barcode, “ & (w + 2 * nc) & „x“ & (h + 2 * nr) & “ cells“
.LockAspectRatio = True
.Placement = xlMove
End With
End With
failed:
If Err.Number Then DataMatrix = „ERROR DataMatrix: “ & Err.Description
End Function

ModulQRcode

17.06.2024

Attribute VB_Name = „ModulQRcode“ Option Explicit Dim mat() As Byte ‚ matrix of QR ‚ QR Code 2005 bar code symbol creation according ISO/IEC 18004:2006 ‚ param text to encode ‚ param level optional: quality level LMQH ‚ param version optional: minimum version size (-3:M1, -2:M2, .. 1, .. 40) ‚ creates QR and micro QR bar code symbol as shape in [...]

ModulCode128

17.06.2024

Attribute VB_Name = „ModulCode128“ Option Explicit ‚ Code 128 symbol creation according ISO/IEC 15417:2007 Public Function Code128(text As String) As String Attribute Code128.VB_Description = „Draw Code 128 barcode“ Attribute Code128.VB_ProcData.VB_Invoke_Func = “ \n18″ On Error GoTo failed If Not TypeOf Application.Caller Is Range Then Err.Raise 513, [...]

ModulBarcode

17.06.2024

Attribute VB_Name = „ModulBarcode“ ‚ Barcode symbol creation by VBA ‚ Author: alois zingl ‚ Version: V1.1 jan 2016 ‚ Copyright: Free and open-source software ‚ http://members.chello.at/~easyfilter/barcode.html ‚ Description: the indention of this library is a short and compact implementation to create barcodes ‚ of Code 128, Data Matrix, [...]

Martin Dubéci

Žiadny „trucpodnik“ voči Matovičovi. Dubéci: 17. novembra sa PS stretne na proteste so SaS, Demokratmi a KDH

09.11.2025 15:54

Po ich zhromaždení bude nasledovať zhromaždenie občianskej spoločnosti.

Čína, Orbán, Putin, Peking, Maďarsko, Rusko

Magyar: Putin chce udržať pri moci Orbána, svojho najbližšieho spojenca v EÚ

09.11.2025 14:54

Predseda strany TISZA v rozhovore uviedol, že ak sa stane premiérom, Maďarsko sa opäť obráti na Západ a vstúpi do eurozóny.

šutaj eštok

Šutaj Eštok je proti a aj za hazard. Majerský Huliakovej novele hovorí nie

09.11.2025 14:05, aktualizované: 15:09

Ak pán Huliak tvrdí, že jeho návrh prinesie stovky miliónov eur do rozpočtu, nech sa páči, nech to ukáže, hovorí šéf Hlasu.

Rakúska polícia

Matka omylom zrazila svoju dcéru autom, dieťa zomrelo

09.11.2025 13:57

Rodičia dievčatka v čase incidentu menili pneumatiky na svojom aute.

Štatistiky blogu

Počet článkov: 17
Celková čítanosť: 49583x
Priemerná čítanosť článkov: 2917x

Autor blogu

Kategórie