Excel Indirect() type function For VB.net?

791 Views Asked by At

In excel I could say =INDIRECT("A" & G3) where G3 had a value of 4 and my cell would then refer to A4. What I am looking for is a similar kind of function for VB.net.

Is there a way to refer to a different variable based on a variable. EG. first pass I was to refer to txtJobNum1, txtBatNum1, and lblBat1. on pass two txtJobNum2, txtBatNum2, and lblBat2. If it were only a few, 3-4 maybe, it wouldnt be bothersome, but it's 50. The best I have come up with now to work around is build a class that holds references to those objects and make an array of that class. Below is an example table showing What I want to make with a given input number.

You can see how if I could make use of an "INDIRECT" function It could potentially shrink down to a 5-6 line loop instead of 200 lines of just variable assignments.

my concept of how it would work

BatchGroups(<NUMBER>).Label = lblBatNum<NUMBER+1>

0   BatchGroups(0).Label = lblBatNum1
0   BatchGroups(0).Number = txtBatNum1
0   BatchGroups(0).Quantity = txtQtybat1
0   BatchGroups(0).JobNumber = txtJobNum1
1   BatchGroups(1).Label = lblBatNum2
1   BatchGroups(1).Number = txtBatNum2
1   BatchGroups(1).Quantity = txtQtybat2
1   BatchGroups(1).JobNumber = txtJobNum2
2   BatchGroups(2).Label = lblBatNum3
2   BatchGroups(2).Number = txtBatNum3
2

There are 2 best solutions below

0
On

All of the controls are stored in the Controls collection of their parent, and the controls in the Controls collection are addressable by name, like this:

Dim theControl As Control = Me.Controls("txtJobNum" & theNumber)

(Where Me is the Form) If the controls are in some other container control, such as a panel, you can get to them through that container control's Controls property, for instance:

Dim theControl As Control = MyPanel.Controls("txtJobNum" & theNumber)

However, having 50 some-odd controls like that sounds like it may be a bad design anyway. It may be better to consider having a grid, or an editable list of some sort. If you must have all of the separate controls like that, it would probably be better to dynamically load them in a loop, and then store references to them in a list of BatchGroup objects as you were thinking. It would be much easier to to that in a loop because you'd only write the code once rather than separately for each batch group.

More generally, the term in .NET for what you are asking is called "Reflection". However, using reflection can cause your code to be more brittle and it is also not very efficient, so, when there are other alternatives, is is the case here, it is usually best to take one of them, rather than resorting to reflection.

0
On

Create a dictionary of your objects by Name. Then use TryGetValue to retrieve. In this case it would expect a String value as a Key, so you can have a custom naming scheme, which maps 1-to-1 onto your controls list.

Read more about a Dictionary class on MSDN:

You could use .Controls of the parent container, but then your controls could be nested in each other, so you'd have to use recursion or linearize into flat list, either adds complexity and maintainbility effort, and reduces performance. Dictionary is the fastest, especially if your Key is a string.