PDA

View Full Version : My Visual Basic Question for the day


Cap Ologist
11-23-2004, 04:56 PM
I'm working on a loop that checks to make sure the inputs the user makes are of the correct data type (for example, a string for name, a number for age). I wrote a neverending do while loop like this:

Do While (VarType(sFirstName) <> vbString)
nResponse = MsgBox(sMessage + "first name.")
Loop

I want it to be able to check and make sure that the value for the first name is a string, however, this loop doesn't allow the user time to change their answer. It just keeps popping up over and over.

This is a rough outline of my program so far.

Public Sub inputCheck

'Declare local variables.
Dim sFirstName As String
Dim sMessage As String
Dim nResponse as Integer

'Store user input.
sFirstName = txtFirstName.Text

'Store custom message.
sMessage = "Please enter a valid "

Do While (VarType(sFirstName) <> vbString)
nResponse = MsgBox(sMessage + "first name.")
Loop

End Sub

Should I split this into multiple subroutines or functions or is there a way to pause a do while loop and allow the user to go back and change their input?

Thanks for the help in advance.

VPI97
11-23-2004, 05:16 PM
Instead of:
nResponse = MsgBox(sMessage + "first name.")

use:
sFirstName = InputBox(sMessage + "first name.", "App title", sFirstName)

Cap Ologist
11-23-2004, 10:12 PM
Oops, one thing I forgot, not all input comes from text boxes. There are a couple where they select from combo boxes.

Mr. Wednesday
11-23-2004, 10:41 PM
I can see a couple of options.
If this has to happen during a block of code that accepts inputs, then most likely what you need is either a DoEvents loop with some kind of sentinel to indicate that input is complete and check again, or a form displayed modally (vbModal) which will pause execution in the routine until the form is cleared.

Alternatively, perform all validation at the front of the routine and kick out with an "Exit Sub" if it doesn't validate correctly.

InputBox is handy but offers very limited control over presentation and is not suitable for masked or non-text-box input.

Fritz
11-24-2004, 07:09 AM
Well, if you:

Dim sFirstname as String
Dim nResponse as Integer

then you can be fairly sure of their data type. Any value stuck into sFirstName will be a string, so all you really need to see is the length.

If you want something finer, like a-z, then you have some more work to do.


I'm working on a loop that checks to make sure the inputs the user makes are of the correct data type (for example, a string for name, a number for age). I wrote a neverending do while loop like this:

Do While (VarType(sFirstName) <> vbString)
nResponse = MsgBox(sMessage + "first name.")
Loop

I want it to be able to check and make sure that the value for the first name is a string, however, this loop doesn't allow the user time to change their answer. It just keeps popping up over and over.

Cap Ologist
12-01-2004, 01:33 PM
Thanks for the help guys. A couple more questions...

1. Is it possible to adjust the size of arrays within the program?

For example, say I have a list of 10 fictional towns. My user would like to change the name of one of the towns without overwriting one of the present towns. I know I could just make an array bigger than I could possibly use, that just seems like an inefficient use of memory. Is it possible to ask the user how many towns you would like to add then add that number to the existing array index and then add the new names?

2. I'm trying to work on some GUI issues that are probably pretty simple, and I'm just missing something obvious here. From the main screen of my project, I have three buttons, New, Load, and Resume. I'd like Resume to start off disabled, so I disabled the controls. After the user selects New and starts a new file, I'd like to enable Resume to allow him/her to close the window and then be able to start back where they were.

I tried using this code:

Private Sub imgContinue_Click()

frmWindow.imgResume.Enabled = True
frmMain.Show vbModal

End Sub

It doesn't seem to work the way I want it to, am I misunderstanding what enabled means? I think it means it's visible, but unable to be use.

