PDA

View Full Version : Select Case Oddity



gmaxey
03-17-2014, 12:48 PM
Hi,

I prepared a template for another person and everything worked fine on my end, but on their end they were not getting a prefix text as required.

I isolated the problem to a Select Case statement, but I can't for the life of me figure out what the issue could be. As sample of the code is provided below. First a document variable is set to either "Test 1" or "Test 2" and then depending on that variable, two prefix strings are defined.

For some reason on the other person's computer, the Select Case statement isn't working correctly. The expected value of the variable is present and returned, but on their system it just blows right passed the Case "Test 1" statements yet works like a champ using If ElseIf End If:-(

Anyone seen anything like this before or have an explanation? Thanks.


Sub CaseStatementOddity()
Dim strPrefix1 As String
Dim strPrefix2 As String
Debug.Print ActiveDocument.Variables("varTest").Value 'Returned "Test 1"
Select Case ActiveDocument.Variables("varTest").Value
Case "Test 1"
strPrefix1 = "A - "
strPrefix2 = "B - "
Case "Test 2"
strPrefix1 = "C - "
strPrefix2 = "D - "
End Select
Debug.Print strPrefix & " " & strPrefix2 'Returns "A - B -" on my system. Returns "" on other system.
End Sub
Sub WordAround()
Dim strPrefix1 As String
Dim strPrefix2 As String
If ActiveDocument.Variables("varTest").Value = "Test 1" Then
strPrefix1 = "A - "
strPrefix2 = "B - "
ElseIf ActiveDocument.Variables("varTest").Value = "Test 2" Then
strPrefix1 = "C - "
strPrefix2 = "D - "
End If
Debug.Print strPrefix & " " & strPrefix2 'Returns "A - B -" on both systems.
End Sub

fumei
03-17-2014, 01:01 PM
Weird. If you give strPrefix1 and strPrefix2 a value BEFORE the Select Case, do they end up the same, or do they change to ""

snb
03-17-2014, 01:21 PM
Are we comparing the same strings ?
Select case seems to be non case sensitive.


Sub M_snb()
MsgBox ActiveDocument.FullName
MsgBox ThisDocument.FullName

MsgBox ThisDocument.Variables("varTest")
MsgBox ActiveDocument.Variables("varTest")

MsgBox Len(ThisDocument.Variables("varTest"))
MsgBox Len(ActiveDocument.Variables("varTest"))

MsgBox StrComp(ActiveDocument.Variables("varTest"), "Test 1", vbBinaryCompare)

Select Case lcase(ThisDocument.Variables("varTest"))
Case "test 1"
strPrefix1 = "A - "
strPrefix2 = "B - "
Case "test 2"
strPrefix1 = "C - "
strPrefix2 = "D - "
End Select

msgbox strprefix1 & strprefix2
End Sub

gmaxey
03-17-2014, 01:22 PM
Gerry,

I'll have to confirm with the guy on the other end, but I don't thing they would change back to "". I watched him step through his code line by line. When Case "Test 1" is highlighted and then executed, the highlight jumps to Case "Test 2" completely bypassing what it should normally do.

Now there is more information and I really should have reported this from the beginning.

If he creates a new document based on the template then all works as expected. The Case statement executes as required. However, when he attaches the template to existing file created with a different template, the problem occurs. However, he did send me one of these pre-existing files and when I attach the template is still works as expected.

Baaaaafulled ;-)

gmaxey
03-17-2014, 01:45 PM
snb,

11415

Paul_Hossler
03-17-2014, 02:25 PM
Select Case Trim(ActiveDocument.Variables("varTest").Value)


Maybe there's a trailing space??


Paul

snb
03-17-2014, 02:58 PM
Exactly what I 'see' using:


ActiveDocument.Variables("varTest") = "B767 "
MsgBox StrComp(ActiveDocument.Variables("varTest"), "B767", vbBinaryCompare)
Debug.Print ActiveDocument.Variables("varTest")


That's why I introduced strcomp

gmaxey
03-17-2014, 04:40 PM
Guys (Paul, snb),

