ReDim

J

Jan Eliasen

Hi.

I have the following code:

Dim stringArray(0) As String
ReDim Preserve stringArray(1)

When I try to run it, I get the following error:

Compile error:
Array already dimensioned

What is the meaning of this? I thought that ReDim is the way to
redimension an array in VBScripting? Does anyone have any thoughts on
this?

Thanks
 
M

Malcolm Smith

Jan

You should have declared the array as being:

Dim stringArray() as String

and then it would have worked. Because if you actually declare the size
of the array then it effectively fixes it. So, if you want to ReDim the
thing then you need to make sure that there is nothing in the brackets.

Now, there is something in your text which is slightly of concern. You
mention VBScripting. Do you mean VBScript or do you mean VBA? If you
are using Word's language then this is VBA and not VBScript.

There is a huge difference as VBA, like VB, is a typed language so you
really should have to declare your variables to be of a certain type as
you did.

Now, if you are talking about VBScript then this is a type less language
and then you ought to define it like so:

Dim stringArray()


Hope that this helps
- Malc
www.dragondrop.com
 
J

JGM

Hi Jan,

To add to what Malcom said.... I have just recently learned to use arrays
(up to 3 dimensions for now!), so explaining to you (or to anybody else
reading this thread wondering about arrays!) what I know will help me
consolidate my knowledge, and also, if anyone notices that I am way off
somehow, please, let me know.

Arrays are very useful because you can store almost anything in them, and it
is fairly easy to retrieve the information later, especially if you pass the
array variable between subs or functions. OTH, very often you do not know
the array size until some loop or other similar counting procedure or code
determines its size.

If you know at the start the array size, then you do not need Redim, you
just use something like:

'_______________________________________
Dim i As Integer
Dim MyArrayTest(4) As String
'note that
'MyArrayTest(4) = MyArrayTest(0 to 4), or 5 rows
'and MyArrayTest(1 to 5) also equals 5 rows...
For i = 0 To 4
MyArrayTest(i) = "My item # " & i & "."
Next i
'_______________________________________

Now, if your code is going to determine the size, then I find that there are
two situations.
1) You have a way of determining the size before you fill it in, like if you
were building an array to contain all bookmark names in a document:

'_______________________________________
Dim i As Integer
Dim MyArrayTest() As String
Dim ItemCount As Integer

ItemCount = ActiveDocument.Bookmarks.Count

'use Redim here to size the array before filling it
'Start the array at 1 because the first bookmark index is 1
ReDim MyArrayTest(1 To ItemCount)

For i = 1 To ItemCount
MyArrayTest(i) = "Bookmark " & i & " name: " & _
ActiveDocument.Bookmarks(i).Name
Next i
'_______________________________________

or

2) You do not know the size beforehand, your code will look at a list of
items and select/discard some items based on some condition(s).
Here, what I do is fix the size before I start with a number that I know is
higher than (or equal to) the maximum I need, then whem I am done, I resize
the array. You can incude defensive programming to make sure that the user
is not in a situation where that pre-determined over-sized number is in fact
larger than necessary. You have to do that otherwise, if you do not fix an
array size, you cannot fill it in. Here you need Redim and redim Preserve:

'_______________________________________
Dim i As Integer
Dim IncludedItems As Integer
Dim MyArrayTest() As String
Dim ItemCount As Integer

ItemCount = ActiveDocument.Bookmarks.Count
IncludedItems = 0

'Maximum possible
ReDim MyArrayTest(1 To ItemCount)

For i = 1 To ItemCount
If InStr(ActiveDocument.Bookmarks(i).Name, "Test") <> 0 Then
MyArrayTest(i) = "Bookmark " & i & " name: " & _
ActiveDocument.Bookmarks(i).Name
IncludedItems = IncludedItems + 1
End If
Next i

'Resize to actual maximum, use Preserve otherwise the array
'content will be flushed
ReDim Preserve MyArrayTest(1 To IncludedItems)
'_______________________________________

In a nutshell, this is what I have understood about arrays in the last few
months.

HTH
Cheers!
 
M

Malcolm Smith

Jean-Guy,

Next thing to look at are perhaps Collections. Sometimes when one doesn't
know how long an array is a Collection could be useful and it's not
impossible to make multiple dimension collections either.

I do this when gathering betting price data off the internet and I end up
with, effectively, a five dimensional data structure all run off
collections or, sometimes, as a throwback to the past; a linked list.

