Is [AWorrkbookName] new or old syntax for VBA? - vba

I'm maintaining a piece of code and came across this in a VBA function:
isIn("Fred", [PeopleList])
Where PeopleList is a workbook named range. I've never noticed that syntax before and just wondered is it something I've missed or is it new? Should I pass in the range into the function or is this okay usage?

This [PeopleList] syntax is shorthand for Application.Evaluate("PeopleList") and it will try to evaluate PeopleList as a formula or named range and return the result as a variant containing an array. This usage is OK and has been available in VBA since Excel version 5.

Related

Can't get vba function to return correct answer

I'm learning VBA from a book, and the sample function in it is:
Function CubeRoot(number)
CubeRoot = number ^ (1 / 3)
End Function
If I call that function from a sub procedure, I get the correct result, but when I try to use it directly in Excel, I get a "FALSE" result in the cell. I followed the book step-by-step and it does not say to do anything that I haven't done. What am I missing/doing wrong or maybe I need to change some option? I am using Excel 2016.
Edit:
This is what I write in an excel cell: =CubeRoot(8) The result I get is FALSE. However, if I click the fX button and the function arguments box pops up, the formula result shown there is calculated correctly.
I write in an excel cell: =CubeRoot(8) The result I get is FALSE
At first try declaring the variable types properly:
Function CubeRoot(number As Variant) As Double
CubeRoot = number ^ (1 / 3)
End Function
But I do not believe that this will help because the error result then would be #VALUE! but not a boolean FALSE.
But the ^ operator can be overloaded. Maybe by some AddIn you are using. So it seems that it was overloaded to be some boolean operator.
Try the following:
Function CubeRoot(number As Variant) As Double
CubeRoot = Application.Power(number, (1 / 3))
End Function
If that helps, then my suspicion is true and you should go through your installed AddIns to determine which one is doing the weird overload.
If even the using Application.Power(number, (1 / 3)) does not help, then the cell containing the formula seems to be formatted using a weird number format. Try formatting it using the General number format.
According to your mention: "if I click the fX button and the function arguments box pops up, the formula result shown there is calculated correctly.", I suspect it is the weird number format rather than the first two suspicions. So do selecting the cell containing the formula =CubeRoot(8) and set number format General to it using Home tab and Number group.
Finally the problem was that the worksheet functions had been inputted into Excel4 macro sheets instead of worksheets. Probably the Excel4 macro sheets were added using Sheets.Add Method using the type xlExcel4MacroSheet. But in Excel4 macro sheets only Excel4 macro code is possible not default formulas as in worksheets. Excel4 macro is ancient type of macro language from Excel 4.0 (1992). Since Excel 5.0 (1993) VBA is used for Excel macros.
Declare all variables as double, and also the function return type as double.
By default 8 is treated as integer, so 8*X will result integer even if x is single or double.

VBA automatically changing .Range to .range

I have been writing an Excel macro to help me process data at work, and now that I have finished writing the code I keep getting errors because Microsoft Visual Basic keeps changing .Range to .range. Whenever it does this I get a compile error because the method doesn't exist.
Is there anyway to fix this? Is there a way to get around using .Range if there isn't? As long as my code keeps getting changed from .Range to .range it will keep spitting out errors here.
SOLVED: the error wasn't rooted in the method but the data member that preceded it.
Try declaring Range as a Range somewhere in your code (note the case):
Dim Range As Range
then delete the statement.
This should convert all your range to Range
EDIT: The O.P. stated:
SOLVED: the error wasn't rooted in the method but the data member that preceded it.
However, the related issues of a lowercase method can come from creating a variable or routine which you named range and the system will auto change case based on that definition. You should never create a variable or routine with the same name as a defined process like Range().
As mentioned by #RubberDuck:
This is a side effect of VB being case insensitive and the IDE trying to be "helpful".
I have several models and procedures, and at some point all of my Ranges got converted to lowercase range. My easy fix was to go to ThisWorkbook in my project, and Dim Range as Range there, and then it will automatically change "range" to "Range" everywhere it appears in your code
When you have use many times words like 'range', autocorrect will change 'Range' value to 'range'. Try manually change this method to 'Range' and sure that you don't have any variables like 'range'.

Howto convert excel formula to work in VBA?

