Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Arrays - arrrggghhh!!

Status
Not open for further replies.

scasystems

Programmer
Jan 15, 2003
44
GB
I have a class with

Private mErrors() as String

Public SomeProc()
if ubound(mErrors)=0 then
fill array
end if
do something
end sub

The problem is the array is not initialized. so get subscript out of range error. if I do private mErrors(0) then i cannot redim the array. What is the most efficient method for checking unitialized arrays

cheers for any help
 

If possible, I'd forget arrays and use a Collection.

...very simplified

Private mErrors As New Collection

Private Sub Form_Load()
InsertError "Bad Thing happened here"
InsertError "Another Bad Thing happened"
If mErrors.Count > 0 Then
For Each eobj In mErrors
errmsg = errmsg & eobj & vbCrLf
Next
MsgBox errmsg
End If
ClearErrors
If mErrors.Count > 0 Then
For Each eobj In mErrors
errmsg = errmsg & eobj & vbCrLf
Next
MsgBox errmsg
End If
End Sub

Sub InsertError(err)
mErrors.Add err
End Sub

Sub ClearErrors()
While mErrors.Count > 0
mErrors.Remove (mErrors.Count)
Wend
End Sub



Mark
 
There are several possibilities:

1. Declare mErrors Variant data type (not an array of variants) and test if it's Empty.

2. Set a boolean variable to True when the array has been initialised and check the variable.

3. Use On Error GoTo to hanndle the subscript out of range error. The statement can be placed immediately before the Ubound call and cancelled afterwards:

Public SomeProc()

Dim blnNoArray As Boolean

On Error 5 GoTo NoArray
Reenter:
If blnNoArray Then
fill array
Elseif ubound(mErrors)=0 then
fill array
End If
On Error GoTo 0
do something
Exit Sub

NoArray:
blnNoArray = True
Resume Reenter

End Sub

Paul Bent
Northwind IT Systems
 
This is not necessarily the most efficient method (which is probably simply to raise an exception), but I offer it for fun. It's a substantially cut down version of a solution posted about a month and a half ago:

[tt]
Option Explicit

Private Type SafeArray
cDims As Integer
fFeatures As Integer
cbElements As Long
cLocks As Long
pvData As Long
End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private Declare Function VarPtrArray Lib "msvbvm60.DLL" Alias "VarPtr" (Ptr() As Any) As Long

Private Function IsDimmedArray(arrTest As Long) As Boolean
Dim lSourceAddress As Long
Dim sSource As SafeArray

CopyMemory lSourceAddress, ByVal arrTest, 4
IsDimmedArray = lSourceAddress
End Function

' And how to call it...
Private Sub Command1_Click()
Dim a() As Long
Dim b(1, 1) As Long
Dim c() As String


Debug.Print IsDimmedArray(VarPtrArray(a))
Debug.Print IsDimmedArray(VarPtrArray(b))
Debug.Print IsDimmedArray(VarPtrArray(c))
ReDim a(1)
Debug.Print IsDimmedArray(VarPtrArray(a))
End Sub
 
When using Arrays that you redimension later on, always im like this:
dim vntArr() as variant
redim vntArr(0)
After that, there's always an UBBound(vntArr).
 
The thing you have to be careful with concerning variant arrays is that you can do things like:

vntArr(0) = "Fred"
vntArr(1) = 5
vntArr(2) = 5 + "5"

which means it is easy for odd errors to creep into your program (OTOH this can sometimes be useful)...
 
strongm, I have a question about the code you posted - What is the purpose of the SafeArray UDT and the sSource variable? It looks like it was just dimmed and never used again, unless I'm missing something.

Thanks! Be an idiot:
 
EAh..er...yes...SafeArray and sSource are remnants of the earlier version posted in this forum and are not necessary in this version.
 
I can't see why you aren't able to redim the array when declared like mErrors(0), but you could try this:

' <-- Start of code -->
Private mErrors() As String

Public Sub SomeProc()
dim intUbound as Integer

' First give the array a dimension and thus a 'Ubound'.
ReDim mErrors(0)
While Not condition
' Now remember the Ubound
intUbound = UBound(mErrors)
' Fill the array's Ubound element
mErrors(intUbound) = &quot;Element &quot; & CStr(intUbound)
' Increment Ubound
intUbound = intUbound + 1
' Redim while preserving array content
' Remember: ReDim only redims the last array dimension!
ReDim Preserve mErrors(intUbound)
' Now check the looping condition
.. Check condition ..
Wend
End Sub
' <-- End of code -->

This is some code I use in one of my apps.

I hope it helps you out.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top