Založ si blog

ModulAztec

Attribute VB_Name = „ModulAztec“
Option Explicit
Dim typ As Long, enc(1665) As Integer
Dim md As Long, eb As Long, el As Long, b As Long

‚ Aztec bar code symbol creation according ISO/IEC 24778:2008
‚ param text to encode
‚ param security optional: percentage of checkwords used for security 2%-90% (23%)
‚ param layers optional: number of layers (size), default autodetect, 0 – Aztec rune
‚ creates Actec and compact Aztec bar code symbol as shape in Excel cell.
Public Function Aztec(text As String, Optional security As Integer, Optional layers As Integer = 1) As String
Attribute Aztec.VB_Description = „Draw Aztec barcode“
Attribute Aztec.VB_ProcData.VB_Invoke_Func = “ \n18″
Dim fColor As Long, bColor As Long, line As Long, shp As Shape, txt As String
Dim x As Long, y As Long, dx As Long, dy As Long, ctr As Long, ec As Long
Dim c As Long, i As Long, j As Long, k As Long, l As Long, m As Long

On Error GoTo failed
If Not TypeOf Application.Caller Is Range Then Err.Raise 513, „Aztec code“, „Call only from sheet“
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
If security < 1 Then security = 23 Else If security > 90 Then security = 90
txt = IIf(text = „“, “ „, utf16to8(text)) ‚ at least 1 char
el = Len(txt): x = 4: typ = 0
Do ‚ compute word size b: 6/8/10/12 bits
i = Int(el * 100 / (100 – security) + 3) * x ‚ needed bits, at least 3 checkwords
If i > l Then l = i
b = IIf(l <= 240, 6, IIf(l <= 1920, 8, IIf(l <= 10208, 10, 12))) ‚ bit capacity -> word size
i = IIf(layers < 3, 6, IIf(layers < 9, 8, IIf(layers < 23, 10, 12))) ‚ layer paramerter
If i > b Then b = i
If x >= b Then Exit Do
el = 0: md = 0: eb = 0: enc(0) = 0 ‚ clr bit stream
For i = 1 To Len(txt) ‚ scan text
c = Asc(Mid(txt, i, 1)): k = 0
If i < Len(txt) Then k = Asc(Mid(txt, i + 1, 1))
If c = 32 Then ‚ space
If md = 3 Then push 31: md = 0 ‚ punct: latch to upper
c = 1 ‚ space in all other modes
ElseIf md = 4 And c = 44 Then
c = 12 ‚ , in digit mode
ElseIf md = 4 And c = 46 Then
c = 13 ‚ . in digit mode
ElseIf ((c = 44 Or c = 46 Or c = 58) And k = 32) Or (c = 13 And k = 10) Then
If md <> 3 Then push (0) ‚ shift to punct
push IIf(c = 46, 3, IIf(c = 44, 4, IIf(c = 58, 5, 2))) ‚ two char encoding
i = i + 1: GoTo continue
Else
c = IIf(c = 13 And modeOf(k) \ 32 = md, 97, modeOf(c))
If c < 0 Then ‚ binary
If md > 2 Then push IIf(md = 3, 31, 14): md = 0 ‚ latch to upper
j = 0: push 31 ‚ shift to binary
For k = 0 To Len(txt) – i – 1 ‚ calc binary length
If modeOf(Asc(Mid(txt, k + i, 1))) < 0 Then
j = 0
Else
j = j + 1
If j > 5 Then Exit For ‚ look for at least 5 consecutive non binary chars
End If
Next k
k = k – j
If k > 30 Then
push 0: push k – 30, 11
Else
push k + 1
End If
For j = 0 To k ‚ encode binary data
push Asc(Mid(txt, i + j, 1)), 8
If el > 1660 Then Exit For
Next j
i = i + k: GoTo continue
End If
m = c \ 32 ‚ needed mode
If m = 4 And md = 2 Then push 29: md = 0 ‚ mixed to upper (to digit)
If m <> 3 And md = 3 Then push 31: md = 0 ‚ exit punct: to upper
If m <> 4 And md = 4 Then ‚ exit digit
If (m = 3 Or m = 0) And modeOf(k) > 129 Then
push (3 – m) * 5: push c And 31, 5 ‚ shift to punct/upper
GoTo continue
End If
push 14: md = 0 ‚ latch to upper
End If
If md <> m Then ‚ mode change needed
If m = 3 Then ‚ to punct
If md <> 4 And modeOf(k) \ 32 = 3 Then ‚ 2x punct, latch to punkt
If md <> 2 Then push 29 ‚ latch to mixed
push 30 ‚ latch to punct
md = 3 ‚ mode punct
Else
push 0 ‚ shift to punct
End If
ElseIf md = 1 And m = 0 Then ‚ lower to upper
If modeOf(k) \ 32 = 1 Then
push 28 ‚ shift
Else
push 30: push 14, 4 ‚ latch
md = 0
End If
Else ‚ latch to ..
push Array(29, 28, 29, 30, 30)(m)
md = m
End If
End If
End If
push c And 31 ‚ add char
If el > 1660 Then Exit For
continue:
Next i
push 2 ^ (b – eb) – 1, b – eb ‚ add padding bits
x = b
Loop
If el > 1660 Then Err.Raise 514, „Aztec code“, „Message too long.“
typ = IIf(l > 608 Or el > 64, 14, 11) ‚ full or compact Aztec
md = val(Left(txt, 3)) ‚ Aztec rune possible ?
If md < 0 Or md > 255 Or md & „“ <> txt Or layers > 0 Then
i = -Int((typ – Sqr(l + typ * typ)) / 4) ‚ needed layers
If i > layers Then layers = i
If layers > 32 Then layers = 32
End If
ec = (8 * layers * (typ + 2 * layers)) \ b – el ‚ # of checkwords
typ = typ \ 2: ctr = typ + 2 * layers: ctr = ctr + (ctr – 1) \ 15 ‚ center position
security = 100 * ec / (el + ec)

