Excel Macro updating rows in a file with new data - excel

The code below runs and executes perfectly, I just want to add some features. The code imports the new rows from Report file to Workbook file, and I want it to check for a potential row with new data by every cell in the row, and not by just column G(contains number or numbers separated by comma), but in range A2:BQ. Also update the newly found cells even if the row exists in Workbook by the number in column G. Also to highlight the new rows with a bright color in the Workbook file. One last thing is to wrap the text after the importing of new cells finishes.
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 rows needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report
Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next
Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
Exit Sub
End If
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
Dim s As String, rng As Range, m As Long
For iRow = iStartRow To iLastRow
s = CStr(wsReport.Cells(iRow, "G").Value)
Set rng = wsData.Columns("A:BQ").Find(s)
If rng Is Nothing Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
Debug.Print iRow, s, "New row " & m
Else
m = rng.Row
Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
End If
wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value 'Put the new line in Workbook
Next
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
" to " & iLastRow, vbInformation, sFilename
wbReport.Close False 'Close the Report
End Sub

This updates column P and S for rows matching column G or adds the rows if no match.
Option Explicit
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 cells in the row needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report
Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next
Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
Exit Sub
End If
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
Dim rng As Range, rng2 As Range, rng3 As Range
Dim m As Long, m2 As String, m3 As String, s As String, s2 As String, s3 As String, c As Variant
Dim iAdd As Long, iUpdate As Long
For iRow = iStartRow To iLastRow
s = CStr(wsReport.Cells(iRow, "G").Value)
Set rng = wsData.Columns("G").Find(s)
If rng Is Nothing Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
With wsData.Cells(m, 1).Resize(1, NUM_COLS)
.Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
.Interior.Color = vbYellow
End With
iAdd = iAdd + 1
Debug.Print iRow, s, "New row " & m
Else
m = rng.Row
For Each c In Array("P", "S")
If wsData.Cells(m, c) <> CStr(wsReport.Cells(iRow, c).Value) Then
wsData.Cells(m, c) = CStr(wsReport.Cells(iRow, c).Value)
wsData.Cells(m, c).Interior.Color = vbGreen
iUpdate = iUpdate + 1
End If
Next
Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
End If
Next
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
" to " & iLastRow & vbCrLf & "added rows = " & iAdd & vbCrLf & _
"updated cells = " & iUpdate, vbInformation, sFilename
wbReport.Close False 'Close the Report
End Sub

Since you seem to be stuck on comparing two ranges:
'Do two ranges contain the same value(s)?
' does not handle error values...
Function RangesMatch(rng1 As Range, rng2 As Range) As Boolean
Dim rv As Boolean, v1, v2, r As Long, c As Long
If rng1.Rows.Count = rng2.Rows.Count And _
rng1.Columns.Count = rng2.Columns.Count Then
v1 = rng1.Value
v2 = rng2.Value
If rng1.Count = 1 Then
RangesMatch = (v1 = v2) 'single cell ranges...
Else
'multi-cell ranges: loop and compare values
For r = 1 To UBound(v1, 1)
For c = 1 To UBound(v1, 2)
If v1(r, c) <> v2(r, c) Then
Exit Function 'by default returns false
End If
Next c
Next r
RangesMatch = True
End If
End If
End Function

