Ok, this should work
Please add the Microsoft Scripting Runtime reference to your project to allow for early binding of dictionary objects
'#################################################################################################################################
'# requires microsoft scripting runtime
'#################################################################################################################################
Public Sub pub_sub_ExportRows()
'#
'# declare private variables
'#
Dim pvt_xls_Current As Excel.Worksheet
Dim pvt_rng_Current As Excel.Range
Dim pvt_lng_AreaNumber As Long
Dim pvt_lng_FirstColumn As Long
Dim pvt_lng_LastColumn As Long
Dim pvt_flg_ValidRow As Boolean
Dim pvt_flg_ValidSelection As Boolean
Dim pvt_lng_RowNumber As Long
Dim pvt_lng_ColumnNumber As Long
Dim pvt_dct_ValidColumn As Scripting.Dictionary
Dim pvt_dct_ValidRow As Scripting.Dictionary
Dim pvt_int_ColumnElement As Integer
Dim pvt_int_RowElement As Integer
Dim pvt_wbk_New As Excel.Workbook
Dim pvt_lng_TargetColumn As Long
Dim pvt_lng_TargetRow As Long
'#
'# initialise
'#
Set pvt_xls_Current = ThisWorkbook.ActiveSheet
Set pvt_rng_Current = Selection
Set pvt_dct_ValidRow = New Scripting.Dictionary
Set pvt_dct_ValidColumn = New Scripting.Dictionary
pvt_flg_ValidSelection = False
'#
'# the maximum number of columns to be considered is not dependent on the columns defined in the
'# worksheet, but rather by a limit imposed by the user - i.e. column HG is the last column to be copied,
'# and column Q is the first column to be considered
'#
pvt_lng_FirstColumn = Columns("Q").Column
pvt_lng_LastColumn = Columns("HG").Column
'#
'# identify all rows in the user selection and add the rows to the valid row dictionary with an
'# indication that the row is invalid - only when later one or more filled cells are found for the
'# row in question will the status be changed to valid
'#
For pvt_lng_AreaNumber = 1 To pvt_rng_Current.Areas.Count
For pvt_lng_RowNumber = pvt_rng_Current.Areas(pvt_lng_AreaNumber).Row To (pvt_rng_Current.Areas(pvt_lng_AreaNumber).Row + pvt_rng_Current.Areas(pvt_lng_AreaNumber).Rows.Count - 1)
pvt_dct_ValidRow.Add pvt_lng_RowNumber, "INVALID"
Next pvt_lng_RowNumber
Next pvt_lng_AreaNumber
'#
'# for all rows in the selection a check is performed to see if one or more non-empty cells are found -
'# when found the column is valid for the copy step and the row is valid because one or more non-blank cells were found
'#
With pvt_xls_Current
For pvt_int_RowElement = 0 To (pvt_dct_ValidRow.Count - 1)
'#
'# initialise row variables for the current row of the selected area
'#
pvt_flg_ValidRow = False
pvt_lng_RowNumber = pvt_dct_ValidRow.Keys(pvt_int_RowElement)
'#
'# loop for all columns between Q and HG, skipping the columns that should be ignored as per the requirements -
'# if the cell is not empty then the column is valid and should be included in the copy step, and the row is also
'# considered valid (non-blank) because a valid entry has been found
'#
For pvt_lng_ColumnNumber = pvt_lng_FirstColumn To pvt_lng_LastColumn
If InStr(1, "$AF,$BF,$CG,$DH,$ES,$FV,$HD, $HF,", Split(Columns(pvt_lng_ColumnNumber).Address, ":")(0) & ",") = 0 Then
If LenB(.Cells(pvt_lng_RowNumber, pvt_lng_ColumnNumber).Value) > 0 Then
pvt_flg_ValidRow = True
If Not pvt_dct_ValidColumn.Exists(pvt_lng_ColumnNumber) Then
pvt_dct_ValidColumn.Add pvt_lng_ColumnNumber, "VAL"
End If
End If
End If
Next pvt_lng_ColumnNumber
'#
'# if one or more non-empty cells were encountered for the current row, the row is considered a valid
'# row for the copy step, if not a message is presented to the user
'#
If pvt_flg_ValidRow Then
pvt_dct_ValidRow(pvt_int_RowElement) = "VALID"
pvt_flg_ValidSelection = True
Else
MsgBox "Row number " & pvt_lng_RowNumber & " is skipped as all cells are empty"
End If
Next pvt_int_RowElement
End With
'#
'# if no rows have been selected
'#
If Not pvt_flg_ValidSelection Then
MsgBox "No valid rows selected, no new workbook created"
Exit Sub
End If
'#
'# the dictionary objects now hold all valid columns and all valid rows that should be included in the
'# copy workbook - create the new workbook and copy the data
'#
Set pvt_wbk_New = Application.Workbooks.Add
pvt_lng_TargetRow = 0
With pvt_xls_Current
'#
'# always create the header rows
'#
For pvt_lng_RowNumber = 4 To 5
pvt_lng_TargetColumn = 0
pvt_lng_TargetRow = pvt_lng_TargetRow + 1
For pvt_int_ColumnElement = 0 To (pvt_dct_ValidColumn.Count - 1)
pvt_lng_TargetColumn = pvt_lng_TargetColumn + 1
pvt_wbk_New.Worksheets("Sheet1").Cells(pvt_lng_TargetRow, pvt_lng_TargetColumn).Value = _
.Cells(pvt_lng_RowNumber, pvt_dct_ValidColumn.Keys(pvt_int_ColumnElement)).Value
Next pvt_int_ColumnElement
Next pvt_lng_RowNumber
'#
'# now loop for all valid rows as stored in the dictionary - and per row copy the valid columns again
'# from the dictionary
'#
For pvt_int_RowElement = 0 To (pvt_dct_ValidRow.Count - 1)
If pvt_dct_ValidRow(pvt_int_RowElement) = "VALID" Then
pvt_lng_RowNumber = pvt_dct_ValidRow.Keys(pvt_int_RowElement)
pvt_lng_TargetRow = pvt_lng_TargetRow + 1
pvt_lng_TargetColumn = 0
For pvt_int_ColumnElement = 0 To (pvt_dct_ValidColumn.Count - 1)
pvt_lng_TargetColumn = pvt_lng_TargetColumn + 1
pvt_wbk_New.Worksheets("Sheet1").Cells(pvt_lng_TargetRow, pvt_lng_TargetColumn).Value = _
.Cells(pvt_lng_RowNumber, pvt_dct_ValidColumn.Keys(pvt_int_ColumnElement)).Value
Next pvt_int_ColumnElement
End If
Next pvt_int_RowElement
End With
'#
'# set all columns in the new workbook to autofit and activate the new workbook
'#
With pvt_wbk_New
.Worksheets("Sheet1").Cells.Columns.AutoFit
.Activate
End With
End Sub
Bookmarks