É;xcel VBA在宏中打开已在单元格中调用的工作簿

É;xcel VBA在宏中打开已在单元格中调用的工作簿,vba,excel,Vba,Excel,我从Excel中的单元格调用函数时遇到一些问题。 宏应打开工作簿,获取一些数据,然后将数学结果返回给单元格 但是当我使用下面的代码时,它不会打开wordbook,只返回#VALUE!去牢房。在我试图打开工作簿后,它立即跳出了代码 ' This Interpolation function is used to get data from other Excel sheets Public Function DatasheetLookup(ExcelFile As String, ExcelShe

我从Excel中的单元格调用函数时遇到一些问题。 宏应打开工作簿,获取一些数据,然后将数学结果返回给单元格

但是当我使用下面的代码时,它不会打开wordbook,只返回#VALUE!去牢房。在我试图打开工作簿后,它立即跳出了代码

' This Interpolation function is used to get data from other Excel sheets
Public Function DatasheetLookup(ExcelFile As String, ExcelSheet As String, xVal As Double, Optional isSorted As Boolean = True) As Variant
    ' abosolute or relative path?
    If Not (Left(ExcelFile, 3) Like "[A-Z]:\") Or (Left(ExcelFile, 2) = "\\") Then
        ExcelFile = ThisWorkbook.path & "\" & ExcelFile
    End If

    ' does file exits?
    If Dir(ExcelFile, vbDirectory) = vbNullString Then
        DatasheetLookup = "No such file!"
        Exit Function
    End If

    ' open the source workbook, read only
    Dim Wbk As Workbook
    Dim WS As Worksheet
'    Application.ScreenUpdating = False ' turn off the screen updating
    Set Wbk = Workbooks.Open(ExcelFile)
       ' Run through all sheets in the source workBook to find "the one"
        For Each WS In Wbk.Worksheets     ' <-- Here it exit the code and return #VALUE!
            If WS.Name <> ExcelSheet Then
                DatasheetLookup = "Sheet not found!"
            Else
                Dim xRange As Range
                Dim yRange As Range
                xRange = WS.Range("A1", "A" & WS.UsedRange.Rows.Count)
                yRange = WS.Range("B1", "B" & WS.UsedRange.Rows.Count)



                Dim yVal As Double
                Dim xBelow As Double, xAbove As Double
                Dim yBelow As Double, yAbove As Double
                Dim testVal As Double
                Dim High As Long, Med As Long, Low As Long

                Low = 1
                High = WS.UsedRange.Rows.Count

                If isSorted Then
                    ' binary search sorted range
                    Do
                        Med = Int((Low + High) \ 2)
                        If (xRange.Cells(Med).Value) < (xVal) Then
                        Low = Med
                        Else
                        High = Med
                        End If
                    Loop Until Abs(High - Low) <= 1
                Else
                    ' search every entry
                    xBelow = -1E+205
                    xAbove = 1E+205

                    For Med = 1 To xRange.Cells.Count
                        testVal = xRange.Cells(Med)
                        If testVal < xVal Then
                            If Abs(xVal - testVal) < Abs(xVal - xBelow) Then
                                Low = Med
                                xBelow = testVal
                            End If
                        Else
                            If Abs(xVal - testVal) < Abs(xVal - xAbove) Then
                                High = Med
                                xAbove = testVal
                            End If
                        End If
                    Next Med
                End If

                xBelow = xRange.Cells(Low): xAbove = xRange.Cells(High)
                yBelow = yRange.Cells(Low): yAbove = yRange.Cells(High)
                DatasheetLookup = yBelow + (xVal - xBelow) * (yAbove - yBelow) / (xAbove - xBelow)
                Exit For
            End If

        Next WS
    Wbk.Close Savechanges:=False
    Set Wbk = Nothing
    Application.ScreenUpdating = True
End Function
”此插值函数用于从其他Excel工作表获取数据
公共函数DatasheetLookup(ExcelFile作为字符串,ExcelSheet作为字符串,xVal作为Double,可选的isSorted作为Boolean=True)作为变量
'是溶质路径还是相对路径?
如果不是(左(ExcelFile,3)像“[A-Z]:\”)或(左(ExcelFile,2)=“\\”),那么
ExcelFile=ThisWorkbook.path&“\”ExcelFile
如果结束
'文件是否退出?
如果Dir(ExcelFile,vbDirectory)=vbNullString,则
DatasheetLookup=“没有这样的文件!”
退出功能
如果结束
'以只读方式打开源工作簿
将Wbk设置为工作簿
将WS设置为工作表
'Application.ScreenUpdate=False'关闭屏幕更新
设置Wbk=Workbooks.Open(ExcelFile)
'运行源工作簿中的所有工作表以查找“唯一”

对于Wbk.Worksheets'中的每个WS,我不确定具体原因,但您不能在用户定义的函数中打开文件。还有许多附加操作无法在
功能中执行。这个堆栈溢出回答中也讨论了这一点

但是,在您的情况下,您可以通过在调用函数之前打开要读取的文件来轻松地欺骗此限制。我准备了一个非常基本的演示,您需要根据需要修改代码以适合您的特定示例:

“此工作簿”中的代码:

“模块1”中的代码:

单元格A1中的代码:

=testFunc()

您是否尝试过使用VBA调试器对此进行调试?我猜您正在对字符串值执行数学运算。我认为通过调试很容易找到。是的,已经使用了VBA调试器!-Wbk中每个WS的函数在
之后立即退出。工作表
并返回#VALUE!-所以它永远不会到达那个部分。你说它退出代码是什么意思?在Excel文件中看不到任何工作表?您是否查看了“局部变量”窗口以查看此工作簿是否正确创建?提示1:在执行函数转义的行之前,在变量
Wbk
中添加一个观察者,然后告诉我们其中包含什么。提示2:确保变量
ExcelFile
的类型是
name+扩展名
,而不仅仅是
name
。为了更清楚,请确保您通过了
MyWorkbook.xlsx
,而不仅仅是
MyWorkbook
。Tip1:Wbk=Nothing。提示2:这是正确的路径ExcelFile=“C:\test\test.xlsx”您锁定了它:-)-这就是问题所在<代码>工作簿。从excel中的单元格调用“打开”
时不起作用。您的解决方法可行,但我使用此方法的问题是,此时我不知道工作簿的路径/文件名。我想我需要制作一个宏来检查调用我的
数据表lookup
的每个单元格,并打开相关的工作簿(隐藏),但是如果你引入了一个新工作簿,它只有在你关闭并打开“主工作簿”时才起作用工作簿-或者你有更好的建议吗?我不确定你在做什么任务,所以我想我帮不了你多少忙。我认为基于宏的解决方案可能是处理这一问题的好方法。可能是一个“重新计算”按钮,运行宏刷新页面上的所有数据?本文可以解释如何从关闭的文件中获取数据,但该方法对如何使用它有一些规定:
Global Wbk As Workbook

Public Function testFunc()
    ' the workbook is already opened, so you may perform this iteration operation w/o any problems.
    For Each WS In Wbk.Worksheets
        testFunc = 1
        Exit Function
    Next WS
End Function
=testFunc()