I have found this terrific tip:
http://vlookupweek.wordpress.com/2012/03/27/richard-schollar-vlookup-left
However, the formula
=VLOOKUP(F2,CHOOSE({1,2},$C$2:$C$7,$A$2:$A$7),2,False)
works if entered in a cell but in VBA it gives a syntax error:
Set Rng = Range(Application.WorksheetFunction.Choose({1, 2}, colMax.Address, colId.Address))
Since this works althought it doesn't do what I want:
Set Rng = Range(Application.WorksheetFunction.Choose(1, colMax.Address, colId.Address))
it seems to be the {...} that is the problem. The problem with googling this is that I don't know what {...} is called (array, sequence list...???).
So the question is how to use this tip in VBA.
Just use the Evaluate function to evalute the formula in VBA. There is no need of "translating" it to VBA:
See this link
http://msdn.microsoft.com/en-us/library/office/ff193019(v=office.15).aspx

Using Excel Formula functions (ERF, ERFC) in Excel VBA code?

I'm trying to use the error function and the complimentary error function in my program. Neither are working. I keep getting the error Compile Error: Sub or Function not defined. However, if I go into a cell and manually try to use the error function, it works.
Why is that? How can I use it in my actual code?
The error function is ERF(x) and the complimentary error function is ERFC(x).
Here's an example of things that don't work:
Sub SeriouslyWHYIsntThisWorking()
x = 3
Range("A1") = Erf(x)
End Sub
Even this doesn't work:
Sub PleaseWork()
Range("A1") = Erfc(1)
End Sub
But if I went into Excel and typed =ERF(3) or =ERFC(1) into a cell, it'll work.
I'm very new to this and probably missing something incredibly simple. Help would be greatly appreciated!
Do you have the Analysis Toolpak for VBA add-in installed/referenced? (Look for atpvbaen.xls)
The ERF function is part of that add-in, and there are two versions of it (one for use in Excel functions, and one for VBA), and you'll need the right one set up and referenced by your project to be usable.
The add-ins are standard from MSFT, but not always set up by default. If you can use it in Excel normally, then you've already set up at least the Excel version. So using it all like it looks like you want to do will require the add-in, regardless of how you implement/use that function. Meaning, if you want to share this with anyone else, they will need the add-in installed/activated.
To link together this answer with the others provided (which are equally accurate and correct), either setting a cell value with
Range("A1").value = Application.WorksheetFunction.ERF(x)
or setting a cell formula with
Range("A1").Formula = "=Erfc(" + x + ")"
will require the end-user using the add-in.
To use a worksheet formula in vba, you need to put Application.WorksheetFunction. in front of it.
Some functions do have vba equivalents, but (as far as I know) not in the case of erf and erfc
Try this:
Sub ThisShouldWorkNow()
x = 3
formula = "=Erfc(" + x + ")"
Range("A1").Formula = formula
End Sub
Totally untested, since I don't have Excel on my Linux machine... But I think I'm getting the point across -- you need to use the .Formula property of the Range object.
There's more information here:
http://msdn.microsoft.com/en-us/library/office/gg192736.aspx

VBA: How to get the last used cell by VBA code when the last error occured in a Workbook/Worksheet?

Eventually, I want to move the cell to the location where the last error occured. Edit: Forgot to say that I'm using Excel 2003.
As requested in comments...
Look up the 'Caller' property of the 'Application' object in the Excel VBA help. When you use it from a VBA routine, it will tell you where the call to the routine came from - what Range, Chart, etc.
An important thing to be aware of when using 'Application.Caller' is that it isn't always a Range object. Look at the help, but the property returns a Variant value that can be a Range, String, or Error. (It is a Range object in the case you're interested in, but you'll need to be aware of this.)
Because of the above, and the vagaries of VBA syntax when it comes to objects vs. values, it can be tricky to use 'Application.Caller'. Putting a line like:
Debug.Print Application.Caller.Address
in your code will fail when the caller isn't a Range. Doing something like:
Dim v
v = Application.Caller
will "compile", but will create circular references when the caller is a Range because you're trying to access the value of the calling Range.
This all means that it's probably best to write a little utility function for yourself:
Public Function currentCaller() As String
If TypeOf Application.Caller Is Range Then
Dim rng As Range
Set rng = Application.Caller
currentCaller = rng.Address(External:=True)
Else
currentCaller = CStr(Application.Caller)
End If
End Function
and then call it from your error handlers where you want to know where the call came from.
One more thing - obviously this can only tell you the caller once a VBA routine has actually been called. If you have errors in your calling formulas, Excel will return error values to your cells without ever calling your VBA routines.
Wrap your VBA function in another function that stores the cell location and value as variants. Keep this 'wrapper' function as basic as possible so it won't cause any additional errors.
If you're trying to debug app-crashing errors, the wrapper function could even store those values in a comma-delimited text file. Once stored, Excel can crash all it wants and you'll still know what the cell location and value were since you stored them outside of Excel beforehand.
Could this be done with an error handler?
An example of what I mean below:
sub code1()
on error goto cell A1
end sub