PDA

View Full Version : OPTION BUTTON WOES



Greg
01-07-2008, 12:11 AM
Hi all,

Attached herewith is a document in which there are 3 frames containing two or three Option Buttons and some text boxes.

The Option Buttons work well enough but I want the buttons selected from any previous use to appear as already selected when the document is re-opened for its next use.

In other words, I want them to behave just like the text boxes on this document. No matter what I enter into the text boxes, I am able to re-use the previously entered text or I can change it if I need to.

I would add that I have been struggling make my dropown lists and option buttons work together but I'll save that problem for another session.

I hope you can help with my immediate problem.

Regards,

Greg.

fumei
01-07-2008, 11:38 AM
Explain: "when the document is re-opened for its next use.
"

Why is there an next use? Why would a "next" use even be calling the userform again? What is the business case for this?

You have some funny code. The Function SelectedButton for one. You never use it. Here is its code:Function SelectedButton() As String
Dim oCtrl As Control
For Each oCtrl In fra1.Controls
If oCtrl = True Then
SelectedButton = oCtrl.Caption
For Each oCtrl In fra2.Controls
If oCtrl = True Then
SelectedButton = oCtrl.Caption
For Each oCtrl In fra3.Controls
If oCtrl = True Then
SelectedButton = oCtrl.Caption
End If
End If
End If
Next
End FunctionYou are not closing things properly. It is a good thing you never call this function, as I think it would probably fail. Actually...I know it will fail. I just tried to use it.

Bottom line to your question is you will need something that will persist. A document variable...or....a bookmark Just like you are reading the text values in the bookmarks, and then writing them as text the values on the userform. The option buttons are Boolean. They are either on, or off. The default is off. ALL values on a userform are destroyed when the userform is unloaded.

The text values are as well. The difference being is that you write the text values into the document. You get them back into the userform...how? By reading the bookmarks.

So, do the same with your option buttons. In your Userform_Intialize add:If oBM("OverUnder").Range.Text = "Over" Then
OptOver.Value = True
Else
OptUnder.Value = True
End IfThe Option Buttons are in frames. Therefore only ONE can be true. That is the way frames work. The default shows as off, but what it really is, is Null. This is interpreted as False for practical purposes. So when you start the userform, neither - for example - "Under" or "Over" - is TRUE, that is, selected.

You can make them explicitly True (or False) with the logic above. BECAUSE a frame does not allow multiple options buttons to be True, if one is true, the other must be false. Which is exactly the logic in the code sample (for the Over/Under option buttons) does.

If the bookmark OverUnder is "Over", the OptionButton Over is True. This makes the OptionButton Under...False.

If the bookmark OverUnder is NOT "Over" - this is an IF statement so it is Boolean - then the userform OptionButton Under is True.

Please note the logic. There is no testing of the actual content of the bookmark OverUnder, except whether it is "Over".

If someone put a character (a "y" say...) into the bookmark - which of course they can do - and made it "Ovyer" - then the IF statement will always, always always come back as False. The bookmark is NOT "Over". Period.

If you wanted to actually test the text, then use a Select Case.Select Case oBM("OverUnder").Range.Text
Case "Over" ' it is "Over"
OptOver.Value = True ' also makes OptUnder False
Case "Under" ' it is "Under"
OptUnder.Value = True ' also makes OptOver False
Case Else ' it is neither "Over" or "Under"
Msgbox "What the HECK have you done to my form????"
End Select

fumei
01-07-2008, 12:35 PM
You can use the same type of logic when you are setting the bookmarks matched to the OptionButtons.If OptUnder.Value Then
FillABookmark "OverUnder", "Under"
ElseIf OptOver.Value Then
FillABookmark "OverUnder", "Over"
End IfThere is nothing inherently wrong with this, using ElseIf. But you could do it:If OptUnder.Value Then
FillABookmark "OverUnder", "Under"
Else
FillABookmark "OverUnder", "Over"
End IfDo you follow this? If OptUnder.Value is True then you...FillABookmark "OverUnder", "Under".

If OptUnder.Value is False then OptOver is True. There is no need to test ElseIF it is true. It has to be True....except if the user did not click either of them.

Now, if you are bringing values into the document, and there IS a value (either "Over" or "Under"), then fine. One of them will be made explicitly true, thus making the other false.

But suppose someone removed the text? They deleted either "Over" or "Under" from the bookmark. If you used just the "Over" IF statement, then it will always make OptUnder true. If you used the Select case, then you would get whatever you put for the Case Else.

One more reason to do proper error trapping.

But suppose you DO take care of that. What exactly do you do?

As it stand now, as you are reopening a document, and it has, say, "Under" in the bookmark. They run the userform, and the Over vs Under OptionButtons are both blank. The user is, say, supposed to - for this iteration - have it as "Over".

If they forget to change Over/Under, that is, BOTH OptOver and OptUnder are still blank, then the existing text in the bookmark ("Under") will remain.