gottimd
12-01-2004, 01:46 PM
This board (http://www.mrexcel.com/board2/) should be able to help you pretty fast. I use this when I get stuck on VBA and coding problems.

Gary Gorski
12-01-2004, 02:27 PM
Thanks for the help guys. A couple more questions...

1. Is it possible to adjust the size of arrays within the program?

For example, say I have a list of 10 fictional towns. My user would like to change the name of one of the towns without overwriting one of the present towns. I know I could just make an array bigger than I could possibly use, that just seems like an inefficient use of memory. Is it possible to ask the user how many towns you would like to add then add that number to the existing array index and then add the new names?

2. I'm trying to work on some GUI issues that are probably pretty simple, and I'm just missing something obvious here. From the main screen of my project, I have three buttons, New, Load, and Resume. I'd like Resume to start off disabled, so I disabled the controls. After the user selects New and starts a new file, I'd like to enable Resume to allow him/her to close the window and then be able to start back where they were.

I tried using this code:

Private Sub imgContinue_Click()

frmWindow.imgResume.Enabled = True
frmMain.Show vbModal

End Sub

It doesn't seem to work the way I want it to, am I misunderstanding what enabled means? I think it means it's visible, but unable to be use.


1. You can use ReDim (ex. ReDim sCity(11) as string)

2. You are correct with enabled meaning visible and clickable/not clickable. Without a lot more code its hard to tell why its not working but one thought is are you setting imgResume.enabled = false at run time or in the code itself and are you unloading frmWindow? If you enabled imgResume but then unload and reload frmWindow it will revert to whatever you have imgResume set as in the code.

Hope that helps

sterlingice
12-01-2004, 03:39 PM
This board (http://www.mrexcel.com/board2/) should be able to help you pretty fast. I use this when I get stuck on VBA and coding problems.
The Microsoft newsgroups work pretty well, too. But might as well ask here first.

SI

Cap Ologist
12-01-2004, 04:00 PM
I usually check here first because there seems to be plenty of people who are familiar with VB 6.0, but thanks for the other sites as well.

Mr. Wednesday
12-01-2004, 05:39 PM
microsoft.public.vb.general.discussion IIRC is the ongoing VB classic newsgroup (.NET questions go to a different group). There should be a number of knowledgeable people there, but sometimes the good questions get drowned out in the volume.

Mr. Wednesday
12-01-2004, 05:40 PM
Dola, also, note that load/unload will handle the visible elements of the form, but the underlying object type may not be released without setting it to Nothing -- i.e. variables that you set may not clear. I'm not sure if the properties of visual elements are associated with load/unload or with the underlying object type.

Mr. Wednesday
12-01-2004, 05:42 PM
1. Is it possible to adjust the size of arrays within the program?

For example, say I have a list of 10 fictional towns. My user would like to change the name of one of the towns without overwriting one of the present towns. I know I could just make an array bigger than I could possibly use, that just seems like an inefficient use of memory. Is it possible to ask the user how many towns you would like to add then add that number to the existing array index and then add the new names?Use ReDim / ReDim Preserve (the former will nuke existing data in the array, the latter will expand/contract in-place). Personally, I use variable-size arrays almost exclusively, I rarely if ever hard-code the limits.

Cap Ologist
12-05-2004, 11:11 PM
How much attention should I pay to how I declare variables? For instance, I have a three dimension array (12,000, 1, 3). This is going to be an array that "grows" in the future, meaning that the first two dimensions will increase over time. It is likely that at some point, the first dimension will pass the range of an integer variable. I could start the array at the low end of an integer range (-32768) and that would buy me some extra time or I could just go ahead and declare it to be "single". An integer takes 2 bytes of storage compared to 4 bytes for a single. Say I reach 64,000 in my first dimension, that is 128,000 bytes of storage compared to 256,000 bytes for a single. How much of an impact will that make as far as performance and storage space required for a user?

Mr. Wednesday
12-05-2004, 11:28 PM
How much attention should I pay to how I declare variables? For instance, I have a three dimension array (12,000, 1, 3). This is going to be an array that "grows" in the future, meaning that the first two dimensions will increase over time. It is likely that at some point, the first dimension will pass the range of an integer variable. I could start the array at the low end of an integer range (-32768) and that would buy me some extra time or I could just go ahead and declare it to be "single". An integer takes 2 bytes of storage compared to 4 bytes for a single. Say I reach 64,000 in my first dimension, that is 128,000 bytes of storage compared to 256,000 bytes for a single. How much of an impact will that make as far as performance and storage space required for a user? I think you're confusing the indexing with what is actually stored in the array. The way the array is indexed is that the array has a descriptor, which keeps track of where the data starts (it's all addressed as a big chunk, with the Windows memory manager taking care of gory details that shouldn't concern you), how many dimensions there are, what the length is in each dimension (so it knows where to go to jump to the next row, sometimes also referred to as a stride), and what the base index is in each dimension (because VB can index from anything you want).

The size of that data doesn't change as you extend the array in a given dimension, it only changes as you add dimensions. I highly doubt you'd even try to add enough dimensions to cause trouble in terms of the size of the descriptor, and even if you did, the compiler would stop you.

That's all distinct from the question of the data type you use for what you store in the array. There, you should consider what you want to store and use the most appropriate type for the performance (in both speed and memory usage) that you want to target. Unless you are talking really gigantic arrays or support for very out-of-date hardware, memory usage is probably not a big deal. Most computers nowadays have a lot of physical memory backed by a massive amount of swap space, to the extent that you'd sooner risk running out of address space (2 GB limit there) than out of swap space to use. As far as speed goes, at least in VB Longs are typically faster than Integers, I think because they're the native integer type in Win32.


This is probably also a good place to make a note about arrays and performance. Although VB has a lot of programming features in common with C and C++, it has more of a Fortran heritage and this is particularly important in array performance. Unlike C and C++, VB uses column-major arrays, meaning that for maximum performance, you should vary the first index most rapidly, not the last. Otherwise, you'll defeat the use of the fast cache memory on your processor as you will use a single value from a cache line and then toss the rest and refresh from slow main memory. This is really a big deal only if you're doing a lot of batch processing on the array, otherwise you don't need to worry about it.

Cap Ologist
12-05-2004, 11:44 PM
Thanks, you're right I was getting those confused. That makes a lot of sense.