Reputation: 3
I have to match a value in 1st workbook to a column of data in the 2nd workbook, then copy specific cells in 1st workbook and paste it in specific cells (same row as match data) in second workbook.
Here is the code I've come up with so far, but it doesn't work, and returns a run time error 1004: application-defined or object-defined error.
Dim FindNo As String
Dim X As Long, LastRow As Long
Dim FoundCell As Range
Dim FColumn As Integer, FRow As Integer
Dim WB1 As Workbook, SHT1 As Worksheet
Dim WB2 As Workbook, SHT2 As Worksheet
Application.ScreenUpdating = False
Set WB1 = ThisWorkbook
Set WB2 = Workbooks.Open("Z:\ISO MTSO DOCUMENTS (New Templates)\Incident & Accident Monitoring (2016 and 2017)\Incident Monitoring 2016 and 2017.xlsx")
Set SHT1 = WB1.Sheets("F-IMS-11")
Set SHT2 = WB2.Sheets("2017")
FindNo = SHT1.Range("Q1").Value
LastRow = SHT2.Range("C" & Rows.Count).End(xlUp).Row
For X = 3 To LastRow
If SHT2.Cells(X, "C") = FindNo Then
FRow = FoundCell.Row
FColumn = FoundCell.Column
SHT2.Range(Cells(FColumn + 14, FRow)) = SHT1.Cells(13, 1)
SHT2.Range(Cells(FColumn + 15, FRow)) = SHT1.Cells(7, 6)
SHT2.Range(Cells(FColumn + 17, FRow)) = SHT1.Cells(46, 2)
SHT2.Range(Cells(FColumn + 18, FRow)) = SHT1.Cells(58, 2)
SHT2.Range(Cells(FColumn + 19, FRow)) = SHT1.Cells(58, 13)
End If
Application.CutCopyMode = False
Next X
SHT2.Columns(17).WrapText = True
SHT2.Columns(20).WrapText = True
SHT2.Columns(21).WrapText = True
WB2.Save
WB2.Close
Application.ScreenUpdating = True
It would great to hear suggestions, as I don't really have a good background in VBA, and I just tried to modify most of the codes.
Upvotes: 0
Views: 100
Reputation: 29421
you're not setting FoundCell
before exploiting it, so you should add some Set FoundCell = SHT2.Cells(X, "C")
right after If SHT2.Cells(X, "C") = FindNo Then
. But it's a waste of crossed references since you already know that matched cell row and column indexes are, respectively X
and 3
.
furthermore you may want to adopt With-End With
syntax to reference an object (a workbook
, a worksheet
a range
...) and access its methods or properties by means of a simple dot (.
). this will give you more control over proper object referencing and relieve you from many variables declaring and using.
finally you should avoid repeating access to the same objects within a loop when those objects doesn't change
for all what above you could consider the following refactoring
Option Explicit
Sub main()
Dim FindNo As String
Dim X As Long
Dim val1 As Variant, val2 As Variant, val3 As Variant, val4 As Variant, val5 As Variant
Application.ScreenUpdating = False
With ThisWorkbook.Sheets("F-IMS-11") '<--| reference Worksheet object directly from "WB1" workbook
FindNo = .Range("Q1").Value
val1 = .cells(13, 1)
val2 = .cells(7, 6)
val3 = .cells(46, 2)
val4 = .cells(58, 2)
val5 = .cells(58, 13)
End With
With Workbooks.Open("Z:\ISO MTSO DOCUMENTS (New Templates)\Incident & Accident Monitoring (2016 and 2017)\Incident Monitoring 2016 and 2017.xlsx") '<--| open and reference wanted "WB2" workbook
With .Sheets("2017") '<--| reference its "2017" worksheet
For X = 3 To .Range("C" & .Rows.Count).End(xlUp).Row '<--| loop through its column "C" cells from row 3 down to last not empty one
If .cells(X, "C") = FindNo Then
.cells(X, 17) = val1
.cells(X, 18) = val2
.cells(X, 20) = val3
.cells(X, 21) = val4
.cells(X, 22) = val5
End If
Next X
Range("Q:Q , T:T, U:U").WrapText = True
End With
.Close True
End With
Application.ScreenUpdating = True
End Sub
Upvotes: 1
Reputation: 3068
Within your X = 3 to LastRow
loop you are populating variables using the FoundRow
range object but FoundRow has not been set.
Try replacing that loop with this:
For X = 3 To LastRow
If SHT2.Cells(X, "C") = FindNo Then
Set FoundCell = SHT2.Cells(X, "C")
FRow = FoundCell.Row
FColumn = FoundCell.Column
Set FoundCell = Nothing
SHT2.Range(Cells(FColumn + 14, FRow)) = SHT1.Cells(13, 1)
SHT2.Range(Cells(FColumn + 15, FRow)) = SHT1.Cells(7, 6)
SHT2.Range(Cells(FColumn + 17, FRow)) = SHT1.Cells(46, 2)
SHT2.Range(Cells(FColumn + 18, FRow)) = SHT1.Cells(58, 2)
SHT2.Range(Cells(FColumn + 19, FRow)) = SHT1.Cells(58, 13)
End If
Application.CutCopyMode = False
Next X
Upvotes: 0