I've got a function which uses InStr() to locate a character in a string, but I know there is a built in function in Excel called FIND(). Can anyone advise which is faster or more cpu efficient?
hours_position = InStr(1, value, " ")
vs
hours_position = Application.WorksheetFunction.Find(" ", value, 1)
Both are same and it does the same action.
Most (but not all) worksheet functions can also be called from VBA. For example, you can use the VLOOKUP worksheet function in VBA by calling Application.WorksheetFunction.VLookup (or Application.VLookup).
Similarly, you can use Application.WorksheetFunction.Find and Application.WorksheetFunction.Search. You can use them to emulate the way the worksheet functions work in your VBA code.
These functions are only available in Excel VBA, whereas InStr is a generic VBA function, available in all Office applications (and in VB6, VB.NET etc.)
Apart from that, the Range object in Excel VBA has a Find method, and the Worksheet object has a Find object. These, however, serve a different purpose: you can't use them to search for text within a string, but to search for cells with specified content.
Related
I´m using an Excel workbook with a custom formula for taking a value from the previous worksheet. I use this formula like INDIRECT(SHEETNAME(SHEET(A1)-1)&"!A1"), so SHEET(A1) returns the current sheet number, and SHEETNAME(SHEET(A1)-1) returns the name of the previous sheet, then I use INDIRECT to take the value A1 from that previous sheet.
Here is the code for the custom sheetname formula:
Function SHEETNAME(number As Long) As String
SHEETNAME = Sheets(number).Name
End Function
The problem is that when I use other workbook at the same time, the mentioned command returns #VALUE!.
Thanks for the help! :)
You should always fully qualify.
So instead of Sheets(number).Name, try ThisWorkbook.Sheets(number).Name
Not doing so can lead to bugs that are difficult to diagnose.
I would always suggest avoiding "ActiveWorkbook" unless you specifically need it.
In VBA, most Excel functions are either accessible through Application.WorksheetFunction or VBA
Take sinh and sin for example:
Worksheet Function
Debug.Print Application.WorksheetFunction.sinh(5)
74,2032105777888
VBA Function
Debug.Print VBA.sin(5)
-0,958924274663138
Question:
Why does CallByName not work on both Worksheet functions and VBA functions?
Worksheet Function
Debug.Print CallByName(Application.WorksheetFunction, "sinh", VbGet, 5)
74,2032105777888
VBA Function
Debug.Print CallByName(VBA, "sin", VbGet, 5)
In VBA, most Excel functions are either accessible through Application.WorksheetFunction or VBA
No. Excel functions are accessible as late-bound member calls against the global Excel.Application object (if you're hosted in Excel), and then some have an early-bound "equivalent" (error handling strategy will need to differ) in the Excel.WorksheetObject interface (you get it from Application.WorksheetFunction indeed).
The members of the VBA library, global-scope or not, have nothing to do with Excel: the VBA standard library is referenced by every VBA project, regardless of its host application (Word, Excel, Access, ...SolidWorks, Sage300, etc.). If a function looks like it exists in both the VBA and the Excel libraries, the VBA function should probably/theoretically be preferred.
Use the object browser (F2) to discover the members of the VBA standard library, including and perhaps particularly its Math module.
The call signature of CallByName... which is actually a member of VBA.Interaction as seen below (so your snippet is equivalent to VBA.Interaction.CallByName(VBA, "sin", VbGet, 5) or just VBA.CallByName..., in any case a side point):
is
CallByName(Object As Object, ProcName As String, CallType As VbCallType, Args() As Variant)
As VBA is not an Object, but the standard VBA library, this throws a type mismatch error.
I want to add an Excel Function to a Cell via C# and Interop (Office 2010).
Let's take SUM for example.
Using WorksheetFunction ist NOT what I want, because this is a one time function call.
So what I want is
Xl.Range range = SomeWorksheet.Range["A1"];
range.Formula = "=SUM(A2:A5)";
This is fine if you are using an english version of excel but is an error in every other language.
I found this overview but this would mean to handcode the localization. Not so very nice.
What I need is s.th. like
string localizedFunctionName = Xl.Application.GetFuncName(Func.Sum);
Kind Regards
Martin
Try the following:
range.FormulaLocal = "=SUM(A2:A5)";
Read more here: http://msdn.microsoft.com/en-us/library/office/aa205983%28v=office.10%29.aspx and this question: VBA: cannot automatically recalculate Excel formula after updating it -- needs manual interaction
I have searched far and wide, but can't find an answer to this simple question. I want to make a custom function in excel which will create a hyperlink.
Excel has a built in hyperlink function that works like this:
=Hyperlink(link_location, display_text)
I want to create a function called CustomHyperlink which takes one parameter, and returns a hyperlink to a google query with that parameter. Just for the sake of the question, lets assume that the passed parameter is a alphanumeric string, with no spaces.
Essentially, calling
=CustomHyperlink("excel")
should be the same as calling
=Hyperlink("http://www.google.com/search?q=excel", "excel")
This seems like such a simple task, but I absolutely cannot find a way to make this function.
Can anyone offer some quick help?
I can offer a partial solution, one that will update an existing hyperlink. This only makes sence if you are using it like, say
CustomHyperlink(A1)
were A1 contains the required serch term
To use,
enter your UDF formula in a cell, eg =CustomHyperlink(A1)
create a hyperlink on the cell (right click, Hyperlink...) . This can be any hyperlink, valid or invalid
put the required search term in the referenced cell, eg in A1 put excel
When the UDF runs it will update the hyperlink to Google the entered search term
Function CustomHyperlink(Term As String) As String
Dim rng As Range
Set rng = Application.Caller
CustomHyperlink = Term
If rng.Hyperlinks.Count > 0 Then
rng.Hyperlinks(1).Address = "http://www.google.com/search?q=" & Term
End If
End Function
In VBA editor you can use
ThisWorkbook.FollowHyperlink Address:=(strWebsite), NewWindow:=True
Which will take you to that specific website, and just build a function around that to navigate you to the site you need.
Nice idea although this isn't possible.
You seem to want to have the formula of the cell as one thing (your custom function call) and yet have the value as another (the hyperlink / URL) which simply isn't possible.
The correct way through VBA to add a hyperlink is to use the Hyperlinks property but it is not possible to call this property, through a Worksheet UDF (because of the reason above).
What is wrong with just using the the built-in =Hyperlink() worksheet function? You could effectively parameterise your URL as follows (where cell A1 = Excel):
=HYPERLINK("http://www.google.com/search?q="&A1)
You can't do this directly for the reasons creamyegg suggests, but there is a way to achieve the functionality albeit with a bit of a performance consideration.
You could use the Worksheet_Change event to track for the presence of your UDF then process the hyperlink addition there.
You would need to set up an empty function to allow this to happen, otherwise Excel will throw an error whenever you entered =CustomHyperlink... in a cell.
The below should work, not really had time to test.
Private Sub worksheet_change(ByVal target As Range)
Dim SearchValue As String
If LCase(Left(target.Formula, 16)) = "=customhyperlink" Then
SearchValue = Mid(target.Formula, 19, Len(target.Formula) - 20)
target.Value = SearchValue
target.Hyperlinks.Add target, "http://www.google.com/search?q=" & SearchValue, , "Search Google for " & SearchValue, SearchValue
End If
End Sub
The performance consideration is of course the volatile Worksheet_Change event as this can really kill large, complex workbooks.
I want to write a little logging function in an excel add-in that I will be calling from many different workbooks. I'd like to be able to just call it by passing only the log text, and the log function itself could handle the timestamp, workbookname, etc.
However, I cannot use either ThisWorkbook or ActiveWorkbook to determine which workbook was responsible for making the call, as Thisworkbook will return a reference to the add-in itself, whereas VBA code running in a workbook other than the workbook with active focus in Excel could make the call, but the ActiveWorkbook will return the one that has focus in the window.
Application.Caller looked like a possible solution, but this seems to work only when the function is called from a cell, not from VBA.
Is what I'm trying to do impossible?
Update
According to > 1 person, this is in fact impossible. If anyone happens to know some clever workaround please speak up.
Ok, so having read the question properly I'll try again...
So, to state the problem:
you want a routine written in an addin, that when called from vba in another workbook can work out (among other things) which workbook contains the vba that made the call, without having to pass this information explicitly.
As stated this is not possible (this is a similar question to accessing the call stack from code: something that is to my knowledge not possible)
However you can almost get what you want like this
Declare your log function like this:
Sub MyLogger(wb as Workbook, LogText as String)
Dim CallerName as String
CallerName = wb.name
' your code...
End Sub
Then wherever you call the sub use
MyLogger ThisWorkbook, "Log Text"
Not quite as good as passing nothing, but at least its always the same
To get the name of the calling workbook, use
Application.Caller.Worksheet.Parent.Name
Application.Caller returns information about how Visual Basic was called. If called from a custom function entered in a single cell, a Range object specifying that cell is returned
Having got a reference to the cell, .Worksheet.Parent.Name gives you the name of the workbook
Note that Application.Caller will return other things depending on how your function is called (see VBA help for details)
In an Add-In Function called by an Excel Worksheet Array Entered Function Call, I find that "Application.Caller.Parent.name" gives the Sheet Name (Tab Name, not sheet number).
I had the same issue when coding a custom function. Function works well, but anytime another workbook is calculated or activated, all cells using that function revert to #value. It can be very frustrating when working with multiple files using this formula.
To get the Workbook I used:
Dim CallingWb As Workbook
Set CallingWb = Application.Caller.Parent.Parent
This should work if your function is in a cell.
Too late for the original post, but might help others!