PDA

View Full Version : Redim Preserve Change LBOUND



mailmaverick
05-08-2016, 11:45 PM
Hello


I have a single dimensional array in which I want to change lower bound, keeping the upper bound as same.


One way is to loop through the array and copy the desired values to a new variable. But, is there any shortcut or direct function ?

mancubus
05-09-2016, 12:51 AM
assuming existing array holds (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) and you want (6, 7, 8, 9, 10) in resultant array, try:



Sub vbax_55984_change_arrLB()

Dim arrA
Dim i As Long, NewLB As Long

arrA = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
NewLB = 5


For i = NewLB To UBound(arrA)
arrA(i - NewLB) = arrA(i)
Next i

ReDim Preserve arrA(UBound(arrA) - NewLB)

'test
For i = LBound(arrA) To UBound(arrA)
MsgBox "index is " & i & " - Element is " & arrA(i)
Next

End Sub


yeah, loop :)

snb
05-09-2016, 01:00 AM
Why would you want this ?

Lbound is 0 or 1.

mancubus
05-09-2016, 01:00 AM
but if you want (1, 2, 3, 4, 5) in the final array, below procedure will do it:



Sub vbax_55984_change_arrLB()

Dim arrA
Dim i As Long, NewLB As Long

arrA = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
NewLB = 5

ReDim Preserve arrA(NewLB To UBound(arrA))

End Sub

Paul_Hossler
05-09-2016, 06:50 AM
Why would you want this ?

Lbound is 0 or 1.

LBound can be (almost) anything

I oft times use something like




Dim A (14 to 26) as String

For i = LBound(A) to UBound(A)
A(i) = Cells(1,i).Value
Next i

snb
05-09-2016, 07:04 AM
I don't see any advantage.

Aflatoon
05-09-2016, 08:25 AM
But, is there any shortcut or direct function ?

Assuming you want to remove the entries from the start of the array, no. If you redim preserve and change the lower bound, you'll still lose the entries from the end. Also, you can only do it if your variable is actually declared as a Variant, not an array.

Paul_Hossler
05-09-2016, 09:01 AM
I don't see any advantage.

Maybe so, but I find that the code is more readable than having a lot of things like "+14" etc




Dim A (12) As String

For i = LBound(A) To UBound(A)
A(i) = Cells(1, i+14).Value
Next i


I figure that since I've dealing with columns 14 to 26, why not just use 14-26 in the array

Kenneth Hobs
05-09-2016, 09:08 AM
Try using row.

Sub vbax_55984_change_arrLB_2() Dim arrA, i As Long, NewLB As Long

arrA = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
MsgBox Join(arrA, vbLf)

NewLB = 5
For i = NewLB To UBound(arrA)
arrA(i - NewLB) = arrA(i)
Next i
ReDim Preserve arrA(UBound(arrA) - NewLB)
MsgBox Join(arrA, vbLf)
End Sub


'snb arrays, http://www.snb-vba.eu/VBA_Arrays_en.html
'http://www.snb-vba.eu/VBA_Arrays_en.html#L_6.1
Sub vbax_55984_change_arrLB_3()
Dim arrA, i As Long, NewLB As Long, arrB() As Variant

arrA = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
MsgBox Join(arrA, vbLf)

NewLB = 5
'arrB() = Application.Index(arrA, [row(5:10)])
arrB() = Application.Index(arrA, Evaluate("=row(" & NewLB & ":10)"))
Show2DArray arrB()
MsgBox Join(Application.Transpose(arrB), vbLf)
End Sub


'similar to, http://www.cpearson.com/excel/vbaarrays.htmhttp://www.cpearson.com/excel/vbaarrays.htm
Public Sub Show2DArray(ByRef myArry() As Variant) '<-- Note ByRef modifier.
Dim x As Long
Dim y As Long
Dim s As String


s = ""
For y = LBound(myArry, 2) To UBound(myArry, 2)
For x = LBound(myArry, 1) To UBound(myArry, 1)
s = s & myArry(x, y) & ", "
Next x
If Mid(s, Len(s) - 1, 1) = "," Then s = Left(s, Len(s) - 2)
s = s & vbNewLine
Next y
MsgBox s
End Sub

mailmaverick
05-10-2016, 12:16 AM
HI All Thanks for your answers,

The reason for me to change the LBOUND of a single dimensional array is that I want to delete first few entries from the array. Is there any other solution to do this ?

snb
05-10-2016, 01:14 AM
Why did they get there in the first place ?
You can ignore any value in any array without modifying the array.
You can 'remove/retain' any value in any 1-dimensional array using 'filter'.

Paul_Hossler
05-10-2016, 06:38 AM
The reason for me to change the LBOUND of a single dimensional array is that I want to delete first few entries from the array. Is there any other solution to do this ?

1. Are the elements fixed length, intrinsic variables (Long, Double, etc.) not String?

2. Do you start with ary1(1 to 100) [= 100 elements]and then you only want ary2 (51 to 100) [= 50 elements] such that ary2(51) = ary1(51) ?

However, it's really not necessary to delete elements like that

jonh
05-10-2016, 07:34 AM
Sub test()
Dim c As New Collection

'add 20 items
For i = 1 To 20
c.Add i
Next

'remove first 10
For i = 1 To 10
c.Remove 1
Next

'print remaining values
For Each itm In c
Debug.Print itm
Next
End Sub

snb
05-10-2016, 07:36 AM
A collection <> an Array

jonh
05-10-2016, 07:39 AM
so?

Kenneth Hobs
05-10-2016, 01:22 PM
There are 3 viable solutions and with a bit more work, another using jonh's collection method. I guess we could go at this for a long time to find many solutions. The row and filter methods are usually sufficient for my needs. snb's web site is best if you want to learn more about vba arrays.

This method is similar to rewriting the array method and the collection method. The main purpose is to show you the power that arraylist can provide.

'https://msdn.microsoft.com/en-us/library/system.array_methods(v=vs.110).aspx 'Array Methods
Sub Test_aRedim()
Dim a() As Variant, i As Integer
a() = Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")
MsgBox Join(a, vbLf)

'a() = aRedim(a(), 4, 3) 'e,f,g
a() = aRedim(a(), 4) 'e,f,g,h,i,j
MsgBox Join(a(), vbLf)
End Sub


Function aRedim(a() As Variant, iFrom As Long, Optional iTo As Long = 0)
Dim o As Object, i As Long

If iTo = 0 Then
iTo = UBound(a) - iFrom
End If
If LBound(a) = 0 Then iTo = iTo + 1

Set o = CreateObject("System.Collections.ArrayList")
With o
For i = LBound(a) To UBound(a)
.Add a(i)
Next i
aRedim = o.getrange(iFrom, iTo).Toarray()
End With
End Function

snb
05-11-2016, 12:46 AM
To 'remove' the first 5 items in this array:


Sub M_snb()
sn = Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")
sn = Split(Trim(Split(Join(sn), sn(4))(1)))
End Sub