Ownership Partners Grouping using excel VBA - excel

I have data which shows the acquisition of property from one partner to another and transfer of properties. Based on the inactive date and then seeing the document date I have to detect the transfer of property. Here is the snap of data:
For example in the second picture when the contract inactive date passes, ownership transfers to other having document date of the next day. Like in first group the 13th one William G & ALMA have ownership now look inactive date it is 10/3/1971, now I will find the next day date in document dates which I found 10/4/1971 for ALMA TEST TR, therefore, ownership transferred to him and new partners are WILLIAM G & ALMA TEST TR as both make to 100% of ownership. Here the output I have done manually but I need a VBA code to make it easier as I am new to VBA here is the required output.
Here is my code:
Sub DateFill()
Dim rng As Range, destRow As Long
Dim shtSrc As Worksheet, shtDest As Worksheet
Dim c As Range '-- this is used to store the single cell in the For Each loop
Set shtSrc = Sheets("Input") ' Sets "Sheet1" sheet as source sheet
Set shtDest = Sheets("Output") 'Sets "Sheet2." sheet as destination sheet
destRow = 2 'Start copying to this row on destination sheet
Dim x, y, i As Long
y = Array("ERROR", "(ERROR)") ' To delete rows having the name error to clean data
With ActiveSheet.UsedRange.Columns(1)
x = .Value
For i = 1 To UBound(x, 1)
If Not IsError(Application.Match(LCase(x(i, 1)), y, 0)) Then x(i, 1) = ""
Next
.Value = x
.SpecialCells(4).EntireRow.Delete
End With
' >> Look for matching dates in columns F to G <<
For Each c In rng.Cells
If (c.Offset(0, 2).Value + 1 = c.Offset(1, 3).Value) Then
shtSrc.Range("A" & c.Row).Copy shtDest.Range("A" & destRow)
shtSrc.Range("B" & c.Row).Copy shtDest.Range("B" & destRow)
shtSrc.Range("C" & c.Row).Copy shtDest.Range("C" & destRow)
shtSrc.Range("D" & c.Row).Copy shtDest.Range("D" & destRow)
shtSrc.Range("E" & c.Row).Copy shtDest.Range("E" & destRow)
shtSrc.Range("F" & c.Row).Copy shtDest.Range("F" & destRow)
shtSrc.Range("G" & c.Row).Copy shtDest.Range("G" & destRow)
destRow = destRow + 1
' > Ends search for dates <
End If
Next
End Sub
It's over my knowledge level. Any help would be appreciated, as I can't seem to figure this code out. If you could explain how this works in simple terms, that would be equally awesome!

I used the following data as sheet "Data". Note that the columns need to be in exactly this order and position. The code addresses the columns by A, B, C …
Note that I used another date format, but the code will work with any other date format too, as long as the cells contain real dates and not strings.
The following code has to be in a module. You need to specify your sheet names.
Option Explicit
Global wsData As Worksheet
Global wsDest As Worksheet
Global LastRow As Long
Global LastCol As Long
Global GroupCounter As Long
Public Sub ExtractGroups()
Set wsData = ThisWorkbook.Worksheets("Data") 'specify source sheet
Set wsDest = ThisWorkbook.Worksheets("Groups") 'specify destination sheet
LastRow = wsData.Cells(wsData.Rows.Count, "A").End(xlUp).Row
LastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column
GroupCounter = 0
'## Sort data
With wsData.Sort
.SortFields.Clear
'sort by Acquistion Date, Document Date and Inactive Date
.SortFields.Add Key:=Range("E2:E" & LastRow), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.SortFields.Add Key:=Range("F2:F" & LastRow), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.SortFields.Add Key:=Range("G2:G" & LastRow), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.SetRange wsData.UsedRange
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'## Find first group
Dim iRow As Long
iRow = LastRow
Dim IntSum As Double
Do While IntSum + wsData.Cells(iRow, "C").Value <= 100
IntSum = IntSum + wsData.Cells(iRow, "C").Value
Application.CutCopyMode = False
wsDest.Rows(2).Insert xlDown
wsData.Rows(iRow).Resize(ColumnSize:=LastCol).Copy
wsDest.Rows(2).Cells(1, "A").Value = GroupCounter
wsDest.Rows(2).Cells(1, "B").PasteSpecial xlPasteAll
iRow = iRow - 1
Loop
'## Analyze the data
Dim GroupRows As Long
GroupRows = LastRow - iRow
Dim destRow As Long, FirstGroupRow As Long, FirstDate As Date, AddedRows As Long
Do While GroupRows >= 0
GroupCounter = GroupCounter + 1
FirstGroupRow = 2
AddedRows = 0
destRow = 2 + GroupRows - 1
FirstDate = 0
GroupRows = 0
Do While destRow + GroupRows >= FirstGroupRow + GroupRows
If FirstDate = 0 Then
If Not IsDate(wsDest.Cells(destRow + GroupRows, "H").Value) Then Exit Do
FirstDate = wsDest.Cells(destRow + GroupRows, "H").Value
GroupRows = GroupRows + AddNextOwners(wsDest.Cells(destRow + GroupRows, "H").Value + 1)
ElseIf FirstDate <> wsDest.Cells(destRow + GroupRows, "H").Value Then
GroupRows = GroupRows + 1
Application.CutCopyMode = False
wsDest.Rows(2).Insert xlDown
wsDest.Rows(destRow + GroupRows).Resize(ColumnSize:=LastCol - 1).Offset(ColumnOffset:=1).Copy
wsDest.Rows(2).Cells(1, "A").Value = GroupCounter
wsDest.Rows(2).Cells(1, "B").PasteSpecial xlPasteAll
End If
destRow = destRow - 1
Loop
If GroupRows = 0 Then Exit Do
'## Sort within the group
With wsDest.Sort
.SortFields.Clear
.SortFields.Add Key:=wsDest.Range("H2").Resize(RowSize:=GroupRows), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.SetRange wsDest.Rows("2").Resize(RowSize:=GroupRows)
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'## color every second group
With wsDest.Rows("2").Resize(RowSize:=GroupRows).Interior
If GroupCounter Mod 2 = 0 Then
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent4
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
Else
.Pattern = xlNone
.TintAndShade = 0
.PatternTintAndShade = 0
End If
End With
'## check if group int exceeds 100 %
If Application.WorksheetFunction.Sum(wsDest.Range("D2").Resize(RowSize:=GroupRows)) > 100 Then
MsgBox "'Int' in group " & GroupCounter & " exceeded 100 %. Please fix the source data.", vbCritical
'ReNumberGroups
Exit Sub
End If
DoEvents
Loop
'ReNumberGroups
'## everything was going correctly!
MsgBox "Mission accomplished!", vbInformation
End Sub
'## Substitute the old owner with the new ones (for the next group)
Private Function AddNextOwners(DocDate As Date) As Long
Dim iRow As Long
For iRow = LastRow To 2 Step -1
If wsData.Cells(iRow, "F").Value = DocDate Then
AddNextOwners = AddNextOwners + 1
Application.CutCopyMode = False
wsDest.Rows(2).Insert xlDown
wsData.Rows(iRow).Resize(ColumnSize:=LastCol).Copy
wsDest.Rows(2).Cells(1, "A").Value = GroupCounter
wsDest.Rows(2).Cells(1, "B").PasteSpecial xlPasteAll
End If
Next iRow
End Function
And it will end up with the worksheet "Groups" like this below.
Note that the algorithm fails in the end because of some data inconsistency.
If you want the group numbers the other way round use …
Private Sub ReNumberGroups()
Dim iRow As Long
Const StartGroupNumber As Long = 1 'define first group number
For iRow = 2 To wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Row
wsDest.Cells(iRow, "A").Value = GroupCounter - wsDest.Cells(iRow, "A").Value + StartGroupNumber
Next iRow
End Sub

Related

vba range of hours and dates

hi I have a table that I schedule workers at the workers are scheduled at a range of hours for example 11:00-18:00 and a range of dates for example 21/01/2021-26/01/2021
and I need to spot duplicates for example if the same worker is scheduled at 21/04/2021-22/04/2021 at 11:00:18:00 and 13:00-15:00 it would detect a duplicate schedule
the table looks like this
my code right now spots only exact same schedule duplicate or once that start at the same hour
Private Sub CommandButton1_Click()
Dim lrow As Long
Dim x As Integer
Dim y As Integer
Dim i As Integer
lrow = ActiveSheet.ListObjects("LeaveTracker").DataBodyRange.Rows.Count + 5
shibuzim.ListObjects("LeaveTracker").ListColumns(2).DataBodyRange.Clear
For x = 5 To lrow
For y = x + 1 To lrow
If (Cells(x, 12).Value = Cells(y, 12).Value And _
Cells(x, 13).Value = Cells(y, 13).Value And _
Cells(x, 14).Value = Cells(y, 14).Value And _
Cells(x, 17).Value = Cells(y, 17).Value And _
Cells(x, 18).Value = Cells(y, 18).Value And _
Cells(x, 20).Value = Cells(y, 20).Value) _
Or _
(Cells(x, 12).Value = Cells(y, 12).Value And _
Cells(x, 13).Value = Cells(y, 13).Value And _
Cells(x, 14).Value = Cells(y, 14).Value And _
Left(Cells(x, 17).Value, 3) = Left(Cells(y, 17).Value, 3) And _
Cells(x, 18).Value = Cells(y, 18).Value And _
Cells(x, 20).Value = Cells(y, 20).Value) _
Then
Cells(x, 11).Value = "duplicate"
Cells(y, 11).Value = "duplicate"
MsgBox "line" & " " & x - 4 & " " & "with line" & " " & y - 4
End If
Next y
Next x
End Sub
This create a list of all shifts on a sheet named Check , sorts them by employee, start date, days and then checks them for shifts that start before the previous one ended.
Option Explicit
Sub CheckDupl()
Const COL_DUPL = 2 ' table column 2
Const COl_EMPLOYEE = 3
Const COL_START = 4
Const COL_END = 5
Const COL_HOURS = 8
Dim wb As Workbook, ws As Worksheet, wsCheck As Worksheet
Dim tbl As ListObject, lrow As Long
Dim r As Long, p As Long, iDupl As Long, count As Long
' clear table
Set wb = ThisWorkbook
Set ws = wb.Sheets(1) ' or wb.ActiveSheet
Set tbl = ws.ListObjects("LeaveTracker")
With tbl
lrow = .DataBodyRange.Rows.count
.ListColumns(COL_DUPL).DataBodyRange.Clear
End With
Dim sEmploy As String, s As String
Dim dtStart As Date, dtEnd As Date, dt As Date
Dim bDupl As Boolean, arHours, dur As Single
' prepare output sheet
Set wsCheck = wb.Sheets("Check")
wsCheck.Cells.Clear
wsCheck.Range("A1:F1") = Array("Employee", "Shift Start", "Shift End ", _
"Days", "Table Row", "Duplicate")
' scan table
iDupl = 2
For r = 1 To lrow
sEmploy = Trim(tbl.DataBodyRange(r, COl_EMPLOYEE))
dtStart = tbl.DataBodyRange(r, COL_START)
dtEnd = tbl.DataBodyRange(r, COL_END)
' get shift start/end times
s = Replace(tbl.DataBodyRange(r, COL_HOURS), " ", "") 'remove spaces
If Not s Like "##:##-##:##" Then
MsgBox "Check times '" & s & "'", vbCritical, "Table Row " & r
Exit Sub
Else
arHours = Split(s, "-")
End If
' add each shift to duplicate sheet
dt = dtStart
Do While dt <= dtEnd
With wsCheck.Cells(iDupl, 1)
.Value = sEmploy
.Offset(, 1) = CDate(Format(dt, "yyyy-mm-dd ") & arHours(0))
.Offset(, 2) = CDate(Format(dt, "yyyy-mm-dd ") & arHours(1))
.Offset(, 3) = dtEnd - dtStart
.Offset(, 4) = r ' table row
' sanity check
If .Offset(, 2) - .Offset(, 1) < 0 Then
MsgBox "ERROR - End date before Start date for " & _
sEmploy, vbCritical, "Table Row " & r
Exit Sub
End If
End With
dt = dt + 1
iDupl = iDupl + 1
Loop
Next
iDupl = iDupl - 1
' sort calendar by employee, start date, days
' check longer date ranges against shorter ones
With wsCheck.Sort
With .SortFields
.Clear
.Add key:=Range("A2:A" & iDupl), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add key:=Range("B2:B" & iDupl), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add key:=Range("D1:D" & iDupl), SortOn:=xlSortOnValues, _
Order:=xlDescending, DataOption:=xlSortNormal
End With
.SetRange Range("A1:F" & iDupl)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' now check for overlaps
With wsCheck
p = 2
For r = 3 To iDupl
' check start is before previous end for same employee
If .Cells(r, 1) = .Cells(p, 1) _
And .Cells(r, 2) < .Cells(p, 3) Then
.Cells(r, 6) = "Overlap with row " & p
' update table
tbl.DataBodyRange(.Cells(r, 5), COL_DUPL) = "Duplicate"
count = count + 1
Else
p = r
End If
Next
.Columns("A:F").AutoFit
.Activate
.Range("A1").Select
End With
MsgBox count & " duplicates found - see sheet " & wsCheck.Name, vbInformation
End Sub

Code Snips that work independently, no longer work when stitched together - VBA Userform

