How to use a function directly inside a code - vba

I have a code that used information from worksheets to create arrays. It then fills the arrays (given some criteria), create a new workbook and past the transpose of this array to the workbook.
Instead of doing this multiple time (one for each output file), I am trying to create a function that does exactly the same thing. Problem is I don't know how to call this function from the code (without assigning variables).
Code is as follows:
Sub FixerAndExporter()
Dim w As Workbook
Dim w2 As Workbook
Dim WSArray() As Variant, PArray() As Variant, P0Array() As Variant
Dim lRow As Long, lColumn As Long
Dim Pr As Integer, Pr0 As Integer
Dim ws As Worksheet
Set w = ThisWorkbook
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
For Each ws In w.Worksheets
If ws.Name = "Pr" Then
PArray = ws.UsedRange.Value
ElseIf ws.Name = "Pr0" Then
P0Array = ws.UsedRange.Value
End If
Next ws
'this is what I don't know how to do:
'ArrayFiller(PArray, P0Array)
'what the code is doing is this:
For lRow = LBound(PArray, 1) To UBound(PArray, 1)
For lColumn = LBound(PArray, 2) + 1 To UBound(PArray, 2)
If PArray(lRow, lColumn) <> "" And PArray(lRow, lColumn - 1) = "" Then
If P0Array(lRow, lColumn) <> "" And P0Array(lRow, lColumn) <> "--" Then
PArray(lRow, lColumn - 1) = P0Array(lRow, lColumn)
'PArray(lRow, lColumn - 1).Interior.Color = RGB(255, 0, 0)
ElseIf P0Array(lRow, lColumn) = "" Or P0Array(lRow, lColumn) = "--" Then
PArray(lRow, lColumn - 1) = PArray(lRow, lColumn)
'PArray(lRow, lColumn - 1).Interior.Color = RGB(255, 0, 0)
End If
End If
Next
Next
Workbooks.Add
Set w2 = ActiveWorkbook
w2.Sheets("Sheet1").Range("A1").Resize(UBound(PArray, 2), UBound(PArray, 1)) = Application.WorksheetFunction.Transpose(PArray())
w2.SaveAs Filename:=ThisWorkbook.path & "\POutput", FileFormat:=6
w2.Close True
End Sub
And this is the function:
Function ArrayFiller(arr As Variant, arr0 As Variant) As Variant
Dim lRow As Long, lColumn As Long
Dim w2 As Workbook
Workbooks.Add
For lRow = LBound(arr, 1) To UBound(arr, 1)
For lColumn = LBound(arr, 2) + 1 To UBound(arr, 2)
If arr(lRow, lColumn) <> "" And arr(lRow, lColumn - 1) = "" Then
If arr0(lRow, lColumn) <> "" And arr0(lRow, lColumn) <> "--" Then
arr(lRow, lColumn - 1) = arr0(lRow, lColumn)
'PriceArray(lRow, lColumn - 1).Interior.Color = RGB(255, 0, 0)
ElseIf arr0(lRow, lColumn) = "" Or arr0(lRow, lColumn) = "--" Then
arr(lRow, lColumn - 1) = arr(lRow, lColumn)
'PriceArray(lRow, lColumn - 1).Interior.Color = RGB(255, 0, 0)
End If
End If
Next
Next
Set w2 = ActiveWorkbook
w2.Sheets("Sheet1").Range("A1").Resize(UBound(PriceArray, 2), UBound(PriceArray, 1)) = Application.WorksheetFunction.Transpose(PriceArray())
w2.SaveAs Filename:=ThisWorkbook.path & "\PriceOutput.xls", FileFormat:=6
w2.Close True
Set w = ActiveWorkbook
End Function
The code is already working. My doubt would be how to use the function directly, so I don't have to write that block of code over and over for each new different item I need (there are multiple).
Any suggestions?

You should use Option Explicit (at the start of each module)!
Because with the function you wrote, you'll output nothing as PriceArray isn't defined nor filled!
With what you have written, a function is no use as you don't output anything, you could just use a sub with arguments.
Sub FixerAndExporter()
Dim w As Workbook
Dim WSArray() As Variant, PArray() As Variant, P0Array() As Variant
Dim lRow As Long, lColumn As Long
Dim Pr As Integer, Pr0 As Integer
Dim ws As Worksheet
Set w = ThisWorkbook
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
For Each ws In w.Worksheets
If ws.Name = "Pr" Then
PArray = ws.UsedRange.Value
ElseIf ws.Name = "Pr0" Then
P0Array = ws.UsedRange.Value
End If
Next ws
Dim PathToOutputFile As String
PathToOutputFile = ArrayFiller(PArray, P0Array)
MsgBox PathToOutputFile
End Sub
And the function (with an output)
Function ArrayFiller(arr As Variant, arr0 As Variant) As String
Dim lRow As Long, lColumn As Long
Dim w2 As Workbook
Dim TempStr As String
For lRow = LBound(arr, 1) To UBound(arr, 1)
For lColumn = LBound(arr, 2) + 1 To UBound(arr, 2)
If arr(lRow, lColumn) <> "" And arr(lRow, lColumn - 1) = "" Then
If arr0(lRow, lColumn) <> "" And arr0(lRow, lColumn) <> "--" Then
arr(lRow, lColumn - 1) = arr0(lRow, lColumn)
'PriceArray(lRow, lColumn - 1).Interior.Color = RGB(255, 0, 0)
ElseIf arr0(lRow, lColumn) = "" Or arr0(lRow, lColumn) = "--" Then
arr(lRow, lColumn - 1) = arr(lRow, lColumn)
'PriceArray(lRow, lColumn - 1).Interior.Color = RGB(255, 0, 0)
End If
End If
Next lColumn
Next lRow
TempStr = ThisWorkbook.Path & "\PriceOutput.xls"
Set w2 = Workbooks.Add
With w2
.Sheets(1).Range("A1").Resize(UBound(arr, 2), UBound(arr, 1)) = Application.WorksheetFunction.Transpose(arr())
.SaveAs Filename:=TempStr, FileFormat:=6
.Close True
End With 'w2
Set w2 = Nothing
ArrayFiller = TempStr
End Function

Related

Copy range based on criteria then dynamically create a new worksheet containing it

