pulling lastrow data from multiple files

gordsky

Well-known Member
Joined
Jun 2, 2016
Messages
556
Office Version
  1. 2016
Platform
  1. Windows
Hi all,

Im trying to pull the data from the last row in Column E of multiple files within a folder. I was initially looking to do this via vba but as I dont want to "open" each workbook individually it was suggest that power query may be the way forward. I am new to power query but have managed to work out how to pull all the files and even managed to work out how to get rid of the columns etc i dont need. what I cant work out is how to get the data from just the last row (which would be variable) of each workbook.
Can someone give me some pointers please.
 

Excel Facts

Why does 9 mean SUM in SUBTOTAL?
It is because Sum is the 9th alphabetically in Average, Count, CountA, Max, Min, Product, StDev.S, StDev.P, Sum, VAR.S, VAR.P.
Getting started on this and I have another question. Is there data in all the columns A thru E in the 'HrsWRK' sheets?
 
Upvote 0
Sorry, there is something that is messing up the code I am trying to put together, maybe I have stared at it too long. I will look into it again tomorrow.
 
Upvote 0
Is column E the longest or equal to the longest column in the sheet?
 
Upvote 0
Is column E the longest or equal to the longest column in the sheet?
Hi JohnnyL yes column E is either the longest or equal to the longest. really do appreciate the time you are putting into this
 
Upvote 0
I think I have it worked out, I just need to do some cleanup now.
 
Upvote 0
Try this out:

VBA Code:
Sub GetLastValueFromColumnFromClosedWorkbookIntoAnArrayWithoutHelperSheet()
'
'   This code assumes:
'       1) All files in the folder that is selected are files that you want to get data from.
'       2) There is only one sheet in the files.
'       3) The column to get the data from is the longest or tied for the longest column in the sheet.
'       4) The Results are stored into a newly created workbook, the new workbook is not automatically saved because that was not mentioned as a desire.
'
    Dim UserFolderPath          As String
'
    With Application.FileDialog(msoFileDialogFolderPicker)
        .AllowMultiSelect = False                                                       '   Allow only one folder to be selected by user
        .Title = "Select a folder that contains the files you are interested in."
        .Show                                                                           '   Show the pop-up box asking for a folder to use
'
        If .SelectedItems.Count = 0 Then                                                '   If user cancelled then ...
            MsgBox "Operation Cancelled by the user", vbExclamation + vbOKOnly          '       Display message box confirming the cancellation
            Exit Sub                                                                    '       Exit the Sub
        End If
'
        UserFolderPath = .SelectedItems(1) & "\"                                        '   Add a '\' to the end of the folder path selected by the user
    End With
'
    Application.ScreenUpdating = False                                                  ' Turn ScreenUpdating off
'
    Dim StartTime               As Single
    StartTime = Timer                                                                   ' Start the stop watch
''
    Dim ProcessedFiles          As Long
    Dim AllFiles                As Object, CurrentFile      As Object, fso          As Object
    Dim conexion                As Object, objCatalog       As Object, objRecordSet As Object
    Dim ResultsAddress          As Range
    Dim CodeCompletionTime      As Single
    Dim AddressForResults       As String
    Dim ClosedWorkbookString    As String
    Dim SourceColumn            As String
    Dim strSQL                  As String
    Dim DataNeededArray         As Variant, ResultsArray    As Variant
    Dim NewWorkbook             As Workbook
'
    SourceColumn = "E"                                                                  ' <--- Set this to the Column that you want last value from
    AddressForResults = "B1"                                                            ' <--- Set this to the cell that you want to display results to
'
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set AllFiles = fso.GetFolder(UserFolderPath).Files
'
    ProcessedFiles = 0                                                                  ' Initialize ProcessedFiles to zero
'
    ReDim DataNeededArray(1 To 50000, 1 To 4)                                           ' Set Rows & Columns for DataNeededArray
    ReDim ResultsArray(1 To 50000)                                                      ' Set Rows & Columns for ResultsArray
'
    For Each CurrentFile In AllFiles                                                    ' Loop through each file in the user selected folder
        Set objCatalog = CreateObject("ADOX.Catalog")                                   '   Set up catalog so we can get the sheet name
        Set conexion = CreateObject("ADODB.Connection")                                 '   Set up connection so we can connect to the source file
        Set objRecordSet = CreateObject("ADODB.Recordset")                              '   Set up recordset so we can get the Last row
'
        On Error GoTo InvalidInput                                                      '   If an error is encountered, goto the error handling section
        conexion.Open "Provider=MSDASQL.1;Data Source=Excel Files;" & _
                "Initial Catalog=" & CurrentFile                                        '   open the connection to the source file
'
        objCatalog.ActiveConnection = conexion
        SourceSheetName = Replace(objCatalog.Tables(0).Name, "$", "")                   '   Get sheet name of 1st sheet & Remove $ from end of sheet name
        SourceSheetName = Replace(SourceSheetName, "'", "")                             '   Remove 's from sheet name
'
        strSQL = "SELECT Count(*) FROM [" & SourceSheetName & "$]"                      '   Select all data on the source sheet
'
        objRecordSet.Open Source:=strSQL, ActiveConnection:=conexion, _
                CursorType:=adOpenForwardOnly, Options:=adCmdText
        SourceLastRow = objRecordSet(0) + 1                                             '   Save Last row number into SourceLastRow
'
        On Error GoTo 0                                                                 '   Turn off error handling
'
        ProcessedFiles = ProcessedFiles + 1                                                             '   Increment the ProcessedFiles counter
        DataNeededArray(ProcessedFiles, 1) = UserFolderPath                                             '   Save the folder path
        DataNeededArray(ProcessedFiles, 2) = Mid(CurrentFile, InStrRev(CurrentFile, "\") + 1)           '   Save the file name
        DataNeededArray(ProcessedFiles, 3) = SourceSheetName                                            '   Save the sheet name
        DataNeededArray(ProcessedFiles, 4) = SourceColumn & SourceLastRow                               '   Save address of last row of desired column
'
        ClosedWorkbookString = "'" & UserFolderPath & "[" & Mid(CurrentFile, InStrRev(CurrentFile, "\") + 1) & _
                "]" & SourceSheetName & "'!" & Range("E" & SourceLastRow).Address(True, True, xlR1C1)   '   Save string we will use to get cell value
        ResultsArray(ProcessedFiles) = ExecuteExcel4Macro(ClosedWorkbookString)                         '   Save the value of the cell into ResultsArray
    Next
'
    ReDim Preserve ResultsArray(1 To ProcessedFiles)                                                    ' Resize the ResultsArray to the actual size
'
       Set NewWorkbook = Workbooks.Add                                                                  ' Create a new workbook
    Set ResultsAddress = NewWorkbook.Worksheets(1).Range(AddressForResults)                             ' Set the address to save the results into
'
    Range(AddressForResults).Resize(UBound(ResultsArray)) = Application.Transpose(ResultsArray)         ' Display ResultsArray to designated location
'
'   Clean-Up!
    conexion.Close                                                                                      ' close the connection object
'
      Set objCatalog = Nothing                                                                          ' Delete Object
        Set conexion = Nothing                                                                          ' Delete Object
    Set objRecordSet = Nothing                                                                          ' Delete Object
'
    Application.ScreenUpdating = True                                                                   ' Turn ScreenUpdating back on
'
    CodeCompletionTime = Timer - StartTime                                                              ' Stop the stop watch
    CodeCompletionTime = Format(CodeCompletionTime, ".#####")                                           ' Prevent scientific notation results
    Debug.Print "Time to complete MoveDataToDifferentSheets = " & CodeCompletionTime & " seconds."      ' Display the time elapsed to the user (Ctrl-G)
'
    Application.Speech.Speak "This code completed in, , , " & CodeCompletionTime & " seconds."          ' Provide audio result
'
    Exit Sub                                                                                            ' Exit the Sub
'
InvalidInput:
    MsgBox "An error was encountered during processing!", vbExclamation, "Get data from closed workbook"    ' Inform user that an error occurred
'
'   Clean-Up!
      Set objCatalog = Nothing                                                                              ' Delete Object
        Set conexion = Nothing                                                                              ' Delete Object
    Set objRecordSet = Nothing                                                                              ' Delete Object
End Sub

I left code in there to store data into an array that was used to get the cell value. If you want, you can use that array (DataNeededArray) to display the data that was used to get the cell value.
 
Upvote 0
Solution
Try this out:

VBA Code:
Sub GetLastValueFromColumnFromClosedWorkbookIntoAnArrayWithoutHelperSheet()
'
'   This code assumes:
'       1) All files in the folder that is selected are files that you want to get data from.
'       2) There is only one sheet in the files.
'       3) The column to get the data from is the longest or tied for the longest column in the sheet.
'       4) The Results are stored into a newly created workbook, the new workbook is not automatically saved because that was not mentioned as a desire.
'
    Dim UserFolderPath          As String
'
    With Application.FileDialog(msoFileDialogFolderPicker)
        .AllowMultiSelect = False                                                       '   Allow only one folder to be selected by user
        .Title = "Select a folder that contains the files you are interested in."
        .Show                                                                           '   Show the pop-up box asking for a folder to use
'
        If .SelectedItems.Count = 0 Then                                                '   If user cancelled then ...
            MsgBox "Operation Cancelled by the user", vbExclamation + vbOKOnly          '       Display message box confirming the cancellation
            Exit Sub                                                                    '       Exit the Sub
        End If
'
        UserFolderPath = .SelectedItems(1) & "\"                                        '   Add a '\' to the end of the folder path selected by the user
    End With
'
    Application.ScreenUpdating = False                                                  ' Turn ScreenUpdating off
'
    Dim StartTime               As Single
    StartTime = Timer                                                                   ' Start the stop watch
''
    Dim ProcessedFiles          As Long
    Dim AllFiles                As Object, CurrentFile      As Object, fso          As Object
    Dim conexion                As Object, objCatalog       As Object, objRecordSet As Object
    Dim ResultsAddress          As Range
    Dim CodeCompletionTime      As Single
    Dim AddressForResults       As String
    Dim ClosedWorkbookString    As String
    Dim SourceColumn            As String
    Dim strSQL                  As String
    Dim DataNeededArray         As Variant, ResultsArray    As Variant
    Dim NewWorkbook             As Workbook
'
    SourceColumn = "E"                                                                  ' <--- Set this to the Column that you want last value from
    AddressForResults = "B1"                                                            ' <--- Set this to the cell that you want to display results to
'
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set AllFiles = fso.GetFolder(UserFolderPath).Files
'
    ProcessedFiles = 0                                                                  ' Initialize ProcessedFiles to zero
'
    ReDim DataNeededArray(1 To 50000, 1 To 4)                                           ' Set Rows & Columns for DataNeededArray
    ReDim ResultsArray(1 To 50000)                                                      ' Set Rows & Columns for ResultsArray
'
    For Each CurrentFile In AllFiles                                                    ' Loop through each file in the user selected folder
        Set objCatalog = CreateObject("ADOX.Catalog")                                   '   Set up catalog so we can get the sheet name
        Set conexion = CreateObject("ADODB.Connection")                                 '   Set up connection so we can connect to the source file
        Set objRecordSet = CreateObject("ADODB.Recordset")                              '   Set up recordset so we can get the Last row
'
        On Error GoTo InvalidInput                                                      '   If an error is encountered, goto the error handling section
        conexion.Open "Provider=MSDASQL.1;Data Source=Excel Files;" & _
                "Initial Catalog=" & CurrentFile                                        '   open the connection to the source file
'
        objCatalog.ActiveConnection = conexion
        SourceSheetName = Replace(objCatalog.Tables(0).Name, "$", "")                   '   Get sheet name of 1st sheet & Remove $ from end of sheet name
        SourceSheetName = Replace(SourceSheetName, "'", "")                             '   Remove 's from sheet name
'
        strSQL = "SELECT Count(*) FROM [" & SourceSheetName & "$]"                      '   Select all data on the source sheet
'
        objRecordSet.Open Source:=strSQL, ActiveConnection:=conexion, _
                CursorType:=adOpenForwardOnly, Options:=adCmdText
        SourceLastRow = objRecordSet(0) + 1                                             '   Save Last row number into SourceLastRow
'
        On Error GoTo 0                                                                 '   Turn off error handling
'
        ProcessedFiles = ProcessedFiles + 1                                                             '   Increment the ProcessedFiles counter
        DataNeededArray(ProcessedFiles, 1) = UserFolderPath                                             '   Save the folder path
        DataNeededArray(ProcessedFiles, 2) = Mid(CurrentFile, InStrRev(CurrentFile, "\") + 1)           '   Save the file name
        DataNeededArray(ProcessedFiles, 3) = SourceSheetName                                            '   Save the sheet name
        DataNeededArray(ProcessedFiles, 4) = SourceColumn & SourceLastRow                               '   Save address of last row of desired column
'
        ClosedWorkbookString = "'" & UserFolderPath & "[" & Mid(CurrentFile, InStrRev(CurrentFile, "\") + 1) & _
                "]" & SourceSheetName & "'!" & Range("E" & SourceLastRow).Address(True, True, xlR1C1)   '   Save string we will use to get cell value
        ResultsArray(ProcessedFiles) = ExecuteExcel4Macro(ClosedWorkbookString)                         '   Save the value of the cell into ResultsArray
    Next
'
    ReDim Preserve ResultsArray(1 To ProcessedFiles)                                                    ' Resize the ResultsArray to the actual size
'
       Set NewWorkbook = Workbooks.Add                                                                  ' Create a new workbook
    Set ResultsAddress = NewWorkbook.Worksheets(1).Range(AddressForResults)                             ' Set the address to save the results into
'
    Range(AddressForResults).Resize(UBound(ResultsArray)) = Application.Transpose(ResultsArray)         ' Display ResultsArray to designated location
'
'   Clean-Up!
    conexion.Close                                                                                      ' close the connection object
'
      Set objCatalog = Nothing                                                                          ' Delete Object
        Set conexion = Nothing                                                                          ' Delete Object
    Set objRecordSet = Nothing                                                                          ' Delete Object
'
    Application.ScreenUpdating = True                                                                   ' Turn ScreenUpdating back on
'
    CodeCompletionTime = Timer - StartTime                                                              ' Stop the stop watch
    CodeCompletionTime = Format(CodeCompletionTime, ".#####")                                           ' Prevent scientific notation results
    Debug.Print "Time to complete MoveDataToDifferentSheets = " & CodeCompletionTime & " seconds."      ' Display the time elapsed to the user (Ctrl-G)
'
    Application.Speech.Speak "This code completed in, , , " & CodeCompletionTime & " seconds."          ' Provide audio result
'
    Exit Sub                                                                                            ' Exit the Sub
'
InvalidInput:
    MsgBox "An error was encountered during processing!", vbExclamation, "Get data from closed workbook"    ' Inform user that an error occurred
'
'   Clean-Up!
      Set objCatalog = Nothing                                                                              ' Delete Object
        Set conexion = Nothing                                                                              ' Delete Object
    Set objRecordSet = Nothing                                                                              ' Delete Object
End Sub

I left code in there to store data into an array that was used to get the cell value. If you want, you can use that array (DataNeededArray) to display the data that was used to get the cell value.
JohnnyL - What can I say, seems to do exactly what I need. Ill try and get my head around the code but cant thank you enough for the time you put into this one. Very Much appreciated
 
Upvote 0

Forum statistics

Threads
1,223,675
Messages
6,173,748
Members
452,533
Latest member
Alex19k

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top