With Application.Caller.Parent.Shapes ‚ layout Aztec barcode
m = .Count + 1
For y = 1 – typ To typ – 1 ‚ layout central finder
For x = 1 – typ To typ – 1
If (IIf(Abs(x) > Abs(y), x, y) And 1) = 0 Then
.AddShape(msoShapeRectangle, ctr + x, ctr + y, 1, 1).Name = Application.Caller.Address
End If
Next x
Next y
For i = 0 To 5 ‚ orientation marks
x = Array(-typ, -typ, 1 – typ, typ, typ, typ)(i)
y = Array(1 – typ, -typ, -typ, typ – 1, 1 – typ, -typ)(i)
.AddShape(msoShapeRectangle, ctr + x, ctr + y, 1, 1).Name = Application.Caller.Address
Next i
If layers > 0 Then ‚ layout data
addCheck ec, 2 ^ b – 1, Array(67, 301, 1033, 4201)(b / 2 – 3) ‚ error correction, generator polynomial
x = -typ: y = x – 1 ‚ start of layer 1 at top left
j = (3 * typ + 11) / 2: l = j ‚ length of inner side
dx = 1: dy = 0 ‚ direction right
For ec = ec + el – 1 To 0 Step -1 ‚ layout codeword
c = enc(ec) ‚ data in reversed order inside to outside
For i = 1 To b / 2
If c And 1 Then ‚ odd bit
.AddShape(msoShapeRectangle, ctr + x, ctr + y, 1, 1).Name = Application.Caller.Address
End If
move x, y, dy, -dx ‚ move across
If c And 2 Then ‚ even bit
.AddShape(msoShapeRectangle, ctr + x, ctr + y, 1, 1).Name = Application.Caller.Address
End If
move x, y, dx – dy, dx + dy ‚ move ahead
j = j – 1
If j = 0 Then ‚ spiral turn
move x, y, dy, -dx ‚ move across
j = dx: dx = -dy: dy = j ‚ rotate clockwise
If dx < 1 Then
move x, y, dx – dy, dx + dy ‚ move ahead
move x, y, dx – dy, dx + dy ‚ move ahead
Else
l = l + 4 ‚ full turn -> next layer
End If
j = l ‚ start new side
End If
c = c \ 4
Next i
Next ec
If typ = 7 Then ‚ layout reference grid
For x = (15 – ctr) And -16 To ctr Step 16
For y = (1 – ctr) And -2 To ctr Step 2
If Abs(x) > typ Or Abs(y) > typ Then
.AddShape(msoShapeRectangle, ctr + x, ctr + y, 1, 1).Name = Application.Caller.Address ‚ down
If y And 15 Then
.AddShape(msoShapeRectangle, ctr + y, ctr + x, 1, 1).Name = Application.Caller.Address ‚ across
End If
End If
Next y
Next x
End If
md = (layers – 1) * (typ * 992 – 4896&) + el – 1 ‚ 2/5 + 6/11 mode bits
End If
el = typ – 3 ‚ process modes message compact/full
For i = el – 1 To 0 Step -1
enc(i) = md And 15 ‚ mode to 4 bit words
md = md \ 16
Next i
addCheck typ \ 2 + 3, 15, 19 ‚ add 5/6 words error correction
el = el + typ \ 2 + 3 ‚ init bit stream
b = (typ * 3) \ 2 ‚ 7/10 bits per side
eb = 0: j = IIf(layers, 0, 10) ‚XOR Aztec rune data
For i = 0 To b – 1
push j Xor enc(i), 4 ‚ 8/16 words to 4 chunks
Next i
j = 1 ‚ layout mode data
For i = 2 – typ To typ – 2
If typ = 7 And i = 0 Then i = i + 1 ‚ skip reference grid
If enc(b) And j Then .AddShape(msoShapeRectangle, ctr – i, ctr – typ, 1, 1).Name = Application.Caller.Address ‚ top
If enc(b + 1) And j Then .AddShape(msoShapeRectangle, ctr + typ, ctr – i, 1, 1).Name = Application.Caller.Address ‚ right
If enc(b + 2) And j Then .AddShape(msoShapeRectangle, ctr + i, ctr + typ, 1, 1).Name = Application.Caller.Address ‚ bottom
If enc(b + 3) And j Then .AddShape(msoShapeRectangle, ctr – typ, ctr + i, 1, 1).Name = Application.Caller.Address ‚ left
j = j + j
Next i
m = .Count – m
ReDim shps(m) As Integer ‚ group all shapes
For i = .Count To 1 Step -1
If .Range(i).Name = Application.Caller.Address Then
shps(m) = i: m = m – 1
If m < 0 Then Exit For
End If
Next i
With .Range(shps).Group
.Fill.ForeColor.RGB = fColor ‚ format barcode shape
.line.ForeColor.RGB = bColor
.line.Weight = line
x = Application.Caller.MergeArea.Width
y = Application.Caller.MergeArea.Height
If x > y Then x = y
.Width = x * (2 * ctr + 1) / (2 * ctr + 3) ‚ fit symbol in excel cell
.Height = .Width
.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 = „Aztec “ & IIf(typ = 5, „compact“, „full“) & “ barcode, security “ & security & „%, layers “ & layers & „, “ & (2 * ctr + 1) & „x“ & (2 * ctr + 1) & “ cells“
.LockAspectRatio = True
.Placement = xlMove
End With
End With
failed:
If Err.Number Then Aztec = „ERROR Aztec: “ & Err.Description
End Function

