PDA

View Full Version : Solved: Debug interference with code



andalusia
08-25-2006, 08:43 PM
I have a problem where using the debugger alters the behavior of the VBA code. Can you give me some tips for dealing with this, or perhaps a link to a webpage which discusses this problem?

Ken Puls
08-25-2006, 10:30 PM
Uh...

I think you're going to need to be WAY more specific for us to help you there. Exactly what kind of changes are you seeing?

fumei
08-28-2006, 02:29 PM
Yup...."the debugger alters the behavior of the VBA code" is simply not good enough.

andalusia
08-28-2006, 07:28 PM
I was seeing some tabbing effects change in the overall finished project. I approached the problem by narrowing down where the effects were taking place. What I was referring to is when one hits a breakpoint and continues or steps without affecting the cursor location, and the finished product (I am building letters) is different from the case with no breakpoints.

mdmackillop
08-28-2006, 11:47 PM
I think you'll need to post your code to see if the problem can be replicated. I have written code which worked in debug, but not in realtime, but never the other way round.

andalusia
08-29-2006, 01:05 AM
I've kind of moved on from that point, and figuring out which code to include here would be difficult at this time. It was as you said, where it worked with in debug but not in realtime. Something similar had happened previously and I was wondering if there were any guidelines to use when dealing with such a thing. What I did to solve it was to alter the breakpoint from an early location until it progressed after the strange behavior. That gave me an idea of where the problem was arising. This way the debugger is running in realtime up to a stopping point, so you can compare to see where the debug and realtime branch.

fumei
08-29-2006, 10:57 AM
Something similar had happened previously and I was wondering if there were any guidelines to use when dealing with such a thing. Sorry, but I, for one, still have absolutely NO idea what "something similar" IS! WHAT is the something???

So, "such a thing" is also meaningless.

Are you saying this is solved? if so, please mark it solved.

If it is NOT solved, could you please be more specific?

andalusia
08-29-2006, 03:27 PM
How do you mark a thread as solved?

Ken Puls
08-29-2006, 03:32 PM
Thread tools menu. But is it actually solved? You don't need to mark it such unless it actually is.

I'm actually kind of curious if you could replicate the issue. I've run into situation where my "code cannot execute in break mode". My options there are to let it run through or end it... just no stepping line by line.

I also vaguely do remember once running into something that seemed to work while stepping, but not at run time. I can't remember what it was now though, and am not even sure that it just wasn't the way I coded something at the time...

As I say... I'm curious...

andalusia
08-29-2006, 03:38 PM
I have a present example that works while stepping but not at run time. It is difficult for me to include the code, however, because there is quite a bit of it. I'm not sure what the standards are here on how much VBA code to include in a post. I will see if I can reduce the amount of code involved to a point where it would be reasonable to attach it here.

fumei
08-30-2006, 03:01 PM
Well now, I'm kinda curious myself, so if you can, yes please post something. It may be better if you could have it in a file (ZIPPED), rather than actually posting the code itself. That way we can take a look off-line easier.

andalusia
08-30-2006, 07:13 PM
I managed to get the phenomenon in a fairly compact set of files. I have attached VBAX.zip. The directory inside should be moved to a location so that C:\VBAX\chart.doc exists. Basically, create a VBAX directory right off of root on C: drive. The macro accesses some of the documents there.

When the macro "mforum" is executed, it puts some text and then a chart. However, it only produces one copy of this chart. When the macro is stepped through in debugging mode (starting with a breakpoint of the File Insertion of c:\vbax\chart.doc), it is seen that the chart appears twice.

See if you can figure out what is causing this.

fumei
08-31-2006, 12:09 AM
1. Why do you have this as a separate .BAS file? It forces us to import it. Is there a reason for this?

2. It would be MUCH nicer if you commented your code!

3. It would be MUCH nicer if you used indents in your code.

4. It would be MUCH better if you used With statements, and got rid of junk you possibly don't need.

