Reputation: 1304
I have the following function which I use to fetch data from a closed workbook:
Public Function GetValue(path, file, sheet, ref)
' Retrieves a value from a closed workbook
Dim arg As String
' Make sure the file exists
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetValue = "File Not Found"
Exit Function
End If
' Create the argument
arg = "'" & path & "[" & file & "]" & sheet & "'!" & _
Range(ref).Range("A1").Address(, , xlR1C1)
' Execute an XLM macro
GetValue = ExecuteExcel4Macro(arg)
End Function
Then I have the following test routine which works:
Sub TestGetValue()
p = Range("B2").Value
f = Range("B3").Value
s = "TOTAL"
a = "D" & ActiveCell.Row + 3
MsgBox GetValue(p, f, s, a)
End Sub
However, if I use the GetValue
function in an Excel cell providing all 4 parameters exactly like in the routine, it always throws a #VALUE! error.
Why does it work in a routine and not while being called as a function?
Upvotes: 1
Views: 2052
Reputation: 1304
After several attempts I did find 3 solutions:
First one while being able to use it as an excel custom formula, it is the slowest, especially when you need data from a specific range. So I don't recommend this option as it would slow your workbook down a lot.
Second option while being much faster, still takes around 15 seconds to get data from several ranges across 2 workbooks.
Third option was the fastest. Like an instant really less than 1 second execution time during which data was pulled from 2 closed workbooks and for different ranges.
Here's the 3rd option's procedure:
Sub getDS()
asname = "data"
bsname = "Anual"
csname = "Total"
filename = Sheets("data").Range("B64").Value
path = Sheets("data").Range("B63").Value
Dim ws As Worksheet
Set ws = Sheets("data")
With ws.Range("D4:D34")
.ClearContents
.Formula = "='" & path & "[" & filename & "]" & bsname & "'!R11"
.Value = .Value
End With
With ws.Range("J4:J34")
.ClearContents
.Formula = "='" & path & "[" & filename & "]" & bsname & "'!U11"
.Value = .Value
End With
With ws.Range("J37:J37")
.ClearContents
.Formula = "='" & path & "[" & filename & "]" & csname & "'!DW96"
.Value = .Value
End With
End Sub
I found this by far to be the BEST and FASTEST VBA solution to fetch data in an INSTANT from closed workbooks (with variables) without opening them.
Upvotes: 1