Try this macro, to be copied within the vba module "ThisWorkbook":
VBA Code:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Dim myC As Range
'
For Each myC In Sheets("Sheet1").Range("D17:D40") '<<<<<
If myC.Value = "" And myC.Offset(0, 1).Value <> "" Or _
myC.Value <> 0 And myC.Offset(0, 1).Value = "" Then
MsgBox ("Please fill Description & Quantity")
myC.Select
Cancel = True
Exit Sub
End If
Next myC
End Sub
It will check that any description have a quantity and viceversa (each qty corresponds to a description)
Check the range set in the line marked with <<<<, it should reflect the height of the table to be printed; I dont know if you have additional information at the bottom of the table, so I didn't try to find the last used line in columns D & E
Note that if what you have to print is a structured Table that it would not be a problem to identify the lenght of the columns, because vba can address any of them as ListColumns.DataBodyRange. I mean that if you use a structured table, and it is named Table1, and Item # is column 1, then the macro to use would be
VBA Code:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
Dim myC As Range
'
For Each myC In Sheets("Sheet1").ListObjects("Table1").ListColumns(2).DataBodyRange '<<<<
If myC.Value = "" And myC.Offset(0, 1).Value <> "" Or _
myC.Value <> 0 And myC.Offset(0, 1).Value = "" Then
MsgBox ("Please fill Description & Quantity")
myC.Select
Cancel = True
Exit Sub
End If
Next myC
End Sub
The line marked <<< will automatically addrress the whole second column (Qty) whichever is its height.
Bye