Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 410
  • Last Modified:

passing an object name into a procedure

Private Sub HighLiteMe(oObj As Control)
 oObj.SelStart = 0
 oObj.SelLength = Len(oObj.Text)
 oObj.SetFocus
End Sub
This is used to highlite text in a text box and set the focus to that text box.
It works fine, but I have to hard code the object name as opposed to using a memory
variable.  That is
Menu01 is the name of a text box
HighLiteMe(Menu01)   works fine BUT
HighLiteMe(mTextBoxName)  where mTextBoxName contains the string "Menu01" does not
work, it tells me "wrong datatype"


0
dastaub
Asked:
dastaub
  • 4
  • 3
1 Solution
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
If you want to use a string variable then you would have to write a function to iterate all controls and return the control with the matching name.  Then pass that control to your HighLiteMe() sub.

Idle_Mind
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Here is one way to do it:

Private Sub Command1_Click()    
    If controlWithNameExists("Menu01") Then
        HighLiteMe(getControlFromName("Menu01"))
    End If
End Sub

Private Function controlWithNameExists(controlname As String) As Boolean
    Dim curForm As Form
    Dim curControl As Control
   
    controlWithNameExists = False
    For Each curForm In Forms
        For Each curControl In curForm.Controls
            If UCase(curControl.Name) = UCase(controlname) Then
                controlWithNameExists = True
                Exit Function
            End If
        Next curControl
    Next curForm
End Function

Private Function getControlFromName(controlname As String) As Control
    Dim curForm As Form
    Dim curControl As Control
   
    For Each curForm In Forms
        For Each curControl In curForm.Controls
            If UCase(curControl.Name) = UCase(controlname) Then
                Set getControlFromName = curControl
                Exit Function
            End If
        Next curControl
    Next curForm
End Function
0
 
wsteegmansCommented:
> HighLiteMe(mTextBoxName)  where mTextBoxName contains the string "Menu01" does not work,
> it tells me "wrong datatype"

That's because the parameter of your procedure is a Control. You're passing a String if you call it like HighLiteMe(Menu01). So, the Control datatype and the String datatype are not compatible, so that's why the Wrong Datatype Error.

If you want both options (passing a control, or passing a string) you have use the Variant DataType. This DataType is sort of general DataType that always works!

Remark! Don't use this Variant DataType too much, because using it, every time you use it, there occurrs a datatype conversion to the real (stored) datatype. Suppose, you pass a string. This string is stored in the Variant datatype. But, if you use it, it's first converted from Variant to String (takes some time). So, for this case a Variant is ideal, but in other cases, don't use it.

Because your HighLiteMe Procedure is a Private Procedure, I suppose it's located in your form's code?
So, change your code like this, and it handles both possibilities:

Private Sub HighLiteMe(aControl As Variant)
   
    Dim ctrl As Control
   
' - Check if passed a Object (or a String => Else)
    If IsObject(aControl) Then
       Set ctrl = aControl
    Else
' - - - Look in the Controls Collection for the Control with name aControl
        Set ctrl = Me.Controls.Item(CStr(aControl))
    End If
   
    With ctrl
        .SelStart = 0
        .SelLength = Len(.Text)
        .SetFocus
    End With
End Sub
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Mike TomlinsonMiddle School Assistant TeacherCommented:
wsteegmans,

Nice code.  However, we can do even better by adding error trapping.

Set ctrl = Me.Controls.Item(CStr(aControl)) ' <---- Will cause error if a control matching aControl string is not found

With ctrl ' <---- Will cause error if control doesn't support properties in With clause
    .SelStart = 0
    .SelLength = Len(.Text)
    .SetFocus
End With

Try this instead:

Private Sub HighLiteMe(aControl As Variant)
    On Error GoTo nosuchcontrol
   
    Dim ctrl As Control
   
' - Check if passed a Object (or a String => Else)
    If IsObject(aControl) Then
       Set ctrl = aControl
    Else
' - - - Look in the Controls Collection for the Control with name aControl
        Set ctrl = Me.Controls.Item(CStr(aControl))
    End If
   
    With ctrl
        .SelStart = 0
        .SelLength = Len(.Text)
        .SetFocus
    End With
    Exit Sub
   
nosuchcontrol:
    MsgBox "Control Not Found or Does Not Support Desired Properties"
End Sub

Regards,

Idle_Mind
0
 
wsteegmansCommented:
Hi Idle_Mind,

Thx for reviewing the code. However, Errorhandling is something you ALWAYS have to do, in every program and in every procedure or function. But, every person or company has it's own strategy for that. So, mine opinion is that you don't provide it in the examples here on EE.

But, if you wan't to zoom on errorhandling? Normally you write a Class or Module that handles all errors in your program. This class or Module will also store your Userdefined ErrorID's and Descriptons. You also define what to do next after the error (Resume, Resume Next or Exit) So, when an error occurs, you call this general ErrorHandler. An example could be:

Exit_HighLiteMe:
    Exit Sub

Err_HighLiteMe:
    Select Case ErrorHandler(ERRID_NOCONTROLFOUND)
        Case errResult_Resume
            Resume
        Case errResult_ResumeNext
            Resume Next
        Case errResult_Exit
            Goto Exit_HighLiteMe
    End Select

However, you will write such errorhandling in a main procedure (in your form or in your class ...). If your write 'general' procedures or functions, who are always called by a parent procedure/function, you don't want to handle the error in this subprocedure/subfunction. Your parent procedure will do that.

Suppose, you have a library with lots of procedures and function. Your program can be called or as desktop application, or as background program. When it's running like a desktop app, all errors will be shown as a dialogbox. However, if you call it as a background program (processing lot's of datachanges in a DB for example), all errors are written to the EventViewer or a LogFile.

So, even better is just to throw an exception, so it can be handled by the calling procedure. When writing big programs, putting a MsgBox everywhere is not a preferred strategy.

A general userfriendly programming tip:
Don't show too much messageboxes in your programs. Users will be used to it, and after a wile, they don't read the message, but just click on OK (and that's what you don't want!)

So, in our case, when there is an error, that's because there is a mistake in the code (the programmer passed the wrong variable/parameter). The user didn't do anything wrong, so don't give him a messagebox!

Example:

Exit_HighLiteMe:
    Exit Sub

Err_HighLiteMe:
    Err.Raise ERRID_NOCONTROLFOUND, ERRDESC_NOCONTROLFOUND

Regards.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Nicely put wsteegmans.

Judging by the original question though, dastaub is not a very experienced programmer in Visual Basic so I wanted to keep it simple, yet functional while covering all bases. =)

I always bulletproof my code and just as you suggest use Classes and Events to handle my errors.

Idle_Mind
0
 
dastaubAuthor Commented:
This is the code that I pasted then edited from the answers and it worked.

Private Sub HighLiteMe3(aControl As Variant)
Dim ctrl As Control
Set ctrl = Me.Controls.Item(CStr(aControl))
With ctrl
    .Text = mMenuText
    .SelStart = 0
    .SelLength = Len(.Text)
    .SetFocus
End With
End Sub

P.S. Idle_Mind - your mind is clearly not idle.
0
 
wsteegmansCommented:
dastaub,

Thx for helping you! Howerver, if more then one person helps you with the solution, or if people change other people's code to optmize it, you give them both points (split it) -> Accepted and Assisted Answers.

Something to remember with future questions. All experts are here to help everybody in the first place. However, if they desirve some honour, they also would like to get it ;-)
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now