I've been applying VBA at work for a number of purposes. I have noted the more 'clicks' a user has to do for a form (with a number of macros), the higher the rate of error. I was wondering rather than having 3 separate functions requiring 3 separate clicks - should I bunch all these functions together into the one sub module for ease of use?
Clinical staff have indicated that this would work best with them, but in terms of code optimization and keeping different functions separate - wouldn't it make things very messy? As I'm still in the process of learning VBA, I thought I'd turn to the expert community which has helped me out a lot so far.
I'd appreciate any and all comments regarding your thoughts on this and how I can create best-practice VBA standards to adhere towards.
An example of this would be the static copy function I have created and the monthly Calculation function. For the monthly calculation to be completed it pulls data from a summary tab and compares this against the static data. However for the static data to first be captured - the user needs to click the static data macro. I've separated the static snap-shot function and the monthly-report function but was wondering if I could instead combine both of these into one function. Readability wise it's not problematic (as I have the comments explaining each section) - but standard wise, would it be unwise?
I apologize if this question is somewhat broad in nature.
After reading around a few forums I've picked up the following information:
Do not use global variables unless you have a specific reason to do so
Don't forget to initialize variables else you may run into sub-script errors
Keep your code simple (iPhone Approach - one click approach)
If modules are similar consider grouping the functions together into one
Macro recorder is your friend
Thanks for the tips everyone!
Related
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
As I mentioned before, I am hardly a programmer, so I once again need the expertise of those that are...
I am working on a program that will help me manage some data for a volunteer emergency communications group. In this program I currently have multiple different structures built for multiple different objects (if I am using the term correctly). I have a structure for Site Personnel, a structure for Members (yes they are different), a structure for Operation Info (considered its own object), and a structure for Facility. This was all fine and well, even having each element of the structure defined with <VBFixedString(nameOfConstant)> to ensure an equal record length.
And that is where I hit my problem. Each object (again I hope I'm not butchering this term as I am calling the Facility or the Site Personnel etc the 'object') is a set of fields for a random access file (I abandoned the Excel file idea, way too much headache and nothing but failures on that front, I'll use an in-house system). And, certainly to all of your dismays, I did finally decide to go with FileOpen, FileGet, FilePut, etc for my random access file management (I can already hear your teeth grinding and your skulls crackling to epic facepalms, but believe me I NEED to go simple for this presentation version and for the Version 1 Release which will be beta tested at a National Disaster Medical System exercise in May). The problem I encountered is that each file will need its own filenumber, its own position, and so on, and each one will need a Dim Temp as <structure> where <structure> is SitePersonnel, OpInfo, MemberData, or other relevant structure. Each file will also need its own file handling controls, such as GetRecord, PutRecord, DeleteRecord, NextRecord, PreviousRecord, AddRecord, and so on, and each file will need its own functions for file opening and finding the last record. The reason each structure will need its own copies of this code is that I cannot find a way to pass in a variable to a module-level function such as Public Function FileOpener(ByVal FileNum as Integer, ByVal StructureName as String, ByVal FileName as String, ByVal AccessType as String) and in the code define Dim Temp as (StructureName) where StructureName would be a String value for the actual name of the structure. And finally, I decided to have the redundant file handlers in each object since at any time there can be two or more of these file open, reading, writing, and seeking. Last thing I need during an emergency is for a module-level function to get confused and return the wrong data.
Now that you have the background, this is where I really need some advice. I am aware that structures can have Functions, so I could code each of these functions into the structure. However, I have also started thinking that an object this complex and that can do so many different things may just belong in a class instead of a structure. I am not familiar with classes in Visual
Basic, but I am familiar with Classes from Java, if there is any similarity between the two on the OOP level. So my question is this: Would this example be better (and more reliably) handled in a Structure, or in a Class? And if in a class, would I be best off with each Class in its own file, or should I combine all of these classes into one Module (mainly for clarity and ease of maintenance)?
I apologize again for any permanent damage I have caused anyone here by my sub-newbieness and painful choice of code, and I thank you ahead of time for helping a sorta-noob get back into the swing of things (last Visual Basic program I wrote was when Visual Basic 4 was hot off the press, yep, that long...).
For a system like yours, to manage users and other objects, I recommend the use of classes. They usually get used for management system as they offer the abbility of hierachical variables and functions, so you don't accidentaly call an internal function or access a variable you shouldn't. Also, classes are more flexible than structurs, so you should preferable use them when you aren't sure wether a class or a structure is the better way.
As Plutonix pointed out before, this is not a platform for recommendations, it is for problems with code. So next time, please go to a VB.Net forum. The text written above is my opinion based on my knowledge about the difference between classes and structures and this msdn-article. Further internetresearch is still something you should do, maybe ask in forum or friends / other programmers you know.
I am busy with a VBA Code for automatically importing and re-sizing images into a Word Document at specific places, it will also provide error messages for various situations.
My question is:
Is it better to use and call a Sub which is specific for a part of the code or to have one long code which is divided into sections with comments.
I am currently using one long Sub and trying to see if I can get the same result by calling each sub separately, doing this I struggle with getting global variables or string assigned to be available in all modules and subs.
I understand for sharing the code having one long Sub is beneficial.
Having the additional experience now, I can see that multi-sub programs are beneficial for repeating for repeating parts of the code as #KazimerzJawor mentioned.
Also, apart from having loads of comments which is a must, it helps to divide you code up to manageable parts which contains smaller ideas of the main coding.
Why excel? Well excel is what is used to import the player salaries.
Now I need the spreadsheet to do the following.
Create teams within salary cap.
Include/exclude specific player function
Build multiple lineups from a selected list of players within the cap
Can I do all of this with excel? or do I need to know excel vba as well?
Also which parts of excel or if necessary excel vba must I need to know to code such a thing? Also if someone could give me a short summary of the steps needed to hypothetically make such a thing it would be great. Thanks.
I'm posting this as a reply because it is too long for a comment window.
Just because Excel has a grid doesn't mean that it is fit for data storage and data handling, on the contrary.
What you typically want to do is create a transparent structure that guarantees the integrity of your data and that allows dynamic portability when needed one day.
Excel is meant to be a spreadsheet, people forget this all the time or they just avoid the topic: although Excel has a grid, doesn't mean that it is a good fit for reliable data storage. It is not even the least complex way of storing data, depending on the amount of VBA that you need to manage all these data and the gates that you unnecessarily open towards potential bugs.
This is why an RDBMS is what will fit your needs, in this case Access would be a good option as it preserves your data integrity if you get the table structure right and it executes a lot of tasks for you that you should otherwise need to program yourself to protect the integrity of your data.
Although you can perform SQL on spreadsheets too, note that Excel does NOT cover related tables (what you typically seem to need for building your teams and salary limits), so what many Excel programmers will typically do is to create their own code to make this cross-table data storage thing work.
Don't do this if the alternative is available and much more reliable and future-proof.
At first sight, it seems that you won't even need any VBA; I'm not sure of all the things you want to do, but my first impression is that you can manage everything with SQL syntax and stored queries in MS Access. You can import Excel sheets into Access if you get their format right so that should not be a problem.
Once your data is stored there, rest assured that you have made your life a lot easier.
Suppose you have an Excel workbook and you need to write a macro that takes inputs from many different cell references, and updates values at many different cell references, how do you keep the code neat and maintainable?
It would be helpful to know:
best practices
useful tricks
unavoidable difficulties
necessary trade offs
If there are links to existing guides or discussions that would be helpful too. I haven't been able to find any.
Edit: I found http://www.eusprig.org/best-practice.htm very useful - from the European Spreadsheet Risk Interest Group (EuSPRIG).
It slightly depends om what the macro is going to do, but I use 'calculation' sheets, where I gather together the data I need for the macro, and output the results there.
I tend to do this do in defined ranges.
The result data can then be referenced from elsewhere.
Tricks: One thing I do is to create a visual 'check off' for each piece of input data as it's used. This just enables me to make sure that all the data I thought I was going to use, I have used.
Following Naming criteria is better solution , irrespictve of language.
in_name_range, out_name_range
in_num_range, out_num_range
Check points and adding watch , would surely help.
If you are going for modularity, Take care about updated ranges
(As you can't return more than one value at a time better write ranges in some predefined order in some sheet. This works for me.)