You have no error trapping that checks to see if one of them IS clicked.

Making sure that one of them IS checked can be done either at the front-end (by logic that extracts the current value from the bookmark and MAKES one of the OptionButtons true), or at the back-end (by logic that checks to see if one of the OptionButtons is checked).

Let's look at your existing code again:If OptUnder.Value Then
FillABookmark "OverUnder", "Under"
ElseIf OptOver.Value Then
FillABookmark "OverUnder", "Over"
End If

If neither of them are checked - then neither

FillABookmark "OverUnder", "Under"

OR

FillABookmark "OverUnder", "Over"

will happen. Both your tests (your IF and your ELSEIF) are to see if an OptionButton is True. If neither are checked then both your tests return false, so neither FillABookmark will execute.

Logic. Pain in the butt isn't it?

Error trapping. Pain in the butt isn't it?

But we have had that rant before.....

One bottom line is careful scruntiny of IF statements. It is a common mistake to think that IF statements test the value, the content, of the object of the IF statement. They do, but ONLY, one thing. Ever. They test IF the object is the parameter given to test. The answer is either True, or False. Not content. Not "Under", or "Over", or "yaddaYadda".

The is answer is ONLY, "Yes, it is whatever", or "No, it is not whatever". With the critical concept being that "whatever" is strictly, absolutely, defined.

Greg
01-11-2008, 08:27 PM
Thanks Gerry.

I see now that my question was unclear. What I wanted to know was how to show a particular option button as being already selected on my userform.

The business case for this is simply that a selection made on first use of the document may be incorrect and upon returning to the document I want to see the chosen option button already selected on the userform.

For example if I selected "Over" but got interrupted and came back to the document later I could see that "Over" had already been selected.

I know that this is fairly basic stuff but as I am yet to master it I still need help.

Regards

Greg.

Greg
01-13-2008, 05:47 AM
Gerry,

Your shortened code doesn't work if there are three choices. That is to say if I add another line such as Else FillABookmark "OverUnder", "Inside" I get a compile errror messge "Else without If".

Have I misunderstood you? Is the short code only good for 2 options?

Greg.

fumei
01-14-2008, 11:30 AM
Else FillABookmark "OverUnder", "Inside"

Please post your actual code. normally, that would be written as:If somerthing Then
' do something
Else
FillABookmark "OverUnder", "Inside"
End If

fumei
01-14-2008, 11:59 AM
Ooops, sorry. i was not quite reading fully. Yes, an If..Then..Else statement covers TWO options. If...and Else.

Yes, you can do more than two possibilities with a If..Then...ElseIf...Then...ElseIf (three).

However, I would recommend that if you are testing ONE value, and it could have three possibilities, then use Select Case.

Select Case cboWhatever.Text ' what you are testing
Case "Over"
' do whatever is needed with that
Case "Under"
' do whatever is needed with that
Case "Yadda"
' do whatever is needed with that
Case ....
' etc. etc.
Case Else
' for just in case it is not ANY of your choices
' do whatever
End SelectYou need to clarify in your mind the difference.

IF.. (with either Else, or ElseIf) are Boolean. The only thing tested is whether the given parameter is True, or False. For the IF part, and any Else, or ElseIf, parts.

Yes or No.

Select Case, on the other hand, is NOT Boolean. It tests a given parameter value against whatever you state as a Case to test.

Greg
01-17-2008, 06:17 AM
Sorry Gerry. I don't get it.

My intention is to bring up the Userform with a particular selection on a check box displayed from the Userform's previous use.

For example if I had previously chosen "BAILIFF" I want to see the checkbox (or option button) diplaying the selection "BAILIFF" when I bring up the Userform for futher editing.

Why? The answer is simple. If, after preparing the document, I find a mistake, I (or a secretary) can bring up the Userform and make the change but if I overlook the checkbox it will default to "CLAIMANT", the first item on the list. If this isn't noticed the document gets printed with an error that it didn't previously have.

I'm sorry to labour this point but I haven't found anything in the KB and I'm starting to think I'm the only one bothered by it.

Regards,

Greg.

fumei
01-17-2008, 02:37 PM
"My intention is to bring up the Userform with a particular selection on a check box displayed from the Userform's previous use."

My emphasis. This is simply not possible. As I mentioned, all values on a userform are destroyed when the userform is unloaded. That is not to say that you can not get what was there, but you can only get it by reading that value from someplace you wrote it to.

"I'm sorry to labour this point but I haven't found anything in the KB and I'm starting to think I'm the only one bothered by it."

No, no, this is not belabouring. This is, in fact, the whole point of error trapping. And you most certainly are not the only one bothered by it. I have hammered this before. Error trapping is a pain in the butt. However, if you want professional level stuff, then that is what you have to do.

It is not hard, per se, but it IS tedious and nick-picky. And it is ONLY, repeat ONLY, a matter of logic.

So, when you start up your userform, you check against the existing values in the document.

I do not see a Baliff or Claimant in the file you attached earlier. I am looking at it right now. So I will use your liquidated/unliquidated/other option buttons. Adjusted demo back at you.

NOTE: this only checks the liquidated/unliquidated/other option buttons. You have to do the other part.

I will stress again, that this is only a matter of logic, of checking. There is nothing difficult here at all. If you want to do the level of error trapping you want - and I most certainly do not disagree - it is this kind of stuff you have to do.

Here is the demo code I added into your MatchCurrentBookmarks procedure. This is executed on _Initialize, which is the proper place. So the code below checks what is the current value of the bookmark, and logically sets the OptionButton to match that.Dim strTest As String

' the other stuff....

' for OptionButton Liquidated ONLY
' for demo purposes
strTest = ActiveDocument.Bookmarks("LiquidatedUnliquidated") _
.Range.Text
Select Case strTest
Case "Liquidated Amount"
optLiquidated.Value = True
Case "Unliquidated Amount"
optUnliquidated.Value = True
Case "Other Amount"
optOther.Value = True
Case Else
MsgBox "Oh-oh...something is wrong!"
End SelectSo the userform will make the option button match the text in the bookmark.

Keep thinking.....what if it is the first time? Is there something in the Liquidated bookmark? I will assume there should not be. Do you want a default option button pre-selected? Yes? No? If no - all three option buttons are blank - then you would use the Case Else....and do nothing.

Greg
01-18-2008, 12:29 AM
Hi Gerry,

I have adopted your "test" method to each of the option buttons in the subject document and the Userform just as I had hoped it would. Thank you.

However, I have not had the same success with the check boxes on a similar document. For you benefit the recalcitrant document is attached.

Each time I open the Userform I get a Compile Error message and "strTest =" is highlighted in the code. Of course this document is rather different from the first but I had hoped the "test" procedure would be more or less the same. Apparently not.

Are you able to point me in the right direction once more?

Regards,

Greg.

fumei
01-18-2008, 10:38 AM
"Each time I open the Userform I get a Compile Error message and "strTest =" is highlighted in the code. "

OK...please, please, I am not trying to be nasty, really I am not. But how many times have it been mentioned that when posting that there is an error message, it is required to state what that message is. What it says.

Yes, you get a Complie Error, and yes strTest is highlighted.

But...ahem...what does the rest of the error message say?

Complie Error
Variable not defined.

My bold.

"Variable not defined." strTest is highlighted. What do you think that means?

BTW: even if you DO declare (define) strTest, you will get more "Compile Error - Variable not defined." errors. I found two more variable/objects in your code that are not defined, and so the compiler will crash on those as well.

Just to help out....they are in the MatchCurrentBookmarks procedure.

You have:cboUnliquidated.Value = TrueThat's nice. Except you do not HAVE a object, or anything, named cboUnliquidated. Compile Error - Variable not defined.

You have:cboOther.Value = TrueThat's nice. Except you do not HAVE a object, or anything, named cboOther. Compile Error - Variable not defined.

You copied and pasted code didn't you.

Let me give you a hint. One of the good things about using Option Explicit, is that it also permits jumping to declared variables and procedures when you type.

In the editor, type:

"cbo" then Ctrl-Spacebar. Voila! The popup will jump to the first cbo"xxxxxxxxxx". In your case:

cboDefaultType, followed by cboFeeEarnerName.

But no cboUnliquidated, or cboOther. Because there are none named as such.

Using Ctrl-Spacebar is very very handy. You know all those Call FillABookmark("yadda...) lines?

You can shorten typing all that by typing:

Call Fill Ctrl-Spacebar (

Hitting Ctrl-Spacebar after "fill" will jump to FillABookmark as IntelliSense also knows about all your Subs as well. You do not need to press Enter, IntelliSense is also smart enough to know that the current item in the list (FillABookmark) is a Sub that takes parameters.

So "fill" Ctrl-Spacebar "(" goes right into being able to type the parameters.

In any case, you have your Complie Error because....you are using a variable, and you have not defined it. Just like the error messages states. There are two more.

And then, after you correct those, you will still get a compile error...as you have a inappropriate "Next" line.

You copied and pasted code, didn't you. Not a bad thing per se, but you have to be careful.

"Are you able to point me in the right direction once more?"

Yes. Read the full error message.

BTW: just to stress again how useful Ctrl-Spacebar is.

Say you have a Public variable in either Normal, or a loaded global.
Public objDoc As Word.Document

You use that anywhere by "objd". For example, typing:

set objd=doc Ctrl-Spacebar .doc Ctrl-Spacebar Tab Enter

Result? Set objDoc = Documents.Add

Or, in your document, say:cboFeeEarnerName.Value = True

can be entered by typing:

cbo Ctrl-Spacebar DownArrow .v=true

IntelliSense is your friend. It does take a little to get used to, but once you do, things can be much faster and less prone to error. If you enter variable or procedure names with it, you will only get valid ones.