Consulting

Page 1 of 2 1 2 LastLast
Results 1 to 20 of 24

Thread: Solved: Consolidation macro

  1. #1
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location

    Solved: Consolidation macro

    Hi

    Each day I will have an unspecified number of identical spreadsheet logs saved into a specific folder. I have a Master spreadsheet that I want to collect all the data to.

    In all the other spreadsheets, the data the agents complete starts on Row 3, each row of data contains info from columns A to I but the number of rows will vary depending on how many calls an agent takes each day. If I need to give a figure, then I would choose 1000 as agents would need to be bionic to do more than that.

    So can i get a macro in Master.xls to open all other files in the same folder and copy all the data from the other spreadsheets so that I have one very long list on my master sheet?

    Thanks

    Sir BD
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  2. #2
    VBAX Master
    Joined
    Jun 2007
    Location
    East Sussex
    Posts
    1,110
    Location
    Yes.
    Is there a column that will always have data in it? (to determine the last row, not a problem if not)
    Also, do you want the data appended each time the macro is run, or do you want to clear the old data first?
    Regards,
    Rory

  3. #3
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Quote Originally Posted by rory
    Yes.
    Is there a column that will always have data in it? (to determine the last row, not a problem if not)
    Also, do you want the data appended each time the macro is run, or do you want to clear the old data first?
    Regards,
    Rory
    There should be, but human error might mean that an agent forgets to fill in his name - otherwise it would be column A.

    No each day I will create a new report with all of that day's results, the next day will always be a clean sheet.

    Thanks Rory
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  4. #4
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    BD,

    Just use Dir to loop through all files in the specified directory (start with say [vba]myFile = Dir("C:\test\*.xls")[/vba] and use [vba]myFile = Dir[/vba] to get the rest, open the workbooks ( as in myFile), calculate the lastrow [vba]With Activeworkbook.Worksheets("Sheet1")
    LastRow = .Cells(.Rows.Count).End(xlUp).Row
    End With
    [/vba]
    and append to the existing data.

    With dir, myFile will be blank when there are no more.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  5. #5
    VBAX Master
    Joined
    Jul 2006
    Location
    Belgium
    Posts
    1,286
    Location
    Not sure if it's still relevant. But I use this to know the real last filled in row and/or column.[vba] 'sh is dimmed as worksheet
    'shrange is dimmed as worksheetrange
    'Last used row, last used column when
    'using usedrange
    Set shrange = sh.Range(Cells(1, 1), _
    Cells(sh.UsedRange.Rows.Count, sh.UsedRange.Columns.Count))[/vba]so the [VBA]sh.UsedRange.Rows.Count[/VBA]would find the last row with something in (no matter which column) --- that's what I think at least ---

  6. #6
    VBAX Master
    Joined
    Jun 2007
    Location
    East Sussex
    Posts
    1,110
    Location
    You could use something like this - note there is no check for the data going over 65536 rows though!

    [VBA]Sub Consolidation()
    Dim wbk As Workbook
    Dim wksSource As Worksheet, wksDest As Worksheet
    Dim strFile As String, strPath As String
    Dim rngLastCell As Range
    Dim lngRowCount As Long, lngColumnCount As Long, lngTargRow As Long
    Dim varData

    ' Note: the workbook must be saved before running this macro!!
    strPath = ThisWorkbook.Path
    If strPath = "" Then
    MsgBox "This workbook must be saved in directory first!"
    Exit Sub
    End If
    Application.ScreenUpdating = False
    strPath = strPath & Application.PathSeparator
    strFile = Dir(strPath & "*.xls")
    Set wksDest = ActiveSheet
    lngTargRow = 2
    Do Until strFile = ""
    If Not strFile = ThisWorkbook.Name Then
    Set wbk = Workbooks.Open(strPath & strFile)
    ' Assumes only one sheet
    Set wksSource = wbk.Worksheets(1)
    Set rngLastCell = LastCellInSheet(wksSource)
    With wksSource
    varData = .Range(.Cells(3, "A"), rngLastCell)
    End With
    lngRowCount = UBound(varData, 1)
    lngColumnCount = UBound(varData, 2)
    With wksDest
    .Range(.Cells(lngTargRow, 1), .Cells(lngTargRow + lngRowCount - 1, _
    lngColumnCount)).Value = varData
    End With
    lngTargRow = lngTargRow + lngRowCount
    wbk.Close False
    End If
    strFile = Dir
    Loop
    Application.ScreenUpdating = True
    End Sub
    Public Function LastCellInSheet(wks As Worksheet) As Range
    ' Returns the cell at the bottom right corner of the sheet's real used range
    Dim lngLastCol As Long, lngLastRow As Long
    lngLastCol = 1
    lngLastRow = 1
    On Error Resume Next
    With wks.UsedRange
    lngLastCol = .Cells.Find(what:="*", after:=.Cells(1), _
    SearchOrder:=xlByColumns, _
    SearchDirection:=xlPrevious).Column
    lngLastRow = .Cells.Find(what:="*", after:=.Cells(1), _
    SearchOrder:=xlByRows, _
    SearchDirection:=xlPrevious).Row
    End With
    Set LastCellInSheet = wks.Cells(lngLastRow, lngLastCol)
    End Function
    [/VBA]

    HTH
    Rory

  7. #7
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Thanks guys - Rory for being so kindly thorough - and XLD and Charlize for trying to teach me!

    Sir BD
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  8. #8
    VBAX Mentor
    Joined
    Sep 2004
    Posts
    431
    Location
    I find this post similar to mine and the last question in my post remains.,
    Will the code fail in the suggestions given here as it does in mine if there is no sheet tiltled Sheet1 (but rather Sheet2) in one of the WBs ? If yes is there an error handler to address this problem ?
    Something like on error go to next ....
    Thank you.

    http://www.vbaexpress.com/forum/showthread.php?t=13804
    Thank you for your help

  9. #9
    VBAX Mentor
    Joined
    Sep 2004
    Posts
    431
    Location
    I now understand this:
    [vba]
    ' Assumes only one sheet
    Set wksSource = wbk.Worksheets(1)
    [/vba]
    Sorry
    Thank you for your help

  10. #10
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Hmm,

    I've noticed that where one or more of the Agent spreadsheets have no data - then the headers are imported by this macro - which I don't want to happen.

    I see that the code specifies to start at row 3, and this works fine when there's data there - but it screws up if not and I get the imported header (from row 2) plus one blank row.

    What's going wrong?
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  11. #11
    VBAX Master
    Joined
    Jun 2007
    Location
    East Sussex
    Posts
    1,110
    Location
    The last cell is returned from the header row and the code copies from A3 to the last cell; in this case that range goes up, not down! Try this tweak:
    [VBA]Sub Consolidation()
    Dim wbk As Workbook
    Dim wksSource As Worksheet, wksDest As Worksheet
    Dim strFile As String, strPath As String
    Dim rngLastCell As Range
    Dim lngRowCount As Long, lngColumnCount As Long, lngTargRow As Long
    Dim varData

    ' Note: the workbook must be saved before running this macro!!
    strPath = ThisWorkbook.Path
    If strPath = "" Then
    MsgBox "This workbook must be saved in directory first!"
    Exit Sub
    End If
    Application.ScreenUpdating = False
    strPath = strPath & Application.PathSeparator
    strFile = Dir(strPath & "*.xls")
    Set wksDest = ActiveSheet
    lngTargRow = 2
    Do Until strFile = ""
    If Not strFile = ThisWorkbook.Name Then
    Set wbk = Workbooks.Open(strPath & strFile)
    ' Assumes only one sheet
    Set wksSource = wbk.Worksheets(1)
    Set rngLastCell = LastCellInSheet(wksSource)
    If rngLastCell.Row > 2 Then
    With wksSource
    varData = .Range(.Cells(3, "A"), rngLastCell)
    End With
    lngRowCount = UBound(varData, 1)
    lngColumnCount = UBound(varData, 2)
    With wksDest
    .Range(.Cells(lngTargRow, 1), .Cells(lngTargRow + lngRowCount - 1, _
    lngColumnCount)).Value = varData
    End With
    lngTargRow = lngTargRow + lngRowCount
    End If
    wbk.Close False
    End If
    strFile = Dir
    Loop
    Application.ScreenUpdating = True
    End Sub
    [/VBA]

    HTH
    Rory

  12. #12
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Quote Originally Posted by rory
    The last cell is returned from the header row and the code copies from A3 to the last cell; in this case that range goes up, not down! Try this tweak:

    HTH
    Rory
    That worked perfectly thanks!
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  13. #13
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Oh,

    Can I put a test in the code? Basically I need the code to make sure that, when it cycles through all the workbooks etracting data, it misses workbooks that have nothing to do with this particular exercise.
    So I put input "UseWorkbook" in cell A1 of sheet 1 (the same sheet the data is collected from) of the right workbooks, but How do I get the macro to test A1 of Sheet 1 of all the spreadsheets it opens, and if it doesn't contain "UseWorkbook" then to ignore that workbook?

    Thanks
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  14. #14
    VBAX Master
    Joined
    Jul 2006
    Location
    Belgium
    Posts
    1,286
    Location
    Try this. But can't you check for a similar namepart in the workbooks you want to process. For example Agent ?[VBA]Do Until strFile = ""
    If Not strFile = ThisWorkbook.Name Then
    'or maybe use this
    'and left(strFile,5) = "Agent"
    'if every agent puts agent in filename
    Set wbk = Workbooks.Open(strPath & strFile)
    ' Assumes only one sheet
    Set wksSource = wbk.Worksheets(1)
    Set rngLastCell = LastCellInSheet(wksSource)
    '*** extra check on A1
    If rngLastCell.Row > 2 And _
    wksSource.Range("A1").Value = "UseWorkbook" Then
    With wksSource
    varData = .Range(.Cells(3, "A"), rngLastCell)
    End With
    lngRowCount = UBound(varData, 1)
    lngColumnCount = UBound(varData, 2)
    With wksDest
    .Range(.Cells(lngTargRow, 1), .Cells(lngTargRow + lngRowCount - 1, _
    lngColumnCount)).Value = varData
    End With
    lngTargRow = lngTargRow + lngRowCount
    End If
    wbk.Close False
    End If
    strFile = Dir
    Loop[/VBA]

  15. #15
    VBAX Master
    Joined
    Jun 2007
    Location
    East Sussex
    Posts
    1,110
    Location
    Try this:
    [VBA]Sub Consolidation()
    Dim wbk As Workbook
    Dim wksSource As Worksheet, wksDest As Worksheet
    Dim strFile As String, strPath As String
    Dim rngLastCell As Range
    Dim lngRowCount As Long, lngColumnCount As Long, lngTargRow As Long
    Dim varData

    ' Note: the workbook must be saved before running this macro!!
    strPath = ThisWorkbook.Path
    If strPath = "" Then
    MsgBox "This workbook must be saved in directory first!"
    Exit Sub
    End If
    Application.ScreenUpdating = False
    strPath = strPath & Application.PathSeparator
    strFile = Dir(strPath & "*.xls")
    Set wksDest = ActiveSheet
    lngTargRow = 2
    Do Until strFile = ""
    If Not strFile = ThisWorkbook.Name Then
    Set wbk = Workbooks.Open(strPath & strFile)
    ' Assumes only one sheet
    Set wksSource = wbk.Worksheets(1)
    If LCase$(wksSource.Cells(1, 1).Value) = "useworkbook" Then
    Set rngLastCell = LastCellInSheet(wksSource)
    If rngLastCell.Row > 2 Then
    With wksSource
    varData = .Range(.Cells(3, "A"), rngLastCell)
    End With
    lngRowCount = UBound(varData, 1)
    lngColumnCount = UBound(varData, 2)
    With wksDest
    .Range(.Cells(lngTargRow, 1), .Cells(lngTargRow + lngRowCount - 1, _
    lngColumnCount)).Value = varData
    End With
    lngTargRow = lngTargRow + lngRowCount
    End If
    End If
    wbk.Close False
    End If
    strFile = Dir
    Loop
    Application.ScreenUpdating = True
    End Sub
    [/VBA]

    Regards,
    Rory

  16. #16
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Quote Originally Posted by Charlize
    ...can't you check for a similar namepart in the workbooks you want to process. For example Agent?
    Thanks for your answer Charlize

    No can do as the agents have autonomy to rename their workbooks if they want to - so a check on a cell seems the most effective solution given my constraints.

    Gonna try your solution now - thanks again
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  17. #17
    VBAX Master
    Joined
    Jul 2006
    Location
    Belgium
    Posts
    1,286
    Location
    Do they always use the same headers at the same row ?
    So A2, B2, C2 ... have always the same text in it.

  18. #18
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location
    Charlize - ceers for your help!

    Rory - that works great now - thanks!
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  19. #19
    VBAX Mentor Sir Babydum GBE's Avatar
    Joined
    Mar 2005
    Location
    Cardiff, UK
    Posts
    499
    Location

    A slight adjustment needed

    Hi,

    In the section of code below that opens all the workbooks in a folder until there aren't any more... I need it to not ask me whether i want to update the links - and I need it to not update the links.

    I would put a DisplayAlerts=False bit in there, except I think the default option is to update links - but that slows things down to much and there are no links on the sheets I'm interested in anyway.

    Cheers

    BD
    Have a profound problem? Need a ridiculous solution? Post a question in Babydum's forum

  20. #20
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    There is an UpdateLinks argument to the Open method, use that with a value of 0.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •