Excel VBA: Call Sub procedure after executing a function - vba

In myFunction, I want to create a log in a sheet with the arguments of the function and the time it was last executed.
My code is like this:
Function myFunction(arg1, arg2 As String)
//code here
Sheets("Sheet1").Range("A1") = arg1
Sheets("Sheet1").Range("B1") = arg2
Sheets("Sheet1").Range("C1") = datetime.Now
End Function
This function doesn't work with the last 3 lines (it does otherwise).
I also tried to create a separate module for this task:
Function myFunction(arg1, arg2 As String)
//code here
Call myLog(arg1,arg2)
End Function
But it doesn't work either
Public Sub myLog(arg1,arg2)
Sheets("Sheet1").Range("A1") = arg1
Sheets("Sheet1").Range("B1") = arg2
Sheets("Sheet1").Range("C1") = datetime.Now
End Sub
Thanks in advance for helping!

"It just returns #VALUE! error when I type the function in a cell".
A function can only modify the cell which it is called from. So you will get an error when you try to modify other cells.
Here are some references that might be useful:
Making Excel functions affect 'other' cells
VBA - Update Other Cells via User-Defined Function
http://www.vbforums.com/showthread.php?508759-Counting-Particular-Letter-Occurrences-in-a-String

Related

Using a function to clean data in VBA

I am familiar with this post: How to Return a result from a VBA Function but changing my code does not seem to help.
I want to write a simple function in VBA that allows to lowercase an input sentence. I wrote this:
Private Function Converter(inputText As String) As String
Converter = LCase(inputText)
End Function
Sub test()
Dim new_output As String
new_output = Converter("Henk")
MsgBox (new_output)
End Sub
I tried following the advice I found at another stackoverflow post. I made me change this:
Private Function Converter(inputText As String)
Set outputText = LCase(inputText)
End Function
Sub test()
Dim new_output As String
Set new_output = Converter("Henk")
MsgBox (new_output)
End Sub
However, now I get an error that an object is required. Why does it require an object now? I dont get it...
Set outputText = LCase(inputText)
The Set keyword is reserved for Object data types. Unlike VB.NET, String in VBA is a basic data types.
So you dont Set a variable to a string. Drop the second version of your code altogether. It doesn't make sense. That "advice" was probably in another context.
To fix your first version
1- Assign the returned result to the name of the function Converter
2- It would be beneficial to specify explicitly the return type, as String. Currently it is a Variant that always embeds a String, so better make it explicit:
' vvvvvvvvv
Private Function Converter(inputText As String) As String
Converter = LCase(inputText) ' <------------ assign return to name of function
End Function

Calling a function from a sub in VBA - qualifier error

I am trying to be more "object oriented" in my VBA code. However, I am having trouble passing variables through to functions. Here, I get an invalid qualifier error message on the IsEmpty function.
How can I correct my code?
Sub test_too_much_data()
If toomuchdata("Data input", "B1018") = False Then
MsgBox ("Sorry, the tool can only accomodate 1000 rows.")
Exit Sub
End If
End Sub
Function toomuchdata(sheet As String, range As Variant) As Boolean
toomuchdata = IsEmpty(Sheets("String")).range(range)
End Function
Thank you!
Update your Function code to something like below:
Function toomuchdata(sheetStr As String, RngStr As String) As Boolean
toomuchdata = IsEmpty(Sheets(sheetStr).Range(RngStr).Value)
End Function

VBA ByRef Argument Type Mismatch When Using Function In If Statement

