convert saved string of numbers into an array of integers - arrays

i have a comma separated string of numbers inside of a var named num_str
the contents of num_str looks like this: "1,2,3,4,5" etc
i am looking for a way to add num_str to an expression to convert the sting of numbers contained therein to an array of integers
i want to make sure i can simply reference 'num_str' to get the numbers from instead of spelling it out like {"1,2,3,4,5"}
i have tried this, where 'num_str' contains the numbers
Dim test As String = Nothing
Dim result() As Integer = Int32.TryParse(num_str.Split(","c))
For i = 0 To result.Length - 1
test += result(i)
Next
but that doesn't work
what i am looking for is a result with an array of numbers

Dim totalValue = str.
Split(","c).
Select(Function(n) Integer.Parse(n)).
Sum()

Try this to create integer array
Dim numbers = str.Split(","c).[Select](Function(n) Integer.Parse(n)).ToList()
Then you can use the loop you are using at the moment to append value to string

You can do it like this:
Dim num_str As String = ...
Dim str() As String = num_str.Split(",")
Dim result(str.Length - 1) As Integer
For i = 0 To str.Length - 1
result(i) = str(i)
Next

I was just working on this for a client, and I found an elegant little piece of code that will replace your single string value and effectively convert it to integer (or more precisely "double") very easily, and can be used for "find and convert" just as easily. I wrote a bunch of these into a GPA calculator that changes the letter grade entered into the GPA number format for math conversion and display without anything else but these three lines and a little loop.
For m = 0 To UBound(myArray)
myArray(m) = Replace(myArray(m), "thisstring", 0.0) 'integer 0.0 can be any
Next m

Related

VBA, How to pass in a string argument, convert to single character array and resize according to non-numerical values?