I have a sheet with values, what I want is with each unique value in column F to make a sheet named that, and copy all those rows to the new sheet.
this code looks close, but i need it to make a new sheet with each criteria (individuals)
Sub NewSheetData()
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Dim Rng As Range, rCell As Range
Set Rng = Range([A1], Range("A" & Rows.Count).End(xlUp))
For Each rCell In Range("MyTable")
On Error Resume Next
With Rng
.AutoFilter , field:=1, Criteria1:=rCell.Value
.Offset(1).SpecialCells(xlCellTypeVisible).EntireRow.Copy _
Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1)
.AutoFilter
End With
On Error GoTo 0
Next rCell
Application.EnableEvents = True
End Sub
The 3 procedures bellow, in a separate module, will create and populate new sheets with unique values in column F, on the main sheet
This uses dictionaries and late binding is slow: CreateObject("Scripting.Dictionary")
Early binding is fast: VBA Editor -> Tools -> References -> Add Microsoft Scripting Runtime
Option Explicit
Private Const X As String = vbNullString
Public Sub GetUniques()
Const MAIN_COL As Long = 6 'F '<-------------------- update column number
Dim ws As Worksheet, arr As Variant, r As Long, rng As Range, d As Dictionary
Dim val As Variant, wsNew As Worksheet, lr As Long, lc As Long
Set ws = ThisWorkbook.Worksheets("Sheet1") '<-------------------- update sheet name
lr = ws.Cells(ws.Rows.Count, MAIN_COL).End(xlUp).Row
lc = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
Set rng = ws.Range(ws.Cells(1, MAIN_COL), ws.Cells(lr, MAIN_COL))
arr = rng: Set d = New Dictionary
For r = 1 To UBound(arr)
If Len(arr(r, 1)) > 0 Then
val = CleanWsName(CStr(arr(r, 1)))
If Not d.Exists(val) Then d.Add val, X
End If
Next
Application.ScreenUpdating = False: Application.DisplayAlerts = False
For Each val In d
Set wsNew = MakeWS(val)
rng.AutoFilter Field:=1, Criteria1:="=" & val
ws.Range(ws.Cells(1, 1), ws.Cells(lr, lc)).SpecialCells(xlCellTypeVisible).Copy
With wsNew.Cells(1, 1)
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteAll
Application.CutCopyMode = False
wsNew.Activate: .Cells(1, 1).Select
End With
Next
ws.Activate: ws.Cells(1, 1).Copy: rng.AutoFilter
Application.ScreenUpdating = True: Application.DisplayAlerts = True
End Sub
Public Function CleanWsName(ByVal wsName As String) As String
Const x = vbNullString
wsName = Trim$(wsName) 'Trim, then remove [ ] / \ < > : * ? | "
wsName = Replace(Replace(Replace(wsName, "[", x), "]", x), " ", x)
wsName = Replace(Replace(Replace(wsName, "/", x), "\", x), ":", x)
wsName = Replace(Replace(Replace(wsName, "<", x), ">", x), "*", x)
wsName = Replace(Replace(Replace(wsName, "?", x), "|", x), Chr(34), x)
If Len(wsName) = 0 Then wsName = "DT " & Format(Now, "yyyy-mm-dd hh.mm.ss")
CleanWsName = Left$(wsName, 31) 'Resize to max len of 31
End Function
Public Function MakeWS(ByVal wsName As String) As Worksheet
Dim ws As Worksheet, result As Boolean, activeWS As Worksheet, id As Long
With ThisWorkbook
If .Worksheets.Count = 1 And .Worksheets(1).Name = wsName Then Exit Function
id = IIf(ActiveSheet.Index = 1, ActiveSheet.Index + 1, ActiveSheet.Index - 1)
Set activeWS = ActiveSheet
If activeWS.Name = wsName Then Set activeWS = .Worksheets(id)
For Each ws In .Worksheets
If ws.Name = wsName Then
ws.Delete
Exit For
End If
Next
Set ws = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
End With
ws.Name = wsName
activeWS.Activate
Set MakeWS = ws
End Function
Hope this helps
How about this? If you don't need the filtered list for anything else, you could also read it into a variable and pick the unique items to another variable and the create the sheets based on the latter one?
Sub NewSheets()
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Dim vList()
Dim vUniqueList()
Dim vUniqueCount As Integer
Dim vIsUnique As Boolean
vList = Range([A1], Range("A" & Rows.Count).End(xlUp))
ReDim vUniqueList(1 To UBound(vList, 1))
vUniqueCount = 0
For n = 1 To UBound(vList, 1)
vIsUnique = True
For m = 1 To UBound(vList, 1)
If vUniqueList(m) = vList(n, 1) Then
vIsUnique = False
End If
Next m
If vIsUnique Then
vUniqueCount = vUniqueCount + 1
vUniqueList(vUniqueCount) = vList(n, 1)
End If
Next n
For n = 1 To vUniqueCount
With Sheets.Add(after:=Sheets(Sheets.Count))
.Name = vUniqueList(n)
End With
Next n
Application.EnableEvents = True
End Sub

Invalid Or Unqualified Reference at: lastRA = .Range("A2" & .Rows.Count).End(xlUp).Row

Why do I receive the following error
Invalid or Unqualified reference"
at this line: lastRA = .Range("A2" & .Rows.Count).End(xlUp).Row with .Rows highlighted?
Sub HighlightUpgrds()
Dim lastRA As Long
Dim ws As Worksheet
Dim linecount As Long
Dim rng1 As Range
Dim rng2 As Range
linecount = 2
Set ws = Worksheets("Walk Ups")
Set rng1 = Cells(linecount, "N")
Set rng2 = Cells(linecount, "O")
lastRA = .Range("A2" & .Rows.Count).End(xlUp).Row
For i = 1 To lastRA
If Cells(linecount, "N") <> Cells(linecount, "O") Then
Cells(linecount, "N").Interior.Color = RGB(255, 255, 64)
Cells(linecount, "O").Interior.Color = RGB(255, 255, 64)
Else
End If
linecount = linecount + 1
Next i
End Sub
Change lastRA = .Range("A2" & .Rows.Count).End(xlUp).Row into
lastRA = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
Or put a With ws … End With around it:
With ws
lastRA = .Range("A" & .Rows.Count).End(xlUp).Row
End With
You should always fully qualify your cells/ranges:
Also the others in your code like Cells(linecount, "N") should be qualified to the worksheet e.g. ws.Cells(linecount, "N")
Try one of the following approach...
Sub HighlightUpgrds()
Dim lastRA As Long
Dim ws As Worksheet
Dim linecount As Long
Dim rng1 As Range
Dim rng2 As Range
linecount = 2
Set ws = Worksheets("Walk Ups")
Set rng1 = ws.Cells(linecount, "N")
Set rng2 = ws.Cells(linecount, "O")
lastRA = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastRA
If ws.Cells(linecount, "N") <> ws.Cells(linecount, "O") Then
ws.Cells(linecount, "N").Interior.Color = RGB(255, 255, 64)
ws.Cells(linecount, "O").Interior.Color = RGB(255, 255, 64)
Else
End If
linecount = linecount + 1
Next i
End Sub
OR
Sub HighlightUpgrds()
Dim lastRA As Long
Dim ws As Worksheet
Dim linecount As Long
Dim rng1 As Range
Dim rng2 As Range
linecount = 2
Set ws = Worksheets("Walk Ups")
With ws
Set rng1 = .Cells(linecount, "N")
Set rng2 = .Cells(linecount, "O")
lastRA = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 1 To lastRA
If .Cells(linecount, "N") <> .Cells(linecount, "O") Then
.Cells(linecount, "N").Interior.Color = RGB(255, 255, 64)
.Cells(linecount, "O").Interior.Color = RGB(255, 255, 64)
Else
End If
linecount = linecount + 1
Next i
End With
End Sub

Generate new worksheet based on column data for LARGE spreadsheets

I have a spreadsheet with 800k rows and 150 columns. I'm attempting to create new worksheets based on the contents of a column. So, for example if column Y has many elements ("alpha", "beta", "gamma", etc.) then I'd like to create new worksheets named "alpha", "beta", "gamma" which contain only the rows from the original that have those respective letters. I've found two scripts that work for smaller spreadsheets, but due to the size of this particular spreadsheet, they don't work.
Here are the two scripts that I have tried:
Sub parse_data()
Dim lr As Long
Dim ws As Worksheet
Dim vcol, i As Integer
Dim icol As Long
Dim myarr As Variant
Dim title As String
Dim titlerow As Integer
vcol = 1
Set ws = Sheets("Sheet1")
lr = ws.Cells(ws.Rows.Count, vcol).End(xlUp).Row
title = "A1:C1"
titlerow = ws.Range(title).Cells(1).Row
icol = ws.Columns.Count
ws.Cells(1, icol) = "Unique"
For i = 2 To lr
On Error Resume Next
If ws.Cells(i, vcol) <> "" And Application.WorksheetFunction.Match(ws.Cells(i, vcol), ws.Columns(icol), 0) = 0 Then
ws.Cells(ws.Rows.Count, icol).End(xlUp).Offset(1) = ws.Cells(i, vcol)
End If
Next
myarr = Application.WorksheetFunction.Transpose(ws.Columns(icol).SpecialCells(xlCellTypeConstants))
ws.Columns(icol).Clear
For i = 2 To UBound(myarr)
ws.Range(title).AutoFilter field:=vcol, Criteria1:=myarr(i) & ""
If Not Evaluate("=ISREF('" & myarr(i) & "'!A1)") Then
Sheets.Add(after:=Worksheets(Worksheets.Count)).Name = myarr(i) & ""
Else
Sheets(myarr(i) & "").Move after:=Worksheets(Worksheets.Count)
End If
ws.Range("A" & titlerow & ":A" & lr).EntireRow.Copy Sheets(myarr(i) & "").Range("A1")
Sheets(myarr(i) & "").Columns.AutoFit
Next
ws.AutoFilterMode = False
ws.Activate
End Sub
this returns "overflow"
the other code that I have tried:
Sub columntosheets()
Const sname As String = "VOTERFILE_WITHABSENTEEINFORMATI" 'change to whatever starting sheet
Const s As String = "O" 'change to whatever criterion column
Dim d As Object, a, cc&
Dim p&, i&, rws&, cls&
Set d = CreateObject("scripting.dictionary")
With Sheets(sname)
rws = .Cells.Find("*", , , , xlByRows, xlPrevious).Row
cls = .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
cc = .Columns(s).Column
End With
For Each sh In Worksheets
d(sh.Name) = 1
Next sh
Application.ScreenUpdating = False
With Sheets.Add(after:=Sheets(sname))
Sheets(sname).Cells(1).Resize(rws, cls).Copy .Cells(1)
.Cells(1).Resize(rws, cls).Sort .Cells(cc), 2, Header:=xlYes
a = .Cells(cc).Resize(rws + 1, 1)
p = 2
For i = 2 To rws + 1
If a(i, 1) <> a(p, 1) Then
If d(a(p, 1)) <> 1 Then
Sheets.Add.Name = a(p, 1)
.Cells(1).Resize(, cls).Copy Cells(1)
.Cells(p, 1).Resize(i - p, cls).Copy Cells(2, 1)
End If
p = i
End If
Next i
Application.DisplayAlerts = False
.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End With
Sheets(sname).Activate
End Sub
Returns error with "excel does not have enough resources".
Is it possible to do what I want on my hardware?
You can refer to the modified subroutine in another article 'Macro for copying and pasting data to another worksheet'.
Sub CopySheet()
Dim wsAll As Worksheet
Dim wsCrit As Worksheet
Dim wsNew As Worksheet
Dim LastRow As Long
Dim LastRowCrit As Long
Dim I As Long
Set wsAll = Worksheets("All") ' change All to the name of the worksheet the existing data is on
LastRow = wsAll.Range("A" & Rows.Count).End(xlUp).Row
Set wsCrit = Worksheets.Add
' column G has the criteria eg project ref
wsAll.Range("A1:A" & LastRow).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=wsCrit.Range("A1"), Unique:=True
LastRowCrit = wsCrit.Range("A" & Rows.Count).End(xlUp).Row
For I = 2 To LastRowCrit
wsAll.Copy Before:=Sheets("All")
ActiveSheet.Name = wsCrit.Range("A2")
Range("A1").CurrentRegion.AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:=wsCrit.Range("A1:A2"), _
Unique:=False
wsCrit.Rows(2).Delete
Next I
Application.DisplayAlerts = False
wsCrit.Delete
Application.DisplayAlerts = True
End Sub

Find values in range and print to column

How can I generate the Excel as in the image below via a macro?
Briefly I would like to make:
numbers between a1 and b1 print to d column;
numbers between a2 and b2 print to e column;
numbers between a3 and b3 print to f column.
Columns A and B have thousands of values.
As an alternative, here is a formula solution:
=IF(ROW(D1)>INDEX($A:$B,COLUMN(D1)-COLUMN($C1),2)-INDEX($A:$B,COLUMN(D1)-COLUMN($C1),1)+1,"",INDEX($A:$B,COLUMN(D1)-COLUMN($C1),1)+ROW(D1)-1)
Though I realize that a formula solution may not be feasible based on this statement:
Columns A and B have thousands of values.
EDIT: Pure array VBA solution:
Sub tgr()
Dim ws As Worksheet
Dim rData As Range
Dim aData As Variant
Dim aResults() As Variant
Dim lMaxDiff As Long
Dim i As Long, j As Long
Dim rIndex As Long, cIndex As Long
Set ws = ActiveWorkbook.ActiveSheet
Set rData = ws.Range("A1", ws.Cells(Rows.Count, "B").End(xlUp))
lMaxDiff = Evaluate("MAX(" & rData.Columns(2).Address(external:=True) & "-" & rData.Columns(1).Address(external:=True) & ")") + 1
aData = rData.Value2
ReDim aResults(1 To lMaxDiff, 1 To rData.Rows.Count)
For i = LBound(aData, 1) To UBound(aData, 1)
If IsNumeric(aData(i, 1)) And IsNumeric(aData(i, 2)) Then
rIndex = 0
cIndex = cIndex + 1
For j = Int(aData(i, 1)) To Int(aData(i, 2))
rIndex = rIndex + 1
aResults(rIndex, cIndex) = j
Next j
End If
Next i
ws.Range("D1").Resize(UBound(aResults, 1), UBound(aResults, 2)).Value = aResults
End Sub
Only because I like puzzles:
Sub u5758()
Dim x As Long
Dim i As Long
Dim oArr() As Variant
Dim arr() As Long
Dim rng As Range
Dim ws As Worksheet
Application.ScreenUpdating = False
Set ws = ActiveSheet
x = 4
With ws
oArr = .Range(.Cells(1, 1), .Cells(.Rows.Count, 2).End(xlUp)).value
For j = LBound(oArr, 1) To UBound(oArr, 1)
ReDim arr(oArr(j, 1) To oArr(j, 2))
For i = LBound(arr) To UBound(arr)
arr(i) = i
Next i
.Cells(1, x).Resize(UBound(arr) - LBound(arr) + 1).value = Application.Transpose(arr)
x = x + 1
Next j
End With
Application.ScreenUpdating = True
End Sub
I like puzzles too.
Sub from_here_to_there()
Dim rw As Long
With Worksheets("Sheet5") '<~~ set this worksheet properly!
For rw = 1 To .Cells(Rows.Count, 1).End(xlUp).Row
If IsNumeric(.Cells(rw, 1)) And IsNumeric(.Cells(rw, 2)) Then
With .Columns(Application.Max(4, .Cells(1, Columns.Count).End(xlToLeft).Column + 1))
.Cells(1, 1) = .Parent.Cells(rw, 1).Value2
.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Date:=xlDay, _
Step:=1, Stop:=.Parent.Cells(rw, 2).Value2
End With
End If
Next rw
End With
End Sub
      
You could use this:
Sub test()
Dim Lastrow As Long
Dim j As Double, i As Double, r As Double
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1") ' Change the name of your sheet
Lastrow = ws.Range("A" & Rows.Count).End(xlUp).Row
j = 4 ' Column D
With ws
For i = 1 To Lastrow ' Start the loop at A1 until the last row in column A
.Cells(1, j) = .Cells(i, 1).Value
r = 1
Do
.Cells(r + 1, j) = .Cells(r, j) + 1
r = r + 1
Loop Until .Cells(r, j) = .Cells(i, 2).Value
j = j + 1
Next i
End With
End Sub
Here's another quick one just for fun:
Sub transposeNfill()
Dim lastRow&, i&, xStart$, xEnd$, xMid$
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To lastRow
xStart = Cells(i, 1)
xEnd = Cells(i, 2)
xMid = xEnd - xStart
Cells(1, i + 3).Value = xStart
Cells(1 + xMid, i + 3) = xEnd
Range(Cells(2, i + 3), Cells(xMid, i + 3)).FormulaR1C1 = "=r[-1]c+1"
Cells.Copy
Cells.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
Next i
End Sub

How to make the for loop merge new values across sheets?

I had someone help me make the initial code for this, Im trying to modify it however its wrong.
I need to compare sheet 2 in a spreadsheet to sheets 4 to 10 and if the values of row e or b do not match any other row. copy the entire row to the bottom of sheet 1.
This is what I have so far but the value isn't being set to true and it prints after every sheet. I'm stick
Sub Button13() 'merge
Dim lastSourceRow As Long, LastTargetRow As Long, allSheets As Long, lastSheet As Long
Dim source As String, TARGET As Integer
Dim tempVal As String, tempValE, tempValT
Dim tRow As Long, lRow As Long, lCol As Long, nRow As Long
Dim match As Boolean
source = "Sheet2"
lastSheet = "10"
lastSourceRow = Sheets(source).Range("A" & Rows.Count).End(xlUp).Row
For allSheets = 1 To lastSheet
TARGET = allSheets
LastTargetRow = Sheets(TARGET).Range("A" & Rows.Count).End(xlUp).Row
For lRow = 2 To lastSourceRow 'Loop through Rows on currentsheet
Count = "0"
match = False 'Reset boolean test for each new row
tempVal = Sheets(source).Cells(lRow, "B").Value 'Assign the tempValue to compare
tempValE = Sheets(source).Cells(lRow, "E").Value
For tRow = 2 To LastTargetRow 'Loop through entire target sheet
tempValT = Sheets(TARGET).Cells(tRow, "B").Value
If (allSheets <> 2 Or allSheets <> 3) And tempVal = Sheets(TARGET).Cells(tRow, "B").Value And tempValE = Sheets(TARGET).Cells(tRow, "E").Value Then
match = True
ElseIf (allSheets <> 2 Or allSheets <> 3) And tempVal = Sheets(TARGET).Cells(tRow, "B").Value And tempValE = "" Then
match = True
ElseIf (allSheets <> 2 Or allSheets <> 3) And tempVal = Sheets(TARGET).Cells(tRow, "B").Value Then
match = True
'ElseIf Sheets(TARGET).Cells(tRow, "G").Value < DateAdd("m", -5, Date) Then
'match = True
End If
Next tRow
If match = False Then 'No Match found, copy row
nRow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row + 1
For lCol = 1 To 26 'Copy entire row by looping through 6 columns
Sheets("Sheet1").Cells(nRow, lCol).Value = Sheets(source).Cells(lRow, lCol).Value
Next lCol
End If
Next lRow
Next allSheets
End Sub
You have 2 problems:
problem 1: you reset match = False inside the lRow loop, this must be inside the tRow loop, otherwise if the first match = True hits then match is never reset
problem 2: If match = False Then can't be entered because it is outside of your tRow loop. so match is set inside the loop but can not be reached by If match = False Then
so the working code should be
Sub Button13() 'merge
Dim lastSourceRow As Long, LastTargetRow As Long, allSheets As Long, lastSheet As Long
Dim source As String, TARGET As Integer
Dim tempVal As String, tempValE, tempValT
Dim tRow As Long, lRow As Long, lCol As Long, nRow As Long
Dim match As Boolean
source = "Sheet2"
lastSheet = "10"
lastSourceRow = Sheets(source).Range("A" & Rows.Count).End(xlUp).Row
For allSheets = 1 To lastSheet
TARGET = allSheets
LastTargetRow = Sheets(TARGET).Range("A" & Rows.Count).End(xlUp).Row
For lRow = 2 To lastSourceRow 'Loop through Rows on currentsheet
Count = "0"
tempVal = Sheets(source).Cells(lRow, "B").Value 'Assign the tempValue to compare
tempValE = Sheets(source).Cells(lRow, "E").Value
For tRow = 2 To LastTargetRow 'Loop through entire target sheet
tempValT = Sheets(TARGET).Cells(tRow, "B").Value
If (allSheets <> 2 Or allSheets <> 3) And tempVal = Sheets(TARGET).Cells(tRow, "B").Value And tempValE = Sheets(TARGET).Cells(tRow, "E").Value Then
match = True
ElseIf (allSheets <> 2 Or allSheets <> 3) And tempVal = Sheets(TARGET).Cells(tRow, "B").Value And tempValE = "" Then
match = True
ElseIf (allSheets <> 2 Or allSheets <> 3) And tempVal = Sheets(TARGET).Cells(tRow, "B").Value Then
match = True
'ElseIf Sheets(TARGET).Cells(tRow, "G").Value < DateAdd("m", -5, Date) Then
'match = True
End If
If match = False Then 'No Match found, copy row
nRow = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row + 1
For lCol = 1 To 26 'Copy entire row by looping through 6 columns
Sheets("Sheet1").Cells(nRow, lCol).Value = Sheets(source).Cells(lRow, lCol).Value
Next lCol
End If
'2 moved lines
match = False 'Reset boolean test for each new row
Next tRow
Next lRow
Next allSheets
End Sub