Days calculation between a range - algorithm

I have the following problem
In a given range for example 1 Jan 2017 to 31 Jan 2017,
How many days of the following range events period occurred?
Example
1 range 1 Dec 2016 / 30 Jun 2017 = 31
2 range 1 Jan 2017 / 2 Jan 2017 = 2
3 range 4 Aug 2017 / 31 Aug 2017 = 0
4 range 24 Sep 2015 / 2 Jan 2017 = 2
5 range 6 Jan 2015 / 6 Feb 2016 = 0
Do you have some idea for an algorithm in access-VBA?
Many thanks

Public Function DaysInRange(vntRngStart As Date, vntRngEnd As Date, vntTestStart As Date, vntTestEnd As Date) As Integer
On Error GoTo PROC_ERR
Dim vntOverlapStart As Date
Dim vntOverlapEnd As Date
If vntRngStart > vntRngEnd Then
MsgBox "Main date range is specified back-to-front, swap the dates and try again.", vbInformation, "Invalid input..."
DaysInRange = -1
Exit Function
ElseIf vntTestStart > vntTestEnd Then
MsgBox "Test date range is specified back-to-front, swap the dates and try again.", vbInformation, "Invalid input..."
DaysInRange = -2
Exit Function
End If
If vntTestEnd < vntRngStart Or vntTestStart > vntRngEnd Then
'Either your test range ends before the given range starts,
'or the test range starts after the end of the given range,
'so there is no overlap between the two ranges.
DaysInRange = 0
Exit Function
End If
'So now we know that there must be some overlap
If vntTestStart <= vntRngStart Then
'Our test range starts before the start of the given range,
'so the overlap starts at the beginning of the given range
vntOverlapStart = vntRngStart
Else
'Our test range starts after the start of the given range,
'so the overlap starts at the beginning of the test range
vntOverlapStart = vntTestStart
End If
If vntTestEnd >= vntRngEnd Then
'Our test range ends after the end of the given range,
'so the overlap ends at the end of the given range
vntOverlapEnd = vntRngEnd
Else
'Our test range ends after the end of the given range,
'so the overlap ends at the end of the test range
vntOverlapEnd = vntTestEnd
End If
DaysInRange = DateDiff("d", vntOverlapStart, vntOverlapEnd) + 1
PROC_EXIT:
On Error Resume Next
Exit Function
PROC_ERR:
MsgBox "Error " & Err.Number & " in Function 'DaysInRange': " & Err.Description
Resume PROC_EXIT
End Function

Related

Monthly generation with a given dates

Trying to Achieve
I fixed a date on my code say 31-01-2019. Then everyday I will execute my code but only on 28-02-2019/29-02-2020, 31-03-2019, 30-04-2019... I wish to execute the code. It is something like monthly generation. In addition, if the fixed date is 30-01-2019, I wish to execute the code on 28-02-2019/29-02-2020, 30-03-2019, 30-04-2019...
For example
What I have done
I have followed the question VBScript DateDiff month, and have tried out the following code but it is not working.
If I were to have a date say 31-Jan-2010 by DateAdd
endFeb = DateAdd("m",1,"31-Jan-10")
endMar = DateAdd("m",1,endFeb)
endApr = DateAdd("m",1,endMar)
The result
endFeb: 28/02/2010
endMar: 28/03/2010
endApr: 28/04/2010
What I want is
endFeb: 28/02/2010
endMar: 31/03/2010
endApr: 30/04/2010
Code
sFixedDate = "2019-01-31" '==== Fixed
sProcessDate = "2019-02-28" '==== Changes daily
d1 = CDate(sFixedDate)
d2 = CDate(sProcessDate)
diff = DateDiff("m", d1, d2)
If request("btnProcess") <> "" Then
If diff Mod 1 = 0 Then '=== Not as simple as I thought
'=== Trying to do monthly GENERATION.
'===Excecute the CODE
End If
End If
Basically, you want to run something on the last day of each month. Meaning that the day after would be a different month, so you could do something like this for calculating the last day of the next month:
today = Date
tomorrow = today + 1
If request("btnProcess") <> "" Then
If Month(today) <> Month(tomorrow) Then
endNextMonth = DateAdd("m", 1, tomorrow) - 1
End If
End If
To get the last day for any given month adjust the number of months to add to tomorrow's date.
The above assumes that you're doing the calculation on the last day of a month. If you want to calculate the last day of any given month on any day of a month please see Ekkehard Horner's answer.
Use DateSerial:
For m = 1 To 13
d1 = DateSerial(2019, m, 1) ' First day of month is easy
d2 = DateAdd("d", d1, -1) ' Last day of previous month is just 1 day before
WScript.Echo m, d1, d2
Next
cscript lom.vbs
1 01.01.2019 31.12.2018
2 01.02.2019 31.01.2019
3 01.03.2019 28.02.2019
4 01.04.2019 31.03.2019
5 01.05.2019 30.04.2019
6 01.06.2019 31.05.2019
7 01.07.2019 30.06.2019
8 01.08.2019 31.07.2019
9 01.09.2019 31.08.2019
10 01.10.2019 30.09.2019
11 01.11.2019 31.10.2019
12 01.12.2019 30.11.2019
13 01.01.2020 31.12.2019
It seems like for a given start date, you want to calculate x months into the future what that new date is, and if the start date as a day that is greater than the future month, to give the last day of the month instead.
Function CalculateFutureDate(startDate, monthsInFuture)
' Assumes startDate is in the past
Dim dtRepeatDate
Dim dtNewDate
If (IsDate(startDate)) Then
dtRepeatDate = CDate(startDate)
' months between now and Start Date
Dim intMonthsToAdd
Dim dtCurrentDate
dtCurrentDate = Now()
intMonthsToAdd = DateDiff("m", startDate, dtCurrentDate)
If intMonthsToAdd > 0 And Day(startDate) < Day(dtCurrentDate) Then
intMonthsToAdd = intMonthsToAdd - 1
End If
' Add the future months to the month offset
intMonthsToAdd = intMonthsToAdd + monthsInFuture
' Now calculate future date
dtNewDate = DateAdd("m", intMonthsToAdd, dtRepeatDate)
CalculateFutureDate = dtNewDate
End If
End Function
And then you can do something like:
CalculateFutureDate(CDate("2019-01-31"), intFutureMonths)
This will output:
?CalculateFutureDate(CDate("2019-01-31"), 1)
2/28/2019
?CalculateFutureDate(CDate("2019-01-31"), 2)
3/31/2019
?CalculateFutureDate(CDate("2019-01-31"), 3)
4/30/2019
dtLoan = CDate("2019-01-30")
dtProcess = CDate ("2020-02-28")
'dtLoan = CDate("2019-01-31")
'dtProcess = CDate ("2020-02-29")
'dtLoan = CDate("2019-02-28")
'dtProcess = CDate ("2020-02-29")
if LastDateOfMonth(dtLoan) = dtLoan AND dtProcess = LastDateOfMonth(dtProcess) then
response.write " this mean that the Loan date is end of the month, say 31 Jan, 28, 29 of Feb, 31 Feb "
response.write " and Process Date is also end of the month " & "<br>"
response.write " **** End of the month Loan Date : " & dtLoan & "<br>"
response.write " **** End of the month Process Date : " & dtProcess & "<br>"
elseif LastDateOfMonth(dtLoan) <> dtLoan AND dtProcess <> LastDateOfMonth(dtProcess) then
daysFromEndOfLoanMth = DateDiff("d",LastDateOfMonth(dtLoan),dtLoan)
response.write " How many days from end of Loan month: " & daysFromEndOfLoanMth & "<br>"
daysFromEndOfProcessMth = DateAdd("d",daysFromEndOfLoanMth,LastDateOfMonth(dtProcess))
response.write " From end of the month Add " & daysFromEndOfLoanMth & " Days = " & daysFromEndOfProcessMth & "<br>"
response.write " The date of process : " & dtProcess & "<br>"
dtShouldProcess = day(dtLoan) & "/" & Month(dtProcess) & "/" & Year(dtProcess)
if isDate(dtShouldProcess) then
dtShouldProcess=CDate(dtShouldProcess)
else
dtShouldProcess=daysFromEndOfProcessMth
end if
response.write " ** The date of should Process : ** " & dtShouldProcess & "<br>"
if dtProcess = dtShouldProcess then
'if dtProcess = daysFromEndOfProcessMth then
response.write " **** Loan Date : " & dtLoan & "<br>"
response.write " **** Process Date : " & dtProcess & "<br>"
end if
'daysFromEndOfProcessMth = DateDiff("d",LastDateOfMonth(dtProcess1),dtProcess1)
'response.write " How many days from Process Date end of the month: " & daysFromEndOfProcessMth & "<br>"
end if

visual basic write to text file

I have a question about using StreamWriter in visual basic 2008
, Below is code for database filtering using visual basic 2008
On Error Resume Next
If e.KeyCode = Keys.Enter Then
'' Me.Table1BindingSource.Filter = "EmpID = ' " & Me.txtsearch.Text & "'"
On Error Resume Next
Dim temp As Integer = 0
Me.Table1BindingSource.Filter = "EmpID = ' " & Me.txtsearch.Text & "'"
For i As Integer = 0 To Table1DataGridView.RowCount - 1
For j As Integer = 0 To Table1DataGridView.ColumnCount - 1
If Table1DataGridView.Rows(i).Cells(j).Value.ToString = txtsearch.Text Then
''if item found then we play sound ok
My.Computer.Audio.Play("F:\beep.wav", AudioPlayMode.WaitToComplete)
My.Computer.Audio.Play("F:\beep.wav", AudioPlayMode.WaitToComplete)
temp = 1
''write the user name that logged in
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter("C:\Users\haydeer\Desktop\test.txt", True)
file.WriteLine(txtsearch.Text)
file.Close()
txtsearch.Text = ""
End If
Next
Next
'' trytime += 1 'Increment if not found
If temp = 0 And trytime <= 2 Then 'Check if not found 3 times (or more)
''if item not found then we play sound err
My.Computer.Audio.Play("F:\computer_access.wav", AudioPlayMode.WaitToComplete)
Me.Table1TableAdapter.Fill(Me.MydbDataSet.Table1)
Me.Table1DataGridView.Refresh()
trytime += 1 'Increment if not found
txtsearch.Text = ""
ElseIf temp = 0 And trytime >= 3 Then
'' Alarm Gose on
MsgBox("three time")
End If
End If
my problem is when the user is logged-in it will write the date of login for that user, iam successful store the user , but i want to store the date too for example (00:00:00 AM)? any idea ?
To turn the current time on the machine to a string:
My.Computer.Clock.LocalTime.ToLongTimeString (1:23:45 AM)
My.Computer.Clock.LocalTime.ToShortTimeString (1:23 AM)
My.Computer.Clock.LocalTime.ToLongDateString (Saturday, January 1, 2000)
My.Computer.Clock.LocalTime.ToShortDateString (1/1/2000)
My.Computer.Clock.LocalTime.ToString (1/1/2000 1:23:45 AM) I suggest this one
-Mg

How do I find a repeating set of cells in Excel?

I Have a 2100 Rows and 6 Columns Table
Throughout the table there are only 12 Possible values, say A,B,C,D,E,F,G,H,I,J,K,L
The 12th value L is just a blank filler. It denotes blank cell.
Since there are only 11 possible values througout the table, patterns are observed.
First a Pattern Appears and it is later repeated somewhere in the table.
There can be any number of Patterns, but i have a specific format for a pattern which is to found and reported that way.
Solutions in EXCEL-VBA, PHP-MYSQL or C are welcome.
I have attached an example of what Iam looking for. Suggestions are most welcome to refine
the questions.
Information & Format : http://ge.tt/8QkQJet1/v/0 [ DOCX File 234 KB ]
Example in Excel Sheet : http://ge.tt/69htuNt1/v/0 [ XLSX File 16 KB ]
Please comment for more information or specific requirement.
Please try the code below, change the range to what you need it to be and the sheet number to the correct sheet number (I wouldn't put your full range in just yet because if you have 1000 pattern finds, you'll have to click OK on the message box 1000 times, just test with a partial range)
This will scan through the range, and find any pattern of two within a 10 row range, if you need it to find bigger patterns, youll need to add the same code again with an extra IF statement checking the next offset.
This will only find it if the same pattern exists and the same column structure is present, but its a start for you
Works fine on testing
Sub test10()
Dim rCell As Range
Dim rRng As Range
Set rRng = Sheets("Sheet1").Range("A1:I60") '-1 on column due to offset
'Scan through all cells in range and find pattern
For Each rCell In rRng.Cells
If rCell.Value = "" Then GoTo skip
For i = 1 To 10
If rCell.Value = rCell.Offset(i, 0).Value Then
If rCell.Offset(0, 1).Value = rCell.Offset(i, 1) Then
MsgBox "Match Found at: " & rCell.Address & ":" & rCell.Offset(0, 1).Address & " and " & rCell.Offset(i, 0).Address & ":" & rCell.Offset(i, 1).Address
End If
End If
Next i
skip:
Next rCell
End Sub
***UPDATE***
I have updated my code, the following now finds the pattern wherever it may appear in the next 10 rows:
Sub test10()
Dim rCell As Range
Dim rRng As Range
Dim r1 As Range
Dim r2 As Range
Set rRng = Sheets("Sheet1").Range("A1:I50") '-1 on column due to offset
i = 1 'row length
y = 0 'column length
'Scan through all cells in range and find pattern
For Each rCell In rRng.Cells
If rCell.Value = "" Then GoTo skip
i = 1
Do Until i = 10
y = 0
Do Until y = 10
xcell = rCell.Value & rCell.Offset(0, 1).Value
Set r1 = Range(rCell, rCell.Offset(0, 1))
r1.Select
ycell = rCell.Offset(i, y).Value & rCell.Offset(i, y + 1).Value
Set r2 = Range(rCell.Offset(i, y), rCell.Offset(i, y + 1))
If ycell = xcell Then
Union(r1, r2).Font.Bold = True
Union(r1, r2).Font.Italic = True
Union(r1, r2).Font.Color = &HFF&
MsgBox "Match Found at: " & rCell.Address & ":" & rCell.Offset(0, 1).Address & " and " & rCell.Offset(i, y).Address & ":" & rCell.Offset(i, y + 1).Address
Union(r1, r2).Font.Bold = False
Union(r1, r2).Font.Italic = False
Union(r1, r2).Font.Color = &H0&
End If
y = y + 1
Loop
i = i + 1
Loop
skip:
Next rCell
End Sub

VB6 expected end of statement

I can't figure out what I'm doing wrong. I keep getting the error "Expected: end of statement" under the 'Display output. comment.
Option Explicit
Private Sub cmdOkay_click()
'Declare counter variable (p)
Dim p As Integer
p = 8
'Declare variable to hold calculated minutes
Dim minutes As Integer
'Display title of chart in listbox
MyListBox.AddItem “Cooking Chart”
'For each pound (from 8 to 23), calculate and display minutes
For p = 8 To 23
'Calculate minutes.pounds * 17
minutes = p * 17
'Display output.
MyListBox.AddItem p & “ lbs, “ & minutes & “ minutes.” ERROR
Next p
End Sub
Private Sub cmdExit_Click()
End
End Sub
Your code didn't run because of the double quotes. I changed them and it ran without error
Copy and paste this code:
'Declare counter variable (p)
Dim p As Integer
p = 8
'Declare variable to hold calculated minutes
Dim minutes As Integer
'Display title of chart in listbox
MyListBox.AddItem "Cooking Chart"
'For each pound (from 8 to 23), calculate and display minutes
For p = 8 To 23
'Calculate minutes.pounds * 17
minutes = p * 17
'Display output.
MyListBox.AddItem p & " lbs, " & minutes & " minutes."
Next p

How to display a msgbox as per the dates

[Part 1 - Original question]
I have values like 30, 31, 28 or 29 which are total days of the month.
I want to make a for loop
If I select 28 it should display a msgbox 28 times.
If I select 31 it should display a msgbox 31 times.
The code I tried:
Dim dayst As Variant
Dim tot1 As Variant
tot1 = DateDiff("d", "01/2011", DateAdd("m", 1, "01/2011"))
tot1 = Split(tot1, ",")
For Each dayst In tot1
MsgBox dayst
Next
The above code is showing "31" in the msgbox, instead of 31 times like "1", "2", ... "31"
I want to display a msgbox 31 times incrementing from 1 to 31.
[Part 2 - Updated request]
Default Column Value Example
ID 1 2 ..... 31 totaldays
001 Yes Yes .... Yes 31
002 Yes Yes .... Yes 31
003 Yes Yes .... Yes 31
.....
001 is coming from table
Yes is the default column value for 1 to 31 or 1 to 28
totaldays should be no of days permonth.
How can I accomplish this using vb6.
You could just use a simple loop like this - although I dont see why you would want to have 28-31 MsgBox prompts in a row
Dim tot1 As Long
Dim lngDays As Long
tot1 = DateDiff("d", "01/2011", DateAdd("m", 1, "01/2011"))
For lngDays = 1 To tot1
MsgBox lngDays
Next
Updated version - adds early exit option
Dim tot1 As Long
Dim lngDays As Long
Dim lngExit As Long
tot1 = DateDiff("d", "01/2011", DateAdd("m", 1, "01/2011"))
For lngDays = 1 To tot1
lngExit = MsgBox(lngDays, vbOKCancel, "Press Cancel to exit")
If lngExit = vbCancel Then Exit Sub
Next

Resources