Anyway, arrays have their uses but what I am saying that your next stage
is to investigate Collections because sometimes they can be better for
your own use than arrays.

- Malc
 
J

JGM

Hi Malc,

If nothing else, I am a good student!

I investigated the Collection object, then I thought I put it into practice.

I imagined the following scenario:

In a multi-select list box on a UserForm, I want to list all bold words from
a "simple" document , select the words I want to Unbold and click on a
button to do so...

Now remember that my purpose here is to practice fooling around with a
collection object.
So I am not claiming that the way I do it below is the best way...

So here is my code and a question follows:

In a standard module:
'_______________________________________
Public Const ItemSeparatorLen As Integer = 11
'The following constant is to separate the word from its index
'position in the document so I can retrieve it later.
Public Const ItemSeparator As String = "_myNumber_#"
Public BoldWords As New Collection
'_______________________________________
Sub callForm()

Dim i As Integer

With ActiveDocument.Range
For i = 1 To .Words.Count

'And ... > 1 to eliminate paragraph marks and other single character that
Word
'considers as words... I realize that in this simple code I am also
'eliminating words like "a", "I" and so on... but for now it does the job...
If .Words(i).Bold And Len(.Words(i).Text) _
BoldWords.Add .Words(i).Text & _
ItemSeparator & i
End If
Next i
End With

'never mind magic forms for now... it is just a test on a
'single simple document!
'A user form with a list box and 2 buttons
Load UserForm1
UserForm1.Show

End Sub
'_______________________________________

In the UserForm1 code page:

'_______________________________________

Private Sub Cancelcmd_Click()

Unload Me

End Sub
'_______________________________________

Private Sub UnBoldcmd_Click()

Dim i As Long
Dim ItemtoUnBold As Variant
Dim MyNumberPos As Long

For i = 0 To BoldWords.Count - 1
If ListBox1.Selected(i) Then
ItemtoUnBold = BoldWords.Item(i + 1)
MyNumberPos = InStr(1, ItemtoUnBold, _
ItemSeparator)
ItemtoUnBold = Mid(ItemtoUnBold, _
MyNumberPos + ItemSeparatorLen)
ActiveDocument.Range.Words(ItemtoUnBold) _
.Bold = False
End If
Next i

Unload Me

End Sub
'_______________________________________

Private Sub UserForm_Activate()

Dim i As Integer
Dim AddedItem As String
Dim MyNumberPos As Long

For i = 1 To BoldWords.Count
AddedItem = BoldWords.Item(i)
MyNumberPos = InStr(1, AddedItem, _
ItemSeparator)
AddedItem = Left(AddedItem, _
MyNumberPos - 1)
ListBox1.AddItem AddedItem
Next i

End Sub

'_______________________________________


The collection objects behaves as expected and is indeed useful... Thanks
for bringing it to my attention. OTH, I will wait before I venture coding
with collections of collections to simulate multidimensional arrays! But I
see how it could be done.

My question is (Nothing to do with collections!):
in the code that gathers the items to build the collection:

For i = 1 To .Words.Count
If .Words(i).Bold And Len(.Words(i).Text) _
BoldWords.Add .Words(i).Text & _
ItemSeparator & i
End If
Next i

The "For i = 1 To .Words.Count" loop is very slow...
My simple test document had only 448 words on two pages... and it was
already atrociously slow...
Any fast way to iterate through the words collection? A different kind of
loop?
Remember that I need to store the index position of each word I pick up so I
can refer to it later to unbold it if I choose to do so...

TIA

Have a good weekend in frosty Wales!
 
J

Jan Eliasen

On Thu, 4 Dec 2003 15:14 +0000 (GMT Standard Time),
You should have declared the array as being:
Dim stringArray() as String
Right. Thanks. I actually started out doing that, but then I ran into
another problem.

I wanted to have a loop, in which I Redim'ed the array to have one
more place and then I filled it with data. But I couldn't find a way
to do that. If I use
Dim stringArray() As String

then I can't do this:
ReDim Preserve stringArray(UBound(stringArray) + 1) because UBound
will fail. How do I check if stringArray contains any elements (empty
or not)?
Now, there is something in your text which is slightly of concern. You
mention VBScripting. Do you mean VBScript or do you mean VBA? If you
are using Word's language then this is VBA and not VBScript.
Yes, I am sorry about the confusion. I am using VBA.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top