我只是想从VBA函数中填充电子表格中的单元格。举个例子,我想在一个单元格中键入= FillHere(),结果我会在一些单元格中填充一些数据。
我尝试过这样的功能:
Function FillHere()
Dim rngCaller As Range
Set rngCaller = Application.Caller
rngCaller.Cells(1, 1) = "HELLO"
rngCaller.Cells(1, 2) = "WORLD"
End Function
一旦我尝试修改范围,它就会中断。然后我尝试了这个(即使它不是我正在寻找的行为):
Function FillHere()
Dim rngCaller As Range
Cells(1, 1) = "HELLO"
Cells(1, 2) = "WORLD"
End Function
这两个都不起作用。 但如果我使用F5从VBA启动此功能,它会起作用!在调用函数时似乎无法修改电子表格上的任何内容......虽然有些库会这样做...
我也试过(实际上这是我的第一个想法)从函数返回一个数组。问题是我只得到数组中的第一个元素(有一个技巧意味着在左上角选择一个带有公式的整个区域+ F2 + CTRL-SHIFT-ENTER,但这意味着用户需要知道通过提前数组的大小)。
我真的遇到了这个问题。我不是最终的最终用户所以我需要一些非常容易使用的东西,最好不要争论。
PS:对不起我已经问了这个问题,但当时我还没有注册,似乎我再也不能参与其他帖子了。答案 0 :(得分:3)
您需要分两步完成此操作:
将您的模块更改为:
Dim lastCall As Variant
Dim lastOutput() As Variant
Function FillHere()
Dim outputArray() As Variant
ReDim outputArray(1 To 1, 1 To 2)
outputArray(1, 1) = "HELLO"
outputArray(1, 2) = "WORLD"
lastOutput = outputArray
Set lastCall = Application.Caller
FillHere = outputArray(1, 1)
End Function
Public Sub WriteBack()
If IsEmpty(lastCall) Then Exit Sub
If lastCall Is Nothing Then Exit Sub
For i = 1 To UBound(lastOutput, 1)
For j = 1 To UBound(lastOutput, 2)
If (i <> 1 Or j <> 1) Then
lastCall.Cells(i, j).Value = lastOutput(i, j)
End If
Next
Next
Set lastCall = Nothing
End Sub
然后,为了调用Sub进入VBA中的ThisWorkbook区域并添加如下内容:
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Call WriteBack
End Sub
这样做是返回topleft单元格的值,然后在计算完成后填充其余部分。我写这个的方式假定一次只调用一个FillHere函数。如果你想要同时重新计算多个,那么你需要一组更复杂的全局变量。
一句警告是,当它填充其他单元格时,它不会关心它覆盖的内容。
编辑: 如果要在XLA中在应用程序范围内执行此操作。 ThisWorkbook区域的代码应该类似于:
Private WithEvents App As Application
Private Sub App_SheetCalculate(ByVal Sh As Object)
Call WriteBack
End Sub
Private Sub Workbook_Open()
Set App = Application
End Sub
这将连接应用程序级别计算。
答案 1 :(得分:1)
您尝试做的事情将无法在Excel中运行 - 这是设计使然。
你可以这样做,但是:
Function FillHere()
Redim outputArray(1 To 1, 1 To 2)
outputArray(1, 1) = "HELLO"
outputArray(1, 2) = "WORLD"
FillHere = outputArray
End Function
如果您随后在工作表中选择了两个相邻的单元格,请输入=FillHere()
并按Control + Shift + Enter(以应用为数组公式),然后您应该看到所需的输出。
答案 2 :(得分:1)
从根本上说,函数只能影响从中调用的单元格。听起来您可能需要使用Worksheet_Change
or Worksheet_SelectionChange
events来触发预期范围内的单元格修改。
答案 3 :(得分:0)
您可以使用两阶段流程间接完成此操作: 编写UDF,以便以足够持久的方式存储数据(例如全局arrrays)。 然后有一个Addin,其中包含在每次计算事件后触发的应用程序事件,查看UDF存储的任何数据,然后重写必要的单元格(如果合适,还会显示有关覆盖的警告消息)并重置存储的数据。
这样,用户不需要在其工作簿中包含任何代码。
我认为(但不确定)这是彭博等人使用的技术。