I currently have a macro that inserts 3 rows when the value in Column E changes (Course Department). In the 3 rows I am trying to merge the middle row and add the department into this row. I can't work out how to get it to merge, any help would be appreciated.
With Range("e" & myHeader + 2, Range("e" & Rows.Count).End(xlUp)).Offset(, 1)
.Formula = _
"=if(and(r[-1]c[-1]<>"""",rc[-1]<>"""",r[-1]c[-1]<>rc[-1])," & _
"if(r[-1]c=1,""a"",1),"""")"
.Value = .Value
On Error Resume Next
For i = 1 To 3
.SpecialCells(2, 1).EntireRow.Insert
.SpecialCells(2, 2).EntireRow.Insert
Next
This is how it is currently:
This is what I would like to have:
When inserting or deleting rows, work from the bottom up. Some simple offsets and resizing should be sufficient to insert the three rows, merge the cells and transfer the values.
Option Explicit
Sub insertDept3()
Dim i As Long
With Worksheets("sheet10")
For i = .Cells(.Rows.Count, "E").End(xlUp).Row - 1 To 1 Step -1
If .Cells(i, "E").Value <> .Cells(i + 1, "E").Value Or i = 1 Then
.Cells(i + 1, "A").Resize(3, 5).Insert shift:=xlDown
.Cells(i + 2, "A").Resize(1, 5).Merge
.Cells(i + 2, "A") = .Cells(i + 4, "E").Value
End If
Next i
End With
End Sub
I will leave the cell alignment and font formatting to you.
The below code loop column E, import three lines when the value change, merger Column A to column E , import and format value in the middle line.
Try:
Option Explicit
Sub test()
Dim i As Long, Lastrow As Long
Dim Department As String, NextDepartment As String
With ThisWorkbook.Worksheets("Sheet1")
Lastrow = .Cells(.Rows.Count, "E").End(xlUp).Row
For i = Lastrow To 2 Step -1
Department = .Range("E" & i).Value
NextDepartment = .Range("E" & i).Offset(-1, 0).Value
If Department <> NextDepartment Then
.Rows(i).EntireRow.Resize(3).Insert
.Range("A" & i + 1 & ":E" & i + 1).Merge
With .Range("A" & i + 1)
.Value = Department
.Font.Bold = True
.HorizontalAlignment = xlLeft
.VerticalAlignment = xlCenter
End With
End If
Next i
End With
Output:
Related
I'm trying to merge all contiguous duplicate cells in column D. I don't care about the formatting of the cells, and i don't need to sum any of the values. Was wondering what was wrong with my below code since not all of my duplicate cells are merging...Can only assume i'm skipping over them accidentally
with thisworkbook.sheets("sheet1")
For i = StartRow + 1 To LastRow + 1
If Cells(i, 4) <> "" Then
If Cells(i, 4) <> Cells(i - 1, 4) Then
Application.DisplayAlerts = False
Range(Cells(i - 2, 4), Cells(StartMerge, 4)).Merge
Application.DisplayAlerts = True
StartMerge = i
End If
End If
Next i
End With
Close to your code:
(updated; deleted If Cells(i, 4) <> "" Then)
Sub test1()
With ThisWorkbook.Sheets("sheet1")
StartRow = 1
LastRow = .Cells(.Rows.Count, 4).End(xlUp).Row
StartMerge = StartRow + 1
Application.DisplayAlerts = False
For i = StartRow + 1 To LastRow
If .Cells(i, 4) <> .Cells(i + 1, 4) Then
.Range(.Cells(StartMerge, 4), .Cells(i, 4)).Merge
StartMerge = i + 1
End If
Next i
Application.DisplayAlerts = True
End With
End Sub
Result:
you can quickly have a view like below with a pivot table. Just an other idea without coding. Fyi.
Index, Evaluate and filter function approach to avoid loop through each cell. With these functions, following procedure creates an array of row numbers where a value in a cell does not match with the above cell value.
The array is then looped through to merge the desired "same" cells.
Sub MergeSameCells()
Dim ColRng As Range, RowArr
Application.DisplayAlerts = False
Set ColRng = Range("B2:B" & Range("B" & Rows.Count).End(xlUp).Row)
RowArr = Filter(Application.Transpose(Application.Index( _
Evaluate("IF((" & ColRng.Address & "<>" & ColRng.Offset(1).Address & _
"),ROW(" & ColRng.Address & "),""NA"")") _
, 0, 1)), "NA", False, vbTextCompare)
Debug.Print UBound(RowArr)
'result 5, So there will be 6 loops (Zero based array) instead of 13.
For i = UBound(RowArr) To 0 Step -1
If i = 0 Then
If RowArr(i) - 1 <> 1 Then
Range(Cells(2, "B"), Cells(RowArr(i), "B")).Merge
End If
Else
If RowArr(i) - RowArr(i - 1) <> 1 Then
Range(Cells(RowArr(i - 1) + 1, "B"), Cells(RowArr(i), "B")).Merge
End If
End If
Next i
Application.DisplayAlerts = True
End Sub
I have a sheet1 data in below format
I need VBA Code to vlookup in sheet2 on Group Id and Product ID in sheet1 and insert new row highlighted in yellow called BT order and populate 400 and 600 values from DMD column against Wk8 and Wk9 column which is vlookup value of week Num from second sheet.
Dim i As Long
For i = 2 To Range("E" & Rows.Count).End(xlUp).Row
If Trim(Range("E" & i).Value) = RTrim("CMT") Then
Rows(i + 1).Insert shift:=xlShiftDown
Range("A" & i + 1 & ":D" & i + 1).Value = Range("A" & i - 1 & ":D" & i - 1).Value
Range("E" & i + 1).Value = "BT/Order"
End If
Next i
Try this:
Sub Tester()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim i As Long, i2 As Long, grp, prod, amt, wk
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
Set ws2 = ThisWorkbook.Worksheets("Sheet2")
i = 2
Do While i <= ws1.Cells(Rows.Count, "E").End(xlUp).Row
If Trim(ws1.Range("E" & i).Value) = RTrim("CMT") Then
ws1.Rows(i + 1).Insert shift:=xlShiftDown
ws1.Cells(i + 1, "A").Resize(1, 4).Value = ws1.Cells(i, "A").Resize(1, 4).Value
ws1.Cells(i + 1, "E").Value = "BT/Order"
'current group/product id's
grp = ws1.Cells(i, "A").Value
prod = ws1.Cells(i, "C").Value
'loop sheet2 and find matches
For i2 = 2 To ws2.Cells(Rows.Count, 1).End(xlUp).Row
If ws2.Cells(i2, "A").Value = grp Then
If ws2.Cells(i2, "B").Value = prod Then
'got match - check amount and week
amt = ws2.Cells(i2, "D").Value
wk = ws2.Cells(i2, "E").Value
If amt > 0 Then
'insert amount in relevant column
ws1.Cells(i + 1, "F").Offset(0, wk).Value = amt
End If
End If
End If
Next i2
End If
i = i + 1
Loop
End Sub
Following code is suggested by a helpful user, this works well to Calculate "From", "To", "MAX" etc values of a range. But this code gives results in every row of a range. I want to get the results in only first row of each row. Please help with this.
Sub trial()
Dim lastrow As Long
Dim destSht As Worksheet
Dim i As Long, j As Long
Set destSht = Worksheets("Final")
With Worksheets("Source")
lastrow = .Range("B" & .Rows.Count).End(xlUp).Row
For i = 2 To lastrow + 1 'loop whole range (column C)
If .Cells(i, "C") <> "" Then 'If column C is not empty then
For j = i To lastrow + 1 'Loop "group" range to find next empty cell. Start from current loop i to last row and add one row to get to next empty cell.
If .Cells(j, "C") = "" Then 'When next empty cell is found (i.e. end of small group range) then apply formulas
.Cells(i, "E").Value = .Cells(i, "B").Value 'From
.Cells(i, "F").Value = .Cells(j - 1, "B").Value 'To
.Cells(i, "G").Formula = "=MAX(C" & i & ":C" & j - 1 & ")" 'MAX
.Cells(i, "H").Formula = "=MIN(C" & i & ":C" & j - 1 & ")" 'MIN
.Cells(i, "I").Formula = "=AVERAGE(C" & i & ":C" & j - 1 & ")" 'AVG
Exit For
End If
Next j
End If
Next I
End With
End Sub
This Code gives following result
Desired Result
Try changing this line:
If .Cells(i, "C") <> "" Then 'If column C is not empty then
To this line:
If .Cells(i, "C") <> "" AND .Cells(i-1, "C") = "" Then 'If column C is not empty AND the column C above is empty then
I don't believe this has already been asked or that anything similar has been asked. I am trying to separate my data set based on the values in a column. I would then like to insert 3 rows between them. Finally I would like to add formulas to the middle row of the three that I just added. My Frankenstein's code (made up from others bits and pieces) is:
Dim LastRow As Long
Dim i As Long
LastRow = Cells(Rows.Count, "AA").End(xlUp).Row
For i = LastRow To 2 Step -1
If i = 2 Then
'Do nothing
ElseIf Cells(i, "AA") <> Cells(i - 1, "AA") Then
Rows(i).Select
Selection.Insert Shift:=xlDown
Selection.Insert Shift:=xlDown
Selection.Insert Shift:=xlDown
End If
Next i
LR = Range("AA" & Rows.Count).End(xlUp).Row
Range("AA1:AA" & LR & "").Interior.Color = RGB(217, 217, 217)
Range("AA" & LR + 2).Formula = "=SUM(Z2:Z" & LR & ")"
As I am sure you'll notice the summation is after the bottom row and is for the whole column.
Thank you for any help you can give
You've made no mention of what sort of formula you would 'like to add formulas to the middle row of the three that I just added' so I've left in a placeholder.
Dim LastRow As Long, i As Long, lr As Long
With Sheets("Sheet5") 'set this worksheet reference properly!
LastRow = .Cells(Rows.Count, "AA").End(xlUp).Row
For i = LastRow To 3 Step -1
If .Cells(i, "AA").Value <> .Cells(i - 1, "AA").Value Then
.Cells(i, "AA").Resize(3, 1).EntireRow.Insert
.Cells(i + 1, "AA").Formula = "=SUM(AA2:AA" & i & ")"
End If
Next i
lr = .Range("AA" & Rows.Count).End(xlUp).Row
.Range("AA1:AA" & lr).Interior.Color = RGB(217, 217, 217)
.Range("AA" & lr + 2).Formula = "=SUM(Z2:Z" & lr & ")"
End With
There is also no mention of looking for and possibly removing previous summation formula(s) at hte bottom of the column that may have been left from previous run-throughs but I would suppose that this is to be performed on raw data each time.
My main problem is that I am trying to add a row directly beneath another row based on the time value of that row. Here's an example of what I'm trying to do:
column F ========> new column F
2 1
2
2 1
2
1 1
1 1
2 1
2
To better explain, if the value in the first column F is a 2, that represents a time value that is greater than 0:59:00 and another row is added beneath it. If it is a 1, then it represents a time value that is equal to or less than 0:59:00and no row gets added.
I have multiple coding attempts at fixing this, and this first one is by someone more well-versed in VBA than I and includes some of his comments:
Public Sub ExpandRecords()
Dim i As Long, _
j As Long, _
LR As Long
'set variable types
LR = Range("A" & Rows.Count).End(xlUp).Row
'setting variable LR as number of rows with data
Application.ScreenUpdating = False
Columns("F:F").NumberFormat = "hh:mm:ss"
'sets number format in column b to text
For i = LR To 1 Step -1
'Executes following code from last row with data to row 1 working backwards
'If CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6)) > 0 Then
If CLng(Hour(Range("F" & i))) > 0 Then
'If the hour value in column F is greater than 1, then...
With Range("F" & i)
'starting with column F, loop through these statements...
'.Offset(1, 0).Resize(CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6)) - 1, 1).EntireRow.Insert Shift:=xlDown
.Offset(1, 0).Resize(CLng(Hour(Range("F" & i))).Value, Len(Range("F" & i).Value) - 1, 1).EntireRow.Insert Shift:=xlDown
'return the value of column F's hour value, change the range to insert the number of rows below based on hour value
'.Resize(CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6)), 1).EntireRow.Value = Range("A" & i).EntireRow.Value
.Resize(Hour(Range("F" & i)), 1).EntireRow.Value = Range("A" & i).EntireRow.Value
'Get value of row to be copied
'For j = 0 To CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6))
For j = 0 To Hour(Range("F" & i))
Range("H" & i).Offset(j - 1, 0).Value = Application.Text(j, "0")
Next j
End With
Else
Range("H" & i).Value = Application.Text(1, "0")
End If
Next i
Application.ScreenUpdating = True
End Sub
Here is a similar question from a previous user
Any help would be greatly appreciated.
Use this instead:
Public Sub ExpandRecords()
Dim i As Long, s As String
Const COL = "F"
For i = 1 To Cells(Rows.Count, COL).End(xlUp).Row
If Cells(i, COL) = 2 Then s = s & "," & Cells(i, COL).Address
Next
If Len(s) Then
Range(Mid$(s, 2)).EntireRow.Insert
For i = 1 To Cells(Rows.Count, COL).End(xlUp).Row
If Cells(i, COL) = vbNullString Then Cells(i, COL) = 1
Next
End If
End Sub