Re: can .range return a 1D array?



Yes, simpler, but a lot slower as your Redim Preserve, as I understand it,
makes a full copy of the array. The posted code doesn't.

RBS


"Alan Beban" <unavailable@xxxxxx> wrote in message news:uunc9ZutIHA.1316@xxxxxxxxxxxxxxxxxxxxxxx
Doesn't something like the following, with a modest amount of error trapping (not provided), suffice?

Function changeBounds(inputArray, newLB, newUB)
Dim arrV
arrV = inputArray
ReDim Preserve arrV(newLB To newUB)
changeBounds = arrV
End Function

Sub testabc1000()
Dim arr() As Integer
ReDim arr(1 To 10)
For i = 1 To 10
arr(i) = i
Next
arr = changeBounds(arr, 0, 11)
Debug.Print TypeName(arr), LBound(arr), UBound(arr), arr(0), arr(9)
End Sub

Alan Beban

RB Smissaert wrote:
This is some useful code (as it is very fast) to change the
LBound of arrays that are declared like this: Dim arr()

Option Explicit
Private Declare Function VarPtrAry _
Lib "msvbvm60" _
Alias "VarPtr" (Ary() As Any) As Long
Private Declare Sub CopyMemory _
Lib "kernel32" _
Alias "RtlMoveMemory" (Dest As Any, Src As Any, _
ByVal cBytes As Long)

Function GetArrayDims(arr As Variant) As Integer

'---------------------------------------'
'copied from Francesco Balena at: '
'http://www.devx.com/vb2themax/Tip/18265'
'---------------------------------------'
Dim ptr As Long
Dim VType As Integer
Const VT_BYREF = &H4000&

' get the real VarType of the argument
' this is similar to VarType(), but returns also the VT_BYREF bit
CopyMemory VType, arr, 2

' exit if not an array
If (VType And vbArray) = 0 Then
Exit Function
End If

' get the address of the SAFEARRAY descriptor
' this is stored in the second half of the
' Variant parameter that has received the array
CopyMemory ptr, ByVal VarPtr(arr) + 8, 4

' see whether the routine was passed a Variant
' that contains an array, rather than directly an array
' in the former case ptr already points to the SA structure.
' Thanks to Monte Hansen for this fix

If (VType And VT_BYREF) Then
' ptr is a pointer to a pointer
CopyMemory ptr, ByVal ptr, 4
End If

' get the address of the SAFEARRAY structure
' this is stored in the descriptor

' get the first word of the SAFEARRAY structure
' which holds the number of dimensions
' ...but first check that saAddr is non-zero, otherwise
' this routine bombs when the array is uninitialized
' (Thanks to VB2TheMax aficionado Thomas Eyde for
' suggesting this edit to the original routine.)
If ptr Then
CopyMemory GetArrayDims, ByVal ptr, 2
End If

End Function

Sub SetLBound(Ary() As Variant, lNewLBound As Long)

' "As Variant" for example only -- use your specific type
' Note that this won't work for string() or UDT() with strings
' Sets Ary's LBound to NewBound, returns previous LBound.
'-------------------------------------------------------------
Dim i As Integer
Dim AryPtr As Long
Dim PrevLBound As Long
Dim iDims As Integer

iDims = GetArrayDims(Ary)

If iDims = 0 Then
Exit Sub
End If

AryPtr = VarPtrAry(Ary) ' address of address of safearray struct
CopyMemory AryPtr, ByVal AryPtr, 4

AryPtr = AryPtr + 20 ' pointer to safearray.bounds.lLbound
CopyMemory PrevLBound, ByVal AryPtr, 4

'no point altering lBound to the existing lBound
If PrevLBound = lNewLBound Then
Exit Sub
End If

For i = 1 To iDims
CopyMemory ByVal AryPtr + (i - 1) * 8, lNewLBound, 4
Next

End Sub

Sub test()

Dim arr()

ReDim arr(0 To 10)

MsgBox LBound(arr), , "Original LBound"
SetLBound arr, 1
MsgBox LBound(arr), , "New LBound"

End Sub


RBS


"Alan Beban" <unavailable@xxxxxx> wrote in message news:%23iAXR9qtIHA.3564@xxxxxxxxxxxxxxxxxxxxxxx

Dave Peterson wrote:

And if arr is a single row 2-D array, then



As will:

with application
arr = .transpose(.Transpose(arr))
end with

just another way...


Which reminds me . . .

Both arr = Application.Transpose(Application.Transpose(arr)) and
arr = Application.Index(arr,1,0)

will return a 1-based array, regardless of the base of the array that was input.

If the add-in functions I referred to in my previous post are available to the workbook

arr = OneD(arr) will return a 1-based or 0-based array, depending on the base of the array that was input.

Alan Beban

.



Relevant Pages

  • Re: Why Compile error on Myarr()?
    ... you cannot assign to an array. ... 'I wouldn't use Arr() here. ... 'Dim Arr() As Variant ...
    (microsoft.public.excel.programming)
  • Re: Populate a multi-dimensional array from Ranges
    ... You will be working with a 1d array of 2d arrays. ... "Peter T" wrote: ... Dim i As Long ... Dim arr ...
    (microsoft.public.excel.programming)
  • Re: Binary file from C++ to Matlab
    ... By convoluting array and pointer syntax, ... arr is an array of doubles but also an acronym for &arr. ... ptr is a pointer to a constant array literal. ...
    (comp.soft-sys.matlab)
  • Re: Binary file from C++ to Matlab
    ... By convoluting array and pointer syntax, ... arr is an array of doubles but also an acronym for &arr. ... ptr is a pointer to a constant array literal. ...
    (comp.soft-sys.matlab)
  • Re: Populate a multi-dimensional array from Ranges
    ... I added the following to code to output the values of multiArr to G1:I10. ... Dim i As Long ... Dim arr ... You can assign values in a single area range to an array in one go like ...
    (microsoft.public.excel.programming)