What I want to do is to count the number of words a variable has. It's for a hangman game, and will be separated by commas. So I'm basically hoping that the variable will look something like this:
"hang,man,group,toll,snail"
I'm planning on splitting it with the commas to create an array, but apart from that, I'm totally lost on what to do.
On the other hand, I'm more than happy to see any other suggestions for sorting out words to be used in a hangman game!
You're halfway there.
Dim wordCount as Integer = "hang,man,group,toll,snail".Split(",").Length
This splits it into an array, and then returns the number of elements in that array.
Dim Words as String = "hang,man,group,toll,snail"
Dim Word = Words.Split(",")
So the result will be .. Word(0) = "hang", Word(1) = "man" ... so on ..
use Split like so
Dim words As String() = SOMESTRING.Split(New Char() {","c})
now to find length you can
words.length ' set this to a variable or output
alternativly you can also use the words individually
words(0) ' set this to a variable or output
words(1) ' set this to a variable or output
and so on
You can easily split a string into an array by using the String.Split method.
There are a number of overloads, however the one I use most often is this one:
Dim myString as String = "hang,man,group,toll,snail"
Dim myStringArray as String()
myStringArray = myString.Split(new String { "," }, StringSplitOptions.None)
This will give you a string array of length 5.
Documentation can be found here: http://msdn.microsoft.com/en-us/library/tabh47cf.aspx
Dim Text As String
Dim i As Integer
Dim ary() As String
Text = "hang,man,group,toll,snail"
ary = Text.Split(",")
For i = 0 To UBound(ary)
MsgBox(ary(i)) 'here you will get all the words in the array
Next i
MsgBox(i) 'You will get the number of items in your array
Related
I am hoping to find help with this current VBA problem. I have looked throughout Stack Overflow and other Google searches, but can't seem to find what I'm looking for.
Essentially, I have a user pasted value on my page which I am delimiting on a comma, and then storing that into an array. What I am aiming to do is then loop through that array and eliminate any extra spaces, and then also delete any values that AREN'T a number.
Copy user values
Store into an array
Erase whitespace
So far, I have not been able to:
Copy items that ARE a number to new array
Currently, my code looks like:
Sub grabText()
' This macro was written as a test macro to grab and filter data entered in a textbox
Application.ScreenUpdating = False
Dim enteredValue As String ' Value taken from page
Dim vals() As String ' Array once it is split
Dim goodvals() As String 'Formatted array
Dim i As Integer 'Index
enteredValue = ActiveSheet.myTxt.Text
' MsgBox enteredValue
vals() = Split(enteredValue, ",")
lastitem = UBound(vals)
' MsgBox lastitem
'Formats array
For i = LBound(vals) To UBound(vals)
i = TRIM(vals(i))
'
' If (ISNUMBER(vals(i)) == TRUE) Then
' enter i into goodvals()
'
Next i
Application.ScreenUpdating = True
Any help or advice would be greatly appreciated. I was thinking about ways to do this in other languages (Java, Python) and I was thinking about Linked-Lists.
Thanks in advance!
Some issues:
Don't assign the result of Split to vals(), but to vals
Don't re-use the variable i for the result of the Trim. It is better to use a separate variable for that, which you can then type as a String
You can capture the desired result if you
First reserve enough room for your target array: it can never be longer than the Split result, so use that as the initial size
Use a separate index variable for referencing the target array index, and only increment it when you have stored a number in it
Finally reduce the size of the target array to the size that was actually used
Code:
Dim enteredValue As String ' Value taken from page
Dim vals() As String ' Array once it is split
Dim goodvals() As String 'Formatted array
Dim i As Long 'Index in vals
Dim j As Long 'Index in goodvals
Dim s As String 'Individual string
enteredValue = ActiveSheet.myTxt.Text
vals = Split(enteredValue, ",")
' Reserve as many entries in the target array
ReDim goodvals(UBound(vals))
j = LBound(goodvals)
For i = LBound(vals) To UBound(vals)
s = Trim(vals(i))
If IsNumeric(s) Then
goodvals(j) = CDbl(s)
MsgBox goodvals(j)
j = j + 1
End If
Next
' Shorten the array size to the part that is used
If j Then
ReDim Preserve goodvals(j - 1)
Else ' There were no numericals at all, so erase the array:
Erase goodvals
End If
I am inputing numbers separated by commas. I need to store these numbers in an array of double elements, ignoring any other character the user has input. But the problem is that TextBox indices and array indices are different, and also 2.4 is stored as each separate elements.
For example, I have a string like this
"1,2.4,5.4,6,2"
How can I convert this to an array with elements
(1),(2.4),(5.4),(6),(2)
Utilizing the String.Split() function and combining that with a For-loop should give you the result that you want.
This will also check if it actually is a number or not, to avoid errors:
Public Function StringToDoubleArray(ByVal Input As String, ByVal Separators As String()) As Double()
Dim StringArray() As String = Input.Split(Separators, StringSplitOptions.RemoveEmptyEntries) 'Split the string into substrings.
Dim DoubleList As New List(Of Double) 'Declare a list of double values.
For x = 0 To StringArray.Length - 1
Dim TempVal As Double 'Declare a temporary variable which the resulting double will be put in (if the parsing succeeds).
If Double.TryParse(StringArray(x), TempVal) = True Then 'Attempt to parse the string into a double.
DoubleList.Add(TempVal) 'Add the parsed double to the list.
End If
Next
Return DoubleList.ToArray() 'Convert the list into an array.
End Function
The Separators As String() parameter is an array of strings that the function should split your string by. Every time you call it you can initialize a new array with the separators you want (a single separator is fine).
For example:
StringToDoubleArray("1,2;3", New String() {",", ";"})
The above will split by commas (,) and semicolons (;).
Example usage for your purpose:
Dim Values As Double() = StringToDoubleArray(TextBox1.Text, New String() {","}) 'Uses a comma as the separator.
Update:
Online test: http://ideone.com/bQASvO
For example, if we have an array A.
In matlab, we just use A[a:b] to get a sub array easily,where a,b are start point and end point respectively.
Is there similar way to do it in VBA?
Thanks
Working with arrays is incredibly fast so this will probably give no discernable benefit - although I can understand how it may appeal from a coding sense than looping to fill a smaller array
Given you are working with a single element array you could:
Introduce a "marker" string inside the large array.
Join the large array with a delimiter into a single string.
Split the large array by the "marker" string, then separate the reduced string into a smaller array with the delimiter.
The code below dumps the numbers 1 to 100 into an array, and then splits it as above to pull out the first 10 records.
Sub test()
Dim bigArr
Dim subArr
Dim strSep As String
Dim strDelim As String
Dim strNew As String
Dim rowBegin As Long
Dim rowEnd As Long
strDelim = ","
strSep = "||"
'fill array with 1 to 100
bigArr = Application.Transpose(Application.Evaluate("row(1:100)"))
rowBegin = 1
rowEnd = 10
bigArr(rowEnd + 1) = strSep
'make a single string
strNew = Join(bigArr, strDelim)
'split the string at the marker
vArr = Split(strNew, strSep)
ReDim subArr(rowBegin To rowEnd)
'split the smaller string with the desired records
subArr = Split(Left$(vArr(0), Len(vArr(0)) - 1), strDelim)
End Sub
In vb.net I want to split a string into an array, I also want to be able to know how many indices are in the array.
In vb6
I would write it like this
dim v1, arrIN(), idcCount
v1 = "1,2,3,4,5"
arrin() = split(v1,",")
idcCount = ubound(arrin))
I can get this to actually put those values into an array using:
Dim arrIN() = Split(v1, ",")
But I cannot figure out how to get the count of indices
When I try to test this in the immediate window I get the message below
?UBound(arrIN())
Number of indices is less than the number of dimensions of the indexed array.
You may use arrVar.GetUpperBound(0) and arrVar.GetLowerBound(0) methods.
Have look at MSDN reference : Array.GetUpperBound(dimension)
Dim v1 As String = "1,2,3,4,5"
Dim arrIN() As String = Split(v1, ",")
'Gets the total number of elements in the array
Dim a As Integer = arrIN.Length
'Gets the index of the last element
Dim b As Integer = arrIN.GetUpperBound(0)
In this instance:
arrIN.Length = 5
arrIN.GetUpperBound(0)=4
The zero in GetUpperBound(0) is the dimension that you want the upper index for.
AVD gave you the right answer. I just added arrIN.Length just in case you needed it.
I know you can easily take a range of cells and slap them into a Variant Array but I want to work with a string array (because it's single-dimensional and takes less memory than a Variant array).
Is there any way to automatically convert a range into a string array?
Right now I am using a function that will take the range and save the values in a variant array, then convert the variant array to a string array. It works nice , but I'm looking for a way to go directly from the range to string array. Any help would be greatly appreciated.
Function RangeToArray(ByVal my_range As Range) As String()
Dim vArray As Variant
Dim sArray() As String
Dim i As Long
vArray = my_range.Value
ReDim sArray(1 To UBound(vArray))
For i = 1 To UBound(vArray)
sArray(i) = vArray(i, 1)
Next
RangeToArray = sArray()
End Function
UPDATE:
It's looking like there is no way to skip the step of throwing the data into a variable array first before converting it to a single-dimensional string array. A shame if it's true (even if it doesn't take much effort, I like to ultra-optimize so I was hoping there was a way to skip that step). I'll close the question in a few days if no solution presents itself. Thanks for the helpful comments, guys!
UPDATE2:
Answer goes to Simon who put in great effort (so did everyone else) and utlimately pointed out it's indeed impossible to go from range to string array in one shot. Thanks, everyone.
You actually can go directly from a range to an array using the functions Split, Join and a delimiter not in the text.
Assuming you have already assigned a 1D range of values as SrcRange
Dim Array() As String: Array = Split(Join(Application.Transpose(SrcRange), "#"), "#")
How about...
Public Function RangeToStringArray(theRange As Excel.Range) As String()
' Get values into a variant array
Dim variantValues As Variant
variantValues = theRange.Value
' Set up a string array for them
Dim stringValues() As String
ReDim stringValues(1 To UBound(variantValues, 1), 1 To UBound(variantValues, 2))
' Put them in there!
Dim columnCounter As Long, rowCounter As Long
For rowCounter = UBound(variantValues, 1) To 1 Step -1
For columnCounter = UBound(variantValues, 2) To 1 Step -1
stringValues(rowCounter, columnCounter) = CStr(variantValues(rowCounter, columnCounter))
Next columnCounter
Next rowCounter
' Return the string array
RangeToStringArray = stringValues
End Function
Function RangeToStringArray(myRange as range) as String()
ReDim strArray(myRange.Cells.Count - 1) As String
Dim idx As Long
Dim c As Range
For Each c In myRange
strArray(idx) = c.Text
idx = idx + 1
Next c
RangeToStringArray = strArray
End Function
If you don't mind altering the contents of the clipboard then:
COPY the range to the clipboard with the Copy method:
MyTargetRange.Copy
Copy the contents from the clipboard to a string variable (search this site or elsewhere for functions to transfer strings to/from the clipboard).
SPLIT the string into a variant array:
MyStringArray = Split(MyClipboardText, vbCrLf)
OPTIONAL: The array will have one additional blank element because there is always an additional Return (vbCrLf) at the end of the text you just copied to the clipboard. To remove simply resize the array:
Redim Preserve MyStringArray(Ubound(MyStringArray) - 1)
Very simple and quick!!!
Drawbacks are that the clipboard may change when you least expect it (during a recalculation) and that it only produces arrays of strings (not Doubles or other numerical value types).
This would be EXTREMELY HELPFUL if you are working with lots of repetitive functions (thousands) that use the same data (thousands of data points). The first time your function is called, do all the intermediate calculations on the ranges of data that you need but save the results in static variables. Also save a string copy of your input ranges via the clipboard. With each subsequent call to your function, convert the input ranges to text, again via the clipboard, and compare with the saved copy. If they are the same you may be able to bypass allot of your preliminary calculations.
Named ranges used in VBA are already arrays. So first make the range into a named range, then refer to it and delete the named range.
For example:
ThisWorkbook.Names.Add Name:="test_array", RefersTo:=Sheet1.Range("A4:B10")
a = Sheet1.Range("test_array")
ThisWorkbook.Names("test_array").Delete