This is how far I got:
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True 'Set true if the file has a header(Report)
Const NUM_COLS As Long = 69 '69 cells in the row needed to be imported from the Report
Const FILENAME = "Report.xlsx"
Const PATH = "C:\Users\Documents\" 'path of the report
Dim wbReport As Workbook, wsReport As Worksheet, wsData As Worksheet
Dim next_blank_row As Long, iStartRow As Long, iLastRow As Long, iRow As Long
Dim sFilename As String
Set wsData = ThisWorkbook.Worksheets("Sheet1") 'for example: destination worksheet
next_blank_row = wsData.Cells(Rows.Count, "G").End(xlUp).Row + 1 'next blank row
sFilename = PATH & FILENAME
Debug.Print "Opening ", sFilename 'Openning file
On Error Resume Next
Set wbReport = Workbooks.Open(sFilename)
On Error GoTo 0
If wbReport Is Nothing Then
MsgBox "Can not open " & sFilename, vbCritical, "ERROR" 'If the file was not found or cannot be opened
Exit Sub
End If
Set wsReport = wbReport.Worksheets(1) 'Expects only one sheet in the Report
iStartRow = IIf(HAS_HEADER, 2, 1) 'If it has header start from row 2
iLastRow = wsReport.Cells(Rows.Count, 1).End(xlUp).Row
Dim s As String, rng As Range, m As Long, m2 As String, m3 As String, s2 As String, s3 As String, rng2 As Range, rng3 As Range
For iRow = iStartRow To iLastRow
s = CStr(wsReport.Cells(iRow, "G").Value)
Set rng = wsData.Columns("G").Find(s)
s2 = CStr(wsReport.Cells(iRow, "P").Value)
Set rng2 = wsData.Columns("P").Find(s2)
s3 = CStr(wsReport.Cells(iRow, "S").Value)
Set rng3 = wsData.Columns("S").Find(s3)
If rng Is Nothing Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
Debug.Print iRow, s, "New row " & m
Else
m = rng.Row
Debug.Print iRow, s, "Match row " & m 'Match row:if the line already exists in the file
m2 = rng2.Row
m3 = rng3.Row
End If
wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
wsData.Cells(m2, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
wsData.Cells(m3, 1).Resize(1, NUM_COLS).Value = wsReport.Cells(iRow, 1).Resize(1, NUM_COLS).Value
Next
MsgBox wsReport.Name & " scanned from row " & iStartRow & _
" to " & iLastRow, vbInformation, sFilename
wbReport.Close False 'Close the Report
End Sub

Related

Copy and pasting to a template and saving as new workbook

I'm trying to loop through and paste each different group of IDs into a template I have in a separate workbook. I then want it to save as a new workbook, using the Vendor Name in C1 of the second sheet in the new workbook.
But there's a few problems in me trying to complete this;
It is giving me an error at the SaveAs line.
The filename is not pulling from the cell I want.
It stops after the first loop.
Anybody have any ideas of what I need to fix?
Here is my current macro:
Option Explicit
SubNewBillback()
Dim wsBData, wsBackup, wsCreditMemo As Worksheet
Dim wb, wbTemplate, wbAllRebates As Workbook
Dim rngHeader As Range
Dim i As Long, n As Long, LastRow As Long, StartRow As Long
Dim InvNum, InvDate, VendName, VendNum, strPath, FileName, openfile As String
Dim Amt As Integer
strPath = "\\Billback Data Base-Spreadsheet\2021\September\Excel\"
openfile = "\\Billback Data Base-Spreadsheet\2021\September\BillbackAutoTemplate.xlsx"
Set wbAllRebates = ActiveWorkbook
With wbAllRebates
Set wsBData = .Sheets("BackupData")
Set wsBackup = .Sheets("Backup")
End With
'copy data from query
wsBData.Cells.Copy
wsBackup.Cells.PasteSpecial Paste:=xlPasteValues
StartRow = 2
Application.ScreenUpdating = False
'searches for change in ID#
With wsBackup
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rngHeader = .Range("A1:O1")
For i = 2 To LastRow
' change ID next row
If .Cells(i, "A") <> .Cells(i + 1, "A") Then
' create new workbook
Set wbTemplate = Workbooks.Open(openfile)
.Range("A" & StartRow & ":O" & i).Copy wbTemplate.Sheets(2).Range("A2")
wbTemplate.SaveAs FileName:=strPath & Sheets(2).Cells(i, "C") & ".xlsx"
wbTemplate.Close True
' move to next
StartRow = i + 1
n = n + 1
End If
Next
End With
Application.ScreenUpdating = True
MsgBox n & " billbacks created."
End Sub
The function at the bottom will remove invalid characters from your file name. I've added the call to the function in your Save As line in your original code. It will replace any of the following characters in the vendor name : \ / ? | * [ ] { } < > ~ " # % & with a _. If you would rather it replace it with something else just change the "_" in the line sFileName = Replace(sFileName, Mid(vInval, i, 1), "_") to some other valid character
Option Explicit
Sub NewBillback()
Dim wsBData, wsBackup, wsCreditMemo As Worksheet
Dim wb, wbTemplate, wbAllRebates As Workbook
Dim rngHeader As Range
Dim i As Long, n As Long, LastRow As Long, StartRow As Long
Dim InvNum, InvDate, VendName, VendNum, strPath, FileName, openfile As String
Dim Amt As Integer
strPath = "\\Billback Data Base-Spreadsheet\2021\September\Excel\"
openfile = "\\Billback Data Base-Spreadsheet\2021\September\BillbackAutoTemplate.xlsx"
Set wbAllRebates = ActiveWorkbook
With wbAllRebates
Set wsBData = .Sheets("BackupData")
Set wsBackup = .Sheets("Backup")
End With
'copy data from query
wsBData.Cells.Copy
wsBackup.Cells.PasteSpecial Paste:=xlPasteValues
StartRow = 2
Application.ScreenUpdating = False
'searches for change in ID#
With wsBackup
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
Set rngHeader = .Range("A1:O1")
For i = 2 To LastRow
' change ID next row
If .Cells(i, "A") <> .Cells(i + 1, "A") Then
' create new workbook
Set wbTemplate = Workbooks.Open(openfile)
.Range("A" & StartRow & ":O" & i).Copy wbTemplate.Sheets(2).Range("A2")
wbTemplate.SaveAs FileName:=strPath & ValidateFileName(Sheets(2).Cells(i, "C")) & ".xlsx"
wbTemplate.Close True
' move to next
StartRow = i + 1
n = n + 1
End If
Next
End With
Application.ScreenUpdating = True
MsgBox n & " billbacks created."
End Sub
Function ValidateFileName(ByVal sFileName As String) As String
Dim vInval As String
Dim i As Long
vInval = ":\/?|*[]{}<>~""#%&" & Chr(10) & Chr(13)
For i = 1 To Len(vInval)
sFileName = Replace(sFileName, Mid(vInval, i, 1), "_")
Next i
ValidateFileName = sFileName
End Function

VBA Excel Macro not responding after execution

I am trying to import data from Report file to my workbook file. Also to do it automatically with different files with new data, so that I can update my rows in the workbook file. The code opens the Report file after executing but it is not responding.
Sub Weekly_Report()
Path = "C:\Users\Documents\Report"
Filename = Dir(Report & "*.xlsx")
Do While Filename <> ""
Workbooks.Open Filename:=Path & Report, ReadOnly:=True
Loop
Dim starting_row As Long
header_exists = True 'If the file has a header and you don't want to import it, set this to True
starting_row = 1
If header_exists Then starting_row = 2
Dim first_blank_row As Long
first_blank_row = Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row 'Finds the last blank row
Dim r As Long
r = starting_row
Dim Filenames As String
Filenames = Path
Dim found As Range
Row = Workbooks(Filenames).ActiveSheet.Range("a" & r).Value
Do While Not Row = ""
Set found = Columns("x:x").Find(what:=Row, LookIn:=xlValues, lookat:=xlWhole)
If found Is Nothing Then
write_line_from_export Filenames, r, first_blank_row
first_blank_row = first_blank_row + 1
Else
write_line_from_export Filenames, r, found.Row
End If
r = r + 1
Row = Workbooks(Filenames).ActiveSheet.Range("a" & r).Value
Loop
End Sub
Sub write_line_from_export(Filenames As String, s As Long, d As Long)
For e = 1 To 69
Cells(d, e).Value = Workbooks(Filenames).ActiveSheet.Cells(s, e).Value
Next e
End Sub
Try this:
Sub Weekly_Report()
Const HAS_HEADER As Boolean = True '<< use contants for fixed values
Const NUM_COLS As Long = 69
Dim Path, Filename, wbReport As Workbook, wsReport As Worksheet, m
Dim wsData As Worksheet, next_blank_row As Long, r As Long, c As Range, rwStart As Long
Path = "C:\Users\Documents\Report\"
Filename = Dir(Path & "Report*.xlsx") '???
Set wsData = ThisWorkbook.Worksheets("Data") 'for example: destination worksheet
next_blank_row = next_blank_row = wsData.Cells(Rows.Count, 1).End(xlUp).Row + 1 'next blank row (edited)
'make sure row is really empty...
Do While Application.CountA(wsData.Rows(next_blank_row)) > 0
next_blank_row = next_blank_row + 1
Loop
Do While Filename <> ""
Set wbReport = Workbooks.Open(Path & Filename) '<< get a reference to the workbook
Set wsReport = wbReport.Worksheets(1) '<< assumes only one sheet
rwStart = IIf(HAS_HEADER, 2, 1)
For r = rwStart To wsReport.Cells(Rows.Count, 1).End(xlUp).Row
'Match is faster than Find
m = Application.Match(wsReport.Cells(r, 1).Value, wsData.Columns("X"), 0)
If IsError(m) Then
m = next_blank_row 'no match - use next blank row and increment
next_blank_row = next_blank_row + 1
End If
'don't go cell-by-cell
wsData.Cells(m, 1).Resize(1, NUM_COLS).Value = _
wsReport.Cells(r, 1).Resize(1, NUM_COLS).Value
Next r
wbReport.Close False
Filename = Dir()
Loop
End Sub

Selecting a Excel sheet based on number

I'm new to macros and VBA in Excel. Is there a way to check if the Testvalue is between Value 1 and Value 2, and move to the corresponding sheet? And if it's not, move to the next row and repeat.
E.g.
With the testvalue 3742 sheet A21 should be selected.
Simply iterate over each row until required condition is met:
Dim testVal As Long, r As Integer
Dim yourSheet As Worksheet
Set yourSheet = Sheet1
With yourSheet
testVal = .Range("E2").Value
r = 2
Do Until (.Range("A" & r).Value <= testVal) And _
(.Range("B" & r).Value >= testVal)
ThisWorkbook.Worksheets(.Range("C" & r).Value).Activate
r = r + 1
Loop
End With
In my opinion, instead of looping each row is faster if you use Find method.
Sub test()
Dim rngSearchA As Range, rngSearchB As Range, rngFoundA As Range, rngFoundB As Range
Dim strValue As String, strSheetName As String
Dim LastRowA As Long, LastRowB As Long
With ThisWorkbook.Worksheets("Sheet1")
strValue = .Range("E2").Value
strSheetName = ""
LastRowA = .Cells(.Rows.Count, "A").End(xlUp).Row
LastRowB = .Cells(.Rows.Count, "B").End(xlUp).Row
Set rngSearchA = .Range("A2:A" & LastRowA)
Set rngSearchB = .Range("B2:B" & LastRowB)
Set rngFoundA = rngSearchA.Find(strValue, LookIn:=xlValues, Lookat:=xlWhole)
Set rngFoundB = rngSearchB.Find(strValue, LookIn:=xlValues, Lookat:=xlWhole)
If Not rngFoundA Is Nothing And Not rngFoundB Is Nothing Then
If .Range("C" & rngFoundA.Row).Value <> .Range("C" & rngFoundB.Row).Value Then
MsgBox "Searching value appears in both columns with different Sheet name."
Else
strSheetName = .Range("C" & rngFoundA.Row).Value
End If
ElseIf Not rngFoundA Is Nothing Or Not rngFoundB Is Nothing Then
If Not rngFoundA Is Nothing Then
strSheetName = .Range("C" & rngFoundA.Row).Value
Else
strSheetName = .Range("C" & rngFoundB.Row).Value
End If
Else
MsgBox "Value not found!"
End If
If strSheetName <> "" Then
ThisWorkbook.Worksheets(strSheetName).Activate
End If
End With
End Sub

Looping through multiple sheets at once

I am trying to run through a column and get the value in the cell. The value is a unique code and only appears once on the first sheet.
When i get a value, it could be the first cell, i want to go through a column in sheet 4. The unique code can appear multiple times on sheet 4.
I want to match the code from sheet one with the code from sheet 4. If the codes are matching, i want to save the colum value on the row index and insert it into a completely new workbook.
Sub exportSheet2()
Const START_ROW = 11
Const MAX_ROW = 40
Const CODE_SHT1 = "C"
Const CODE_SHT4 = "E"
Const CVR_SHT4 = "C"
Const CVR_SHT3 = "C"
Const WB_OUTPUT = "MyResult.xlsx"
' sheet 4 columns
'C - Employer CVR MD
'D - Employer name
'E - broker code
'F - Broker name
'? Employer CVR CER
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws4 As Worksheet, wsNew As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long
Dim msg As String, i As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionExceptionReport")
Set ws4 = wb.Sheets("MasterData")
Dim dict As Object, sKey As String, ar As Variant
Set dict = CreateObject("Scripting.Dictionary")
' build dictionary from sheet4 of code to rows number
iLastRow = ws4.Cells(Rows.count, CODE_SHT4).End(xlUp).Row
For iRow = 13 To iLastRow
sKey = ws4.Cells(iRow, CODE_SHT4)
If dict.exists(sKey) Then
dict(sKey) = dict(sKey) & ";" & iRow ' matched row on sheet 1
Else
dict(sKey) = iRow
End If
Next
' scan down sheet1
count = 0: countWB = 0
iRow = START_ROW
Do Until (ws1.Cells(iRow, CODE_SHT1) = "END") Or (iRow > MAX_ROW)
sKey = ws1.Cells(iRow, CODE_SHT1)
If dict.exists(sKey) Then
' rows on sheet4 to copy
ar = Split(dict(sKey), ";")
'create new workbook and copy rows
Dim Pheight As Integer
Pheight = 25000
Set WkSht_Src = ThisWorkbook.Worksheets(2)
Set Rng = WkSht_Src.Range(ThisWorkbook.Worksheets(2).Cells(1, 1), ThisWorkbook.Worksheets(2).Cells(Pheight, 48))
Set WkBk_Dest = Application.Workbooks.Add
Set WkSht_Dest = WkBk_Dest.Worksheets(1)
Rng.Copy
WkSht_Dest.Range("A1").PasteSpecial xlPasteValuesAndNumberFormats
Rng.Copy
WkSht_Dest.Range("A1").PasteSpecial xlPasteFormats
WkSht_Src.Pictures(1).Copy
WkSht_Dest.Range("A1").PasteSpecial
WkSht_Dest.Pictures(1).Top = 5
WkSht_Dest.Pictures(1).Left = 0
iTargetRow = 11
Set wsNew = WkSht_Dest
Set wbNew = WkBk_Dest
For i = LBound(ar) To UBound(ar)
iCopyRow = ar(i)
iTargetRow = iTargetRow + 1
' copy selected cols to new workbook
ws4.Range("C" & iCopyRow).Resize(1, 5).Copy wsNew.Range("A" & iTargetRow)
count = count + 1
Next
wbNew.SaveAs sKey & ".xlsx"
wbNew.Close
countWB = countWB + 1
End If
iRow = iRow + 1
Loop
MsgBox dict.count & " keys in dictionary ", vbInformation
msg = iLastRow & " rows scanned on sheet4 " & vbCr & _
count & " rows copied to " & countWB & " new workbooks"
MsgBox msg, vbInformation
End Sub '''
Use a Dictionary Object not a loop in a loop.
Sub exportSheet2()
Const START_ROW = 11
Const MAX_ROW = 40
Const CODE_SHT1 = "C"
Const CODE_SHT4 = "E"
Const CVR_SHT4 = "C"
Const CVR_SHT3 = "C"
' sheet 4 columns
'C - Employer CVR MD
'D - Employer name
'E - broker code
'F - Broker name
'? Employer CVR CER
Dim wb As Workbook, wbNew As Workbook
Dim ws1 As Worksheet, ws3 As Worksheet, ws4 As Worksheet, wsNew As Worksheet
Dim iRow As Long, iLastRow, iTargetRow As Long, iCopyRow As Long
Dim msg As String, i As Integer, j As Integer
Dim count As Long, countWB As Integer
Dim WkSht_Src As Worksheet
Dim WkBk_Dest As Workbook
Dim WkSht_Dest As Worksheet
Dim Rng As Range
Set wb = ThisWorkbook
Set ws1 = wb.Sheets("BrokerSelect")
Set ws3 = wb.Sheets("ContributionExceptionReport")
Set ws4 = wb.Sheets("MasterData")
Dim dict As Object, dictCVR As Object, sKey As String, ar As Variant
Dim sCVR As String, arCVR As Variant
Set dict = CreateObject("Scripting.Dictionary")
Set dictCVR = CreateObject("Scripting.Dictionary")
' build dictionary from sheet4 of code to rows number
iLastRow = ws4.Cells(Rows.count, CODE_SHT4).End(xlUp).Row
For iRow = 13 To iLastRow
sKey = ws4.Cells(iRow, CODE_SHT4)
If dict.exists(sKey) Then
dict(sKey) = dict(sKey) & ";" & iRow ' matched row on sheet 1
Else
dict(sKey) = iRow
End If
Next
' build dictCVR from sheet3
iLastRow = ws3.Cells(Rows.count, CVR_SHT3).End(xlUp).Row
For iRow = 18 To iLastRow
sKey = ws3.Cells(iRow, CVR_SHT3)
If dictCVR.exists(sKey) Then
dictCVR(sKey) = dictCVR(sKey) & ";" & iRow
Else
dictCVR(sKey) = iRow
End If
Next
' scan down sheet1
count = 0: countWB = 0
iRow = START_ROW
Do Until (ws1.Cells(iRow, CODE_SHT1) = "END") Or (iRow > MAX_ROW)
sKey = ws1.Cells(iRow, CODE_SHT1)
If dict.exists(sKey) Then
' rows on sheet4 to copy
ar = Split(dict(sKey), ";")
'create new workbook and copy rows
Set WkSht_Src = wb.Worksheets(2)
Set Rng = WkSht_Src.Range("A1:AV25000")
Set WkBk_Dest = Application.Workbooks.Add
Set WkSht_Dest = WkBk_Dest.Worksheets(1)
With WkSht_Dest
Rng.Copy
.Range("A1").PasteSpecial xlPasteValuesAndNumberFormats
.Range("A1").PasteSpecial xlPasteFormats
WkSht_Src.Pictures(1).Copy
.Range("A1").PasteSpecial
.Pictures(1).Top = 5
.Pictures(1).Left = 0
End With
Application.CutCopyMode = False
iTargetRow = 11
Set wsNew = WkSht_Dest
Set wbNew = WkBk_Dest
For i = LBound(ar) To UBound(ar)
iCopyRow = ar(i)
iTargetRow = iTargetRow + 1
' copy selected cols to new workbook
ws4.Range("C" & iCopyRow).Resize(1, 5).Copy wsNew.Range("A" & iTargetRow)
' add cvr records from sheet3 it any
sCVR = ws4.Cells(iCopyRow, CVR_SHT4)
If dictCVR.exists(sCVR) Then
arCVR = Split(dictCVR(sCVR), ";")
For j = LBound(arCVR) To UBound(arCVR)
If j > 0 Then iTargetRow = iTargetRow + 1
' copy col A to P
iCopyRow = arCVR(j)
Debug.Print sCVR, j, iCopyRow
ws3.Range("A" & iCopyRow).Resize(1, 16).Copy wsNew.Range("E" & iTargetRow)
count = count + 1
Next
Else
count = count + 1
End If
Next
wbNew.SaveAs sKey & ".xlsx"
wbNew.Close
countWB = countWB + 1
End If
iRow = iRow + 1
Loop
msg = dict.count & " keys in CODE dictionary" & vbCr & _
dictCVR.count & " keys in CVR dictionary"
MsgBox msg, vbInformation
msg = iLastRow & " rows scanned on sheet4 " & vbCr & _
count & " rows copied to " & countWB & " new workbooks"
MsgBox msg, vbInformation
End Sub '''

Select the rows (A:J) if column E contains more than 4 Cells with value. Next selective print the selected Rows. repeat process till last value

Select the rows (A:J) if column E contains more than 4 Cells with value. Next is to selective print the selected Rows. Then it need to repeat the process until the last filled cell. Have been searching for a macro to get tenter link description herehis done for weeks but sadly to no avail.
Hope you all can assist me on this.
After being select as such i believe i could just proceed with printing under "printing selection" setting
This is one of the printed result of the 2 selected row
Added code from comments
Sub EnquiryPrep()
Dim x As Integer
Dim rng As Range
With ActiveSheet
LR = .Range("a" & Rows.Count).End(xlUp).Row
For Each cell In .Range("e7:e" & LR)
If cell.Value <> "" Then
If rng Is Nothing Then
Set rng = cell.Offset(, -4).Resize(, 10)
Else
Set rng = Union(rng, cell.Offset(, -4).Resize(, 10))
End If
End If
Next cell
rng.Select
End With
End Sub
Put this into your ThisWorkbook Code
WHAT IS OUTPUT FROM DEBUG.PRINT statments?? Cut/Paste from Immediate
window below code
Try:
Sub PrintValidRows()
Const SHEET_NUM As Integer = 1 ' Which Sheet to Use
Const CHECK_COL As Integer = 5 ' Column E
Const START_ROW As Integer = 8
Const MIN_FILLED As Integer = 5 ' Min number required for print
Const LAST_COL As String = "H" ' Last column to print
Dim lastCellBlank As Boolean
Dim lngRow As Long
Dim lngLastRow As Long
Dim lngStartRow As Long
Dim intNumFilled As Integer
Dim strRange As String
Dim strPrintRange As String
Dim ws As Worksheet
Set ws = Sheets(SHEET_NUM)
ws.Activate
ws.Cells(1, 1).Select
intNumFilled = 0
' Get last row of data
lngLastRow = ActiveCell.SpecialCells(xlLastCell).Row
Debug.Print "Last Row: "; lngLastRow
lngStartRow = START_ROW
For lngRow = START_ROW To lngLastRow
If IsEmpty(Cells(lngRow, CHECK_COL)) Then
If intNumFilled >= MIN_FILLED Then
strRange = "A" & lngStartRow & ":" & LAST_COL & lngRow - 1
Debug.Print "Adding Range: " & strRange
If lngStartRow = START_ROW Then ' first range
strPrintRange = strRange
Else
strPrintRange = strPrintRange & "," & strRange
End If
End If
' Reset Filled Cell Counter
intNumFilled = 0
' Reset StartRow to next row
lngStartRow = lngRow + 1
Else
intNumFilled = intNumFilled + 1
End If
Next lngRow
' Check for last set of data
If intNumFilled >= MIN_FILLED Then
strRange = "A" & lngStartRow & ":" & LAST_COL & lngRow - 1
Debug.Print "Adding Range: " & strRange
If lngStartRow = START_ROW Then ' first range
strPrintRange = strRange
Else
strPrintRange = strPrintRange & "," & strRange
End If
End If
' Show Print Range in Immediate Window
Debug.Print "Print Range: " & strPrintRange
If strPrintRange <> "" Then
Range(strPrintRange).Select
End If
' You can record a macro to get it to printout exactly what how want
' REMOVE THIS TO TEST HIGHLIGHTING
'Application.Selection.PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
End Sub

Resources