Reputation: 456
I am having trouble figuring out how to subtract the very end date of a contract with the beginning date. However, I cannot figure out how to reference the initial date..
For example, =D2 - C2
as well as be able to do =D10 - C5
. This is what I currently have, and it does not work at all.
Dim sla As Long, slacnt As Long, drng As Long, i As Long
i = 2
With Worksheets("Raw")
slacnt = .Cells(.rows.Count, 2).End(xlUp).Row
For sla = i To slacnt
drng = Sheets("Data").Range("B" & i).Value
If .Range("B" & i) <> .Range("B" & i).Offset(1, 0) Then
Else: drng = .Range("D" & i).Value - .Range("C" & i).Value
End If
Next sla
End With
Any direction would be greatly appreciated, thanks in advance.
Upvotes: 0
Views: 97
Reputation: 23081
Vityata has beaten me to it, but I started this so might as well post it.
Sub x()
Dim r As Range, r1 As Range, a, b
With Worksheets("Raw")
Set r1 = .Range("A2", .Range("D" & Rows.Count).End(xlUp))
End With
With r1.Columns(1)
.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C"
For Each r In .SpecialCells(xlCellTypeConstants)
a = Evaluate("MIN(IF(" & .Address & "=" & r & ",IF(" & r1.Columns(3).Address & "<>""""," & r1.Columns(3).Address & ")))")
b = Evaluate("MAX(IF(" & .Address & "=" & r & "," & r1.Columns(4).Address & "))")
r.Offset(, 4) = b - a
Next r
.SpecialCells(xlCellTypeFormulas).ClearContents
End With
End Sub
Upvotes: 0
Reputation: 43575
This would be a perfect problem to be resolved with a dictionary, but somehow I am too lazy to do it this way.
However, let's imagine that all the dates are actually numbers (and in Excel they are!) then your input can be translated to something like this:
What is wanted now is to get the smallest value for each value in column A in column D and the biggest in column E. I have achieved the following:
This is how the code looks like:
Option Explicit
Sub TestMe()
Dim lngLastRow As Long
Dim rngCell As Range
Dim rngRange As Range
Dim lngMin As Long
Dim lngMax As Long
Dim lngPreviousRow As Long
Dim ws As Worksheet
lngLastRow = lastRow(column_to_check:=2)
Set ws = ActiveSheet
Set rngRange = ws.Range(ws.Cells(1, 1), ws.Cells(lngLastRow, 1))
For Each rngCell In rngRange
If Len(rngCell) > 0 Then
If lngPreviousRow > 0 And (rngCell.Row - 1 <> lngPreviousRow) Then
ws.Cells(lngPreviousRow, 4) = lngMin
ws.Cells(lngPreviousRow, 5) = lngMax
End If
If (rngCell.Row = 1) Or lngPreviousRow = (rngCell.Row - 1) Then
ws.Cells(rngCell.Row, 4) = WorksheetFunction.Min(rngCell.Offset(0, 1), rngCell.Offset(0, 2))
ws.Cells(rngCell.Row, 5) = WorksheetFunction.Max(rngCell.Offset(0, 1), rngCell.Offset(0, 2))
End If
lngPreviousRow = rngCell.Row
lngMin = WorksheetFunction.Min(rngCell.Offset(0, 1), rngCell.Offset(0, 2))
lngMax = WorksheetFunction.Max(rngCell.Offset(0, 1), rngCell.Offset(0, 2))
Else
lngMin = WorksheetFunction.Min(lngMin, rngCell.Offset(0, 1), rngCell.Offset(0, 2))
lngMax = WorksheetFunction.Max(lngMax, rngCell.Offset(0, 1), rngCell.Offset(0, 2))
End If
Next rngCell
Cells(lngPreviousRow, 4) = lngMin
Cells(lngPreviousRow, 5) = lngMax
End Sub
Function lastRow(Optional strSheet As String, Optional column_to_check As Long = 1) As Long
Dim shSheet As Worksheet
If strSheet = vbNullString Then
Set shSheet = ActiveSheet
Else
Set shSheet = Worksheets(strSheet)
End If
lastRow = shSheet.Cells(shSheet.Rows.Count, column_to_check).End(xlUp).Row
End Function
Points for improvement:
WorksheetFunction.Min
and WorksheetFunction.Max
are repeating 3 times, it would be a good idea to build a separate function for them.Upvotes: 1