TheSwamp
Code Red => VB(A) => Topic started by: Mark on October 17, 2006, 02:13:06 PM
-
Does anyone have some code for retrieving TextBox text?
thanks
-
x = textbox1.value
-
you can also use textbox1.text
-
forgot to mention...
I'm assuming the textbox is in a userform..
ie
userform1.textbox1.text = userform2.textbox4.text
or as stated above substitute .text with .value
Come to think of it, .value might be better, but I'm not really sure if it matters.
-
I'm assuming the textbox is in a userform..
You'd be assuming correctly too. :-)
-
dont forget to
Dim x as String
so that x can take the value
-
Let me rephrase the question. How would you get TextBox.Text from within a Public Sub?
Public Sub RunMe()
'
' test module
'
Dim MsgText As String
Dim myFormInstance As MyForm
Set myFormInstance = New MyForm
With myFormInstance
.Label1.Caption = "A caption."
.TextBoxMsg.Text = "Enter some text"
End With
myFormInstance.Show
Unload myFormInstance
End Sub
-
Public Sub RunMe()
'
' test module
'
Dim MsgText As String
Dim myFormInstance As MyForm
Set myFormInstance = New MyForm
With myFormInstance
.Label1.Caption = "A caption."
.TextBoxMsg.Text = "Enter some text"
End With
myFormInstance.Show
dim text as string
text = myFormInstance.textboxmsg.text
msgbox text
Unload myFormInstance
End Sub
Coded blind but should work. The preferred way (IMO) would be to expose a property explicity for the purposes of granting access to said text but that might be another topic.
-
Thanks Michael, I was close .... real close! Missed the myFormInstance.textboxmsg.text part. :-)
-
Hey Mark, I quickly bashed out a small example AutoCAD VBA Project (ha, my first ever!) for you. Far from perfect but maybe it will help a bit.
See attached zip file. There is code in the form (frmMain) as well as the module (mdlMain).
Have fun.
:)
-
Thanks Michael.
I'll give it a go in the morning. :-)
-
My pleasure Mark, hope it helps.
:)
-
For those that cannot download due to security settings at their place of employ here is the code.
First, the form, named frmMain has 3 controls:
CommandButton, named btnOk
CommandButton, named btnCancel
TextBox, named tbxMain
frmMain code --
Option Explicit
Private myExitState As Boolean
Public Property Get ExitState() As Boolean
'' Return the value hosted our private member variable.
'' Since we have no corresponding Let Property statement
'' it's ostensibly read-only.
ExitState = myExitState
End Property
Public Property Get UserText() As String
'' Return the current value of the text in the tbxMain
'' object. While the way VB[A] is structured it allows
'' access to the object directly we should not go that
'' route [IMO]. A future implementation may use a
'' different object, or otherwise employ a different
'' implementation. Such changes should not affect clients
'' or consumers of the form. Also, this gives us the
'' opportunity to perform other activities before we
'' return the value, like qualifying, logging, whatever.
UserText = tbxMain.text
End Property
Public Property Let UserText(value As String)
'' Allow the client set the value of the txbMain object,
'' BUT NOT DIRECTLY. See balance of comments in the Get
'' UserText Property.
tbxMain.text = value
End Property
Private Sub btnOk_Click()
'' Set the state and then hide the form.
IndicateAccept
Me.Hide
End Sub
Private Sub btnCancel_Click()
'' Set the state and then hide the form.
IndicateCancel
Me.Hide
End Sub
Private Sub IndicateAccept()
'' As there may be more than one way this is triggered
'' let's have one procedure have responsibility for
'' setting the state. While this seems overkill because
'' we have but one little variable representing state,
'' in a big application there could be many things that
'' have to be done aside from merely setting said variable.
'' This gives us one entry point, and thus, only one area
'' to edit when things change, and more often than not
'' they will.
myExitState = True
End Sub
Private Sub IndicateCancel()
'' See comment in Sub IndicateAccept.
myExitState = False
End Sub
Private Sub UserForm_Activate()
'' Start with state indicating cancel.
IndicateCancel
End Sub
Private Sub UserForm_Initialize()
'' Start with state indicating cancel.
IndicateCancel
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'' If the user closed the form via the control
'' box instead of the [Ok] or [Cancel] buttons ...
If CloseMode = VbQueryClose.vbFormControlMenu Then
IndicateCancel
End If
End Sub
And then the module code, in a module named mdlMain --
Option Explicit
Public Sub Main()
Dim myForm As frmMain
Set myForm = New frmMain
'' Access and use the property(s) we exposed.
myForm.UserText = "Mark's great adventure."
'' Alrighty, let's show it.
myForm.Show
'' Program execution will not end up here until the
'' user closes the form, either by clicking the [Ok]
'' or [Cancel] buttons or via the control box (the
'' [x] in the top right corner).
If Not (myForm Is Nothing) Then
'' An error may be thrown if the user closes the
'' form via the control box because it will have
'' been unloaded but not yet nothing (let's trap
'' that possibility).
On Error GoTo ErrHandler
If myForm.ExitState Then
'' access the UserText Property we exposed
MsgBox _
"User pressed [Ok]." & vbCrLf & vbCrLf & _
"UserText = <" & _
myForm.UserText & ">"
Else
MsgBox "User pressed [Cancel]."
End If
Unload myForm
Set myForm = Nothing
Exit Sub
ErrHandler:
If Err.Number = -2147418105 Then
MsgBox _
"The user closed the form via the " & _
"form's control box."
Else
'' Uhhh, what the h3ll? An error we didn't
'' anticipate. Let's display the error
'' description.
MsgBox Err.Description
End If
Err.Clear
Resume OutOfHere
End If
OutOfHere:
Set myForm = Nothing
End Sub
See a problem, see bad advice etc? Let me / us know. Thanks!
-
And in one fell swoop MP reminds JM that he really is just a hack....
Looks like all great advice Michael! Now if only I could learn to incorporate that advice into the stuff I write......
Thanks for posting the code because I wasn't going to download the project (I've got enough things going now...) but Wow! what an eye opener.
/me goes back to writing code with hammer & chisel.....
-
And in one fell swoop MP reminds JM that he really is just a hack ...
It's true, I am a hack <not deserving of your praise> -- but I honestly try to get a little better each day! If you see anything wrong with that code or commentary, a distinct possibility, please let me know!
Thanks Jeff!
:)
-
WoW, this is beautifully written, Michael!
I really love the detailed comments as well as your sense of humor!
Thank you for sharing and for helping me to continue to learn as well!
-
Quick question. "Private myExitState As Boolean" declares the variable "myExitState" as a boolean and is only accessible to frmMain, correct?
-
WoW, this is beautifully written, Michael!
The wow is that you think so -- thanks Arizona!!
I really love the detailed comments ...
<Michael is smiling inside>.
...as well as your sense of humor!
I was funny? <reviewing post ...>
Thank you for sharing and for helping me to continue to learn as well!
Truly my pleasure -- we're all in a state of share and learn -- this is the little bit I'm delusional enough to think I know well enough to share -- and but a teeny, teeny fragment compared to the stuff I've learned at the swamp!!
:)
-
Quick question. "Private myExitState As Boolean" declares the variable "myExitState" as a boolean and is only accessible to frmMain, correct?
Yes sir!
:)
-
Quick question. "Private myExitState As Boolean" declares the variable "myExitState" as a boolean ...
Another tactic might be to exploit the MsgBox constants, and return the exit state as a function of the applicable constant, i.e. vbOKOnly, vbOKCancel ... I was just trying to keep the example relatively simple.
:)
-
Hi MP, nice work!
I modified your sub main code, particularly the error handler. I was wondering if I could get your opinion on it? I basically rearranged the error handler to a form that I have been using for a few years now and it seems to perform well. There is one big cavet with this type of strategy - you can not have any errors occur in the error handler itself :-)
Option Explicit
Public Sub Main()
Dim myForm As frmMain
''' moved the On Error statement as close to the begining of the routine so that any possible error would pass through the error handler
On Error GoTo ErrHandler
Set myForm = New frmMain
myForm.UserText = "Mark's great adventure."
myForm.Show
If Not (myForm Is Nothing) Then
If myForm.ExitState Then
'' access the UserText Property we exposed
MsgBox _
"User pressed [Ok]." & vbCrLf & vbCrLf & _
"UserText = <" & _
myForm.UserText & ">"
Else
MsgBox "User pressed [Cancel]."
End If
End If '''Moved this statement out of the errorhandler
'''Moved the OutOfHere label so that it doesn't need to be called explicitly if nothing went wrong, the code sort of falls into it :)
OutOfHere:
if Not myForm is nothing then
Unload myForm
Set myForm = Nothing
end if
Exit Sub
ErrHandler:
'''Changed from an if statement to a select case so that more errors can be easily accomodated for in the future
Select Case Err.Number
Case -2147418105
MsgBox _
"The user closed the form via the " & _
"form's control box."
Case Else
'' Uhhh, what the h3ll? An error we didn't
'' anticipate. Let's display the error
'' description.
MsgBox Err.Description
End Select
Err.Clear
Resume OutOfHere
End Sub
The biggest change from your original method is placing the "OutOfHere" label before the "ErrHandler" label and putting a select case statement within the error handler itself. My theory on setting up the error handler in this fashion was that I was able to make a template and simply copy and paste the error handling code into my routines (with a few changes like exit sub or exit function).
I would simply paste this into the body of the routine and go from there:
'Variable Declaration goes before the On Error Statement
On Error Goto ErrHandler
'Code goes here
ExitHere:
'Perform Cleanup here:
Exit Sub 'This needs to change depending on the type of routine - sub or function
ErrHandler:
Select Case Err.Number
'create a case statement to catch a specfic error number
Case Else
MsgBox Err.Number & ": " & Err.Description
End Select
Err.Clear
Resume ExitHere
-
Thanks for the kind words Troy, means a lot coming from you.
:)
Error handling is actually not a trivial subject, and my attempting to discuss it now <on the 2 +/- hours sleep I'm running on this morning> is probably unwise at best. However, I don't wish to leave your post dangling so I'll attempt something of a response.
Off the top of my head what strikes me first is the placement of the On Error Goto ... statement. As is in theory it could catch potential design errors (i.e. an error with the form, or no form at all) rather than execution errors, i.e. what happens after the form has been given life. Is that desired behavior? Is that likely to happen? I don't know; I'll have to muse a bit on that.
The subtitle to the preceding comment is that I <generally> try to put error handing code right where an error is likely to be thrown (where defensive coding cannot prevent) rather than a blanket handler, but that may be a flaw in my design rationale / style, not yours.
Code sporting a label in the middle of an If .. End If block <as mine did>? Probably poor form, given that it's easy enough to code a cleaner alternatate.
Branching on the error number via the select statement <as yours did>? Flexible: I should have shown same.
An aside, to be semi complete on error handing one should address turning on and off error handing, that is, one should turn off handling (via On Error Goto 0) if there is indeed no chance of error in a spread of code, especially if there is any intensive (e.g. looping) logic going on, restoring error handling if it becomes applicable again.
Finally (no try-catch ... pun intended) I tend to be shy of error templates as they tend to make me a bit lazy, i.e. relying on it rather than the specifics of the present implementation, but again, this is me recognizing my habits and shortcoming, not yours. The alternate view is that the template approach makes for constancy -- a good thing.
So as an overall strategy? I think what you posted is probably better than what I had. It's clear, consistant and logical -- what's not to like?
<kinda rambly, sorry?>
:)
-
I to realize that I am just a hack :-( Great coding MP, I learned something, and its not even sun up yet.
-
MP,
I appreciate your input!
Error handling is indeed a large topic and potential can o' worms :-)
The error handling method that I have presented is a little simplified from what I use. Normally I report back a substantial amount of information about the error and I have a custom logging class that will email me the information.
I have found that error handling (similar to what I presented) at the function/sub level works well in practice (for me). The other thing that I have found by wrapping the working code in an error handler (similar to a try catch block) the readability of the code is improved - which is important to me.
-
I to realize that I am just a hack :-( Great coding MP, I learned something, and its not even sun up yet.
Wish y'all wouldn't dismiss your own abilities and talents and disproportionately elevate mine -- we're all in this school together -- and take turns teachin', learnin', sharin' <sounds like a Journey song> ... !
:)
-
-- and take turns teachin', learnin', sharin' <sounds like a Journey song> ... !
< Larry the cable guy >That's funny right there
Have a nice nap Michael? :-)
-
MP,
I appreciate your input!
Thanks Troy, wish I'd had more sleeps before the post your refer to, might have been a litle more coherent!
The error handling method that I have presented is a little simplified from what I use. Normally I report back a substantial amount of information about the error and I have a custom logging class that will email me the information.
I use the logging class technique too! Mine isn't clever enough to email me, it just collects errors and returns them in a message box at the end of program execution (if any messages were collected). This is for an app that has to execute many different steps, regardless the success of any individual step, and for which "as generated" error reporting would be inefficient (and annoying). So each method is passed the sole instance of the logger, which is interogated at the end of the program.
But I digress! <spank>
I have found that error handling (similar to what I presented) at the function/sub level works well in practice (for me). The other thing that I have found by wrapping the working code in an error handler (similar to a try catch block) the readability of the code is improved - which is important to me.
And of paramount importance to me too. Sure hope that shows!
Thanks for sharing your thoughts Troy. Hope you didn't have any impression other than I thought your post, and strategy was a good one. I take notice every time you post -- always good, insightful techniques and info. Keep up the good works Troy!
:)
-
Have a nice nap Michael? :-)
Not long enough (1 sleep cycle; 90 minutes) but I'll take what I can get!
:)