‚ get character encoding mode of ch
Private Function modeOf(ByVal ch As Integer) As Integer
Dim i As Integer, k As Variant
If ch = 32 Then modeOf = md * 32: Exit Function ‚ space
k = Array(0, 14, 65, 26, 32, 52, 32, 48, 69, 47, 58, 82, 57, 64, 59, 64, 91, -63, 96, 123, -63)
For i = 0 To UBound(k) Step 3 ‚ check range
If ch > k(i) And ch < k(i + 1) Then Exit For
Next i
If i <= UBound(k) Then modeOf = ch + k(i + 2): Exit Function ‚ ch in range
i = InStr(„@\^_’|~ []{}“, Chr(ch))
modeOf = IIf(i = 0, -1, IIf(i < 9, 20 + 64, 27 + 96 – 8) + i – 1) ‚ binary/mixed/punct
End Function

‚ add value to data stream
Private Sub push(ByVal val As Long, Optional ByVal bits As Integer = 0)
val = val * 2 ^ b
If bits = 0 Then bits = IIf(md = 4, 4, 5)
eb = eb + bits
enc(el) = enc(el) + val \ 2 ^ eb ‚ add data
Do While eb >= b ‚ word full ?
If typ = 0 And (enc(el) < 2 Or enc(el) + 3 > 2 ^ b) Then ‚ bit stuffing
enc(el) = enc(el) Xor ((enc(el) + 3) \ 2 And 1) ‚ add complementary bit
eb = eb + 1
End If
eb = eb – b: el = el + 1
enc(el) = (val \ 2 ^ eb) And ((2 ^ b) – 1)
Loop
End Sub

