0

I am currently using a piece of code to loop through files in a folder and copy certain cells from each file into a master list. There are a number of files being added into the folder every week. One of the columns in the master list includes the filenames of previously looped files. The code only loops through files that are not included in the filename list and therefore also have not previously been looped.

The code works really well and copies cells with satisfactory results however I now need to modify it to also copy a range of data (A20:H33 specifically) as well as meeting the above condition of not already being looped.

I have tried the following unsuccesfully:

  • Adding another varTemp to the code (As seen in the main code)
  • Adding a sub that can copy a range (However I have been unable to incorporate this into the code so it satisfies the not looped condition)
  • Using selection.copy and selection.paste however an error that I cannot workaround pops up ("Object doesn't support this property or method")

Here is the main code:

    Option Explicit

    Sub CopyFromFolderExample()

    Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1)
    Dim strFolder As String, strFile As String, r As Long, wb As Workbook
    Dim varTemp(1 To 6) As Variant

    Application.ScreenUpdating = False
    strFolder = "D:\Other\folder\"

        r = ws.Range("A" & ws.Rows.Count).End(xlUp).Row

        strFile = Dir(strFolder & "*.xl*")
        Do While Len(strFile) > 0
            If Not Looped(strFile, ws) Then
                Application.StatusBar = "Reading data from " & strFile & "..."
                Set wb = Workbooks.Add(strFolder & strFile)
                With wb.Worksheets(1)
                    varTemp(1) = strFile
                    varTemp(2) = .Range("A13").Value
                    varTemp(3) = .Range("H8").Value
                    varTemp(4) = .Range("H9").Value
                    varTemp(5) = .Range("H37").Value
                    'varTemp(6) = .Range("A20:H33").Value

                End With
                wb.Close False

                r = r + 1
                ws.Range(ws.Cells(r, 1), ws.Cells(r, 6)).Formula = varTemp
            End If    
          strFile = Dir
        Loop

    Application.StatusBar = False
    Application.ScreenUpdating = True

    End Sub

    Private Function Looped(strFile As String, ws As Worksheet) As Boolean

    Dim Found As Range
    Set Found = ws.Range("A:A").Find(strFile)

    If Found Is Nothing Then
        Looped = False
    Else
        Looped = True
    End If

    End Function

This is the snippet of code that when inserted into the main code just below tha last vartemp gives me the following error ("Object doesn't support this property or method")

.Range("A20:H33").Select
.Range(Selection, Selection.End(xlDown)).Select
Selection.Copy

ws.Activate

If ws.Range("A1") = "" Then
    ws.Range("A1").Select
    Selection.Paste
Else
    Selection.End(xlDown).Offset(6, 0).Select
    Selection.Paste
End If

Here is what I am trying to achieve: Aim of code

  • So you're pasting in a row and moving down one, but now you are adding a range of 14 rows so how are you wanting the output arranged? – SJR Dec 13 '18 at 16:12
  • Which line throws the error you mentioned? I cannot see anywhere in your code where you copy and paste a selection – Zac Dec 13 '18 at 16:34
  • i.n.d.e.n.t.a.t.i.o.n.s. – JohnyL Dec 13 '18 at 19:18
  • @JohnyL updated the code – M.Laszkowski Dec 14 '18 at 11:19
  • @SJR So the single rows of data that include the cells take up the first 5 columns - I was hoping to paste the ranges of data in the 6th column onward. With the next range being pasted underneath the first etc. So in summary; the first 5 columns I am pasting in one row and moving down one whereas in the 6th column onward I am wanting to paste a range then move down 14 rows and paste the next range and so on. Does that make sense? – M.Laszkowski Dec 14 '18 at 11:25
  • @Zac I have updated the question with the code snippet that gives me the error. ''Selection.Paste'' is the line more specifically that gives the error. The workbook from which the data is being copied opens and the range is selected but then the error pops up. – M.Laszkowski Dec 14 '18 at 11:45
  • Not sure. Let's say the first five values go in A1:E1. Then the A20:H33 range goes in F1:L14? Then the second group of five goes in A15:E15 etc? Is that right? – SJR Dec 14 '18 at 11:46
  • @SJR That could also work but it isn't exactly what I meant. Your approach would end up with blank cells in between A2:E14. What I was trying to achieve was what you are describing minus the blank spaces. – M.Laszkowski Dec 14 '18 at 11:55
  • A picture paints a thousand words. Please can you post a screenshot? – SJR Dec 14 '18 at 11:57
  • 1
    @SJR updated with a screenshot – M.Laszkowski Dec 14 '18 at 13:01

2 Answers2

1

I think that if you use a Range variable instead of a Variant to copy and paste the Range(A20:AH33) should get the job done. Declare:

Dim rg as Range

Then replace this line of code:

varTemp(6) = .Range("A20:H33").Value

For this:

Set rg = .Range("A20:H33")

Then you can just Rg.Copy and paste whereaver you want. Don't forget to "clear" the copybuffer after you paste the information:

Application.CutCopyMode = False 

Avoid to use Selectionand Activate in your code, the reasons for it can be seen here:

How to avoid using Select in Excel VBA

and here:

https://www.businessprogrammer.com/power-excel-vba-secret-avoid-using-select/

  • This has definitely helped, but isn't exactly the answer that I was looking for. I am nearly there, need to tidy a few things up and figure out how to only paste values using your method. – M.Laszkowski Dec 14 '18 at 15:46
  • @M.Laszkowski if you want to paste only the values then you can simply `.PasteSpecial xlPasteValues`. You can see the documentation here: https://learn.microsoft.com/en-us/office/vba/api/excel.range.pastespecial – Fabricio Montagnani Dec 14 '18 at 17:35
0

This should do it. I've turned your array back to 5 elements, and the range is transferred separately. I've added a few new variables which you might want to give more meaningful names.

Sub CopyFromFolderExample()

Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1)
Dim strFolder As String, strFile As String, r As Long, wb As Workbook
Dim varTemp(1 To 5) As Variant, r1 As Long, r3 As Range

Application.ScreenUpdating = False
strFolder = "D:\Other\folder\"
strFile = Dir(strFolder & "*.xl*")

Do While Len(strFile) > 0
    If Not Looped(strFile, ws) Then
        Application.StatusBar = "Reading data from " & strFile & "..."
        Set wb = Workbooks.Add(strFolder & strFile)
        With wb.Worksheets(1)
            varTemp(1) = strFile
            varTemp(2) = .Range("A13").Value
            varTemp(3) = .Range("H8").Value
            varTemp(4) = .Range("H9").Value
            varTemp(5) = .Range("H37").Value
            Set r3 = .Range("A20:H33")
        End With
        With ws
            r = .Range("A" & .Rows.Count).End(xlUp).Row + 1
            r1 = .Range("F" & .Rows.Count).End(xlUp).Row + 1 'last used row in col F
            .Range(.Cells(r, 1), .Cells(r, 5)).Value = varTemp
            .Cells(r1, 6).Resize(r3.Rows.Count, r3.Columns.Count).Value = r3.Value 'transfer A20:H33
        End With
        wb.Close False
    End If
  strFile = Dir
Loop

Application.StatusBar = False
Application.ScreenUpdating = True

End Sub
SJR
  • 22,986
  • 6
  • 18
  • 26
  • That works perfectly, I manged to get onto a similar path just before you posted this answer with everyone's help. But it wasn't anything as crisp as this! Thanks! – M.Laszkowski Dec 17 '18 at 09:44