My vba code to split text and numbers doesnt work - vba

I have written this code to split text and number in excel but whenever I run it... it doesn't work
Public Function Strip(ByVal x As String, LeaveNums As Boolean) As Variant
Dim y As String, z As String, n As Long
For n = 1 To Len(x)
y = Mid(x, n, 1)
If LeaveNums = False Then
If y Like "[A-Za-z ]" Then z = z & y 'False keeps Letters and spaces only
Else
If y Like "[0-9. ]" Then z = z & y 'True keeps Numbers and decimal points
End If
Next n
Strip = Trim(z)
End Function

You've written (copied?) a Function, not a subroutine. Functions are commonly used for repeated processes, and return (if written properly) values. So, you call a function from within a subroutine and then do something with the value the function returned. The function does something with the x and LeaveNums parameters, just like formulae do.
In fact, you can write Functions and use these as formulae in your Excel worksheets.
You can call this Function as follows (note, this is an example)
Sub Usefunction()
rslt = Strip("test this 1.01", True)
MsgBox rslt
End Sub
This will return "test this". If you set the boolean to False, the function returns "1.01" instead.

Related

VBA Finding Max value, without using MAX function and printing corresponding cell

I think I need to do a loop here but I'm not quite sure how exactly to write out the syntax as I'm used to just using the max function.
The function I need to create takes in two arrays; the first array has the numeric values while the second array has strings. The function is supposed to find the value in the first array that is the largest and return the corresponding string from the second array.
I'm not sure exactly how to construct my loop. I'm thinking I need to use some form of conditional statements.
Here's what I have so far:
Function FindMax(valueArray() As Integer, nameArray() As String) As String
Dim i As Long, y As Long
y = valueArray(0) 'change to 1 if using a different array structure
FindMax = nameArray(0) 'change to 1 if using a different array structure
For i = LBound(valueArray, 1) To UBound(valueArray, 1)
If valueArray(i) > y Then
y = valueArray(i)
FindMax = nameArray(i)
End If
Next i
Debug.Print ; y
Debug.Print ; FindMax
End Function
Here's a worksheet formula that gets the job done quick & easy:
=INDEX($C$3:$C$10,MATCH(MAX($B$3:$B$10),$B$3:$B$10))
If your:
Numbers of which to find the Maximum are in cells B3:B10, and,
Strings that you want to return are in cells C3:C10
...then the Maximum can be found with:
{MyMax} =MAX($B$3:$B$10)
...and the "Position #` of {MyMax} can be found with:
{Pos#} =MATCH( {MyMax} ,$B$3:$B$10)
...and the corresponding string can be found with:
=INDEX($C$3:$C$10, {Pos#} )
...so if we put it all together, we get:
=INDEX($C$3:$C$10,MATCH(MAX($B$3:$B$10),$B$3:$B$10))
Function FindMax(valueArray() As Integer, nameArray() As String) As String
dim i as long, y as long
y = valueArray(0) 'change to 1 if using a different array structure
FindMax = nameArray(0) 'change to 1 if using a different array structure
for i = lbound(valueArray,1) to ubound(valueArray,1)
if valueArray(i) > y then
y = valueArray(i)
FindMax = nameArray(i)
end if
next i
End Function
Pay attention to the bottom half of the code. See where is say :
this=FindMax(arr,arr2)
?
That is how you call a function. Obviously you'll need two arrays to pass to this function. I suggest googling "Functions vba" and do some light reading.

Returning an Array/Matrix in Excel VBA from a user defined function

I'm new to Excel VBA and its been 5 years since I've done any VBA at all. I've written a UDF to do a basic regression, but I can't get it to output an array of regressed values. I select the range I want to output so and hit crtl+shift+enter, but it doesn't work. I've tried a few different things, but nothing does the trick. Here is my latest attempt:
Function REGRESSMEDIAN(x As Range, y As Range) As Double
Dim slope As Double, intercept As Double, count As Integer
count = x.count
Dim lny() As Double, regression() As Double
ReDim lny(1 To count), regression(1 To count)
Dim i As Integer
For i = 1 To count
lny(i) = Application.WorksheetFunction.Ln(y(i))
Next i
slope = Application.WorksheetFunction.slope(lny, x)
intercept = Application.WorksheetFunction.intercept(lny, x)
Dim j As Integer
For j = 1 To count
regression(j) = Exp(slope * x(j) + intercept)
Next j
REGRESSMEDIAN = regression
End Function
This test function:
Function tester()
tester = Array("a", "b", "c")
End Function
will work fine as a UDF as long as your 3 output cells are in a row, not in a column. If they're in a column then you'll just see "a" in all 3 cells.
If you're trying to put the output in a column then this will work:
Function tester()
tester = Application.Transpose(Array("a", "b", "c"))
End Function
Try
Function REGRESSMEDIAN(x As Range, y As Range) As Double()
only putting the parentheses in the function declaration.
It will work.

Integer subtraction and looping based on integer values

I'm having two problems here. First off all I want to x to change values to x - y and if the new X is higher then 0 i want the process to repeat itself. I've worked out the code below but i'm not certiant on two things.
Am I even allowed to make the equation x = x - y or does this mess up everything? I mean in mathematical terms it would not be possible but if we take X as Hp and Y as damage I want the damage to add up. I don't want it to create an "damage HP" integer for every subtraction as I even don't know how many "Z = x - y" style equations I would have to create if I set Y to be random.
My guess is that I could create a Z integral that would copy X a moment before the subtraction would go off and then have the subtraction be X = Z - Y but I'm not sure how I would go about coding this.
I want it to go ahead and loop itself if X is higher then 0 and I'm not sure if I coded that correctly.
Here is my code:
Module Module1
Dim A As Integer
Dim B As Integer
Dim x As Integer
Dim y As Integer
Sub Main()
End Sub
Sub Maths()
A = 5
B = 4
x = 3
y = 1
Subtraction()
Console.WriteLine("You deal {0} damage to your enemy reducing it to {1} hp.", y, x)
Do Until x <= 0
Loop
End Sub
Private Sub Subtraction()
If A > B Then x = x -y
Return
End Sub
End Module
I liked this question. Here's my thoughts:
Yes, x = x - y is perfectly valid code. It's no different than if I had a string variable named myRunOnSentence and I wanted to concatenate the string that was already in the variable and another string and then store the results back in the string variable. Like this: myRunOnSentence = myRunOnSentence + "another string" Same concept, just change the datatype to an Integer. x = x + y. That programatically says: "take the value in x and the value in y, add them together, and store the result of that expression in x."
You did indeed make a mistake with the loop. You don't have any code inside the body of the loop itself.
You have nothing happening in the Main() sub of your module so this module when run will do nothing. You should just take the code from the Maths() method and put it in the Main() sub.
In your Subtraction() method, A > B will always evaluate to True because A and B are initialized with values and then never changed.
Your code should look something like this:
Module Module1
Dim A As Integer = 5
Dim B As Integer = 4
Dim x As Integer = 3
Dim y As Integer = 1
Sub Main()
Do Until x <= 0
Subtraction()
Console.WriteLine("You deal {0} damage to your enemy reducing it to {1} hp.", y, x)
Loop
End Sub
Private Sub Subtraction()
If A > B Then x = x - y 'Return statement wasn't needed.
End Sub
End Module
If this answered your question, please don't forget to mark it as the answer.

Recalculate sheet excel in VBA when getting numbers from cells with Cells.Value

Here is a simple example to explain what I want to do:
Function fun(X As Double)
Worksheets("Sheet1").Activate
Y = Cells(2, "C").Value
fun = X + Y
End Function
So, if I am changing the value of X inside the excel sheet, result of fun will change as expected, but if I change the value of Y, nothing happens. I must change X again so the function will get the new value of Y and calculate the proper value.
Is there a way to add code in this VBA function so the result of fun will automatically update with a change of value for Y?
Add Application.Volatile to your function as the first line.
Function fun(X As Double)
Application.Volatile
'Worksheets("Sheet1").Activate
Dim Y As Long
Y = Worksheets("Sheet1").Cells(2, "C").Value
fun = X + Y
End Function
The assignment to Y should be done directly, not by activating a worksheet.

How can I check if a cell in Excel spreadsheet contains number

I have a column of addresses and I have to find those which don't contain street numbers. Unfortunately, addresses have been input by various users and they do not follow the same pattern so the street type, street name, suburb are in different order and I can't use functions like LEFT, RIGHT or MID to check if particular character is a number. The column looks like this:
10 Willsons Drive, Manhattan
Epping, 23 Wet Rd
Longsdale St, Kingsbury
11 Link Crt, Pakenham
Is there an Excel or VBA function that can tell me if cell / string contains numbers?
Put this into a Module, then in your worksheet, may be a column next to it, put formula =HaveNumbers(A2) and check if you want it like that (True/False). You can change it to Return a String instead. This Returns TRUE / FALSE.
Function HaveNumbers(oRng As Range) As Boolean
Dim bHaveNumbers As Boolean, i As Long
bHaveNumbers = False
For i = 1 To Len(oRng.Text)
If IsNumeric(Mid(oRng.Text, i, 1)) Then
bHaveNumbers = True
Exit For
End If
Next
HaveNumbers = bHaveNumbers
End Function
There isn't a single VBA function that will do what you want, but the following function should do the trick:
Public Function ContainsNumbers(Inp As String) As Boolean
Dim Strings() As String, Str As Variant
Strings = Split(Inp, " ")
For Each Str In Strings
If IsNumeric(Str) Then
ContainsNumbers = True
Exit For
End If
Next
End Function
Then put something like =ContainsNumbers(A1) in a nearby cell.
Thanks Monty. In my case, though, numbers were not always separated from words so I had to iterate over each character. I used following:
Function ContainsNumber(text As String)
'checks if given cell contains number
For i = 1 To Len(text)
If IsNumeric(Mid$(text, i, 1)) Then
ContainsNumber = True
Exit Function
End If
Next
ContainsNumber = False
End Function