i m trying to loop through project components and if the result is 3 (Userform) to loop through teach Userform and get it's control name and properties but i receive an error in the second for each.
any help will appreciate!!
Option Explicit
Sub Find_From_control()
Dim Control As Control
Dim Component As Object
Dim LastRow As Long
For Each Component In ThisWorkbook.VBProject.VBComponents
If Component.Type = 3 Then
For Each Control In Form.Controls
LastRow = wsControl.Range("I" & Rows.Count).End(xlUp).Row
If TypeName(Control) = "TabStrip" Or TypeName(Control) = "ScrollBar" Or TypeName(Control) = "SpinButton" Or TypeName(Control) = "MultiPage" Or TypeName(Control) = "TextBox" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = Control.Type
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
wsControl.Range("M" & LastRow + 1).Value = Control.TabIndex
ElseIf TypeName(Control) = "Image" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = Control.Type
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
ElseIf TypeName(Control) = "Frame" Or TypeName(Control) = "ToggleButton" Or TypeName(Control) = "OptionButton" Or TypeName(Control) = "CheckBox" Or TypeName(Control) = "Label" Or TypeName(Control) = "CommandButton" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = Control.Type
wsControl.Range("K" & LastRow + 1).Value = Control.Caption
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
wsControl.Range("M" & LastRow + 1).Value = Control.TabIndex
ElseIf TypeName(Control) = "ListBox" Or TypeName(Control) = "ComboBox" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = Control.Type
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
wsControl.Range("M" & LastRow + 1).Value = Control.TabIndex
wsControl.Range("N" & LastRow + 1).Value = Control.ColumnCount
End If
Next
End If
Next
End Sub
The Userform is the Component Component.Designer.
Control.Type is not a valid property, use TypeName(Control) instead.
Sub Find_From_control()
Dim Control As Control
Dim Component As Object
Dim Form As UserForm
Dim LastRow As Long
For Each Component In ThisWorkbook.VBProject.VBComponents
If Component.Type = 3 Then
Set Form = Component.Designer
For Each Control In Form.Controls
LastRow = wsControl.Range("I" & Rows.count).End(xlUp).Row
If TypeName(Control) = "TabStrip" Or TypeName(Control) = "ScrollBar" Or TypeName(Control) = "SpinButton" Or TypeName(Control) = "MultiPage" Or TypeName(Control) = "TextBox" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = TypeName(Control)
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
wsControl.Range("M" & LastRow + 1).Value = Control.TabIndex
ElseIf TypeName(Control) = "Image" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = TypeName(Control)
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
ElseIf TypeName(Control) = "Frame" Or TypeName(Control) = "ToggleButton" Or TypeName(Control) = "OptionButton" Or TypeName(Control) = "CheckBox" Or TypeName(Control) = "Label" Or TypeName(Control) = "CommandButton" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = TypeName(Control)
wsControl.Range("K" & LastRow + 1).Value = Control.Caption
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
wsControl.Range("M" & LastRow + 1).Value = Control.TabIndex
ElseIf TypeName(Control) = "ListBox" Or TypeName(Control) = "ComboBox" Then
wsControl.Range("I" & LastRow + 1).Value = Control.Name
wsControl.Range("J" & LastRow + 1).Value = TypeName(Control)
wsControl.Range("L" & LastRow + 1).Value = Control.Tag
wsControl.Range("M" & LastRow + 1).Value = Control.TabIndex
wsControl.Range("N" & LastRow + 1).Value = Control.ColumnCount
End If
Next
End If
Next
End Sub
I tried to 1) Centre and underline the Column E and F in Order List sheet, from line 22 up to the blank line. 2) Bold and centre the VAT and Total in the spreadsheet. 3) Clear Column G28 afterwards in the other sheets after generate Order List. However, it is not underlined or centralised or bolded. Could you please take a look for me? Here is my code below. Many thanks
Option Explicit
Sub copy_info()
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
With Sheets("Order List")
.Cells.Clear
.Range("A21") = "PART CODE"
.Range("B21") = "DESCRIPTION"
.Range("C21") = "PRICE"
.Range("D21") = "QUANTITY"
.Range("E21") = "NET AMOUNT"
.Range("F21") = "SHEET NAME"
.Range("A21:F21").Font.Bold = True
End With
j = 22
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Order List" And sh.Name <> "INDEX" And sh.Name <> "SELECTOR" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 28 To lastRow
If sh.Range("G" & i) > 0 Then
sh.Range("b" & i).Copy Destination:=Worksheets("Order List").Range("A" & j)
sh.Range("e" & i & ":g" & i).Copy Destination:=Worksheets("Order List").Range("B" & j)
Sheets("Order List").Range("E" & j) = Sheets("Order List").Range("C" & j) * Sheets("Order List").Range("D" & j)
Sheets("Order List").Range("F" & j) = sh.Name
Sheets("Order List").Range("B" & j + 1) = ""
Sheets("Order List").Range("B" & j + 2) = "VAT".bold.center
Sheets("Order List").Range("E" & j + 1) = ""
Sheets("Order List").Range("E" & j + 2) = Application.WorksheetFunction.Sum(Columns("E:E"))
Sheets("Order List").Range("B" & j + 3) = "TOTAL".bold.center Sheets("Order List").Range("E" & j + 3) = Application.WorksheetFunction.Sum(Columns("E:E"))
j = j + 1
End If
Next i
End If
Next sh
Sheets("Order List").Columns("A").AutoFit
Sheets("Order List").Columns("B").ColumnWidth = 90
Sheets("Order List").Columns("C:D").AutoFit
Sheets("Order List").Columns("E:F").AutoFit.Underline.Center
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Order List" And sh.Name <> "INDEX" And sh.Name <> "SELECTOR" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 28 To lastRow
If sh.Range("G" & i) > 0 Then
sh.Range("G" & i).Select
Selection.ClearContents
End If
Next i
End If
Next sh
End Sub
That's a bit strange - you have Option Explicit on the top and thus your code should not be working at all, because of the compiling errors. The VBEditor should show you where they are exactly, once you try to run the code.
Here is one example:
In stead of:
Sheets("Order List").Range("B" & j + 2) = "VAT".bold.center
Write:
Sheets("Order List").Range("B" & j + 2).value = "VAT"
Sheets("Order List").Range("B" & j + 2).Font.Bold = True
Sheets("Order List").Range("B" & j + 2).HorizontalAlignment = xlCenter
Then you can improve it further like this:
With Sheets("Order List").Range("B" & j + 2)
.value = "VAT"
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
Or even write a separate function, to which you are passing only the range and the string.
You are trying to do everything at the same time(bold and center in the first part, center and underline at the bottom). This doesn't work in VBA. It is necessary to take just one action after another.
One possible solution to your problem could be this:
Sub copy_info()
Dim i As Long, j As Long, lastRow As Long
Dim sh As Worksheet
With Sheets("Order List")
.Cells.Clear
.Range("A21") = "PART CODE"
.Range("B21") = "DESCRIPTION"
.Range("C21") = "PRICE"
.Range("D21") = "QUANTITY"
.Range("E21") = "NET AMOUNT"
.Range("F21") = "SHEET NAME"
.Range("A21:F21").Font.Bold = True
End With
j = 22
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Order List" And sh.Name <> "INDEX" And sh.Name <> "SELECTOR" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 28 To lastRow
If sh.Range("G" & i) > 0 Then
sh.Range("b" & i).Copy Destination:=Worksheets("Order List").Range("A" & j)
sh.Range("e" & i & ":g" & i).Copy Destination:=Worksheets("Order List").Range("B" & j)
Sheets("Order List").Range("E" & j) = Sheets("Order List").Range("C" & j) * Sheets("Order List").Range("D" & j)
Sheets("Order List").Range("F" & j) = sh.Name
Sheets("Order List").Range("B" & j + 1) = ""
Sheets("Order List").Range("B" & j + 2) = "VAT"
Sheets("Order List").Range("B" & j + 2).Font.Bold = True
Sheets("Order List").Range("B" & j + 2).HorizontalAlignment = xlCenter
Sheets("Order List").Range("E" & j + 1) = ""
Sheets("Order List").Range("E" & j + 2) = Application.WorksheetFunction.Sum(Columns("E:E"))
Sheets("Order List").Range("B" & j + 3) = "TOTAL"
**Sheets("Order List").Range("B" & j + 3).Font.Bold = True
Sheets("Order List").Range("B" & j + 3).HorizontalAlignment = xlCenter**
Sheets("Order List").Range("E" & j + 3) = Application.WorksheetFunction.Sum(Columns("E:E"))
j = j + 1
End If
Next i
End If
Next sh
Sheets("Order List").Columns("A").AutoFit
Sheets("Order List").Columns("B").ColumnWidth = 90
Sheets("Order List").Columns("C:D").AutoFit
Sheets("Order List").Columns("E:F").AutoFit
Sheets("Order List").Columns("E:F").HorizontalAlignment = xlCenter
Sheets("Order List").Columns("E:F").Font.Underline = xlUnderlineStyleSingle
For Each sh In ActiveWorkbook.Sheets
If sh.Name <> "Order List" And sh.Name <> "INDEX" And sh.Name <> "SELECTOR" Then
lastRow = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
For i = 28 To lastRow
If sh.Range("G" & i) > 0 Then
sh.Range("G" & i).Select
Selection.ClearContents
End If
Next i
End If
Next sh
End Sub
I am comparing two column D and E in my sheet which are containing Dates.
The column E has date and sometime there are no Dates and sometime it has X, in the row. I get an runtime error
type mismatch
Could anyone suggest what is wrong with my code. ?
Sub datecompare()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Dim zWeeks As Double, zcolour As Long
Dim Ztext As String
Set ws = Sheets("Preparation Sheet")
With ws
lRow = .range("D" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow
zWeeks = DateDiff("ww", .range("E" & i).Value, .range("D" & i).Value)
If .range("A" & i).Value <> "" And .range("B" & i).Value <> "" And .range("E" & i).Value = "" Then
Ztext = "remaining"
zcolour = vbYellow
Cells(i, 7) = "Yellow"
ElseIf .range("B" & i).Value = "" And .range("E" & i).Value = "" Then
GoTo nextrow
ElseIf zWeeks < 4 Then
Ztext = " on time"
zcolour = vbGreen
Cells(i, 7) = "Green"
ElseIf zWeeks > 8 Then
Ztext = " delayed"
zcolour = vbRed
Cells(i, 7) = "Red"
ElseIf zWeeks > 4 < 8 Then
Ztext = "remaining"
zcolour = vbYellow
Cells(i, 7) = "Yellow"
End If
With .range("F" & i)
.Value = Ztext
.Interior.Color = zcolour
End With
nextrow:
Next i
End With
End Sub
The error occurs at
GoTo nextrow
and it jumps to next, without running through the in between code.
I think, the code woult to be like this.
Sub datecompare()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Dim zWeeks As Double, zcolour As Long
Dim Ztext As String
Set ws = Sheets("Preparation Sheet")
'Cells.Interior.Color = xlNone
With ws
lRow = .Range("D" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow
If IsDate(.Range("E" & i).Value) And IsDate(.Range("D" & i).Value) Then
Else
GoTo nextrow
End If
zWeeks = DateDiff("ww", .Range("E" & i).Value, .Range("D" & i).Value)
If .Range("A" & i).Value <> "" And .Range("B" & i).Value <> "" And .Range("E" & i).Value = "" Then
Ztext = "remaining"
zcolour = vbYellow
Cells(i, 7) = "Yellow"
Else '<~~ .Range("A" & i).Value <> "" And .Range("B" & i).Value <> "" And .Range("E" & i).Value = "" true or false , this is false
If .Range("B" & i).Value = "" And .Range("E" & i).Value = "" Then
GoTo nextrow
Else '<~~ .Range("B" & i).Value = "" And .Range("E" & i).Value = "" Then true or false, this is false
'<~~ When the result is false, after code applied
If zWeeks < 4 Then
Ztext = " on time"
zcolour = vbGreen
Cells(i, 7) = "Green"
ElseIf zWeeks > 8 Then
Ztext = " delayed"
zcolour = vbRed
Cells(i, 7) = "Red"
ElseIf zWeeks >= 4 And zWeeks <= 8 Then
Ztext = "remaining"
zcolour = vbYellow
Cells(i, 7) = "Yellow"
End If
End If
End If
With .Range("F" & i)
.Value = Ztext
.Interior.Color = zcolour
End With
nextrow:
Next i
End With
End Sub
This script is giving me an error because it consumes too much resources. What can I do to fix that?
Dim oSht As Worksheet
Dim i As Long, j As Integer
Dim LRow As Long, LCol As Long
Dim Email1Col As Integer, Email2Col As Integer, Email3Col As Integer
Dim arr As Variant
Dim SplEmail3 As String
'Definitions
Set oSht = ActiveSheet
Email1Col = 6
Email2Col = 7
Email3Col = 8
'-----------
With oSht
'LRow = .Range("G" & .Rows.Count).End(xlUp).Row
LRow = 1048576
'LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
For i = 2 To LRow
'If oSht.Rows(i + 1).EntireRow = 0 Then GoTo Skip
If Cells(i, Email1Col).Value <> "" Or Cells(i, Email3Col).Value <> "" Then
If Cells(i, Email2Col) <> "" Then
'email2 to new row + copy other data
Rows(i + 1).EntireRow.Insert
oSht.Rows(i + 1).EntireRow.Value = oSht.Rows(i).EntireRow.Value
Range(Cells(i + 1, Email1Col), Cells(i + 1, Email3Col)).ClearContents
Cells(i + 1, Email1Col) = Cells(i, Email2Col)
'email3 to new row + copy other data
End If
If Cells(i, Email3Col) <> "" Then
arr = Split(Cells(i, Email3Col), ",", , 1)
For j = 0 To UBound(arr)
'split into single emails
SplEmail3 = Replace((arr(j)), " ", "", 1, , 1)
'repeat the process for every split
Rows(i + 2 + j).EntireRow.Insert
oSht.Rows(i + 2 + j).EntireRow.Value = oSht.Rows(i).EntireRow.Value
Range(Cells(i + 2 + j, Email1Col), Cells(i + 2 + j, Email3Col)).ClearContents
Cells(i + 2 + j, Email1Col) = SplEmail3
Next j
End If
Range(Cells(i, Email2Col), Cells(i, Email3Col)).ClearContents
Else
Rows(i).EntireRow.Delete
End If
Skip:
Next i
sample data:
col1, col2,..., col6, col7 , col8
name, bla, ...,mail1,mail2,(mail3,mail4,mail5)
needs to become this:
col1, col2,..., col6
name, bla, ...,mail1
Note: I have tested this with very small piece of data.. Give it a try and if you are stuck then let me know. We will take it from there.
Let's say our data looks like this
Now we run this code
Sub Sample()
Dim oSht As Worksheet
Dim arr As Variant, FinalArr() As String
Dim i As Long, j As Long, k As Long, LRow As Long
Set oSht = ActiveSheet
With oSht
LRow = .Range("A" & .Rows.Count).End(xlUp).Row
arr = .Range("A2:H" & LRow).Value
i = Application.WorksheetFunction.CountA(.Range("G:H"))
'~~> Defining the final output array
ReDim Preserve FinalArr(1 To (LRow + i - 3), 1 To 6)
k = 0
For i = LBound(arr) To UBound(arr)
k = k + 1
FinalArr(k, 1) = arr(i, 1)
FinalArr(k, 2) = arr(i, 2)
FinalArr(k, 3) = arr(i, 3)
FinalArr(k, 4) = arr(i, 4)
FinalArr(k, 5) = arr(i, 5)
If arr(i, 6) <> "" Then FinalArr(k, 6) = arr(i, 6)
For j = 7 To 8
If arr(i, j) <> "" Then
k = k + 1
FinalArr(k, 1) = arr(i, 1)
FinalArr(k, 2) = arr(i, 2)
FinalArr(k, 3) = arr(i, 3)
FinalArr(k, 4) = arr(i, 4)
FinalArr(k, 5) = arr(i, 5)
FinalArr(k, 6) = arr(i, j)
End If
Next j
Next i
.Rows("2:" & .Rows.Count).Clear
.Range("A2").Resize(UBound(FinalArr), 6).Value = FinalArr
End With
End Sub
Output
You can use Power Query. Your comment led me to do some testing, and that can be done while recording a macro. For example, assuming your data is in a "table":
Sub createPQ()
ActiveWorkbook.Queries.Add Name:="Table1", Formula:= _
"let" & Chr(13) & "" & Chr(10) & " Source = Excel.CurrentWorkbook(){[Name=""Table1""]}[Content]," & Chr(13) & "" & Chr(10) & " #""Changed Type"" = Table.TransformColumnTypes(Source,{{""FirstName"", type text}, {""LastName"", type text}, {""blah1"", type text}, {""b lah2"", type text}, {""bla3"", type text}, {""email1"", type text}, {""email2"", type text}, {""email3"", type text}})," & Chr(13) & "" & Chr(10) & " #""Unpivoted Columns"" = Tab" & _
"le.UnpivotOtherColumns(#""Changed Type"", {""FirstName"", ""LastName"", ""blah1"", ""b lah2"", ""bla3""}, ""Attribute"", ""Value"")" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " #""Unpivoted Columns"""
Sheets.Add After:=ActiveSheet
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Table1" _
, Destination:=Range("$A$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array("SELECT * FROM [Table1]")
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = False
.ListObject.DisplayName = "Table1_2"
.Refresh BackgroundQuery:=False
End With
End Sub
If your user adds data, and needs to refresh the query, Data Ribbon ► Connection tab ► Refresh (or you could create a button to do that if you prefer).
The unknown is how it will work on a DB of your size.
-- Before
-- After
I have 2 Excel sheets, I need to take 1 value in Sheet 1, look for it in Sheet 2. If I find it, then I need to make sure that some other values are matching. If yes, I copy the sheet 1 row in a "match" tab.
If not, I copy the row in "mismatch" tab and I need to insert a message that says which value didn't match.
I cannot make it work right now. I think I'm not exiting the loop in the right place. Here is my code. If anybody could help, I would appreciate.
Sub compareAndCopy()
Dim LastRowISINGB As Integer
Dim LastRowISINNR As Integer
Dim lastRowM As Integer
Dim lastRowN As Integer
Dim foundTrue As Boolean
Dim ErrorMsg As String
' stop screen from updating to speed things up
Application.ScreenUpdating = False
'Find the last row for column F and Column B from Sheet 1 and Sheet 2
LastRowISINGB = Sheets("Sheet1").Cells(Sheets("Sheet1").Rows.Count, "f").End(xlUp).row
LastRowISINNR = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count, "b").End(xlUp).row
'fIND THE LAST ROW OF MATCH AND MISMATCH TAB
lastRowM = Sheets("mismatch").Cells(Sheets("mismatch").Rows.Count, "f").End(xlUp).row + 1
lastRowN = Sheets("match").Cells(Sheets("match").Rows.Count, "f").End(xlUp).row + 1
'ISIN MATCH FIRST
For I = 2 To LastRowISINGB
For J = LastRowISINNR To 2 Step -1
If Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value = "Y" And _
Worksheets("Sheet2").Range("Z" & J).Value = "" And _
(Worksheets("Sheet1").Range("c" & I).Value = Worksheets("Sheet2").Range("AF" & J).Value Or _
Worksheets("Sheet1").Range("K" & I).Value = Worksheets("Sheet2").Range("K" & J).Value Or _
Worksheets("Sheet1").Range("N" & I).Value = Worksheets("Sheet2").Range("L" & J).Value) Then
Sheets("Sheet1").Rows(I).Copy Destination:=Sheets("match").Rows(lastRowN)
lastRowN = lastRowN + 1
Exit For
ElseIf Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value = "Y" And _
Worksheets("Sheet2").Range("Z" & J).Value = "" And _
Worksheets("Sheet1").Range("c" & I).Value <> Worksheets("Sheet2").Range("AF" & J).Value And _
Worksheets("Sheet1").Range("K" & I).Value <> Worksheets("Sheet2").Range("K" & J).Value And _
Worksheets("Sheet1").Range("N" & I).Value <> Worksheets("Sheet2").Range("L" & J).Value Then
ErrorMsg = "dates don't match"
ElseIf Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value <> "Y" Then
ErrorMsg = "B column don't match"
ElseIf Sheets("Sheet1").Cells(I, 6).Value = Sheets("Sheet2").Cells(J, 2).Value And _
Worksheets("Sheet1").Range("B" & I).Value = "Y" And _
Worksheets("Sheet2").Range("Z" & J).Value <> "" Then
ErrorMsg = "Z column don't match"
Else: ErrorMsg = "ISIN don't match"
End If
Next J
Sheets("Sheet1").Rows(I).Copy Destination:=Sheets("mismatch").Rows(lastRowM)
Worksheets("mismatch").Range("S" & lastRowM).Value = ErrorMsg
lastRowM = lastRowM + 1
Next I
' stop screen from updating to speed things up
Application.ScreenUpdating = True
End Sub
First, I think you should add "Exit For" for each clause in If..else method. Otherwise it will lead to the fact that almost of your "miss match" result will be "ISIN don't match".
Second, I think you should set ErrorMsg = "" before For J = LastRowISINNR To 2 Step -1, and have condition ErrorMsg <> "" when you input result in sheet miss match.
Sheets("Sheet1").Rows(I).Copy Destination:=Sheets("mismatch").Rows(lastRowM)
Worksheets("mismatch").Range("S" & lastRowM).Value = ErrorMsg
lastRowM = lastRowM + 1
Otherwise, all your row even match or missmatch will input into miss match sheet.