Convert range to 1 column without blank cells

Kra

Board Regular
Joined
Jul 4, 2022
Messages
160
Office Version
  1. 365
Platform
  1. Windows
Hi all!

I need help with converting range into one column. I was able to get VBA code which works fine, but it is creating empty rows if cell from range was empty. Is there any way to ignore empty cells?

VBA Code:
Sub ConvertRangeToColumn()
Dim Range1 As Range, Range2 As Range, Rng As Range
Dim rowIndex As Integer
xTitleId = "Move to one column"
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Convert to (single cell):", xTitleId, Type:=8)
rowIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Rows
    Rng.Copy
    Range2.Offset(rowIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
    rowIndex = rowIndex + Rng.Columns.Count
Next
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
 

Excel Facts

Ambidextrous Undo
Undo last command with Ctrl+Z or Alt+Backspace. If you use the Undo icon in the QAT, open the drop-down arrow to undo up to 100 steps.
Rather than try to "guess" what your data looks like, and try to reverse engineer your code, it would be much better for us to see a sample of what your data looks like initially, and what you want the output to look like.

MrExcel has a tool called “XL2BB” that lets you post samples of your data that will allow us to copy/paste it to our Excel spreadsheets, so we can work with the same copy of data that you are. Instructions on using this tool can be found here: XL2BB Add-in

Note that there is also a "Test Here” forum on this board. This is a place where you can test using this tool (or any other posting techniques that you want to test) before trying to use those tools in your actual posts.
 
Upvote 0
Rather than try to "guess" what your data looks like, and try to reverse engineer your code, it would be much better for us to see a sample of what your data looks like initially, and what you want the output to look like.

MrExcel has a tool called “XL2BB” that lets you post samples of your data that will allow us to copy/paste it to our Excel spreadsheets, so we can work with the same copy of data that you are. Instructions on using this tool can be found here: XL2BB Add-in

Note that there is also a "Test Here” forum on this board. This is a place where you can test using this tool (or any other posting techniques that you want to test) before trying to use those tools in your actual posts.
Understand, here it is:

1. I got range of data in cells A3:E13. I need to have them in one clear line in one column. Code I posted lets me choose range (I select A3 to E13), then lets me choose output cell (I select J1). But the code do not ignores empty cells, it creates empty rows in Column J. I need to be able to select range with empty cells, like in this case, and move them to one Column like it is shown in mini sheet column J:

Test.xlsx
ABCDEFGHIJ
1Input:Output:VALUE 1
2VALUE 2
3VALUE 1VALUE 4VALUE 10VALUE 18VALUE 21VALUE 3
4VALUE 2VALUE 5VALUE 11VALUE 19VALUE 22VALUE 4
5VALUE 3VALUE 6VALUE 12VALUE 20VALUE 23VALUE 5
6VALUE 7VALUE 13VALUE 24VALUE 6
7VALUE 8VALUE 14VALUE 25VALUE 7
8VALUE 9VALUE 15VALUE 26VALUE 8
9VALUE 16VALUE 27VALUE 9
10VALUE 17VALUE 28VALUE 10
11VALUE 29VALUE 11
12VALUE 30VALUE 12
13VALUE 31VALUE 13
14VALUE 14
15VALUE 15
16VALUE 16
17VALUE 17
18VALUE 18
19VALUE 19
20VALUE 20
21VALUE 21
22VALUE 22
23VALUE 23
24VALUE 24
25VALUE 25
26VALUE 26
27VALUE 27
28VALUE 28
29VALUE 29
30VALUE 30
31VALUE 31
Sheet3
 
Upvote 0
You can just add additional code to your code that selects the range you pasted to, and select the blank cells, then deletes them, shifting everything else up, like this:
VBA Code:
Sub ConvertRangeToColumn()
Dim Range1 As Range, Range2 As Range, Rng As Range
Dim lr As Long
Dim rowIndex As Integer
xTitleId = "Move to one column"
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Convert to (single cell):", xTitleId, Type:=8)
rowIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Rows
    Rng.Copy
    Range2.Offset(rowIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
    rowIndex = rowIndex + Rng.Columns.Count
Next
Application.CutCopyMode = False

'Find last row in column of Range2 with data
lr = Cells(Rows.Count, Range2.Column).End(xlUp).Row
'Remove all blanks from final paste range
Range(Cells(Range2.Row, Range2.Column), Cells(lr, Range2.Column)).SpecialCells(xlCellTypeBlanks).Delete Shift:=xlUp

Application.ScreenUpdating = True
End Sub
 
Upvote 0
How about with a formula?
Two options, one does what your macro is doing & the other gives the data as you have shown it.
Fluff.xlsm
ABCDEFGHI
1Input:Output:
2VALUE 1VALUE 1
3VALUE 1VALUE 4VALUE 10VALUE 18VALUE 21VALUE 4VALUE 2
4VALUE 2VALUE 5VALUE 11VALUE 19VALUE 22VALUE 10VALUE 3
5VALUE 3VALUE 6VALUE 12VALUE 20VALUE 23VALUE 18VALUE 4
6VALUE 7VALUE 13VALUE 24VALUE 21VALUE 5
7VALUE 8VALUE 14VALUE 25VALUE 2VALUE 6
8VALUE 9VALUE 15VALUE 26VALUE 5VALUE 7
9VALUE 16VALUE 27VALUE 11VALUE 8
10VALUE 17VALUE 28VALUE 19VALUE 9
11VALUE 29VALUE 22VALUE 10
12VALUE 30VALUE 3VALUE 11
13VALUE 31VALUE 6VALUE 12
14VALUE 12VALUE 13
15VALUE 20VALUE 14
16VALUE 23VALUE 15
17VALUE 7VALUE 16
18VALUE 13VALUE 17
19VALUE 24VALUE 18
20VALUE 8VALUE 19
21VALUE 14VALUE 20
22VALUE 25VALUE 21
23VALUE 9VALUE 22
24VALUE 15VALUE 23
25VALUE 26VALUE 24
26VALUE 16VALUE 25
27VALUE 27VALUE 26
28VALUE 17VALUE 27
29VALUE 28VALUE 28
30VALUE 29VALUE 29
31VALUE 30VALUE 30
32VALUE 31VALUE 31
33
Main
Cell Formulas
RangeFormula
H2:H32H2=LET(data,A3:E13,c,COLUMNS(data),s,SEQUENCE(c*ROWS(data),,0),x,INDEX(data,INT(s/c)+1,MOD(s,c)+1),FILTER(x,x<>""))
I2:I32I2=LET(data,A3:E13,r,ROWS(data),s,SEQUENCE(r*COLUMNS(data),,0),x,INDEX(data,MOD(s,r)+1,INT(s/r)+1),FILTER(x,x<>""))
Dynamic array formulas.
 
Upvote 0
How about with a formula?
Two options, one does what your macro is doing & the other gives the data as you have shown it.
Fluff.xlsm
ABCDEFGHI
1Input:Output:
2VALUE 1VALUE 1
3VALUE 1VALUE 4VALUE 10VALUE 18VALUE 21VALUE 4VALUE 2
4VALUE 2VALUE 5VALUE 11VALUE 19VALUE 22VALUE 10VALUE 3
5VALUE 3VALUE 6VALUE 12VALUE 20VALUE 23VALUE 18VALUE 4
6VALUE 7VALUE 13VALUE 24VALUE 21VALUE 5
7VALUE 8VALUE 14VALUE 25VALUE 2VALUE 6
8VALUE 9VALUE 15VALUE 26VALUE 5VALUE 7
9VALUE 16VALUE 27VALUE 11VALUE 8
10VALUE 17VALUE 28VALUE 19VALUE 9
11VALUE 29VALUE 22VALUE 10
12VALUE 30VALUE 3VALUE 11
13VALUE 31VALUE 6VALUE 12
14VALUE 12VALUE 13
15VALUE 20VALUE 14
16VALUE 23VALUE 15
17VALUE 7VALUE 16
18VALUE 13VALUE 17
19VALUE 24VALUE 18
20VALUE 8VALUE 19
21VALUE 14VALUE 20
22VALUE 25VALUE 21
23VALUE 9VALUE 22
24VALUE 15VALUE 23
25VALUE 26VALUE 24
26VALUE 16VALUE 25
27VALUE 27VALUE 26
28VALUE 17VALUE 27
29VALUE 28VALUE 28
30VALUE 29VALUE 29
31VALUE 30VALUE 30
32VALUE 31VALUE 31
33
Main
Cell Formulas
RangeFormula
H2:H32H2=LET(data,A3:E13,c,COLUMNS(data),s,SEQUENCE(c*ROWS(data),,0),x,INDEX(data,INT(s/c)+1,MOD(s,c)+1),FILTER(x,x<>""))
I2:I32I2=LET(data,A3:E13,r,ROWS(data),s,SEQUENCE(r*COLUMNS(data),,0),x,INDEX(data,MOD(s,r)+1,INT(s/r)+1),FILTER(x,x<>""))
Dynamic array formulas.
I am not able to use formulas sadly, because this sheet will be used by many people and they will place data in random places. Is it possible to add this kind of sorting into a code?
 
Upvote 0
You can just add additional code to your code that selects the range you pasted to, and select the blank cells, then deletes them, shifting everything else up, like this:
VBA Code:
Sub ConvertRangeToColumn()
Dim Range1 As Range, Range2 As Range, Rng As Range
Dim lr As Long
Dim rowIndex As Integer
xTitleId = "Move to one column"
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Convert to (single cell):", xTitleId, Type:=8)
rowIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Rows
    Rng.Copy
    Range2.Offset(rowIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
    rowIndex = rowIndex + Rng.Columns.Count
Next
Application.CutCopyMode = False

'Find last row in column of Range2 with data
lr = Cells(Rows.Count, Range2.Column).End(xlUp).Row
'Remove all blanks from final paste range
Range(Cells(Range2.Row, Range2.Column), Cells(lr, Range2.Column)).SpecialCells(xlCellTypeBlanks).Delete Shift:=xlUp

Application.ScreenUpdating = True
End Sub
Works amazing, thanks! Is it possible to take this data sorted? Or it is too much to ask?
 
Upvote 0
If you want to sort the data, then there is no reason for us to delete the blanks, because sorting will move them to the bottom automatically.
So we can replace the "Delete" code with some "Sort" code like this:
VBA Code:
Sub ConvertRangeToColumn()

Dim Range1 As Range, Range2 As Range, Rng As Range, Range3 As Range
Dim lr As Long
Dim rowIndex As Integer
xTitleId = "Move to one column"
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Convert to (single cell):", xTitleId, Type:=8)
rowIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Rows
    Rng.Copy
    Range2.Offset(rowIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
    rowIndex = rowIndex + Rng.Columns.Count
Next
Application.CutCopyMode = False

'Find last row in column of Range2 with data
lr = Cells(Rows.Count, Range2.Column).End(xlUp).Row
'Set range to sort
Set Range3 = Range(Cells(Range2.Row, Range2.Column), Cells(lr, Range2.Column))
'Sort range
Range3.Sort Key1:=Range2, Order1:=xlAscending, Header:=xlYes, OrderCustom:=1, _
    MatchCase:=False, Orientation:=xlTopToBottom
        
Application.ScreenUpdating = True

End Sub
 
Upvote 0
If you want to sort the data, then there is no reason for us to delete the blanks, because sorting will move them to the bottom automatically.
So we can replace the "Delete" code with some "Sort" code like this:
VBA Code:
Sub ConvertRangeToColumn()

Dim Range1 As Range, Range2 As Range, Rng As Range, Range3 As Range
Dim lr As Long
Dim rowIndex As Integer
xTitleId = "Move to one column"
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Convert to (single cell):", xTitleId, Type:=8)
rowIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Rows
    Rng.Copy
    Range2.Offset(rowIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
    rowIndex = rowIndex + Rng.Columns.Count
Next
Application.CutCopyMode = False

'Find last row in column of Range2 with data
lr = Cells(Rows.Count, Range2.Column).End(xlUp).Row
'Set range to sort
Set Range3 = Range(Cells(Range2.Row, Range2.Column), Cells(lr, Range2.Column))
'Sort range
Range3.Sort Key1:=Range2, Order1:=xlAscending, Header:=xlYes, OrderCustom:=1, _
    MatchCase:=False, Orientation:=xlTopToBottom
       
Application.ScreenUpdating = True

End Sub
Now it is sorting in an odd way. As you can see in column A there are values starting with "9TF". After running a macro (results in column L) first 9TF in on the top of the list and second on the bottom.

Test.xlsx
ABCDEFGHIJKLM
19TF000138
29B0001940
39B0002071
49B0002102
59B0002218
69D0003126
79D0003127
89D0003376
99D0003434
109TF0001389B00021029D00033769K00086339D0003577
119TF0002819B00019409D00034349K00086349D0003578
129B00022189D00031269K00086359K0007648
139B00020719D00031279K00088569K0007649
149D00035779K00088579K0007650
159D00035789K00076489K0007651
169K00076499K0007652
179K00076509K0007653
189K00076519K0008175
199K00076529K0008633
209K00076539K0008634
219K00081759K0008635
229K00093349K0008856
239K00093359K0008857
249K00093369K0009334
259K00093379K0009335
269K00093389K0009336
279K00093399K0009337
289K00093409K0009338
299K00093419K0009339
309K00093429K0009340
319K00093439K0009341
329K0009342
339K0009343
349TF000281
35
X
 
Upvote 0
Whoops, had a bad setting.

This part of the code:
VBA Code:
Header:=xlYes
should actually be this:
VBA Code:
Header:=xlNo

So the final code would look like:
VBA Code:
Sub ConvertRangeToColumn()

Dim Range1 As Range, Range2 As Range, Rng As Range, Range3 As Range
Dim lr As Long
Dim rowIndex As Integer
xTitleId = "Move to one column"
Set Range1 = Application.Selection
Set Range1 = Application.InputBox("Source Ranges:", xTitleId, Range1.Address, Type:=8)
Set Range2 = Application.InputBox("Convert to (single cell):", xTitleId, Type:=8)
rowIndex = 0
Application.ScreenUpdating = False
For Each Rng In Range1.Rows
    Rng.Copy
    Range2.Offset(rowIndex, 0).PasteSpecial Paste:=xlPasteAll, Transpose:=True
    rowIndex = rowIndex + Rng.Columns.Count
Next
Application.CutCopyMode = False

'Find last row in column of Range2 with data
lr = Cells(Rows.Count, Range2.Column).End(xlUp).Row
'Set range to sort
Set Range3 = Range(Cells(Range2.Row, Range2.Column), Cells(lr, Range2.Column))
'Sort range
Range3.Sort Key1:=Range2, Order1:=xlAscending, Header:=xlNo, OrderCustom:=1, _
    MatchCase:=False, Orientation:=xlTopToBottom
        
Application.ScreenUpdating = True

End Sub
 
Upvote 0
Solution

Forum statistics

Threads
1,214,978
Messages
6,122,549
Members
449,089
Latest member
davidcom

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