Let's assume we have an array defined like the following:
Dim Data1 As Object()
Dim Data2 As Double()
I would like to find a way to manage changes in an Array, such as:
//Example #1
Redim Data2(5)
//Example #2
Data2(0) = 3.14
My idea was to create a CustomArray(of T), which inherits from System.Array, and raise an event at the right time. Unfortunately, however, the System.Array class cannot be inherited...
I know that for this kind of operations it would be better to use other data structures (ObservableCollection), but I need to keep the arrays functions (for example Redim and Ubound): by creating a new class (with all array functions), I would still not be able to use Ubound, which requires a System.Array.
Is there a solution?
Ubound and Redim can be simulated. A short example,
Dim foo As New List(Of String) From {"A", "B", "C", "Z"}
Dim uBnd As Integer = foo.Count - 1 ' UBound
' redim - grow
foo.AddRange({"d", "e", "f", "x"})
' redim - decrease
foo.RemoveRange(1, 3)
Related
whats the easiest way to convert an array of integers into string form? I'm trying to copy the whole array of integers into strings.
{1, 2, 3}
to
{"1", "2", "3"}
The easiest method would be to use the Select extension method which is provided by LINQ:
Dim intArray() As Integer = {1, 2, 3}
Dim strArray() As String = intArray.Select(Function(x) x.ToString()).ToArray()
If you don't want to, or cannot use LINQ, you can use the Array.ConvertAll method, which is almost as easy:
Dim strArray() As String = Array.ConvertAll(Of Integer, String)(intArray, Function(x) x.ToString())
EDIT
Based on your comments, below, it looks like you need to convert from an ArrayList of integers to an ArrayList of strings. In that case, you could do it like this:
Dim intArray As New ArrayList({1, 2, 3})
Dim strArray As New ArrayList(intArray.ToArray().Select(Function(x) x.ToString()).ToArray())
Although, at that point, it's starting to get a bit messier. It's probably easier to just do a standard loop, like this:
Dim myArray As New ArrayList({1, 2, 3})
For i As Integer = myArray.Count - 1 To 0 Step -1
myArray(i) = myArray(i).ToString()
Next
For what it's worth, though, unless you are still on a really old version of the .NET Framework, you really ought to be using the List(Of T) class rather than the ArrayList class, in most cases.
First try
Dim holdValues() As Integer 'Doesn't Work
holdValues(1) = 55
Second try
Dim holdValues(-1) As Integer 'Gives me Index was outside the bounds of the array.
holdValues(1) = 55
I'm trying to do something similar to
Dim myString(-1) As String
But apparently this doesn't apply to integer arrays. I don't know what the size of the array will be, it wont get smaller but it will grow larger.
Any help will be appreciated, thank you!
You could use the Initializers shortcut:
Dim myValues As Integer() = New Integer() {55, 56, 67}
But if you want to resize the array, etc. then definately have a look at a List(Of Integer):
'Initialise the list
Dim myValues As New System.Collections.Generic.List(Of Integer)
'Shortcut to pre-populate it with known values
myValues.AddRange(New Integer() {55, 56, 57})
'Add a new value, dynamically resizing the array
myValues.Add(32)
'It probably has a method do do what you want, but if you really need an array:
myValues.ToArray()
you add the number to
holdValues(x) //x+1 will be size of array
so something like this
Dim array(2) As Integer
array(0) = 100
array(1) = 10
array(2) = 1
you can re-allocate the array to be bigger if needed by doing this.
ReDim array(10) as Integer
you'll have to add in your code when you should make your array bigger. You can also look into lists. Lists take care of this issue automatically.
here's some info on Lists: http://www.dotnetperls.com/list-vbnet
Hope this helps.
Also a link for general knowledge on arrays http://www.dotnetperls.com/array-vbnet
Alright, so I'm used to PHP where I can declare a multi-level array like $something[0][1] = "test";. I need to be able to accomplish the same thing, but I'm using VB.NET. How would I do this?
And sorry if this isn't what a multi-dimentional array is, I might be wrong at what it's called but that's what I want to do.
Thanks!
Multidimensional array in VB.Net...
Dim twoDimensionalArray(10, 10) As String
twoDimensionalArray(0, 1) = "test"
I rarely use arrays, however. More elegant solutions can typically be achieved using Lists, Dictionaries, or combinations of the two.
Update .
The (10, 10) is the upper bound of the array (the size is actually 11, 0 through 10). If you don't specify the bounds, you have to Redim Preserve the array when you want to add to it. That's one good thing about lists, you don't have to specify an initial size and you can add to them freely.
Here's a quick example of a list of lists.
Dim listOfLists As New List(Of List(Of String))
listOfLists.Add(New List(Of String)(New String() {"a", "b", "c"}))
listOfLists.Add(New List(Of String)(New String() {"d", "e", "f"}))
listOfLists.Add(New List(Of String)(New String() {"g", "h", "i"}))
'listOfLists(0)(0) = "a"
'listOfLists(0)(1) = "b"
'listOfLists(2)(1) = "h"
Just a plain sample with dynamic resizing of the array
Dim arr(0)() As String '** array declaration
For i As Integer = 0 To 100 '** Outer loop (for the 1st dimension)
For j As Integer = 0 To 1 '** inner loop (for the 2nd dimension)
ReDim Preserve arr(i) '** Resize the first dimension array preserving the stored values
ReDim Preserve arr(i)(j) '** Resize the 2nd dimension array preserving the stored values
arr(i)(j) = String.Format("I={0},J={1}", i, j) '** Store a value
Next
Next
In .NET Arrays are usually static and won't be automatically resized. (As for example in Javascript etc.) Therefore it's necessary to manually resize the array each time you want to add a new item, or specify the size at the beginning.
I know we can define single dimension array in excel VBA using the following
GroupCols = Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L")
How can you predefine multi- dimensional array in the same manner?
Also I want to keep track of certain levels in the following manner
Level[16][0]
Level[16][1]
Level[16][2]
Level[8][0]
Level[8][1]
Level[8][2]
Level[7][0]
Level[7][1]
Level[7][2]
The first index defines the level and so may not be consecutive...like after 16 there is straight 8 and so on. For each i need 3 info which is 0,1,2 second indexes.
Can anyone guide me on how to achieve the same in excel VBA?
There is a way to define a 2D array by using evaluate() almost like using array() for 1D:
Sub Array2DWithEvaluate()
Dim Array2D As Variant
'[] ist a shorthand for evaluate()
'Arrays defined with evaluate start at 1 not 0
Array2D = [{"1,1","1,2","1,3";"2,1","2,2","2,3"}]
Debug.Print Array2D(2, 2) '=> 2,2
End Sub
If you want to use a string to define the array you have to use it like this
Sub Array2DWithEvaluateFromString()
Dim strValues As String
Dim Array2D As Variant
strValues = "{""1,1"",""1,2"",""1,3"";""2,1"",""2,2"",""2,3""}"
Array2D = Evaluate(strValues)
Debug.Print Array2D(2, 2) '=> 2,2
End Sub
If you want more info about other uses of the function Evaluate() check this great post.
http://www.ozgrid.com/forum/showthread.php?t=52372
You can't have non-consecutive indices in an array like that. If you do only use a non-consecutive subset of the indices, then all the other elements will be empty but still use up storage space, which is both inefficient and error-prone (LaunchMissile = Levels(17,1), whoops!).
What you're looking for is the Dictionary object. Before use, must set reference as follows: Tools > References > check Microsoft Scripting Runtime.
Example:
Dim Levels As Scripting.Dictionary
Set Levels = New Scripting.Dictionary
' Fill up the dictionary
Levels.Add Key:=16, Item:=Array("A", "B", "C")
Levels.Add Key:=8, Item:=Array("FAI", "CNT", "YES")
Levels.Add Key:=7, Item:=Array("Once", "Twice", "Thrice")
' Retrieve items from the dictionary
Debug.Print Levels.Item(8)(0)
Debug.Print Levels.Item(8)(1)
Debug.Print Levels.Item(8)(2)
Note that a Collection object could also do the trick. Advantage: native to VBA, so no need to set reference. Disadvantage: Key is write-only, which can be quite awkward.
You could use Array(Array()) for e.g.
data = Array(Array(1,2), Array(3,4))
To refer to the first element, use data(0)(0)
(copied from here)
There is no way to declare and populate a two-dimensional array like when you use the array() function. You can use ReDim to define the array dimensions, then populate it. Here's an example:
ReDim myArray(0 To 16, 0 To 3)
myArray(0, 0) = "A"
myArray(0, 1) = "B"
...
Unfortunately, when you create an array, an element will be created for each entry from the lower bound to upper bound. They will be empty, but they are there, so you need to be aware of it, especially if you plan to loop through it.
In VB.NET, I create my arrays like
Dim myArray = New ArrayList
But isn't there a way to create an array with elements without having to make a variable?
In Ruby, the long way was
array = Array.new
And the simple, non-variable way was just
[element,element,...]
Well, things you can do with primitive (and String) arrays:
Dim array As New String()
Dim array As New String() { "one", "two", "three" }
If (New String() { "one", "two", "three" }).Contains("one") Then
' Do something for "one"
End If
If you move to VB.NET 2010 you will get some extra array initialization features, but if you're using 2008 or below the shortest you can get your lists created might be something like this:
Dim list As New List(Of String)
list.AddRange(New String() { "one", "two", "three" })
And to touch on the point of declaring things without assigning them to a variable: .NET is strongly typed, so while you don't always have to declare a variable, your objects will always need to be of a single type (and one you need to specify through a New).
I'm not sure just how useful such a beast is since, without a name, you can't easily access the elements of it.
I know C has a feature that allows this with "one-shot" accesses like:
char hexchar = "0123456789abcdef"[nybble];
but, after that statement's finished the char array making up that string is no longer accessible.
If you want an array you can access continuously, I suspect it will need an identifying name. I might be wrong, I haven't used VB since VB6 but even if it's possible, it's a dubious language feature (IMO).
You can do a few things.
Public Sub Main()
Dim xs = New Integer() {1, 2, 3}
CType({1, 2, 3}, Integer()).CopyTo(...)
Dim s2 = Sum({1, 2, 3})
End Sub
Public Function Sum(ByVal array As Integer()) As Integer
Return array.Sum()
End Function
Is this the kind of thing you're after?
For Each foo As String In New String() {"one", "two", "three"} 'an array with no name - "On the first part of the journey..."
Debug.WriteLine(foo)
Next