can anybody explain me.the use of redim statement and preserve
keyword over here.kindly let me know the idea .any help would be
Highly appreciated.

Public Function LoadData() As Boolean
Dim codeString As String
    On Error GoTo LoadData_Error

    Dim Obj As IProducts                '// The classinterface
    Dim rs As ADODB.Recordset           '// Recordset to hold the class.Getall call
    Dim inxCode As Integer              '// Index / offset for recordset id (code) field
    Dim i As Integer                    '// Counter for the array
    Dim strItem As String               '// String we add to combo box
    Dim J As Integer                    '// Used for iterating columns of the recordset

    '// Assume function fails
    LoadData = False
    i = 0
    Select Case ClassName

        Case ValidClassNames.cnProducts
            Set Obj = New Products
            inxCode = ProductFields.fldProductID
            Obj.FilterStr = mFilter

        Case Else
            Err.Raise Number:=10000, description:="Programming error. Unknown class type."
            Exit Function
    End Select

    cmbCodes.Clear
    Obj.QueryType = m_queryType
    Set rs = Obj.GetAll

    If blnDataReturned(rs) Then
        If IncludeBlank Then
            [B]ReDim mClassCodes(0)[/B]
            cmbCodes.AddItem BLANK
            mClassCodes(i) = CStr(BLANK_ID)
            i = i + 1
        End If
        mDontFireClickEvent = True
        Do Until rs.EOF
            strItem = ""
            strItem = rs.Fields(1).Value
            cmbCodes.AddItem strItem
            ReDim Preserve mClassCodes(i)
            codeString = IIf(IsNull(rs.Fields(inxCode).Value), NULL_STRING, rs.Fields(inxCode).Value)
            codeString = codeString & ";" & m_queryType
            mClassCodes(i) = codeString
            i = i + 1
            rs.MoveNext
        Loop
        
        If cmbCodes.ListCount > 0 Then cmbCodes.ListIndex = 0
    End If
    mDontFireClickEvent = False
    Call CloseRecordset(rs)
    'Set rs = Nothing
    '// Now, if we have a design time default, set it!
    If DefaultCode <> NO_DEFAULT Then
        Id = DefaultCode
    End If

    '// All's well - return True
    LoadData = True

LoadData_Done:
    Exit Function

LoadData_Error:
    Call Process_Error(MODULE_NAME, "LoadData")
    Resume LoadData_Done

End Function

Dani AI

Generated

Brief, practical summary: ReDim (without Preserve) allocates or reallocates a dynamic array and clears its contents; ReDim Preserve resizes while copying existing elements into the new array but can only change the upper bound of the last dimension. See the official ReDim docs for details.
ReDim statement (VBA)

Why the code uses ReDim mClassCodes(0): that single line creates a one-element array (index 0) so the following assignment mClassCodes(i) is valid when i is 0. The routine sets i = 0 initially; when IncludeBlank is true it does ReDim mClassCodes(0), stores the blank value at mClassCodes(0) and increments i to 1. Inside the loop the code uses ReDim Preserve mClassCodes(i) before writing to mClassCodes(i) — that ensures there is room for the new element and preserves the previously stored entries.

Answer to : calling ReDim Preserve AnArray(10) can allocate the array, but Preserve only makes sense when there is something to copy. A common trap is using UBound on an uninitialised array (to compute the new size) — UBound will raise a runtime error if the array has not been dimensioned. To avoid that either allocate once first, track the count explicitly, or test initialization (e.g. SafeArrayGetDim / IsArray patterns) before using UBound. See approaches to check array initialization.
How to determine if an array is initialized in VB6 (StackOverflow)

Performance / robustness tips (expands on ): do not repeatedly ReDim Preserve on every row when the dataset is large — the copy on each resize is costly. Alternatives:

  • pre-count the recordset and ReDim once (but RecordCount can return -1 for forward-only cursors — use a client/static cursor or a separate COUNT query).
    RecordCount property (ADO)
  • collect items in a Collection (fast append), then copy to an array once; or
  • grow the array in chunks (double capacity) to get amortized append cost.

Small examples:

' chunk growth
Dim arr() As String, cap As Long, n As Long
cap = 16: ReDim arr(cap - 1): n = 0
' inside loop:
If n >= cap Then
  cap = cap * 2
  ReDim Preserve arr(cap - 1)
End If
arr(n) = codeString: n = n + 1
' collection then copy
Dim col As New Collection
' inside loop: col.Add codeString
ReDim arr(col.Count - 1)
For i = 1 To col.Count: arr(i - 1) = col(i): Next i

For reliability: prefer an explicit initial ReDim (no Preserve) for the first allocation, avoid UBound on unknown arrays, and use chunked growth or a collection for larger recordsets to keep the UI responsive. For more on the cost and limitations of ReDim Preserve, see the linked discussions.
Why repeated ReDim Preserve is costly / alternatives (StackOverflow)

Recommended Answers

All 3 Replies

Hi,

ReDim statement is used to change the size of a dynamic array in procedure level.

Preserve keyword is used to preserve the data in an existing array when you change the size.
Ex

'
' Declare Dynamic Array
'
Dim AnArray() As Integer

'
' Now allocate the size
'
ReDim AnArray(2) As Integer

'
'Now An Array has bound 0 to 2
'

AnArray(0) = 100
AnArray(1) = 300
AnArray(2) = 400

'
'  Change the size
'

ReDim AnArray(10) As Integer

'
' Now AnArray size is changed but all the values in that array are lost
'
' To preserve the existing values use Preserve keyword
'
' Change the previous code as

ReDim Preserve AnArray(10) As Integer

In your code if IncludeBlank flag is set, you are change the size of mClassCodes array to 1 ( 0 to 0).

For the other data of Class Codes, you are changing the size one by one with preserving the existing values.

'
Still doubt kindly explain this also.

If blnDataReturned(rs) Then        If IncludeBlank Then            [b]ReDim mClassCodes(0)[/b]            cmbCodes.AddItem BLANK            mClassCodes(i) = CStr(BLANK_ID)            i = i + 1        End If

To: selvaganapathy

Is it ok, if i will just use the

ReDim Preserve AnArray(10) As Integer

does this statement will automatically change the size of the array? so that I will not have to type in the :

ReDim AnArray(10) As Integer

above it? Thanks in advance...^_^...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.