• In mã vạch 128, 39 không cần font barcode
  • In mã vạch 128, 39 không cần font barcode

    ongke0711 > 06-11-16, 08:22 AM

    Trong diễn đàn đã có mấy bài hướng dẫn về in mã vạch rồi nhưng chủ yếu là phải cài đặt thêm các font barcode 39 + Hàm nhưng đôi khi sử dụng cũng không được như ý. 
    (http://thuthuataccess.com/forum/thread-8942.html
    http://thuthuataccess.com/forum/thread-270.html)


    Tôi tìm được bộ code dùng để tạo mã vạch mà không cần cài đặt font barcode, nay chia sẽ với các bạn. Bộ code này được viết bởi Rodney Marr (RodMarr@mailcity.com), tôi chỉ có công làm thành file demo minh họa.  007

    - Trong demo này tôi cũng thêm code dùng để in nhiều lần 1 record cho đến khi hết số lượng cần in thì nhảy tiếp sang reocord khác để in (như các phần mềm in mã vạch). Cái này rất hữu ích khi in tem mã vạch.
    - Tôi không có máy scan barcode để thử nhưng dùng app trên điện thoại để scan report trên màn hình thì thấy nhận dạng đúng số barcode. Các bạn có thiết bị thì test thử giùm nhé.

    Kết quả:
    [Hình: 30796067445_266f557746_b.jpg]


    Link file demo: http://www.mediafire.com/file/9npw322fsa...tBC%29.mdb

    Cách làm:
    - Copy code vào Module.
    - Trong Report: vẽ 1 textbox có Control source là field chứa mã barcode. Set thuộc tính Visible: No cho textbox này.
    - Ở phần Detail của report, vô sự kiện On Print nhập đoạn code này: 
    Mã PHP:
    Private Sub Detail_Print(Cancel As IntegerPrintCount As Integer)
       Dim Result As Boolean
       Result 
    Barcode_128(Me.BarCodeMe)
       Call InNhieuCopy(MeMe.txtSoLuongIn)
    End Sub 

    - Về phần in nhiều lần 1 record, bạn muốn in hàng ngang bao nhiêu cột thì vô Page Setup của report -> chọn Tab Columns -> chọn Number of columns rồi nhập số cột cần hiển thị. 
    - 2 bộ code cho việc in mã vạch 128 và 39:
    Code 128
    Mã PHP:
    ' Written by Rodney Marr (RodMarr@mailcity.com) October 7, 2000
    '
    ' Barcode 128-B Generator
    '
    ' Permission granted for public use and royalty-free distribution.
    No mention of source or credits is required.
    '
    I got a lot of help from the following people's work
    Russ Adams' BarCode 1 Web Page   http://www.adams1.com/pub/russadam/info.html
    A Free 128-B code generator in Visual Basic by Stefan Karlsson (mrswede@libertysurf.se)
    ' And the Creator of the code 39 Module
    '
    'For Notes on how to use this code look at the code for the barcode39 Generator'

    Public Function Barcode_128(Ctrl As Controlrpt As Report)
       On Error GoTo ErrorTrap_Barcode_128

       
    'Code 128B has 5 main parts to it. The first part is a start character(211214), followed by DataCharcters. The Data
       '
    Characters are followed by a check(or ChecksumCharacter, and that is followed by a stop Character(2331112)
       'The last part of Code 128B is the two quiet sections at the front and back of the barcode. These are 10 dimensions
       '
    Long(I am thinking that is 11 modules long). Each character is 11 modules longexcept the stop character which is
       
    '13 modules long'

       Dim CharNumber As VariantCharData As VariantCharBarData As VariantNratio As VariantNbar As Variant
       Dim barcodestr 
    As StringBarCode As ControlBarchar As StringBarcolor As LongParts As IntegerAs Integer
       Dim tsum 
    As Integerlop As IntegerAs Integerchecksum As IntegerAs Integerbarwidth As Integer
       Dim boxh 
    As Singleboxw As Singleboxx As Singleboxy As SinglePix As SingleNextbar As Single
       Const White 
    16777215: Const Black 0

       
    'This is the Raw data that I threw into an arrays'
       CharNumber = Array("0""1""2""3""4""5""6""7""8""9""10""11""12""13""14""15""16,""17""18""19""20""21""22""23""24""25""26""27""28""29,""30""31""32""33""34""35""36""37""38""39""40""41""42""43""44""45""46""47""48""49""50""51""52""53""54""55""56""57""58""59""60""61""62""63""64""65""66""67""68""69""70""71""72""73""74""75""76""77""78""79""80""81""82""83""84""85""86""87""88""89""90""91""92""93""94""95""96""97""98""99""100""101""102""103""104""105""106")
       CharData = Array("SP""!"Chr(34), "#""$""%""&""'""("")""*""+"",""-"".""/""0""1""2""3""4""5""6""7""8""9"":"";""<""="">""?""@""A""B""C""D""E""F""G""H""I""J""K""L""M""N""O""P""Q""R""S""T""U""V""W""X""Y""Z""[""\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "I", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "DEL", "FNC 3", "FNC 2", "SHIFT", "CODE C", "FNC 4", "CODE A", "FNC 1", "Start A", "Start B", "Start C", "Stop")
       CharBarData = Array("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", "413111", "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")

       barcodestr = "211412" 'Add the Startcode for Start B (characterset B) to the barcode string'
       tsum = 103                      'And this is the value for that startcode which will be added with the other character values to find the checksum character'
       boxx = Ctrl.Left: boxy = Ctrl.Top: boxw = Ctrl.Width: boxh = Ctrl.Height    'Get control size and location properties.'

       Set BarCode = Ctrl                                                          'Set handle on control.'

       Nratio = Array("0", "15", "30", "45", "60")           'Set up the array for the different bar width ratios'
       Parts = ((11 * (Len(BarCode))) + 35) * Nratio(1)  'This is the formula for the width of the barcode'
       Pix = (boxw / Parts)                                                  'Here I find out exactly how many Pixels a bar will be'
       Nbar = Array((Nratio(0) * Pix), (Nratio(1) * Pix), (Nratio(2) * Pix), (Nratio(3) * Pix), (Nratio(4) * Pix)) 'Set up the array to handle the pixels for each type of bar'

       'Loop through all bardata to count the sum for all characters and add barcode charcter strings the to the barcode string'
       For lop = 1 To Len(BarCode)
           Barchar = Mid(BarCode, lop, 1)
           If Barchar = " " Then Barchar = "SP"
           For s = 0 To UBound(CharData)
               If Barchar = CharData(s) Then
                   barcodestr = barcodestr & CharBarData(s) 'This is where I added the character strings to each other to make one long string of 1's, 2's, 3's, & 4's'
                   tsum = tsum + (CLng(CharNumber(s)) * lop) 'Here every barcode character's number value is multiplied by its position in the line and added to tsum
                   'The actual formula for find the the  Checksum  is "(104 + (1 * CharcterNumber) + (2 * CharcterNumber) + ...)/103" You would Use the Remainder as
                   'The Checksum Character. In the case of "BarCode 1" the formula would look
                   'like "(104+(1*34)+(2*65)+(3*82)+(4*35)+(5*79)+(6*68)+(7*69)+(8*0)+(9*17))/103=20 with Remainder of 33" Therefore the checksum would equal 33'
                   Exit For
               End If
           Next s
       Next lop

       checksum = tsum - (Int(tsum / 103) * 103)                                             'Here I use the the totat sum (tsum) to find the checksum'
       barcodestr = barcodestr & CharBarData(checksum) & "2331112" 'Here I add the checksum then the stop character into the barcode string'

       'lets do some initialization'
       Barcolor = Black
       Nextbar = boxx + 11     'I added the 20 for the whitespace (or quiet space) at the beginning of the barcode

       'Draw the Barcode
       For J = 1 To Len(barcodestr)
           Barchar = Mid(barcodestr, J, 1)   'Reuse variable barchar to store the character to be drawn'
           barwidth = CInt(Barchar)              'Change the barcode charcter into an integer so I can use in the array part of the next line'
           rpt.Line (Nextbar, boxy)-Step(Nbar(barwidth), boxh), Barcolor, BF 'Draw the line
           Nextbar = Nextbar + Nbar(barwidth)                                                      'Calculate the next starting point
           If Barcolor = White Then Barcolor = Black Else Barcolor = White      'Swap line colors
       Next J

    Exit_Barcode_128:
       Exit Function

    ErrorTrap_Barcode_128:
       MsgBox Error$

       Resume Exit_Barcode_128
    End Function 

    Code 39
    Mã PHP:
    ' Barcode Generator for Code 3 of 9, Code 39, and Mil-spec Logmars.
    '
    ' version 2.0 (updated for MsAccess 97)
    '
    ' (c) 1993-1999 James Isle Mercanti, Cocoa Beach, FL 32931  USA
    Permission granted for public use and royalty-free distribution.
    ' No mention of source or credits is required. All rights reserved.
    '
    ' TO USE THIS CODE:
    '
    '   1 - Create Report with a TextBox control. (example named Barcode)
          Make sure the Visible property is set to "No".
    '   2 - Set On-Print property of section to [Event Procedure]
          by clicking on the [...] and selecting "Code Builder"
    '   3 - Confirm that the following code matches yours...
    '
    '      Sub Detail1_Print (Cancel As Integer, PrintCount As Integer)
    '
    '         Result = Barcode_39(Barcode, Me)
    '
    '      End Sub
    '
    '   4 - NOTE: The name of the section is "Detail1" for example only!
          Your section might show a different nameDitto for "Barcode".
    '
      5 NOTETo use on sub-formsthe Report name should be hard-coded
    '       into the function. i.e. Rpt = Reports!MainForm!SubForm.Report.
          The easy method is to just avoid using sub-forms and sub-reports.
    '

    Function Barcode_39(Ctrl As Control, rpt As Report)
       On Error GoTo ErrorTrap_BarCode39

       Dim Nbar As Single, Wbar As Single, Qbar As Single, Nextbar As Single
       Dim CountX As Single, CountY As Single, CountR As Single
       Dim Parts As Single, Pix As Single, Color As Long, BarCodePlus As Variant
       Dim Stripes As String, BarType As String, BarCode As Control
       Dim Mx As Single, my As Single, Sx As Single, Sy As Single
       Const White = 16777215: Const Black = 0
       Const Nratio = 20, Wratio = 55, Qratio = 35

       '
    Get control size and location properties.
       Sx Ctrl.LeftSy Ctrl.TopMx Ctrl.Widthmy Ctrl.Height

       
    'Set handle on control.
       Set BarCode = Ctrl

       '
    Calculate actual and relative pixels values.
       Parts = (Len(BarCode) + 2) * ((Nratio) + (Wratio) + (Qratio))
       Pix = (Mx Parts):
       Nbar = (20 Pix): Wbar = (55 Pix): Qbar = (35 Pix)

       'Initialize bar index and color.
       Nextbar = Sx
       Color = White

       '
    Pad each end of string with start/stop characters.
       BarCodePlus "*" UCase(BarCode) & "*"

       'Walk through each character of the barcode contents.
       For CountX = 1 To Len(BarCodePlus)
           '
    Get Barcode 1/0 string for indexed character.
           Stripes MD_BC39(Mid$(BarCodePlusCountX1))
           For CountY 1 To 9
               
    'For each 1/0, draw a wide/narrow bar.
               BarType = Mid$(Stripes, CountY, 1)

               '
    Toggle the color (black/white).
               If Color White Then Color Black Else Color White
               Select 
    Case BarType
                   Case 
    "1"
                       'Draw a wide bar.
                       rpt.Line (Nextbar, Sy)-Step(Wbar, my), Color, BF
                       Nextbar = Nextbar + Wbar
                   Case "0"
                       '
    Draw a narrow bar.
                       rpt.Line (NextbarSy)-Step(Nbarmy), ColorBF
                       Nextbar 
    Nextbar Nbar
               End Select
           Next CountY

           
    'Toggle the color (black/white).
           If Color = White Then Color = Black Else Color = White

           '
    Draw intermediate "quiet" bar.
           rpt.Line (NextbarSy)-Step(Qbarmy), ColorBF
           Nextbar 
    Nextbar Qbar
       Next CountX

    Exit_BarCode39
    :
       Exit Function

    ErrorTrap_BarCode39:
       Resume Exit_BarCode39
    End 
    Function

    Function 
    MD_BC39(CharCode As String) As String
       On Error 
    GoTo ErrorTrap_BC39

       ReDim BC39
    (90)

       BC39(32) = "011000100" ' space
       BC39(36) = "010101000" ' 
    $
       BC39(37) = "000101010" ' %
       BC39(42) = "010010100" ' 
    Start/Stop
       BC39
    (43) = "010001010" ' +
       BC39(45) = "010000101" ' 
    |
       BC39(46) = "110000100" ' .
       BC39(47) = "010100010" ' 
    /
       BC39(48) = "000110100" ' 0
       BC39(49) = "100100001" ' 
    1
       BC39
    (50) = "001100001" ' 2
       BC39(51) = "101100000" ' 
    3
       BC39
    (52) = "000110001" ' 4
       BC39(53) = "100110000" ' 
    5
       BC39
    (54) = "001110000" ' 6
       BC39(55) = "000100101" ' 
    7
       BC39
    (56) = "100100100" ' 8
       BC39(57) = "001100100" ' 
    9
       BC39
    (65) = "100001001" ' A
       BC39(66) = "001001001" ' 
    B
       BC39
    (67) = "101001000" ' C
       BC39(68) = "000011001" ' 
    D
       BC39
    (69) = "100011000" ' E
       BC39(70) = "001011000" ' 
    F
       BC39
    (71) = "000001101" ' G
       BC39(72) = "100001100" ' 
    H
       BC39
    (73) = "001001100" ' I
       BC39(74) = "000011100" ' 
    J
       BC39
    (75) = "100000011" ' K
       BC39(76) = "001000011" ' 
    L
       BC39
    (77) = "101000010" ' M
       BC39(78) = "000010011" ' 
    N
       BC39
    (79) = "100010010" ' O
       BC39(80) = "001010010" ' 
    P
       BC39
    (81) = "000000111" ' Q
       BC39(82) = "100000110" ' 
    R
       BC39
    (83) = "001000110" ' S
       BC39(84) = "000010110" ' 
    T
       BC39
    (85) = "110000001" ' U
       BC39(86) = "011000001" ' 
    V
       BC39
    (87) = "111000000" ' W
       BC39(88) = "010010001" ' 
    X
       BC39
    (89) = "110010000" ' Y
       BC39(90) = "011010000" ' 
    Z

       MD_BC39 
    BC39(Asc(CharCode))

    Exit_BC39:
       Exit Function

    ErrorTrap_BC39:
       MD_BC39 ""

       Resume Exit_BC39
    End 
    Function 

    Code dùng để in nhiều copies
    Mã PHP:
    Option Compare Database
    Option Explicit

    Dim intSoBanIn
    Dim intSoLanIn

    Function InNhieuCopy(rpt As ReportSoBanIn As Long)
     'Print appropriate number of labels for each record.'
       intSoBanIn SoBanIn
       On Error 
    GoTo errHandler
       If intSoLanIn 
    < (intSoBanIn 1Then
           rpt
    .NextRecord False
           intSoLanIn 
    intSoLanIn 1
       Else
           intSoLanIn 
    0
       End 
    If
       Exit Function
     
    errHandler
    :
       MsgBox Err.Number ": " Err.Description_
       vbOKOnly
    "Error"
    End Function 

    * Nói thêm về sự khác nhau giữa barcode 39 và 128:
    Barcode 128
    [Hình: 30714990871_f4afff9db1_m.jpg].
    Barcode 39
    [Hình: 30714991151_d801b5e151_m.jpg]

    - Barcode 39 có thể mã hóa chữ, số và cả một số ký tự đặc biệt như - " $ % +/*". Barcode 128 thì có thể mã hóa tất cả 128 ký tự trong bảng mã ASCII.
    - Barcode 39 dùng 5 thanh và 4 khoảng trắng để đại diện cho 1 ký tự với các thanh chỉ có 2 loại là thanh nhỏ, thanh lớn với độ rộng như nhau do vậy việc in ấn barcode 39 sẽ dễ dàng và chính xác hơn. Barcode 128 thì dùng 3 thanh, 3 khoảng trắng nhưng riêng thanh to có đến 4 kích cỡ rộng khác nhau. Do vậy Barcode 128 sẽ giảm được độ rộng dãy barcode hơn so với loại 39. 
    Nói túm lại, nếu số mã barcode ít thì nên dùng barcode 39, nếu số ký tự barcode nhiều thì dùng lại 128 để lợi hơn về kích thước.
  • RE: In mã vạch 128, 39 không cần font barcode

    maidinhdan > 06-11-16, 01:49 PM

    Khi chạy báo lỗi : Missing: Full Justin ....textbox COntrol ( Các bạn bỏ check là chạy bình thường)

    Khi sử dụng chỉ cần chừa lại 2 thư viên chính là đủ:
    1. Visual Basic Aplication
    2. MS Access 11. Libraly hoặc hơn.

    Xin phép gửi file đính kèm đã sửa lỗi trên.
  • RE: In mã vạch 128, 39 không cần font barcode

    ongke0711 > 06-11-16, 02:08 PM

    Cảm ơn bạn Dân đã sửa giùm.
    Lỗi này là do lúc làm mình có thêm cái JustifyTextVer2.OCX tính dùng để canh điều cái text nhưng sau đó không cần dùng nữa mà quên gỡ bỏ.
  • RE: In mã vạch 128, 39 không cần font barcode

    Minh Tiên > 06-11-16, 09:24 PM

    Ongke0711 !
    Report in mã vạch theo cách của bạn mình đã thử trên máy quét mã vạch của cửa hàng mình --> Kết quả: Máy quét ko nhận được mã !
    Ko biết do lỗi gì.
    Mình so sánh cùng một mã hàng nhưnh hình ảnh mã vạch của mình đã sài và hình ảnh mã vạch theo cách của bạn hoàn toàn khác nhau (Cùng barcode 128).
    Cụ thể:
    1. Tiên:
    http://www.upsieutoc.com/image/n64sU
    2. Ongke0711:
    http://www.upsieutoc.com/image/n6p2M
    Các Pro test thử nhé !
    Thân./.
  • RE: In mã vạch 128, 39 không cần font barcode

    ongke0711 > 07-11-16, 12:20 PM

    Bạn Tiên nói đúng. Có vẻ là thông số trong code tạo mã này chưa đúng. Tôi dùng phần mềm tạo barcode thì thấy nó khác so với file access. Để check lại xem như thế nào.
  • RE: In mã vạch 128, 39 không cần font barcode

    ongke0711 > 08-11-16, 02:19 PM

    Sau khi test lại bộ code dùng để tạo barcode 128, có 2 thông số cần điều chỉnh để chương trình mã hóa các ký tự thành barcode cho đúng từng trường hợp. (Cái này mình cũng tự suy đoán test thử chứ không thực sự hiểu sâu về cách mã hóa thành barcode cũng như công thức vẽ line của bộ code này)

    Đối với barcode 128 có 3 loại:
    + Bảng mã code 128A có các ký tự ASCII từ 00 - 95
    + Bảng mã code 128B có các ký tự ASCII từ 37 - 127
    + Bảng mã code 128C có các ký tự ASCII từ 00 - 99

    Trường hợp của bạn Minh Tiên thì đổi sang bảng mã 128A. Bạn Tiên đã test giùm và máy scan đã đọc đúng barcode. Cảm ơn bạn Tiên đã hỗ trợ.

    Đổi 2 thông số này thì code vẽ line cho barcode sẽ thay đổi.
    * 128A: 
             - barcodestr = “211412
             - tsum = 103
    * 128B:
             - barcodestr = “211214
             - tsum = 104
    * 128B:
            - barcodestr = “211232
            - tsum = 105

    Các ký tự trong bảng mã ASCII như hình dưới đây: 

    [Hình: 30853570355_1a6f6fc3c4_b.jpg]

    Các bạn sử dụng thử đi nhé. Có bạn nào hiểu biết sau hơn về barcode thì hướng dẫn thêm giùm.