# vb.net adding elements to multi-dimensional array



## weslee (Apr 11, 2004)

is it possible to make a multi-dimensional array and dynamically add items to it? I'm in need a string array with 2 dimensions. If another method exists, how do I use it?

I am creating a program that will allow me to view/update customer status for my customers. The first dimension in the array will be my "column" for customers, and the 2nd dimension will hold the information about each customer (name, etc).

So the structure is like this:
1,[name,number,etc]
2,[name,number,etc]

Thanks
Tanner


----------



## weslee (Apr 11, 2004)

Let me clarify what I'm attempting to do here.

I thought I could do this by using a For loop. Here's some example code...


```
Dim objCustomer as New Customer
Dim customerArray(,) as String
Dim intCustomerCount, intIndex as Integer

intCustomerCount = 20 <-- This would be dynamic in my real code

For intIndex = 0 to intCustomerCount

customerArray(intIndex,0) = objCustomer.customerID
customerArray(intIndex,1) = objCustomer.FirstName
customerArray(intIndex,2) = objCustomer.LastName
customerArray(intIndex,3) = objCustomer.Address

Next
```
Basically, the first dimension of the array would be considered "the different customers", and the second dimension would hold the attributes for each customer, based off the first dimension.

WesLee


----------



## cristobal03 (Aug 5, 2005)

I don't know in regard to .Net, but what you have there isn't too far off for VB. The problem is that you haven't dimensioned the array. At least, that'd be a problem in VB. I imagine .Net is at least as strict a language as VB (which isn't very strict, but anyway).


```
Private Sub BuildArray()
  Dim saArray()  As String
  Dim strText    As String
  Dim intFirst   As Integer
  Dim intLast    As Integer

  Dim i As Integer, j As Integer

  ' the first index:
  intFirst = 0

  ' the last index:
  intLast = 19

  ' dimension the array 2-D with the first dimension
  ' having indices 0-19 and the second dimension
  ' having indices 0-3:
  ReDim saArray(intFirst To intLast, 3)

  For i = 0 To UBound(saArray, 1) ' first dim. upper bound
    For j = 0 To UBound(saArray, 2) ' second dim. upper bound
      saArray(i, j) = (i + j) ^ 2
    Next j
  Next i
End Sub
```
There's more to it than that. For example, if you want a truly dynamic multi-dimensional array, you'll have to be able to redimension it on the fly. For that you'd use

*ReDim Preserve array(1st dimension upperbound, new 2nd dimension upper bound)*

You may only change the size of the last dimension using the *Preserve* keyword, and then only by increasing its upper bound. In other words, you can't shrink any of the dimensions. A more practical example of dimensioning an array in your case might be something like this:


```
Private Sub BuildArray(ByVal lngCustomerCount As Long) As String()
  Dim saArray() As String

  ' 1st dim. would be base one here, or have an extra index
  ReDim saArray(lngCustomerCount, 3)

  ' for base zero
  ReDim saArray(lngCustomerCount - 1, 3)

  ' returns a dimensioned, unpopulated array.
  BuildArray = saArray
End Sub
```
Anyway, you might already know all this. If you do, sorry, ignore this post.

HTH

chris.

[edit]
Added a note about the base to the second example.
[/edit]


----------



## weslee (Apr 11, 2004)

Your input is helpful, but doesn't do the trick.

It's very hard to explain the exactness of what I'm doing, but I'll try as hard as I can.

I created a class that will connect to an Access database and pull the customers out of it. All those customers are added to a collection named CustomerList.

Right now I have the code set up as:

```
For Each objCustomer In objcustomers.CustomerList
txtCustomerID.Text = Convert.ToString(objCustomer.CustomerID)
txtFirstName.Text = objCustomer.FirstName
txtLastName.Text = objCustomer.LastName
Next
```
In this case though, it will run through all my customers that are in the CustomerList collection, and the result will be the last customer showing up in my text fields... because it loops through all the customers and ends with the last one. I don't want to have to limit my SQL query down to a specific customer (that comes later when I attempt to add search function in my program). Right now my SQL query gets all the records from my Access table. I want a way to specify "okay, I want to look at customer 3" and it will take an "intCurrentCustomer = 3" ... and then pull out the 3rd customer in the CustomerList (collection).

I tried to go like this:
objCurrentCustomer = objCustomers.CustomerList.Item(intCurrentCustomer)

But that doesn't work... it tells me that it won't allow implicit conversions from 'system.object' to 'Customer_Review.Customer'

Does that even make sense? lol, I don't feel like it does, but whatever.


----------



## cristobal03 (Aug 5, 2005)

This is where my helpfulness ends, because I don't know .Net; however, it sounds like *CustomerList* is a user-defined class object property, so it won't have an *Item* property/method unless you write one yourself.

[edit]
Or does .Net support subclassing and inheritance?
[/edit]

I assume with the array you were trying to build a collection of every customer, so that you could use the ordinal indices to get the same functionality as what you'd have with *Item*. That may not be the optimal solution, but you ought to be able to pull it off.

However, it sounds like you might not be taking advantage of the methods available to Access recordset objects. You could accomplish the exact same thing using a recordset's *Move* method, which takes a long integer argument, like so:


```
Private Sub MoveToRecord(Optional ByVal lngCurrentCustomer As Long = 3)
  Dim rst                 As Recordset

  Set rst = CurrentDb.OpenRecordset("SELECT * FROM tblSomeTable")

  With rst
    .MoveLast
    .MoveFirst
    .Move lngCurrentCustomer

    txtCustomerID = !CustomerID
    txtNameFirst = !NameFirst
    txtNameLast = !NameLast
  End With

  Set rst = Nothing
End Sub
```
Also, it seems like there is some presupposition involved in your logic.



> *Originally posted by weslee:*
> 
> I don't want to have to limit my SQL query down to a specific customer


cf.



> I want a way to specify "okay, I want to look at customer 3"


Those two statements seem inconsistent; more importantly, it sounds like you will already know something about the identity of customer 3, so you don't _really_ need a way to dynamically select customers but rather a way to select a known set of customers from the master list.

But really, I don't know .Net, so. Sorry I couldn't be more helpful. If it sounds like I might be on to something, though, and you have more questions, post back.

chris.


----------



## weslee (Apr 11, 2004)

Your post might prove to be very helpful. Thanks for the feedback.

You are right in the inconsistency of my logic. The problem is that my Customers class runs the SQL query, and the only way i KNOW how to get what i want is by passing a variable to the query so that it says:

"WHERE customerID = " & intCustomerID

I want the master list to include all customers so that i can take advantage of a "next" and "previous" button and cycle through the results, but still have a way to specify a specific one from that list.

I don't have time tonight, but tomorrow I will try to put your good knowledge to use and I'll post back to let you know what I find out.

Thanks for helping me out.


----------



## weslee (Apr 11, 2004)

okay, I actually did start to try what you said, but Recordset is apparnetly no longer a part of VB in .NET. I looked up the alternative to Recordset in google and found this:

http://www.dotnet247.com/247reference/msgs/48/240970.aspx

But the problem is that I'm not sure how to interpret EVERYTHING the guy is saying there. You have a good understanding of what I'm trying to do, so maybe you could read that article and convert it over for me. I don't want to waste too much of your time though.

This is a line of code that I tried using, but instead of pulling out the proper "item" out of the database, it ends the loop with the last item in the database and then "reads" the information to me... again, not what i'm trying to do.

' intCurrentCustomer was passed to the function in this class from my main program
While objOleDbDataReader.Read()
objCurrentCustomer.FirstName = Convert.ToString(objOleDbDataReader.Item(intCurrentCustomer))
End While


----------



## cristobal03 (Aug 5, 2005)

Hey weslee, sorry I haven't responded in a while.

First, I think I should've been more explicit about this point:



> *Originally posted by cristobal03:*
> 
> it sounds like you might not be taking advantage of the methods available to _Access_ recordset objects


I meant, since your application seems to use an Access database as a back-end you can create an Access Recordset object. I don't know how to do that in .Net, but in VBA it might be something a little like this:


```
Dim oAccessRecordset As Object

  Set oAccessRecordset = CreateObject("DAO.Recordset")

  ' or

  Set oAccessRecordset = CreateObject("ADO.Recordset")
```
However, like I said, I don't know if .Net supports that class of objects.

Sorry, but I think my knowledge has reached its limit concerning your problem.

GL

chris.

[edit]
Typo.
[/edit]


----------



## OBP (Mar 8, 2005)

Weslee, have you managed to store the records in the array? Does your previous/next work?


----------



## treydx (Jan 4, 2006)

I don't know much about .Net, but it sounds like we might have some fuzzy client/server logic going on. 

Where do you anticipate storing this multidimensional array (Session or Application variables are server-side)? After you send a record (customer #3) to the client, that connection with the server is going to be severed and the client will have to resubmit the page to the server anyway, so why not just return that singular customer instead of returning all the customers to the client but throwing them all away except the target one.


----------



## OBP (Mar 8, 2005)

Better still why not just an Access Database "Access Page" which is a web based Access Form.


----------



## RGregory (Jul 27, 2005)

The recordset object no longer exists in dotnet. The new object is called a dataset, which I like to think of as a spreadsheet containing the data. It will connect to the data source, retrieve all records requested, and then disconnect. The good part about this is there is less constraints on the table. The bad part is that if you make changes to the data, it will not be reflected in the table unless you specify an update. If you fill the dataset with results from a query the appropriate record will be located at dataset.row(item you are looking for -1) since they are 0-based. Of course you will have to specify .item to get the appropriate field.


----------



## cristobal03 (Aug 5, 2005)

RGregory,

If I'm reading that correctly, the syntax to read/write to the particular field of a recordset (now dataset) would be

*Dataset.Row(Index).Item(Index).Value*

where *Index* can be a named or zero-based number argument, is that correct? How would one dimension and instantiate a dataset object with reference to an Access table/query?

Thanks for the input, by the way. I've been sort of floundering.

Also, weslee, the points treydx and OBP raise are also worth considering. They'll be pretty tough to answer without more information about the application and its requirements, though.

chris.


----------



## weslee (Apr 11, 2004)

Thanks for the input. My program is basic enough that I actually found another way to do what I need to do.

First, treydx, this is not a web application or service. This is all being done locally.

What I did was create a method for extraction in my customers class, and a 2nd method for querying the entired database to give a number for how many records are in it. I realize that this is a terrible way to do things, but it worked for me.

I am however interested in learning more about the dataset. My current program will not allow for searches, but I would like to be able to perform searches. From what I've read, it sounds like a dataset would possibly allow me to perform a search so that I can pull out more than one customer with the first name of "john"?

This would be helpful information for any future programs that I might write.


----------



## OBP (Mar 8, 2005)

weslee, if this is not web based application why are you using VB.net instead of Access queries for "local" data manipulation?
Is it a learnign exercise?


----------



## weslee (Apr 11, 2004)

Yes, it's SORT OF a learning exercise.... but the point also is that by using this same "Customers.vb" class, I could incorporate a web based application as well. I'm doing this to build my skills in a practical way.

Plus, a vb.net app is more user friendly than Access... and if I ever wanted to fully develop this piece of software and make it freeware, people wouldn't need Access to manage their data, but would just need a "mdb" file to kick start them off.

This may seem dumb & pointless to most of you, but it is mostly for my learning experience. I DO have a few ideas for some applications I would like to code that WOULD be web based, and I would then need to know how to use datasets and such.

Thanks for everything so far and pointint me in the right direction.


----------

