I have a function in my DLL with alias "MAX".
Then I try to use it via VBA in my Excel document:
part of VBA-file:
Declare PtrSafe Function MAX_impl Lib "model_64.dll" Alias "MAX" (x As Variant, ByVal idx_f As Integer, out As Variant) As Integer
cell value in Excel-file:
=MAX(B2:B3, 1)
But instead of call to my DLL-function I got a call to MAX function from Excel.
Is there a way to specify that call should be performed to DLL?
Maybe some prefix is possible?
Like:
=<prefix>.MAX(B2:B3, 1) # call to DLL function
Solution which worked for me: I ended up with this prefix - Module1
So in Excel-file I writes:
=Module1.MAX(B2:B3, 1) # this actually calls my DLL function
From the top of my head, I'd suggest you create a public function in a VBA-Module and then call this from within the Excel-Cell.
Say, you want to Call =MyMax(...) in order to use the function from your DLL. Then, you'd need to follow those two simple steps:
Add a module (if not already present), by using Insert ➡️ Module
Within this module, please create a public function like so:
Public Function MyMax(x As Variant, ByVal idx_f As Integer, out As Variant) As Integer
MyMax = Max(x, idx_f)
End Function
This allows you to create function MyMax that you'll be able to call from your spreadsheet. This, in turn, just acts as proxy to call the actual function from the DLL and returns it's value to the cell.
Note: I've not tested it, but I suppose you're better of aliasing your function with a name i) other than "Max" to avoid confusion with built-in functions and ii) other than your proxy function to avoid confusion with that one, as well.
More detailed instructions on how to create such a user defined function, can be found here.
Related
I am building a User Defined Function.
I get an error
A Value used in the formula is of the wrong data type
I am trying to build a function that adding one comment, will also add the comment to another location as the comments always come in pairs.
Public Function AddComments(vesselCell As Variant, shopCell As Variant, comment As String) As Variant
Range(vesselCell).AddComment (comment)
Worksheets("Shop").Range(shopCell).Value = comment
End Function
I have singled it out to the third line of code causing the problem.
The setup currently is the Vessel Cell will be a comment added to the sheet, and then the Shop sheet has a section for comments as a column.
Assuming vesselCell and shopCell are both Range objects, Range(vesselCell) and Worksheets("Shop").Range(shopCell) are part of the problem.
Make them Range, not Variant.
vesselCell.AddComment comment
shopCell.Value = comment
Now, this code isn't legal in a UDF. Make your procedure a Sub procedure (remove the As Variant return type), and invoke it from other VBA code, or attach it to a shape or button's OnAction property.
User-Defined Functions take inputs, compute a result, and then return that result to the calling cell: your code not returning anything is a strong indicator that a Function isn't appropriate here.
I'm trying to loop through the passed parameters of a function/sub and print their values (for debugging).
The annoying way would be to create an array/collection at the start of each function that loads my declared params in a hardcoded way for each function:
Function myfunc(foo, bar)
Dim fPARAMS As New Collection
fPARAMS.Add foo
fPARAMS.Add bar
'...
Is there is some built-in way to get an array-like object that has my parameters?
Something like;
fPARAMS() = built_in_func_that_returns_my_params()
I haven't found anything on Google nor in SO.
I want to have a faster process looking up cross references.
Right now I use VLOOKUP, and it works fine - but it takes time when it needs to be done multiple times everyday.
It is always the same sheet I use to lookup the cross references, so the only thing that changes is my input value in the VLOOKUP function.
Therefore I want a function where I only input 1 value to get the VLOOKUP value.
The idea is a function like:
=CROSS(ID)
where
CROSS = vlookup(ID, table_array, col_index_num,[range_lookup])
So the vlookup_value is replaced by ID.
I hope you can provide me with some answers - thanks in advance.
I have tried multiple different things, but with no success.
As I am new, I've googled and recorded macros to look for answers.
You could write a UDF (user defined function) for that, using the WorksheetFunction.VLookup method:
Option Explicit
Public Function CROSS(ID As Variant) As Variant
CROSS = Application.WorksheetFunction.VLookup(ID, table_array, col_index_num, range_lookup)
End Function
I got it working as it should now!
The code ended up like this:
Sub crossref()
Option Explicit
Public Function CROSS(ID As Variant) As Variant
CROSS = Application.WorksheetFunction.VLookup(ID, Worksheets("Sheet1").Range("E:F"), 2, 0)
End Function
Access 2013
I'm calling a formula to modify a string and it's changing the values w/in the parent sub.
Example:
Debug.Print Str 'Hello World my name is bob
BOBexists = InStringChceck(Str,"bob")
Debug.Print Str 'HELLO WORLD MY NAME IS BOB
Debug.Print BOBexists 'TRUE
I've used this function, InStringCheck, in Excel VBA before (and it's just an example, all of my string tools are doing this same thing now and I don't know why)
Function InStringCheck(Phrase as string, Term as string) as Boolean
Phrase = UCase(Phrase)
Term = UCase(Term)
if instr(1, Phrase, Term) then InStringCheck = True else InStringCheck = False
end function
In several of my functions I manipulate the input variables, to arrive at a solution, but I don't want those manipulations to persist outside of the function unless I pass them back up - some how they're being passed up, but they're not dimed as public variables
VBA parameters are implicitly passed by reference (ByRef). This means you're passing a reference to the value, not the value itself: mutating that value inside the procedure will result in that mutated value being visible to the calling code.
This is often used as a trick to return multiple values from a function/procedure:
Public Sub DoSomething(ByVal inValue1 As Integer, ByRef outResult1 As Integer, ...)
You have two options:
Pass the parameters by value (ByVal)
Introduce local variables and mutate them instead of mutating the paramters (and heck, pass the parameters ByRef explicitly)
If you have lots of occurrences of parameters being implicitly passed ByRef in your project, fixing them everywhere can easily get tedious. With Rubberduck you can easily locate all occurrences, navigate there, and apply appropriate fixes:
Disclaimer: I'm heavily involved in the Rubberduck project.
Building a little on #Sorcer's answer, VBA has default Sub/Functions parameters passing "by reference" (i. e.: "ByRef" keyword assumed if not specified) so that if you don't want their "inside" modifications survive outside them you have to explicitly type "ByVal" keyword before them in the arguments list.
But you have the option to avoid such modifications take place altoghether by using StrComp():
Function InStringCheck(Phrase as string, Term as string) as Boolean
InStringCheck = StrComp(Phrase, Term, vbTextCompare) = 0
End Function
Which could also lead you to avoid the use of InStringCheck() in favour of a direct use of StrComp() in your code
I create a Public vba function with 2 parameters(module).
When I call the function I type "=InvoiceAmount2(A9;B9)".
The first parameter turns blue. The second black.
I remake the same function using one parameter, the second I use into the function, that way it´s ok. But I need two parameters
This is how you call a user defined function with two parameters:
=MyFunction(A1,B1)
Sample Code:
Function MyFunction(rCellA As Range, rCellB As Range)
MyFunction = rCellA.Value + rCellB.Value
End Function
I found the problem.
I call the udf function in formula constructor. I informed the parameters (A9 and B9)
finally, the udf function filled the cell. "=InvoiceAmount2(A9;B9)".