VBA Programming for Microsoft Excel Macro - vba

While implementing a macro via Visual Basic Editor, i got an error "Compile Error: Procedure Too Long".........i wanted to know why is there a limit to the size of the macro and is there any way to increase the allowed size. My macro is pretty big (based on around 150 different cases) and because of this error i will have to divide the task among 8 macros approximately. Is there anyway around it?
Will appreciate your help.

You can speculate on the logic for limiting the text size of a subroutine - maybe they don't think it is necessary to have subs that long - maybe they gain some slight performance boost by doing it - maybe it is just a purposeful limitation to prevent people from recording ridiculously long macros. But in any case it is probably better from a scripting/programming perspective to not have monstrous subs anyways. And with loops you shouldn't need to have subs with that much text in them. So my hypothesis is that they wanted to prevent people from relying on recorded macros when it would be better and more efficient to use loops. But it's just a hypothesis. Good Luck.

Related

How can one see the size of the compiled subroutine in VBA Excel 2016?

After finding a "procedure to large" error on a specific subroutine of a module, I am refactoring the code in the module. I was curious on how effective the refactoring is at reducing the compiled code size.
So I was wondering if there is a way to see the size of the compiled code of a subroutine in a Module of Excel 2016?
My attempts so far have been limited to searching online for methods to determine the size of a compiled module or subroutine in VBA.
It led me to the limits of VBA as listed in here. It does not mention a way to see the size of the procedure compiled, nor does it mention whether that is (practically) possible.
(As was mentioned in the comments, the current maximum size of the compiled procedure is 64K as stated here.)
I think the compiled procedure size is not 1 on 1 related to the number of lines. (Because that does not take into account short or long lines. But I am currently unsure about how the vba-procure is compiled, and consequently how lines contribute to the compiled file size, otherwise a solution could possibly be to compute the compiled file size.)
Nor is the procedure 1 on 1 dependent on the size of the code as stored as a '.txt' file. (because it can contain comments which do not contribute to the compiled code size)
Disclamer - I am well aware of the shortcomings of the old code I am modifying. That it is poorly written, I think this quote of Bill Gates illustrates it quite well:
Measuring programming progress by lines of code is like measuring
aircraft building progress by weight.
I think refactoring, and breaking the code up in shorter subroutines is an appropriate first step. To monitor this process, in combination with the hard bottleneck presented by VBA as the Procedure too long- error led me to this question.
No, you can't do that. VBA is compiled in several stages, it's part p-code, part interpreted, and at the end of the day the size in kb of the compiled procedure isn't what you need to work on.
You need to read about Abstraction, urgently. A procedure that triggers this compiler error is over 10K lines of code. A healthy procedure at the appropriate abstraction level might be somewhere between 500 and a thousand times smaller than that (not kidding) - the size of the compiled code is absolutely meaningless.
If you're worrying about the size of the compiled code, you're not writing the code for a human.
Code isn't written for a compiler to crunch and a runtime environment to run. Code is written for a human maintainer to read, understand, follow, debug, modify, extend, etc. Without any level of abstraction, code is a boring, excruciatingly mind-numbing series of executable statements that are invariably redundant, inefficient, and annoyingly bug-prone.
There are 3rd-party tools you can use to analyze VBA code. MZ-Tools 3.0 was free, but the latest version isn't. It has a feature that can tell you how many lines of code are in each procedure of each module, how much of it is commented-out, whether you have unused variables, etc.
Rubberduck is free and open-source, under active development (disclaimer: I own the project's repository), and has a code metrics feature (distinct from code inspections) that can probably help you identify the most problematic areas (although, parsing a 10K-liner module might take a while):
Lines is your "lines of code" metric; Cyclomatic Complexity is a rough indicator of the different possible execution paths in your code (how much sense that metric makes at a module-level aggregate is debatable); Maximum Nesting is also an indicator of how badly "arrow-shaped" code might be.
High values in these metrics are a sign that you may need to extract methods.

Group lines of code in vba

I was wondering if it was possible to group lines of code in vba excel, in order to make the view more pleasant. Meaning I have 1000 lines of code and would like to group lines in order to hide/show them. I know this is possible in other coding languages, so I would like to know if it was possible in vba.
Thanks
The short answer is no, not out of the box. There is an open source tool that will be able to do this in a future release http://rubberduckvba.com/
If you have a lengthy procedure you may what to ask yourself if it does more than one thing. As a general rule, a procedure should only do one thing. If you break up each separate "thing" into individual procedures, then you can call each procedure in a parent subroutine. A good book on this is "Clean Code: A Handbook of Agile Software Craftsmanship"
Sub ParentSub()
ChildSub1()
ChildSub2()
End Sub
In addition to breaking code up (refactoring) into smaller logical functions, you can also break them across different modules if the Private/Public setting allows it.
If your code is in a class (or in a worksheet), then you can also use Friend for your functions/subroutines.
Of course, once refactored, I often find that I build classes to make my code simpler and easier to maintain. This allows you to hide (encapsulate) much of your lower level code and your main program is now at a much higher level and sometimes almost (if you squint hard enough and you have named your classes and methods properly) look like readable English!
As an aside, the Call keyword is not recommended unless the called expression does not start with an identifier (MSDN ref). In the answer above, the following will work quite fine.
Sub ParentSub()
ChildSub1()
ChildSub2()
End Sub

How bad is it to have tonnes of unused variables

I am using VBA and I have downloaded a tool called MZ-Tools, it helps me find all the unused variables in all the code, now I have almost 300 objects which roughly 500 lines in each.
Overall it has found almost 500 unused variables/procedures
Would removing these variables speed up the program a lot or would it just be a waste of time to clean up code which doesn't have much effect on the program?
Short answer: It is never a waste of time to clean up code. You or someone else will be so happy when you have to revise it a year later or so.
Longer answer: The application probably wont speed up a lot. At least you probably will not feel a change. This depends on how heavy it already is. Also it depends on the kind of objects that are created, how 'big' and complex they are. If there is some of those objects running methods every couple of seconds for example in a loop, it will affect the performance of the application considerably.
More: As result of cleaning up your application you will get a better performance. If it is perceptible or not, depends on a variety of stuff. The bigger problem is that you will not know if the objects used wont cause errors in the future. Maybe some of them will get discontinued at some time, or they could cause other kind of unexpected exceptions. This is, I think the biggest threat.
Have fun going trough the code sooner or later!
Based on your question and comments, my impression is your focus is exclusively on execution speed. If that's all you and the team care about for that project, don't invest any time cleaning up those items because I doubt you will notice any runtime performance improvement.
However, I suggest you look beyond only execution speed. How challenging is this project to debug/troubleshoot for the current maintainer(s)? How difficult to add new features, if needed? How about if someone new has to take over responsibility? How much easier would those tasks be without the distractions of unused variables and procedures?
A related consideration is just how much time are we talking about for that cleanup effort? I wonder whether someone has over-estimated the workload.
Make a copy of the db file. From the Mz-Tools code review panel, choose "export" and save the analysis report as a text file. Print the text file. Then move though that printed list, fix each item, and cross it off the list. If you're really slow, you may only average 2 per minute. And for 500 items, that means 250 minutes. But realistically, the task should take less than 4 hours. Running the Mz-tools code review again will show you if you missed anything. And compiling will tell you whether you removed something by mistake.

Does the Native VBA Compiler Optimize?

My code is as follows:
#Const debuggingEnabled = False
Sub debugMessage(str As String)
#If debuggingEnabled Then
Debug.Print str
#End If
End Sub
Sub doThings()
debugMessage "test" 'Does this get optimised away, or must it be explicitly
'wrapped with `#If .. #End If` every time it's called
'if one is to avoid the jump and stack push/pop ops?
End Sub
Does Microsoft's VBA compiler optimise away calls to procedures that do nothing? How can I find out?
Upgrading this from comment to answer:
What is the point in "optimizing away" a procedure containing a single, one-bit, binary, boolean test? Are you sure that this represents a significant portion of execution time? The chances of that are pretty remote.
Before optimizing, always do some profiling, so you don't waste time and worry on bits of code that represent 0.0001% of your execution time.
VBA has no native profiler, but there are third-party options out there, some of them free. This is one, accompanied by an instructive read: Profiling and Optimizing VBA
By bruce mcpherson. A DuckDuckGo search gives plenty of other leads as well.
So, the answer to your original question is: I don't think VBA optimizes such a procedure away, but I'm not entirely sure, and either way it is in all likelihood completely irrelevant. Before worrying about optimizing, always do some profiling, so you can spend your time wisely. After profiling, you will almost always find that what you thought slowed down your program is actually very fast, and that something else is the culprit.
AFAIK the VBA interpreter does little or no optimisation. If you test this in VBE debug mode you can see execution jump to the "empty" sub.
But I would have thought that the additional overhead will anyway be drowned by the rest of the VBA execution.

Apache POI and Excel VBA performance comparison

in term of performance speed comparsion and without consider the development time
is that Excel VBA always faster than Apache POI when perform same task?
e.g. - fill background color/font formatting
- convert csv into excel file
As I hear people smarter than me say all the time: it depends. You will have to go through some testing yourself to see what gives you the best performance for the tasks you want to accomplish.
If I would have to guess than I'd go for VBA. Chances are you'll be able to do much more than is available in POI too. The choice in the end will also be influenced by experience and architecture and ...