I have this problem with a very simple function written in an XLL, using VS2012. I have tried reading up in MSDN and Steve Dalton's book, and I cannot see what I am doing wrong.
The tricky bit is that I need my function to read values in worksheet cells other than the one from which it is called. The function takes no arguments, and returns an integer. I have declared it as J# (the # signifying that it can call XLM functionality as advised by Dalton...although I still get the same problem without the #). I have not included the declaration of my function to save space, but it is simple and I do not think it is the cause of the problem.
This first block of code works fine. I wrote it just to build confidence.
//This block works correctly. A trial copied from the old Excel 97 documentation
XLOPER12 xlInput1, xlOutput2;
/* Evaluate the string "2+3" */
xlInput1.xltype = xltypeStr;
xlInput1.val.str = L"\0032+3"; //prefix with string length in Octal
Excel12(xlfEvaluate, &xlOutput2, 1, (LPXLOPER12) &xlInput1);
//works OK, and xlOutput2 contains 5
But this second block does not work. I cannot see why. I am trying to read a value from a cell, which is a different cell from that from which the function was called. What I get is an return XLOPER12 that contains an error (xltypeErr) and junk values in the val.num field (the worksheet cell does contain an integer value).
//This block does not work
XLOPER12 xlInput3, xlOutput3;
/* Look up the name Tst on the active sheet called Sht */
xlInput3.xltype = xltypeStr;
xlInput3.val.str = L"\003Tst"; //this also gives problems regardless of whether the string is defined as \004!Tst or \007Sht!Tst
Excel12(xlfEvaluate, &xlOutput3, 1, (LPXLOPER12) &xlInput3); //xlOutput3 now has a type of xltypeErr, rather than the correct integer value on the worksheet
Can you kindly explain what is going wrong?
If you're trying to read a value from a cell that is different from the cell calling the function you'll need a parameter to refer to that different cell. For example in A1 you may have '=myfunc(A2)'. Then your C++ extension func will need to be declared 'JP#', with the P corresponding to the A2 cell reference parameter. If Excel can resolve the 'A2' reference it will pass in an XLOPER with that value as xltypeNum, xltypeInt or xltypeStr depending on the the contents of A2. If not you may get an xltypeSRef.
xlfEvaluate: here's the MS doc https://msdn.microsoft.com/en-us/library/office/bb687913(v=office.15).aspx
Note that MS specify that the string passed to xlfEvaluate must 'contain only functions, not command equivalents'. I suspect L"\003Tst" doesn't correspond to any function known to your Excel. There's no built in function called Tst in my Excel 2013. It's possible you have an addin that supplies a function called Tst, but I'm guessing not. So try changing xlInput3.val.str to L"\006RAND()" and see what happens.
Related
Despite of checking many questions relating error 13, I could not find answers to my problem, so I am giving a shot here:
I am building my code to save information from a userform, but first I am testing to see if mandatory textboxes are empty. Since I am using a 64 bits machine I have used Trevor Eyre´s CalendarForm.
However while testing the code I hit a problem with the empty textboxes that receives the dates from CalendarForms:
In this line:
Dim dteCompraDataOps As Date: dteCompraDataOps = Me.txtTesouro_Compra_DataOps.value
This part is highlighted and returns Runtime Error 13:
dteCompraDataOps = Me.txtTesouro_Compra_DataOps.value
When I check the values coming from empty TextBoxes I get:
dteCompraDataOps = "00:00:00"`
Which is correct since it should be treated as Date, but this:
Me.txtTesouro_Compra_DataOps.value = ""
Is coming as a string.
I did a little search and noticed that Date data types are tricky when the textbox they come from are empty.
I could find a solution: creating a Select Case to test the mandatory fields before declaring the variables but I would like o learn how to deal with the empty textboxes that are supposed to be empty.
Any chance you can shed some light into my conundrum?
Thanks in advance.
Cub4_RJ
There are two ways to handle this.
a) Check for Null:
With Me.txtTesouro_Compra_DataOps
If Not IsNull(.Value) Then
If IsDate(.Value) Then dteCompraDataOps = . Value
End if
End With
b) Introduce a new variable of Variant type which accepts everything (including nulls) and check it's value.
Dim rawData As variant
rawData = Me.txtTesouro_Compra_DataOps.Value
If Not IsNull(rawData) Then
If IsDate(rawData) Then dteCompraDataOps = rawData
End If
The problem with approach A, is that the value 123 is treated as a date, however option B will catch it.
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've been tasked with an ExactTarget task, which uses Ampscript. Trying to learn on the go here. See code snippet below:
%%[
Var #testString, #testOutput
Set #testString = Qwerty
Set #testOutput = BuildRowsetFromString(#testString,"~")
]%%
TestOutput:%%= v(#testOutput) =%%
The code works if the testString contains a ~, but when there is no ~ character in the string, the ouput is blank. Is this correct by design? Do I need to add a conditional to check for the presence of the ~ character?
That's the expected behavior. The BuildRowsetFromString() function alone isn't going to return any value when displayed, you're going to need to use Row() and Field() in order to pull the value out.
Using your example:
%%[
Var #testString, #testOutput
Set #testString = "Qwerty"
Set #testOutput = BuildRowsetFromString(#testString,"~")
]%%
RowCount: %%=RowCount(#testOutput)=%%
TestOutput: %%=v(#testOutput)=%%
The RowCount() function returns a value of 1, essentially saying it knows there's at least one 'row' in there. To display that one value, you'll need to wrap that value with Field() and Row():
TestOutput: %%=Field(Row(#testOutput,1),1)=%%
If you want to display other values in the string, say you were passing "Qwerty~Second~Third", you'll need to either change the number at the Row() function or perform a loop.
References
Using Loops
BuildRowsetFromString() Function
I'm wondering if it's possible to write a user define function in VBA to get a value from a fixed row within the column of the calling function.
Ie I have some fixed values on row 2 of a Excel table; I want to refer to those values from a user defined function.
The caveat is I want the value in row 2, of the calling functions column.
Note : the actual function is more complex than this, however solving this problem would get me where I need to be.
Pseudocode:
Function GetStandardPayment()
GetStandardPayment = CallingColumn.Row(2).Value
End Function
What I have is the following:
Function GetStandardPayment()
GetStandardPayment = ActiveCell.Offset(ActiveCell.Column:2).Value
End Function
However it has syntax errors.
Edited to remove the possibly unneccessary variable.
You can use the Caller property of the Application object. When using a UDF in a worksheet cell, this will return a range object -- the cell where the function exists.
Function GetStandardPayment()
Application.Volatile
GetStandardPayment = Cells(2, Application.Caller.Column)
End Function
The Volatile property is used else the function won't update, since there are no cell references in the function argument.
I would like to access information from a HTTP based API and manipulate it with excel.
The API returns about 20 pieces of information, and you can get that information by looking up any number of about ten lookup fields: name, serial number etc.
I want to write a function similar to the Match Function in excel where one of the parameters (in this case MATCH TYPE) has multiple possible values.
I have a list of values (the 20 pieces of information the API can return) and I want to make these pieces of information the possible return values for one of the Functions parameters.
How do I do I create a function where one parameter has a list of possible values?
And how do I add tooltip help statements to those parameter options so people know what they are?
You want to use an Enum.
In the declarations part of your module (before any subs or functions) you can place code like this.
Enum MyFunctionsArgValue
LessThan
Equal
GreaterThan
End Enum
This will assign each of these keywords an integer value, starting at zero and counting up. So LessThan = 0, Equal = 1, and GreaterThan = 2. (You can actually start at any number you want, but the default is usually fine.)
Now you can use it in your function something like this.
Function MySuperCoolFunction(matchType as MyFunctionsArgValue)
Select Case matchType
Case LessThan
' do something
Case Equal
' do it different
Case GreaterThan
' do the opposite of LessThan
End Select
End Function
To get the tool tip, you need to use something called an Attribute. In order to add it to your code, you'll need to export the *.bas (or *.cls) file and open it in a regular text editor. Once you've added it, you'll need to import it back in. These properties are invisible from inside of the VBA IDE. Documentation is sketchy (read "nonexistent"), so I'm not sure this works for an Enum, but I know it works for functions and module scoped variables.
Function/Sub
Function MySuperCoolFunction(matchType as MyFunctionsArgValue)
Attribute MySuperCoolFunction.VB_Description = "tool tip text"
Module Scoped Var
Public someVar As String
Attribute someVar.VB_VarDescription = "tooltip text"
So, you could try this to see if it works.
Enum MyFunctionsArgValue
Attribute MyFunctionsArgValue.VB_VarDescription = "tool tip text"
LessThan
Equal
GreaterThan
End Enum
Resources
https://www.networkautomation.com/automate/urc/resources/help/definitions/Sbe6_000Attribute_DefinintionStatement.htm
http://www.cpearson.com/excel/CodeAttributes.aspx