Ben_S

AutosizeColumnWidths for Access

Aug 11th, 2020
469
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ' This is a nice-to-have module for developers and power users.
  2.  
  3. Option Compare Database
  4. Option Explicit
  5.  
  6. Public Function AutosizeColumnWidths()
  7. ' Autosize column widths of open Table/Query datasheet.
  8. ' All columns are processed but the width is based on the currently visible rows.
  9. ' Concept from http://wvmitchell.blogspot.com/2010/08/resize-query-columns.html
  10. ' This is called by the AutoKeys macro, ^R
  11. ' BS 1/23/2018
  12. ' BS 9/5/2018:  Added support for the active control being on a form that is in datasheet view.
  13. ' BS 9/16/2018: Added support for a memo field configured as RichText.  It will be set at a
  14. '               fixed width.  Special thanks to Jack Stockton and James Pilcher.
  15.  
  16.     Dim frm As Form
  17.     Dim ctl As Control
  18.     Dim prp As DAO.Property
  19.     Dim T As Single
  20.  
  21.     On Error GoTo ErrorHandler
  22.  
  23.     Set frm = Screen.ActiveDatasheet
  24.  
  25.     If (frm Is Nothing) Then
  26.         ' See if the active control is on a subform.
  27.        Set frm = Screen.ActiveControl.Parent
  28.     End If
  29.  
  30.     If Not (frm Is Nothing) Then
  31.         If frm.CurrentView = 2 Then    ' DataSheet view
  32.  
  33.             T = Timer
  34.            
  35.             'Debug.Print frm.Name, frm.RecordSource
  36.            For Each ctl In frm.Controls
  37.                 'Debug.Print frm.name, ctl.name
  38.                
  39.                 Select Case ctl.Name
  40.                     '--- HARD CODED SPECIAL CASES ---  Adjust for the developer preference.
  41.                    ' Check for common fields that typically have a heading that is wider
  42.                    ' than the data, or aren't interesting enough to expand completely.
  43.                    '------- Oracle Data ------
  44.                    Case "EMPLOYEE_NUMBER": ctl.ColumnWidth = 1200
  45.                     Case "GLOBAL_EMPLOYEE_NUMBER": ctl.ColumnWidth = 1500
  46.                     Case "EMPLOYEE_GEN": ctl.ColumnWidth = 1500
  47.                     Case "EXPENDITURE_ENDING_DATE": ctl.ColumnWidth = 1200
  48.                     Case "EXPENDITURE_ENDING_DATE": ctl.ColumnWidth = 1200
  49.                     Case "TERMINATION_DATE": ctl.ColumnWidth = 1200
  50.                     Case "EXPENDITURE_CATEGORY": ctl.ColumnWidth = 1500
  51.                     Case "PROJECT_NUMBER": ctl.ColumnWidth = 1200
  52.                     Case "GDW_PROJECT_NUMBER": ctl.ColumnWidth = 1000
  53.                     Case "FISCAL_YEAR": ctl.ColumnWidth = 600
  54.                     Case "YEAR": ctl.ColumnWidth = 600
  55.                     Case "COST_CENTER": ctl.ColumnWidth = 800
  56.                     Case "GDW_COST_CENTER": ctl.ColumnWidth = 800
  57.                     Case "QUANTITY": ctl.ColumnWidth = 1000
  58.                     Case "EMPSTATUS": ctl.ColumnWidth = 400
  59.                     Case "MATCH_FLAG": ctl.ColumnWidth = 500
  60.                     Case "EXPENDITURE_ITEM_ID": ctl.ColumnWidth = 1200
  61.                     Case "CLIENT_NAME": ctl.ColumnWidth = 4000
  62.                     Case "Tap_UoM": ctl.ColumnWidth = 450
  63.                
  64.                     Case Else
  65.                         If IsRichText(frm.RecordSource, ctl.Properties("ControlSource")) Then
  66.                             ' Set column to a fixed width because -2 will result in a 1" width on a RichText column.
  67.                            ctl.ColumnWidth = 8000
  68.                         Else
  69.                             ctl.ColumnWidth = -2    ' Set to auto-width based on visible cells in this column
  70.                        End If
  71.  
  72.                         If ctl.ColumnWidth > 8000 Then
  73.                             ctl.ColumnWidth = 8000    'Prevent width greater than 8000 twips
  74.                        End If
  75.                
  76.                 End Select
  77.                
  78.                 If Timer - T > 1 Then
  79.                     ' If it takes more than a second to process controls, show the hourglass
  80.                    ' and refresh the screen after every second so the user sees it is working.
  81.                    ' This was first developed for a table linked to a large .CSV file.
  82.                    DoCmd.Hourglass True
  83.                     DoEvents
  84.                     T = Timer
  85.                 End If
  86. Next_ctl:
  87.             Next ctl
  88.  
  89. '            Beep    ' Let the user know something ran.  Disable it if you get annoyed.
  90.        End If
  91.     End If
  92.  
  93. Exit_Function:
  94.     Set ctl = Nothing
  95.     Set frm = Nothing
  96.     DoCmd.Hourglass False
  97.     Exit Function
  98.  
  99. ErrorHandler:
  100.     If err.Number = 2484 Then
  101.         'There is no active datasheet.
  102.        Resume Next
  103.  
  104.     ElseIf err.Number = 2474 Then
  105.         'The expression you entered requires the control to be in the active window.
  106.        'Probably no ActiveControl
  107.        Resume Next
  108.        
  109.     ElseIf err.Number = 2467 Then
  110.         'The expression you entered refers to an object that is closed or doesn't exist.
  111.        'Probably no ActiveControl
  112.        Resume Next
  113.        
  114.     ElseIf err.Number = 438 Then
  115.         'Object doesn't support this property or method
  116.        Resume Next_ctl
  117.  
  118.     ElseIf err.Number = 2455 Then
  119.         'You entered an expression that has an invalid reference to the property ControlSource.
  120.        Resume Next_ctl
  121. '        If ctl.Name = "Child0" Then
  122. '            ' Ignore the subdatasheet control
  123. '            Resume Next_ctl
  124. '        Else
  125. '            MsgBox Err.Number & " " & Err.Description & vbCrLf & "in procedure AutosizeColumnWidths", vbOKOnly + vbCritical, "Error"
  126. '            Debug.Print "Error: " & Err.Number & " - " & Err.Description
  127. '            Debug.Print "Control: " & ctl.Name
  128. '            Resume Exit_Function
  129. '            Resume
  130. '        End If
  131.    Else
  132.         MsgBox err.Number & " " & err.Description & vbCrLf & "in procedure AutosizeColumnWidths", vbOKOnly + vbCritical, "Error"
  133.         Debug.Print "Error: " & err.Number & " - " & err.Description
  134.         Debug.Print "Control: " & ctl.Name
  135.         Resume Exit_Function
  136.         Resume
  137.     End If
  138.  
  139. End Function
  140.  
  141.  
  142. Public Function ResetColumnWidths()
  143. ' Reset the column widths of open Table/Query datasheet to the default ~1.0" width.
  144. ' This is called by the AutoKeys macro, CTRL+SHIFT+R
  145. ' Set all Column widths back to -1
  146. ' BS 9/16/2018
  147.  
  148.     Dim frm As Form
  149.     Dim ctl As Control
  150.     Dim prp As DAO.Property
  151.  
  152.     On Error GoTo ErrorHandler
  153.  
  154.     Set frm = Screen.ActiveDatasheet
  155.  
  156.     If (frm Is Nothing) Then
  157.         ' See if the active control is on a subform.
  158.        Set frm = Screen.ActiveControl.Parent
  159.     End If
  160.  
  161.     If Not (frm Is Nothing) Then
  162.         If frm.CurrentView = 2 Then    ' DataSheet view
  163.  
  164. '            Debug.Print frm.Name, frm.RecordSource
  165.  
  166.             For Each ctl In frm.Controls
  167. '                Debug.Print ctl.name
  168.                ctl.ColumnWidth = -1    ' Set to default width
  169. Next_ctl:
  170.             Next ctl
  171.  
  172. '            Beep    ' Let the user know something ran.
  173.        End If
  174.     End If
  175.  
  176. Exit_Function:
  177.     Exit Function
  178.  
  179. ErrorHandler:
  180.     If err.Number = 2484 Then
  181.         'There is no active datasheet.
  182.        Resume Next
  183.  
  184.     ElseIf err.Number = 438 Then
  185.         'Object doesn't support this property or method
  186.        Resume Next_ctl
  187.  
  188.     Else
  189.         MsgBox err.Number & " " & err.Description & vbCrLf & "in procedure ResetColumnWidths", vbOKOnly + vbCritical, "Error"
  190.         Resume Exit_Function
  191.         Resume
  192.     End If
  193.  
  194. End Function
  195.  
  196.  
  197.  
  198. Public Function IsRichText(strTableName As String, strFieldName As String) As Boolean
  199. ' Return TRUE if the passed field is Memo/Long Text with the
  200. ' Text Format set as "Rich Text"
  201. ' This is from James Pilcher and Jack Stockton
  202.  
  203.     On Error GoTo PROC_ERR
  204.  
  205.     Dim db  As DAO.Database
  206.     Dim tdf As DAO.TableDef
  207.     Dim qdf As DAO.QueryDef
  208.     Dim fld As DAO.Field
  209.     Dim prp As DAO.Property
  210.  
  211.     Set db = CurrentDb
  212.  
  213.     'Test if Table Exists
  214.    If Not IsNull(DLookup("Name", "MSysObjects", "Name='" & strTableName & "' And Type In (1,4,6)")) Then
  215.         Set tdf = db.TableDefs(strTableName)
  216.         Set fld = tdf.Fields(strFieldName)
  217.     Else
  218.         Set qdf = db.QueryDefs(strTableName)
  219.         Set fld = qdf.Fields(strFieldName)
  220.     End If
  221.  
  222.     If fld.Type = dbMemo Then
  223.         On Error Resume Next
  224.         Set prp = fld.Properties("TextFormat")
  225.         If err.Number = 0 Then
  226.             IsRichText = prp.Value ' 1=Rich Text, 0=Plain Text
  227.        End If
  228.     End If
  229.  
  230. PROC_EXIT:
  231.     If Not prp Is Nothing Then _
  232.        Set prp = Nothing
  233.     If Not fld Is Nothing Then _
  234.        Set fld = Nothing
  235.     If Not tdf Is Nothing Then _
  236.        Set tdf = Nothing
  237.     If Not qdf Is Nothing Then _
  238.        Set qdf = Nothing
  239.     If Not db Is Nothing Then _
  240.        Set db = Nothing
  241.  
  242.     Exit Function
  243.    
  244. PROC_ERR:
  245.     If err.Number = 3265 Then
  246.         Resume PROC_EXIT
  247.         Resume
  248.     ElseIf err.Number = 3075 Or err.Number = 3223 Then
  249.         ' 3075:  Syntax error (missing operator) in query expression <strTableName>
  250.        ' 3223:  <strTableName> is invalid because it is too long, or contains invalid characters.
  251.        ' This happens when strTableName is a SQL statement and is passed to DLookup().
  252.        Resume PROC_EXIT
  253.         Resume Next
  254.     Else
  255.         MsgBox "Error " & err.Number & " (" & err.Description & ") in procedure IsRichText"
  256.         Resume PROC_EXIT
  257.         Resume
  258.     End If
  259. End Function
  260.  
Add Comment
Please, Sign In to add comment