3

Long time reader and admirer of StackOverflow.

Basically I am trying to to loop through a series of Excel files to copy a range of data and paste it on a single Excel workbook/sheet.

The cell range location (C3:D8, D3:E8) is not always consistent, but the table dimensions are: 29 R x 2 C. Also, the files only have 1 sheet, and aside from the table dimensions specified, no data values in other cells.

In its current form the code is executing, but not pasting anything to its destination Excel file.

I need it to

  1. Find the data dimension in file (table)
  2. Copy the table
  3. Paste to destination (below previous table)
  4. Loop through to next file
  5. Repeat Step 1-4

The code is from: Excel VBA: automating copying ranges from different workbooks into one final destination sheet?

Thanks a lot for any help, I really appreciate it and please feel tell me to specify anything if my question is vague.

Sub SourcetoDest()

    Dim wbDest As Workbook
    Dim wbSource As Workbook
    Dim sDestPath As String
    Dim sSourcePath As String
    Dim shDest As Worksheet
    Dim rDest As Range
    Dim vaFiles As Variant
    Dim i As Long

    'array of folder names under sDestPath

    'array of file names under vaFiles
    vaFiles = Array("Book1.xls")

    sDestPath = "C:\Users"
    sSourcePath = "C:\Users"


    Set wbDest = Workbooks.Open(sDestPath & "\" & "Book2.xlsm")
    Set shDest = wbDest.Sheets(1)

    'loop through the files
    For i = LBound(vaFiles) To UBound(vaFiles)
        'open the source
        Set wbSource = Workbooks.Open(sSourcePath & "\" & vaFiles(i))

        'find the next cell in col C
        Set rDest = shDest.Cells(shDest.Rows.Count, 3).End(xlUp).Offset(1, 0)
        'write the values from source into destination
        rDest.Resize(5, 1).Value = wbSource.Sheets(1).Range("C7:D33").Value


        wbSource.Close False
    Next i

End Sub
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Andrew Karl
  • 33
  • 1
  • 1
  • 3
  • Your code seems just fine, have you try to go through it in breakmode? You only need the part to size your initial data range, but nothing you can't handle there (as you already know the `End()` function). But I can't see why you won't have any data in the destination sheet... – R3uK Jul 21 '15 at 09:17
  • If you try `wbSource.Sheets(1).Range("C7:D33").Select` just before the `rDest.Resize(5, 1).Value = wbSource.Sheets(1).Range("C7:D33").Value ` line, it will highlight the source data. Step through your code using F8 and check that your source range is correct. Next try `rDest.Resize(5, 1).Select` to check the destination range. Once these are correct, you can remove both lines when you have finished debugging. – tonester640 Jul 21 '15 at 09:32
  • Thanks, the funny thing is when scrolling through the code with F8, and it gets to line Set wbDest = Workbooks.Open(sDestPath & "\" & "Book2.xlsm") the excel file Book2 opens but then the code just stops? – Andrew Karl Jul 22 '15 at 06:38

2 Answers2

1

The below should achieve what you're after.

Option Explicit
Sub copy_rng()
    Dim wb As Workbook, wbDest As Workbook, ws As Worksheet, wsDest As Worksheet, wsSrc As Worksheet
    Dim wbNames() As Variant
    Dim destFirstCell As Range
    Dim destColStart As Integer, destRowStart As Long, i As Byte
    Dim destPath As String

    Set wb = ThisWorkbook
    Set ws = wb.Sheets("Sheet1") ' Amend to your sheet name
    Set wsSrc = wb.Sheets("Sheet2") ' Amend to sheet name with table data
    wbNames = ws.Range("A2:A" & lrow(1, ws)) ' Pass col number into lrow function
    destPath = "C:\Users\"

    Application.ScreenUpdating = False
    For i = 1 To UBound(wbNames, 1)
        Set wbDest = Workbooks.Open(destPath & wbNames(i, 1))
        Set wsDest = wbDest.Worksheets(1)
        With wsDest
            Set destFirstCell = .Cells.Find(What:="*")
            destColStart = destFirstCell.Column
            destRowStart = destFirstCell.Row
            .Range(Cells(destRowStart, destColStart), _
                Cells(lrow(destColStart, wsDest), icol(destRowStart, wsDest))).Copy
        End With
        wsSrc.Cells(lrow(1, wsSrc) + 1, 1).PasteSpecial Paste:=xlPasteAll
        wbDest.Close False
    Next i
    Application.ScreenUpdating = True

End Sub

Function lrow(ByVal col_num As Integer, sheet_name As Worksheet) As Long
    lrow = sheet_name.Cells(Rows.Count, col_num).End(xlUp).Row
End Function

Function icol(ByVal row_num As Long, sheet_name As Worksheet) As Integer
    icol = sheet_name.Cells(row_num, Columns.Count).End(xlToLeft).Column
End Function

Ensure you copy both of the functions across, they're used to create the dimensions of the table, and then copying the table.

You will need to amend the sheet name variables. Let me know if you have any questions.

You need to amend the range of where the workbook names are stored. You need to pass the column number in, so that the last row can be calculated. You can also amend the column in which data is pasted back into the workbook.

luke_t
  • 2,935
  • 4
  • 22
  • 38
  • Thanks for the reply Iturner, just one thing the data dimension I am trying to copy and paste into my final file are sitting in separate excel files, is it possible to modify WsSrc so that it goes to a separate file and pulls data from it? – Andrew Karl Jul 22 '15 at 06:35
  • The above creates an array containing the workbook names (assuming workbook names are stored in column A). Where do you get the workbook names which you want to open? – luke_t Jul 22 '15 at 07:36
  • Ah I see, thanks Iturner, previously I was putting the workbook names manually in the vba code (in array format), so now if I put them in Column A on the sheet I indicate within MyWorkBook, it will automatically go through these workbooks. I'll try this in a bit when I'm at my computer :) Thanks again! – Andrew Karl Jul 22 '15 at 09:32
  • Correct, if you populate column A with workbook names, and their file extension (eg. "myWorkbook.xlsb"), the array will collect them from Sheet1 (or the sheet you specify if you rename the `ws` variable). Let me know how you get on. – luke_t Jul 22 '15 at 09:39
  • Iturner it worked! Cheers! Thanks a lot, I hope you don't mind if I disturb you again; I'm going to now play around and see if I can get it to paste special a data range, and with this code I think I have a great start. Thanks again and wish you a good week :) – Andrew Karl Jul 22 '15 at 10:29
  • Great stuff! No problem, let me know if there's anything else. If you're happy, you can select this as the answer; this allows anyone else looking at questions to know this particular question has been resolved. – luke_t Jul 22 '15 at 10:39
  • Hey Iturner, I need to follow up on the macro, it works great except one thing which is the data's fault. The code copies and pastes a data table range, but only with 1 column instead of 2. I think this is because the first few cells are merged so when the code copies the range it only takes the first column range and omits the other one. – Andrew Karl Jul 27 '15 at 11:00
  • Hmm.. well I would firstly advise to try and format the workbook without using merged cells. If that's not an option let me know. – luke_t Jul 28 '15 at 07:35
  • hmm.. it isn't an option since I need the code to automate this process without having to go into the files separately. However, I tried to unmerge the cells, and it still only copied 1 column instead of 2. thanks :) – Andrew Karl Jul 28 '15 at 12:30
0

With the help of this code you can copy all workbooks and worksheets data into one workbook

Sub copydata()

Dim fso As Scripting.FileSystemObject
Dim fill As Scripting.File
Dim oldfolder As String
Dim newfolder As String
Dim subfolder As Folder
Dim myfolder As Folder
Dim fd As FileDialog
Dim loopcount As Integer
Dim wb
Dim wb2 As Workbook
Dim rr As Range

Set fso = New Scripting.FileSystemObject

Set wb = ThisWorkbook

Set fd = Application.FileDialog(msoFileDialogFolderPicker)
fd.Title = "Please Select Folder to copy"
fd.ButtonName = "Go!"
fd.Show

oldfolder = fd.SelectedItems(1)

Set myfolder = fso.GetFolder(oldfolder)

'Application.ScreenUpdating = False

Application.EnableEvents = False
 

For Each subfolder In myfolder.SubFolders

    For Each fill In subfolder.Files
            If fill Like "*.xlsm" Or fill Like "*.xlsx" Or fill Like ".*xls" Then
            'fill.Range("A1:Z100").Copy
            Set wb2 = Application.Workbooks.Open(fill,0 , True)
            wb2.Activate
            For loopcount = 1 To wb2.Worksheets.Count
            wb2.Activate
            Worksheets(loopcount).Activate
            Range("A1:Z300").Copy          'Replace your range
            wb.Activate
            Sheet1.Activate
            Set rr = Range("A:A").Find("", Range("A1"))
            rr.Select
            ActiveSheet.Paste
            ActiveCell.Offset(1, 0).Select
            Next loopcount
            wb2.Close False
            End If
            
        Application.CutCopyMode = False
        
        Debug.Print fill.Name
    
    Next fill
    
Next subfolder
        MsgBox "Done"

    For Each fill In myfolder.Files
        Application.DisplayAlerts = False
    
         If fill Like "*.xlsm" Or fill Like "*.xlsx" Or fill Like ".*xls" Or fill Like "*.xlsb" Then
            'fill.Range("A1:Z100").Copy
            Set wb2 = Application.Workbooks.Open(fill, 0, True)
            wb2.Activate
            
            For loopcount = 1 To wb2.Worksheets.Count
        
            wb2.Activate
            Worksheets(loopcount).Activate
            
            Range("A:Z").EntireColumn.Hidden = False
            
            Range("A1:Z1").AutoFilter
            Range("A1:Z300").Copy
            wb.Activate
            
            Sheet1.Activate
            Set rr = Range("A:A").Find("", Range("A1"))
            rr.Select
            ActiveSheet.Paste
            ActiveCell.Offset(1, 0).Select
            Next loopcount
            wb2.Close False
            End If
            
        Application.CutCopyMode = False
        
        Debug.Print fill.Name
        
    Next fill

Application.EnableEvents = True

End Sub

mithun
  • 1
  • 2