You're kind of losing me. There is no trailing space in the document variable. If there were, then I don't thing the If statement wouldn't work either, right?

The document variable value is "Test 1"
The result of the Debug.Print is "Test 1"
The If condition is "Test 1" and it works on my system and his.
The Case is "Test 1" and it works on my system and his if he creates a new document from the template, but it doesn't work if he attaches the template to an existing document.

I'm completely stumped, but unless someone has seen this before, I'm willing to concede to the adage that Word never cease to perplex ;-)

fumei
03-17-2014, 05:39 PM
So it is NOT a factor of your system versus another system, but a factor of a document created from the template versus ATTACHING the template. Hmmmm. That speaks to the document variable. But...you say Debug.Print returns the correct value. Hmmmm. yup another Word perplex.

gmaxey
03-17-2014, 05:55 PM
Gerry,

Yes and no. I can repeat the steps that he does to produce the error on his end but it doesn't reproduce it on my end. Well, I don't have the original template on my end so that might be a factor. Regardless, it definitely twists the rope. When the guy first reported it and looking at the code, my initial reaction was "impossible." Well, I ate that crow and started picking feathers out of my teeth when I watched him step through the code on his PC via Skype and observed execution blow right past the Case statement. Fortunately the If statement worked or I would still be bouncing off the walls ;-)

SamT
03-17-2014, 07:19 PM
What happens if you change

Select Case ActiveDocument.Variables("varTest").Value
Case "Test 1"
to


Dim MyVar As [Variant|String]
MyVar = ActiveDocument.Variables("varTest").Value
Select Case MyVar
Case "Test 1"

gmaxey
03-17-2014, 07:57 PM
Sam,

Nothing happens here of course, because it works either way. I'm not positive I can get the guy on the other end to troubleshoot further or not. He has a working solution (the If Elseif End If method) and may have lost interest. I'll try though. Thanks.

fumei
03-17-2014, 11:09 PM
Yes and no. I can repeat the steps that he does to produce the error on his end but it doesn't reproduce it on my end. Well, I don't have the original template on my end so that might be a factor. You do not have the actual file that is attached as a template? Hmmm. Bummer.

snb
03-18-2014, 03:15 AM
Without seeing the 'culprit' (nor the if..elseif solution) it's hard to tell.

gmaxey
03-18-2014, 06:43 AM
Well, like in the original post, the workaround (misspelled wordaround) I posted here:


Sub WordAround()
Dim strPrefix1 As String
Dim strPrefix2 As String
If ActiveDocument.Variables("varTest").Value = "Test 1" Then
strPrefix1 = "A - "
strPrefix2 = "B - "
ElseIf ActiveDocument.Variables("varTest").Value = "Test 2" Then
strPrefix1 = "C - "
strPrefix2 = "D - "
End If
Debug.Print strPrefix & " " & strPrefix2 'Returns "A - B -" on both systems.
End Sub


So you can see that the variables value actually is "Test 1" and VBA is quiet content to evaluate it as such.

fumei
03-18-2014, 06:47 AM
VBA is quiet content to evaluate it as suchBetter that than standing up and screaming about it...

gmaxey
03-18-2014, 07:39 PM
Sam,

No difference on the other end either. To make matters worse, he reported that the If ElseIf End If work around we implemented yesterday is now failing in a similar manner!!!

I totally stumped and he is losing interest in furthering troubleshooting so I guess I'll have to fine this one off as a freak experience.

Thanks to everyone who offered comment and suggestions.

fumei
03-19-2014, 12:27 PM
And there is no way to get a hold of that actual template file?

gmaxey
03-19-2014, 01:22 PM
Gerry,

Considered asking, but the same thing happens when he creates a new document based on his normal.dotm and then attaches my template.

If he creates a new document based on my template (which is what it was really designed for), then both the Case and If statement methods of evaluating and document variable work fine.

Then two days I observed the Case method fail when he attached my template to one of his existing documents. That is when I proposed and wrote the If method and watched as he confirmed it worked.

Then he attached my template to another one of his documents yesterday and the IF method was failing. It was at this point that he told me that if he creates a new blank document and then attaches my template both the Case and If methods fail to set the prefix values.


I certainly can't reproduce the behavior here with my normal template so I'm thinking now it must be something else. The guy said it was no big deal as he rarely has to attach the template and I think he just wants to move on.

fumei
03-19-2014, 05:24 PM
Maybe so, but it nevertheless would be interesting to get a hold of that template so we can try and duplicate things in multiple scenarios. It is a unusual and interesting situation; it does not make any sense. There has to be SOME reason...OK, maybe not considering it is Word and VBA, but still. I have never heard of something making Select Case fail. I do not see how anything could as that is a logical operation. It is like something making 2 + 2 not equal 4.

gmaxey
03-19-2014, 06:05 PM
Gerry,

I've asked the template owner if he want to share it. Part of the issue I think is my actual template, his old template and the document contents may not be something that he wants to share with a wider audience.

I agree with you it is a very unusual situation and I am completely baffled.

SamT
03-19-2014, 06:05 PM
I think it's something on the other guy's office IT system.

gmaxey
03-19-2014, 06:17 PM
Sam,

I've also invited him to read this thread. If he does, he may see something that we've both overlooked that will explain it.

gmaxey
03-19-2014, 07:25 PM
Sam, Gerry,

The template owner sent me his old template and a copy of his normal.dotm. I created new documents based on both, saved them, reopened and attached the new template and it worked fine here.

We he does that, the Debug.Print variable value reports as expected but the Case Variable Value fails to execute.

He may have read this post because he said that he reinstalled Office 365 and it had no effect.

I’m afraid that unless some guy or gal smarter than me is sitting at his PC to see the behavior there isn’t much else that he or I can think of to do.

Thanks.

Best Regards,
Greg Maxey

Frosty
03-20-2014, 02:43 PM
Office 365? Hrrm... I'll take a wild-guess that you're having an issue with the identified document object (especially since the IF...ElseIf...EndIf started failing too).

You might want to break apart the code a good bit more... get a document object, use a function to return the value of a passed document object as well as the name of a variable... and if either thing fails, then have that function return an empty string.

I don't trust that ActiveDocument is always reporting what you think during execution and stepping through. I'm betting something is getting confused, and you've got a null being thrown around.

But all guesses ;)

Frosty
03-20-2014, 02:45 PM
Sorry, just to be clear-- I don't have any real ideas, except that I would break apart the actual line of code causing the issue into constituent parts and error trapped functions. Somewhat similar to SamT's suggestion of setting the value to a variable, and then testing the value of the variable. But I'd go further and get rid of the use of ActiveDocument, which could be the root of the problem for some reason.

Are you testing the code on your end in Office 365 too?

fumei
03-20-2014, 04:21 PM
Certainly testing for a Set document object rather than ActiveDocument may be a good idea. I would be very surprised if the issue is Select Case itself. I just can not see it. It is a basic logical operation so deeply inherent to VBA that I just can not see how it can be broken. SOMETHING is screwing up the value of the variable.

gmaxey
03-22-2014, 12:10 PM
Jason\Gerry

So how would you adapt this code? I'll ask him to try a modified version.



Sub CaseStatementOddity()
Dim strPrefix1 As String
Dim strPrefix2 As String
Debug.Print ActiveDocument.Variables("varTest").Value 'Returned "Test 1"
Select Case ActiveDocument.Variables("varTest").Value
Case "Test 1"
strPrefix1 = "A - "
strPrefix2 = "B - "
Case "Test 2"
strPrefix1 = "C - "
strPrefix2 = "D - "
End Select
Debug.Print strPrefix & " " & strPrefix2 'Returns "A - B -" on my system. Returns "" on other system.
End Sub
Sub WordAround()
Dim strPrefix1 As String
Dim strPrefix2 As String
If ActiveDocument.Variables("varTest").Value = "Test 1" Then
strPrefix1 = "A - "
strPrefix2 = "B - "
ElseIf ActiveDocument.Variables("varTest").Value = "Test 2" Then
strPrefix1 = "C - "
strPrefix2 = "D - "
End If
Debug.Print strPrefix & " " & strPrefix2 'Returns "A - B -" on both systems.
End Sub

