Code to move rows with a blank cell/s to top of range

L. Howard

Well-known Member
Joined
Oct 16, 2012
Messages
4,514
With a range that the number of rows will vary and the number of columns will vary I want to do this:

For each row in range if row cell/s = blank then move row to top of range, next row.

Where "cell/s" would be a cell or a few cells but not a completely blank row.

End results would look like this:

First row with blank cell would be first row of new range, 2nd row with a blank would the next until all rows with a blank are at the top of the range and all rows without a blank are below in the order they originally were.

Title says I want code but if Excel sort functions can do this that seems okay with me.

Thanks.
Howard
 

Excel Facts

What does custom number format of ;;; mean?
Three semi-colons will hide the value in the cell. Although most people use white font instead.
With a range that the number of rows will vary and the number of columns will vary I want to do this:

For each row in range if row cell/s = blank then move row to top of range, next row.

Where "cell/s" would be a cell or a few cells but not a completely blank row.

End results would look like this:

First row with blank cell would be first row of new range, 2nd row with a blank would the next until all rows with a blank are at the top of the range and all rows without a blank are below in the order they originally were.

Title says I want code but if Excel sort functions can do this that seems okay with me.

Thanks.
Howard
Adjust the range R address to match your range:
Code:
Sub BlanksToTop()
Dim R As Range, newR As Range, rw As Range, n As Long
Set R = Range("A1:G18") 'Adjust range to suit
Application.ScreenUpdating = False
R.EntireColumn.Insert
Set newR = R.Offset(0, -R.Columns.Count)
For Each rw In R.Rows
    If WorksheetFunction.CountA(rw) < rw.Cells.Count Then
        n = n + 1
        newR.Rows(n).Value = rw.Value
    End If
Next rw
For Each rw In R.Rows
    If WorksheetFunction.CountA(rw) = rw.Cells.Count Then
        n = n + 1
        newR.Rows(n).Value = rw.Value
    End If
Next rw
R.Value = newR.Value
newR.EntireColumn.Delete
End Sub
 
Upvote 0
L. Howard,

Sample raw data:


Excel 2007
ABCDEFGH
1Title ATitle BTitle CTitle DTitle ETitle FTitle GTitle H
22222
33333
4
555555555
6
77
88
9
101010
1111
12
1313
14
Sheet1


After the macro:


Excel 2007
ABCDEFGH
1Title ATitle BTitle CTitle DTitle ETitle FTitle GTitle H
2
3
4
5
62222
73333
855555555
97
108
111010
1211
1313
14
Sheet1


Please TEST this FIRST in a COPY of your workbook (always make a backup copy before trying new code, you never know what you might lose).

Code:
Option Explicit
Sub MoveBlankRowsUP()
' hiker95, 04/13/2013
' http://www.mrexcel.com/forum/excel-questions/696918-code-move-rows-blank-cell-s-top-range.html
Dim r As Long, lr As Long, lc As Long, n As Long, nn As Long
lr = Cells.Find("*", , xlValues, xlWhole, xlByRows, xlPrevious, False).Row
lc = Cells.Find("*", , xlValues, xlWhole, xlByColumns, xlPrevious, False).Column
nn = 0
For r = lr To 2 Step -1
  n = Application.CountA(Range(Cells(r, 1), Cells(r, lc)))
  If n = 0 Then
    nn = nn + 1
    Rows(r).Delete
  End If
Next r
If nn > 0 Then
  Rows(2).Resize(nn).Insert
End If
End Sub

Before you use the macro with Excel 2007 or newer, save your workbook, Save As, a macro enabled workbook with the file extension .xlsm

Then run the MoveBlankRowsUP macro.
 
Upvote 0
Hi JoeMoe and Hiker95,

Thanks for your responses.

My bad where I may have done a "Ready, Fire, Aim"

My range is A2:AJ200, w/ Headers in A1:AJ1. The range may change but I don't think the code will needs to try to adjust to any varying range size, I believe if I name the range and apply the code to the named range I will be okay.

My big bad is we can key on column S alone, if it is blank then move "Range("Sx").Offset(0, -18).Resize(1, 36)" to the top, next blank S under the previous.

Thanks.
Howard
 
Upvote 0
Hi JoeMoe and Hiker95,

Thanks for your responses.

My bad where I may have done a "Ready, Fire, Aim"

My range is A2:AJ200, w/ Headers in A1:AJ1. The range may change but I don't think the code will needs to try to adjust to any varying range size, I believe if I name the range and apply the code to the named range I will be okay.

My big bad is we can key on column S alone, if it is blank then move "Range("Sx").Offset(0, -18).Resize(1, 36)" to the top, next blank S under the previous.

Thanks.
Howard
I revised my code so you can select the range you want to reorder when prompted. Do not include the header row.
Code:
Sub BlanksToTop()
Dim R As Range, newR As Range, rw As Range, n As Long

