Run-Time Error '6' overflow (copy range from closed workbook) - vba

I have the below code placed on my active workbook which copy's data from a closed workbook. It works fine and very fast but i can only copy up to 8 columns if I select more than that I get a
run-time error 6 - Overflow
Code:
Sub Get_Data()
Dim RngToCopy As Range
Dim wkbk As Workbook
Dim DestCell As Range
Dim myFileNames As Variant
Dim iCtr As Long
Dim testStr As String
Set DestCell = ThisWorkbook.Worksheets(1).Range("a1")
myFileNames = Array("C:\my documents\excel\book1.xlsm") ' i could add more workbooks to copy from and append on current worksheet
For iCtr = LBound(myFileNames) To UBound(myFileNames)
testStr = ""
On Error Resume Next
testStr = Dir(myFileNames(iCtr))
On Error GoTo 0
If testStr = "" Then
MsgBox myFileNames(iCtr) & " doesn't exist!"
Else
Set wkbk = Workbooks.Open(Filename:=myFileNames(iCtr))
With wkbk.Worksheets(1)
Set RngToCopy = .Range("a2:r2", _
.Cells(.Rows.Count, "A").End(xlUp))
End With
DestCell.Resize(RngToCopy.Rows.Count, _
RngToCopy.Columns.Count).Value _
= RngToCopy.Value
Set DestCell = DestCell.Offset(RngToCopy.Rows.Count, 0)
wkbk.Close savechanges:=False
End If
Next iCtr
End Sub
when I debug the line that it goes to is: where am I going wrong :(
DestCell.Resize(RngToCopy.Rows.Count, _
RngToCopy.Columns.Count).Value _
= RngToCopy.Value
the source workbook is a big file with a lot of data, I tried most of the suggestions when I researched on the error but no luck.
if it helps workbook contains 18 columns and 300k+ rows

Try a different approach, use Copy >> PasteSpecial (values only) :
' 1st: set copy range
With wkbk.Worksheets(1)
Set RngToCopy = .Range("A2:R2", .Cells(.Rows.Count, "A").End(xlUp))
End With
' 2nd: set destination range start position
Set DestCell = DestCell.Offset(RngToCopy.Rows.Count, 0)
' 3rd: use copy>>paste special (values only)
RngToCopy.Copy
DestCell.PasteSpecial xlPasteValues

Related

Moving row from one workbook to another

I am new to StackOverflow, but have been working on this problem for some time, and am pretty stuck. Right now, my code takes 'Name' input from a textbox, and if the data in column A matches the name that was input, it copies data from the entire row in that sheet, copies it to another sheet, then deletes the data from the original sheet, and tells the user how many rows were moved. This code is listed below:
I have two problems. One, I need an error check where if the name that is typed into the textbox does not exist, it displays a messagebox with that message, and two, I need to allow for this code to do what it does, but from seperate workbooks. As in, copy the data from a sheet in one workbook, and move it to a sheet in another workbook. My code only works within the same workbook right now.
Any and all help is appreciated. Thank you in advance.
Private Sub buttonDelete_Click()
'When the Delete button is clicked, the following function is ran to copy the row from Current Services, move it to Cancelled Services
'and then delete the row from Current Services.
Dim wkBk1 As Workbook
Dim wkBk2 As Workbook
Dim xRg As Range
Dim xCell As Range
Dim I As Long
Dim J As Long
Dim K As Long
Dim count As Long
On Error Resume Next
Set wkBk1 = Workbooks.Open("C:\Users\Nathan\Desktop\Sandbox\testMacro.xlsm")
Set wkBk2 = Workbooks.Open("C:\Users\Nathan\Desktop\Sandbox\testMacro2.xlsm")
If Err.Number = 1004 Then
MsgBox "File Does Not Exist"
End If
I = wkBk1.Worksheets("Current Customers").UsedRange.Rows.count
J = Worksheets("Cancelled Services").UsedRange.Rows.count
count = 0
If J = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Cancelled Services").UsedRange) = 0 Then J = 0
End If
Set xRg = Worksheets("Current Customers").Range("A1:A" & I)
On Error Resume Next
Application.ScreenUpdating = False
For K = 1 To xRg.count
If CStr(xRg(K).Value) = Me.fName.Value Then
count = count + 1
xRg(K).EntireRow.Copy Destination:=Worksheets("Cancelled Services").Range("A" & J + 1)
xRg(K).EntireRow.Delete
If CStr(xRg(K).Value) = Me.fName.Value Then
K = K - 1
End If
J = J + 1
End If
Next
Application.ScreenUpdating = True
MsgBox count & " rows moved"
End Sub
EDIT : OK, here is one more wrinkle. What if I wanted to search through four or five different workbooks, and move all of the rows where the conditions are met into one worksheet called 'Cancelled Services' that will be a worksheet in one of the aforementioned workbooks.
There are a LOT of strange things going on in your code, so I've tried to clean it up a bit and left some comments as to why you shouldn't have some things in there. I've addressed the first part of your question, but in order to move rows between workbooks you need to decide what data you're looking to move and where, especially by fully qualifying your ranges using Workbook, or in your case, wkBk1 and wkBk2
Private Sub buttonDelete_Click()
'When the Delete button is clicked, the following function is ran to copy the row from Current Services, move it to Cancelled Services
'and then delete the row from Current Services.
Dim wkBk1 As Workbook, wkBk2 As Workbook
Dim xRg As Range, xCell As Range
Dim I As Long, J As Long, K As Long, count As Long
Dim MyName As String
'Assign our name value here
MyName = Me.fName.Value
'Let's use an error handler instead - this way our Err.Number will actually be triggered
On Error GoTo Handler
Set wkBk1 = Workbooks.Open("C:\Users\Nathan\Desktop\Sandbox\testMacro.xlsm")
Set wkBk2 = Workbooks.Open("C:\Users\Nathan\Desktop\Sandbox\testMacro2.xlsm")
On Error GoTo 0
I = wkBk1.Worksheets("Current Customers").UsedRange.Rows.count
J = Worksheets("Cancelled Services").UsedRange.Rows.count 'Need to add either wkBk1 or wkBk2 to the front of this
'We don't really NEED this, as count is initialized as 0 anyways
'count = 0
If J = 1 Then
'What is the purpose of this? Can it ever even return true if J = 1?
If Application.WorksheetFunction.CountA(Worksheets("Cancelled Services").UsedRange) = 0 Then J = 0
End If
Set xRg = Worksheets("Current Customers").Range("A1:A" & I) 'Need to add either wkBk1 or wkBk2 to the front of this
'Here we check the range for the name. If it's not there, we throw a messsage box and exit the sub
If Not WorksheetFunction.CountIf(xRg, MyName) > 0 Then
MsgBox "Name doesn't exist in the range"
Exit Sub
End If
'Got rid of On Error Resume Next, we don't need it and it's sloppy coding
Application.ScreenUpdating = False
'This whole snippet needs to be changed
'Also since you're deleting rows, you need to step BACKWARDS through this loop
For K = 1 To xRg.count
If CStr(xRg(K).Value) = MyName Then
xRg(K).EntireRow.Copy Destination:=Worksheets("Cancelled Services").Range("A" & J + 1)
xRg(K).EntireRow.Delete
'Why do we have this? We already know this is true?
'If CStr(xRg(K).Value) = MyName Then
K = K - 1
'End If
'Move count to AFTER we've actually moved the row, with On Error Resume Next your count could've gone up without a row being moved...
count = count + 1
J = J + 1
End If
Next
Application.ScreenUpdating = True
MsgBox count & " rows moved"
Handler:
If Err.Number = 1004 Then
MsgBox "File Does Not Exist"
End If
End Sub
This code uses FIND rather than looking at each row. It creates a range of all found rows as it goes and then copies the whole lot over in one hit before deleting the original values. Before ending it tells you how many it found.
This assumes that you have a textbox called fname and button called buttonDelete on a Userform.
Private Sub buttonDelete_Click()
Dim wrkBk1 As Workbook
Dim wrkBk2 As Workbook
Dim sPath As String
Dim wrkSht1 As Worksheet
Dim wrkSht2 As Worksheet
Dim rLastCell_Cur As Range
Dim rLastCell_Can As Range
Dim sNameToSearch As String
Dim rSearchRange As Range
Dim rFound As Range
Dim sFirstAddress As String
Dim lFoundCount As Long
Dim rFoundUnion As Range
sPath = "C:\Users\Nathan\Desktop\Sandbox\"
If Not (FileExists(sPath & "testMacro.xlsm") And FileExists(sPath & "testMacro2.xlsm")) Then
'One of the files doesn't exist so display message and exit.
MsgBox "One of the files does not exist.", vbOKOnly + vbCritical
Else
Set wrkBk1 = Workbooks.Open(sPath & "testMacro.xlsm")
Set wrkBk2 = Workbooks.Open(sPath & "testMacro2.xlsm")
If Not (WorkSheetExists("Current Customers", wrkBk1) And _
WorkSheetExists("Cancelled Services", wrkBk2)) Then
'One of the sheets doesn't exist so display message and exit.
MsgBox "One of the required sheets doesn't exist.", vbOKOnly + vbCritical
Else
'Find the limits of the two sheets.
Set wrkSht1 = wrkBk1.Worksheets("Current Customers")
Set rLastCell_Cur = LastCell(wrkSht1)
Set wrkSht2 = wrkBk2.Worksheets("Cancelled Services")
Set rLastCell_Can = LastCell(wrkSht2).Offset(1) 'We want the cell below the last cell here.
'Grab what we're searching for and where we're searching for it.
sNameToSearch = Me.fName
With wrkSht1
Set rSearchRange = .Range(.Cells(1, 1), .Cells(rLastCell_Cur.Row, 1))
End With
With rSearchRange
'Perform first search.
Set rFound = .Find(What:=sNameToSearch, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext)
'If something was found then we're good to go.
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
lFoundCount = lFoundCount + 1
'Create a union of ranges to copy over.
If rFoundUnion Is Nothing Then
Set rFoundUnion = rFound.EntireRow
Else
Set rFoundUnion = Union(rFoundUnion, rFound.EntireRow)
End If
'Look for the next item.
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
'All instances have been found so copy it all over and then delete the original.
rFoundUnion.Copy wrkSht2.Cells(rLastCell_Can.Row, 1)
rFoundUnion.Delete Shift:=xlUp
End If
MsgBox "Found " & lFoundCount & " occurrences of " & sNameToSearch, vbOKOnly + vbInformation
End With
End If
End If
End Sub
Public Function FileExists(FilePath As String) As Boolean
FileExists = Dir(FilePath) <> ""
End Function
Public Function WorkSheetExists(SheetName As String, Optional WrkBk As Workbook) As Boolean
Dim wrkSht As Worksheet
If WrkBk Is Nothing Then
Set WrkBk = ThisWorkbook
End If
On Error Resume Next
Set wrkSht = WrkBk.Worksheets(SheetName)
WorkSheetExists = (Err.Number = 0)
Set wrkSht = Nothing
On Error GoTo 0
End Function
Public Function LastCell(wrkSht As Worksheet, Optional Col As Long = 0) As Range
Dim lLastCol As Long, lLastRow As Long
On Error Resume Next
With wrkSht
If Col = 0 Then
lLastCol = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
lLastRow = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
Else
lLastCol = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
lLastRow = .Columns(Col).Find("*", , , , xlByColumns, xlPrevious).Row
End If
If lLastCol = 0 Then lLastCol = 1
If lLastRow = 0 Then lLastRow = 1
Set LastCell = wrkSht.Cells(lLastRow, lLastCol)
End With
On Error GoTo 0
End Function
This update to the buttonDelete_Click() procedure will open all Excel files within a specific folder and copy the found name to another file that isn't in that folder.
Private Sub buttonDelete_Click()
Dim colFiles As Collection
Dim vFile As Variant
Dim sTemp As String
Dim wrkBk1 As Workbook
Dim wrkBk2 As Workbook
Dim sPath As String
Dim wrkSht1 As Worksheet
Dim wrkSht2 As Worksheet
Dim rLastCell_Cur As Range
Dim rLastCell_Can As Range
Dim sNameToSearch As String
Dim rSearchRange As Range
Dim rFound As Range
Dim sFirstAddress As String
Dim lFoundCount As Long
Dim rFoundUnion As Range
sPath = "C:\Users\Nathan\Desktop\Sandbox\"
'Put the full path of each Excel file in to a collection.
'These contain the "Current Customers" sheet.
Set colFiles = New Collection
sTemp = Dir$(sPath & "*.xls*")
Do While Len(sTemp) > 0
colFiles.Add sPath & sTemp
sTemp = Dir$
Loop
If Not (FileExists("C:\Users\Nathan\Desktop\Cancelled.xlsx")) Then
'Cancelled Services book doesn't exist.
MsgBox "Cancelled Services doesn't exist.", vbOKOnly + vbCritical
Else
'Open Cancelled Services before working through the collection of Current Customers.
Set wrkBk2 = Workbooks.Open("C:\Users\Nathan\Desktop\Cancelled.xlsx")
Set wrkSht2 = wrkBk2.Worksheets("Cancelled Services")
For Each vFile In colFiles
Set wrkBk1 = Workbooks.Open(vFile)
'The file will only be processed if it contains "Current Customers" sheet.
If WorkSheetExists("Current Customers", wrkBk1) Then
Set wrkSht1 = wrkBk1.Worksheets("Current Customers")
Set rLastCell_Can = LastCell(wrkSht2).Offset(1)
Set rLastCell_Cur = LastCell(wrkSht1)
'Grab what we're searching for and where we're searching for it.
sNameToSearch = Me.fName
With wrkSht1
Set rSearchRange = .Range(.Cells(1, 1), .Cells(rLastCell_Cur.Row, 1))
End With
With rSearchRange
'Perform first search.
Set rFound = .Find(What:=sNameToSearch, LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlNext)
'If something was found then we're good to go.
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
lFoundCount = lFoundCount + 1
'Create a union of ranges to copy over.
If rFoundUnion Is Nothing Then
Set rFoundUnion = rFound.EntireRow
Else
Set rFoundUnion = Union(rFoundUnion, rFound.EntireRow)
End If
'Look for the next item.
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
'All instances have been found so copy it all over and then delete the original.
rFoundUnion.Copy wrkSht2.Cells(rLastCell_Can.Row, 1)
rFoundUnion.Delete Shift:=xlUp
End If
End With
End If
Set rFound = Nothing
Set rFoundUnion = Nothing
sFirstAddress = ""
wrkBk1.Close SaveChanges:=True
Next vFile
MsgBox "Found " & lFoundCount & " occurrences of " & sNameToSearch, vbOKOnly + vbInformation
End If
End Sub
To answer the first question about checking if a sheet exist in a workbook, you can use a Function like this:
Public Function U_W_DoesWorksheetExist(ByVal sheetname As String, aWorkbook As Workbook) As Boolean
On Error Resume Next
U_W_DoesWorksheetExist = (Not aWorkbook.Sheets(sheetname) Is Nothing)
On Error GoTo 0
End Function
Now, when you reference the destination, you are saying just Worksheets("Cancelled Services") and the Macro will assume the ActiveWorkook as the main workbook where to copy the Sheet. You need to reference the Workbook where the sheet you are pasting is located. See if the code below works for you and take a look at the comments I added on it:
Private Sub buttonDelete_Click()
'When the Delete button is clicked, the following function is ran to copy the row from Current Services, move it to Cancelled Services
'and then delete the row from Current Services.
Dim wkBk1 As Workbook
Dim wkBk2 As Workbook
Dim xRg As Range
Dim xCell As Range
Dim i As Long
Dim J As Long
Dim K As Long
Dim count As Long
Dim arrFromWorkbookPath(1 To 4) As String
Dim c As Long
' If you need more than 4 rearrange the Array to as many as you need.
arrFromWorkbookPath(1) = "C:\Users\Nathan\Desktop\Sandbox\FromWB1.xlsm"
arrFromWorkbookPath(4) = "C:\Users\Nathan\Desktop\Sandbox\FromWB2.xlsm"
arrFromWorkbookPath(3) = "C:\Users\Nathan\Desktop\Sandbox\FromWB3.xlsm"
arrFromWorkbookPath(4) = "C:\Users\Nathan\Desktop\Sandbox\FromWB4.xlsm"
' The Workbook were you will be pasting the sheets.
Set wkBk2 = Workbooks.Open("C:\Users\Nathan\Desktop\Sandbox\testMacro2.xlsm")
For c = LBound(arrFromWorkbookPath) To UBound(arrFromWorkbookPath)
On Error Resume Next
' Open the Workbook from where the sheet will be copied from.
Set wkBk1 = Workbooks.Open(arrFromWorkbookPath(c))
If Err.Number = 1004 Then
MsgBox "File Does Not Exist"
Exit Sub
End If
' USE PROCEDURE LIKE THIS TO CHECK "Current Customers" in wkBk1 and Cancelled Services in wkBk2.
If U_W_DoesWorksheetExist("Current Customers", wkBk1) And U_W_DoesWorksheetExist("Cancelled Services", wkBk1) Then
i = wkBk1.Worksheets("Current Customers").UsedRange.Rows.count
J = wkBk2.Worksheets("Cancelled Services").UsedRange.Rows.count
count = 0
If J = 1 Then
If Application.WorksheetFunction.CountA(wkBk2.Worksheets("Cancelled Services").UsedRange) = 0 Then J = 0
End If
Set xRg = wkBk1.Worksheets("Current Customers").Range("A1:A" & i)
On Error Resume Next
Application.ScreenUpdating = False
For K = 1 To xRg.count
If CStr(xRg(K).Value) = Me.fName.Value Then
count = count + 1
' Here you need to specify the workbook, not just the sheet wkBk2.Worksheets("Cancelled Services").
xRg(K).EntireRow.Copy Destination:=wkBk2.Worksheets("Cancelled Services").Range("A" & J + 1)
xRg(K).EntireRow.Delete
If CStr(xRg(K).Value) = Me.fName.Value Then
K = K - 1
End If
J = J + 1
End If
Next
wkBk1.Close False
Else
' Display error if the sheet doesn't exist.
MsgBox "Sheets Current Customers or Cancelled Services don't exists."
End If
Next c
Application.ScreenUpdating = True
End Sub

Excel 2013 cannot find and open the file in ThisWorkbook directory

The following issue occured to me. I use MS Excel 2013.
With the macro below I tried to find those accounts (which meets the criteria "In scope", e.g. account 12345678), to copy them, to search in the same folder (where ThisWorkbook is), to find another excel file which has as name the number of account (e.g. "12345678.xlsx") and to open it.
After the proposed corrections below, my macro finds and opens the desired file. But now the problem is that no actions can be performed on it: copy, paste, etc.
Could you please help on this?
Sub FileFinder()
'Excel variables:
Dim RngS As Excel.Range
Dim wbResults As Workbook
'Go to the column with specific text
Worksheets("Accounts source data").Activate
X = 3
Y = 25
While Not IsEmpty(Sheets("Accounts source data").Cells(X, Y))
Sheets("Accounts source data").Cells(X, Y).Select
If ActiveCell = "In scope" Then
Sheets("Accounts source data").Cells(X, Y - 22).Select
'Copy the account in scope
Set RngS = Selection
Selection.Copy
'Search, in same directory where the file is located, the file with that account (file comes with account number as name)
sDir = Dir$(ThisWorkbook.Path & "\" & RngS & ".xlsx", vbNormal)
Set oWB = Workbooks.Open(ThisWorkbook.Path & "\" & sDir)
'Here is where my error occurs
'[Run-time error 5: Invalid procedure call or argument]
Sheet2.Cells("B27:B30").Copy
oWB.Close
End If
X = X + 1
Wend
End Sub
Try the code below, I have my explanation and questions for you in the code (as commnets):
Option Explicit
Sub FileFinder()
' Excel variables:
Dim wbResults As Workbook
Dim oWB As Workbook
Dim Sht As Worksheet
Dim RngS As Range
Dim sDir As String
Dim LastRow As Long
Dim i As Long, Col As Long
Col = 25
' set ThisWorkbook object
Set wbResults = ThisWorkbook
' set the worksheet object
Set Sht = Worksheets("Accounts source data")
With Sht
' find last row with data in Column "Y" (Col = 25)
LastRow = .Cells(.Rows.Count, 25).End(xlUp).Row
For i = 3 To LastRow
If .Cells(i, Col) = "In scope" Then
' Set the range directly, no need to use `Select` and `Selection`
Set RngS = .Cells(i, Col).Offset(, -22)
' Search, in same directory where the file is located, the file with that account (file comes with account number as name)
sDir = Dir$(ThisWorkbook.Path & "\" & RngS.Value & ".xlsx", vbNormal)
Set oWB = Workbooks.Open(ThisWorkbook.Path & "\" & sDir)
oWB.Worksheets("Report").Range("B27:B30").Copy
' *** Paste in ThisWorkbook, in my exmaple "Sheet2" <-- modify to your needs
wbResults.Worksheets("Sheet2").Range("C1").PasteSpecial Paste:=xlPasteAll, Transpose:=True
oWB.Close SaveChanges:=False
' sDir = Dir$
' clear objects
Set RngS = Nothing
Set oWB = Nothing
End If
Next i
End With
End Sub

errors pulling key information from multiple excel workbooks

I am attempting to write a macro in a workbook whose purpose is to display the key information from each of a set of excel files. the first column contains the name of the file which will be used in the code.
the code I have written so far should loop through the list of 11 file names in the summary sheet and pull the info called from cell E21 in each of those files and place it in cell Hx in the summary sheet.
I have had no luck getting it to work so far, my first error im getting is "invalid Qualifier" on the line that says "MySheet". I know that there are alot of other mistakes here as I have never attempted to write a sub that pulls from other closed workbooks.
My code is as follows:
Option Explicit
Sub OEEsummmary()
Dim Gcell As Range
Dim Txt$, MyPath$, MyWB$, MySheet$
Dim myValue As Integer
Dim x As Long
Dim v As Variant, r As Range, rWhere As Range
MyPath = "L:\Manufacturing Engineering\Samuel Hatcher\"
x = 2
MySheet = ActiveSheet.Name
Application.ScreenUpdating = False
Do While MySheet.Range("A" & x).Value <> ""
MyWB = MySheet.Range("A" & x).Txt
Workbooks.Open Filename:=MyPath & MyWB
Set Gcell = ActiveSheet.Range("E21")
With ThisWorkbook.ActiveSheet.Range("A" & x)
.Value = "Item"
.Offset(7, 0).Value = Gcell.Value
End With
ActiveWorkbook.Close savechanges:=False
x = x + 1
Loop
End Sub
Ive looked at what an invalid qualifier error is and i dont understand what i have wrong with that part of my code. Any help with this and any other blinding errors would be greatly appreciated!
The issue I see that's causing the Invalid Qualifier error is that you are declaring MySheet as a string, but trying to use it as a Worksheet object. Below I've declared it as a worksheet and set it to the Activesheet. I also changed the ThisWorkbook.ActiveSheet reference to MySheet, which I think is what you want. Also changed Txt to Text:
Sub OEEsummmary()
Dim Gcell As Range
Dim MySheet As Worksheet
Dim Txt$, MyPath$, MyWB$
Dim myValue As Integer
Dim x As Long
Dim v As Variant, r As Range, rWhere As Range
MyPath = "L:\Manufacturing Engineering\Samuel Hatcher\"
x = 2
Set MySheet = ActiveSheet
Application.ScreenUpdating = False
Do While MySheet.Range("A" & x).Value <> ""
MyWB = MySheet.Range("A" & x).Text
Workbooks.Open Filename:=MyPath & MyWB
Set Gcell = ActiveSheet.Range("E21")
With MySheet.Range("A" & x)
.Value = "Item"
.Offset(7, 0).Value = Gcell.Value
End With
ActiveWorkbook.Close savechanges:=False
x = x + 1
Loop
End Sub

Error at attempt to copy data from external workbook with several worksheets to another workbook

The problem: I am trying to copy data from one workbook to another.
Lets say I have a workbook (called DATA) with several worksheets filled with data. Each column of data has a unique heading (all headings on the same row).
On the other hand I have another workbook (called REPORT) with one worksheet that contains only the heading of the data (in one row). They are not in the same order as in DATA workbook. For example I have 3 headings in REPORT worksheet that can be found in different worksheets in DATA workbook.
I need to loop through all the worksheets in the DATA workbook and copy paste the whole column to the REPORT worksheet when the same heading is found.
This image may help to understand. Explanation
My first attempt:
Dim MyFile As String
Dim ws As Worksheet
''Workbook that contains one worksheet with all the headings ONLY NO DATA
Dim TargetWS As Worksheet
Set TargetWS = ActiveSheet
Dim TargetHeader As Range
''Location of Headers I want to search for in source file
Set TargetHeader = TargetWS.Range("A1:G1")
''Source workbook that contains multiple sheets with data and headings _
not in same order as target file
Dim SourceWB As Workbook
Set SourceWB = Workbooks("Source.xlsx")
Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
Dim SourceCell As Range
''Stores the col of the found value and the last row of data in that col
Dim RealLastRow As Long
Dim SourceCol As Integer
''Looping through all worksheets in source file, looking for the heading I want _
then copying that whole column to the target file I have
For Each ws In SourceWB.Sheets
ws.Activate
For Each Cell In TargetHeader
If Cell.Value <> "" Then
Set SourceCell = Rows(SourceHeaderRow).Find _
(Cell.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
SourceCol = SourceCell.Column
RealLastRow = Columns(SourceCol).Find("*", LookIn:=xlValues, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
If RealLastRow > SourceHeaderRow Then
Range(Cells(SourceHeaderRow + 1, SourceCol), Cells(RealLastRow, _
SourceCol)).Copy
TargetWS.Cells(2, Cell.Column).PasteSpecial xlPasteValues
End If
End If
End If
Next
Next
I am getting an error of Application-defined or object-defined error Run-time 1004. Is there something wrong with my logic/syntax..?
Please help I am so bad in VBA.
Thanks in advance!
your last edited code works
but you're making unnecessary checks and I'd suggest you to loop through each sheet header and check if it exists in TargetHeader range to possibly subsequently copy its column to SourceWB
furthermore you may want to have your code more robust and check for actual wanted workbooks/worksheets existence before attempting to set variables to them
like follows:
Option Explicit
Sub main()
Dim SourceWB As Workbook
Dim ws As Worksheet, TargetWS As Worksheet
Dim TargetHeader As Range, cell As Range, SourceCell As Range
Dim SourceHeaderRow As Integer: SourceHeaderRow = 1
''Source workbook that contains multiple sheets with data and headings _
not in same order as target file
Set SourceWB = GetWb("Source.xlsx")
If SourceWB Is Nothing Then Exit Sub
''Workbook that contains one worksheet with all the headings ONLY NO DATA
'Set TargetWS = ActiveSheet
Set TargetWS = GetWs("REPORT") 'it will get the first worksheet (if any) in "REPORT" workbook (if open)
If TargetWS Is Nothing Then Exit Sub
''Location of Headers I want to search for in source file
Set TargetHeader = TargetWS.Range("A1:G1")
''Looping through all worksheets in source file, looking for the heading I want _
then copying that whole column to the target file I have
For Each ws In SourceWB.Sheets
For Each cell In ws.Rows(SourceHeaderRow).SpecialCells(xlCellTypeConstants, xlTextValues)
Set SourceCell = TargetHeader.Find(cell.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not SourceCell Is Nothing Then
Range(cell.Offset(1), ws.Cells(ws.Rows.Count, cell.Column).End(xlUp)).Copy
SourceCell.Offset(1).PasteSpecial xlPasteValues
End If
Next
Next
End Sub
Function GetWb(wbName As String) As Workbook
On Error Resume Next
Set GetWb = Workbooks(wbName)
On Error GoTo 0
If GetWb Is Nothing Then MsgBox "Sorry, the workbook '" & wbName & "' isn't open" & vbCrLf & vbCrLf & "Please open it and run the macro again"
End Function
Function GetWs(wbName As String, Optional wsName As Variant) As Worksheet
Dim wb As Workbook
Dim ws As Worksheet
Set wb = GetWb(wbName)
If wb Is Nothing Then Exit Function
On Error Resume Next
If IsMissing(wsName) Then
Set GetWs = wb.Worksheets(1) ' if no ws name passed then get the first one
Else
Set GetWs = wb.Worksheets(wsName)
End If
On Error GoTo 0
If GetWs Is Nothing Then MsgBox "Sorry, the worksheet '" & wsName & "0 isn't in '" & wb.Name & "'" & vbCrLf & vbCrLf & "Please open a valid workbook and run the macro again"
End Function

Import data from different Workbooks VBA

I have a code see below to import data from different workbooks inside one folder. I try it and it works perfectly however I was wondering if someone could help me to improve it.
I explain: "zmaster.xlms" workbook is the one where all data are past in sheet one. In this same workbook in sheet2 i have a table like this:
Where the column "Excel Column code" is where the data should be past (in the "zmaster.xlms") and "Form Cell Code" correspond to the cells which should be copy from every workbooks (which are in the same file in my desktop).
Question: How To say to the macro to look at the table and copy the cell K26 and past it in the columnA of the zmaster file and loop until the end of the table?
Dim MyFile As String
Dim erow
Dim Filepath As String
Filepath = "C:\Desktop\New folder\"
MyFile = Dir(Filepath)
Do While Len(MyFile) > 0
If MyFile = "zmaster.xlsm" Then
Exit Sub
End If
Workbooks.Open (Filepath & MyFile)
' Range("A1:D1").Copy
ActiveWorkbook.Close
erow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range(Cells(erow, 1), Cells(erow, 4))
MyFile = Dir
Loop
End Sub
Thank you in advance for your help!
All you need to do is to loop through the cells in sheet 2 (zmaster.xlsm). Have a look at example code. Please, read comments.
[EDIT]
Code has been updated!
Option Explicit
'assuming that:
'- "Excel Column Code" is in column A
'- "Form Cell Code" is in column B
'in zmaster.xlsm!Sheet2
Sub UpdateData()
Dim sFile As String, sPath As String
Dim srcWbk As Workbook, dstWbk As Workbook
Dim srcWsh As Worksheet, dstWsh As Worksheet, infoWsh As Worksheet
Dim i As Long, j As Long, k As Long
On Error GoTo Err_UpdateData
Set dstWbk = ThisWorkbook
Set dstWsh = dstWbk.Worksheets("Sheet1")
Set infoWsh = dstWbk.Worksheets("Sheet2")
sPath = "C:\Desktop\New folder\"
sFile = Dir(sPath)
Do While Len(sFile) > 0
If sFile = "zmaster.xlsm" Then
GoTo SkipNext
End If
Set srcWbk = Workbooks.Open(sPath & sFile)
Set srcWsh = srcWbk.Worksheets(1)
i = 2
'loop through the information about copy-paste method
Do While infoWsh.Range("A" & i) <> ""
'get first empty row, use "Excel Column Code" to get column name
j = GetFirstEmpty(dstWsh, infoWsh.Range("A" & i))
'copy data from source sheet to the destination sheet
'use "Form Cell Code" to define destination cell
srcWsh.Range(infoWsh.Range("B" & i)).Copy dstWsh.Range(infoWsh.Range("A" & i) & j)
i = i + 1
Loop
srcwbk.Close SaveChanges:=False
SkipNext:
sFile = Dir
Loop
Exit_UpdateData:
On Error Resume Next
Set srcWsh = Nothing
Set dstWsh = Nothing
Set srcWbk = Nothing
Set dstWbk = Nothing
Exit Sub
Err_UpdateData:
MsgBox Err.Description, vbExclamation, Err.Number
Resume Exit_UpdateData
End Sub
'returns first empty row in a destination sheet based on column name
Function GetFirstEmpty(ByVal wsh As Worksheet, Optional ByVal sCol As String = "A") As Long
GetFirstEmpty = wsh.Range(sCol & wsh.Rows.Count).End(xlUp).Row + 1
End Function
At the moment you code
erow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Sheet1").Range(Cells(erow, 1), Cells(erow, 4))
is simply copying columns A to D of the first row of data in the source worksheet to a new row in the destination worksheet.
I'm assuming that you still want to create a new single row, but that you want the table on sheet2 to define which cells are put into which column of the new row.
you need to write something like this (which is untested):
Sub YourCode()
Dim MyFile As String
Dim erow
Dim Filepath As String
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim wsDestination As Worksheet
Dim rngMapping As Range
Dim DestinationRow As Long
Dim cell As Range
Filepath = "C:\Desktop\New folder\"
MyFile = Dir(Filepath)
Set wsDestination = ActiveWorkbook.Sheet1
' Named range "MappingTableFirstColumn" is defined as having the first column in the sheet2 table and all the rows of the table.
Set rngMapping = ActiveWorkbook.Names("MappingTable").RefersToRange
Do While Len(MyFile) > 0
If MyFile = "zmaster.xlsm" Then
Exit Sub
End If
Set wbSource = Workbooks.Open(Filepath & MyFile)
Set wsSource = wbSource.Sheets("Sheet1")
DestinationRow = wsDestination.Cells(wsDestination.Rows.Count, 1).End(xlUp).Offset(1, 0).Row
For Each cell In rngMapping
wsDestination.Range(cell.Value & DestinationRow) = wsSource.Range(cell.Offset(0, 1)).Value
Next cell
MyFile = Dir
Loop
ActiveWorkbook.Close
End Sub