A few days ago, we received a requirement to create a timesheet for the selected month in the Power Apps application. This timesheet needs to display the selected month’s week names, starting from the first date to the last date, dynamically.
In this article, I will explain how to create a monthly timesheet in Power Apps step by step.
Create Power Apps Monthly Time Sheet
In the example below, you can see that the Power Apps timesheet contains a dropdown control with month names. When im select any month, the weekdays from the first date to the last date of that month appear in the gallery, and weekends are disabled.
I can provide the working hours on weekdays. There is a WK field at the end of each week, which calculates the total working hours for that week. Next, the MO field calculates the total sum of working hours across all weeks.
Finally, the total chargeable hours are displayed at the bottom. At the top, I im also showing the current logged-in user’s display name and ID as their employee number.

Follow the steps below to achieve this!
- Open the Power Apps application, click the Settings icon on the top ribbon, and then the settings page will open, as shown below. Click on Display, choose the Custom option in the Size setting, and then provide the Width and Height according to your needs.

- In the new screen, add two text input controls and a dropdown control. Then provide the formulas below in the mentioned properties.
- txt_EmpName control’s Default property:
User().FullName
- txt_EmpNumber control’s Default property:
User().EntraObjectId
- drp_Month control’s Items property:
[
"January 2025",
"February 2025",
"March 2025",
"April 2025",
"May 2025",
"June 2025",
"July 2025",
"August 2025",
"September 2025",
"October 2025",
"November 2025",
"December 2025"
]
- Provide the formula below in the OnVisible property of the current screen.
ClearCollect(colHours, []);
Here, we created an empty collection named colHours using the ClearCollect() function.
- Then, add the following formula to the OnChange property of the drp_Month control.
Clear(colHours);
Set(
varSelectedMonth,
Month(DateValue("01 " & drp_Month.Selected.Value))
);
Set(
varSelectedYear,
Year(DateValue("01 " & drp_Month.Selected.Value))
);
Set(
varStartDate,
Date(varSelectedYear, varSelectedMonth, 1)
);
Set(
varDaysInMonth,
Day(DateAdd(varStartDate, 1, TimeUnit.Months) - 1)
);
Set(varMonthName, First(Split(drp_Month.Selected.Value, " ")).Value);
Set(varYearValue, Value(Last(Split(drp_Month.Selected.Value, "")).Value));
ClearCollect(
colMonthDays,
ForAll(
Sequence(varDaysInMonth),
{
DayName: Text(DateAdd(varStartDate, Value - 1, TimeUnit.Days), "ddd"),
DayDate: DateAdd(varStartDate, Value - 1, TimeUnit.Days),
WeekNumber: WeekNum(DateAdd(varStartDate, Value - 1, TimeUnit.Days), StartOfWeek.Monday)
}
)
);
Clear(colMonthDaysWithWK);
ForAll(
colMonthDays As d,
Collect(
colMonthDaysWithWK,
d,
If(
d.DayName = "Fri",
{
DayName: "WK",
DayDate: Blank(),
WeekNumber: d.WeekNumber
}
)
)
);
If(
Last(colMonthDays).DayName <> "Fri",
Collect(
colMonthDaysWithWK,
{
DayName: "WK",
DayDate: Blank(),
WeekNumber: Last(colMonthDays).WeekNumber
}
)
);
// Add final MO record
Collect(
colMonthDaysWithWK,
{
DayName: "MO",
DayDate: Blank(),
WeekNumber: Blank()
}
);
Here,
- Using the Clear() function, we are removing the colHours collection data.
- varSelectedMonth = This variable contains the selected month number from the dropdown. For example, if we choose “April 2025”, this variable contains the value 4.
- varSelectedYear = This variable extracts the year from the selected month in the dropdown. Exe: 2025.
- varStartDate = This variable includes the 1st date of the month chosen in the dropdown. Exe: if you choose “April 2025”, this variable contains “4/1/2025, 12:00 AM.”
- varDaysInMonth = This variable holds the number of days in the selected month. Exe: if you choose “April 2025”, this variable contains 30.
- varMonthName = Holds the selected month name. For example, if you choose “April 2025”, this variable includes the month of April.
- varYearValue = It extracts the last digit of the year from the selected value in the dropdown. For example, 5, because all months end with 2025.
- colMonthDays = This collection is iterating over the number of days in a month using the variable varDaysInMonth and storing the data for the following three fields:
- DayName = It includes the days’ names, such as Mon, Tue, Wed, etc.
- DayDate = It consists of the dates, such as 1/1/2025, 12:00 AM, 1/2/2025, 12:00 AM, etc.
- WeekNumber = It contains the week numbers that start from 1,2, etc.
- colMonthDaysWithWK = Then, we created another collection to include the WK field, which appears exactly after each Friday, used for calculating the sum of working hours in a week.
- If the month ends with any weekdays except Friday, we also add the WK field to calculate the last week’s working hours.
- At last, again we are adding one more field named MO, which will display at the end of the month. This field we are used for calculating the entire month’s working hours.
- Add a Horizontal Container control from the +Insert tab, then provide the values below to the given properties.
Direction = Horizontal
Justify(horizontal) = start
Justify(vertical) = start
Gap = 0
Horizontal Overflow = Scroll
Vertical Overflow = Hide
Wrap = Off
Size [Width] = 2000
Size [Height] = 256

- Within this horizontal container, add a regular container and rename it “Cont_Galleries”. Then, add two text input controls and their corresponding text labels for “Project Number” and “Description”.
- Then, within the same regular container, add a Blank Horizontal gallery [Gal_Months]. Then, provide the values below for the given properties.
Items = colMonthDaysWithWK
Template Size = 95
Height = 80
X = lbl_Description.X+lbl_Description.Width
Width = Switch(
true,
varDaysInMonth = 31 && CountIf(colMonthDaysWithWK, DayName = "WK") >= 6, 4260,
varDaysInMonth = 31 && CountIf(colMonthDaysWithWK, DayName = "WK") = 5, 4160,
varDaysInMonth = 31, 4160,
varDaysInMonth = 30 && CountIf(colMonthDaysWithWK, DayName = "WK") >= 6, 4160,
varDaysInMonth = 30 && CountIf(colMonthDaysWithWK, DayName = "WK") = 5, 4060,
varDaysInMonth = 30, 4060,
varDaysInMonth = 29, 3860,
varDaysInMonth = 28, 3762,
Max( (CountRows(colMonthDaysWithWK) * 95), 3762 )
)
Here:
- We used a Switch() function to provide width to the gallery, because the number of days in each month will vary between 28, 30, and 31 days.
- To adjust the width of the gallery for all months, we used the following formula. Here, the varDaysInMonth variable contains the number of days present in the selected month.

- Now, within this gallery, add two text labels and one Rectangle control. Then provide the following values to the given properties.
- lbl_Week‘s Text property:
ThisItem.DayName
- lbl_Date‘s Text property:
Text(ThisItem.DayDate,"d")
- Rectangle’s Fill Property:
If(
ThisItem.DayName in ["Sat", "Sun","WK"],
RGBA(200, 200, 200, 0.5),
RGBA(255, 255, 255, 1)
)
To display the weekend and the WK field in gray, we use this formula.

You can adjust the rectangle’s width and height according to your needs. I have given Width 95, Height 70.
- We need to update the regular container’s [Cont_Galleries] Minimum Width property with the value below.
Gal_Month.Width +95
Here, the minimum width we are taking is based on the gallery’s [Gal_Month] width, plus 95 extra pixels.

- After this, add another blank horizontal gallery [Gal_Hours] within the same regular container. Then provide the values below for the mentioned properties.
Items = colMonthDaysWithWK
Height = 80
Width = Gal_Month.Width
TemplateSize = 95
X = lbl_Description.X+lbl_Description.Width
Y = Gal_Month.Y+Gal_Month.Height

- Within the above gallery [Gal_Hours], add a text input control and provide the following values for the given properties.
DisplayMode = If(
ThisItem.DayName in ["Sat", "Sun","WK"],
DisplayMode.Disabled,
DisplayMode.Edit
)
Default =
If(
ThisItem.DayName = "WK",
Sum(Filter(colHours, WeekNumber = ThisItem.WeekNumber), EnteredHours),
If(
ThisItem.DayName = "MO",
Sum(colHours, EnteredHours),
// day cell
If(
!IsBlank(ThisItem.DayDate),
LookUp(colHours, DayDate = ThisItem.DayDate, EnteredHours),
Blank()
)
)
)
Height = 70
Width =95
OnChange =
Set(_hoursVal, Value(Self.Text));
If(
!IsBlank(ThisItem.DayDate),
If(
IsBlank(LookUp(colHours, DayDate = ThisItem.DayDate)),
Collect(colHours, { DayDate: ThisItem.DayDate, EnteredHours: _hoursVal, WeekNumber: ThisItem.WeekNumber }),
Patch(colHours, LookUp(colHours, DayDate = ThisItem.DayDate), { EnteredHours: _hoursVal })
);
If(IsBlank(Self.Text), RemoveIf(colHours, DayDate = ThisItem.DayDate))
)
Here:
- To disable the text fields for weekends and the WK field, we used the formula in the DisplayMode property.
- In the OnChange property, we are calculating the sum of working hours for each week.
- _hoursVal = Contains the entered hours in text input controls for each date.
- Then, it checks if this record in the gallery actually has a valid date, not a WK or MO row.
- Only then proceed to save hours and skip WK and MO records since those don’t have DayDate.
- IsBlank(LookUp(colHours, DayDate = ThisItem.DayDate)) = It checks inside the collection colHours if that day already has an entry.
- If no record exists yet,
- It adds a new record using the Collect() with the date (DayDate), the entered hours (EnteredHours), and the week number (WeekNumber).
- If a record for that date already exists,
- It updates (patches) the record with the new hours value.
- If(IsBlank(Self.Text), RemoveIf(colHours, DayDate = ThisItem.DayDate)) = If we remove the hours entered in the text input control, from the collection, it also removes that record.
- Then, in the Default property:
- We are checking if the record is WK. Then, using the same week number, we add and display the hours entered for that whole week. This will be the same for all WK fields in a month.
- If the current record is MO, we add all the hours entered for each week and display them for this month.
- If the current record is not MO or WK, then only the entry we made displays.
- If we didn’t enter any value, then it shows a blank value.

- After that, again add a blank horizontal gallery [Gallery_WKTotals] within the same regular container. Then provide the values below to the given properties.
Items = colMonthDaysWithWK
Height = 80
Width = Gal_Month.Width
TemplateSize = 95
X = lbl_TotalHours.X+lbl_TotalHours.Width
Y = Gall_Hours.Y +Gall_Hours.Height

- Now, within the above gallery [Gallery_WKTotals], add a text input control and provide the below values to the given properties.
Default = If(
ThisItem.DayName = "WK",
Sum(
Filter(colHours, WeekNumber = ThisItem.WeekNumber),
EnteredHours
),
If(
ThisItem.DayName = "MO",
Sum(colHours, EnteredHours),
LookUp(colHours, DayDate = ThisItem.DayDate, EnteredHours)
)
)
DisplayMode = If(
ThisItem.DayName in ["Sat", "Sun","WK"],
DisplayMode.Disabled,
DisplayMode.Edit
)
Height = 70
Width = 95
- Here in the Default property, we check if the current record is WK. If it is, we add all the hours entered for the same week number and display the sum.
- If the current record is MO, then add all the hours that we have entered.
- In DisplayMode, we check if the current record is on a weekend (WK, Sat, or Sun). We are disabling those cells.

- At last, add a text label outside the horizontal container to display the total chargeable hours. Then, provide the code below in its Text property.
"Chargable Hours:" & Sum(colHours, EnteredHours)
Here, Sum(colHours, EnteredHours) will return the sum of entered hours for the entire month.

Now, save the changes and publish the app. Then, preview it and provide the working hours in the text input controls. You will see that the weekdays are automatically calculated, as well as the total working hours for the entire month.
I hope you found this article helpful!, In this article, I explain how to create a monthly timesheet in Power Apps and calculate the total working hours for each week and the entire month. Additionally, disabling the weekends and the total week calculation field WK, etc.
Also, you may like:
- Power Apps Modern Form Control
- Show Hide Fields Based On Power Apps Dropdown Selection
- Set Default Value in Power Apps Modern Radio Button Control
- Power Apps Modern Header Control
- You do not have permission to view the membership of the Group

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.