SamT
03-23-2014, 07:02 AM
That is a small part of the code you are using and we have pretty much eliminated it as a candidate for the problem.

Why modify it? Except for the use of "ActiveDocument," it is as good as it gets.

Show us the actual procedure and it's calling procedure, and, if any, the called functions and procedures.

gmaxey
03-23-2014, 07:34 PM
Sam,

I am not at liberty to post the complete template. It belongs to another person. I posted here thinking that someone might have encountered this issue before and could offer and explanation. He did report that he attempted the code on another machine that isn't using Office 365. Maybe it is a regional settings thing, but I just don't know.

fumei
03-23-2014, 07:35 PM
Well at least try changing ActiveDocument to a set document object. Shrug.

gmaxey
03-23-2014, 08:46 PM
Gerry,

Do you mean

Dim oDoc as Document
Set oDoc = ActiveDocument

Frosty
03-23-2014, 09:04 PM
He might, but what I mean is go up to the top calling routine, and whatever the active document is there that you want, set oDoc = ActiveDocument there, and then don't use active document anywhere else. Just pass the oDoc variable to any child routines. This eliminates the possibility that somehow, some way, the ActiveDocument is being changed by one of your subroutines in certain circumstances. That's how I'd troubleshoot next.

fumei
03-24-2014, 01:47 AM
Heck as it is we do not know what, if any, calling routines may be in use. But...yeah. I just can not believe that logical operations like Select Case or If..ElseIf...End if can be broken so (apparently) arbitrarily. Something is wonky and I for one find it hard to accept the blow to VBA if is Select Case or If themselves. Isolating the routine to the action I s good place to start.

gmaxey
03-24-2014, 10:07 AM
Gerry\Jason\Sam\Others,

Setting ActiveDocument = a publicly declared p_oDoc variable made no difference on the other user's end.


As reported, admittedly late, he is able to create new documents based on the template with no issues. However, if he attaches the template to and existing file, then it breaks down as described.

I am not a liberty to post the complete template here. I wish I could because I am really interested in finding out what is causing the issue. The problem to the template owner is not so large that he wants to make public his file so there is nothing else I can do.

Thanks again for your interest and for offering suggestions.

snb
03-24-2014, 01:52 PM
If a template contains a variable "vartest".
If you create a new document based on that template, or attach that template to a Word document you can read that variable using this macro in the document (not in the template):


sub M_snb()
Select Case activedocument.variables("vartest")
Case "Test 1"
msgbox "'correct"
End Select
End Sub

What you are 'reading' exactly is the value of the variable 'vartest' in the template.
If you also have a variable 'vartest' in the document, VBA has to decide which variable to take.
It could result in unpredictable outcomes.

Frosty
03-24-2014, 02:16 PM
Have you tested this, snb? Because it seems like you might be confusing/conflating what is supposed to be the difference in behavior between ThisDocument and ActiveDocument.

ThisDocument (a document object, as opposed to the ThisDocument module) refers to the document which contains the calling code.
ActiveDocument refers to the document currently "Active" (and visible-- invisible documents can't be active) in the Documents collection.

This would be the first time I've seen the ActiveDocument object work like the ThisDocument object, which seems to be what you're describing. VBA doesn't have to decide which variable to read (in my experience) -- it reads the variable that it is supposed to, in the object that you've told it to look in (again, in my experience-- but I haven't used Office 2013 or Office 365 yet, and wouldn't be surprised to find some new bugs).

In Word 2010 and prior... if a template contains a variable called "vartest" -- any documents created based on that template will also have a document variable called "vartest", with the same value as the template at the time the document is created.

However, if a template contains a variable called "vartest", and you attach the activedocument (without that variable) to that template... then a document variable "vartest" looked for in ActiveDocument should return nothing or null.

Frosty
03-24-2014, 02:28 PM
But this does beg a question, Greg... where is the code stored? In a global addin, or is it stored in some kind of template. Because if you're running code and swapping templates which contain code, you're obviously going to have some issues. Without giving the whole template-- what's the actual structure of where code resides?