Results 1 to 6 of 6

Thread: Class / Collection Debugging

  1. #1

    Thread Starter
    Hyperactive Member rjbudz's Avatar
    Join Date
    Jul 2005
    Location
    San Diego
    Posts
    262

    Class / Collection Debugging

    This may help to find problems when using Classes or Collections of classes. It's an application that creates a function that outputs to the Immediate Window all of a classes' variable values. (Yeah, that was long-winded but it is what it is.)

    Here’s how it works. From the class you already created, copy & paste the class header into the Input textbox. The app's output textbox will display a function. Click Copy to Clipboard, and then paste it at the bottom of your class.

    It's commented to death. I want new programmers to understand it. The code contains instructions and sample input/output

    Here's what you need to make it work:

    1) A new project

    2 Two textboxes on the default form:
    Set attributes to:
    (name) txtInput
    Font Courier New
    Font Size 10
    MultiLine True
    scroll 3-Both
    Text ""

    (name) txtOuput
    Font Courier New
    Font Size 10
    Locked True
    MultiLine True
    scroll 3-Both
    Text ""

    3) Two buttons :

    (name) cmdClearTextBoxes
    Text Clear Textboxes

    (name) cmdCopyToClipboard
    Text Copy To Clipboard


    4) This Code:

    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub txtInput_Change()
    4.     ' paste all class header variable declarations in Input textbox
    5.     ' copy text in Output textboxes to bottom of class
    6.     ' call function when you need to know
    7.  
    8. '   Example: paste to Input textbox
    9. '
    10. '   'local variable(s) to hold property value(s)
    11. '   Private mvarLineContent As String 'local copy
    12. '   'local variable(s) to hold property value(s)
    13. '   Private mvarEntryDate As String 'local copy
    14. '   'local variable(s) to hold property value(s)
    15. '   Private mvarEntryTime As String 'local copy
    16. '
    17. '   Ouptut textbox will contain:
    18. '
    19. '   Public Function ShowAll()
    20. '     ' For debugging. shows values of all variables in class instance
    21. '     ' SYNTAX: in class instance: [instanceName].ShowAll
    22. '     ' SYNTAX: in collection of class instance: [collectionName].([index])ShowAll
    23. '     '
    24. '     ' Author: Robert Budzynowski
    25. '
    26. '       Debug.Print "LineContent = {" & mvarLineContent & "}"
    27. '       Debug.Print "EntryDate = {" & mvarEntryDate & "}"
    28. '       Debug.Print "EntryTime = {" & mvarEntryTime & "}"
    29. '
    30. '   End Function
    31.  
    32.     Dim lines() As String
    33.     Dim x As Integer
    34.     Dim mvarLoc As Integer
    35.     Dim SpaceLoc As Integer
    36.     Dim classVarName As String
    37.     Dim varName As String
    38.     Dim trimmedLine As String
    39.     Dim processInput As Boolean
    40.    
    41.     ' no point if no class header data
    42.     mvarLoc = InStr(UCase(txtInput.Text), "MVAR")
    43.    
    44.     If mvarLoc = 0 Then
    45.         MsgBox "Text entered does not contain class header data", vbOKOnly, "Input Error"
    46.        
    47.         ' clear existing output text
    48.         txtOuput.Text = ""
    49.        
    50.         ' highlight text
    51.         txtInput.SelStart = 0
    52.         txtInput.SelLength = Len(txtInput.Text)
    53.         txtInput.SetFocus
    54.     End If
    55.      
    56.     ' function header & description
    57.     txtOuput = "Public Function ShowAll()" & vbCrLf
    58.     txtOuput = txtOuput & "  ' For debugging. shows values of all variables in class instance" & vbCrLf
    59.     txtOuput = txtOuput & "  ' SYNTAX: in class instance: [instanceName].ShowAll" & vbCrLf
    60.     txtOuput = txtOuput & "  ' SYNTAX: in collection of class instance: [collectionName].([index])ShowAll" & vbCrLf
    61.    
    62.     ' please give credit where credit is due!
    63.     txtOuput = txtOuput & "  ' " & vbCrLf
    64.     txtOuput = txtOuput & "  ' Author: Robert Budzynowski" & vbCrLf
    65.     txtOuput = txtOuput & vbCrLf
    66.  
    67.     ' create array element for each line in input textbox
    68.     lines = Split(txtOuput.Text, vbCrLf)
    69.    
    70.     ' process each line of input textbox
    71.     For x = 0 To UBound(lines)
    72.    
    73.         ' check for "mvar" text is line, if so we work with it
    74.         mvarLoc = InStr(UCase(lines(x)), "MVAR")
    75.        
    76.         If mvarLoc > 0 Then
    77.             ' valid line. Trim everything prior to start of var name (usually "Private ")
    78.             trimmedLine = Right(lines(x), Len(lines(x)) - mvarLoc + 1)
    79.            
    80.             ' find the space after the var name
    81.             SpaceLoc = InStr(trimmedLine, " ")
    82.          
    83.             ' the modular var name is before the space
    84.             classVarName = Trim(Left(trimmedLine, SpaceLoc))
    85.            
    86.             ' get the var name without the mvar prefix
    87.             varName = Right(classVarName, Len(classVarName) - Len("mvar"))
    88.                        
    89.             ' this is the line you want
    90.             txtOuput = txtOuput & vbTab & "Debug.Print " & Chr(34) & varName & " = {" & Chr(34) & " & " & classVarName & " & " & Chr(34) & "}" & Chr(34) & " " & vbCrLf
    91.            
    92.         End If
    93.  
    94.     Next x
    95.    
    96.     ' finish function text
    97.     txtOuput = txtOuput & vbCrLf
    98.     txtOuput = txtOuput & "End Function"
    99.  
    100. End Sub
    101.  
    102. Private Sub cmdClearTextBoxes_Click()
    103. ' clear textboxes
    104.     txtInput.Text = ""
    105.     txtOuput.Text = ""
    106. End Sub
    107.  
    108. Private Sub cmdCopyToClipboard_Click()
    109. ' copy output text
    110.   Clipboard.Clear
    111.   Clipboard.SetText txtOuput.Text
    112. End Sub
    113.  
    114. End Sub

  2. #2

    Thread Starter
    Hyperactive Member rjbudz's Avatar
    Join Date
    Jul 2005
    Location
    San Diego
    Posts
    262

    Re: Class / Collection Debugging

    BTW, the code listing above has an extra End Sub at the end. Delete it.

  3. #3
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Class / Collection Debugging

    Quote Originally Posted by rjbudz
    BTW, the code listing above has an extra End Sub at the end. Delete it.
    you can Edit your post and change it.

    aside from the little bugs, your code suffers from a few problems
    - the variables have to be consistently named
    - if you put the variable name in a comment it'll try and parse that too
    - it'll flake out on objects and arrays

    it's basically not robust enough to be usable by a wide range of people

    the VB code at the bottom will take the input (you can put the whole code in or just the declarations) and parse out the variables regardless of names. e.g.
    Code:
    Option Explicit
    
    Private m_cATBar As New cActiveTitleBar
    Private m_cSize As New cSizeWin
    
    Private Type POINTAPI
            x As Long
            y As Long
    End Type
    
    Private Declare Function ClientToScreen Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
    
    Private Const iGap As Integer = 8
    
    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 * 33
    End Type
    
    Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
    
    Private Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    
    Const ANSI_CHARSET As Long = 0
    Const FF_DONTCARE As Long = 0
    Const CLIP_LH_ANGLES As Long = &H10
    Const CLIP_DEFAULT_PRECIS As Long = 0
    Const OUT_TT_ONLY_PRECIS As Long = 7
    Const PROOF_QUALITY As Long = 2
    Const TRUETYPE_FONTTYPE As Long = &H4
    Const p_WIDTH As Long = 6
    Const p_HEIGHT As Long = 10
    
    Private m_cIl As cVBALImageList
    
    Private iColOver As Integer
    Private iColPress As Integer
    
    Private lTextHeight As Long
    Private lTextWidth As Long
    Private lSmallWidth As Long
    will give
    Code:
    Public Sub ShowAll()
        On Error Resume Next
        If Not TypeName(m_cATBar) = "Object" Then Debug.Print "m_cATBar (" & TypeName(m_cATBar) & ") = " & m_cATBar
        If Not TypeName(m_cSize) = "Object" Then Debug.Print "m_cSize (" & TypeName(m_cSize) & ") = " & m_cSize
        If Not TypeName(m_cIl) = "Object" Then Debug.Print "m_cIl (" & TypeName(m_cIl) & ") = " & m_cIl
        If Not TypeName(iColOver) = "Object" Then Debug.Print "iColOver (" & TypeName(iColOver) & ") = " & iColOver
        If Not TypeName(iColPress) = "Object" Then Debug.Print "iColPress (" & TypeName(iColPress) & ") = " & iColPress
        If Not TypeName(lTextHeight) = "Object" Then Debug.Print "lTextHeight (" & TypeName(lTextHeight) & ") = " & lTextHeight
        If Not TypeName(lTextWidth) = "Object" Then Debug.Print "lTextWidth (" & TypeName(lTextWidth) & ") = " & lTextWidth
        If Not TypeName(lSmallWidth) = "Object" Then Debug.Print "lSmallWidth (" & TypeName(lSmallWidth) & ") = " & lSmallWidth
    End Sub
    it should be fairly robust:
    VB Code:
    1. Private Sub Command1_Click()
    2.     Const sTAB As String = "    "
    3.     Dim sLines() As String
    4.     Dim sParts() As String
    5.     Dim sSub As String
    6.     Dim N As Long, I As Long
    7.  
    8.     If Len(Trim$(txtInput.Text)) = 0 Then Exit Sub
    9.    
    10.     sSub = "Public Sub ShowAll()" & vbCrLf & sTAB & "On Error Resume Next" & vbCrLf
    11.    
    12.     sLines = Split(txtInput.Text, vbCrLf)
    13.     For N = 0 To UBound(sLines)
    14.         ' Remove spaces
    15.         sLines(N) = Trim$(sLines(N))
    16.         ' make sure it's not blank
    17.         If Len(sLines(N)) Then
    18.             ' check it's not a comment
    19.             If Not Asc(sLines(N)) = 39 Then
    20.                 ' Get each part
    21.                 sParts = Split(sLines(N), " ")
    22.                     ' Check we have enough words
    23.                 If UBound(sParts) Then
    24.                     ' check it's a declaration
    25.                     Select Case UCase$(sParts(0))
    26.                         Case "PRIVATE", "PUBLIC", "DIM"
    27.                             ' check it's a variable
    28.                             Select Case UCase$(sParts(1))
    29.                                 Case "DECLARE", "CONST", "TYPE", "ENUM", "PROPERTY"
    30.                                 Case "FUNCTION", "SUB"
    31.                                     ' Exit
    32.                                     Exit For
    33.                                 Case Else
    34.                                     If InStr(sParts(1), "(") Then
    35.                                         ' It's an array
    36.                                     Else
    37.                                         ' it's valid - construct line:
    38.                                         ' If Not TypeName(varName) = "Object" Then Debug.Print "varName(" & TypeName(varName) & ") = " & varName
    39.                                         sSub = sSub & sTAB & "If Not TypeName(" & sParts(1) & _
    40.                                                ") = ""Object"" Then Debug.Print """ & sParts(1) & _
    41.                                                " ("" & TypeName(" & sParts(1) & ") & "") = "" & " & sParts(1) & vbCrLf
    42.                                     End If
    43.                             End Select
    44.                         Case "FUNCTION", "SUB"
    45.                             ' Exit
    46.                             Exit For
    47.                     End Select
    48.                 End If
    49.             End If
    50.         End If
    51.     Next N
    52.                            
    53.     sSub = sSub & "End Sub"
    54.     txtOutput.Text = sSub
    55. End Sub
    where it says It's an array you could add code to construct a loop through the array, but i couldn't be bothered

  4. #4

    Thread Starter
    Hyperactive Member rjbudz's Avatar
    Join Date
    Jul 2005
    Location
    San Diego
    Posts
    262

    Re: Class / Collection Debugging

    The pvital line of code should be

    VB Code:
    1. lines = Split(txtInput.Text, vbCrLf)

    not

    VB Code:
    1. lines = Split(txOutput.Text, vbCrLf)

  5. #5

    Thread Starter
    Hyperactive Member rjbudz's Avatar
    Join Date
    Jul 2005
    Location
    San Diego
    Posts
    262

    Re: Class / Collection Debugging

    The object of the code submission was to take a simple class definition and allow the developer to quicly create something to output the variables for troubleshooting. I, myself, seldom use classes to hold objects. I'm glad you were able to flesh it out to be as robust as you have.

  6. #6
    Oi, fat-rag! bushmobile's Avatar
    Join Date
    Mar 2004
    Location
    on the poop deck
    Posts
    5,592

    Re: Class / Collection Debugging

    Quote Originally Posted by rjbudz
    The object of the code submission was to take a simple class definition and allow the developer to quicly create something to output the variables for troubleshooting. I, myself, seldom use classes to hold objects. I'm glad you were able to flesh it out to be as robust as you have.
    well i mainly wrote it so that it would pick up a variable regardless of what it was called - i don't think i've ever written any piece of code in which every variable name has a common section.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width