我不希望我的Excel加载项返回一个数组(而是我需要一个UDF来更改其他单元格)
我已经创build了一个Excel加载项,并且这个加载项的function之一,可以说New_Years
目前需要2年时间,并且在这两年之间以Excel中的一个数组forms输出每一个新年。 因此, New_Years(2000,2002)
将在2000年1月1日,2001年1月1日和2002年1月1日返回最后一个小区。
问题是我必须知道那个时候会有3个date,select3个单元格,在顶部单元格中input我的公式,然后Ctrl + Shift + Enter
来填充数组。
我使用XLW版本5将我的C ++代码转换为.xll文件。 我真的很喜欢,如果有一些方法,我可以用我的公式填写一个正方形,Excel将根据需要填写下面的正方形和相应的date。 任何人都知道这是可能的吗? 或者不可能?
非常感谢!
这实际上可能是复杂的。 我从凯文·琼斯(又名Zorvek)转载了一段魔法,因为它位于EE Paywall后面 (如果任何人有权访问,链接都会附上)
虽然Excel严格禁止UDF更改任何单元格,工作表或工作簿属性,但是在使用Windows计时器和Application.OnTime计时器按顺序调用UDF时,有一种方法可以实现这种更改。 Windows计时器必须在UDF中使用,因为Excel忽略UDF内的任何Application.OnTime调用。 但是,由于Windows计时器有限制(如果Windows计时器尝试运行VBA代码(如果正在编辑单元格或打开对话框时,Excel将立即退出),它仅用于计划Application.OnTime计时器,一个安全计时器只有当单元格不被编辑且没有打开对话框时才允许触发Excel。
下面的示例代码演示了如何从UDF内部启动Windows计时器,如何使用该计时器例程来启动Application.OnTime计时器,以及如何将仅知道UDF的信息传递给后续的计时器执行的例程。 下面的代码必须放在常规模块中。
Private Declare Function SetTimer Lib "user32" ( _ ByVal HWnd As Long, _ ByVal nIDEvent As Long, _ ByVal uElapse As Long, _ ByVal lpTimerFunc As Long _ ) As Long Private Declare Function KillTimer Lib "user32" ( _ ByVal HWnd As Long, _ ByVal nIDEvent As Long _ ) As Long Private mCalculatedCells As Collection Private mWindowsTimerID As Long Private mApplicationTimerTime As Date Public Function AddTwoNumbers( _ ByVal Value1 As Double, _ ByVal Value2 As Double _ ) As Double ' This is a UDF that returns the sum of two numbers and starts a windows timer ' that starts a second Appliction.OnTime timer that performs activities not ' allowed in a UDF. Do not make this UDF volatile, pass any volatile functions ' to it, or pass any cells containing volatile formulas/functions or ' uncontrolled looping will start. AddTwoNumbers = Value1 + Value2 ' Cache the caller's reference so it can be dealt with in a non-UDF routine If mCalculatedCells Is Nothing Then Set mCalculatedCells = New Collection On Error Resume Next mCalculatedCells.Add Application.Caller, Application.Caller.Address On Error GoTo 0 ' Setting/resetting the timer should be the last action taken in the UDF If mWindowsTimerID <> 0 Then KillTimer 0&, mWindowsTimerID mWindowsTimerID = SetTimer(0&, 0&, 1, AddressOf AfterUDFRoutine1) End Function Public Sub AfterUDFRoutine1() ' This is the first of two timer routines. This one is called by the Windows ' timer. Since a Windows timer cannot run code if a cell is being edited or a ' dialog is open this routine schedules a second safe timer using ' Application.OnTime which is ignored in a UDF. ' Stop the Windows timer On Error Resume Next KillTimer 0&, mWindowsTimerID On Error GoTo 0 mWindowsTimerID = 0 ' Cancel any previous OnTime timers If mApplicationTimerTime <> 0 Then On Error Resume Next Application.OnTime mApplicationTimerTime, "AfterUDFRoutine2", , False On Error GoTo 0 End If ' Schedule timer mApplicationTimerTime = Now Application.OnTime mApplicationTimerTime, "AfterUDFRoutine2" End Sub Public Sub AfterUDFRoutine2() ' This is the second of two timer routines. Because this timer routine is ' triggered by Application.OnTime it is safe, ie, Excel will not allow the ' timer to fire unless the environment is safe (no open model dialogs or cell ' being edited). Dim Cell As Range ' Do tasks not allowed in a UDF... Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Do While mCalculatedCells.Count > 0 Set Cell = mCalculatedCells(1) mCalculatedCells.Remove 1 Cell.Offset(0, 1).Value = Cell.Value Loop Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True End Sub