SharePoint Blogs / SharePoint University
SharePoint Blogs and SharePoint University - all in one place!
Need SharePoint Training? Attend a SharePoint Bootcamp!

Please delete cookies related to sharepointblogs.com and sharepointu.com to resolve login issues!

Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference

When using the (now infamous) "Today" column trick, in calculated columns, you'll no doubt notice that the dates resulting from this calculation don't dynamically update.  This has become a major point of contention with the use of this technique in formulas because in most (if not all) cases, the whole point of using this in a formula is to track information that does actually need to be updated (daily, in most cases).

I've lost count on the number of discussion threads pointing out this flaw (several of which I've participated in myself), so in an attempt to come up with a solution, I'm going to list out a couple options you can take that can (could) be workable to get around this limitation.

Note - these are "coded" solutions, but are simple to deploy (modify the following code to meet the needs of your specific environment and best practices).


Option 1 - Console application added as a "Scheduled Task" in Windows

Performs a "SPListItem.SystemUpdate()" of all items on the target list at 12:01 a.m. each morning (as discussed here in a thread I participated in awhile back on the "SharePointU" forums).

This program uses "SPListItem.SystemUpdate()" in order to not modify any of the tasks visible details, but since it is an actual update, it will in fact force a re-calculation of any formula using the "Today" reference (the alternative of the "SPListItem.Update()" method will change the "Modified" date property, which in this case we don't want because it'd be preferable to preserve the date it was last modified by an actual person instead of the system).

Steps to create the application (using the object model - haven't tried with web services):

  1. In Visual Studio, create a new "Console Application" project (named something like "UpdateSPList").

  2. Add in references for "SharePoint" and "System.Configuration" (the latter is optional, but will allow you to use the appropriate "ConfigurationManager" call instead of "ConfigurationSettings").

  3. Add in an "Application Configuration File" (will house the name of the site and list - contained in this configuration file so you can make changes later).

  4. Add in two "key's" to hold the name of the site and list:

    (Example)
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     
    <appSettings>
       
    <add key="Site" value="http://My_Portal/Sites/TheSite"/>
       
    <add key="List" value="Tasks"/>
     
    </appSettings>
    </configuration>

  5. Change the default "Program.cs" code to be:

    using Microsoft.SharePoint;
    using System.Configuration;
    namespace UpdateSPList
    {
        
    class Program
        
    {
             
    static void Main(string[] args)
             
    {
                  
    SPSite site = new SPSite(ConfigurationManager.AppSettings["Site"]);
                  
    SPWeb web = site.OpenWeb();
                  
    SPList list = web.Lists[ConfigurationManager.AppSettings["List"]];
                  
    web.AllowUnsafeUpdates = true;
                  
    foreach (SPListItem item in list.Items)
           {

                      
    item.SystemUpdate();
           }

                 
    web.AllowUnsafeUpdates = false;
             
    }
        
    }
    }

  6. Build (compile) the program.

  7. Copy the "exe" and "config" files from the "debug" folder into the server location that you'll use for production ("UpdateSPList.exe" and "UpdateSPList.exe.config").

  8. Create a new "Scheduled Task" in Windows scheduler that uses "UpdateSPList.exe" and have it scheduled to run after midnight of each day (I use 12:01 a.m., setup as applicable for you).


When ran, the application will connect into the site, find the list, open each item on the list and perform an update on it that will force the recalculation of all formulas which will update any dates based off the "Today" reference.


Option 2 - Add code to the page in SPD to update the contents each time the page is viewed.

This approach comes with a warning, if you choose to enable the ability to run server-side code in your pages, anyone who can upload pages, can access system pages and/or use SPD to connect to and modify pages, will be able to run their own code (use this approach at your own risk).

To make this approach work, we need to do two things - modify the "web.config" file to allow us to run code, and then add in the code.

  1. Modify the "web.config" file:
    1. Using an editor of your choice (notepad, Visual Studio, etc.), open the web configuration file for your site (generally located at "C:\Inetpub\wwwroot\wss\VirtualDirectories\80\web.config" if using the "default" site for your instance).
    2. Modify it as follows (you'll be adding in the "PageParserPath" node):

      <SafeMode MaxControls="200" CallStack="false" DirectFileDependencies="10" TotalFileDependencies="50" AllowPageLevelTrace="false">
      <PageParserPaths>
      <
      PageParserPath VirtualPath="/*" CompilationMode="Always" AllowServerSideScript="true" IncludeSubFolders="true"/>
      </
      PageParserPaths>
      </
      SafeMode>

This will tell the system the path that contains the pages we want to run code on ("/*" will allow it on all pages), and whether or not to actually allow the code (again - use with caution).

Once we have enabled the ability to run code, we need to add the code into the page.

  1. Using the default "Tasks" list as our example:
    1. Open SPD and connect to your site.
    2. Once connected, open the "AllItems.aspx" page for the "Tasks" list (Root of site > Lists > Tasks > AllItems.aspx).
    3. In the "Code" view of the site, locate the section "<SharePoint:RssLink runat="server"/>" (used as an example - you could place the code wherever you see fit) and add in the following just below it:

      <script runat="server">
      protected void Page_Load(object sender, EventArgs e)

      {   SPSite site = new SPSite("<Your_Site_URL>");  
         
      SPWeb web = site.OpenWeb();
        
         
      SPList list = web.Lists["Tasks"];
        
         
      web.AllowUnsafeUpdates = true;
        
         
      foreach (SPListItem item in list.Items)
        
         
      {
            
             
      item.SystemUpdate();
        
         
      }
         
      web.AllowUnsafeUpdates = false; 
      }

      </script>

(Notice it's the exact same code as used in the "Console Application" except for the site and list are specified in the code rather than in a configuration file for this example)

  1. Save the page (ignoring any errors or "squiggly" lines you may see in the code view).

Since we've told the system to allow us to run code in the page (via the "web.config" file), once we now visit the page, all items on the list should be updated without throwing any errors (the update of items will occur each time the page is visited).

---------------------------------------------

Both of these solutions will work, but depending on your environment may, or may not, be doable (especially if you don't have access to the server running SharePoint or access via SPD - I generally don't develop for web services since I do have the access I need, but you may be able to work up a similar application that accesses SharePoint via its web services as another option). 

Additionally, the above code should be used as a reference for how to create the "Update" functionality and can (should) be written in a better fashion (disposing objects etc.) to follow good programming practices...this is just an example - modify it as you see fit.

Aside from these two methods, you may also be able to use a workflow to update the list that fires off each time an item is updated.  Although this approach does work as well, I don't like the idea of creating an endless loop and I believe there's also an issue with how many times a self-fired SPD workflow will run (it appears to stop working after a time). 

There may be other methods as well to get the calculated column's formula to dynamically update each day, but both of the methods I've listed above seem to do the trick with minimal effort (and are easy to disable/update when needed).

I'm still looking for other approaches to tackle this, especially since I've been blogging recently on Mark Miller's site (EndUserSharePoint.com) regarding calculated columns (with a bunch of examples using the "Today" column trick).  So if anyone has any other suggestions/approaches (not just coded, any other ideas that might work better for end-users, not just programmers) please share them.

Hopefully these ideas will help, they're not perfect (perfect would be the system doing what we want without these types of hacks), but at least as a work-around they'll do the job.

Till next time...

- Dink


Posted 07-31-2008 11:18 AM by dink

Comments

Links (7/31/2008) « Steve Pietrek - Everything SharePoint wrote Links (7/31/2008) &laquo; Steve Pietrek - Everything SharePoint
on 07-31-2008 7:52 PM

Pingback from  Links (7/31/2008) &laquo; Steve Pietrek - Everything SharePoint

Ben wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 07-31-2008 10:22 PM

Have you checked out the SPD blog concerning for filtering and formatting Date Values...

blogs.msdn.com/.../filtering-and-formatting-with-date-values.aspx

EndUserSharePoint.com: Dynamically Updating the “Today” Reference in a Calculated Column : End User SharePoint wrote EndUserSharePoint.com: Dynamically Updating the &#8220;Today&#8221; Reference in a Calculated Column : End User SharePoint
on 08-13-2008 4:01 PM

Pingback from  EndUserSharePoint.com: Dynamically Updating the &#8220;Today&#8221; Reference in a Calculated Column : End User SharePoint

Christophe wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 08-25-2008 7:39 AM

Here is a method that uses the Data View Web Part and JavaScript to include today's date in formulas:

pathtosharepoint.wordpress.com/.../a-countdown-for-tasks-lists

Calculated Column Dynamically Updated (When using [Today]) « SharePoint Knowledge Base wrote Calculated Column Dynamically Updated (When using [Today]) &laquo; SharePoint Knowledge Base
on 10-03-2008 12:38 PM

Pingback from  Calculated Column Dynamically Updated (When using [Today]) &laquo; SharePoint Knowledge Base

waqas sarwar wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 10-22-2008 3:09 PM

Hello Dink

Thanks for the nice post. I am trying to implement this code to perform in a little different scanerio.

What I am trying to do,

I have document library and in that library I create new calculated column which gets the value from the ID column and append it to my special words.

My column name is Test column and I put the following column

=”Win000”&[ID]&”P”    the outcome of this formula is Win000p but did not include the ID in it but when go to design mode and save it then it update the column with the required result e.g Win0001P.

I think your code will help me in this regard. I implement it but I was surprised to see that when I run the exe file instead of updating the new rows its wipe out the all rows of that column and show following result

Before running Exe File                            After Running Exe File

Win0001P Win000P

Win0002P Win000P

Win0003P Win000P

Win000P(This should update with            Win000P

latest id number but)

So please help me in this regards, tell me where I am doing wrong.

Thanks

Waqas, waqas105@gmail.com

Larry wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 10-31-2008 1:40 PM

If you don't have code access, then I found the best way around being unable to use [Today] in a calculation is to make a modified date that I could compare to [Today] in a list filter.  

For example, I wanted to track issues (in my issue list) that have been open for more than 60 days, but I couldn't calculate "days open" for my issue witout using [Today].  The hack didn't update automatically, so that was useless for me.  So I:

- Made a calculated field called [Deadline60], which equaled [Created}+60.  

- Made a list view which filters on (Deadline60 < Today) AND (Status <> Closed)

- Made a KPI that counts the items in that view.

The "birthdays this month" question that seems ubiquitous can't be solved quite so easily - even "Upcoming Birthdays" is tough because of the year issue.  Maybe a more creative calculation can get you there?

KPIs for the Masses: A Dashboard based upon a date-time field | End User SharePoint wrote KPIs for the Masses: A Dashboard based upon a date-time field | End User SharePoint
on 12-18-2008 12:59 AM

Pingback from  KPIs for the Masses: A Dashboard based upon a date-time field | End User SharePoint

Grouping in SharePoint Lists and Libraries, SharePoint Style | End User SharePoint wrote Grouping in SharePoint Lists and Libraries, SharePoint Style | End User SharePoint
on 01-12-2009 1:59 PM

Pingback from  Grouping in SharePoint Lists and Libraries, SharePoint Style | End User SharePoint

cris wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 02-21-2009 12:00 PM

The two solution  are usefull for those who has access to the Admin Server of the farm..

But for simple Admin web.. this will not helpfull...

cris wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 02-21-2009 1:19 PM

where do drop the file?

after created with visual studio

xris wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 02-24-2009 3:50 PM

yes

From option one

where do I drop the files? in my _catalog??!!

after created with visual studio

... wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 03-02-2009 11:51 PM

Gut!

... wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 03-06-2009 9:40 AM

Gute Arbeit hier! Gute Inhalte.

... wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 03-14-2009 1:46 PM

Sehr wertvolle Informationen! Empfehlen!

Marco wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 03-27-2009 9:19 AM

Hi Dink,

this information was very  very usefull and it works fine for me.

Is there a possibility, to only update items in a list, which fulfill a special criteria. For example only items containing the value "open" in a dropdown field ?

I have a list with many items and the more items are added, the longes the update procedure takes. I only need to update some of the items.

Greets and big thanks

Marco

Garth wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 03-29-2009 9:57 PM

I have tried to use option 2 and have easily modified web.config, then after editing my view that I am using I can't view the page as I get "An unexepcted error has occurred."

Any ideas of what I may have missed, I have copied the code exactly as written.

Garth wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 03-30-2009 9:03 PM

I worked it out. For those slow like me, you need to change <Your_Site_Url> to the web address of you SP site, eg. http://url

And you also need to change "Tasks" to the name of your list.

Gretchen wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 04-07-2009 1:04 PM

Dink,

I created 5 lists which use the Today calculation that I wanted dynamically updated.  2 of these lists reside on the same site.

I also had our IT guy use Method I in your instructions.  In step 4 we entered a site and list.  It ran at midnight per the instructions and everything was perfect.  When we went to add the other 4 lists and sites within the code, still only the first instance works.  We then tried separating them out and having 5 instances of step #4 but also, at midnight the program only seems to be reading the first one.  I am not technical (as you can probably tell), but I have so many applications where I need the date to dynamically update but if I can only get one list to update this doesn't help much.

Any thoughts>

Ricantun wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 04-13-2009 8:00 AM

Hi

I have the "Today" update problem but I dont have Visual Studio nor SPD, can you put for downloading the "UpdateSPList.exe" and "UpdateSPList.exe.config" files?

Thank you

Enrique wrote re: Dynamically Updating A SharePoint Calculated Column Containing A "Today" Reference
on 06-16-2009 10:50 AM

Hello,

Good tutorial however I could not get it to work on my server, every time I ran the code the calculated field will return 0 (meaning that there has been activity) with the following calculated formula =DATEDIF(Modified,MyToday,"d") for my DaysOfInactivity field (column).  The only way I could get it to work properly on my server was to code the following which I was able to find on www.novolocus.com/.../wss-practice-create-a-list-columns-and-view-programmatically

Hope this helps someone who is having a similar problem.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.SharePoint;

namespace AutoCalculate

{

   class Program

   {

       static void Main(string[] args)

       {

           //My SharePoint site

           SPSite web = new SPSite("svr-fp-sharep1/DAIHelpDesk");

           SPWeb site = web.OpenWeb();

           //Target list

           SPList targetList = site.Lists["DAIHelpDesk"];

           //Field that I want to update so the calculated field will work

           SPField updateField = targetList.Fields["DaysOfInactivity"];

           //This should simulate manually going into sharepoint and do an update on the field(column) DaysOfInactivity

           updateField.Update();

       }

   }

}

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Need SharePoint Training? Attend a SharePoint Bootcamp!
Posts (c) their respective authors. Everything else (c) 2009 SharePoint Experts, Inc.