Redim Multidimenional Arrays

  • Thread starter Thread starter Anil Gupte
  • Start date Start date
A

Anil Gupte

I am having a problem using Multidim arrays. I want to create an array
which as I understand it is dimensioned as:

dim xyz (rows,columns) as String

I want to populate it with rows from a table in a database. I don't know
how many rows I am getting so of course I have to Redim inside the loop that
does this.

Unfortunately, the error message and documentation say: "In a
multidimensional array, you can change only the last dimension when you use
Preserve"

How can that be? How can you not be able to change the number of rows? Or
am I missing something? Is there a different variable type that I need to
use?

Thanx in advance,
 
Is there a different variable type that I need to use?

Use a dataset for working with database tables.

Also you could build a dynamic array by first counting the number of
rows and columns, then sizing the array, and then populating it. But
that will give you a difficult to manage, unflexible, memory hog of an
object, so you should stick with the datasets.

Thanks,

Seth Rowe
 
Well, two things here. Not allowing the number of rows to change is the
dmbest implementation of Arrays I have ever seen. I'd like to thump the guy
in charge of that piece. :-)

But more pertinently, lests discuss your suggestion of using datasets. I
already am using a dataset. I am trying to put the data from the dataset
into an array so I can access it more easily. The underlying problem is
that I have a dropdown list where based on the selection I want to access
another table. So, for example, if I have:

One
Two
Three
Four

in a drop down list that comes from a table (call it Table1) containing
One, Kids
Two, Adults
Three, Couples
Four, Singles

I want to then select from a different table based on the drop down
selection. So if someone chooses Kids from the drop down, I want to execute
"Select * from Table2 where xyz='Kids'"

Any suggestions?
--
Anil Gupte
www.keeninc.net
www.icinema.com

rowe_newsgroups said:
Is there a different variable type that I need to use?

Use a dataset for working with database tables.

Also you could build a dynamic array by first counting the number of
rows and columns, then sizing the array, and then populating it. But
that will give you a difficult to manage, unflexible, memory hog of an
object, so you should stick with the datasets.

Thanks,

Seth Rowe
 
Anil said:
I am having a problem using Multidim arrays. I want to create an array
which as I understand it is dimensioned as:

dim xyz (rows,columns) as String

I want to populate it with rows from a table in a database. I don't know
how many rows I am getting so of course I have to Redim inside the loop that
does this.

Unfortunately, the error message and documentation say: "In a
multidimensional array, you can change only the last dimension when you use
Preserve"
<snip>

You must declare your array like this:

Dim xyz(Columns, Rows) As String

This way the Rows dimmension can be resized at will.

The Redim keyword comes from VB.Classic. It turns out that arrays, in
VB.Classic, used column-major order (maybe because Basic copied so many
Fortran features). This means that the array binaries were layed out in
memory in a way that turned impractical to redim any but the last
dimmension. For instance, the following array:

Dim A(0 To 1, 0 To 2) As Integer

Would have the following layout in memory in VB.Classic:

(0,0) (1, 0) (0, 1) (1, 1) (0, 2) (1, 2)

As you can see, resizing the first dimmension would require introducing
gaps all over the array, something doable but expensive. On the other
hand, resizing the last dimmension would only allocate more space at
the end of the array.

Notice that arrays in .Net have Row.major order. This means that the
previous array, in .Net, is layed out in memory like this:

(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2)

which makes easier to resize the first dimmension, but not the others.

Nevertheless, the Redim rule from VB.Classic still applies, because of
compatibility issues. The irony is that VB.Net must now perform a
costly "copy by chunks" operation when you redim the array... :-P


HTH.

Regards,

Branco.
 
Well, two things here. Not allowing the number of rows to change is the
dmbest implementation of Arrays I have ever seen. I'd like to thump the guy
in charge of that piece. :-)

If you really wanted to, you could create your own methods to resize an
array. You would just have to create a new array with the correct
number or rows and columns. Then loop through the original array
plugging these values into the proper place in the new array. But then
you might as well flush the scalability and performance of your app
down the toilet :-)
I want to then select from a different table based on the drop down
selection. So if someone chooses Kids from the drop down, I want to execute
"Select * from Table2 where xyz='Kids'"