On Error Resume Next
Set R = Application.InputBox("Use your mouse to select the range you want to reorder. Do not include any header row.", Type:=8)
If R Is Nothing Then Exit Sub
On Error GoTo 0
Application.ScreenUpdating = False
R.EntireColumn.Insert
Set newR = R.Offset(0, -R.Columns.Count)
For Each rw In R.Rows
    If WorksheetFunction.CountA(rw) < rw.Cells.Count Then
        n = n + 1
        newR.Rows(n).Value = rw.Value
    End If
Next rw
For Each rw In R.Rows
    If WorksheetFunction.CountA(rw) = rw.Cells.Count Then
        n = n + 1
        newR.Rows(n).Value = rw.Value
    End If
Next rw
R.Value = newR.Value
newR.EntireColumn.Delete
End Sub
 
Last edited:
Upvote 0
I tried the revised code where at the InputBox prompt I selected A2:AJ200, click OK. Long pause w/ hour glass, 10 to 15 seconds and page reverts to sheet module, no error noted. Sheet remains unchanged.

If I select column S for Input Box prompt works fine to move all column S blanks to top, but not the row data from A to AJ with it.

Any ideas? Am I using the code correctly?

Howard
 
Last edited:
Upvote 0
L. Howard,

Sample raw data:


Excel 2007
ARSTAJ
1ARSTAJ
222222
333333
44444
555555
66666
777777
888888
99999
101010101010
111111111111
1212121212
131313131313
1414141414
1515151515
161616161616
171717171717
181818181818
1919191919
202020202020
2121212121
222222222222
232323232323
242424242424
2525252525
262626262626
272727272727
2828282828
292929292929
3030303030
31
Sheet1


After the very fast macro using arrays in memory:


Excel 2007
ARSTAJ
1ARSTAJ
24444
36666
49999
512121212
614141414
715151515
819191919
921212121
1025252525
1128282828
1230303030
1322222
1433333
1555555
1677777
1788888
181010101010
191111111111
201313131313
211616161616
221717171717
231818181818
242020202020
252222222222
262323232323
272424242424
282626262626
292727272727
302929292929
31
Sheet1


Please TEST this FIRST in a COPY of your workbook (always make a backup copy before trying new code, you never know what you might lose).

Code:
Option Explicit
Sub MoveBlank_S_UP()
' hiker95, 04/13/2013
' http://www.mrexcel.com/forum/excel-questions/696918-code-move-rows-blank-cell-s-top-range.html
Dim a As Variant, b As Variant, s As Variant
Dim lr As Long, lc As Long, n As Long, nr As Long
Dim i As Long, ii As Long, iii As Long, c As Long
lr = Cells(Rows.Count, 1).End(xlUp).Row
lc = Cells(1, Columns.Count).End(xlToLeft).Column
n = Application.CountA(Range("S2:S" & lr))
a = Range("A2:AJ" & lr)
ReDim b(1 To UBound(a, 1), 1 To UBound(a, 2))
ReDim s(1 To lr - n - 1, 1 To UBound(a, 2))
For i = 1 To UBound(a, 1)
  If a(i, 19) = "" Then
    ii = ii + 1
    For c = 1 To UBound(a, 2)
      s(ii, c) = a(i, c)
    Next c
  Else
    iii = iii + 1
    For c = 1 To UBound(a, 2)
      b(iii, c) = a(i, c)
    Next c
  End If
Next i
Range("A2:AJ" & lr).ClearContents
Range("A2").Resize(UBound(s, 1), UBound(s, 2)) = s
nr = Range("A" & Rows.Count).End(xlUp).Offset(1).Row
Range("A" & nr).Resize(UBound(b, 1), UBound(b, 2)) = b
End Sub

Before you use the macro with Excel 2007 or newer, save your workbook, Save As, a macro enabled workbook with the file extension .xlsm

Then run the MoveBlank_S_UP macro.
 
Upvote 0
Hi Hiker95,

Nailed it!!!!

Very nice and bullet fast.
I will probably never learn to how dump data to an array to be processed and dump it back to the sheet but it sure works well.

I run this little snippet, which contributes to some blanks in Col. S and along comes your gold nugget and cleans it all up.

Code:
Option Explicit
Sub Col_S_Failed_Del()
Dim c As Range
For Each c In Range("S:S")
  If c.Value = "Failed" Then
    c.Offset(0, -1).Resize(1, 2).ClearContents
  End If
Next
MoveBlank_S_UP
End Sub

Thanks very much, I appreciate it.

Regards,
Howard
 
Upvote 0
L. Howard,

Thanks for the feedback.

You are very welcome. Glad I could help.

And, come back anytime.
 
Upvote 0

Forum statistics

Threads
1,214,653
Messages
6,120,750
Members
448,989
Latest member
mariah3

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top