I’d do it with a countblank() function in column D. Then sort for D and delete all rows that have a higher value than 0.
If the initial order is to be preserved, simply add a counter (1,2,3,…) before you sort. Remember to sort all(!) coloums. If you want to have the initial order back, simply sort for you counter column.
A low-tech solution that could work over many rows, very quickly and very easily:
(1) Make sure your row 1 is a “header” row, select and enable Data > Filter > AutoFilter. You’ll get something like this:
(2) Now click on the filter toggle in Column B and select the “empty” check box, so that only those rows with an empty cell in the B column will be active:
(3) Now select those rows:
(4) With the rows selected, right-click in the row number gutter and choose the “Delete selected rows” option:
(5) Now click on the Column B filter toggle again, and this time select “All” to remove the filter:
(6) Result: rows with empty cells in Column B are gone, total operation time is just a few seconds:
Row data of course remains intact, so there’s no need to worry about sort-order with this method.
There’s more than one solution to this problem, and the best one for you depends on the nature of your data, etc. Hope this helps.