32 Grenville Street M4Y 1A3
Traps for Young Players
These four are not the only traps for young players. They are some of the mistakes in my coding uncovered during a recent debugging exercise.
My application manipulates VBA Program Code in Modules within Projects. A primary requirement is to identify procedures and manipulate the block of code known by the name of the procedure.
The code includes:-
(1) Examination of procedure headers by type vbext_pk_Proc, vbext_pk_Get, vbext_pk_Let and vbext_pk_Set
(2) Examination of modules by CountOfDeclarationLines and CountOfLines
(3) Determination of the extent of procedures by ProcStartLine and ProcCountLines
In my haste to write the original code I stumbled across the property of a module giving me the count of the number of lines in a code module:-
Dim intLine As Integer
intLine = objmod.CodeModule.CountOfLines
While intLine > 1
I was smart enough to obtain the property “CountOfLines “ and then decrement a pointer so that I worked from the last line (the “foot”) of the module to the first line (the “head”) of the module.
I garnered peculiar results in the string array in which I built a summary picture of the modules.
I stumbled across a problem with a module that had, amongst other things, three lines of declaration in its head.
From this I learned to make use of a second property of the module:-
Dim intLine As Integer
intLine = objmod.CodeModule.CountOfDeclarationLines + objmod.CodeModule.CountOfLines
While intLine > 1
After I included the property “CountOfDeclarationLines”, some, but not all, of my troubles disappeared.
I do not like the “On Error” clause for aesthetic reasons.
I had written some On Error code as a series of inline blocks of code.
I built instead a stand-alone procedure which you see implemented in the screen shot below:-
Unfortunately a poor choice of name for a DIMensioned variable (“strName”) was swept up in the code garnered in the slave procedure.
Lacking the explicit declaration in the slave procedure, the definition resolved itself into the name of a utility procedure in my utility library, so that the string value returned the value of my name (useful in producing signature blocks and letter-heads)
After I changed the variable name to “strProcedurename”, some, but not all, of my troubles disappeared.
As a test case I began analyzing the stripped-down module code you see reproduced below.
To assist myself I pasted the VBA code into a document body and applied line numbering, the better to check on the starting line and count of lines in each procedure.
The document shows that there are sixty-two lines in the module, yet my program code said that there were but fifty-seven lines.
After much tracing and single-stepping the truth made itself known.
In Portrait mode a document wraps lines and so reports the line-numbering for a wrapped line in two parts.
Using page-layout to set landscape mode with small margins gave me a clearer picture of the line values within the VBA module.
After I changed the page layout, some, but not all, of my apparent troubles disappeared.
Yet still I had problems with line counts. Bear in mind that in this one procedure I am trying to build a string array that describes each procedure in a module – the name, starting line, and line count of each procedure.
Armed with these descriptors I can manipulate the procedures.
Here is a screenshot of the Debug Window showing that the number of lines in the module is seventy-one – and yet I could see only sixty or so.
In this screenshot I have typed in a comment over the last blank line of the module. How did all those empty lines appear at the foot of the code module?
I do not know.
I do know that those blank lines are counted as lines within the module, and if I take the name of the procedure that owns those blank lines – the last procedure in the module – and then use that name to obtain the count of lines in the procedure and subtract that count from the last line in the module, I will end up somewhere in the body of a procedure instead of being at the head of the procedure.
As a consequence of this discovery I abandoned the fast method of looping backwards through the code module – by subtracting the count-of-lines in a procedure from my loop index, and reverted to the slower method of decrementing the loop counter by one, examining the module code line by line, and taking action to assemble another entry ONLY when the procedure name changed.
After I changed the looping method, enough of my apparent troubles disappeared that I felt justified in stopping work for the day.
Toronto, Saturday, March 26, 2016 10:23 AM
Copyright © 1996-2016 Chris Greaves. All Rights Reserved.