The VBA code below calculates the Sum of cells above empty cells in a column in Excel. The number of rows preceding each empty cell in the column is in not the same. I want to adjust the code to calculate the average instead. A counter can be added and then divide the sum (which is already calculated) by the counter.
The original problem and the code (written by Bernard Liengme) are presented on the link below:
https://answers.microsoft.com/en-us/msoffice/forum/all/automatically-calculate-the-sum-of-data-separated/a691afcf-683e-463f-bad7-9fa3a81cf48c
Thanks.
Sub tryme()
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For k = 1 To lastRow
If Cells(k, "A") <> "" Then
Subtotal = Subtotal + Cells(k, "B")
Else
Cells(k, "B") = Subtotal
Subtotal = 0
End If
Next k
Cells(lastRow + 1, "B") = Subtotal
End Sub
Add Subaverages
A Quick Fix
Option Explicit
Sub AddSubAVG()
Dim ws As Worksheet: Set ws = ActiveSheet ' improve
Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim k As Long
Dim tCount As Long
Dim tSum As Double
For k = 1 To LastRow
If ws.Cells(k, "A").Value <> "" Then
tSum = tSum + ws.Cells(k, "B").Value
tCount = tCount + 1
Else
If tCount > 0 Then
ws.Cells(k, "B").Value = tSum / tCount
tSum = 0
tCount = 0
End If
End If
Next k
If tCount > 0 Then ws.Cells(LastRow + 1, "B").Value = tSum / tCount
End Sub
Related
Objective of the code is to count the number of rows that meet three conditions and output the count to populate in a particular cell.
Input data:
The 3 conditions are:
Column A of the row must contain a date field
Column B of the row must be equal to "B"
Column A of the row must have red font
I have the following code, but it seems to not pick up the last condition properly. I am expecting to see 1 as an output but seeing 0:
Sub code()
Dim lrow As Long
lrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
Cells(2, "D").Value = "Count"
Count = 0
For i = 2 To lrow
If IsDate(Cells(i, "A").Value) = True And Cells(i, "B").Value = "B" And Cells(i, "A").Font.Color = -16776961 Then
Count = Count + 1
End If
Next i
Cells(2, "E").Value = Count
End Sub
Sub test1()
Set cl = ActiveSheet.Range("A2")
Do Until IsEmpty(cl)
cnt = cnt - (IsDate(cl.Value) And cl.Offset(0, 1) = "B" And cl.Font.Color = vbRed)
Set cl = cl.Offset(1)
Loop
Debug.Print "Matches = " & cnt
End Sub
Input:
Output:
Matches = 2
Try this:
Dim lrow As Long
lrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
Cells(2, "D").Value = "Count"
Count = 0
For i = 2 To lrow
If IsDate(Cells(i, "A").Value) = True And Cells(i, "B").Value = "B" And Cells(i, "A").Font.Color = vbRed Then
Count = Count + 1
End If
Next i
Cells(2, "E").Value = Count
You can achieve this using the color index as below:
.Font.ColorIndex = 3 which is red [enter link description here][1] They give more options and details on working with font colors.
Sub code()
Dim lrow As Long
lrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
Cells(2, "D").Value = "Count"
Count = 0
For i = 2 To lrow
If IsDate(Cells(i, "A").Value) = True And Cells(i, "B").Value = "B" And Cells(i, "A").Font.ColorIndex = 3 Then
Count = Count + 1
End If
Next i
Cells(2, "E").Value = Count
End Sub
[1]: https://access-excel.tips/excel-vba-color-code-list/
Dim I As Long
For I = 2 To lastrow
If Not IsEmpty(Cells(I, "f")) And IsEmpty(Cells(I, "j")) Then
Cells(I, "j").Value = "unregister"
End If
Next I
Dim I2 As Long
For I2 = 2 To lastrow
If IsEmpty(Cells(I2, "f")) Then
Cells(I2, "i").Value = Cells(I2 - 1, "i").Value
End If
Next I2
can you make this code more simple i want to copy above row for 3 different column if column f is empty
You can do something like this, using a single loop and Offset(-1, 0) to get the cell above:
Dim i As Long, ws As Worksheet
Set ws = ActiveSheet
For i = 2 To ws.Cells(ws.Rows.Count, "F").End(xlUp).Row
With ws.Rows(i)
If Not IsEmpty(.Columns("F")) Then
If IsEmpty(.Columns("J")) Then .Columns("J").Value = "unregister"
Else
.Columns("I").Value = .Columns("I").Offset(-1, 0).Value
.Columns("L").Value = .Columns("L").Offset(-1, 0).Value
'etc
End If
End With
Next I2
I have to delete a row if the of the column values of Column C, Column D , Column E of the same row is zero.
for example.
ColumnA Column B ColumnC ColumnD ColumnE
row1- abc xyz 0 abs abx
row2- wqe tuy 0 0 0
row3 uhiu khj kjh khk 0
here I have to delete the row 2 only because values of all column c , D , E are zero
Please help
A reverse loop should do the job. Try the below:
Option Explicit
Public Sub DeleteRows()
Dim i As Long, count As Long, lastRow As Long
' Replace Sheet1 with your sheetname
With ThisWorkbook.Worksheets("Sheet2")
' Change C with your most consistent column letter
' (a column that has data always to make sure there's no possibility to miss the last row due to empty cells)
lastRow = .Cells(.Rows.count, "C").End(xlUp).Row
' We do a reverse loop to not screw up the index
For i = lastRow To 2 Step -1
If .Range("C" & i).Value = "0" And .Range("D" & i).Value = "0" And .Range("E" & i).Value = "0" Then
.Range("C" & i).EntireRow.Delete
count = count + 1
End If
Next i
End With
' Display some message
If count > 0 Then
MsgBox "Done!" & vbCrLf & "Deleted " & count & " row(s).", vbInformation + vbOKOnly, "Success"
Else
MsgBox "No matches found for deletion", vbInformation + vbOKOnly, "Success"
End If
End Sub
Try,
Sub test()
Dim vDB, vR()
Dim Ws As Worksheet, toWs As Worksheet
Dim i As Long, n As Long
Dim j As Integer
Set Ws = ActiveSheet
vDB = Ws.UsedRange
For i = 1 To UBound(vDB, 1)
If vDB(i, 3) = 0 And vDB(i, 4) = 0 And vDB(i, 5) = 0 Then
Else
n = n + 1
ReDim Preserve vR(1 To 5, 1 To n)
For j = 1 To 5
vR(j, n) = vDB(i, j)
Next j
End If
Next i
Set toWs = Sheets.Add '<~~ set your sheet
With toWs
.Cells.Clear
.Range("a1").Resize(n, 5) = WorksheetFunction.Transpose(vR)
End With
End Sub
Try this code, fast and easy code.
Sub deleterow()
Dim i As Integer
i = 2
LastR = Cells(Rows.Count, 1).End(xlUp).row
For i = LastR To 2 Step -1
If Cells(i, 3).value = "0" And Cells(i, 4).value = "0" And Cells(i, 5).value = "0" Then
Cells(i, 1).EntireRow.delete
End If
Next i
End Sub
please assist my thought below, I would like to get the value place in different rows according to the value. I believe my code is with looping issues but I can't figure out why.
The action is very simple, row A is a set of value, if range("A2").value + 50 <= 100 then place the answer on B2.value, else place value on C2.value and etc.
Sub ttest()
Dim item, lastR, itemplus As Integer
Dim i, j As Integer
i = 2
j = 2
item = Cells(i, 1).value
lastR = Cells(Rows.Count, 1).End(xlUp).row
itemplus = item + 50
For i = 2 To lastR
If itemplus <= 100 Then
Cells(i, j).value = itemplus
Else
Cells(i, j + 1).value = itemplus
End If
item = Cells(i, 1).value
Next i
End Sub
As #SJR says, you partly work outside your loop and partly inside your loop, constantly comparing to the exact same variable.
May I suggest an alternative to work through memory instead (and avoid slower calls to your worksheet too often):
Sub Test()
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Sheet1")
Dim lr As Long, x As Long
Dim arr As Variant
With ws
lr = .Cells(.Rows.Count, 1).End(xlUp).Row
arr = .Range("A2:C" & lr).Value
For x = LBound(arr) To UBound(arr)
If arr(x, 1) < 50 Then
arr(x, 2) = arr(x, 1)
Else
arr(x, 3) = arr(x, 1)
End If
Next
.Range("A2:C" & lr).Value = arr
End With
End Sub
As you may notice, we don't have to add 50 to each value to compare if its <= to a 100. That would imply that the initial value must simply be below 50.
That being said, the same is achieved swiftly through native Excel functions if you would want to avoid VBA.
Just change the order of assignment:
Sub ttest()
Dim item, lastR, itemplus As Integer
Dim i, j As Integer
i = 2
j = 2
item = Cells(i, 1).Value
lastR = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastR
item = Cells(i, 1).Value
itemplus = item + 50
If itemplus <= 100 Then
Cells(i, j).Value = itemplus
Else
Cells(i, j + 1).Value = itemplus
End If
Next i
End Sub
Sub test()
Set Rng = Range("A2", Range("A2").End(xlDown))
For Each cell In Rng
Sum = cell.Value + 50
If Sum <= 100 Then cell.Offset(0, 1).Value = Sum
If Sum > 100 Then cell.Offset(0, 2).Value = Sum
Next
End Sub
I'm trying to copy a cell and the adjacent cell in a row and insert it as a new row with all the data to the right of this cell also copied over. My data looks like this after mining.
and im trying to get my data to look like this:
the image above is just one record but essentially its moving all the people and their corresponding position in the original row to a new row. In each row there are about 5 employees and their positions.
thanks
EDIT Attempted code for just 2 cols. 1 position. the idea was to create the empty rows and just copy the rest of the data with auto fill, then work from there
Sub TransposeInsertRows()
Dim rng As Range
Dim i As Long, j As Long, k As Long
Dim x As Long, y As Long
Set rng = Application.InputBox _
(Prompt:="Range Selection...", _
Title:="Enter the name col and pos col", Type:=8)
Application.ScreenUpdating = False
x = rng(1, 1).Column + 2
y = rng(1, rng.Columns.Count).Column
For i = rng(rng.Rows.Count, 1).Row To rng(1, 1).Row Step -1
If Cells(i, x) <> "" And Cells(i, x + 1) <> "" Then
k = Cells(i, x - 2).End(xlToRight).Column
If k > y Then k = y
For j = k To x + 1 Step -1
Cells(i + 1, 1).EntireRow.Insert
With Cells(i + 1, x - 2)
.Value = .Offset(-1, 0)
.Offset(0, 1) = .Offset(-1, 1)
.Offset(0, 2) = Cells(i, j)
End With
Cells(i, j).ClearContents
Next j
End If
Next i
Application.ScreenUpdating = True
End Sub
If there are always 5 people in each row then this should do it:
Sub foo()
LastRow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
For i = 1 To LastRow 'loop through rows
For x = 1 To 10 Step 2 'loop through columns
LastRow2 = Sheet2.Cells(Sheet2.Rows.Count, "A").End(xlUp).Row + 1 'find the next free row on Sheet2
Sheet2.Cells(LastRow2, 1).Value = Sheet1.Cells(i, x).Value 'add Person Name to Sheet2
Sheet2.Cells(LastRow2, 2).Value = Sheet1.Cells(i, x + 1).Value 'add position to Sheet2
Sheet1.Range("K" & i & ":U" & i).Copy Destination:=Sheet2.Cells(LastRow2, 3) 'copy range from K to U to Sheet2
Next x
Next i
End Sub