‚ compute Reed Solomon error detection and correction
Private Sub addCheck(ByVal ec As Integer, ByVal s As Integer, ByVal p As Integer)
Dim i As Integer, j As Integer, x As Integer
ReDim rc(ec + 2) As Integer, lg(s + 1) As Integer, ex(s) As Integer
j = 1
For i = 0 To s – 1 ‚ compute log/exp table of Galois field
ex(i) = j: lg(j) = i
j = j + j: If (j > s) Then j = j Xor p ‚ GF polynomial
Next i
rc(ec + 1) = 0
For i = 0 To ec ‚ compute RS generator polynomial
rc(ec – i) = 1
For j = ec – i + 1 To ec
rc(j) = rc(j + 1) Xor ex((lg(rc(j)) + i) Mod s)
Next j
enc(el + i) = 0
Next i
For i = 0 To el – 1 ‚ compute RS checkwords
x = enc(el) Xor enc(i)
For j = 1 To ec
enc(el + j – 1) = enc(el + j) Xor IIf(x, ex((lg(rc(j)) + lg(x)) Mod s), 0)
Next j
Next i
End Sub

‚ move one cell
Private Sub move(x As Long, y As Long, ByVal dx As Integer, ByVal dy As Integer)
Do
x = x + dx
Loop While typ = 7 And (x And 15) = 0 ‚ skip reference grid
Do
y = y + dy
Loop While typ = 7 And (y And 15) = 0
End Sub

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 [...]

ModulDataMatrix

17.06.2024

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 [...]

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, [...]

ústavný súd

Ústavný súd zrušil len malú časť zmien v trestnom práve. Verdikt padol po vyše štyroch mesiacoch

03.07.2024 18:18

Pozastavené časti sa týkajú znižovania trestných sadzieb a skracovania premlčacích lehôt za niektoré trestné činy.

Jennie Carignanová

Kanadskú armádu po prvý raz povedie žena. Trudeau vyzdvihol jej kvality a vodcovstvo

03.07.2024 16:53

Pôsobila ako veliteľka vojenskej misie v Afganistane, Bosne a Hercegovine, Iraku a Sýrii.

seniorka, podvod

Slovensko zaplavili podvodné telefonáty v mene polície. Čo robiť v prípade prijatia hovoru?

03.07.2024 16:16

Prezrite si konkrétne telefónne čísla podvodníkov.

Forró, Pellegrini

Forró ako Pellegriniho poradca? Prezident neplánuje mať v tíme aktívnych politikov, reaguje palác

03.07.2024 15:43

Debaty o poradcovi medzi prezidentom a Forróm potvrdila jeho strana.

Štatistiky blogu

Počet článkov: 17
Celková čítanosť: 45377x
Priemerná čítanosť článkov: 2669x

Autor blogu

Kategórie