Single vs Multi Sub Program - vba

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.

Related

Having trouble making my VI work as a Sub VI

I am having trouble getting the terminals to pass any data to what they are connected to because the controls they connect to are in a while loop. My frustration level is high since I would have already had this done if I wrote it in C.
First, let me say this might get a little long so if you don't want to read it, then don't. Here goes. I have watched a couple of tutorials, read a lot, and even tried a few things out in code. I get why this can't be done directly in a while loop. Having said that, it seems that I have no choice but to use while loop(s) in my VI.
My VI is loosely based on Queued Message Handler in the Templates section of creating a new VI. I have 2 things that must take place. One - I have created a TCP client where I constantly send messages to get status from the equipment I am communicating with. This is a timed event and must be handled in a while loop so I can maintain the connection to the server. I am not doing the Open, Send, Close, Reopen, Send, Close, etc. type of message handling. Too inefficient. This is the lower half of the example template.
Second - On occasion the user will press a button on the front panel which creates a message that is sent to the equipment to make it do something. And this, it would seem, needs to be in a while loop also, hence my problem. Some/most of the controls exist with the event structure. This is the top half of the example template.
I actually have this working as a front panel, but every thing is in just one while loop and I cannot get the terminals to work. Here is where my confusion comes in, if I am passing something to the while loop, I only get its value once and if it changes, you don't get that change, and if you are passing the data out of the while loop, you only get it when the loop ends. These two things are really baffling me. How can pass data that changes while using a while loop, because I have to, but the while loop breaks using the terminals. Seems circular. The TCP communications cannot stop, and I cannot find an example of how to do this using my friend Google. Am I the only person on this planet that needs to do this? Doubt it.
Not going to show my code, as this in not a code problem. It is an understanding how LabView does things vs. how you would just write the code in C using some library. And also just being unfamiliar with all the things you can do in LabView, not to mention how things are different. I don't know what I don't know, but I can learn.
I want to be able to give the VI I have created to any user and let them use it to control my equipment. If they just want to run it as a front panel, or if they want to use it as a Sub VI that is OK too. I just need to be able to make the terminals actually pass data when used that way.
Thanks, I did order a book on LabView today, but I won't get it soon. I really need to put this problem to bed.
Cannot help that much without seeing the code. But I can try to give you a little bit of an idea of what is going on.
Dataflow is an important concept to understand in LabVIEW. elements (VIs, loops, etc.) will not start until all of their inputs (ie. terminals) have been received or set by something called before, and then they only take their inputs once. If your terminal is outside the loop, then the loop can only read it's starting value. (See "Infinite Loops" on this page). A simple way of solving this would be to put the terminal inside of the loop rather than outside, so it is then read on every iteration of the loop.
As for passing values outside of the loop, there are a number of methods for this. Again, because of dataflow, you will not usually be able to access the value of something inside the loop until the loop finishes executing. However, there are a number of ways to read those values in a different loop. Local or global variables would be the simplest way, but they are not recommended by NI. The proper way of handling this is using something on the synchronization pallet. More info on the options can be found here.
Seeing as you are basing something on the Queued Message Handler, a queue might be a good way to start. LabVIEW has built in examples of code to show you how to use these functions.
Loop synchronization and asynchronous programming are fundamental concepts for writing LabVIEW code. If these are not concepts you are familiar with, I would say that you will gain a lot from showing others your actual code and having people help you with the issues. If you are concerned about sharing something proprietary, try making a simple example and posting that code instead to understand the concepts better.
Event structure to react to evr8and functional global to pass data out.
Suggest pasting block diagram.

How can I access data that changes locations and header names across workbooks?

I am trying to access data that changes locations and header names across different workbooks. This is part of a bigger project but this is the only part I cannot figure out. I have attached images to help clarify what I mean. Let's say that I'm trying to access the range that contains the Net Worth/Balance so I can do some calculations with it. How do I do this if the headers change across dozens of workbooks? On top of that the headers aren't always the first rows with any writing on it. Sometimes there is info in the upper rows that are needed for the workbook but not my purpose.
The programmer in me wants to use a dictionary and find all variations of the "Net Worth" title that exist but is that the most efficient way? Should I just use a super long if then statement?
Thanks in advance for your help!
****Also if anyone is wondering if I should even use a macro for this please remember this is part of a much larger project where there are many calculations and they are repetitive across workbooks. My only difficulty is finding where the data is in each workbook.

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

visual basic 2010 would a class or structure be better in this use case

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.

VBA Code Standardisation Practices

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!