Ok,
To all those who may come across this question, this is a problem I have been banging my head against for the past two weeks and have made little or no progress, so any help would be extremely welcome.
Here's the set up; then I will follow with an excerpt of the code I have written:
I am writing a function to get a very specific formula for each file name in a given folder. This naturally requires me to write a program which can take string arguments (in this case, excel file names) from a very broad domain of possibilities and yield a very specific output based on some key -and highly unique- parameters. Hence, my function is bijective and the set of arguments and set of products are massive; therefore, I am in the process of writing a sub-process for this function which partitions the string argument, by character, into a corresponding array, remove all the unnecessary characters, concatenate the remaining characters into the output string, and then go through a series of checks to enforce whatever name-formula the file requires. For now, I am just focused on splitting the string into an array, removing all non-numeric characters and combining the remaining characters back into a single string.
Naturally, I have tried the split function, but to my knowledge VBA doesn't support the splitting of a string into single characters. So I have written the following code, which, admittedly, is a bit inelegant, but I think in principle must work. -It does not. Would someone kindly tell me why it doesn't, and make a recommendation for altering it.
Dim arr() As Variant
For i = Len(strArg) To i = 1
If IsNumeric(Mid$(strArg, i, 1)) = True Then
arr(i - 1) = Mid$(strArg, i, 1)
Else: arr(i - 1) = ""
End If
Next
newStr = Join(arr())
arr() always returns empty, so newStr is always "". Yet there are always numeric values in each string argument. -I can't imagine why I am getting this result. If I use ReDim arr(Len(strArg)), I get Len(strArg) number of " " back....
Thanks in advance to whomever may provide help.
Not sure why you need to split it into an array for this. Your description says you only want to have numeric characters returned in a new string variable. A function like this should work for you:
Function GetNumbers(ByVal arg_sText As String) As String
Dim i As Long
Dim sChar As String
Dim sNumbers As String
For i = 1 To Len(arg_sText)
sChar = Mid(arg_sText, i, 1)
If IsNumeric(sChar) Then sNumbers = sNumbers & sChar
Next i
GetNumbers = sNumbers
End Function
Then just call it in your code like this:
newStr = GetNumbers(strArg) 'Example: "ab1c2d" = "12"
Alternatively use a Regular Expression
Function NumOnly(s As String) As String
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = False
.IgnoreCase = True
.Pattern = "[^0-9]+"
NumOnly = .Replace(s, "")
End With
End Function
As a further approach to the existing solutions, I'd like to demonstrate how to use the â–ºFilterXML() function and to check valid results.
The proposed function NumsOnly() consists only of three steps:
a) execute an XPath search upon xml content which has been created by getXML()
b) check valid results via procedure check
c) return the function result as new formed string
Coming close to the requirements in OP this includes also a way to
convert a string to a single character array (c.f. #JNevill 's comment to OP) and
to build a well-formed xml string as base for Filter.XML (see function getXML()) .
Main function NumsOnly()
Function NumsOnly(ByVal s As String) As String
'Purp: recognizes only numeric values in comparisons
'Note: no findings and single digit results are handled by proc check
Const xpath As String = "//*[.>0]" ' get only digits out of atomized characters
'a) execute XPath search upon xml content
Dim x: x = Application.FilterXML(getXML(s), xpath)
'b) check valid results
check x
'c) return only-nums string as function result
NumsOnly = x
End Function
Helper function getXML()
Extended udf based on Split string into array of characters?
Function getXML(ByVal s As String)
'Purp: return well-formed xml content string as base for FilterXML function
'1) atomize string elements into array
Dim buff() As String: buff = Split(StrConv(s, vbUnicode), Chr$(0))
ReDim Preserve buff(UBound(buff) - 1)
'2) return valid xml content string
getXML = "<ch><c>" & Join(buff, "</c><c>") & "</c></ch>"
End Function
Procedure check
As FilterXML returns findings of more than one element as a 2-dim array,
non-findings as Error 2015 and a single element as stand-alone value, it is necessary to distinguish between the returned var types:
Sub check(ByRef x, Optional ErrorResult As String = "")
'Purp: provide for correct xml result by checking var types
Select Case VarType(x)
Case vbError ' non-findings (Error 2015)
x = ErrorResult
Case Is >= vbArray ' 2-dim results (if more than 1 element)
x = Join(Application.Transpose(x), vbNullString)
'Case Else ' single element (here: digit, i.e. Double)
End Select
End Sub

VBA UDF multiple array arguments

I am trying to make a UDF in VBA that takes multiple arrays of equal size as an argument and then loops through them staying at the same index for each array.
I have set the code up as follows.
Public Function TwoArrays(TargetRange(), CriteriaRange())
dim value as range
for each value in TargetRange
next
end function
The issue is I can't get the index of the TargetRange to use in the CriteriaRange and even if I could for whatever reason whenever I put something like
CriteriaRange(2)
I get an error instead of what happens to be within that index.
Is there a way I can get the UDF to treat the array like a normal VBA array where I can do something along the lines of
Public Function TwoArrays(TargetRange(), CriteriaRange())
dim result as range
for i = lowerbound(TargetRange) to ubound(TargetRange)
If CriteriaRange(i) > 0 then
result = result + TargetRange(i)
end if
next i
end function
Thank you!
Like this:
Public Function TwoArrays(TargetRange As Range, CriteriaRange As Range)
Dim result, arrT, arrC, r As Long, c As Long
arrT = TargetRange.Value
arrC = CriteriaRange.Value
'probably should add some code here to check both ranges are the same size...
For r = 1 To UBound(arrT, 1)
For c = 1 To UBound(arrT, 2)
If arrC(r, c) > 0 Then result = result + arrT(r, c)
Next c
Next r
TwoArrays = result
End Function

remove an item from an integer array

I'm trying to remove an element from an integer array given its index, are there any simple ways of accomplishing just that in VB.Net?
All I can find is .RemoveAt() for removing a string in an ArrayList, but none for an integer in an integer array.
Dim PossibleValues(8) As Integer
For x As Integer = 0 To 8
PossibleValues(x) = x + 1
Next
Added the code, don't think it entails much as I am now trying to find ways to remove an element from the array PossibleValues
The problem with removing an item from an array is that it is of fixed size. So The simplest way is to convert the array to a list, ToList(), and then do the RemoveAt and then, if you need to, convert it back to a new array with ToArray().
EDIT
Dim PossibleValues(8) As Integer
For x As Integer = 0 To 8
PossibleValues(x) = x + 1
Next
Dim tempList = PossibleValues.ToList()
tempList.RemoveAt(1)
PossibleValues = tempList.ToArray()

Visual Basic 2D Array Issue

I currently am having some trouble trying to get my program to work with a 2D array. I had it working earlier with a 1D array but I am totally lost now that I have to make these changes.
Below is what I currently have as my 2D array and the code that I thought would work for spitting out a letter grade but does not give me anything. Would anyone be able to tell me what I'm doing wrong?
Private strGrades(,) As String = {{"900", "A"},
{"815", "B"},
{"750", "C"},
{"700", "D"},
{"0", "F"}}
Dim strGradeSearch As String
Dim intRow As Integer
strGradeSearch = txtGrade.Text
For intRow = 0 To 4
If intRow > strGrades.GetUpperBound(0) Then
strGrades(0, intRow) = strGradeSearch
intRow += 1
End If
Next intRow
If intRow <= strGrades.GetUpperBound(0) Then
lblLetter.Text = strGrades(intRow, 0)
End If
Please take all the following as positive comments :-)
OK. looking at your code, there are tbh several issues. You're trying to treat strings as numbers. While a string can contain what looks like a number, it only contains a string of characters that happen to be numbers. They make sense to use, but to a computer, they aren't. There is often stuff that VB does in the background to try and make life easier, but to be honest, it can be a pain.
When comparing something like grades, you need to compare actual numbers, not strings that contain numbers. You'll potentially get unexpected results. You need to get the computer to convert the string to a number. See below.
Your loop wont actually do anything because the If statement will never execute the code inside it because intRow will never be greater than the last element of the array. Anyhow.. Onwards.
A way to convert strings to numbers is to user the Val function, though this "old" VB. The current way is to use Integer.Parse. Have a look at this link for some basic information about it.
Lets walk through what you want to do.
Get the string in the textbox.
Convert the string to a number.
Loop through the array and for each element, get the number stored as a string and convert it to a number and then compare it to the grade number.
If the grade is greater than any of the values, make a note of the
letter linked to the grade and stop searching through the loop.
Assign the letter that was found to the label.
The following code should do this
Dim strGrades(,) As String = {{"900", "A"},
{"815", "B"},
{"750", "C"},
{"700", "D"},
{"0", "F"}}
Dim intGradeSearch As Integer
Dim strGradeLetter As String = ""
intGradeSearch = Integer.Parse(TxtGrade.Text)
For i As Integer = 0 To 4
If intGradeSearch >= Integer.Parse(strGrades(i, 0)) Then
strGradeLetter = strGrades(i, 1)
Exit For
End If
Next
LblLetter.Text = strGradeLetter
End Sub
You dont need to check intRow after the loop has finished, because in this case, at some point in the loop, a grade letter will always be found if the number in the textbox is greater than or equal to a number in the array.
If you have any questions, please don't hesitate to ask.

Finding the mean using a function. vb.net

I'd firstly like to say I'm a beginner in vb.net and coding in general.
I'm trying to find the mean of the numbers in an array.
So far, my code is this.
Function getMean() As Double
Dim DblArray(lstbxInput.Items.Count - 1) As Double
Dim totalsum As Double
Dim i As Integer
For i = 0 To dblArray.Length - 1
totalsum += DblArray(i)
Next i
dblmean = totalsum / DblArray.Length
Return dblmean
End Function
In the end, I need for dblmean to return the mean value of the dblarray numbers.
Would this be correct?
Well obviously it's wrong because I tried to print the value on a label and it always comes out as zero. Why?
Is there something wrong with the code? or was there something wrong in printing out the value?
Also, this is the code used to print out dblmean
lblLrgAns.Text = dblmean.ToString
it happens when i click a button.
A simple approach is to use the Enumerable.Average extension method which is sitting in the System.Linq namepsorts(so remember to add the Import).
Dim mean As Double = DblArray.Average()
In your case you need to initialize the array first. I guess the items in lstbxInput are already doubles.
Dim DblArrayAs As Double() = lstbxInput.Items.Cast(Of Double)().ToArray()
When you do this
Dim DblArray(lstbxInput.Items.Count - 1) As Double
All of DblArray items are 0, but you never change any of the DblArray items in your code, so dblmean would also be 0. You need to assign each item of DblArray before calculating the mean.
I would guess this is related to your previous question: putting a list into an array?, so here's how your code should look like
Function getMean() As Double
Dim DblArray(lstbxInput.Items.Count - 1) As Double
'get the items from lstbxInput
getNumbers(DblArray)
Dim totalsum As Double
Dim i As Integer
For i = 0 To dblArray.Length - 1
totalsum += DblArray(i)
Next i
dblmean = totalsum / DblArray.Length
Return dblmean
End Function

Resources