Crystal Reports Code 128 条码打印形状而不是数字
Posted
技术标签:
【中文标题】Crystal Reports Code 128 条码打印形状而不是数字【英文标题】:Crystal Reports Code 128 Barcode Printing Shape Instead of Number 【发布时间】:2014-04-22 22:40:09 【问题描述】:我有一个字体为 Code 128 的公式字段,用于打印用户输入的字符串。
每次打印都很好,除非两 (2) 个零彼此相邻。但是当它打印 100 时它很好,但是说我做 1000,它会在条形码中打印一些矩形形状。再次 1001 打印正常,10001 打印矩形。
这是公式字段:
@QuantityBarCode
' http://support.wisys.com/documentation/Crystal_Report_IDAutomation_Basic_Syntax_Barcode_Settings.htm
Dim DataToEncode As String
DataToEncode = Trim(@Quantity) ' Quantity
Dim PrintableString As String
Dim DataToFormat As String
Dim WeightedTotal As Number
Dim CurrentValue As Number
Dim CheckDigitValue As Number
Dim C128CheckDigit As String
Dim StringLength As Number
Dim I As Number
Dim CurrentCharNum As Number
Dim CurrentEncoding As String
Dim C128Start As String
Dim CorrectFNC As Number
Dim CurrentChar As String
CorrectFNC = 0
PrintableString = ""
DataToFormat = DataToEncode
DataToEncode = ""
'Here we select character set A, B or C for the START character
StringLength = Len(DataToFormat)
CurrentCharNum = Asc(Mid(DataToFormat, 1, 1))
If CurrentCharNum < 32 Then C128Start = Chr(203)
If CurrentCharNum > 31 And CurrentCharNum < 127 Then C128Start = Chr(204)
If ((StringLength > 4) And IsNumeric(Mid(DataToFormat, 1, 4))) Then C128Start = Chr(205)
'202 & 212-215 is for the FNC1, with this Start C is mandatory
If CurrentCharNum = 202 Then C128Start = Chr(205)
If CurrentCharNum = 212 Then C128Start = Chr(205)
If CurrentCharNum = 213 Then C128Start = Chr(205)
If CurrentCharNum = 214 Then C128Start = Chr(205)
If CurrentCharNum = 215 Then C128Start = Chr(205)
If C128Start = Chr(203) Then CurrentEncoding = "A"
If C128Start = Chr(204) Then CurrentEncoding = "B"
If C128Start = Chr(205) Then CurrentEncoding = "C"
For I = 1 To StringLength
'check for FNC1 in any set which is ASCII 202 and ASCII 212-215
CurrentCharNum = Asc(Mid(DataToFormat, I, 1))
If ((CurrentCharNum = 202) Or (CurrentCharNum = 212) Or (CurrentCharNum = 213) Or (CurrentCharNum = 214) Or (CurrentCharNum = 215)) Then
DataToEncode = DataToEncode & Chr(202)
'check for switching to character set C
ElseIf ((I < StringLength - 2) And (IsNumeric(Mid(DataToFormat, I, 1))) And (IsNumeric(Mid(DataToFormat, I + 1, 1))) And (IsNumeric(Mid(DataToFormat, I, 4)))) Or ((I < StringLength) And (IsNumeric(Mid(DataToFormat, I, 1))) And (IsNumeric(Mid(DataToFormat, I + 1, 1))) And (CurrentEncoding = "C")) Then
'switch to set C if not already in it
If CurrentEncoding <> "C" Then DataToEncode = DataToEncode & Chr(199)
CurrentEncoding = "C"
CurrentChar = Mid(DataToFormat, I, 2)
CurrentValue = Val(CurrentChar)
'set the CurrentValue to the number of String CurrentChar
If (CurrentValue < 95 And CurrentValue > 0) Then DataToEncode = DataToEncode & Chr(CurrentValue + 32)
If CurrentValue > 94 Then DataToEncode = DataToEncode & Chr(CurrentValue + 100)
If CurrentValue = 0 Then DataToEncode = DataToEncode & Chr(194)
I = I + 1
'check for switching to character set A
ElseIf (I <= StringLength) And ((Asc(Mid(DataToFormat, I, 1)) < 31) Or ((CurrentEncoding = "A") And (Asc(Mid(DataToFormat, I, 1)) > 32 And (Asc(Mid(DataToFormat, I, 1))) < 96))) Then
'switch to set A if not already in it
If CurrentEncoding <> "A" Then DataToEncode = DataToEncode & Chr(201)
CurrentEncoding = "A"
'Get the ASCII value of the next character
CurrentCharNum = Asc(Mid(DataToFormat, I, 1))
If CurrentCharNum = 32 Then
DataToEncode = DataToEncode & Chr(194)
ElseIf CurrentCharNum < 32 Then
DataToEncode = DataToEncode & Chr(CurrentCharNum + 96)
ElseIf CurrentCharNum > 32 Then
DataToEncode = DataToEncode & Chr(CurrentCharNum)
End If
'check for switching to character set B
ElseIf (I <= StringLength) And (((Asc(Mid(DataToFormat, I, 1))) > 31) And ((Asc(Mid(DataToFormat, I, 1)))) < 127) Then
'switch to set B if not already in it
If CurrentEncoding <> "B" Then DataToEncode = DataToEncode & Chr(200)
CurrentEncoding = "B"
'Get the ASCII value of the next character
CurrentCharNum = Asc(Mid(DataToFormat, I, 1))
If CurrentCharNum = 32 Then
DataToEncode = DataToEncode & Chr(194)
Else
DataToEncode = DataToEncode & Chr(CurrentCharNum)
End If
End If
Next I
'<<<< Calculate Modulo 103 Check Digit >>>>
WeightedTotal = Asc(C128Start) - 100
StringLength = Len(DataToEncode)
For I = 1 To StringLength
CurrentCharNum = Asc(Mid(DataToEncode, I, 1))
If CurrentCharNum < 135 Then CurrentValue = CurrentCharNum - 32
If CurrentCharNum > 134 Then CurrentValue = CurrentCharNum - 100
If CurrentCharNum = 194 Then CurrentValue = 0
CurrentValue = CurrentValue * I
WeightedTotal = WeightedTotal + CurrentValue
If CurrentCharNum = 32 Then CurrentCharNum = 194
PrintableString = PrintableString & Chr(CurrentCharNum)
Next I
CheckDigitValue = (WeightedTotal Mod 103)
If CheckDigitValue < 95 And CheckDigitValue > 0 Then C128CheckDigit = Chr(CheckDigitValue + 32)
If CheckDigitValue > 94 Then C128CheckDigit = Chr(CheckDigitValue + 100)
If CheckDigitValue = 0 Then C128CheckDigit = Chr(194)
DataToEncode = ""
' Final Barcode format
Formula = C128Start & PrintableString & C128CheckDigit & Chr(206) & " "
图像将 1000 显示为文本(用户输入),条形码以矩形打印,我还将条形码文本添加到右下角以显示条形码文本在编码时的样子。我注意到当我得到这个奇怪的形状时,星号似乎在文本中。
任何帮助将不胜感激:)
【问题讨论】:
如果您创建一个新公式,提供10001
作为值,将其字体设置为条形码字体,会发生什么?您是否仍然遇到同样的问题?
如果您只是在没有编码的情况下获取用户输入的数量 (@Quantity),并且只应用 Code 128 条形码字体,它打印出来的效果很好,没有奇怪的形状,但它是不可扫描的。它需要使用开始/停止字符和校验位进行编码。
有人有什么建议吗?我想不通。
想给出解决这个问题的决心。我使用的是“code128.ttf”字体文件。我得到了一个“IDAutomationC128M.ttf”,用它作为标签上条形码的新字体,一切都很好。正确打印和扫描。
【参考方案1】:
我知道可能为时已晚,但如果将来有人遇到类似问题,我会回答这个问题。
此代码是为 IDAutomationC128M.ttf 字体提供的,该字体在 ascii 194 上具有字符,而 Code128.ttf 字体在 ascii 194 上没有...。 Code128.ttf 中的相同字符在 ascii 207 上可用。
要使此代码与 Code128.ttf 一起使用,只需将 chr(194) 更改为 chr(207),例如
有:
DataToEncode = DataToEncode & Chr(194)
应该是:
DataToEncode = DataToEncode & Chr(207)
【讨论】:
【参考方案2】:我尝试了上面的代码和 Mateusz 解决方案,但并不完全正确。
为了有效纠正提供的代码并在 0 相邻时创建一些可读的条形码,您需要将 chr(194) 更改为 chr(32) 在代码中随处可见。
【讨论】:
【参考方案3】:这里是免费Code128字体的BarCode128A水晶报表功能
Function (StringVar input)
NumberVar CheckDigit := 0;
NumberVar i := 0;
StringVar BarCodeOutput := "";
StringVar BarCodeInput := input;
StringVar BarCodeTemp := "";
NumberVar SingleByte := 0;
BarCodeInput := Uppercase(input);
For i := 1 To Len(BarCodeInput) Step 1 Do
(SingleByte := Asc(Mid(BarCodeInput, i,1));
If SingleByte >=0 And SingleByte < 32 Then
BarCodeTemp := BarCodeTemp + Chr(SingleByte +64)
Else if SingleByte > 31 And SingleByte < 127 Then
BarCodeTemp := BarCodeTemp + Chr(SingleByte - 32)
Else
BarCodeTemp := BarCodeTemp + ""
);
For i := 1 To Len(BarCodeTemp) Step 1 Do
(SingleByte := Asc(Mid(BarCodeTemp, i,1));
CheckDigit := (CheckDigit + (SingleByte * i)) Mod 103;
);
BarCodeTemp := BarCodeTemp + Chr(CheckDigit);
For i := 1 To Len(BarCodeTemp) Step 1 Do
(SingleByte := Asc(Mid(BarCodeTemp, i, 1));
If SingleByte =0 Then
BarCodeOutput := Chr(206)
Else if SingleByte > 0 And SingleByte < 94 Then
BarCodeOutput := BarCodeOutput + Chr(SingleByte + 32)
Else
BarCodeOutput := BarCodeOutput + Chr(SingleByte + 103)
);
Chr(203) + BarCodeOutput + Chr(206)
【讨论】:
感谢@Astriti 的代码。我已经好几年没有搞砸这些东西了!!大声笑以上是关于Crystal Reports Code 128 条码打印形状而不是数字的主要内容,如果未能解决你的问题,请参考以下文章
Crystal Reports 2008 中的单个条形图需要多个页面
Crystal Report CRforVS_13_0_8 code39 或 code128 的条码集成
使用Crystal Reports ReportDocument