Just for example: .gutter = InchesToPoints(0)
.HeaderDistance = InchesToPoints(0.5)
.FooterDistance = InchesToPoints(0.5)
.PageWidth = InchesToPoints(8.5)
.PageHeight = InchesToPoints(11)
.FirstPageTray = wdPrinterDefaultBin
.OtherPagesTray = wdPrinterDefaultBin
.SectionStart = wdSectionContinuous
.OddAndEvenPagesHeaderFooter = False
.DifferentFirstPageHeaderFooter = False
.VerticalAlignment = wdAlignVerticalTop
.SuppressEndnotes = False
' etc etc etc.Do you REALLY need all this? If not, it getting rid of it makes reading and following code easier.

5. What is the purpose of:ActiveDocument.Bookmarks("\EndofDoc").Select 'posdocbottom
ActiveDocument.Bookmarks("\Line").Select 'poslineend
ActiveDocument.Bookmarks("\EndofSel").SelectFirst of all using the Selection object is inefficient. Second of all, essentially this seems to be the equivalent to:Selection.EndKey Unit:=wdStory It moves the Selection to the end of the document. What difference are you seeing between EndOfDoc, Line, EndOfSel? It ALL moves the Selection to the last character. Could you explain this?

Further, then you make a PageBreak....and repeat the EndOfDoc, Line, EndOfSel code again. This is pointless! You add nothing after the page break...so selecting these bookmarks is a complete waste of code.

6. You declare f and l as Strings. I see nowhere where these are actually set as anything. However, ignoring that for the moment, assuming that they ARE set for something, here is another example of using too much code.Selection.TypeText (f)
Selection.TypeText (" ")
Selection.TypeText (l)
Selection.TypeText (Chr(13))is EXACTLY equivalent to:Selection.TypeText Text:=f & " " & l & vbCrLfWhy are you using four lines of instructions when one will do? What I am saying isDim f As String
Dim l As String
f = "Hello"
l = "World"

Selection.TypeText (f)
Selection.TypeText (" ")
Selection.TypeText (l)
Selection.TypeText (Chr(13))

' will do PRECISELY the same as

Selection.TypeText Text:=f & " " & l & vbCrLf

So what I am trying to is clean up the code itself so I can try to follow it better, in the hopes of actually figuring out what is going on.

Later.

fumei
08-31-2006, 12:16 AM
Sorry...I really did not mean to sound overly critical. That was NOT my intention at all. If it came across that way, my apologies.

Ken Puls
08-31-2006, 08:40 AM
andalusia,

I just wanted to vouch for Gerry here. He comes across as a bit gruff sometimes, but the he gives great advice and knows a great deal about working with code in Word (among other things.) Follow his advice, and you'll learn a ton. ;)

fumei
08-31-2006, 08:48 AM
yeah....sorry, I DO get carried away, and I will admit to being "gruff". Again, my apologies. I am still looking at this code.

Ken...have you looked at it? Any ideas what is going on?

Ken Puls
08-31-2006, 08:51 AM
Hi Gerry,

No, actually I haven't. I just signed on this morning. Word isn't my strong point, so I may not be able to offer much, but will definately take a look. :)

Ken Puls
08-31-2006, 09:07 AM
Okay... so some questions...

1) What file is this module supposed to be imported to?
If I try any of the files that you provided, I end up with an error about not be able to import into itself. If I put it in a new document, I end up with a bunch of recursive calls in the procedure, and a 315 page document at the end.

2) Why the use of all the goto statements? Try either (or both) of the following two things:
-Break your code up into manageable and re-usable sub procedures that you can call from the main one when needed. This way you can re use them.
-Control your loops via a simple For Each array to count how many times you want to run it.

The current structure of gotos leaves you jumping everywhere. This is a model of programming that went out of style... what... 20 years ago?

Sorry, andalusia, you're probably going to feel like you're taking some lumps here, but it looks like both of us are finding your code pretty hard to follow...

fumei
08-31-2006, 10:18 AM
1. Ken, it is - I believe - supposed to be imported into chart.doc. But again, that is why I asked why it is a BAS file in the first place. Why are we being forced to import it? If it is the actionable code for chart.doc, it should be in chart.doc.

2. andalusia, I will reiterate Ken here. We are NOT trying to dump on you. The code is, ummm, not the best design. In particular, I want to strongly suggest following Ken's advice regarding breaking things into manageable (and simply Call-able) procedures. It makes code much easier to follow, for you as well. It is not good design to have long procedures, and more importantly, very long complex procedures are (generally) not needed. Having more simplified chunks makes your code - as Ken mentions - more reuseable - and MUCH easier to debug.

Also, yes, using For Each is a much better way to loop through things. It uses the object model in the way objects are most efficiently used.

Still looking at it though......

andalusia
09-02-2006, 12:26 AM
I have incorporated many of your comments, resulting in the following new .zip.

I'm not really sure what your complaint is about importing the .bas file as a module, but I have set it up now so that you can copy and paste into some space in an existing module.

For me to make it work, I import narrow6.bas as a module into Normal.dot. Is this undesirable because of security reasons?

As before, the files should be placed in c:\vbax\

TonyJollans
09-02-2006, 12:45 PM
I just picked this up to see if there was anything obvious - or interesting.

I haven't really looked at the code but I always seem to get the same result however I run it (Word 2000 on Windows 2000). What difference might I expect to see?

andalusia
09-02-2006, 04:51 PM
If you put a breakpoint on the line:

Selection.InsertFile FileName:="c:\vbax\" + "chart.doc", Range:="", _
ConfirmConversions:=False, Link:=False, Attachment:=False

and then step through to the end, the code will act as it should, producing two apple charts in the document. If this breakpoint is left out, only one apple chart is produced.

TonyJollans
09-02-2006, 11:04 PM
A-ha!

It makes no difference on my machine but (and still without going into the code in any great detail) I'm sure the reason for what you are seeing is the Application.Run statement - a much misunderstood one about which much bad advice is given.

Application.Run causes code to be executed asynchronously - exactly when is up to Word - and you cannot guarantee that the routine which you Run will actually have been run when you reach the statement after the Run. Putting a breakpoint immediately after the Run statement does, however, give Word all the time it needs and the routine will always have been run when you do that.

Application.Run is a very useful statement but you really must understand what it does before using it.

Ken Puls
09-02-2006, 11:15 PM
Nice work, Tony! :thumb

andalusia
09-04-2006, 01:23 AM
Tony, thank you for discovering this. I will use subroutine calls instead.

andalusia
09-06-2006, 08:12 PM
I tried it with a trforum subroutine, so instead of

Application.Run MacroName:="trforum" the line now reads

trforum

I thought this would fix the problem because a subroutine call should be synchronous - it has to execute before the subroutine returns to the calling macro.

However, this did not fix the problem, and the same behavior was observed. Are subroutine calls asynchronous too?

TonyJollans
09-07-2006, 01:59 AM
No. If that doesn't fix the problem I'm not sure what might. As I don't see it in the first place it is difficult to guess what might be causing it.

This is pure conjecture but it may be that some other operation such as InsertFile runs asynchronously and is not getting completed in time. Try adding a DoEvents statement immediately before the point where you were setting the break and see if that has any effect.

andalusia
09-07-2006, 02:34 AM
Tony, you said that when you ran the macro "mforum" that you ended up with two charts, as it was 'supposed' to? I am surprised that there would be different performance of the macro on our computers. I am hoping that someone can observe the bad behavior that I did to be able to take a closer look at it. I will do what I can to make the macro easier to install, if you have suggestions on that.

TonyJollans
09-07-2006, 06:49 AM
The fact that different behaviour is exhibited on different computers suggests, perhaps amongst other things, the possibility of a timing issue. I have no idea, for example, whether you may have a modern dual-core processor and whether that may make any difference. What I can say is that there is no setting I know in Word or Windows that would cause this effect.

andalusia
09-07-2006, 10:48 PM
I do not have a dual processor.

I plan to resolve the issue by doing some rewriting of the macro. I am translating from WordPerfect macros to create the macro. I have a feeling that if I try to solve the same problem with a fresh start, the problem will disappear.

I wanted to note that the problem arises from a movement of one space by the cursor, in my translation of "go to previous page" and "go to next page" routines. In the run where the chart is not duplicated, the page prior to it is duplicated, so perhaps a solution would be to create more robust routines to these two translations.

Thanks to all for the help.