Solved

passing an object name into a procedure

Posted on 2003-11-22
8
386 Views
Last Modified: 2010-05-01
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
Comment
Question by:dastaub
  • 4
  • 3
8 Comments
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
 
LVL 7

Expert Comment

by:wsteegmans
Comment Utility
> 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
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 500 total points
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 7

Expert Comment

by:wsteegmans
Comment Utility
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
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
 

Author Comment

by:dastaub
Comment Utility
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
 
LVL 7

Expert Comment

by:wsteegmans
Comment Utility
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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now