When the user changes the selection of the drop down list, why not just
hit one of the dataset tables with the SQL command? Also, you could
just use datareaders to populate the drop down and then execute your
SQL commands directly against the server. This may be better if you
have data that constantly changes, as you won't have to worry about
refreshing the dataset all the time. Also, as a small warning, building
SQL commands "on the fly" can be prone to SQL injection attacks, you
may look into using parameterized Stored procedures (or whatever
alternitive your database provides) in order to protect against these
attacks.

Hope that Helps,

Seth Rowe

Anil said:
Well, two things here. Not allowing the number of rows to change is the
dmbest implementation of Arrays I have ever seen. I'd like to thump the guy
in charge of that piece. :-)

But more pertinently, lests discuss your suggestion of using datasets. I
already am using a dataset. I am trying to put the data from the dataset
into an array so I can access it more easily. The underlying problem is
that I have a dropdown list where based on the selection I want to access
another table. So, for example, if I have:

One
Two
Three
Four

in a drop down list that comes from a table (call it Table1) containing
One, Kids
Two, Adults
Three, Couples
Four, Singles

I want to then select from a different table based on the drop down
selection. So if someone chooses Kids from the drop down, I want to execute
"Select * from Table2 where xyz='Kids'"

Any suggestions?
 
Yes, thanx - that helps undersand what is going on, but seems like the old
legacy dragon strikes again! I have programmed in Lisp for a long time and
Arrays are so easy to redimension in any manner it is not funny. But maybe
because of Lisp, I have always conceptually thought of arrays as being:
((0,0) (0,1)
(1,0) (1,1)
(2,0) (2,1)
and so on...
)

Anyway, I did not underatand your statement:

Dim xyz(Columns, Rows) As String

Do you actually use the words Columns and Rows? I am doing:
Dim xyz(,) As String
 
why not just
hit one of the dataset tables with the SQL command?

Yes, that is exactly waht I want to do. But my problem is that I need some
way of separating what the dropdown list shows from the actual value that is
used in the SQL statement. Something like the DisplayMember and ValueMember
properties. See my other post "How to assign value to a dropdown box
items?"

Thanx,
 
Anil Gupte wrote:
Anyway, I did not underatand your statement:

Dim xyz(Columns, Rows) As String

Do you actually use the words Columns and Rows? I am doing:
Dim xyz(,) As String
<snip>

Sorry, I didn't make it clear. What I meant was to treat the first
dimmension as the column selector, and the last dimmension as the row
selector. So, if you have a table with the columns "Name" and "Age",
you'd have:

Dim Items(0 To 1, 0 To -1) As String 'An empty table

'...
'Adds a row:
Dim NewIndex As Integer = Items.GetLength(1)
Redim Preserve Items(0 To 1, 0 To NewIndex)
Items(0, NewIndex) = TheName
Items(1, NewIndex) = TheAge

Of course, all this trouble is because you want to extract the data
from the original dataset.
Another approach could be to use the orginal table:

mData = New DataTable

mData.Columns.Add("ID", GetType(Integer), Nothing)
mData.Columns.Add("Name", GetType(String), Nothing)
mData.Columns.Add("DisplayText", _
GetType(String), "id + ' - ' + name")

mData.Rows.Add(1, "John")
mData.Rows.Add(2, "Mary")
mData.Rows.Add(3, "Lamb")
mData.Rows.Add(4, "Little Pig")

With Me.ComboBox1
.DataSource = mData
.DisplayMember = "DisplayText"
.ValueMember = "ID"

'Selects the item with ID = 4
.SelectedValue = 4
End With

HTH

Regards,

Branco.
 
Thanx for the help. I got it working with the dataset instead of using the
arrays. However, now I have different problem. The
DropDownProfiles.SelectedValue returns a "DataRowView" instead of the value
from the field (my program expects an integer). If you have some
suggestions, let me know.

Thanx for the help so far.
 
Back
Top