如何从Excel工作簿中选择值并按活动工作簿上的函数返回它们

时间:2015-05-11 16:41:40

标签: excel vba excel-vba

我的目标是实现一些功能,我给它们电动机的功率,频率和速度参数,并查看另一个工作簿(我有电机数据)并返回尺寸,轴径和其他电机的信息。

由于我没有掌握很多VBA,我试图实现一个函数,它只是转到另一个工作簿中的一个单元格并返回值:

Function Test() As String
Dim name As String 

  With Workbooks.Open("D:\ExcelTest\WbSource.xlsm").Sheets("Sheet1")  
    name = .Cells(2, 3) 
  End With

  Test= name

  ActiveWorkbook.Save
  ActiveWorkbook.Close

End Function

问题是它给了我#VALUE!错误,但是使用的每个变量都被定义为一个字符串,并且单元格具有一般格式(如果我将单元格格式更改为文本,它会给我相同的消息)。

3 个答案:

答案 0 :(得分:1)

尽我所能,我无法让workbooks.open在函数中工作,即使该函数调用了一个sub。您可以在工作簿打开事件中打开目录文件,然后在关闭前事件中再次关闭它。

在VProject Explorer中,右键单击" ThisWorkBook,"和"查看代码"。
在顶部的选择列表中,选择“工作簿”,然后应创建子Workbook_open()过程。如果没有,请选择"打开"在右边的选择列表中。请填写以下内容:

Application.Workbooks.Open ("D:\ExcelTest\WbSource.xlsm")
ThisWorkbook.Activate 'restores the "focus" to your worksheet

然后点击右边的选择列表并选择" beforeClose"并放入

On Error Resume Next 'this keeps it from crashing if the catalogue is closed first
Workbooks("WbSource.xlsm").Close

只要工作表首先打开wbsource文件,该函数就可以工作。

答案 1 :(得分:1)

这是一种在队列中调度UDF执行的方法,以及允许摆脱UDF限制的UDF外部处理。因此,已关闭工作簿的值通过链接通过ExecuteExcel4Macro()获得。

将以下代码放入其中一个VBAProject模块中:

Public Queue, QueueingAllowed, UDFRetValue

Function UDF(ParamArray Args())
    If IsEmpty(Queue) Then
        Set Queue = CreateObject("Scripting.Dictionary")
        UDFRetValue = ""
        QueueingAllowed = True
    End If
    If QueueingAllowed Then Queue.Add Application.Caller, (Args)
    UDF = UDFRetValue
End Function

Function Process(Args)
    If UBound(Args) <> 4 Then
        Process = "Wrong args number"
    Else
        ' Args(0) - path to the workbook
        ' Args(1) - filename
        ' Args(2) - sheetname
        ' Args(3) - row
        ' Args(4) - column
        On Error Resume Next
        Process = ExecuteExcel4Macro("'" & Args(0) & "[" & Args(1) & "]" & Args(2) & "'!R" & Args(3) & "C" & Args(4))
    End If
End Function

将以下代码放入VBAProject Excel Objects的ThisWorkbook部分:

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
    Dim Item, TempFormula
    If Not IsEmpty(Queue) Then
        Application.EnableEvents = False
        QueueingAllowed = False
        For Each Item In Queue
            TempFormula = Item.FormulaR1C1
            UDFRetValue = Process(Queue(Item))
            Item.FormulaR1C1 = TempFormula
            Queue.Remove Item
        Next
        Application.EnableEvents = True
        UDFRetValue = ""
        QueueingAllowed = True
    End If
End Sub

之后,您可以使用UDF通过工作表公式从已关闭的工作簿中获取值:

=UDF("D:\ExcelTest\";"WbSource.xlsm";"Sheet1";2;3)

无论如何,您可以将Workbooks.Open()或任何其他内容添加到Function Process(Args)中,以使其按您希望的方式运行。上面的代码只是一个例子。 我已经回答了类似的问题herehere,因此说明可能会有所帮助。

答案 2 :(得分:0)

我建议:

  1. 手动或通过VBA 外部打开WbSource.xlsm。
  2. 将参数传递给UDF
  3. 让UDF搜索新打开的工作簿的列以查找正确的记录
  4. 让UDF将行号传递回工作表
  5. 在工作表中,使用 Match()/ Index()公式来检索其他数据。