I am having a weird issue when I'm calling a function from another function inside an if statement. I defined a Sub, which I am using to test this function, and it calls on a function which relies on another function I use to compare values. The code is below, which should make things clear. Essentially, I don't understand how it's possible for the code to work fine in the print statement, and then throw an error in the GetMatch function. I appreciate any help.
Edit: All of a sudden everything works. Do debugging breakpoints affect the program? I haven't changed anything, but CStr() is no longer required when calling GetMatch. I haven't touched any of the subs or functions, but I did clear some breakpoints. If I find what caused it, I'll post a solution. Thanks for the help everyone.
Edit2: Maybe this is a bug with VBA? If I add the CStr() option to the indexOrder(...) calls, things work. Before, without the CStr() options, things did not work. Now, strangely enough, after using the CStr(), I am able to remove the CStr()'s entirely from the program, and things work again. It breaks if I undo to the point where they weren't there originally though. I don't know what this could be, but if anyone has an explanation, I'm very interested. Thanks
Sub testFind()
Dim SortOrder() As Variant
Dim indexOrder() As Variant
SortOrder = Array("Contact Email", "Last Name", "First Name", "Attempt #", "Customization", "Template #")
indexOrder = Array("First Name", "First Name", "Template #", "Customization")
findAndReplace(indexOrder, SortOrder)
End Sub
Function findAndReplace(indexOrder As Variant, list As Variant) As Variant
Dim indexLength As Integer
Dim listLength As Integer
Debug.Print TypeName(indexOrder(0)) ' Identifies as String
indexLength = getVariantLength(indexOrder)
listLength = getVariantLength(list)
Debug.Print GetMatch(CStr(indexOrder(1)), CStr(indexOrder(1))) ' This works fine. Returns 0 as it should
If GetMatch(indexOrder(1), indexOrder(1)) = 0 Then ' Fails with ByRef error
Debug.Print ("Why don't I work?")
End If
End Function
Function GetMatch(A As String, B As String) As Integer
A = Trim(A)
B = Trim(B)
If (IsEmpty(A) Or Trim(A) = "") Then
GetMatch = 1
Exit Function
ElseIf (IsEmpty(B) Or Trim(B) = "") Then
GetMatch = -1
Exit Function
End If
GetMatch = StrComp(A, B, vbTextCompare)
End Function
Function getVariantLength(vari As Variant) As Integer
If IsNull(index) Then
getVariantLength = 0
Else
getVariantLength = UBound(vari) - LBound(vari) + 1
End If
End Function
You don't have a Sub vartest() or Function vartest(), it's trying to call a sub/function that doesn't exist, or at least it isn't included.
Edit: You aren't doing anything with the function. A function will return a value, a sub will 'do' something. You need to assign a variable to whatever it returns, or do a MessageBox or some other way of returning the value.
The next issue is it's trying to call a function getVariantLength() that isn't defined or listed.

VBA : How to change the cell's value in a function?

I'm a new vba programmer and I have some trouble.
This is my function :
Function CopiePaste(CASEREF As Range, REF)
Dim o As Range
For Each o In CASEREF
o.Value = REF
Next
End Function
I want define multiple cell's value in a function but my code doesn't work and I don't understand why ?
Thanks in advance
In VBA, you would use a Sub rather than a Function
Here is one way that a Sub could use a Function to accomplish this:
Sub MAIN()
Dim MSG As String
MSG = CopiePaste(Range("A1:A10"), 123)
MsgBox MSG
End Sub
Function CopiePaste(CASEREF As Range, REF) As Variant
Dim o As Range
For Each o In CASEREF
o.Value = REF
Next
CopiePaste = "Mission Accomplished!"
End Function
Note: the custom function does not actually appear in a cell, but rather is called from the sub.
I will make some suggestions but I am not an expert either :-)
First: a function is supposed to return a value to the place in the code where the function is called from.
Here, you want to do something instead of returning a value, so you should use a sub() instead of a function.
Second, I think you should also declare the "REF" variable for it to work, (unless if it's a public variable).

Using character as argument to function

I would like to be able to only pass q as argument to a function, so that the user does not have to enter a string "q".
I have a function defined in a module
Function doThis(val As Variant)
MsgBox CStr(val)
' Here is a comparison of val with other strings and additional code
End
I call it from my worksheet:
=doThis(q)
And the messagebox returns
Error 2029
I have tried with String and Boolean as value type as well, but only variant fires the function.
Is it possible to receive a q as argument?
Quite simple. First create a Defined Name for q
Secondly in a standard module:
Function doThis(val As Variant)
MsgBox CStr(val)
doThis = ""
End Function
Finally in the worksheet: