Is there any way in Classic ASP VBScript to get the number of weekdays between 2 dates? Obviously, we have the DateDiff() function but this will pull back the total number of days but I would like to omit the weekends.
You're right, DateDiff() doesn't cover this but it can be used in conjunction with WeekDay() to work out if a Day falls on a weekend.
By using DateDiff() to get the number of days we can then use a For loop to step through the days using DateAdd() to increment the day as we go and check whether the incremented date value is a particular WeekDay(). We can then decide based on this outcome whether to increment a counter that is storing our resulting number of weekdays.
Below is an example of how you would do this, the main logic has been encapsulated in a Function that you could include in a #include script file to use in multiple pages.
<%
Function DateDiffWeekDays(d1, d2)
Dim dy: dy = 0
Dim dys: dys = DateDiff("d", d1, d2)
Dim isWeekDay: isWeekDay = False
Dim wkd
Dim wd: wd = 0
For dy = 0 To dys
wkd = Weekday(DateAdd("d", dy, d1))
isWeekDay = Not (wkd = vbSunday Or wkd = vbSaturday)
If isWeekDay Then wd = wd + 1
Next
DateDiffWeekDays = wd
End Function
'Example of how to call the function and output to the page
Call Response.Write(DateDiffWeekDays(Date(), CDate("12 Nov 2018")))
%>
Output:
16
This is just a quick example and doesn't cover every possible usage case, the idea is it gives you a starting point that you can work from and improve.
VBScript does not include the requested operation, but as DateDiff with a ww interval returns the number of Sundays between two dates, ensuring that start and end dates are out of the weekend we can directly calculate the number of working days:
Option Explicit
Function WorkingDaysBetween( ByVal d1, ByVal d2 )
Dim d
' Adjust date order to simplify calcs and always return 0 or positive number
If d1 > d2 Then
d = d1 : d1 = d2 : d2 = d
End If
' Move start date forward if it is a weekend
d = WeekDay( d1, vbMonday )
If d > 5 Then d1 = DateAdd( "d", 3-(d\6 + d\7), d1)
' Move end date backward if it is a weekend
d = WeekDay( d2, vbMonday )
If d > 5 Then d2 = DateAdd( "d", -1*(d\6 + d\7), d2)
' Calculate
' DateDiff("d") = Number of days between dates
' +1 to include start day
' -2 * DateDiff("ww") to exclude weekends between dates
WorkingDaysBetween = 1 + DateDiff("d", d1, d2, vbMonday) - 2*DateDiff("ww", d1, d2, vbMonday)
' If the result is negative, there are no working days between both dates
If WorkingDaysBetween < 0 Then WorkingDaysBetween = 0
End Function
Related
here is my GUI
Dim d1, d2, d3 As Date
Dim d4 As Integer
Dim x As Long
Option Explicit
Private Sub Command1_Click()
d1 = TimePicker.Value + DTPicker1.Value
d2 = TimePicker2.Value + DTPicker3.Value
x = DateDiff("h", d1, d2)
MsgBox x
End Sub
Private Sub Form_Load()
TimePicker.Format = dtpTime
TimePicker2.Format = dtpTime
End Sub
============================================
i want to calculate more number of hours in three or more days, I can only add two days it gaves me a value of 16hours and its correct, if i add more day it will add 24hours so it become 40 how can i fix this.I want to get 8hrs per day
If you use x = DateDiff("h", d1, d2), you will get the number of hours between d1 and d2.
If you use x = DateDiff("d", d1, d2), you will get the number of days between d1 and d2.
If you want to get 8 hours for each day, just multiply the DateDiff value by 8:
x = DateDiff("d", d1, d2) * 8
I am new to VB Scripting. I have two dates, date_1 and date_2. I need to subtract date_1 from date_2 and the output the difference in date format.
example:
date_1 = 01-09-2014
date_2 = 08-10-2016
output would ideally be:
= date_2 - date_1
= 08-10-2016 - 01-09-2014
= 07-01-0002
Finally i need the output like 02 years, 01 months and 07 days.
Please help me out.
Many thanks in advance.
Take a look at the below code:
Dim date_1, date_2, l, r(2)
date_1 = "01-09-2014"
date_2 = "08-10-2016"
l = SetLocale(2057) ' UK
Delta 0, Array("yyyy", "m", "d"), Array("years", "months", "days"), r, CDate(date_1), CDate(date_2), False
SetLocale l
MsgBox Join(r, ", ") ' 2 years, 1 months, 7 days
Sub Delta(i, t, n, r, d1, d2, c)
Dim q, d
q = DateDiff(t(i), d1, d2)
If UBound(t) > i Then
Do
d = DateAdd(t(i), q, d1)
Delta i + 1, t, n, r, d, d2, c
If c Then Exit Do
q = q - 1
Loop
End If
c = q >= 0
r(i) = q & " " & n(i)
End Sub
You even can set the date and time and compute difference up to second:
Dim date_1, date_2, l, r(5)
date_1 = "01-09-2014 10:55:30"
date_2 = "08-10-2016 15:45:10"
l = SetLocale(2057) ' UK
Delta 0, Array("yyyy", "m", "d", "h", "n", "s"), Array("years", "months", "days", "hours", "minutes", "seconds"), r, CDate(date_1), CDate(date_2), False
SetLocale l
MsgBox Join(r, ", ") ' 2 years, 1 months, 7 days, 4 hours, 49 minutes, 40 seconds
Sub Delta(i, t, n, r, d1, d2, c)
Dim q, d
q = DateDiff(t(i), d1, d2)
If UBound(t) > i Then
Do
d = DateAdd(t(i), q, d1)
Delta i + 1, t, n, r, d, d2, c
If c Then Exit Do
q = q - 1
Loop
End If
c = q >= 0
r(i) = q & " " & n(i)
End Sub
Using some string functions , you can easily achieve your goal .
Hope this helps .
date_1 = InputBox("Enter first Date in format DD-MM-YYYY","Time Difference")
date_2 = InputBox("Enter second Date in format DD-MM-YYYY","Time Difference")
day_differ = Abs(CInt(Left(date_2 , 2)) - CInt(Left(date_1 , 2)))
month_differ = Abs(CInt(Mid(date_2 , 4 , 2)) - CInt(Mid(date_1 , 4 , 2)))
year_differ = Abs(CInt(Right(date_2 , 4)) - CInt(Right(date_1 , 4)))
wscript.echo "Date Difference is " & year_differ & " years, " & month_differ & " months and " & day_differ & " days."
I am looking for a simple algorithm which works on the following table:
In the first column you see the constraints. The second column should be used by the algorithm to output the iterations, which should be done like this:
0 0 0
0 0 1
........
0 0 29
0 1 0
........
0 1 29
0 2 0
0 2 1
........
........
27 9 29
28 0 0
........
........
28 9 29
Currently I have the following code:
Dim wksSourceSheet As Worksheet
Set wksSourceSheet = Worksheets("Solver")
Dim lngLastRow As Long
Dim lngLastColumn As Long
With wksSourceSheet
lngLastRow = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count)
lngLastColumn = IIf(IsEmpty(.Cells(1, .Columns.Count)), _
.Cells(1, .Columns.Count).End(xlToLeft).Column, .Columns.Count)
Dim intRowOuter As Integer
Dim intRowInner As Integer
For intRowOuter = 2 To lngLastRow
.Cells(intRowOuter, lngLastColumn).Value = 0
Next intRowOuter
For intRowOuter = lngLastRow To 2 Step -1
For intRowInner = lngLastRow To intRowOuter Step -1
Dim constraint As Integer
Dim intConstraintCounter As Integer
intConstraint = .Cells(intRowInner, 1)
For intConstraintCounter = 1 To intConstraint
.Cells(intRowInner, lngLastColumn).Value = intConstraintCounter
Next intStampCounter
Next intRowInner
Next intRowOuter
End With
This might be a right approach but something is incorrect. I'm unfortunately stuck so I would appreciate some help on fixing this.
Solution
I would suggest using one array to store the constraints and one to represent the counter.
Dim MaxNum() As Long
Dim myCounter() As Long
ReDim MaxNum(1 To NumDigits)
ReDim myCounter(1 To NumDigits)
Next you need to initialize MaxNum. This will probably involve looping through the cells containing the constraints. Something like:
Dim constraintRange As Range
Dim i As integer
Set constraintRange = wksSourceSheet.Range("A2:A4")
For i = 1 to numDigits
MaxNum(i) = constraintRange.Cells(i,1).Value
Next i
Now we just need to write an increment counter function! The idea is pretty simple we just go from the least significant digit to the most significant. We increment the LSD and, if there is overflow we set it to 0 and then add 1 to the next digit. It looks like this:
Sub IncrNum(ByRef myNum() As Long, ByRef MaxNum() As Long)
Dim i As Integer
For i = LBound(myNum) To UBound(myNum)
myNum(i) = myNum(i) + 1
If myNum(i) > MaxNum(i) Then 'Overflow!
myNum(i) = 0 'Reset digit to 0 and continue
Else
Exit For 'No overflow so we can just exit
End If
Next i
End Sub
Which is just one for-loop! I think this will be the cleanest solution :)
NOTE: To use this function you would simply do IncrNum(myCounter, MaxNum). Which would change the value of myCounter to the next in the sequence. From here you can paste to a range by doing dstRange = myCounter.
Testing
In my own tests I used a while loop to print out all of the values. It looked something like this:
Do While Not areEqual(MaxNum, myCounter)
Call IncrNum(myCounter,MaxNum)
outRange = myCounter
Set outRange = outRange.Offset(1, 0)
Loop
areEqual is just a function which returns true if the parameters contain the same values. If you like I can provide my code otherwise I will leave it out to keep my answer as on track as it can be.
Maybe something like this can be modified to fit your needs. It simulates addition with carry:
Sub Clicker(MaxNums As Variant)
Dim A As Variant
Dim i As Long, j As Long, m As Long, n As Long
Dim sum As Long, carry As Long
Dim product As Long
m = LBound(MaxNums)
n = UBound(MaxNums)
product = 1
For i = m To n
product = product * (1 + MaxNums(i))
Next i
ReDim A(1 To product, m To n)
For j = m To n
A(1, j) = 0
Next j
For i = 2 To product
carry = 1
For j = n To m Step -1
sum = A(i - 1, j) + carry
If sum > MaxNums(j) Then
A(i, j) = 0
carry = 1
Else
A(i, j) = sum
carry = 0
End If
Next j
Next i
Range(Cells(1, 1), Cells(product, n - m + 1)).Value = A
End Sub
Used like:
Sub test()
Clicker Array(3, 2, 2)
End Sub
Which produces:
x%10 or x Mod 10 give the remainder when x is divided by 10 so you will get the last digit of x.
Since your problem is specifically asking for each digit not to exceed 463857. You can have a counter incrementing from 000000 to 463857 and only output/use the numbers the fullfill the following condition:
IF(x%10 <= 7 AND x%100 <=57 AND x%1000 <= 857 AND x%10000 <=3857 AND x%100000 <= 63857 AND x <= 463857)
THEN //perform task.
I have a worksheet with two columns with different Values, Patient ID (ID#) and Institute.
I want to find the Unique values between the two columns and output as 1 (is unique) and 0 (not unique) in an different column corresponding to each cell.
I need to use an Array as I have 10,000 records to test in each column.
Test Conditions:
Case 1 : PatientID in value (A1 = "HC1") goes to Institute value (B2 = "HG"). This is an unique value, as PatientID and Institute only appear once. Hence Output in value (C1 = "1").
Case 2 : PatientID value (A2 = "HC1") goes to Institute value (B2 = "HG"). This is an not unique; as the same patient goes to the same institute again. Hence Output in value (C2 = "0").
Case 3 : PatientID value (A3 = "HC1") goes to Institute value (B3 = "RH"). This is unique; as the same patient goes to an different Institute. Hence Output in value (C3 = "1").
Case 4 : PatientID value (A4 = "HC2") goes to institute value (B4 = "RH"). This is unique; as different patient goes to an different institute. Hence the value of Output should be value (C4 = "1").
I need the VB code to do the same.
Currently i use this Excel 2010 Formulae,
=IF(SUMPRODUCT(($C$2:$C1442=C3)*($A$2:$A1442=A3))>1,0,1)
where,
Column C is Institute and Column A is PatientID.
This takes insane amount of time to compute. Please HELP.
Thank you
You can use a helper column to combine the two cells together, then count if those cells are unique.
Results
if you want you can hide column C
If you want to use macro for the same, you can do it as follow:
Sub TEST()
Set ExcelAppl = CreateObject("Excel.Application")
Set wb = ActiveWorkbook
Set ActiveRange = wb.Worksheets(1).UsedRange
RowCont = ActiveRange.Rows.Count
Dim dataArr() As Variant
ReDim dataArr(RowCont, 1)
For i = 0 To RowCont - 1
InputText = Cells(i + 1, 1).Value & Cells(i + 1, 2).Value
If CheckUnique(dataArr, InputText) = True Then
Cells(i + 1, 3).Value = 0
Else
Cells(i + 1, 3).Value = 1
dataArr(i, 0) = InputText
dataArr(i, 1) = i + 1 'store row number
End If
Next
End Sub
Function CheckUnique(dataArr, InputText)
Dim lb As Long, ub As Long, i As Long, result As Boolean
lb = LBound(dataArr)
ub = UBound(dataArr)
result = False
For i = lb To ub
If dataArr(i, 0) = InputText Then
result = True
Cells(i + 1, 3).Value = 0
Exit For
End If
Next i
CheckUnique = result
End Function
Output will be:
Is there an easy way to get the number of months(over multiple years) that have passed between two dates in ruby?
I found this solution, it seems logical and seems to work.
startdate = Time.local(2001,2,28,0,0)
enddate = Time.local(2003,3,30,0,0)
months = (enddate.month - startdate.month) + 12 * (enddate.year - startdate.year)
Reference: http://blog.mindtonic.net/calculating-the-number-of-months-between-two-dates-in-ruby/
You could provide some test cases, here's one try, not tested very much really:
def months_between d1, d2
d1, d2 = d2, d1 if d1 > d2
(d2.year - d1.year)*12 + d2.month - d1.month - (d2.day >= d1.day ? 0 : 1)
end
This addresses the month edge cases.(i.e. Mar 15 2009 - Jan 12 2010)
def months_between( d1, d2)
d1, d2 = d2, d1 if d1 > d2
y, m, d = (d2.year - d1.year), (d2.month - d1.month), (d2.day - d1.day)
m=m-1 if d < 0
y, m = (y-1), (m+12) if m < 0
y*12 + m
end