I have been tasked with making a vba script that has a userform with a text field, browse button, and convert button. It takes two different .csv files, checks to see if a certain column exists, if it does performs one set of formatting and column removal based on header names. If not performs a different set of formatting based on header names. After that it prints out on the default printer.
I have stitched many different solutions from many different talented people, as well as my own code. Each one on their own worked perfectly when testing one at a time. Once I placed them all together I hit a snag.
I got the error
"Compile error: Else without If"
I searched and found numerous threads where people stated if you add any statement after the then on the same line it closes the if statement. I check my code and could not find any instance of that.
I've been staring at the same chunk of code for days now and am no closer to a solution. I was hoping a fresh set of willing eyes may spot the area I goofed on.
Any and all suggestions or recommendations are welcome!
Thank you all in advanced.
'Shows Open File Dialog Box.
Private Sub CommandButton1_Click()
' Private Sub openDialog()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = FALSE
' Set the title of the dialog box.
.title = "Please Select the file."
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Report Export", "*.csv"
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = TRUE Then
TextBox1 = .SelectedItems(1)
End If
End With
' End Sub
End Sub
'****************************************
Private Sub Convert_Click()
If TextBox1.Value = "" Then
MsgBox "Please Select a file first!"
Else
Workbooks.Open Filename:=TextBox1ActiveSheet.Name = "REPORT"
'DELETES BLANK ROWS
Dim iCounter As Long
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = FALSE
For iCounter = Selection.Rows.Count To 1 Step -1
If WorksheetFunction.CountA(Selection.Rows(iCounter)) = 0 Then
Selection.Rows(iCounter).EntireRow.Delete
End If
Next iCounter
.Calculation = xlCalculationAutomatic
.ScreenUpdating = TRUE
End With
'************************
Dim rngToSearch As Range
Dim WhatToFind As Variant
Dim iCtr As Long
Set rngToSearch = ThisWorkbook.Worksheets("REPORT").Range("A1:Z1")
WhatToFind = Array("Card Type") 'add all Column header that you want to check
With rngToSearch
For iCtr = LBound(WhatToFind) To UBound(WhatToFind)
If WorksheetFunction.CountIf(rngToSearch, WhatToFind(iCtr)) > 0 Then ' Check if column is preset or not
' CODE if column exists
'********START CC********
'DELETES UNUSED COLUMNS
Dim currentColumn As Integer
Dim columnHeading As String
ActiveSheet.Columns("Z").Delete
For currentColumn = ActiveSheet.UsedRange.Columns.Count To 1 Step -1
columnHeading = ActiveSheet.UsedRange.Cells(1, currentColumn).Value
'CHECK WHETHER TO KEEP THE COLUMN
Select Case columnHeading
Case "User", "Effective Date", "Account", "Customer Name", "Email", "Auth Amount", "Auth Status", "Auth Code"
'Do nothing
Case Else
'Delete if the cell doesn't contain "Homer"
If InStr(1, _
ActiveSheet.UsedRange.Cells(1, currentColumn).Value, _
"Homer", vbBinaryCompare) = 0 Then
ActiveSheet.Columns(currentColumn).Delete
End If
End Select
Next
'Format Sheets
'****Column User****
Dim colUser As Long
Dim ColumnUser As Long
'Get Column User
colUser = WorksheetFunction.Match("User", Rows("1:1"), 0)
'Convert To Column Letter
ColumnUser = Split(Cells(1, colUser).Address, "$")(1)
'****Column EffectiveDate****
Dim colEffectiveDate As Long
Dim ColumnEffectiveDate As Long
'Get Column EffectiveDate
colEffectiveDate = WorksheetFunction.Match("Effective Date", Rows("1:1"), 0)
'Convert To Column Letter
ColumnEffectiveDate = Split(Cells(1, colEffectiveDate).Address, "$")(1)
'****Column Account****
Dim colAccount As Long
Dim ColumnAccount As Long
'Get Column Account
colAccount = WorksheetFunction.Match("Account", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAccount = Split(Cells(1, colAccount).Address, "$")(1)
'****Column CustName****
Dim colCustName As Long
Dim ColumnCustName As Long
'Get Column Account
colCustName = WorksheetFunction.Match("Customer Name", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustName = Split(Cells(1, colCustName).Address, "$")(1)
'****Column CustEmail****
Dim colCustEmail As Long
Dim ColumnCustEmail As Long
'Get Column Account
colCustEmail = WorksheetFunction.Match("Email", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustEmail = Split(Cells(1, colCustEmail).Address, "$")(1)
'****Column Amount****
Dim colAmount As Long
Dim ColumnAmount As Long
'Get Column Account
colAmount = WorksheetFunction.Match("Auth Amount", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAmount = Split(Cells(1, colAmount).Address, "$")(1)
'****Column AuthStatus****
Dim colAuthStatus As Long
Dim ColumnAuthStatus As Long
'Get Column Account
colAuthStatus = WorksheetFunction.Match("Auth Status", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAuthStatus = Split(Cells(1, colAuthStatus).Address, "$")(1)
'****Column AuthCode****
Dim colAuthCode As Long
Dim ColumnAuthCode As Long
'Get Column Account
colAuthCode = WorksheetFunction.Match("Auth Code", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAuthCode = Split(Cells(1, colAuthCode).Address, "$")(1)
' Sets Column Widths
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).EntireColumn.AutoFit
Worksheets("REPORT").Range(ColumnCustName & ":" & ColumnCustEmail).ColumnWidth = 30
' Turns Word Wrap ON
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).WrapText = TRUE
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).VerticalAlignment = xlVAlignTop
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).HorizontalAlignment = xlHAlignLeft
Worksheets("REPORT").Range("A1").EntireRow.Font.Bold = TRUE
Worksheets("REPORT").Range("A1").EntireRow.Font.Size = 12
' Set Page Settings
ActiveSheet.Range(ColumnUser & ":" & ColumnAuthCode).CurrentRegion
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.Zoom = FALSE
.FitToPagesWide = 1
.FitToPagesTall = FALSE
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.BottomMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.25)
End With
'Finds the last non-blank cell in a single row or column
Dim lRow As Long
'Find the last non-blank cell
lRow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
' Row color change
Dim i As Integer
For i = 2 To lRow
If i Mod 2 = 0 Then
ActiveSheet.Range(ActiveSheet.Cells(i, 1), ActiveSheet.Cells(i, lCol)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
End If
Next i
' Add Totals
Dim LastRow As Long
Dim bottomRow As Long
LastRow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
If LastRow >= 2 Then
Cells(LastRow + 2, ColumnAmount).Formula = "=SUM(" & ColumnAmount & "2" & ":" & ColumnAmount & LastRow & ")"
ElseIf LastRow < 2 Then
Cells(LastRow + 2, ColumnAmount).Value = Range(ColumnAmount & "2").Value
End If
Cells(lRow + 2, ColumnCustEmail).Value = "Total:"
bottomRow = lRow + 2
Let Copyrange = ColumnCustEmail & bottomRow & ":" & ColumnAmount & bottomRow
Range(Copyrange).BorderAround _
ColorIndex:=3, Weight:=xlThick
Range(Copyrange).Font.Bold = TRUE
Range(Copyrange).Font.Size = 14
' Add Auto Print HERE
Worksheets("REPORT").PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
Application.DisplayAlerts = FALSE
Application.Quit
End If
End Sub
'*********End of CCs**********
Else
' CODE if column is Not Found
'********CHECKS********
'DELETES UNUSED COLUMNS
Dim currentColumn As Integer
Dim columnHeading As String
ActiveSheet.Columns("Z").Delete
For currentColumn = ActiveSheet.UsedRange.Columns.Count To 1 Step -1
columnHeading = ActiveSheet.UsedRange.Cells(1, currentColumn).Value
'CHECK WHETHER TO KEEP THE COLUMN
Select Case columnHeading
Case "User", "Payment Date", "Account", "Customer Name", "Customer Email", "Amount", "Comment"
'Do nothing
Case Else
'Delete if the cell doesn't contain "Homer"
If InStr(1, _
ActiveSheet.UsedRange.Cells(1, currentColumn).Value, _
"Homer", vbBinaryCompare) = 0 Then
ActiveSheet.Columns(currentColumn).Delete
End If
End Select
Next
'Format Sheets
'****Column User****
Dim colUser As Long
Dim ColumnUser As Long
'Get Column User
colUser = WorksheetFunction.Match("User", Rows("1:1"), 0)
'Convert To Column Letter
ColumnUser = Split(Cells(1, colUser).Address, "$")(1)
'****Column PaymentDate****
Dim colPaymentDate As Long
Dim ColumnPaymentDate As Long
'Get Column PaymentDate
colPaymentDate = WorksheetFunction.Match("Payment Date", Rows("1:1"), 0)
'Convert To Column Letter
ColumnPaymentDate = Split(Cells(1, colPaymentDate).Address, "$")(1)
'****Column Account****
Dim colAccount As Long
Dim ColumnAccount As Long
'Get Column Account
colAccount = WorksheetFunction.Match("Account", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAccount = Split(Cells(1, colAccount).Address, "$")(1)
'****Column CustName****
Dim colCustName As Long
Dim ColumnCustName As Long
'Get Column Account
colCustName = WorksheetFunction.Match("Customer Name", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustName = Split(Cells(1, colCustName).Address, "$")(1)
'****Column CustEmail****
Dim colCustEmail As Long
Dim ColumnCustEmail As Long
'Get Column Account
colCustEmail = WorksheetFunction.Match("Customer Email", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustEmail = Split(Cells(1, colCustEmail).Address, "$")(1)
'****Column Amount****
Dim colAmount As Long
Dim ColumnAmount As Long
'Get Column Account
colAmount = WorksheetFunction.Match("Amount", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAmount = Split(Cells(1, colAmount).Address, "$")(1)
'****Column Comment****
Dim colComment As Long
Dim ColumnComment As Long
'Get Column Account
colComment = WorksheetFunction.Match("Comment", Rows("1:1"), 0)
'Convert To Column Letter
ColumnComment = Split(Cells(1, colComment).Address, "$")(1)
' Sets Column Widths
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).EntireColumn.AutoFit
Worksheets("REPORT").Range(ColumnCustName & ":" & ColumnCustEmail).ColumnWidth = 30
Worksheets("REPORT").Range(ColumnComment & ":" & ColumnComment).ColumnWidth = 50
' Turns Word Wrap ON
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).WrapText = TRUE
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).VerticalAlignment = xlVAlignTop
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).HorizontalAlignment = xlHAlignLeft
Worksheets("REPORT").Range("A1").EntireRow.Font.Bold = TRUE
Worksheets("REPORT").Range("A1").EntireRow.Font.Size = 12
' Set Page Settings
ActiveSheet.Range(ColumnUser & ":" & ColumnComment).CurrentRegion
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.Zoom = FALSE
.FitToPagesWide = 1
.FitToPagesTall = FALSE
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.BottomMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.25)
End With
'Finds the last non-blank cell in a single row or column
Dim lRow As Long
'Find the last non-blank cell
lRow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
' Row color change
Dim i As Integer
For i = 2 To lRow
If i Mod 2 = 0 Then
ActiveSheet.Range(ActiveSheet.Cells(i, 1), ActiveSheet.Cells(i, lCol)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
End If
Next i
' Add Totals
Dim LastRow As Long
Dim bottomRow As Long
LastRow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
If LastRow >= 2 Then
Cells(LastRow + 2, ColumnAmount).Formula = "=SUM(" & ColumnAmount & "2" & ":" & ColumnAmount & LastRow & ")"
ElseIf LastRow < 2 Then
Cells(LastRow + 2, ColumnAmount).Value = Range(ColumnAmount & "2").Value
End If
Cells(lRow + 2, ColumnCustEmail).Value = "Total:"
bottomRow = lRow + 2
Let Copyrange = ColumnCustEmail & bottomRow & ":" & ColumnAmount & bottomRow
Range(Copyrange).BorderAround _
ColorIndex:=3, Weight:=xlThick
Range(Copyrange).Font.Bold = TRUE
Range(Copyrange).Font.Size = 14
' Add Auto Print HERE
Worksheets("REPORT").PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
Application.DisplayAlerts = FALSE
Application.Quit
End If
End Sub
'********END CHECKS*********
End If
Next
End With
End Sub
EDIT:
Changes that have been made:
Collapsed and condensed my code to remove unneeded blank lines.
Tab indented the code properly
Removed closing tags that were mistakenly left in.
Added closing tags where they were left out.
Added variable definitions
Corrected Object references.
LOTS OF DEBUGGING.
Thank you everyone for your help. I learned some better practices and was able to get everything up and running!
First, always state Option Explicit at the top of your code. If this was done then you will have seen a number of variables not declared. Additionally you would have seen an abundance of duplicated variables..
Specifically in regards to your error message, this is due to the fact that you have a rogue Else AND also you have a 2 x rogue End If AND you are missing an End If. I have commented these within your code. Remove them both and your code will work.
Also you have used End Sub several times within a procedure. I will make an assumption here that what you actually want to do is EXIT the sub, thus substitute for Exit Sub
I don't normally reveiw code and rewrite but your code was messy, not indented correctly and this no doubt has helped lead to the issues you are having. Neat code is easy to read, easy to write. I do however echo the above that smaller procedures are key to good code writing skills.
'Shows Open File Dialog Box.
Private Sub CommandButton1_Click()
' Private Sub openDialog()
Dim fd As Office.FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.AllowMultiSelect = False
' Set the title of the dialog box.
.Title = "Please Select the file."
' Clear out the current filters, and add our own.
.Filters.Clear
.Filters.Add "Report Export", "*.csv"
.Filters.Add "All Files", "*.*"
' Show the dialog box. If the .Show method returns True, the
' user picked at least one file. If the .Show method returns
' False, the user clicked Cancel.
If .Show = True Then
TextBox1 = .SelectedItems(1)
End If
End With
End Sub
'****************************************
Private Sub Convert_Click()
If TextBox1.Value = "" Then
MsgBox "Please Select a file first!"
Else
Workbooks.Open Filename:=TextBox1ActiveSheet.Name = "REPORT"
'DELETES BLANK ROWS
Dim iCounter As Long
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
For iCounter = Selection.Rows.Count To 1 Step -1
If WorksheetFunction.CountA(Selection.Rows(iCounter)) = 0 Then
Selection.Rows(iCounter).EntireRow.Delete
End If
Next iCounter
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
'************************
Dim rngToSearch As Range
Dim WhatToFind As Variant
Dim iCtr As Long
Set rngToSearch = ThisWorkbook.Worksheets("REPORT").Range("A1:Z1")
WhatToFind = Array("Card Type") 'add all Column header that you want to check
With rngToSearch
For iCtr = LBound(WhatToFind) To UBound(WhatToFind)
If WorksheetFunction.CountIf(rngToSearch, WhatToFind(iCtr)) > 0 Then ' Check if column is preset or not
' CODE if column exists
'********START CC********
'DELETES UNUSED COLUMNS
Dim currentColumn As Integer
Dim columnHeading As String
ActiveSheet.Columns("Z").Delete
For currentColumn = ActiveSheet.UsedRange.Columns.Count To 1 Step -1
columnHeading = ActiveSheet.UsedRange.Cells(1, currentColumn).Value
'CHECK WHETHER TO KEEP THE COLUMN
Select Case columnHeading
Case "User", "Effective Date", "Account", "Customer Name", "Email", "Auth Amount", "Auth Status", "Auth Code"
'Do nothing
Case Else
'Delete if the cell doesn't contain "Homer"
If InStr(1, ActiveSheet.UsedRange.Cells(1, currentColumn).Value, _
"Homer", vbBinaryCompare) = 0 Then
ActiveSheet.Columns(currentColumn).Delete
End If
End Select
Next
'Format Sheets
'****Column User****
Dim colUser As Long
Dim ColumnUser As Long
'Get Column User
colUser = WorksheetFunction.Match("User", Rows("1:1"), 0)
'Convert To Column Letter
ColumnUser = Split(Cells(1, colUser).Address, "$")(1)
'****Column EffectiveDate****
Dim colEffectiveDate As Long
Dim ColumnEffectiveDate As Long
'Get Column EffectiveDate
colEffectiveDate = WorksheetFunction.Match("Effective Date", Rows("1:1"), 0)
'Convert To Column Letter
ColumnEffectiveDate = Split(Cells(1, colEffectiveDate).Address, "$")(1)
'****Column Account****
Dim colAccount As Long
Dim ColumnAccount As Long
'Get Column Account
colAccount = WorksheetFunction.Match("Account", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAccount = Split(Cells(1, colAccount).Address, "$")(1)
'****Column CustName****
Dim colCustName As Long
Dim ColumnCustName As Long
'Get Column Account
colCustName = WorksheetFunction.Match("Customer Name", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustName = Split(Cells(1, colCustName).Address, "$")(1)
'****Column CustEmail****
Dim colCustEmail As Long
Dim ColumnCustEmail As Long
'Get Column Account
colCustEmail = WorksheetFunction.Match("Email", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustEmail = Split(Cells(1, colCustEmail).Address, "$")(1)
'****Column Amount****
Dim colAmount As Long
Dim ColumnAmount As Long
'Get Column Account
colAmount = WorksheetFunction.Match("Auth Amount", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAmount = Split(Cells(1, colAmount).Address, "$")(1)
'****Column AuthStatus****
Dim colAuthStatus As Long
Dim ColumnAuthStatus As Long
'Get Column Account
colAuthStatus = WorksheetFunction.Match("Auth Status", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAuthStatus = Split(Cells(1, colAuthStatus).Address, "$")(1)
'****Column AuthCode****
Dim colAuthCode As Long
Dim ColumnAuthCode As Long
'Get Column Account
colAuthCode = WorksheetFunction.Match("Auth Code", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAuthCode = Split(Cells(1, colAuthCode).Address, "$")(1)
' Sets Column Widths
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).EntireColumn.AutoFit
Worksheets("REPORT").Range(ColumnCustName & ":" & ColumnCustEmail).ColumnWidth = 30
' Turns Word Wrap ON
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).WrapText = True
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).VerticalAlignment = xlVAlignTop
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnAuthCode).HorizontalAlignment = xlHAlignLeft
Worksheets("REPORT").Range("A1").EntireRow.Font.Bold = True
Worksheets("REPORT").Range("A1").EntireRow.Font.Size = 12
' Set Page Settings
ActiveSheet.Range(ColumnUser & ":" & ColumnAuthCode).CurrentRegion
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.BottomMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.25)
End With
'Finds the last non-blank cell in a single row or column
Dim lRow As Long
'Find the last non-blank cell
lRow = Cells.Find(What:="*", After:=Range("A1"), LookAt:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, _
MatchCase:=False).Row
' Row color change
Dim i As Integer
For i = 2 To lRow
If i Mod 2 = 0 Then
ActiveSheet.Range(ActiveSheet.Cells(i, 1), ActiveSheet.Cells(i, _
lCol)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
End If
Next i
' Add Totals
Dim LastRow As Long
Dim bottomRow As Long
LastRow = Cells.Find(What:="*", After:=Range("A1"), LookAt:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, _
MatchCase:=False).Row
If LastRow >= 2 Then
Cells(LastRow + 2, ColumnAmount).Formula = "=SUM(" & ColumnAmount & _
"2" & ":" & ColumnAmount & LastRow & ")"
ElseIf LastRow < 2 Then
Cells(LastRow + 2, ColumnAmount).Value = Range(ColumnAmount & _
"2").Value
End If
Cells(lRow + 2, ColumnCustEmail).Value = "Total:"
bottomRow = lRow + 2
Let Copyrange = ColumnCustEmail & bottomRow & ":" & ColumnAmount & bottomRow
Range(Copyrange).BorderAround ColorIndex:=3, Weight:=xlThick
Range(Copyrange).Font.Bold = True
Range(Copyrange).Font.Size = 14
' Add Auto Print HERE
Worksheets("REPORT").PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
Application.DisplayAlerts = False
Application.Quit
End If
Exit Sub
'*********End of CCs**********
'==========================================================='
' this is your problem
' Else
' delete this ^^
'==========================================================='
' CODE if column is Not Found
'********CHECKS********
'DELETES UNUSED COLUMNS
ActiveSheet.Columns("Z").Delete
For currentColumn = ActiveSheet.UsedRange.Columns.Count To 1 Step -1
columnHeading = ActiveSheet.UsedRange.Cells(1, currentColumn).Value
'CHECK WHETHER TO KEEP THE COLUMN
Select Case columnHeading
Case "User", "Payment Date", "Account", "Customer Name", "Customer Email", "Amount", "Comment"
'Do nothing
Case Else
'Delete if the cell doesn't contain "Homer"
If InStr(1, ActiveSheet.UsedRange.Cells(1, currentColumn).Value, "Homer", _
vbBinaryCompare) = 0 Then
ActiveSheet.Columns(currentColumn).Delete
End If
End Select
Next
'Format Sheets
'****Column User****
'Get Column User
colUser = WorksheetFunction.Match("User", Rows("1:1"), 0)
'Convert To Column Letter
ColumnUser = Split(Cells(1, colUser).Address, "$")(1)
'****Column PaymentDate****
Dim colPaymentDate As Long
Dim ColumnPaymentDate As Long
'Get Column PaymentDate
colPaymentDate = WorksheetFunction.Match("Payment Date", Rows("1:1"), 0)
'Convert To Column Letter
ColumnPaymentDate = Split(Cells(1, colPaymentDate).Address, "$")(1)
'****Column Account****
'Get Column Account
colAccount = WorksheetFunction.Match("Account", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAccount = Split(Cells(1, colAccount).Address, "$")(1)
'****Column CustName****
'Get Column Account
colCustName = WorksheetFunction.Match("Customer Name", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustName = Split(Cells(1, colCustName).Address, "$")(1)
'****Column CustEmail****
'Get Column Account
colCustEmail = WorksheetFunction.Match("Customer Email", Rows("1:1"), 0)
'Convert To Column Letter
ColumnCustEmail = Split(Cells(1, colCustEmail).Address, "$")(1)
'****Column Amount****
'Get Column Account
colAmount = WorksheetFunction.Match("Amount", Rows("1:1"), 0)
'Convert To Column Letter
ColumnAmount = Split(Cells(1, colAmount).Address, "$")(1)
'****Column Comment****
Dim colComment As Long
Dim ColumnComment As Long
'Get Column Account
colComment = WorksheetFunction.Match("Comment", Rows("1:1"), 0)
'Convert To Column Letter
ColumnComment = Split(Cells(1, colComment).Address, "$")(1)
' Sets Column Widths
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).EntireColumn.AutoFit
Worksheets("REPORT").Range(ColumnCustName & ":" & ColumnCustEmail).ColumnWidth = 30
Worksheets("REPORT").Range(ColumnComment & ":" & ColumnComment).ColumnWidth = 50
' Turns Word Wrap ON
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).WrapText = True
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).VerticalAlignment = xlVAlignTop
Worksheets("REPORT").Range(ColumnUser & ":" & ColumnComment).HorizontalAlignment = xlHAlignLeft
Worksheets("REPORT").Range("A1").EntireRow.Font.Bold = True
Worksheets("REPORT").Range("A1").EntireRow.Font.Size = 12
' Set Page Settings
ActiveSheet.Range(ColumnUser & ":" & ColumnComment).CurrentRegion
With ActiveSheet.PageSetup
.Orientation = xlLandscape
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = False
.LeftMargin = Application.InchesToPoints(0.25)
.RightMargin = Application.InchesToPoints(0.25)
.BottomMargin = Application.InchesToPoints(0.25)
.TopMargin = Application.InchesToPoints(0.25)
End With
'Finds the last non-blank cell in a single row or column
'Find the last non-blank cell
lRow = Cells.Find(What:="*", After:=Range("A1"), LookAt:=xlPart, _
LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, _
MatchCase:=False).Row
' Row color change
For i = 2 To lRow
If i Mod 2 = 0 Then
ActiveSheet.Range(ActiveSheet.Cells(i, 1), ActiveSheet.Cells(i, lCol)).Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.ThemeColor = xlThemeColorAccent6
.TintAndShade = 0.799981688894314
.PatternTintAndShade = 0
End With
End If
Next i
' Add Totals
LastRow = Cells.Find(What:="*", After:=Range("A1"), _
LookAt:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, MatchCase:=False).Row
If LastRow >= 2 Then
Cells(LastRow + 2, ColumnAmount).Formula = "=SUM(" & ColumnAmount & "2" & ":" & ColumnAmount & LastRow & ")"
ElseIf LastRow < 2 Then
Cells(LastRow + 2, ColumnAmount).Value = Range(ColumnAmount & "2").Value
End If
Cells(lRow + 2, ColumnCustEmail).Value = "Total:"
bottomRow = lRow + 2
Let Copyrange = ColumnCustEmail & bottomRow & ":" & ColumnAmount & bottomRow
Range(Copyrange).BorderAround _
ColorIndex:=3, Weight:=xlThick
Range(Copyrange).Font.Bold = True
Range(Copyrange).Font.Size = 14
' Add Auto Print HERE
Worksheets("REPORT").PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
Application.DisplayAlerts = False
Application.Quit
'==========================================================='
' this is your problem
' End If
' delete this ^^
'==========================================================='
Exit Sub
'********END CHECKS*********
'==========================================================='
' this is your problem
' End If
' delete this ^^
'==========================================================='
Next iCtr
End With
'==========================================================='
' this is your problem
End If
' added this ^^
'==========================================================='
End Sub
the problem is here:
'*********End of CCs**********
Else
' CODE if column is Not Found
'********CHECKS********
The end sub seems out of place. Either make a new sub or delete it.
Like the commenters said, make your tabbing symmetrical will go a long way. Also, write short functions. When I first started to do it, I felt like I was writing too many sub-routines. But it makes the code incredibly easier to understand.
I write a "Main" sub, and then have it call each of the other functions. Has cut down my errors a lot.
Cheers!

Duplicating VLOOKUP macro in multiple sheets

I recorded a macro that VLOOKUPs from Sheet "P&L" (the first tab that holds all of the data) and filters down in the current sheet until the data in column A runs out. It works; however, I need this code to function for the remaining sheets. These are updated monthly. There will be a different number of inputs in Column A in each sheet. These are all ID #s I'm using to vlookup information from the P&L tab.
When I wrote this macro as a FoorLoopIndex, I keep getting "Compile error: invalid or unqualified" messages.
I do not have any experiences with macros -- I'm struggling to find my error.
Sub update_gp_profits()
Dim StartIndex, EndIndex, LoopIndex As Integer
StartIndex = Sheets("P&L").Index + 1
EndIndex = Sheets("Sheet4").Index - 1
For LoopIndex = StartIndex To EndIndex
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("B2:B" & lastrow).Formula = "=+VLOOKUP(RC[-1],'P&L'!R15C3:R29702C4,2,FALSE)"
Range("C2").Select
.Range("C2:C" & lastrow).Formula = "=+VLOOKUP(RC[-2],'P&L'!R15C3:R29702C5,3,FALSE)"
Range("D2").Select
.Range("D2:D" & lastrow).Formula = "=+VLOOKUP(RC[-3],'P&L'!R15C3:R29702C6,4,FALSE)"
Range("E2").Select
.Range("E2:E" & lastrow).Formula = "=+VLOOKUP(RC[-4],'P&L'!R15C3:R29702C17,15,FALSE)"
Range("F2").Select
.Range("F2:F" & lastrow).Formula = "=+VLOOKUP(RC[-5],'P&L'!R15C3:R29702C18,16,FALSE)"
Range("J2").Select
.Range("k2:k" & lastrow).Formula = "=+VLOOKUP(RC[-10],'P&L'!R15C3:R29702C160,158,FALSE)"
Range("k2").Select
Next LoopIndex
End Sub
Try this one,
Sub update_gp_profits()
Dim ws As Worksheet
Dim rng As Range
Dim lRow As Long
Set ws = ActiveSheet
'
With ws
lRow = ws.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row ' Last row
Set rng = .Range("A2" & ":" & "A" & lRow) ' This is your range
rng.Offset(0, 1).FormulaR1C1 = "=VLOOKUP(RC[-1],'P&L'!R15C3:R29702C4,2,FALSE)"
rng.Offset(0, 2).FormulaR1C1 = "=VLOOKUP(RC[-2],'P&L'!R15C3:R29702C5,3,FALSE)"
rng.Offset(0, 3).FormulaR1C1 = "=VLOOKUP(RC[-3],'P&L'!R15C3:R29702C6,4,FALSE)"
rng.Offset(0, 4).FormulaR1C1 = "=VLOOKUP(RC[-4],'P&L'!R15C3:R29702C17,15,FALSE)"
rng.Offset(0, 5).FormulaR1C1 = "=VLOOKUP(RC[-5],'P&L'!R15C3:R29702C18,16,FALSE)"
rng.Offset(0, 10).FormulaR1C1 = "=VLOOKUP(RC[-10],'P&L'!R15C3:R29702C160,158,FALSE)"
Debug.Print rng.Address
End With
End Sub
Try below code it will loop all the rows on the sheet4.
max num of row in 2010 office = https://stackoverflow.com/a/527026/1411000
https://stackoverflow.com/a/527026/1411000
Sub update_gp_profits()
Dim StartIndex, EndIndex, LoopIndex As Integer
StartIndex = Sheets("Sheet4").).Index + 1
EndIndex = 1048576
For LoopIndex = StartIndex To EndIndex
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("B2:B" & lastrow).Formula = "=+VLOOKUP(RC[-1],'P&L'!R15C3:R29702C4,2,FALSE)"
Range("C2").Select
.Range("C2:C" & lastrow).Formula = "=+VLOOKUP(RC[-2],'P&L'!R15C3:R29702C5,3,FALSE)"
Range("D2").Select
.Range("D2:D" & lastrow).Formula = "=+VLOOKUP(RC[-3],'P&L'!R15C3:R29702C6,4,FALSE)"
Range("E2").Select
.Range("E2:E" & lastrow).Formula = "=+VLOOKUP(RC[-4],'P&L'!R15C3:R29702C17,15,FALSE)"
Range("F2").Select
.Range("F2:F" & lastrow).Formula = "=+VLOOKUP(RC[-5],'P&L'!R15C3:R29702C18,16,FALSE)"
Range("J2").Select
.Range("k2:k" & lastrow).Formula = "=+VLOOKUP(RC[-10],'P&L'!R15C3:R29702C160,158,FALSE)"
Range("k2").Select
Next LoopIndex
End Sub

Generated Project Portfolio Timeline

I have a list of Projects:
Project A
Project B
Project C
and milestones for each project with a date for the milestone:
Project A Milestone 1 01/01/2015
Project A Milestone 2 01/02/2015
Project A Milestone 3 01/03/2015
Project B Milestone 1 01/04/2015
I am looking to generate a type of timeline for all of the projects in one sheet, with milestones displayed in their respective month.
Column A would have the list of projects and row 1 have months, then to display the milestone where the month and project match.
So far I have been able to extract the list of projects using a macro:
Sub UniqueList()
Dim rListPaste As Range
Dim iReply As Integer
On Error Resume Next
Set rListPaste = Application.InputBox _
(Prompt:="Please select the destination cell", Type:=8)
If rListPaste Is Nothing Then
iReply = MsgBox("No range nominated," _
& " terminate", vbYesNo + vbQuestion)
If iReply = vbYes Then Exit Sub
End If
Range("A1", Range("A65536").End(xlUp)).AdvancedFilter _
Action:=xlFilterCopy, CopyToRange:=rListPaste.Cells(1, 1), Unique:=True
End Sub
After this I am pretty stuck. Any advice would be greatly appreciated.
I've done a similar setup to develop a milestone chart based on the current week. I've modified it to match your requirements:
Sub CreateMilestoneChart()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim LastRow As Long
Dim i As Long, j As Long
Dim FirstMonth As Long
Dim FirstYear As Long
Dim LastMonth As Long
Dim LastYear As Long
Dim curRange As Range
Set ws1 = Worksheets("Project List")
Set ws2 = Worksheets("Milestone Chart")
Application.ScreenUpdating = False
LastRow = ws1.Cells(Rows.Count, 1).End(xlUp).Row
'-----You will want to modify or remove these lines once-----
'-----you get the sheet formatted the way you want-----------
ws2.Cells.Clear
ws2.Range("A1").Value = "Milestone Chart"
ws2.Range("A2").Value = "Generated on " & Date
ws2.Range("A3").Value = "Month:"
ws2.Range("A3").HorizontalAlignment = xlRight
'------------------------------------------------------------
ws1.Range("A1:C" & LastRow).Copy
ws2.Range("A4").PasteSpecial Paste:=xlPasteAllUsingSourceTheme, Operation:=xlNone _
, SkipBlanks:=False, Transpose:=False
LastRow = LastRow + 3
For i = 4 To LastRow
ws2.Cells(i, 1).Value = ws2.Cells(i, 1).Value & " " & ws2.Cells(i, 2).Value
Next i
ws2.Range("A4:A" & LastRow).HorizontalAlignment = xlRight
ws2.Range("B4:B" & LastRow).Delete Shift:=xlToLeft
With ws2.Sort
.SortFields.Clear
.SortFields.Add Key:=Range("B4:B" & LastRow), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Range("A4:B" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
FirstMonth = DatePart("m", ws2.Range("B4").Value)
FirstYear = DatePart("yyyy", ws2.Range("B4").Value)
LastMonth = DatePart("m", ws2.Range("B" & LastRow).Value)
LastYear = DatePart("yyyy", ws2.Range("B" & LastRow).Value)
ws2.Range("B3").Value = CDate(FirstMonth & "/" & FirstYear)
Set curRange = ws2.Range("B3")
i = 1
Do Until DatePart("m", curRange.Value) = LastMonth And DatePart("yyyy", curRange.Value) = LastYear
Set curRange = ws2.Cells(3, i + 2)
curRange.Value = DateAdd("m", 1, ws2.Cells(3, i + 1).Value)
i = i + 1
Loop
ws2.Cells(3, i + 2).Value = DateAdd("m", 1, ws2.Cells(3, i + 1).Value)
For i = 4 To LastRow
j = 2
Do Until ws2.Cells(i, j).Value >= ws2.Cells(3, j).Value And ws2.Cells(i, j).Value < ws2.Cells(3, j + 1).Value
ws2.Cells(i, 2).Insert Shift:=xlToRight
ws2.Cells(i, 2).Value = "'-----------------"
j = j + 1
Loop
Next i
Application.ScreenUpdating = True
End Sub
It's not very clean by any means, but it will work. You will need to modify it to fit your needs.

faster deletion of rows

the code below allows me to delete rows if a cells contains certain values. now for some reason it takes me a lot of time(30 mins and counting).
' to delete data not meeting criteria
Worksheets("Dashboard").Activate
n1 = Range("n1")
n2 = Range("n2")
Worksheets("Temp Calc").Activate
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
For z = lastrow To 2 Step -1
If Cells(z, 6).Value = "CNF" Or Cells(z, 4).Value <= n1 Or Cells(z, 3).Value >= n2 Then
Rows(z).Delete
End If
Next z
a google search and some talk with forum member sam provided me with two options
to use filter.(i do want to use this).
using arrays to store the entire worksheet and then copy data that only matches my criteria.He was kind enough to help me come up with the following code.But i am not familiar with working on data in an array.
lastrow = Cells(Rows.Count, 1).End(xlUp).Row
lastCol = Cells(1, Column.Count).End(xlRight).Row
arr1 = Range("A1:Z" & lastrow)
ReDim arr2(1 To UBound(arr1, 1), 1 To UBound(arr1, 2))
j = j + 1
For i = 1 To UBound(arr1, 1)
If arr1(i, 6) <> "CNF" And arr1(i, 4) > n1 And arr1(i, 3) < n2 Then
For k = 1 To lastCol
arr2(j, k) = arr1(i, k)
Next k
j = j + 1
End If
Next i
Range(the original bounds) = arr2
my question is is there a faster way of deleting rows in an array other than the ones mentioned above? Or is array or filter the best options i've got.I am open to suggestions.
Update my new code looks like this. it does not filter the date rangeeven if they are hardcoded can anybody tell me what i am doing wrong ?
Option Explicit
Sub awesome()
Dim Master As Workbook
Dim fd As FileDialog
Dim filechosen As Integer
Dim i As Integer
Dim lastrow, x As Long
Dim z As Long
Application.ScreenUpdating = False
Dim sngStartTime As Single
Dim sngTotalTime As Single
Dim ws As Worksheet
Dim FltrRng As Range
Dim lRow As Long
Dim N1 As Date, N2 As Date
sngStartTime = Timer
Sheets("Dashboard").Select
N1 = Range("n1").Value
N2 = Range("n2").Value
Sheets("Temp Calc").Select
'Clear existing sheet data except headers
'Sheets("Temp Calc").Select
'Rows(1).Offset(1, 0).Resize(Rows.Count - 1).ClearContents
'The folder containing the files to be recap'd
Set fd = Application.FileDialog(msoFileDialogFilePicker)
fd.InitialFileName = "G:\Work\" '<----- Change this to where the files are stored.
fd.InitialView = msoFileDialogViewList
'allow multiple file selection
fd.AllowMultiSelect = True
fd.Filters.Add "Excel Files", "*.xls*"
filechosen = fd.Show
'Create a workbook for the recap report
Set Master = ThisWorkbook
If filechosen = -1 Then
'open each of the files chosen
For i = 1 To fd.SelectedItems.Count
Workbooks.Open fd.SelectedItems(i)
With ActiveWorkbook.Worksheets(1)
Range("O2", Range("O" & Cells(Rows.Count, "O").End(xlUp).Row)).Copy Master.Worksheets(2).Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
Range("p2", Range("P" & Cells(Rows.Count, "P").End(xlUp).Row)).Copy Master.Worksheets(2).Range("B" & Rows.Count).End(xlUp).Offset(1, 0)
Range("Q2", Range("Q" & Cells(Rows.Count, "Q").End(xlUp).Row)).Copy Master.Worksheets(2).Range("C" & Rows.Count).End(xlUp).Offset(1, 0)
Range("R2", Range("R" & Cells(Rows.Count, "R").End(xlUp).Row)).Copy Master.Worksheets(2).Range("D" & Rows.Count).End(xlUp).Offset(1, 0)
Range("A2", Range("A" & Cells(Rows.Count, "A").End(xlUp).Row)).Copy Master.Worksheets(2).Range("E" & Rows.Count).End(xlUp).Offset(1, 0)
Range("AC2", Range("AC" & Cells(Rows.Count, "AC").End(xlUp).Row)).Copy Master.Worksheets(2).Range("F" & Rows.Count).End(xlUp).Offset(1, 0)
End With
' Sheets(1).Range("D4", Sheets(1).Range("D" & Sheets(1).Cells(Rows.Count, "D").End(xlUp).Row)).Copy Sheets(2).Range("B" & Sheets(2).Rows.Count).End(xlUp).Offset(1, 0)
ActiveWorkbook.Close (False)
Next i
End If
Set ws = ThisWorkbook.Worksheets("Temp Calc")
'~~> Start Date and End Date
N1 = #5/1/2012#: N2 = #7/1/2012#
With ws
'~~> Remove any filters
.AutoFilterMode = False
'~~> Get the last row
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Identify your data range
Set FltrRng = .Range("A1:F" & lRow)
'~~> Filter the data as per your criteria
With FltrRng
'~~> First filter on blanks
.AutoFilter Field:=6, Criteria1:="="
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'~~> Delete the filtered blank rows
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
ws.ShowAllData
'~~> Next filter on Start Date
.AutoFilter Field:=3, Criteria1:="<" & N1, Operator:=xlAnd
'~~> Finally filter on End Date
.AutoFilter Field:=4, Criteria1:=">" & N2, Operator:=xlAnd
'~~> Filter on col 6 for CNF
'.AutoFilter Field:=6, Criteria1:="CNF"
'~~> Delete the filtered rows
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
'~~> Remove any filters
.AutoFilterMode = False
End With
sngTotalTime = Timer - sngStartTime
MsgBox "Time taken: " & (sngTotalTime \ 60) & " minutes, " & (sngTotalTime Mod 60) & " seconds"
Application.Goto (ActiveWorkbook.Sheets("Dashboard").Range("A4"))
Sheets("Dashboard").Select
Application.ScreenUpdating = True
End Sub
this works for me ..... thank you everyone.... it is achieved using an advanced filter
Dim x, rng As Range
x = Array("BENIN-00001", "BENIN-00002", "BENTB-0001", "BENTB-0002", "BENTB-0003", "BENTB-0004", _
"BENTB-0005", "BENTB-0006", "BENTB-0007", "BENTB-0008", "BENTH-00001", "CRPTB-00002", "GDSGL-00001", _
"GDSIN-00001", "GDSIN-00002", "GDSIN-00003", "LSIED-00001", "LSIES-00001", "PRSGS-00001", "PRSGS-00002", _
"PRSGS-00003", "PRSGS-00006", "PRSGS-00007", "PRSGS-00008", "PRSPS-00001", "PRSPS-00002", "PRSTB-0001", _
"PRSTB-0002", "PRSTB-0003", "PRSTB-0004", "PRSTB-0005", "PRSTB-0006", "PRSTB-0007", "SNMIN-00001", "SNMIN-00002", _
"TRGIN-00001", "TRGIN-00002", "TRGTH-00001", "BENEU-00002", "BENEU-00003", "GDSEU-00002", "GDSEU-00003", _
"GDSEU-00004", "PRSGS-00005", "PRSGS-00061", "PRSPS-00004", "PRSPS-00005", "TRGEU-00002", "TRGGB-00001", _
"BENMX-00001", "BENUS-00001", "BENUS-00002", "GDSCA-00001", "GDSGL-00002", "GDSMX-00001", "GDSUS-00001", _
"GDSUS-00002", "LSIPP-00001", "PRSGS-00004", "PRSPS-00003", "TRGMX-00001", "TRGUS-00001")
With Sheets("Temp Calc").Cells(1).CurrentRegion
On Error Resume Next
.Columns(6).SpecialCells(4).EntireRow.Delete
On Error GoTo 0
Set rng = .Offset(, .Columns.Count + 1).Cells(1)
.Cells(1, 5).Copy rng
rng.Offset(1).Resize(UBound(x) + 1).Value = Application.Transpose(x)
.AdvancedFilter 1, rng.CurrentRegion
.Offset(1).EntireRow.Delete
On Error Resume Next
.Parent.ShowAllData
On Error GoTo 0
rng.EntireColumn.Clear
End With

Resources