Hi All,
Looking for the syntax that will allow me to code an event sub routine, based off the event of a specific function e.g. findnum being run.
Haven't been able to find a thread on this.
Many thanks!
Hi All,
Looking for the syntax that will allow me to code an event sub routine, based off the event of a specific function e.g. findnum being run.
Haven't been able to find a thread on this.
Many thanks!
I'm not sure what you are after.
Do you want to run some event code as part of a UDF (is findnum a UDF)?
Or do you want this UDF to modify some event code.
_
...How to Cross-post politely...
..Wrap code by selecting the code and clicking the # or read this. Thank you.
Not sure what your referring to by "UDF" its a standard function e.g.
Function Findnum(variable)
End Function
looking for event sub like e.g
Sub Workbook_Open()
End sub
So something to the effect of
Sub Findnum_run()
End Sub
Findnum is just an arbitrary allocation. Is that possible? I've seen a the effects of a code that does something to this effect, the sheet is locked though so unfortunately can't see how it was done.
A UDF is a User Defined function.
You would normally use one on a worksheet, but unfortunately there are no events directly associated with one.
What would you want the event 'sub' do?
If posting code please use code tags, see here.
Oh of course! yeah a UDF, effectively I need to populate multiple cells with my array called from a function. I am trying to replicate a function that does this but from everything I've seen on the threads everyone advises this cannot be done. From messing around with the function I thought that I'd identified it was getting around it with some sort of on function run event procedure.
The code that does it is locked, and the programming team responsible for it don't seem to wish to disclose how they did it frustratingly. I'm not looking to use it in the exact same way as they have applied it, but the example of this set of functions means I know its possible just can't figure out how the managed it. (just to confirm its not ctrl+shift+enter with function=array, its far more elegant)
Like I said there's no event associated with a UDF and a UDF will not directly trigger any other event.
The usual way to return multiple values to multiple cells is to use an array (CSE) function.
Did the code for that you were given in the other thread not work?
Looks like the same issue being discussed here: http://www.excelforum.com/excel-prog...-function.html Mikerickson has provided an array UDF that, I think, should be what the OP is asking for, once he/she understands how to enter and use an array UDF.
Originally Posted by shg
No as mentioned in both threads, I am aware of the CSE option, but this is somewhat elegant as it requires you to ctrl+shift+enter, the range. Particularly frustrating if you are not sure how many columns will be populated and pulling perhaps the top 50 ranked items. The formula I have described above populates a grid the the formula in the top left cell. The goal is a tool that can be used by less knowledgeable users. Therefore any function involving a instruction manual is not ideal.
It's quite frustrating as I have an example of a function that does this, but cannot see the code, and nobody seems to have heard of a method to do this.
Where exactly are you using the function?
PS What's wrong with an elegant solution?![]()
Another work-around to let a UDF modify cells is to have it pass information to a Collection. The Calculate event will then change the cells as indicated.
Here's an example. Put =ColorACell(A1:A3,D4) in a cell and watch A1:A3 change color as you put different numbers in D4.
![]()
' in a normal module Function ColorACell(RangeToColor As Range, ColorForRange As Long) As Boolean ColorACell = True On Error Resume Next ThisWorkbook.CellsToColor.Add Item:=RangeToColor, Key:=RangeToColor.Address(, , , True) ThisWorkbook.ColorsForCells.Add Item:=ColorForRange, Key:=RangeToColor.Address(, , , True) On Error Goto 0 End Function
![]()
'in ThisWorkbook Code module Public CellsToColor As New Collection Public ColorsForCells As New Collection Private Sub Workbook_SheetCalculate(ByVal Sh As Object) Dim oneRange As Range On Error Resume Next For Each oneRange In CellsToColor With oneRange .Interior.ColorIndex = ColorsForCells(oneRange.Address(, , , True)) End With Next oneRange On Error Goto 0 Set CellsToColor = Nothing Set ColorsForCells = Nothing End Sub
meant inelegant :-) The function that I'm trying to copy is based off pulling proprietary data from our internal system so can't upload it to the internet unfortunately, which would be the best way to express what I mean.
Goal is fundamentally is a function, in which you reference the data you want in the function, the function then populates a cell range of the correct size with the array of data automatically. Which is what the other function manages to do. The big benefit of this is its far easier as all the user needs to do is put the function in a single cell.
Hi Mike, thanks let me test that!
Norrie with regards to your question it pulls from an internal database!
Is this mysterious function pulling data from a database, or some other data source?
Hmmm passing it through a collection does seem to work, thanks! So that requires feeding in of the range, not very familiar with collections, so a few follow up questions!
I'm thinking the best option would then to have the array as a public variable and the populating via the above loop through collection, would this be best?
That formula requires the range be be specified, is their any easy method of selecting the correct relative range based from the cell the function is in a ubound of columns and rows of the array?
That formula runs every time the sheet calculates, pretty sure that wouldn't work for multiple instances of the same function in a sheet, for example you wouldn't be able to recalc all the cells through shift+F9 correct?
The way that I would do it is
'in the UDF
test Application.Caller against the result array,
if it (the range Application.Caller) is the right size, return the array: DONE
if it is not
pass the current range (to be blanked)
pass the range of the correct size
pass the formula
End UDF
' in the Calculate event
Blank the current (wrong sized range)
put the formula in the correct sized range. This triggers the UDF again, which will go out the OK branch.
Here is an example. Note that this heavily assumes that the result is wanted in a column.
put =myArrayFtn(A1) in a cell (not in column A) and change the value of A1.
Then put =myArrayFtn(B1) in a different cell.
![]()
' in a normal module Function myArrayFtn(N As Long) As Variant Dim i As Long Dim arrResult As Variant Dim keyAddress As String Dim resultSize As Long Rem get values for array ReDim arrResult(1 To N) For i = 1 To N arrResult(i) = i Next i Rem handle displaying the results resultSize = UBound(arrResult) If TypeName(Application.Caller) = "Range" Then If Application.Caller.Rows.Count <> resultSize Then Rem if array formula is wrong size, send info to collections for adjustment keyAddress = Application.Caller.Resize(resultSize, 1).Address(, , , True) With ThisWorkbook .CellsForFormula.Add Item:=Application.Caller.Resize(resultSize, 1), Key:=keyAddress .FormulaForCells.Add Item:=Application.Caller.FormulaArray, Key:=keyAddress .CellsToBlank.Add Item:=Application.Caller, Key:=keyAddress End With myArrayFtn = False Else Rem if called by array formula (of the correct size), transpose for column output myArrayFtn = Application.Transpose(arrResult) End If Else Rem if not called by worksheet formula myArrayFtn = arrResult End If End Function
![]()
' in ThisWorkbook code module Public CellsForFormula As New Collection Public FormulaForCells As New Collection Public CellsToBlank As New Collection Private Sub Workbook_SheetCalculate(ByVal Sh As Object) Dim keyAddress As String Dim oneRange As Range For Each oneRange In Me.CellsForFormula keyAddress = oneRange.Address(, , , True) Me.CellsToBlank(keyAddress).ClearContents Me.CellsForFormula(keyAddress).FormulaArray = Me.FormulaForCells(keyAddress) Next oneRange With Me Set .CellsForFormula = Nothing Set .CellsToBlank = Nothing Set .FormulaForCells = Nothing End With End Sub
Last edited by mikerickson; 08-06-2014 at 01:28 AM.
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks