Excel VBA - Do While Loop - Date in a cell - excel

I want to increase the settlement date which is (assigned to cell N13) until the network days (assigned to cell P11) reaches 3.
Network days counts the number of weekdays between two dates excluding holidays. However, I added a range of holidays to it.
Sub Settlement_Date()
Do While Cells(16, 12) < 3
Cells(14,11)
Loop

to increase Cells(14,11) within the loop, change that line to
Cells(14,11) = Cells(14,11) + 1

Managed to do it myself but got snippets in some of the post I found here
Sub Settlement_Date()
Do While ActiveCell.Offset(0, 2).Value < 3
ActiveCell.Value = ActiveCell.Value + 1
Loop
End Sub
Moving Right One Cell
Add one day to date in cells using VBA

Related

Excel VBA set date to nearest day, is there a better way to do it?

Recently I needed to set some dates in Excel to the nearest Wednesday for a scheduling process.
I found some answers here in stackoverflow and other sites but none were giving the desired result at all times. So, I wrote a little sub to achieve this for any day you need, but it got me wondering if there was a better way to achieve this, if not then I hope you find it helpful.
EDIT: This sub is part of a large process run by a macro by clicking a custom ribbon button, the input dates come from an array, therefore, I have to use vba to change them.
Here is the matrix with results:
And the code is this:
Sub SetNextWed()
Range("A6").Activate
Do Until ActiveCell.Value = ""
SetToNextDate ActiveCell.Value, vbWednesday, 2
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
Sub SetToNextDate(MyDate As Date, DayOfWeek As Integer, Column As Integer)
Dim dNext_Wednesday As Date
dNext_Wednesday = MyDate
Select Case Weekday(MyDate)
Case DayOfWeek
dNext_Wednesday = MyDate
Case Else
dNext_Wednesday = MyDate + DayOfWeek - Weekday(MyDate)
If MyDate > dNext_Wednesday Then
dNext_Wednesday = MyDate + ((DayOfWeek + 7) - Weekday(MyDate))
End If
End Select
I've tried this solutions:
https://vbaf1.com/date-time/next-wednesday-date/
https://www.mrexcel.com/board/threads/determine-date-of-next-and-most-recent-monday-vba.983467/
How do I find out what the Date is for Next Saturday or the current Saturday?
In Excel, dates are just numbers, and the date number modulo 7 gives you the day of the week, with 0 as Saturday through 6 as Friday. So you don't need VBA. The following cell formula calculates the Wednesday date you desire: =7*INT((A1+2)/7)+4, assuming the original date is in A1.

How to put date to right name of a week days in each month and without weekends

I have this monthly work report sheet. And I don't know how to make some autofill for column B which will provide a number of a day for a right name of a week day in column A.
I was only able to find formula which gave me date of first work day in first week of the month.
This will take month and year from B2 and B3 cells and generate first
day in month:
=TEXT(DATEVALUE(CONCATENATE(1;B2;B3));"dd.mm.yyyy")
This will find from first day in mnoth the first working day.
=TEXT(WORKDAY(EOMONTH(R2;-1); 1);"dd.mm.yyyy")
But the first problem is that the each next month a first work day starts in different name of a week.
And second problem is that the each week has a "Sum:" after each friday.
Please, can someone provide me any solution via formulas or macro?
This is really poorly written tbh, but maybe you can make use of it.
Basically, just select the cell that has the first day of the month and enter the date:
The code will then use the current date and work its way down your list until it runs into Sum: at the bottom or the current month ends and put in the date using dd.mm format (feel free to change this in the code).
If it finds Sum: to its left, it will add 3 days to its current date.
Otherwise, it will add 1 day to its current date.
Worth noting that it looks for the name of the current month in cell B2
If you want to add a period after the format (like you showed in your screenshot), just add an extra . to the line Format(aDate, "dd.mm")
It would become ActiveCell.Value = Format(aDate, "dd.mm.")
Sub GenerateDates()
Dim aDate
aDate = InputBox("Enter Date of Current Cell", "Enter Date of Current Cell")
If IsDate(aDate) Then
aDate = DateValue(aDate)
Do While ActiveCell.Value = ""
ActiveCell.Value = Format(aDate, "dd.mm")
ActiveCell.Offset(1, 0).Select
If ActiveCell.Offset(0, -1).Value = "Sum:" Then
aDate = DateAdd("d", 3, aDate)
ActiveCell.Offset(1, 0).Select
Else
aDate = DateAdd("d", 1, aDate)
End If
If MonthName(Month(aDate)) <> Range("B2").Value Then Exit Sub
Loop
Else
MsgBox "Invalid Date", vbCritical, "Invalid Date!"
Exit Sub
End If
End Sub
Of course, this could be modified to assume that you select the first of the month on the cell - or it could attempt to figure out the first of the month for you to begin by starting at the top, but this just seemed simple enough.
Display the date in reference to the weekdays
Let's use an Excel formula:
=LET(
WeekRange; A6:A34;
WeekInterval; 6;
ThisMonth; MATCH(B2; {"January";"February";"March";"April";"May";"June";"July";"August";"September";"October";"November";"December"};);
ThisYear; B3;
WeekNames; {"Monday";"Tuesday";"Wednesday";"Thursday";"Friday"};
FirstDay; DATE(ThisYear; ThisMonth; 1);
LastDay; EOMONTH(FirstDay; 0);
FirstWorkDay; WORKDAY(EOMONTH(FirstDay; -1); 1);
WeekShift; WEEKDAY(FirstWorkDay; 2);
WeekInMonth; QUOTIENT(ROW(WeekRange) - INDEX(ROW(WeekRange); 1); WeekInterval);
WorkDays; IFNA(FirstWorkDay - WeekShift + MATCH(WeekRange;WeekNames;0) + 7*WeekInMonth; "");
TEXT(WorkDays; "[<" & FirstDay & "] ;[>" & LastDay & "] ;dd.mm."))
Details:
WeekInterval - the number of cells between the same weekdays
WeekShift - the weekday of the first workday of the month starting from Monday
WeekInMonth - a week number in WeekRange
IFNA(...; "") - put an empty string next to the "Sum:"
"[<FirstDay] ;[>LastDay] ;dd.mm." - display a space when a date is outside the month (keep spaces after closing square brackets ])
I use semicolon ; as a separator due to my locale settings.
This formula has to be placed once next to the first Monday of the WeekRange (in your case in a cell B6). The result will be spilled on weekdays.

VBA to Copy Range on Year to Date basis

I have a worksheet with three columns. Column C:C has all calendar dates, N:N contains Data 1 and R:R Data 2.
The macro I am trying to write should check dates in Column C to find dates that are (EDIT) less than today and copy data of Column R:R to Column N:N.
Does this make sense? I have a feeling it's a super basic thing, but oh well, I spent one hour Googling without success.
Example
Thanks!
In Excel a date is just the number of days which starts counting from January 1st 1900. So January 1, 1900 is number 1. With this in mind, it is very easy to calculate with dates. Hours and minutes are fractions.
This sub should do the job:
Sub CopyData()
For i = 1 To 100
If Cells(i, 3) < DateTime.Date Then
Cells(i, 14) = Cells(i, 18)
End If
Next
End Sub
Replace the number 100 with the amount of lines you have or with some logic to count the number of lines.
Succes.

How could I generate a list of dates based on user input?

Say that I have a spreadsheet that allows users to put in some metadata like the following:
Date range start: mm/dd/yyyy
Date range end: mm/dd/yyyy
Mondays: (y/n)
Tuesdays: (y/n)
Wednesdays: (y/n)
Thursdays: (y/n)
Fridays: (y/n)
Based on that, I want to generate a list of dates in the format of mm/dd/yyyy that starts on 4/1/2019, ends on 4/30/2019 and only includes dates of the day that was indicated with a y.
So if a user put in start date = 04/01/2019, end date = 04/30/2019, y for just Mondays and Wednesdays, the list would look like:
04/01/2019
04/03/2019
04/08/2019
04/10/2019
04/15/2019
04/17/2019
04/22/2019
04/24/2019
04/29/2019
Couldn't find an Excel function to start with. I don't know VBA but imagine it would be possible to do this with that.
If I wanted to write this in Python by using an add-in like Pyxll, would everyone with a copy of the Excel file be required to install Pyxll?
#simplycoding: VBA doesn't have a function or suroutine ready to do what you are looking for right out of the box. However, you can compose your own ones based on whatever VBA has on offer, which is a lot.
This is my startup scenario:
I wrote, tested and commented the following SUB in some 20 minutes. Believe me when I say I'm not a first row VBA coder.
Sub DateList()
'(C) Antonio Rodulfo, 2019
Dim dEnd, dStart, dCounter As Date
Dim iaDays(1 To 5) As Integer
Dim iCounter, iRow As Integer
' Indent your sentences properly
' Reading parameters
dStart = Cells(2, 1).Value
dEnd = Cells(2, 2)
For iCounter = 1 To 5
If Cells(2, 2 + iCounter) = "y" Then
iaDays(iCounter) = 1
Else
iaDays(iCounter) = 0
End If
Next iCounter
' Here's where the list of dates will start
iRow = 4
' I process the dates: Excel stores dates in its own
' coding, which we can use to run a for..next loop
For dCounter = dStart To dEnd
' Weekday(datecode,type) returns the day of week
' type 2 means the week starts with monday being day 1
iCounter = Weekday(dCounter, 2)
' The sub only sets dates for working days
' monday to friday
If iCounter <= 5 Then
' date must be set if found "y" in the matching day
If iaDays(iCounter) = 1 Then
' I like setting the proper numberformat so
' that no surprises are found when reading it
Cells(iRow, 1).NumberFormat = "dd/mmm/yyyy"
Cells(iRow, 1) = dCounter
' Increasing iRow sets the focus on next row
iRow = iRow + 1
End If
End If
' Adding the index name to the next sentence helps
' tracking the structures
Next dCounter
End Sub
I always recommend using Option Explicit when coding. It can seem annoying at first, but it will help you a lot when testing and debugging your code.
Good luck!
I was challenged by your request to not use VBA at all, so I was playing around with some Excel functions and here's what I would like you to try.
I used your metadata in the following cells:
OPTION 1 - easy
Enter the following Array function into cell D1 (Ctrl+Shift+Enter) and drag it all the way to the right (e.g. up to cell AW1):
=IF(AND(ISNUMBER(MATCH(WEEKDAY($B$1+COLUMN()-4,2),--($B$3:$B$7="y")*(ROW($B$3:$B$7)-2),0)),($B$1+COLUMN()-4)<=$B$2),$B$1+COLUMN()-4,"")
All dates that are between Start & End dates and for the required weekdays are displayed. However, this option does not prevent the gaps, so you will have lots of blank columns in between.
OPTION 2 - complete
Enter the following Array function into cell D2 (Ctrl+Shift+Enter) and drag it all the way to the right:
=IFERROR(SUMPRODUCT(SMALL(($B$1+ROW($B$1:$B$30)-1)*(IF(ISNUMBER(MATCH(WEEKDAY($B$1+ROW($B$1:$B$30)-1,2),(--($B$3:$B$7="y")*(ROW($B$3:$B$7)-2)),0)),1,0)),30-COUNT(MATCH(WEEKDAY($B$1+ROW($B$1:$B$30)-1,2),(--($B$3:$B$7="y")*(ROW($B$3:$B$7)-2)),0))+COLUMN()-3)),"")
As you can see, this option displays all "proper" dates next to each other, without any gaps.
Hope you will find this helpful - I had lots of fun playing around with the second option and I'm sure it can be still improved.
Take care,
Justyna

Converting all dates in a year into multiple strings using Excel VBA

I have to write a vba code that convert all dates in a year into days in a week eg. Monday, Tuesday, Wednesday....Sunday and the value of all days in a week eg.Monday must be in a string format. (See image inserted)
I tried using the .NumberFormat function but it does not work since the format is still under the date format although the values displayed are correct (please look at the formula bar of F10). Below is the code I have written:
Sub convertdate()
Range("A7:A371").Copy
'copy all the dates throughout the year'
Range("F7:F371").PasteSpecial xlPasteFormulasAndNumberFormats
'paste it into F column'
Worksheets("Sheet1").Range("F7:F371").NumberFormat = "dddd"
'convert the dates into days'
Sum1 = Application.SumIf(Range("F7:F371"), "Monday", Range("B7:B371"))
'example of calculating the total rainfall of all Mondays throughout the year'
Worksheets("Sheet1").Range("G22").FormulaArray = Sum1
End Sub
The formula bar from cell F7:F371 should display the string value "Monday","Tuesday" etc depending on the dates rather than the date itself.The reason of converting it into a string is so that it could be use in a SUMIF function later on to calculate the total rainfall of all Mondays,Tuesday etc.
Appreciate if anyone could help. Thank you.
A formula can do this.
In cell F7 enter =TEXT(A7,"dddd") and drag down.
This will format the date to show the full day name as a string.
https://support.office.com/en-us/article/TEXT-function-20d5ac4d-7b94-49fd-bb38-93d29371225c
Try something like this. It will loop through all the dates in Column A (starting in row 7) and put the associated Weekday name in Column F:
Sub test()
Dim i As Long
Dim lRow As Long
With ActiveSheet
lRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = 7 To lRow
.Cells(i, 6).Value = WeekdayName(Weekday(.Cells(i, 1).Value, 1), False, 1)
Next i
End With
End Sub

Resources