Modul Data Matrix
Modul Data Matrix
Option Explicit
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