MACRO works in stepping through but breaks when run via button - vba

I had created a Macro that reads data from a sheet and create journal entries. I had to update the macro due to some changes to the spreadsheet however now my macro doesnt work.
My macro works if I step through the entire thing or if I hit the play button in the VSB screen. However If I hit the macro button I embedded in spreadsheet, it breaks. I believe its breaking because its skipping this section:
If Cells(iRow2, 1) = "CCC $" Then
wsUp.Cells(iRow2, 1).Value = "CC"
ElseIf Cells(iRow2, 1) = "DDD $" Then
I am not sure why it is skipping this only when I bit the embedded button and not when I run it from the VSB screen.
Sub CreateAllocations_JEs()
Dim iRow As Integer, iCol As Integer, iRow2 As Integer
Dim sEntity As String, sEnt2 As String, sVal1 As String, sEnt3 As String, sDesc2 As String
Dim wsEntry As Worksheet
Dim wsUp As Worksheet
Dim wsInst As Worksheet
Set wsInst = Worksheets("Instructions")
Set wsEntry = Worksheets("Entries")
Set wsUp = Worksheets("Sheet1")
Dim lastrow As Long
Dim sRange As Range
Dim sQLNE As Long
''' Creates expense for holdings
For iRow = 6 To 35
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
sEntity = wsEntry.Range("D5").Value
sAcct = wsEntry.Range("N" & iRow).Value
sAcct2 = wsEntry.Range("M" & iRow).Value
sDesc = wsEntry.Range("O" & iRow).Value
vsum = Application.WorksheetFunction.Sum(wsEntry.Range("E" & iRow & ":J" & iRow))
If vsum > 0 Then
wsUp.Range("A" & lastrow + 1).Value = sEntity
wsUp.Range("J" & lastrow + 1).Value = vsum
wsUp.Range("G" & lastrow + 1).Value = sAcct
''''' Adds description column using the companies that have payables
sDesc2 = ""
End If
For iCol = 5 To 12
If wsEntry.Cells(iRow, iCol) > 0 Then
sEnt3 = wsEntry.Cells(5, iCol).Value
If sDesc2 <> "" Then
sDesc2 = sDesc2 & ", "
End If
sDesc2 = sDesc2 & sEnt3
End If
Next iCol
wsUp.Range("M" & lastrow + 1).Value = sDesc & sDesc2
'''''' Creates receivable for holdings and related fields
For iCol = 5 To 10
If wsEntry.Cells(iRow, iCol) > "0" Then
sVal1 = wsEntry.Cells(iRow, iCol).Value
sDesc = wsEntry.Range("O" & iRow).Value
sEnt3 = wsEntry.Cells(5, iCol).Value
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
wsUp.Range("A" & lastrow + 1).Value = sEntity
wsUp.Range("I" & lastrow + 1).Value = sVal1
vRec = Application.WorksheetFunction.Index(Sheets("IC accounts").Range("C:C"), Application.WorksheetFunction.Match(Sheets("Entries").Cells(5, iCol), Sheets("IC accounts").Range("B:B"), 0), 1)
wsUp.Range("G" & lastrow + 1).Value = vRec
wsUp.Range("M" & lastrow + 1).Value = sDesc & sEnt3
End If
Next iCol
''''Creates the payables and expense in other companies
For iCol = 5 To 12
If wsEntry.Cells(iRow, iCol) > "0" Then
sEnt2 = wsEntry.Cells(5, iCol).Value
sval2 = wsEntry.Cells(iRow, iCol).Value
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
wsUp.Range("A" & lastrow + 1, "A" & lastrow + 2).Value = sEnt2
If wsUp.Range("A" & lastrow + 1).Value = "AAA $" Then
wsUp.Range("J" & lastrow + 1).Value = sval2
wsUp.Range("I" & lastrow + 2).Value = sval2
wsUp.Range("G" & lastrow + 1).Value = sAcct2
wsUp.Range("G" & lastrow + 2).Value = "00-1320001"
ElseIf wsUp.Range("A" & lastrow + 1).Value = "BBB $" Then
wsUp.Range("J" & lastrow + 1).Value = sval2
wsUp.Range("I" & lastrow + 2).Value = sval2
wsUp.Range("G" & lastrow + 1).Value = sAcct2
wsUp.Range("G" & lastrow + 2).Value = "00-1320002"
Else
wsUp.Range("I" & lastrow + 1).Value = sval2
wsUp.Range("J" & lastrow + 2).Value = sval2
wsUp.Range("G" & lastrow + 1).Value = sAcct2
wsUp.Range("G" & lastrow + 2).Value = "00-4100040"
End If
wsUp.Range("M" & lastrow + 1, "M" & lastrow + 2).Value = sDesc & sEntity
End If
Next iCol
Next iRow
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
For iRow2 = 2 To lastrow
If Cells(iRow2, 1) = "CCC $" Then
wsUp.Cells(iRow2, 1).Value = "CC"
ElseIf Cells(iRow2, 1) = "DDD $" Then
wsUp.Cells(iRow2, 1).Value = "DD"
ElseIf Cells(iRow2, 1) = "EEE $" Then
wsUp.Cells(iRow2, 1).Value = "EE"
ElseIf Cells(iRow2, 1) = "FFF $" Then
wsUp.Cells(iRow2, 1).Value = "FF"
ElseIf Cells(iRow2, 1) = "GGG $" Then
wsUp.Cells(iRow2, 1).Value = "GG"
ElseIf Cells(iRow2, 1) = "HHH $" Then
wsUp.Cells(iRow2, 1).Value = "LLL"
ElseIf Cells(iRow2, 1) = "AAA $" Then
wsUp.Cells(iRow2, 1).Value = "LLL"
ElseIf Cells(iRow2, 1) = "LLL $" Then
wsUp.Cells(iRow2, 1).Value = "LLL"
ElseIf Cells(iRow2, 1) = "JJJ $" Then
wsUp.Cells(iRow2, 1).Value = "JJ"
End If
wsUp.Activate
Code Breaks Here. I beleive because skips section above.
vCN =
Application.WorksheetFunction.Index(Sheets("Company").Range("B:B"),
Application.WorksheetFunction.Match(Sheets("Sheet1").Cells(iRow2, 1),
Sheets("Company").Range("A:A"), 0), 1)
wsUp.Range("B" & iRow2).Value = vCN
vAN = Application.WorksheetFunction.Index(Sheets("COA").Range("B:B"),
Application.WorksheetFunction.Match(Sheets("Sheet1").Cells(iRow2, 7),
Sheets("COA").Range("A:A"), 0), 1)
wsUp.Range("H" & iRow2).Value = vAN
sQLNE = wsUp.Cells(Rows.Count, "N").End(xlUp).Row
wsUp.Range("N" & iRow2).Value = sQLNE
wsUp.Range("S" & iRow2).Value = wsUp.Range("I" & iRow2).Value
wsUp.Range("T" & iRow2).Value = wsUp.Range("J" & iRow2).Value
Next iRow2
lastrow = wsUp.Cells(Rows.Count, "A").End(xlUp).Row
sBatch = wsInst.Cells(8, 2).Value
sMonth = wsInst.Cells(6, 2).Value
sYear = wsInst.Cells(7, 2).Value
sDate = wsInst.Cells(5, 2).Value
sRef = sBatch & sMonth & sYear
wsUp.Range("C2", "C" & lastrow).Value = sRef
wsUp.Range("f2", "F" & lastrow).Value = sRef
wsUp.Range("D2", "D" & lastrow).Value = "1"
wsUp.Range("e2", "E" & lastrow).Value = "0"
wsUp.Range("K2", "k" & lastrow).Value = sDate
wsUp.Range("I:J").NumberFormat = "0.00"
wsUp.Range("S:T").NumberFormat = "0.00"
For iRow2 = 2 To lastrow
If Cells(iRow2, 9) = "" Then
wsUp.Cells(iRow2, 9).Value = "0.00"
wsUp.Cells(iRow2, 19).Value = "0.00"
ElseIf Cells(iRow2, 10) = "" Then
wsUp.Cells(iRow2, 10).Value = "0.00"
wsUp.Cells(iRow2, 20).Value = "0.00"
End If
Next iRow2
wsInst.Activate
End Sub

The code skips your if block because the parent for the cell has not been mentioned so it uses the activesheet, you have to explicitly mention that so instead of
If Cells(iRow2, 1) = "CCC $" Then
by this line:
MySheet.Cells(iRow2, 1) = "CCC $" Then
I don't know which one of the sheets is MySheet in your code, so replace it yourself

Related

Loop through UserForm

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

Tried to bold, centralise and underline the columns, and also clear the columns after generate order

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

Runtime error in VBA Excel

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

VBA error: not enough memory for the operation

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

Need to compare 2 excel sheets and create report

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.