Here's what I've come up with. Adjust instructions as needed to fit your own template.
Instructions
- Set A1 to the value of the year for the month you want represented.
- For the date of this post's first revision, it would be "2015".
- Set A2 to the full name of the month you want represented.
- For the date of this post's first revision, it would be "May".
- Fill A3:G3 with the days of the week, starting with "Sunday" in A3 and ending with "Saturday" in G3.
- Put the following formula in A4:
=IF(WEEKDAY(DATEVALUE(CONCATENATE($A$2," 1, ",$A$1)))=1,1,"")
- Depending on the Month/Year, this formula may return a blank value here. (It will for May 2015.) This is normal.
- Put the following formula in B4:
=IF(A4="",IF(WEEKDAY(DATEVALUE(CONCATENATE($A$2," 1, ",$A$1)))=COLUMNS($A$4:B4),1,""),A4+1)
- Depending on the Month/Year, this formula may return a blank value here. (It will for May 2015.) This is normal.
- Copy the formula from B4 across cells C4:G4. Excel should automatically adjust the cell references in the formula as needed.
- At this point, the formula should evaluate to "1" in one of the cells in row 4, and each cell afterward should return an increment higher than the previous cell. Cells before the "1" should be blank. For May 2015, you should see blanks in A4:E4, "1" in F4 (Friday), and "2" in G4 (Saturday).
- Put the following formula in A5:
=IF(ISERROR(DATEVALUE(CONCATENATE($A$2," ",G4+1,", ",$A$1))),"",G4+1)
- The formula result should be one higher than the value of G4.
- Copy the formula in A5 down cells A6:A9. Excel should automatically adjust the cell references in the formula as needed.
- A6:A9 will evaluate to blanks for now. That is normal.
- Put the following formula in B5:
=IF(ISERROR(DATEVALUE(CONCATENATE($A$2," ",A5+1,", ",$A$1))),"",A5+1)
- The formula result should be one higher than the value of A5.
- Copy the formula in B5 across cells C5:G5. Excel should automatically adjust cell references in the formula as needed.
- Formulas in row 5 should now evaluate to a set of numbers increasing incrementally from column A to column G.
- Select B5:G5 and copy those cells down through B6:G9. Excel should automatically adjust cell references in the formula as needed.
- At this point, the calendar should be appropriately populated for the given month. Cells before the first of the month, and after the last day of the month, should be blank.
- For certain months, such as January 2015, Row 9 will be entirely blank. This is normal.
Functions
- CONCATENATE joins text strings together.
- DATEVALUE returns an Excel "serial number" value for the date represented by a text string. It will return an error if the string does not match a known date format, or if the string does not represent an actual date (e.g.: "January 32, 2015" or "February 29, 2015").
- WEEKDAY returns a value, from 1 to 7, representing the weekday of a given date.
- COLUMNS returns the number of columns spanned by a specified array of cells.
- IF allows you to return a chosen value (or formula result) based on whether a specified formula evaluates to TRUE or FALSE.
- ISERROR returns TRUE if the given formula results in an error, or FALSE if the formula does not generate an error.
Formula Explanations
A4 assembles information from A1 and A2 to generate a text string representing the first day of the month. (e.g.: "May 1, 2015".) Then, it checks to see if the weekday of that date would be Sunday. Returns 1 if it is a Sunday, blank if not.
B4:G4 check the preceding cell to see if it is blank. If not, returns a value one higher than the previous cell. If the previous cell is blank, checks to see if the current weekday matches the first day of the given month - returns 1 if so, blank if not.
A5:A9 add 1 to the value from the end of the preceding row, then combines the result with information from A1 and A2 to form a date string. Checks to see if the date actually exists. Returns the day-of-month number if so, blank if not.
B5:G9 add 1 to the value from preceding cell, then combines the result with information from A1 and A2 to form a date string. Checks to see if the date actually exists. Returns the day-of-month number if so, blank if not.
Screenshot
Example output for May 2015.