la_pepe59
asked on
Find a worksheet within a closed workbook
I am trying to use the following code to get data from a closed workbook and copy it to a sheet in the existing workbook. In cell B2 a date will be input and based on that date, it should pull the correct worksheet from the closed workbook. Ex. If cell B2 = 07/02/2007 change it to a short date (Jul-07) and then find the corresponding worksheet in the closed workbook. The wb name will be the same but the sheets be named by month and year. Currently the name of the worksheet don't include the "-" in between the month and year so if that can be excluded, that would be great also. Here is what I have..
Sub CopyFromClosedWB(strSource WB As String, _
strSourceWS As String, strSourceRange As String, _
rngTarget As Range)
' copies information from a closed workbook, no input validation!
' use like this to copy information to the active worksheet:
' CopyFromClosedWB "C:\test.xls", "wsname", "A1:D100", Range("A1")
Dim wb As Workbook
Application.ScreenUpdating = False ' turn off the screen updating
Application.StatusBar = "Copying data from " & strSourceWB & "..."
On Error Resume Next ' ignore errors
' open the source workbook, read only
Set wb = Workbooks.Open(strSourceWB , True, True)
On Error GoTo 0 ' stop when errors occur
If Not wb Is Nothing Then ' opened the workbook
On Error Resume Next ' ignore errors
With wb.Worksheets(strSourceWS) .Range(str SourceRang e)
.Copy rngTarget
End With
On Error GoTo 0 ' stop when errors occur
wb.Close False ' close the source workbook without saving changes
Set wb = Nothing ' free memory
End If
Application.StatusBar = False ' reset status bar
Application.ScreenUpdating = True ' turn on the screen updating
End Sub
Sub TestCopyFromClosedWB()
CopyFromClosedWB "C:\Workbookname", "Worksheet", "B2:f55", Range("Sheet2!A1")
End Sub
I have it running when cell b2 changes. If I input the name of the worksheet, Jul 07 it works great but I need it to be based on cell.
Sub CopyFromClosedWB(strSource
strSourceWS As String, strSourceRange As String, _
rngTarget As Range)
' copies information from a closed workbook, no input validation!
' use like this to copy information to the active worksheet:
' CopyFromClosedWB "C:\test.xls", "wsname", "A1:D100", Range("A1")
Dim wb As Workbook
Application.ScreenUpdating
Application.StatusBar = "Copying data from " & strSourceWB & "..."
On Error Resume Next ' ignore errors
' open the source workbook, read only
Set wb = Workbooks.Open(strSourceWB
On Error GoTo 0 ' stop when errors occur
If Not wb Is Nothing Then ' opened the workbook
On Error Resume Next ' ignore errors
With wb.Worksheets(strSourceWS)
.Copy rngTarget
End With
On Error GoTo 0 ' stop when errors occur
wb.Close False ' close the source workbook without saving changes
Set wb = Nothing ' free memory
End If
Application.StatusBar = False ' reset status bar
Application.ScreenUpdating
End Sub
Sub TestCopyFromClosedWB()
CopyFromClosedWB "C:\Workbookname", "Worksheet", "B2:f55", Range("Sheet2!A1")
End Sub
I have it running when cell b2 changes. If I input the name of the worksheet, Jul 07 it works great but I need it to be based on cell.
ASKER
Thanks for the quick response. If I do it this way, I was rearranging some of the data with a cut and paste so I could do a hlookup and pull some data into sheet1. It wont allow me to do that as it says I can't change an array.
Second, maybe i missed it but I don't see where it is using the cell contents of b2 and changing it into a short date and pulling the corresponding sheet within the closed workbook. Is it possible to use the code I currently have and get it to look at the contents of "b2" and do the above with it?
Second, maybe i missed it but I don't see where it is using the cell contents of b2 and changing it into a short date and pulling the corresponding sheet within the closed workbook. Is it possible to use the code I currently have and get it to look at the contents of "b2" and do the above with it?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Here is the formula to use with the UDF above:
=GetCellsFromClosedWorkboo k("C:\", "Workbookname", TEXT(B2, "mmm-yy"), "B2:F55")
Also, you can break the pulls up into smaller chunks and place them anywhere you want. All you need to do is select the right size range and use the appropriate formula.
Kevin
=GetCellsFromClosedWorkboo
Also, you can break the pulls up into smaller chunks and place them anywhere you want. All you need to do is select the right size range and use the appropriate formula.
Kevin
For example, suppose you wanted to pull in specific columns. Select the column of cells to receive the first column of pulled data and use this formula:
=GetCellsFromClosedWorkboo k("C:\", "Workbookname", TEXT(B2, "mmm-yy"), "B2:B55")
Select another column for the second pulled column and use this formula:
=GetCellsFromClosedWorkboo k("C:\", "Workbookname", TEXT(B2, "mmm-yy"), "C2:C55")
and so on.
Kevin
=GetCellsFromClosedWorkboo
Select another column for the second pulled column and use this formula:
=GetCellsFromClosedWorkboo
and so on.
Kevin
=GetCellsFromClosedWorkboo
and press CTRL+SHIFT+ENTER.
-----
Public Function GetCellsFromClosedWorkbook
ByVal WorkbookPath As String, _
ByVal WorkbookName As String, _
ByVal WorksheetName As String, _
ByVal SourceReference As String, _
Optional ByVal FirstRow As Long = 1, _
Optional ByVal FirstColumn As Long = 1 _
) As Variant
' Read cell values from a closed workbook. The closed workbook cannot be
' password protected.
'
' Syntax
'
' WorkbookPath - The full path to the folder containing the workbook.
'
' WorkbookName - The workbook name including the file extension.
'
' WorksheetName - The name of the worksheet from which to pull the value.
'
' CellReference - A string containing the cell address in A1 reference style.
' The reference can be any size.
'
' FirstRow - The base row from which to offset CellReference. If the source
' workbook's used range starts in a row other than 1, use this parameter to
' tell the function on what row the used range starts. Optional. If omitted
' then 1 is assumed.
'
' FirstColumn - The base column from which to offset CellReference. If the
' source workbook's used range starts in a column other than 1, use this
' parameter to tell the function on what column the used range starts.
' Optional. If omitted then 1 is assumed.
'
' Notes
'
' The reason FirstRow and FirstColumn are required is because, when using ADO
' to open a worksheet, the first field in the first record is the top left cell
' in the used range which may or may not be cell A1.
Dim Result As Variant
Dim Error As Variant
Dim Connection As Object
Dim RecordSet As Object
Dim SourceReferenceRange As Range
Dim SQL As String
Dim FirstRecordSetRow As Long
Dim FirstRecordSetColumn As Long
Dim Rows As Long
Dim Columns As Long
Dim ResultRows As Long
Dim ResultColumns As Long
Dim ValueRows As Long
Dim ValueColumns As Long
Dim Row As Long
Dim Column As Long
Dim ErrorNumber As Long
' Append trailing slash
If Right(WorkbookPath, 1) <> "\" Then WorkbookPath = WorkbookPath & "\"
' Check for valid path name
If Len(Dir(WorkbookPath & WorkbookName)) = 0 Then
Error = "#Bad Path or File!"
GoTo GetCellsFromClosedWorkbook
End If
' Check for valid range reference
On Error Resume Next
Set SourceReferenceRange = Range(SourceReference)
On Error GoTo 0
If SourceReferenceRange Is Nothing Then
Error = "#Invalid Reference!"
GoTo GetCellsFromClosedWorkbook
End If
' Open the ADODB connection and record set
Set Connection = CreateObject("ADODB.Connec
With Connection
.Provider = "Microsoft.Jet.OLEDB.4.0"
.Properties("Extended Properties") = "Excel 8.0;HDR=NO;IMEX=1"
.Open WorkbookPath & WorkbookName
End With
Set RecordSet = CreateObject("ADODB.Record
On Error Resume Next
RecordSet.Open "SELECT * From [" & WorksheetName & "$]", Connection, 1, 1 ' adOpenKeyset, adLockReadOnly
ErrorNumber = Err.Number
On Error GoTo 0
If ErrorNumber <> 0 Then
Error = "#Worksheet Not Found!"
GoTo GetCellsFromClosedWorkbook
End If
FirstRecordSetRow = SourceReferenceRange.Row - FirstRow + 1
Rows = Application.Min(RecordSet.
FirstRecordSetColumn = SourceReferenceRange.Colum
Columns = Application.Min(RecordSet.
' Set up and initialize result
If TypeName(Application.Calle
ResultRows = Application.Caller.Rows.Co
ResultColumns = Application.Caller.Columns
Else
ResultRows = Rows
ResultColumns = Columns
End If
ValueRows = ResultRows
ValueColumns = ResultColumns
If Rows > ValueRows And Not Columns > ValueColumns Then
ValueRows = Application.Max(ValueRows - 1, 1)
ElseIf Not Rows > ValueRows And Columns > ValueColumns Then
ValueColumns = Application.Max(ValueColum
End If
ReDim Result(1 To ResultRows, 1 To ResultColumns)
For Column = 1 To ResultColumns
For Row = 1 To ResultRows
Result(Row, Column) = vbNullString
Next Row
Next Column
' Check range
If FirstRecordSetColumn < 1 Or FirstRecordSetRow < 0 Or Rows < 1 Or Columns < 1 Then
Error = "#Bad Reference!"
GoTo GetCellsFromClosedWorkbook
End If
' Pull the cell values from the record set
If FirstRecordSetRow > 1 Then RecordSet.Move FirstRow
Row = 1
For Row = 1 To Application.Min(ValueRows,
For Column = 1 To Application.Min(ValueColum
If Not IsNull(RecordSet.Fields(Fi
Result(Row, Column) = RecordSet.Fields(FirstReco
End If
Next Column
RecordSet.MoveNext
Next Row
GetCellsFromClosedWorkbook
' Return the result
If IsEmpty(Result) Then
If TypeName(Application.Calle
ResultRows = Application.Caller.Rows.Co
ResultColumns = Application.Caller.Columns
ReDim Result(1 To ResultRows, 1 To ResultColumns)
For Column = 1 To ResultColumns
For Row = 1 To ResultRows
Result(Row, Column) = vbNullString
Next Row
Next Column
Else
ResultRows = 1
ResultColumns = 1
ReDim Result(1 To 1, 1 To 1)
End If
Else
If TypeName(Application.Calle
If Rows > ResultRows And Columns > ResultColumns Then
Result(ResultRows, ResultColumns) = "More..."
Else
If Rows > ResultRows Then
Result(ResultRows, 1) = "More..."
ElseIf Columns > ResultColumns Then
Result(1, ResultColumns) = "More..."
End If
End If
End If
End If
If Not IsEmpty(Error) Then Result(1, 1) = Error
If ResultRows = 1 And ResultColumns = 1 Then
GetCellsFromClosedWorkbook
Else
GetCellsFromClosedWorkbook
End If
' Clean up
On Error Resume Next
RecordSet.Close
Connection.Close
End Function
Kevin