array from 0 to -1


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 8 of 8

Thread: array from 0 to -1

  1. #1
    Michael Culley Guest

    array from 0 to -1

    I have always wished I could define an array from 0 to -1 in VB, it would
    make things so much easier and much more consistant (even better would be 1
    to 0). Either way this would mean that the array had no elements. Now I've
    found that the split function can return an array just like this: Split("").
    Does anyone know whats going on and is it possible to duplicate.

    TIA

    --
    Michael Culley
    www.vbdotcom.com





  2. #2
    Bob O`Bob Guest

    Re: array from 0 to -1

    Michael Culley wrote:
    >
    > I have always wished I could define an array from 0 to -1 in VB, it would
    > make things so much easier and much more consistant (even better would be 1
    > to 0). Either way this would mean that the array had no elements. Now I've
    > found that the split function can return an array just like this: Split("").
    > Does anyone know whats going on and is it possible to duplicate.



    It's an interesting question.

    Don't know _why_ it's different, but that hasn't stopped me from just using
    "Split(vbNullString)" once when I wanted an array that was defined, yet had
    no members.

    Haven't figured out how to do it with arrays of anthing other than strings,
    though.


    Bob
    --
    Seems to me we went through the whole copy-protection thing decades ago,
    and smart folks realized it can only hurt the customer.

  3. #3
    Phil Weber Guest

    Re: array from 0 to -1

    > Does anyone know what's going on and is it possible to duplicate?

    Michael: Split() returns a Variant, so you can duplicate its behavior by
    assigning an empty array to a Variant:

    Dim a As Variant
    a = Array()

    There you go!
    ---
    Phil Weber



  4. #4
    Michael Culley Guest

    Re: array from 0 to -1

    Phil,

    > Michael: Split() returns a Variant, so you can duplicate its behavior by
    > assigning an empty array to a Variant:


    What I would like to do is be able to do is something like this:

    Redim MyArray(1 to lngNumReqd)

    so if lngNumReqd is zero it will still work without giving me an error.
    This would be great for code like this

    for x=1 to ubound(MyArray)
    Do Something
    next

    There are different methods of handling this in VB but I don't think any of
    them are that good.

    --
    Michael Culley
    www.vbdotcom.com


    "Phil Weber" <pweber@_fawcette.com> wrote in message
    news:3bdccec7@news.devx.com...
    > > Does anyone know what's going on and is it possible to duplicate?

    >
    > Michael: Split() returns a Variant, so you can duplicate its behavior by
    > assigning an empty array to a Variant:
    >
    > Dim a As Variant
    > a = Array()
    >
    > There you go!
    > ---
    > Phil Weber
    >
    >




  5. #5
    Matthew Curland Guest

    Re: array from 0 to -1

    You'll have to go straight to the oleaut API. If you have the VBoostTypes
    typelib from my book, then you can do it as follows:

    'Assumes VBoostTypes reference (API definitions), VBoost.bas in project
    (VarPtrArray Declare), and InitVBoost has been called (or use CopyMemory
    instead of VBoost.Assign).
    Dim x() As Long
    Dim Bound As SafeArrayBound 'Leave this at {0, 0}
    VBoost.Assign ByVal VarPtrArray(x), SafeArrayCreateEx(vbLong, 1, Bound)

    Remember to use VarPtrStringArray for String arrays and everything will work
    correctly if you match the array type to the Variant type. Note that the 0
    To -1 array is exactly what you get with an empty ParamArray. -Matt

    "Michael Culley" <mike@vbdotcom.com> wrote in message
    news:3bdcbc04@news.devx.com...
    > I have always wished I could define an array from 0 to -1 in VB, it would
    > make things so much easier and much more consistant (even better would be

    1
    > to 0). Either way this would mean that the array had no elements. Now I've
    > found that the split function can return an array just like this:

    Split("").
    > Does anyone know whats going on and is it possible to duplicate.
    >
    > TIA
    >
    > --
    > Michael Culley
    > www.vbdotcom.com
    >
    >
    >
    >




  6. #6
    Michael Culley Guest

    Re: array from 0 to -1

    Matt,

    This is what I came up with. Any suggestions?

    --
    Michael Culley
    www.vbdotcom.com


    -------------------- Put in form
    Private Sub Form_Load()
    Dim lngX() As Long

    ReDim lngX(5)
    RedimArray lngX, 1, 0
    MsgBox "LBound is " & LBound(lngX) & " UBound is " & UBound(lngX)
    End
    End Sub

    ----------------- Put in a module or general class
    Private Type tagSAFEARRAYBOUND
    cElements As Long 'Number of elements in array
    lLbound As Long 'LBound of array
    End Type

    Private Declare Function SafeArrayRedim Lib "oleaut32.dll" (ByVal ArrayPtr
    As Long, DataPtr As tagSAFEARRAYBOUND) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
    (Destination As Any, Source As Long, ByVal Length As Long)

    Public Sub RedimArray(ArrayRef As Variant, ByVal LowBound As Long, ByVal
    Count As Long)
    Dim lngP As Long
    Dim lngA As Long
    Dim Data As tagSAFEARRAYBOUND
    Dim lngErr As Long

    Data.lLbound = LowBound
    Data.cElements = Count

    CopyMemory lngP, ByVal VarPtr(ArrayRef) + 8, 4
    CopyMemory lngA, ByVal lngP, 4
    If lngA = 0 Then Err.Raise 5, , "Array not initialized."
    lngErr = SafeArrayRedim(lngA, Data)
    If lngErr <> 0 Then Err.Raise lngErr
    End Sub


    "Matthew Curland" <mattcur@microsoft.com> wrote in message
    news:3bdd9bfe$1@news.devx.com...
    > You'll have to go straight to the oleaut API. If you have the VBoostTypes
    > typelib from my book, then you can do it as follows:
    >
    > 'Assumes VBoostTypes reference (API definitions), VBoost.bas in project
    > (VarPtrArray Declare), and InitVBoost has been called (or use CopyMemory
    > instead of VBoost.Assign).
    > Dim x() As Long
    > Dim Bound As SafeArrayBound 'Leave this at {0, 0}
    > VBoost.Assign ByVal VarPtrArray(x), SafeArrayCreateEx(vbLong, 1,

    Bound)
    >
    > Remember to use VarPtrStringArray for String arrays and everything will

    work
    > correctly if you match the array type to the Variant type. Note that the 0
    > To -1 array is exactly what you get with an empty ParamArray. -Matt
    >
    > "Michael Culley" <mike@vbdotcom.com> wrote in message
    > news:3bdcbc04@news.devx.com...
    > > I have always wished I could define an array from 0 to -1 in VB, it

    would
    > > make things so much easier and much more consistant (even better would

    be
    > 1
    > > to 0). Either way this would mean that the array had no elements. Now

    I've
    > > found that the split function can return an array just like this:

    > Split("").
    > > Does anyone know whats going on and is it possible to duplicate.
    > >
    > > TIA
    > >
    > > --
    > > Michael Culley
    > > www.vbdotcom.com
    > >
    > >
    > >
    > >

    >
    >




  7. #7
    Matthew Curland Guest

    Re: array from 0 to -1

    If you're trying to make a generic replacement for ReDim, then this won't
    quite make it. First, SafeArrayRedim is equivalent to ReDim Preserve, not
    ReDim. Second, you don't handle ReDim of an empty array (BTW, you can deduce
    the type for some arrays from VarType(ArrayRef) - vbArray. Typed object
    arrays and structures are a lot more work). Third, you can't pass all array
    types to a Variant (try passing an array of tagSAFEARRAYBOUND). The only
    extra piece of information you get by passing a Variant is that the VarType
    is somewhat known, but you aren't using that data.

    I generally pass VarPtrArray(arrayVar) (VarPtrArray = alias to "VarPtr" with
    Ptr() As Any parameter) in a 'ByVal ppSA As Long' parameter for this type of
    generic array routine instead of using a Variant. You save a CopyMemory
    getting the data out of the Variant, and you don't have to worry about
    record types not working. The tradeoff (there always seems to be one) is
    that you have to use a typelib-declared VarPtrStringArray for a String array
    to work with the function.

    I'm really not sure why you're doing this in the first place. You can easily
    check for an empty array with 'VBoost.Deref(VarPtrArray(myArray))' at any
    time, or get the rank of the array with
    'SafeArrayGetDim(VBoost.Deref(VarPtrArray(myArray)))'. This code is compact
    enough that it isn't prohibitive to use at any point in your application.
    You don't need to rely on LBound/UBound error checking to catch an empty
    array.

    Of course, you can do this with CopyMemory as well, but VBoost is a lot
    easier to use. For this type of work, use VBOOST_INTERNAL=1:VBOOST_CUSTOM=1
    and the VBoost object reduces to ~300 bytes in a .bas module, so there
    really isn't any significant overhead to worry about, and the VBoost
    functions themselves are significantly faster than the generic CopyMemory.
    With the typelib CopyMemory declare in VBoostTypes, you also don't have to
    worry about ANSI/UNICODE issues.

    -Matt

    "Michael Culley" <mike@vbdotcom.com> wrote in message
    news:3bddd6d4@news.devx.com...
    > Matt,
    >
    > This is what I came up with. Any suggestions?
    >
    > --
    > Michael Culley
    > www.vbdotcom.com
    >
    >
    > -------------------- Put in form
    > Private Sub Form_Load()
    > Dim lngX() As Long
    >
    > ReDim lngX(5)
    > RedimArray lngX, 1, 0
    > MsgBox "LBound is " & LBound(lngX) & " UBound is " & UBound(lngX)
    > End
    > End Sub
    >
    > ----------------- Put in a module or general class
    > Private Type tagSAFEARRAYBOUND
    > cElements As Long 'Number of elements in array
    > lLbound As Long 'LBound of array
    > End Type
    >
    > Private Declare Function SafeArrayRedim Lib "oleaut32.dll" (ByVal ArrayPtr
    > As Long, DataPtr As tagSAFEARRAYBOUND) As Long
    > Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
    > (Destination As Any, Source As Long, ByVal Length As Long)
    >
    > Public Sub RedimArray(ArrayRef As Variant, ByVal LowBound As Long, ByVal
    > Count As Long)
    > Dim lngP As Long
    > Dim lngA As Long
    > Dim Data As tagSAFEARRAYBOUND
    > Dim lngErr As Long
    >
    > Data.lLbound = LowBound
    > Data.cElements = Count
    >
    > CopyMemory lngP, ByVal VarPtr(ArrayRef) + 8, 4
    > CopyMemory lngA, ByVal lngP, 4
    > If lngA = 0 Then Err.Raise 5, , "Array not initialized."
    > lngErr = SafeArrayRedim(lngA, Data)
    > If lngErr <> 0 Then Err.Raise lngErr
    > End Sub
    >
    >
    > "Matthew Curland" <mattcur@microsoft.com> wrote in message
    > news:3bdd9bfe$1@news.devx.com...
    > > You'll have to go straight to the oleaut API. If you have the

    VBoostTypes
    > > typelib from my book, then you can do it as follows:
    > >
    > > 'Assumes VBoostTypes reference (API definitions), VBoost.bas in project
    > > (VarPtrArray Declare), and InitVBoost has been called (or use CopyMemory
    > > instead of VBoost.Assign).
    > > Dim x() As Long
    > > Dim Bound As SafeArrayBound 'Leave this at {0, 0}
    > > VBoost.Assign ByVal VarPtrArray(x), SafeArrayCreateEx(vbLong, 1,

    > Bound)
    > >
    > > Remember to use VarPtrStringArray for String arrays and everything will

    > work
    > > correctly if you match the array type to the Variant type. Note that the

    0
    > > To -1 array is exactly what you get with an empty ParamArray. -Matt
    > >
    > > "Michael Culley" <mike@vbdotcom.com> wrote in message
    > > news:3bdcbc04@news.devx.com...
    > > > I have always wished I could define an array from 0 to -1 in VB, it

    > would
    > > > make things so much easier and much more consistant (even better would

    > be
    > > 1
    > > > to 0). Either way this would mean that the array had no elements. Now

    > I've
    > > > found that the split function can return an array just like this:

    > > Split("").
    > > > Does anyone know whats going on and is it possible to duplicate.
    > > >
    > > > TIA
    > > >
    > > > --
    > > > Michael Culley
    > > > www.vbdotcom.com
    > > >
    > > >
    > > >
    > > >

    > >
    > >

    >
    >




  8. #8
    Michael Culley Guest

    Re: array from 0 to -1

    > If you're trying to make a generic replacement for ReDim,

    This is what I'm trying to do!

    > then this won't quite make it.


    D'oh!

    > First, SafeArrayRedim is equivalent to ReDim Preserve, not ReDim


    This is OK

    > Second, you don't handle ReDim of an empty array


    This is also OK. It can be setup by VB then handled by this function,
    although it would be better if it did this also.

    > Third, you can't pass all array types to a Variant (try passing an array

    of tagSAFEARRAYBOUND).

    This is a problem!

    All I am after is to be able to have an array with zero elements in it and
    to encapsulate this a little. I always redim(0) an array in class_init, so I
    never work with empty arrays anyway. The fact that the minimum number of
    elements in an array can be 1 is, in my opinion, VBs worst feature.

    > I generally pass VarPtrArray(arrayVar) (VarPtrArray = alias to "VarPtr"

    with
    > Ptr() As Any parameter) in a 'ByVal ppSA As Long' parameter for this type

    of
    > generic array routine instead of using a Variant. You save a CopyMemory
    > getting the data out of the Variant, and you don't have to worry about
    > record types not working. The tradeoff (there always seems to be one) is
    > that you have to use a typelib-declared VarPtrStringArray for a String

    array
    > to work with the function.


    I like this idea alot, initially I tried to do this but I was getting an
    error that the array was locked. I was using the declare in VB code, not in
    a typelib. With copymem it worked OK, but I didn't want the users of my
    function to have to do a copymem to use it. But doing Redim
    (ArrPtr(MeArray),1,0) would be acceptable.

    --
    Michael Culley
    www.vbdotcom.com


    "Matthew Curland" <mattcur@microsoft.com> wrote in message
    news:3bddf8ff$1@news.devx.com...
    > If you're trying to make a generic replacement for ReDim, then this won't
    > quite make it. First, SafeArrayRedim is equivalent to ReDim Preserve, not
    > ReDim. Second, you don't handle ReDim of an empty array (BTW, you can

    deduce
    > the type for some arrays from VarType(ArrayRef) - vbArray. Typed object
    > arrays and structures are a lot more work). Third, you can't pass all

    array
    > types to a Variant (try passing an array of tagSAFEARRAYBOUND). The only
    > extra piece of information you get by passing a Variant is that the

    VarType
    > is somewhat known, but you aren't using that data.
    >
    > I generally pass VarPtrArray(arrayVar) (VarPtrArray = alias to "VarPtr"

    with
    > Ptr() As Any parameter) in a 'ByVal ppSA As Long' parameter for this type

    of
    > generic array routine instead of using a Variant. You save a CopyMemory
    > getting the data out of the Variant, and you don't have to worry about
    > record types not working. The tradeoff (there always seems to be one) is
    > that you have to use a typelib-declared VarPtrStringArray for a String

    array
    > to work with the function.
    >
    > I'm really not sure why you're doing this in the first place. You can

    easily
    > check for an empty array with 'VBoost.Deref(VarPtrArray(myArray))' at any
    > time, or get the rank of the array with
    > 'SafeArrayGetDim(VBoost.Deref(VarPtrArray(myArray)))'. This code is

    compact
    > enough that it isn't prohibitive to use at any point in your application.
    > You don't need to rely on LBound/UBound error checking to catch an empty
    > array.
    >
    > Of course, you can do this with CopyMemory as well, but VBoost is a lot
    > easier to use. For this type of work, use

    VBOOST_INTERNAL=1:VBOOST_CUSTOM=1
    > and the VBoost object reduces to ~300 bytes in a .bas module, so there
    > really isn't any significant overhead to worry about, and the VBoost
    > functions themselves are significantly faster than the generic CopyMemory.
    > With the typelib CopyMemory declare in VBoostTypes, you also don't have to
    > worry about ANSI/UNICODE issues.
    >
    > -Matt
    >
    > "Michael Culley" <mike@vbdotcom.com> wrote in message
    > news:3bddd6d4@news.devx.com...
    > > Matt,
    > >
    > > This is what I came up with. Any suggestions?
    > >
    > > --
    > > Michael Culley
    > > www.vbdotcom.com
    > >
    > >
    > > -------------------- Put in form
    > > Private Sub Form_Load()
    > > Dim lngX() As Long
    > >
    > > ReDim lngX(5)
    > > RedimArray lngX, 1, 0
    > > MsgBox "LBound is " & LBound(lngX) & " UBound is " & UBound(lngX)
    > > End
    > > End Sub
    > >
    > > ----------------- Put in a module or general class
    > > Private Type tagSAFEARRAYBOUND
    > > cElements As Long 'Number of elements in array
    > > lLbound As Long 'LBound of array
    > > End Type
    > >
    > > Private Declare Function SafeArrayRedim Lib "oleaut32.dll" (ByVal

    ArrayPtr
    > > As Long, DataPtr As tagSAFEARRAYBOUND) As Long
    > > Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
    > > (Destination As Any, Source As Long, ByVal Length As Long)
    > >
    > > Public Sub RedimArray(ArrayRef As Variant, ByVal LowBound As Long, ByVal
    > > Count As Long)
    > > Dim lngP As Long
    > > Dim lngA As Long
    > > Dim Data As tagSAFEARRAYBOUND
    > > Dim lngErr As Long
    > >
    > > Data.lLbound = LowBound
    > > Data.cElements = Count
    > >
    > > CopyMemory lngP, ByVal VarPtr(ArrayRef) + 8, 4
    > > CopyMemory lngA, ByVal lngP, 4
    > > If lngA = 0 Then Err.Raise 5, , "Array not initialized."
    > > lngErr = SafeArrayRedim(lngA, Data)
    > > If lngErr <> 0 Then Err.Raise lngErr
    > > End Sub
    > >
    > >
    > > "Matthew Curland" <mattcur@microsoft.com> wrote in message
    > > news:3bdd9bfe$1@news.devx.com...
    > > > You'll have to go straight to the oleaut API. If you have the

    > VBoostTypes
    > > > typelib from my book, then you can do it as follows:
    > > >
    > > > 'Assumes VBoostTypes reference (API definitions), VBoost.bas in

    project
    > > > (VarPtrArray Declare), and InitVBoost has been called (or use

    CopyMemory
    > > > instead of VBoost.Assign).
    > > > Dim x() As Long
    > > > Dim Bound As SafeArrayBound 'Leave this at {0, 0}
    > > > VBoost.Assign ByVal VarPtrArray(x), SafeArrayCreateEx(vbLong, 1,

    > > Bound)
    > > >
    > > > Remember to use VarPtrStringArray for String arrays and everything

    will
    > > work
    > > > correctly if you match the array type to the Variant type. Note that

    the
    > 0
    > > > To -1 array is exactly what you get with an empty ParamArray. -Matt
    > > >
    > > > "Michael Culley" <mike@vbdotcom.com> wrote in message
    > > > news:3bdcbc04@news.devx.com...
    > > > > I have always wished I could define an array from 0 to -1 in VB, it

    > > would
    > > > > make things so much easier and much more consistant (even better

    would
    > > be
    > > > 1
    > > > > to 0). Either way this would mean that the array had no elements.

    Now
    > > I've
    > > > > found that the split function can return an array just like this:
    > > > Split("").
    > > > > Does anyone know whats going on and is it possible to duplicate.
    > > > >
    > > > > TIA
    > > > >
    > > > > --
    > > > > Michael Culley
    > > > > www.vbdotcom.com
    > > > >
    > > > >
    > > > >
    > > > >
    > > >
    > > >

    > >
    > >

    >
    >




Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center