Good day,
I am trying to create a macro that moves a row to the bottom of the sheet based on criteria.
What i have been able to do so far is copy the row to the bottom, but this will create a duplicate row for me, where in reality i only need it to be moved.
'Moving column "Grand Total" to bottom
With Wbk4.Sheets("TEST")
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
'Loop through each row
For x = 2 To FinalRow
'Decide if to copy based on column A
ThisValue = Cells(x, 1).Value
If ThisValue = "Grand Total" Then
Cells(x, 1).Resize(1, 33).Copy
lrow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A" & lrow + 1, "Z" & lrow + 1).PasteSpecial xlPasteAll
End If
Next x
End With
Thanks
As you've provided no sample data, it is hard to recommend a custom sort but a temporary helper column off the right side could quickly move all Grand Total rows to the bottom.
With Wbk4.Sheets("TEST")
With .Cells(1, 1).CurrentRegion
.Columns(.Columns.Count).Offset(1, 1).Resize(.Rows.Count - 1, 1).Formula = "=--(A2=""Grand Total"")"
End With
With .Cells(1, 1).CurrentRegion 'reestablish current region with new helper column
.Cells.Sort Key1:=.Columns(.Columns.Count), Order1:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Columns(.Columns.Count).Cells.ClearContents
End With
End With
There are two additional sort keys (maximum of three without doubling up) if you wanted to add additional sorting order(s).
Try Cells(x, 1).EntireRow.Delete or Cells(x, 1).Resize(1, 33).Delete before End If
Thanks Jeeped, it works fine !!
I Did it using another method before trying your code, and it works too!!
I am posting it below for reference in case anyone is looking for code references in the future
'Moving column B to bottom
With Wbk4.Sheets("test")
FinalRow = .Cells(rows.Count, 1).End(xlUp).Row
'Loop through each row
For x = 2 To FinalRow
'Decide if to copy based on column A
ThisValue = .Cells(x, 1).Value
If ThisValue = "Grand Total" Then
.Cells(x, 1).Resize(1, 33).Select
Selection.Cut
lRow = .Range("A" & .rows.Count).End(xlUp).Row
.Range("A" & lRow + 1, "Z" & lRow + 1).Select
ActiveSheet.Paste
End If
Next x
End With
'Delete Blank Rows
Dim i As Long
With Wbk4.Sheets("test")
For i = .Range("A" & rows.Count).End(xlUp).Row To 1 Step -1
If .Range("A" & i) = "" Then
.Range("A" & i).EntireRow.Delete
End If
Next i
End With
Related
Hope You are all Safe
I'm trying to calculate MAX, MIN and AVG Values of filled cells which are continued without blank cell (As you can see it in the left side of the sample image ).
I'm facing problem in selecting these randomly placed cells and calculate the above values and also "From" and "To" values of respective range.
Please let me know how to do it. So far I've constructed following code
Dim Cel As Range
Dim lastrow As Long
Dim destSht As Worksheet
Set destSht = Worksheets("Final")
With Worksheets("Source")
lastrow = .Range("B" & .Rows.Count).End(xlUp).Row
For Each Cel In .Range("C2:C" & lastrow)
If .Cells(Cel.Row, "C") <> "" Then
Cel.Offset(0, -1).Copy Destination:=destSht.Cells(destSht.Rows.Count, 1).End(xlUp).Offset(0, 1)
'It will give "From" Column
'' Plz suggest for "To" Column
Range("G5").Select
ActiveCell.FormulaR1C1 = "=MAX(RC[-4]:R[4]C[-4])" 'It will give values "MAX" Column
Range("H5").Select
ActiveCell.FormulaR1C1 = "=MIN(RC[-5]:R[4]C[-5])" 'It will give values "MIN" Column
Range("I5").Select
ActiveCell.FormulaR1C1 = "=AVERAGE(RC[-6]:R[4]C[-6])" 'It will give values "AVG" Column
End If
Next
Did some quick, which should work.
I don't know what you want to do in the "Final" worksheet, so haven't focused on that line.
Logic is to have one big loop (For i...) that go through the whole Column C. When a value is found in column C (If .Cells(i, "C") <> "" Then), we perform a "small loop" (For j = i To lastrow + 1) to check next empty cell to decide the "small group" range. When that range is decided we perform the To, From, MAX, MIN and AVG formulas, which has to be dynamic.
Option Explicit
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
Result:
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:
My raw data looks something like this;
std1
std1
deviant
std2
std1
std2
std2
deviant
The "deviants" are presented randomly and thus do not occur every nth row...
I wish to select 1 row before and 1 row after each "deviant" row so I can copy it in another spread sheet.
See code below.
We loop through each row in the column (I have assumed your data is in column A) and when the given value is found, we add the following and prior rows to our selection array. When the loop is complete, we select the rows in the array
Public Sub DeviantSelect()
Dim myRange As Range
Set myRange = Nothing
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To lastRow
If Cells(i, 1) = "deviant" Then
If myRange Is Nothing Then
Set myRange = Union(Range(i - 1 & ":" & i - 1), Range(i + 1 & ":" & i + 1))
Else
Set myRange = Union(myRange, Range(i - 1 & ":" & i - 1), Range(i + 1 & ":" & i + 1))
End If
myRange.Select
End If
Next
End Sub
The below code copies the cells before and after deviant to another sheet.
Sub check()
Sheet1.Activate
Range("A1").Select
LastRow = Sheets("Sheet1").UsedRange.Rows(Sheets("Sheet1").UsedRange.Rows.Count).Row
For i = 1 To LastRow
Sheet1.Activate
If Range("A" & i).Value = "deviant" Then
Range("A" & i - 1).Select
Selection.Copy
Sheet2.Activate
LastRow2 = Sheets("Sheet2").UsedRange.Rows(Sheets("Sheet2").UsedRange.Rows.Count).Row
If LastRow2 = 1 Then
Range("A" & LastRow2).Activate
Else
Range("A" & LastRow2 + 1).Activate
End If
ActiveSheet.Paste
Sheet1.Activate
Range("A" & i + 1).Select
Selection.Copy
Sheet2.Activate
LastRow2 = Sheets("Sheet2").UsedRange.Rows(Sheets("Sheet2").UsedRange.Rows.Count).Row
Range("A" & LastRow2 + 1).Activate
ActiveSheet.Paste
End If
Next
End Sub
I want to create column that will be filled by city names repeated "x" times.
Data taken from another sheet (Sheet1, column A (text), B (text) and F (formula)):
London Q 3
Paris R 2
Want to have (Sheet2, column A (text), B (text) and C (Number)):
London Q 1
London Q 2
London Q 3
Paris R 1
Paris R 2
I know it is quite easy but I'm new in VBA :/
I've found code like below (from description it should do what I want), but - this loop never ends and xls crushes so I'm not able to see if it is doing what I want or not.
Sub RunMe()
Dim CopyX, x As Integer
CopyX = Sheets("Sheet2").Range("F1")
Sheets("Sheet1").Select
Range("A1").Copy
Do
x = x + 1
Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Loop Until x = CopyX
Application.CutCopyMode = False
End Sub
This code
- loops through each item in sheet1
- repeats the city name however many times are specified in col F
- puts a 1 alongside the first entry
- completes the series in successive cells in steps of 1 until the col F value is reached.
You may have to adjust sheet names.
Sub x()
Dim r As Long, ws2 As Worksheet
Set ws2 = Sheets("Sheet2")
With Sheets("Sheet1")
For r = 1 To .Range("A" & Rows.Count).End(xlUp).Row
ws2.Range("A" & Rows.Count).End(xlUp)(2).Resize(.Cells(r, 6).Value).Value = .Cells(r, 1).Resize(, 2).Value
ws2.Range("B" & Rows.Count).End(xlUp)(2).Value = 1
ws2.Range("B" & Rows.Count).End(xlUp).DataSeries Step:=1, Rowcol:=xlColumns, Type:=xlLinear, Stop:=.Cells(r, 6).Value
Next r
End With
End Sub
Everything went great after inserting if statement because in data column F there also appears "0" values. Added also clearing and sorting. Maybe someone will use it so I implement whole code :)
Sub x()
Dim r As Long, ws2 As Worksheet
With Sheets("Sample_size")
Range(.Range("A2"), .Range("D2").End(xlDown)).ClearContents
End With
Set ws2 = Sheets("Sample_size")
With Sheets("Pres")
For r = 2 To .Range("A" & Rows.Count).End(xlUp).Row
If .Cells(r, 5).Value > 0 Then
ws2.Range("B" & Rows.Count).End(xlUp)(2).Resize(.Cells(r, 5).Value).Value = .Cells(r, 1).Resize(, 2).Value
ws2.Range("C" & Rows.Count).End(xlUp)(2).Resize(.Cells(r, 5).Value).Value = .Cells(r, 2).Resize(, 2).Value
ws2.Range("d" & Rows.Count).End(xlUp)(2).Resize(.Cells(r, 5).Value).Value = .Cells(r, 5).Resize(, 2).Value
ws2.Range("A" & Rows.Count).End(xlUp)(2).Value = 1
ws2.Range("A" & Rows.Count).End(xlUp).DataSeries Step:=1, Rowcol:=xlColumns, Type:=xlLinear, Stop:=.Cells(r, 5).Value
End If
Next r
End With
ws2.Range("A2:D2").End(xlDown).Sort _
Key1:=Range("D2"), Order1:=xlDescending, _
key2:=Range("c2"), order2:=xlAscending, _
key3:=Range("b2"), order3:=xlAscending
End Sub
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.