Forum Discussion
How to set up incremental refresh based on custom conditions?
- 11 months ago
Hi UBP,
Did you manage to run the incremental to see if it worked? I think the logic should be correct.
Thinking your dataset as being stored in two types of "boxes" (partitions):- Archived Partitions (e.g., last 3 years): This contains all your historical data (e.g., data for 01_11_FCST that was loaded in March). During a refresh, Power BI does not touch, query, or delete this data. It is safe.
- Refresh Partition (e.g., last 10 days): This is the only "box" your M script runs against. Power BI completely replaces this partition every day.
Your M script correctly tells Power BI how to build that new "Refresh Partition" efficiently.
How Your Script Works Correctly:
- On 20th March: The script tells Power BI, "For the last 10 days, query the source for FCST_WRKG AND 01_11_FCST." This data is loaded into the model.
- On 5th May: The script tells Power BI, "For the last 10 days, query the source for FCST_WRKG AND 02_10_FCST."
At this point, the data for 01_11_FCST (loaded in March) is now in an archived partition. It is no longer in the 10-day refresh window, so it is safe and will not be deleted.
Your script is performing exactly as intended: it is preventing Power BI from wasting time querying the data source for 01_11_FCST data in May, because you have correctly told it that no new data for that category exists. You are not losing data; you are just performing an efficient, conditional query for the newest partition.
The Final M Script (British English Comments)
This is the correct script to use in your Power Query transformation *before* applying the incremental refresh policy.
let // Connect to your data source Source = YourDataConnectionSource, // 1. Define categories that must refresh daily DailyRefreshList = {"FCST_WRKG", "BDGT_WRKG", "BDGT_PRIM1"}, // 2. Get the current date to determine conditional logic CurrentDate = Date.From(DateTime.LocalNow()), CurrentYear = Date.Year(CurrentDate), // 3. Determine which special forecast to include in the query TODAY ForecastToIncludeToday = if CurrentDate >= #date(CurrentYear, 3, 15) and CurrentDate <= #date(CurrentYear, 4, 1) then "01_11_FCST" else if CurrentDate >= #date(CurrentYear, 4, 15) and CurrentDate <= #date(CurrentYear, 5, 1) then "02_10_FCST" // ... add other 'else if' conditions here else null, // 4. Build the final list of categories to query at the source CategoriesToKeep = DailyRefreshList & List.RemoveNulls({ForecastToIncludeToday}), // 5. CRUCIAL: Filter the SOURCE data based on the categories to refresh today. // This step is highly efficient and (if possible) will be "Query Folded" // (e.g., becoming a WHERE clause in SQL). FilteredByCategory = Table.SelectRows(Source, each List.Contains(CategoriesToKeep, [Plan_Category]) ), // 6. FINAL: Apply the standard Incremental Refresh date filter. // Power BI manages the RangeStart and RangeEnd parameters. FilteredByDate = Table.SelectRows(FilteredByCategory, each [Plan_Date] >= RangeStart and [Plan_Date] < RangeEnd ) in FilteredByDate✅ If this response solved your problem, please mark it as correct to help other community members.
Hi UBP,
To configure incremental refresh based on custom conditions such as the Plan_Category field, it is necessary to combine Power BI’s native incremental refresh functionality with conditional logic implemented in Power Query. Although incremental refresh is designed to operate on date fields, it is possible to filter data dynamically using category-specific rules.
Step-by-Step Configuration
1. Define Required Parameters
- RangeStart (type: DateTime)
- RangeEnd (type: DateTime)
2. Apply Conditional Filtering in Power Query
let
Source = ... , // your original table
CurrentDate = DateTime.Date(DateTime.LocalNow()),
FilteredData = Table.SelectRows(Source, each
(
// Categories that must always be refreshed
List.Contains({"FCST_WRKG", "BDGT_WRKG", "BDGT_PRIM1"}, [Plan_Category])
)
or
(
[Plan_Category] = "01_11_FCST"
and CurrentDate >= #date(Date.Year(CurrentDate), 3, 15)
and CurrentDate <= #date(Date.Year(CurrentDate), 4, 1)
)
or
(
[Plan_Category] = "02_10_FCST"
and CurrentDate >= #date(Date.Year(CurrentDate), 4, 15)
and CurrentDate <= #date(Date.Year(CurrentDate), 5, 1)
)
),
// Apply date range filter for incremental refresh
DateFilteredData = Table.SelectRows(FilteredData, each
[Plan_Date] >= RangeStart and [Plan_Date] < RangeEnd
)
in
DateFilteredData
Replace [Plan_Date] with the appropriate date field in your dataset that represents the plan period.
3. Configure Incremental Refresh in Power BI Desktop
- Select the relevant table → Modelling → Incremental Refresh.
- Enable incremental refresh and specify the retention period.
- Power BI will use the RangeStart and RangeEnd parameters to apply the date filter.
Official Documentation
https://learn.microsoft.com/en-us/power-bi/connect-data/incremental-refresh-overview
Thank you for your response.
This will filter out plan_category versions when the current date does not fall within the specified period.
I would like to keep all rows but only refresh certain plan_category versions during incremental refresh.
Additionally, the plan data contains future five years of data, which needs to remain in the model and be refreshed as well.
- Zanqueta11 months ago
Super User
Hello UBP, thank you for feedback.
All right, let us consider an alternative approach. Try applying the code below:
1. Define Required Parameters
In Power Query, create the following parameters, such as :RangeStart = #datetime(2025, 1, 1, 0, 0, 0), RangeEnd = #datetime(2026, 1, 1, 0, 0, 0)
These are mandatory for enabling incremental refresh.
2. Add a Conditional Flag Column
Use the following M code to add a column that flags whether a row should be refreshed:let Source = ... , // your original table CurrentDate = DateTime.Date(DateTime.LocalNow()), AddRefreshFlag = Table.AddColumn(Source, "RefreshFlag", each if List.Contains({"FCST_WRKG", "BDGT_WRKG", "BDGT_PRIM1"}, [Plan_Category]) then true else if [Plan_Category] = "01_11_FCST" and CurrentDate >= #date(Date.Year(CurrentDate), 3, 15) and CurrentDate <= #date(Date.Year(CurrentDate), 4, 1) then true else if [Plan_Category] = "02_10_FCST" and CurrentDate >= #date(Date.Year(CurrentDate), 4, 15) and CurrentDate <= #date(Date.Year(CurrentDate), 5, 1) then true else false ), // Apply date filter only to rows flagged for refresh FilterForIncremental = Table.SelectRows(AddRefreshFlag, each ([Plan_Date] >= RangeStart and [Plan_Date] < RangeEnd and [RefreshFlag] = true) or [RefreshFlag] = false ) in FilterForIncrementalReplace [Plan_Date] with the appropriate date field representing the plan period.
This approach ensures that:- All data remains in the model, including future years.
- Incremental refresh is applied only to relevant rows, based on business rules.
- No data is permanently excluded during the Power Query transformation.
✅ If this response resolved your issue, please mark it as correct to assist other members of the community.
- UBP11 months agoRegular Visitor
Thank your for your response Zanqueta
Regarding your second solution, the data is not filtered out at a high level. I’m still not sure how this will work .However, I would like to try your option.
I tried a similar approach, but it only returns rows where the condition is true, filtering out the false rows after the incremental refresh (because of true filter)
([Plan_Date] >= RangeStart and [Plan_Date] < RangeEnd and [RefreshFlag] = true)
How do I set up incremental refresh in Power BI Desktop? This plan data includes five future years of data, and I’m not completely clear on how to configure it.
I do have paramaters set to
Rangestart = #datetime(2024, 1, 1, 0, 0, 0)
Rangeend = #datetime(2035, 12, 31, 0, 0, 0)Thank you
- Zanqueta11 months ago
Super User
Hello UBP ,
I make a new code
let // Replace 'YourDataConnectionSource' with the step that connects to your table Source = YourDataConnectionSource, // Define the categories that must refresh daily DailyRefreshList = {"FCST_WRKG", "BDGT_WRKG", "BDGT_PRIM1"}, // Determine the current date (used for Plan_Category logic) CurrentDate = Date.From(DateTime.LocalNow()), // 1. Conditional Logic: Check which specific monthly FCST version should be included today ForecastToIncludeToday = if CurrentDate >= #date(Date.Year(CurrentDate), 3, 15) and CurrentDate <= #date(Date.Year(CurrentDate), 4, 1) then "01_11_FCST" else if CurrentDate >= #date(Date.Year(CurrentDate), 4, 15) and CurrentDate <= #date(Date.Year(CurrentDate), 5, 1) then "02_10_FCST" else null, // 2. Build the final list of categories that need to be fetched for today's refresh CategoriesToKeep = DailyRefreshList & List.RemoveNulls({ForecastToIncludeToday}), // 3. CRUCIAL STEP: Filter the source ONLY for the categories that need to be refreshed today. FilteredByCategory = Table.SelectRows(Source, each List.Contains(CategoriesToKeep, [Plan_Category])), // 4. FINAL STEP: Apply the Incremental Refresh filter FilteredByDate = Table.SelectRows(FilteredByCategory, each [Plan_Date] >= RangeStart and [Plan_Date] < RangeEnd ) in FilteredByDateThe final M script must filter by Plan_Category first to ensure the partitioning engine only receives the categories you want to refresh today.
You have correctly created the parameters. Their specific values (#datetime(2024, 1, 1, 0, 0, 0) to 2035...) are simply placeholders and are ignored by the service after publication.
Setting Value Rationale Base Column [Plan_Date] (Your date column) The column used for partitioning. Archive/Store rows for 6 Years This Retention setting is crucial. It ensures the entire 6-year planning horizon (Current + 5 Future Years) is stored in the Power BI Service partitions. Incrementally refresh rows for 6 Years This Refresh setting dictates the size of the rolling window that is updated. By setting it to 6 years, whenever a refresh is triggered (and the M logic allows the Plan_Category through), the service will reload the entire 6-year block of data for that category, ensuring future dates are updated. If this post helps, then please consider Accepting it as the solution to help the other members find it more quickly. Appreciate your KUDO if you find it useful.