• Hỏi cách lập report
  • RE: Hỏi cách lập report

    tanbacmy > 05-10-15, 03:58 PM

    hay quá! Đúng là cái mình đang muốn tham khảo
  • RE: Hỏi cách lập report

    ledangvan > 05-10-15, 03:59 PM

    (05-10-15, 03:49 PM)tranthanhan1962 Đã viết: Mình hiểu rồi bạn muốn thiết kế report in hóa đơn chứ gì. Thông thường repord này có 2 phần. Phần ghi số hóa đơn và tên đơn vị dạng columnar. Và phần ghi hàng hóa dạng tabular. Đây là kinh nghiệm của mình. Khi thiết kế bạn kiểm tra các ô quan trọng tên đơn vị, địa chỉ, tên hàng hóa xem ô nó chứa được bao nhiêu chữ m, Khi thiết đặt các field bạn xác định field size đúng số lượng ký tự nó hiển thị được. Điều này nhằm khống chế việc đặt tên hoặc ghi địa chỉ tùy tiện.
    Riêng ô bằng chữ thì bạn cho 2 dòng là xong.

    Cách đó là giới hạn người dùng không được đánh quá ký tự, nhưng em thấy cách co ngót chữ của bác ở trên hay nên em muốn hỏi cho kỹ để áp dụng (Chính vì qui định của luật thuế hiện nay là không được đánh tắt ... nên dòng địa chỉ và tên đơn vị của một số đơn vị rất dài ,thậm chí đánh tắt rồi nó vẫn dài)

    ...
    Em muốn nó co ngót chữ nhưng chỉ giới hạn trong ô và chỉ trên 1 dòng thôi có được không bác ?
  • RE: Hỏi cách lập report

    tranthanhan1962 > 05-10-15, 05:10 PM

    (05-10-15, 03:59 PM)ledangvan Đã viết: Cách đó là giới hạn người dùng không được đánh quá ký tự, nhưng em thấy cách co ngót chữ của bác ở trên hay nên em muốn hỏi cho kỹ để áp dụng (Chính vì qui định của luật thuế hiện nay là không được đánh tắt ... nên dòng địa chỉ và tên đơn vị của một số đơn vị rất dài ,thậm chí đánh tắt rồi nó vẫn dài)

    ...
    Em muốn nó co ngót chữ nhưng chỉ giới hạn trong ô và chỉ trên 1 dòng thôi có được không bác ?

    Tên công ty vẫn có quyền gõ tắt những cụm từ như Công ty --> Cty, trách nhiệm hữu hạn --> TNHH, Còn tên địa chỉ thì bỏ các từ tỉnh, huyện, xã. Mình cũng vẫn thường làm như vậy.
    Ví dụ:  CÔNG TY CỔ PHẦN ĐẦU TƯ HỢP VIỆT, Địa chỉ: L9-06, Toà nhà Vincom Center, 72 Lê Thánh Tôn, Phường Bến Nghé, Quận 1, TP Hồ Chí Minh

    Vẫn có thể ghi: CTY CP ĐT HỢP VIỆT, Địa chỉ: L9-06, Vincom Center, 72 Lê Thánh Tôn, Bến Nghé, Quận 1, TP HCM.
    Địa chỉ này được xem thuộc loại  dài nhất cũng chỉ 63 ký tự. Nhưng trong report cũng mình cho đến 75 ký tự m , Với lại quan trọng trong hóa đơn size chữ phải hợp lý (cân đối với size của form in sẵn) thì mới đẹp, Lớn quá hoặc nhỏ quá cũng mất đi tính thẩm mỹ.
    Cơ quan thuế không bắt bẻ cái vụ này đâu, quan trọng là đừng bao giờ sai mã số thuế.  007
  • RE: Hỏi cách lập report

    ledangvan > 05-10-15, 10:22 PM

    Có câu trả lời rồi bác tranthanhan1962 ơi  021

    Em tải lên đây cho mọi người cùng dùng nhé : http://www.mediafire.com/download/3pdauc...n+Size.mdb
    • Nó có tác dụng : Font chữ luôn ở size 14 (hoặc tùy thuộc người dùng) , nếu chữ vừa đủ, hoặc ít hơn ô chứa thì Font luôn là 14, khi chữ nhiều thì font sẽ tự co ngót để vừa với ô chứa.
      Nó không bị xuống dòng bác tranthanhan1962 ạ 
  • RE: Hỏi cách lập report

    ledangvan > 22-03-17, 11:20 AM

    (05-10-15, 12:31 PM)ongke0711 Đã viết: Lúc trước tôi cũng có làm cái vụ này và tìm trên thấy trên mạng cái code này, nay share với bác.
    - Copy code vào sự kiện On Print của Detail Report.
    - Textbox nào cần tự động resize font để fit với textbox thì đặt tên với ký tự "v" ở đầu. Ví dụ: vTenCty. Muốn ký tự nào cũng được, nếu đổi thì sửa chút trong đoạn code.

    Mã PHP:
    Private Sub Detail_Print(Cancel As IntegerPrintCount As Integer)
       Dim ctl As ControlstrText As VariantstrName As String
       
       Me
    .ScaleMode 1
       For Each ctl In Me
    .Detail.Controls
           If ctl
    .ControlType acTextBox And ctl.Name Like "v*" Then
           strName 
    ctl.Name
               If Nz
    (ctl.Tag"") = "" Then
                   ctl
    .Tag ctl.FontSize
               End 
    If
               
               ctl
    .FontSize ctl.Tag
               Me
    .FontSize ctl.FontSize
               strText 
    ctl.Value
               Do Until TextWidth
    (strText) < ctl.Width '- (ctl.Width * 0.26)
                   ctl.FontSize = ctl.FontSize - 1
                   Me.FontSize = ctl.FontSize
               Loop
               Do Until TextHeight(strText) < ctl.Height - (ctl.Height * 0.26)
                   ctl.FontSize = ctl.FontSize - 1
                   Me.FontSize = ctl.FontSize
               Loop
           End If
       Next ctl
    End Sub 

    ongke0711 ơi cái này chạy tốt tuy nhiên nó chỉ giới hạn trong 1 dòng, tức là nó chỉ đo chiều dài của cột rồi co ngót. Có cách nào để dãn ròng như trong word mà vẫn co ngót đủ, hoặc giới hạn nó trong 2 dòng được không. 
    Nhờ bạn xem chỉ giúp với, xin cảm ơn.
  • RE: Hỏi cách lập report

    ongke0711 > 22-03-17, 09:06 PM

    (22-03-17, 11:20 AM)ledangvan Đã viết: ongke0711 ơi cái này chạy tốt tuy nhiên nó chỉ giới hạn trong 1 dòng, tức là nó chỉ đo chiều dài của cột rồi co ngót. Có cách nào để dãn ròng như trong word mà vẫn co ngót đủ, hoặc giới hạn nó trong 2 dòng được không. 
    Nhờ bạn xem chỉ giúp với, xin cảm ơn.

    007 Tôi cũng chưa tìm ra cách như bạn muốn. Để ngâm cứu tiếp xem sao.
  • RE: Hỏi cách lập report

    ledangvan > 23-03-17, 12:52 PM

    (22-03-17, 09:06 PM)ongke0711 Đã viết:
    (22-03-17, 11:20 AM)ledangvan Đã viết: ongke0711 ơi cái này chạy tốt tuy nhiên nó chỉ giới hạn trong 1 dòng, tức là nó chỉ đo chiều dài của cột rồi co ngót. Có cách nào để dãn ròng như trong word mà vẫn co ngót đủ, hoặc giới hạn nó trong 2 dòng được không. 
    Nhờ bạn xem chỉ giúp với, xin cảm ơn.

    007 Tôi cũng chưa tìm ra cách như bạn muốn. Để ngâm cứu tiếp xem sao.

    Tôi tìm được câu trả lời rồi 014  :

    Tạo một report có chứa Text Box : testmemo

    Trong mục On Format của report cho dòng mã này vào :
    Dim lngTextHeight As Long

    With Me.testmemo
        ' Copy the original Font height from the Tag property
        .fontsize = .Tag
        Do While .fontsize > 2
            lngTextHeight = fTextHeight(Me.testmemo)
            
            ' Does text fit? If yes then exit
             If lngTextHeight < .Height Then Exit Do
             
             ' Decrease font height
             .fontsize = .fontsize - 1
        Loop
    End With


    Khi mở report thì cho cái này vào : 
    Private Sub Report_Open(Cancel As Integer)
    DoCmd.MoveSize 2, 2, 6200, 5800

    ' Copy the TextBox default Fontsize to its Tag property.
    Me.testmemo.Tag = Me.testmemo.fontsize

    End Sub


    Thêm một Modules có chứa đoạn code này :
    Option Compare Database
     

    Option Explicit
     
    Private Type RECT
            Left As Long
            Top As Long
            Right As Long
            Bottom As Long
    End Type
     
    Private Const LF_FACESIZE = 32
     
    Private Type LOGFONT
            lfHeight As Long
            lfWidth As Long
            lfEscapement As Long
            lfOrientation As Long
            lfWeight As Long
            lfItalic As Byte
            lfUnderline As Byte
            lfStrikeOut As Byte
            lfCharSet As Byte
            lfOutPrecision As Byte
            lfClipPrecision As Byte
            lfQuality As Byte
            lfPitchAndFamily As Byte
            lfFaceName As String * LF_FACESIZE
    End Type

    Private Type TEXTMETRIC
            tmHeight As Long
            tmAscent As Long
            tmDescent As Long
            tmInternalLeading As Long
            tmExternalLeading As Long
            tmAveCharWidth As Long
            tmMaxCharWidth As Long
            tmWeight As Long
            tmOverhang As Long
            tmDigitizedAspectX As Long
            tmDigitizedAspectY As Long
            tmFirstChar As Byte
            tmLastChar As Byte
            tmDefaultChar As Byte
            tmBreakChar As Byte
            tmItalic As Byte
            tmUnderlined As Byte
            tmStruckOut As Byte
            tmPitchAndFamily As Byte
            tmCharSet As Byte
    End Type

    Private Declare Function GetTextMetrics Lib "gdi32" Alias "GetTextMetricsA" _
    (ByVal hDC As Long, lpMetrics As TEXTMETRIC) As Long
     
    Private Declare Function apiCreateFontIndirect Lib "gdi32" Alias _
            "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
     
    Private Declare Function apiSelectObject Lib "gdi32" Alias "SelectObject" _
    (ByVal hDC As Long, _
    ByVal hObject As Long) As Long
     
    Private Declare Function apiDeleteObject Lib "gdi32" _
      Alias "DeleteObject" (ByVal hObject As Long) As Long
     
    Private Declare Function apiGetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" _
    (ByVal hDC As Long, ByVal nIndex As Long) As Long
     
    Private Declare Function apiMulDiv Lib "kernel32" Alias "MulDiv" _
    (ByVal nNumber As Long, _
    ByVal nNumerator As Long, ByVal nDenominator As Long) As Long
     
    Private Declare Function apiGetDC Lib "user32" _
      Alias "GetDC" (ByVal hwnd As Long) As Long
     
    Private Declare Function apiReleaseDC Lib "user32" _
     Alias "ReleaseDC" (ByVal hwnd As Long, _
     ByVal hDC As Long) As Long
      
    Private Declare Function apiDrawText Lib "user32" Alias "DrawTextA" _
    (ByVal hDC As Long, ByVal lpStr As String, ByVal nCount As Long, _
    lpRect As RECT, ByVal wFormat As Long) As Long

    Private Declare Function CreateDCbyNum Lib "gdi32" Alias "CreateDCA" _
    (ByVal lpDriverName As String, ByVal lpDeviceName As String, _
    ByVal lpOutput As Long, ByVal lpInitData As Long) As Long  'DEVMODE) As Long

    Private Declare Function apiDeleteDC Lib "gdi32" _
      Alias "DeleteDC" (ByVal hDC As Long) As Long
      
    Declare Function GetProfileString Lib "kernel32" _
       Alias "GetProfileStringA" _
      (ByVal lpAppName As String, _
       ByVal lpKeyName As String, _
       ByVal lpDefault As String, _
       ByVal lpReturnedString As String, _
       ByVal nSize As Long) As Long




    ' CONSTANTS
    Private Const TWIPSPERINCH = 1440
    ' Used to ask System for the Logical pixels/inch in X & Y axis
    Private Const LOGPIXELSY = 90
    Private Const LOGPIXELSX = 88
     
    ' DrawText() Format Flags
    Private Const DT_TOP = &H0
    Private Const DT_LEFT = &H0
    Private Const DT_CALCRECT = &H400
    Private Const DT_WORDBREAK = &H10
    Private Const DT_EXTERNALLEADING = &H200
    Private Const DT_EDITCONTROL = &H2000&


    ' Font stuff
    Private Const OUT_DEFAULT_PRECIS = 0
    Private Const OUT_STRING_PRECIS = 1
    Private Const OUT_CHARACTER_PRECIS = 2
    Private Const OUT_STROKE_PRECIS = 3
    Private Const OUT_TT_PRECIS = 4
    Private Const OUT_DEVICE_PRECIS = 5
    Private Const OUT_RASTER_PRECIS = 6
    Private Const OUT_TT_ONLY_PRECIS = 7
    Private Const OUT_OUTLINE_PRECIS = 8

    Private Const CLIP_DEFAULT_PRECIS = 0
    Private Const CLIP_CHARACTER_PRECIS = 1
    Private Const CLIP_STROKE_PRECIS = 2
    Private Const CLIP_MASK = &HF
    Private Const CLIP_LH_ANGLES = 16
    Private Const CLIP_TT_ALWAYS = 32
    Private Const CLIP_EMBEDDED = 128

    Private Const DEFAULT_QUALITY = 0
    Private Const DRAFT_QUALITY = 1
    Private Const PROOF_QUALITY = 2

    Private Const DEFAULT_PITCH = 0
    Private Const FIXED_PITCH = 1
    Private Const VARIABLE_PITCH = 2

    Private Const ANSI_CHARSET = 0
    Private Const DEFAULT_CHARSET = 1
    Private Const SYMBOL_CHARSET = 2
    Private Const SHIFTJIS_CHARSET = 128
    Private Const HANGEUL_CHARSET = 129
    Private Const CHINESEBIG5_CHARSET = 136
    Private Const OEM_CHARSET = 255
    '
     
    Public Function fTextHeight(ctl As Control, _
    Optional ByVal sText As String = "", _
    Optional HeightTwips As Long = 0, Optional WidthTwips As Long = 0, _
    Optional TotalLines As Long = 0) As Long

    On Error Resume Next

    ' Call our function to calculate TextHeight
    ' If blWH=TRUE then we are TextHeight
    fTextHeight = fTextWidthOrHeight(ctl, True, _
    sText, HeightTwips, WidthTwips, TotalLines)

    End Function
     

    Public Function fTextWidth(ctl As Control, _
    Optional ByVal sText As String = "", _
    Optional HeightTwips As Long = 0, Optional WidthTwips As Long = 0, _
    Optional TotalLines As Long = 0) As Long

    On Error Resume Next

    ' If blWH=FALSE then we are TextWidth
    ' Call our function to calculate TextWidth
    fTextWidth = fTextWidthOrHeight(ctl, False, _
    sText, HeightTwips, WidthTwips)

    End Function


     Public Function fTextWidthOrHeight(ctl As Control, ByVal blWH As Boolean, _
     Optional ByVal sText As String = "", _
     Optional HeightTwips As Long = 0, Optional WidthTwips As Long = 0, _
     Optional TotalLines As Long = 0) As Long
     
     'Name                   FUNCTION() fTextWidthOrHeight
     '
     'Purpose:               Returns the Height or Width needed to
     '                       display the contents of the Control passed
     '                       to this function. This function
     '                       uses the Control's font attributes to build
     '                       a Font for the required calculations.
     '
     '                       This function replaces the Report object's TextHeight
     '                       and TextWidth methods which only work for a single line of text.
     '                       This function works with multiple lines of text and
     '                       also with both Forms and Reports.
     '
     'Version:               4.1
     '
     'Calls:                 Text API stuff. DrawText performs the actual
     '                       calculation to determine Control Height.
     '
     'Returns:               Height or width of Control in TWIPS required
     '                       to display current contents.
     '
     'Created by:            Stephen Lebans
     '
     'Credits:               If you want some...take some.
     '
     'Date:                  May 22, 2001
     '
     'Time:                  10:10:10pm
     '
     'Feedback:              Stephen@lebans.com
     '
     'My Web Page:           www.lebans.com
     '
     'Copyright:             Lebans Holdings Ltd.
     '                       Please feel free to use this code
     '                       without restriction in any application you develop.
     '                       This code may not be resold by itself or as
     '                       part of a collection.
     '
     'What's Missing:        Let me know!
     '
     '
     '
     'Bugs:
     'None at this point.
     '
     'Enjoy
     'Stephen Lebans
     
     '***************Code Start***************
     
     ' Structure for DrawText calc
     Dim sRect As RECT
     
     ' Reports Device Context
     Dim hDC As Long
     
     ' Holds the current screen resolution
     Dim lngDPI As Long
     
     Dim newfont As Long
     ' Handle to our Font Object we created.
     ' We must destroy it before exiting main function

     Dim oldfont As Long
     ' Device COntext's Font we must Select back into the DC
     ' before we exit this function.
     
     ' Temporary holder for returns from API calls
     Dim lngRet As Long
     
     ' Logfont struct
     Dim myfont As LOGFONT
     
     ' TextMetric struct
     Dim tm As TEXTMETRIC
     
     ' LineSpacing Amount
     Dim lngLineSpacing As Long
     
     ' Ttemp var
     Dim numLines As Long
     
     ' Temp string var for current printer name
     Dim strName As String
     
     ' Temp vars
     Dim sngTemp1 As Single
     Dim sngTemp2 As Single
     
     On Error GoTo Err_Handler
       
    ' If we are being called from a Form then SKIP
    ' the logic to Create a Printer DC and simply use
    ' the Screen's DC
       
    If TypeOf ctl.Parent Is Access.Report Then
        ' ***************************************************
        ' Warning! Do not use Printer's Device Context for Forms.
        ' This alternative is meant for Report's only!!!!!
        ' For a Report the best accuracy is obtained if you get a handle to
        ' the printer's Device Context instead of the Screen's.
        ' You can uncomment his code and comment out the
        ' apiGetDc line of code.
        ' We need to use the Printer's Device Context
        ' in order to more closely match Font height calcs
        ' with actual ouptut. This example simply uses the
        ' default printer for the system. You could also
        ' add logic to use the Devnames property if this
        ' report prints to a specific printer.
        strName = GetDefaultPrintersName
        hDC = CreateDCbyNum("WINSPOOL", strName, 0&, 0&)
        If hDC = 0 Then
            ' Error cannot get handle to printer Device Context
            Err.Raise vbObjectError + 255, "fTextWidthOrHeight", "Cannot Create Printer DC"
        End If
        ' ***************************************************
    Else
        ' Get handle to screen Device Context
        hDC = apiGetDC(0&)
    End If

     ' Were we passed a valid string
     If Len(sText & vbNullString) = 0 Then
         ' Did we get a valid control passed to us?
         'select case typeof ctl is
         Select Case ctl.ControlType
         
             Case acTextBox
             sText = Nz(ctl.Value, vbNullString)
             
             Case acLabel, acCommandButton
             sText = Nz(ctl.Caption, vbNullString)
             
             Case Else
             ' Fail - not a control we can work with
             fTextWidthOrHeight = 0
             Exit Function
         End Select
     End If

     
     ' Get current device resolution
     ' blWH=TRUE then we are TextHeight
     If blWH Then
         lngDPI = apiGetDeviceCaps(hDC, LOGPIXELSY)
     Else
         lngDPI = apiGetDeviceCaps(hDC, LOGPIXELSX)
     End If

     ' We use a negative value to signify
     ' to the CreateFont function that we want a Glyph
     ' outline of this size not a bounding box.
     ' Copy font stuff from Text Control's property sheet
     With ctl
         myfont.lfClipPrecision = CLIP_LH_ANGLES
         myfont.lfOutPrecision = OUT_TT_ONLY_PRECIS
         myfont.lfEscapement = 0
         myfont.lfFaceName = .FontName & Chr$(0)
         myfont.lfWeight = .FontWeight
         myfont.lfItalic = .FontItalic
         myfont.lfUnderline = .FontUnderline
         'Must be a negative figure for height or system will return
         'closest match on character cell not glyph
         myfont.lfHeight = (.fontsize / 72) * -lngDPI
         ' Create our temp font
         newfont = apiCreateFontIndirect(myfont)
     End With
     
         If newfont = 0 Then
             Err.Raise vbObjectError + 256, "fTextWidthOrHeight", "Cannot Create Font"
         End If

     ' Select the new font into our DC.
     oldfont = apiSelectObject(hDC, newfont)
     ' Use DrawText to Calculate height of Rectangle required to hold
     ' the current contents of the Control passed to this function.
     With sRect
       .Left = 0
       .Top = 0
       .Bottom = 0
       ' blWH=TRUE then we are TextHeight
       If blWH Then
         .Right = (ctl.Width / (TWIPSPERINCH / lngDPI)) - 10
       Else
       ' Single line TextWidth
         .Right = 32000
       End If
       
       ' Calculate our bounding box based on the controls current width
       lngRet = apiDrawText(hDC, sText, -1, sRect, DT_CALCRECT Or DT_TOP Or _
       DT_LEFT Or DT_WORDBREAK Or DT_EXTERNALLEADING Or DT_EDITCONTROL)
     
       ' Get TextMetrics. This is required to determine
       ' Text height and the amount of extra spacing between lines.
       lngRet = GetTextMetrics(hDC, tm)
     
       ' Cleanup
       lngRet = apiSelectObject(hDC, oldfont)
       ' Delete the Font we created
       apiDeleteObject (newfont)
       
      If TypeOf ctl.Parent Is Access.Report Then
        ' ***************************************************
        ' If you are using the Printers' DC then uncomment below
        ' and comment out the apiReleaseDc line of code below
        ' Delete our handle to the Printer DC
        lngRet = apiDeleteDC(hDC)
        ' ***************************************************
      Else
        ' Release the handle to the Screen's DC
        lngRet = apiReleaseDC(0&, hDC)
      End If
     
     ' Calculate how many lines we are displaying
     ' return to calling function. The GDI incorrectly
     ' calculates the bounding rectangle because
     ' of rounding errors converting to Integers.
     TotalLines = .Bottom / (tm.tmHeight + tm.tmExternalLeading)
     numLines = TotalLines
     
     ' Convert RECT values to TWIPS
     .Bottom = (.Bottom) * (TWIPSPERINCH / lngDPI) 'sngTemp2 ' + 20
     
     ' ***************************************************
     ' For A2K only!
     ' Now we need to add in the amount of the
     ' line spacing property.
     'lngLineSpacing = ctl.LineSpacing * (numLines - 1)
     'If numLines = 1 Then lngLineSpacing = lngLineSpacing + (ctl.LineSpacing / 2)
     ' Increase our control's height accordingly
     '.Bottom = .Bottom + lngLineSpacing
     
     
       ' Return values in optional vars
       ' Convert RECT Pixel values to TWIPS
       HeightTwips = .Bottom '* (TWIPSPERINCH / lngDPI)
       WidthTwips = .Right * (TWIPSPERINCH / lngDPI) '(apiGetDeviceCaps(hDC, LOGPIXELSX)))
     
       ' blWH=TRUE then we are TextHeight
       If blWH Then
         fTextWidthOrHeight = HeightTwips
       Else
        fTextWidthOrHeight = WidthTwips
       End If
    End With

    ' Exit normally
    Exit_OK:
    Exit Function

    Err_Handler:
    Err.Raise Err.Source, Err.Number, Err.Description
    Resume Exit_OK
    End Function

    Function GetDefaultPrintersName() As String
    ' This function is from Peter Walker.
    ' Check out his web site at:
    ' http://www.users.bigpond.com/papwalker/
    Dim success As Long
    Dim nSize As Long
    Dim lpKeyName As String
    Dim ret As String
    Dim posDriver
    'call the API passing null as the parameter
    'for the lpKeyName parameter. This causes
    'the API to return a list of all keys under
    'that section. Pad the passed string large
    'enough to hold the data. Adjust to suit.
    ret = Space$(8102)
    nSize = Len(ret)
    success = GetProfileString("windows", "device", "", ret, nSize)
    posDriver = InStr(ret, ",")
    GetDefaultPrintersName = Left$(ret, posDriver - 1)
    End Function