Attached is XLSM (VBA) for transposing rows to columns.
Transpose Varying rows to columns.
If the data is consistent Use TransposeRows the number of columns to be copied and transposed.
If the number of rows for each set is varying then use the TransposeRows2 procedure.
' Please note the code checks the Font color for the end of the record and transposes them to columns so If you need
' anything other than the color Maybe a specific word like 'end' then it can be used instead of the font color.
Sub TransposeRows()
' Convert Rows to Columns specify the range in this case it is 9 rows offset
Dim rng As Range
Dim i As Long
Dim MyRange As Range
Dim lngLastRow As Long
lngLastRow = Sheet1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
MsgBox lngLastRow
Set rng = Sheet1.Range("A1")
i = 1
J = 9
Do While rng.Value <> ""
rng.Resize(J).Copy
Sheet2.Range("A" & i).PasteSpecial Transpose:=True
Set rng = rng.Offset(J)
'MsgBox Sheet2.Range("A" & i).Font.ColorIndex
i = i + 1
Loop
Application.CutCopyMode = False
End Sub
Sub TransposeRows2()
' Transpose Varying rows to columns.
' Please note the code checks the Font color for end of the record and transposes them to columns so If you need
' anything other than the color like say a specific word like end then it can be used instead of the font color.
Dim rng As Range
Dim i As Long
Dim MyRange As Range
Dim lngLastRow As Long
lngLastRow = Sheet1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'MsgBox lngLastRow
Set rng = Sheet1.Range("A1")
i = 1
J = 0
K = 1
J1 = 0
F = 0
Do While rng.Value <> ""
Do Until Sheet1.Range("A" & K).Font.ColorIndex <> 49 And Sheet1.Range("A" & K).Font.ColorIndex <> 16 And Sheet1.Range("A" & K).Font.ColorIndex <> 50 And Sheet1.Range("A" & K).Font.ColorIndex <> 46 And Sheet1.Range("A" & K).Font.ColorIndex <> 55 'And (Sheet1.Range("A" & K).Font.ColorIndex = 50 Or Sheet1.Range("A" & K).Font.ColorIndex = 16)
K = K + 1
Loop
F = F + J
J = K - F
' K = K + 1
J1 = J
If Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
'If Sheet1.Range("A" & K + 1).Font.ColorIndex = 16 And Sheet1.Range("A" & K + 1).Font.ColorIndex = 18 And Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
K = K + 1
End If
rng.Resize(J).Copy
If Sheet1.Range("A" & K).Font.ColorIndex = 18 Then 'Or Sheet1.Range("A" & K).Font.ColorIndex = 16 Or Sheet1.Range("A" & K).Font.ColorIndex = 50 Then
'J = 0
K = K + 1
End If
Sheet3.Range("A" & i).PasteSpecial Transpose:=True
Set rng = rng.Offset(J)
i = i + 1
Loop
Application.CutCopyMode = False
End Sub
But how would we do it for varying rows like one set being 9 rows and another being 16 rows and so on?
Sub TransposeRows2()
Dim rng As Range
Dim i As Long
Dim MyRange As Range
Dim lngLastRow As Long
lngLastRow = Sheet1.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'MsgBox lngLastRow
Set rng = Sheet1.Range("A1")
i = 1
J = 0
K = 1
J1 = 0
F = 0
Do While rng.Value <> ""
Do Until Sheet1.Range("A" & K).Font.ColorIndex <> 49 And Sheet1.Range("A" & K).Font.ColorIndex <> 16 And Sheet1.Range("A" & K).Font.ColorIndex <> 50 And Sheet1.Range("A" & K).Font.ColorIndex <> 46 And Sheet1.Range("A" & K).Font.ColorIndex <> 55 'And (Sheet1.Range("A" & K).Font.ColorIndex = 50 Or Sheet1.Range("A" & K).Font.ColorIndex = 16)
K = K + 1
Loop
F = F + J
J = K - F
' K = K + 1
J1 = J
If Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
'If Sheet1.Range("A" & K + 1).Font.ColorIndex = 16 And Sheet1.Range("A" & K + 1).Font.ColorIndex = 18 And Sheet1.Range("A" & K).Font.ColorIndex <> 49 Then
K = K + 1
End If
rng.Resize(J).Copy
If Sheet1.Range("A" & K).Font.ColorIndex = 18 Then 'Or Sheet1.Range("A" & K).Font.ColorIndex = 16 Or Sheet1.Range("A" & K).Font.ColorIndex = 50 Then
'J = 0
K = K + 1
End If
Sheet3.Range("A" & i).PasteSpecial Transpose:=True
Set rng = rng.Offset(J)
i = i + 1
Loop
Application.CutCopyMode = False
End Sub
Related
I have written a piece of code that does reconciliation:
The first part checks between columns.
Works absolutely fine on upto 100k Rows, then simply freezes on anything bigger. Is the an optimal way to write this? Should I be using a scripting dictionary for the reconciliation too? Ive been off VBA for a while now and I am pretty rusty! Thanks for reading and helping.
Sub AutoRecon()
Worksheets("Main_Recon").Select
Dim i As Long, _
LRa As Long, _
LRb As Long, _
rowx As Long
LRa = Range("A" & Rows.Count).End(xlUp).Row
LRb = Range("G" & Rows.Count).End(xlUp).Row
rowx = 2
Application.ScreenUpdating = False
For i = 2 To LRa
If Range("A" & i).Errors.Item(xlNumberAsText).Value = True Then
Range("A" & i).Value = "N" & Range("A" & i).Value
rowx = rowx + 1
End If
Next i
rowx = 2
For i = 2 To LRb
If Range("G" & i).Errors.Item(xlNumberAsText).Value = True Then
Range("G" & i).Value = "N" & Range("G" & i).Value
rowx = rowx + 1
End If
Next i
rowx = 2
For i = 2 To LRa
If IsError(Application.Match(Range("A" & i).Value, Range("G2:G" & LRb), 0)) Then
Range("O" & rowx).Value = Range("A" & i).Value
rowx = rowx + 1
End If
Next i
rowx = 2
For i = 2 To LRb
If IsError(Application.Match(Range("G" & i).Value, Range("A2:A" & LRa), 0)) Then
Range("S" & rowx).Value = Range("G" & i).Value
rowx = rowx + 1
End If
Next i
Application.ScreenUpdating = True
End Sub
This takes too long.
The issue is that you run the loop 4 times, but you can combine 2 loops.
You can gain some speed in the process using arrays to read/write. Every read/write action to a cell needs a lot of time. So the idea is to read all data cells into an array DataA at once (only 1 read action) then process the data in the array and then write it back to the cells at once (only 1 write action). So if you have 100 rows you save 99 read/write actions.
So you would end up with something like below. Note this is untested, so backup before running this.
Option Explicit
Public Sub AutoRecon()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Main_Recon")
Application.ScreenUpdating = False
'find last rows of columns
Dim LastRowA As Long
LastRowA = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim LastRowG As Long
LastRowG = ws.Cells(ws.Rows.Count, "G").End(xlUp).Row
'read data into array
Dim DataA() As Variant 'read data from column A into array
DataA = ws.Range("A1", "A" & LastRowA).Value
Dim DataG() As Variant 'read data from column G into array
DataG = ws.Range("G1", "G" & LastRowG).Value
Dim iRow As Long
For iRow = 2 To Application.Max(LastRowA, LastRowG) 'combine loop to the max of both columns
If iRow <= LastRowA Then 'run only until max of column A
If ws.Cells(iRow, "A").Errors.Item(xlNumberAsText).Value = True Then
DataA(iRow, 1) = "N" & DataA(iRow, 1)
End If
End If
If iRow <= LastRowG Then 'run only until max of column G
If ws.Cells(iRow, "G").Errors.Item(xlNumberAsText).Value = True Then
DataG(iRow, 1) = "N" & DataG(iRow, 1)
End If
End If
Next iRow
'write array back to sheet
ws.Range("A1", "A" & LastRowA).Value = DataA
ws.Range("G1", "G" & LastRowG).Value = DataG
'read data into array
Dim DataO() As Variant 'read data from column O into array (max size = column A)
DataO = ws.Range("O1", "O" & LastRowA).Value
Dim DataS() As Variant 'read data from column G into array (max size = column G)
DataS = ws.Range("S1", "S" & LastRowG).Value
Dim oRow As Long, sRow As Long
oRow = 2 'output row start
sRow = 2
For iRow = 2 To Application.Max(LastRowA, LastRowG) 'combine loop to the max of both columns
If iRow <= LastRowA Then
If IsError(Application.Match(DataA(iRow, 1), DataG, 0)) Then
DataO(oRow, 1) = DataA(iRow, 1)
oRow = oRow + 1
End If
End If
If iRow <= LastRowG Then
If IsError(Application.Match(DataG(iRow, 1), DataA, 0)) Then
DataS(sRow, 1) = DataG(iRow, 1)
sRow = sRow + 1
End If
End If
Next iRow
'write array back to sheet
ws.Range("O1", "O" & LastRowA).Value = DataO
ws.Range("S1", "S" & LastRowG).Value = DataS
Application.ScreenUpdating = True
End Sub
I have a table which contains merged cells both column and rows as shown in attached picture. I want to unmerge "Only" rows while leaving columns merged. Consider the following snippet of table. In the image attached "Contract
For y = 1 To lRow
p = 1
c = y
d = 1
z = lRow + y
t = Cells(y, 1).Value
For x = 1 To t
Cells(z, p).Value = Cells(c, d).Value
Cells(c, d).Select
' Debug.Print
Selection.End(xlToRight).Select
c = ActiveCell.Row
d = ActiveCell.Column
p = p + 1
Next
Next
Sub ColorMergedCells()
Dim c As Range
Dim startcolumn, endcolumn, startrow, endrow As Long
For Each c In ActiveSheet.UsedRange
If c.MergeCells And c.MergeArea.Rows.Count >= 2 Then
c.Interior.ColorIndex = 28
With c.MergeArea.Rows
.UnMerge
' .Formula = c.Formula
End With
'
'startcolumn = ActiveCell.Column
'endcolumn = Selection.Columns.Count + startcolumn - 1
'startrow = ActiveCell.Row
'endrow = Selection.Rows.Count + startrow - 1
End If
Next
End Sub
Based on your snapshot of requirements , I have wrote a very simple code which shall appear to be crude but I have kept it this way so that you can adjust its various elements as per your actual data. Sample data taken by me and results obtained are shown in the snapshot pasted below, which is followed by code.
Sub Merge_unmerge()
Dim wb As Workbook
Dim ws As Worksheet
Dim rng As Range
Dim cell As Range
Dim LastRow As Long
Dim LastCol As Long
Set wb = ThisWorkbook
Set ws = wb.Sheets(1)
With ws
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
Set rng = ws.Range("A1:D" & LastRow)
For Each cell In rng
cell.UnMerge
Next cell
For i = 2 To LastRow
If Range("A" & i) = "" Then
Range("A" & i).Value = Range("A" & i - 1).Value
End If
Next i
For i = 2 To LastRow
If Range("D" & i) = "" Then
Range("D" & i).Value = Range("D" & i - 1).Value
End If
Next i
For i = 1 To LastRow Step 2
Range("B" & i & ":C" & i).Merge
Range("B" & i & ":C" & i).HorizontalAlignment = xlCenter
Next i
End Sub
Never mind. I solved for the issue at hand. Posting if it helps others.
Sub ColorMergedCells()
Dim c As Range
Dim startcolumn, endcolumn, startrow, endrow As Long
For Each c In ActiveSheet.UsedRange
If c.MergeCells And c.MergeArea.Rows.Count >= 2 Then
c.Interior.ColorIndex = 28
startcolumn = c.Column
endcolumn = c.MergeArea.Columns.Count + startcolumn - 1
startrow = c.Row
endrow = c.MergeArea.Rows.Count + startrow - 1
With c.MergeArea.Rows
.UnMerge
.Formula = c.Formula
End With
For J = startrow To endrow
Application.DisplayAlerts = False
Range(Cells(J, startcolumn), Cells(J, endcolumn)).Merge
Application.DisplayAlerts = True
Next
End If
Next
End Sub
I am building on some code, partly cut and paste from other posts. I need to concatenate with a VBA code keeping the format and running through rows to output in last cell in each row. (Can't paste image) so hope description is clear:
In A1:D1 values are RED,BLUE,GREEN
In A2:D2 Values are YELLOW,PURPLE,ORANGE
OUTPUT IN E1 should concatenate these values, keeping font colour. Each value should have "ALT ENTR" to give line break.
Next row should be displayed in E2, and so on
'************************************************************************************
Sub test()
Dim rng As Range: Set rng = Application.Range("a1:c1") 'Not yet looping
Dim row As Range
For Each row In rng.Rows
'Debug.Print col.Column
Call concatenate_cells_formats(Cells(1, 4), rng) 'Not yet looping
Next row
End Sub
Sub concatenate_cells_formats(cell As Range, source As Range)
'Anon
Dim c As Range
Dim i As Integer
i = 1
With cell
.Value = vbNullString
.ClearFormats
For Each c In source
.Value = .Value & " " & Trim(c)
Next c
.Value = Trim(.Value)
For Each c In source
With .Characters(Start:=i, Length:=Len(Trim(c))).Font
.Name = c.Font.Name
.FontStyle = c.Font.FontStyle
.Size = c.Font.Size
.Strikethrough = c.Font.Strikethrough
.Superscript = c.Font.Superscript
.Subscript = c.Font.Subscript
.OutlineFont = c.Font.OutlineFont
.Shadow = c.Font.Shadow
.Underline = c.Font.Underline
.ColorIndex = c.Font.ColorIndex
End With
.Characters(Start:=i + Len(c), Length:=1).Font.Size = 1
i = i + Len(Trim(c)) + 1
Next c
End With
End Sub
'*****************************************************************************
Option Explicit
Sub concColour()
Dim i As Long, j As Long, s As Long, l As Long, clr As Long, vals As Variant
With Worksheets("sheet4")
For i = 1 To .Cells(.Rows.Count, "A").End(xlUp).Row
vals = Application.Transpose(Application.Transpose(Intersect(.Range("A:D"), .Rows(i)).Value2))
.Cells(i, "E") = Join(vals, vbLf)
s = 1
For j = LBound(vals) To UBound(vals)
l = Len(vals(j))
clr = .Cells(i, "A").Offset(0, j - 1).Font.Color
With .Cells(i, "E").Characters(Start:=s, Length:=l).Font
.Color = clr
End With
s = s + l + 1
Next j
.Cells(i, "E").Font.Size = 4
Next i
End With
End Sub
enter image description here
I think you require something like this. Change source font and formats as per your requirement.
Sub Adding_T()
Dim lena As Integer
Dim lenc As Integer
Dim lend As Integer
Dim lene As Integer
Dim LastRow As Long
Dim nrow As Long
With Worksheets("Sheet2") 'Change sheet as per your requirement
LastRow = .Cells(.Rows.Count, "A").End(xlUp).row
For nrow = 1 To LastRow
.Range("E" & nrow) = .Range("A" & nrow).Value2 & Chr(13) & Chr(10) & .Range("B" & nrow).Value2 & _
Chr(13) & Chr(10) & .Range("C" & nrow).Value2 & Chr(13) & Chr(10) & .Range("D" & nrow).Value2
lena = Len(.Range("A" & nrow).Value2)
lenc = lena + 2 + Len(.Range("B" & nrow).Value2)
lend = lenc + 2 + Len(.Range("C" & nrow).Value2)
lene = lend + 2 + Len(.Range("D" & nrow).Value2)
For i = 1 To lena
.Range("E" & nrow).Characters(Start:=i, Length:=1).Font.Color = _
.Range("A" & nrow).Characters(Start:=i, Length:=1).Font.Color
Next i
For i = lena + 2 To lenc
.Range("E" & nrow).Characters(Start:=i, Length:=1).Font.Color = _
.Range("B" & nrow).Characters(Start:=i, Length:=1).Font.Color
Next i
For i = lenc + 2 To lend
.Range("E" & nrow).Characters(Start:=i, Length:=1).Font.Color = _
.Range("C" & nrow).Characters(Start:=i, Length:=1).Font.Color
Next i
For i = lend + 2 To lene
.Range("E" & nrow).Characters(Start:=i, Length:=1).Font.Color = _
.Range("D" & nrow).Characters(Start:=i, Length:=1).Font.Color
Next i
Next
End With
End Sub
Snapshot of trial:
EDIT: OP Preferred code does not permit looping through the Range. Amended his Sub Test() to allow looping through the range.
Sub Test2()
Dim ws As Worksheet
Dim LastRow As Long
Set ws = ThisWorkbook.ActiveSheet
Dim rng As Range
Dim row As Range
Dim rw As Long
LastRow = ws.Cells(Rows.Count, "A").End(xlUp).row
rw = 1
For rw = 1 To LastRow
Set rng = ws.Range("A" & rw & ":C" & rw)
Call concatenate_cells_formats(Cells(rw, 4), rng)
Next
End Sub
Results are as per snapshot appended here.
I have this code and it works just fine.
The only problem is that after i press enter ,in cell "A2" for example, instead of moving down to cell "A3", like it normally would - it moves to cell "E3", so it makes hard on the user to type.
Any suggestions?
Private Sub Worksheet_change(ByVal Target As Range)
Application.EnableEvents = False
Range("A2:M2").Interior.ColorIndex = 19
Dim LASTROW As Long
TheLastRow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
Dim intx As Variant
For i = 2 To TheLastRow
If Range("a" & i) = Range("a" & i + 1) Then
Range("A" & i + 1 & ":n" & i + 1).Interior.Color = Range("a" & i).Interior.Color
intx = intx + 0
Else
Range("A" & i + 1 & ":n" & i + 1).Interior.ColorIndex = 46 - intx
intx = intx + 1
End If
Next i
For i = 2 To TheLastRow
Range("e" & i).Select
ActiveCell.FormulaR1C1 = _
"=IF(ISBLANK(RC[-1]),"""",HYPERLINK(""PCDOCS://PCDOCS_JLM/""&RC[-1]&""/R"",""link""))"
Next i
Application.EnableEvents = True
End Sub
You should avoid using SELECT or ACTIVATE in VBA, so:
Private Sub Worksheet_change(ByVal Target As Range)
Application.EnableEvents = False
Range("A2:M2").Interior.ColorIndex = 19
Dim LASTROW As Long
TheLastRow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
Dim intx As Variant
For i = 2 To TheLastRow
If Range("a" & i) = Range("a" & i + 1) Then
Range("A" & i + 1 & ":n" & i + 1).Interior.Color = Range("a" & i).Interior.Color
intx = intx + 0
Else
Range("A" & i + 1 & ":n" & i + 1).Interior.ColorIndex = 46 - intx
intx = intx + 1
End If
Next i
For i = 2 To TheLastRow
Range("e" & i).FormulaR1C1 = _
"=IF(ISBLANK(RC[-1]),"""",HYPERLINK(""PCDOCS://PCDOCS_JLM/""&RC[-1]&""/R"",""link""))"
Next i
Application.EnableEvents = True
End Sub
I made some modifications to your code, and when I press {enter} on cell "A2" it performs the code and "jumps" to cell "A3".
Code
Option Explicit
Private Sub Worksheet_change(ByVal Target As Range)
Dim C As Range
Dim intx As Long
Application.EnableEvents = False
Range("A2:M2").Interior.ColorIndex = 19
' loop through all cells with data in column "A"
For Each C In Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row)
If C.Value = C.Offset(1, 0).Value Then
C.Offset(1, 0).Resize(1, 14).Interior.Color = C.Interior.Color
Else
C.Offset(1, 0).Resize(1, 14).Interior.Color = 46 - intx
intx = intx + 1
End If
Next C
' loop through all cells with data in column "E"
For Each C In Range("E2:E" & Cells(Rows.Count, "E").End(xlUp).Row)
C.FormulaR1C1 = "=IF(ISBLANK(RC[-1]),"""",HYPERLINK(""PCDOCS://PCDOCS_JLM/""&RC[-1]&""/R"",""link""))"
Next C
Application.EnableEvents = True
End Sub
You can Read out the Address from the Cell that Trigert the Event and save them.
After your code is done, you can select the Cell, 1 Row below.
Hope this Helps.
Private Sub Worksheet_change(ByVal Target As Range)
Application.EnableEvents = False
Dim rngAddress As String
rngAddress = Target.Address
Range("A2:M2").Interior.ColorIndex = 19
Dim LASTROW As Long
TheLastRow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
Dim intx As Variant
For i = 2 To TheLastRow
If Range("a" & i) = Range("a" & i + 1) Then
Range("A" & i + 1 & ":n" & i + 1).Interior.Color = Range("a" & i).Interior.Color
intx = intx + 0
Else
Range("A" & i + 1 & ":n" & i + 1).Interior.ColorIndex = 46 - intx
intx = intx + 1
End If
Next i
For i = 2 To TheLastRow
Range("e" & i).Select
ActiveCell.FormulaR1C1 = _
"=IF(ISBLANK(RC[-1]),"""",HYPERLINK(""PCDOCS://PCDOCS_JLM/""&RC[-1]&""/R"",""link""))"
Next i
Range(rngAddress).offset(1,0).select
Application.EnableEvents = True
End Sub
I have multiple rows which are sometimes in order and sometimes not.
Out of rows which are in order, I would need to create a range, which are not in order just to copy the number.
The thing is, the most rows in order can be even 20.
For example cells:
1
3
5
6
7
8
9
10
13
14
15
There would be:
1
3
5-10
13-15
Is it possible to code it?
Thanks
Assuming your data starts with A1.... and
required results will be printed at C column.
Try with below code
Sub test()
Dim i As Long, lastrow As Long, incre As Long
Dim startno As Variant
Dim endno As Variant
incre = 1
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastrow
If Cells(i, 1) = (Cells(i + 1, 1) - 1) Then
startno = Cells(i, 1)
Do While Cells(i, 1) = (Cells(i + 1, 1) - 1)
endno = Cells(i + 1, 1)
i = i + 1
Loop
Cells(incre, 3) = "'" & startno & "-" & endno
incre = incre + 1
Else
Cells(incre, 3) = Cells(i, 1)
incre = incre + 1
End If
Next i
End Sub
if you want the address of all consecutive ranges you could use:
Option Explicit
Sub main()
Dim rangeStrng As String
With Worksheets("MyRowsSheet") '<--| change "MyRowsSheet" with your actual sheet name
rangeStrng = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeConstants).Areas.Parent.Address(False, False)
End With
End Sub
if you want only the rows range then you could use:
Option Explicit
Sub main2()
Dim rng As Range
Dim rowsRangeStrng As String
With Worksheets("MyRowsSheet") '<--| change "MyRowsSheet" with your actual sheet name
For Each rng In .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeConstants).Areas
If rng.Rows.Count = 1 Then
rowsRangeStrng = rowsRangeStrng & rng.Rows(1).Row & ","
Else
rowsRangeStrng = rowsRangeStrng & rng.Rows(1).Row & "-" & rng.Rows(rng.Rows.Count).Row & ","
End If
Next rng
End With
If rowsRangeStrng <> "" Then rowsRangeStrng = Left(rowsRangeStrng, Len(rowsRangeStrng) - 1)
End Sub
If I understood your question correctly, you are not looking to address a range, but rather want an output table. This code below should provide you with just that. My input numbers are in column A, and the output is in column B.
Sub sequentials()
Dim tws As Worksheet
Dim tmpRowA, tmpRowB As Integer
Dim seq() As Long
Dim frA, frB, lrA As Integer 'firstrow col A, col B, lastrow of data
Set tws = ThisWorkbook.Worksheets("Sheet1")
frA = 2
frB = 2
lrA = tws.Range("A1000000").End(xlUp).Row
'Input in column A, Output in column B
'Headers in Row 1
ReDim seq(0 To lrA - 1)
seq(0) = -2
seq(1) = tws.Range("A" & frA).Value
tmpRowA = frA
tmpRowB = frB
tws.Range("B" & frB & ":B" & lrA).NumberFormat = "#"
For r = frA + 1 To lrA
If r = 23 Then
r = 23
End If
With tws
seq(r - 1) = .Range("A" & r).Value
If seq(r - 1) = seq(r - 2) + 1 Then
If r = lrA Then
.Range("B" & tmpRowB).Value = .Range("A" & tmpRowA - 1).Value & "-" & seq(r - 1)
End If
Else
If seq(r - 2) = seq(r - 3) + 1 Then
.Range("B" & tmpRowB).Value = .Range("A" & tmpRowA - 1).Value & "-" & seq(r - 2)
Else
.Range("B" & tmpRowB).Value = seq(r - 2)
End If
tmpRowB = tmpRowB + 1
tmpRowA = r + 1
If r = lrA Then
.Range("B" & tmpRowB).Value = seq(r - 1)
End If
End If
End With
Next r
End Sub
Proof of concept: