I'm attempting to count the number of rows in my sheet that meet 3 sets of criteria: the client name in column C matches my active row; the due date in column G; and column M is blank (indicating no previous submission was sent).
I can get this to work just fine with the following code:
Dim ws As Worksheet: Set ws = ThisWorkbook.Worksheets("Broker Workflow")
Dim i As Long
Dim iVal As Long
Dim lastRow As Long: lastRow = ws.Range("C" & Rows.Count).End(xlUp).Row
Dim strClient As String: strClient = Cells(ActiveCell.Row, "C").Value
Dim strRenDate As String: strRenDate = Cells(ActiveCell.Row, "G").Value
Dim strNotSubmitted As String: strNotSubmitted = ""
Dim strCriteria As String: strCriteria = strClient & strRenDate & strNotSubmitted
iVal = 0
For i = 8 To lastRow
If ws.Range("C" & i).Value & ws.Range("G" & i).Value & ws.Range("M" & i).Value = strCriteria Then
iVal = iVal + 1
End If
Next i
Dim strCount As String: strCount = iVal
My problem is that now I want to extend this to count all rows with a due date that is within a range of my active row date +/- 7 days (14 day range). So if my due date is 07/06/2020 it will count the number of rows that match my client name in C, have blank cell in M and a date of anything between 01/06/2020-14/06/2020 in G.
You are making it more complicated than needed... can get rid of the four variables above, and simply test like this:
For i = 8 To lastRow
If ws.Range("C" & i).Value = Cells(ActiveCell.Row, "C").Value & _
ws.Range("M" & i).Value = "" & _
ws.Range("G" & i).Value >= DateAdd(Cells(-7, "d", ActiveCell.Row, "G").Value) & _
ws.Range("G" & i).Value <= DateAdd(Cells(7, "d", ActiveCell.Row, "G").Value) Then
iVal = iVal + 1
End If
Next i
[EDIT]
Sorry!
I have no idea what I wrote earlier.
I mixed up the parameters in DateAdd and used & instead of and
This works, tested:
For i = 8 To lastRow
If Cells(i, "C").Value = Cells(ActiveCell.Row, "C").Value And _
Cells(i, "M").Value = "" And _
Cells(i, "G").Value >= DateAdd("d", -7, Cells(ActiveCell.Row, "G").Value) And _
Cells(i, "G").Value <= DateAdd("d", 7, Cells(ActiveCell.Row, "G").Value) Then
iVal = iVal + 1
End If
Next i
It will also work with your ws.Range syntax, it was just simpler for me to test it like this with Cells
Please note that the current line also gets counted if it has an empty M column...
Related
Thanks for opening my thread. I need help from you.
So in this sheet the total amount should be sum of fuel + surge + delivery_charge should be added in Total amount column.
Ex:- 1st order = 456777 this should add 109.49+303.41+25966.51 = 26379.41
2nd order = 23213213 should add 10+11318+65 = 11393
Dim i As Long, lastrow As Long, rng As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "A") <> "" Then
rng = Cells(i, "A").End(xlDown).Row - 1
Cells(i, "B").Value = WorksheetFunction.Sum(Range("C" & i & ":C" & rng), Range("E" & i & ":E" & rng), Range("G" & i & ":G" & rng))
End If
Next i
I'm getting output from this logic :
But the issue is for 2nd order id. It should take only that row. But here its taking 5th and 6th row for addition.
2nd order id= 23213213 total_amt should be 11393.
So anyone could you please help me to find out an issue.
Thanks and Regards,
Ranger
The issue is in how you find rng.
rng = Cells(i, "A").End(xlDown).Row - 1
You're using xlDown to find the start of the next block of data. This works as you'd expect, except where the data changes every cell. If you click on cell A5 and press CTRL-Shift-Down, you'll see that it selects three cells as it jumps to the end of that block of data (A7). This is normal Excel behaviour.
You could re-write your code to loop through all the data until it finds the right scenario, but in this case I believe the single cell issue can just be trapped with the right If statement.
If Cells(i + 1, "A") <> "" Then rng = i
Try this:
Dim i As Long, lastrow As Long, rng As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "A") <> "" Then
rng = Cells(i, "A").End(xlDown).Row - 1
If Cells(i + 1, "A") <> "" Then rng = i
Cells(i, "B").Value = WorksheetFunction.Sum(Range("C" & i & ":C" & rng), Range("E" & i & ":E" & rng), Range("G" & i & ":G" & rng))
End If
Next i
I have two Tables.
Table1 goes from A1:F10 and shows the machine assignment.
Table2 goes from G1:K10 and shows the storage for the machines.
With a button I want to simulate which storage should be used for which machine.
In column C stands the date when the machine has to be built. In Column I stands the date when the storage is ready to use.
For example: The first machine has to start on 08/15/2018. How can I check which date in Column I is the closest to 08/15/2018?
This is my code so far:
Private Sub CommandButton1_Click()
Dim lastrow as Long
lastrow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row
for a = 1 to lastrow
If Cells(a, 1) = "Machine Name" And _ ' Find the specific machine
Cells(a, 4) = "" Then ' In this cell the serial number of the storage should be added
' Now check if Storage for this machine is ready to use.
For b = 1 to lastrow
If Cells(b, 8) = "123" And _ ' Serial Number of the Storage
Cells(b, 10) = "" Then ' In this Cell serial number of the machine should be added
' Here it should check which Date in Column I is the closest to the date in Column C
Cells(a, 4).Value = Cells(b, 8)
Cells(b, 10).Value = Cells(a, 2)
End If
Next b
End If
Next a
End Sub
I tried to change the code from Find closest date to current date in VBA.
In the picture you can see an example how the table looks:
you didn't specify where you want the closest date before start so i just added the date as a comment to the start date in column C.
Sub FindClosestBeforeDate()
Dim ws As Worksheet
Dim lLastReadyUsed As Long
Dim lLastStartUsed As Long
Dim dt As String
Dim temp As Variant
Set ws = Application.ThisWorkbook.ActiveSheet
lLastStartUsed = ws.Cells(Rows.Count, "C").End(xlUp).Row
lLastReadyUsed = ws.Cells(Rows.Count, "I").End(xlUp).Row
'Delete previous comments
For l = 2 To lLastStartUsed
If Not Range("c" & l).Comment Is Nothing Then
ws.Range("C" & l).Comment.Delete
End If
Next l
'add comments with closeste date before startdate
For l = 2 To lLastStartUsed
For i = 2 To lLastReadyUsed
If DateDiff("D", ws.Range("C" & l).value, ws.Range("I" & i).value) < 0 Then
If IsEmpty(temp) Then
temp = DateDiff("D", ws.Range("C" & 3).value, ws.Range("I" & i).value)
dt = ws.Range("I" & i).value
ElseIf temp < DateDiff("D", ws.Range("C" & 3).value, ws.Range("I" & i).value) Then
temp = DateDiff("D", ws.Range("C" & 3).value, ws.Range("I" & i).value)
dt = ws.Range("I" & i).value
End If
End If
Next i
temp = Empty
ws.Range("C" & l).AddComment dt
Next l
End Sub
Hope this helps you out
With your example, im assuming you want
Start = 15.06.2018, Ende = 14.03.2018
Start = 25.08.2018, Ende = 26.07.2018
Add this Function and call it like YourCell.Value = getClosestDateBefore(StartCell.Value, Range("I2:I9"))
Function getClosestDateBefore(d As Date, RefDateRange As Range) As Date
Dim i As Long, ref_date As Date, diff As Double, best_diff As Double
best_diff = -10000000
With RefDateRange
For i = 1 To .Cells.Count
ref_date = .Cells(i).Value2
diff = ref_date - d
If diff < 0 And diff > best_diff Then
best_diff = diff
getClosestDateBefore = ref_date
End If
Next i
End With
End Function
I have the below code which searches for specific text based on the Col header, like Col O, Col P etc. Instead I want to search using the respective column name in Row 1.
I have added the column name in the code comments.
Sub PassFailValidationandupdatecomments()
Dim Rng As Range, cl As Range
Dim LastRow As Long, MatchRow As Variant
With Sheets("DRG")
LastRow = .Cells(.Rows.count, "E").End(xlUp).Row '"E" - Live ASIN
Set Rng = .Range("E2:E" & LastRow) ' "E" - Live ASIN
End With
With Sheets("Latency")
For Each cl In .Range("B2:B" & .Cells(.Rows.count, "B").End(xlUp).Row) ` "B" - ASIN
MatchRow = Application.Match(cl.Value, Rng, 0)
If Not IsError(MatchRow) Then
Select Case Sheets("DRG").Range("AH" & MatchRow + 1).Value ' "AH" - Final Test Result
.Range("O" & cl.Row).Value = "Pass" '"O" - Pass/Fail
Case "Pended"
.Range("O" & cl.Row).Value = "Fail"'"O" - Pass/Fail
Case "In progress"
.Range("O" & cl.Row).Value = "In progress"'"O" - Pass/Fail End Select
If Not Sheets("DRG").Range("E" & MatchRow + 1).Value = vbNullString Then .Range("P" & cl.Row).Value = .Range("P" & cl.Row).Value & IIf(Not .Range("P" & cl.Row).Value = vbNullString, ";", "") & Sheets("DRG").Range("S" & MatchRow + 1).Value ' "E" - Live ASIN ; "P" - Comments ; "S" - App Trail
End If
Next cl
End With
This is a follow on from How do I get all the different unique combinations of 3 columns using VBA in Excel?
It almost what i need, however, my requirements is that it sums the third column which will contain figures instead of yes/no
Sub sample()
Dim ws As Worksheet
Dim lRow As Long, i As Long, j As Long
Dim col As New Collection
Dim Itm
Dim cField As String
Const deLim As String = "#"
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow
cField = .Range("A" & i).Value & deLim & _
.Range("B" & i).Value & deLim & _
.Range("C" & i).Value
On Error Resume Next
col.Add cField, CStr(cField)
On Error GoTo 0
Next i
i = 2
.Range("A1:C1").Copy .Range("F1")
.Range("I1").Value = "Count"
For Each Itm In col
.Range("F" & i).Value = Split(Itm, deLim)(0)
.Range("G" & i).Value = Split(Itm, deLim)(1)
.Range("H" & i).Value = Split(Itm, deLim)(2)
For j = 2 To lRow
cField = .Range("A" & j).Value & deLim & _
.Range("B" & j).Value & deLim & _
.Range("C" & j).Value
If Itm = cField Then nCount = nCount + 1
Next
.Range("I" & i).Value = nCount
i = i + 1
nCount = 0
Next Itm
End With
End Sub
This code was originally added by
Siddharth Rout
try this (follows comments)
Option Explicit
Sub Main()
Dim i As Long
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
For i = 4 To Range("A" & Rows.Count).End(xlUp).Row '<-- change 4 and "A" to your data actual upleftmost cell row and column
dict(cells(i, 1).Value & "|" & cells(i, 2).Value) = dict(cells(i, 1).Value & "|" & cells(i, 2).Value) + cells(i, 3).Value '<--| change 3 to your actual "column to sum up" index
Next
With Range("G3").Resize(dict.Count) '<-- change "G3" to your actual upleftmost cell to start writing output data from
.Value = Application.Transpose(dict.Keys)
.TextToColumns Destination:=.cells, DataType:=xlDelimited, Other:=True, OtherChar:="|"
.Offset(, 2).Resize(dict.Count).Value = Application.Transpose(dict.Items) '<--| change 2 to your actual column offset where to start writing summed values form
End With
End Sub
I have a sheet:
I am trying to write code to be able to combine multiple values into one row, I need to sum the values from columns, B, C and D.
My aim is to be able to press a button and I have all of my duplicate values removed, but before this, the numerical values in the adjacent columns are summed into the single version.
So far I have removed the duplicates from the column:
Sheets("Sheet4").Select
With Columns("A:A")
.Replace What:="mobile", Replacement:=""
End With
Previous code should do your job. It may need a fine tuning but idea would work. Do not forget to make proper addressing of worksheets for your ranges. I did not do it. This will work on the active sheet currently.
Update: Updated with worksheet addresses.
Dim ws As Worksheet
Dim LastRow As Long
Dim S_Value As String
Set ws = Sheets("Sheet1")
LastRow = Range("A" & Rows.Count).End(xlUp).Row
i = 2
While i <= LastRow
S_Value = ws.Range("A" & i).Value
j = i + 1
While j <= LastRow
If ws.Range("A" & j).Value = S_Value Then
ws.Range("B" & i).Value = ws.Range("B" & i).Value + ws.Range("B" & j).Value
ws.Range("C" & i).Value = ws.Range("C" & i).Value + ws.Range("C" & j).Value
ws.Range("D" & i).Value = ws.Range("D" & i).Value + ws.Range("D" & j).Value
ws.Rows(j & ":" & j).EntireRow.Delete
LastRow = ws.Range("A" & Rows.Count).End(xlUp).Row
j = j - 1
End If
j = j + 1
Wend
i = i + 1
Wend
Here you go,
Sub SumCount()
Dim s, c, sm
Dim Rws As Long, Rng As Range
Rws = Cells(Rows.Count, "B").End(xlUp).Row
Set Rng = Range(Cells(2, 2), Cells(Rws, 4))
s = InputBox("What Number to Find?")
c = Application.WorksheetFunction.CountIf(Rng, s)
sm = s * c
MsgBox sm
End Sub