About

As you may know, CorasWorks is continually working with our customers in the field to make them more productive and successful. Everyday we engage with these customers through professional services, training, and support. Through this, we have learned a lot about what makes a CorasWorks customer successful. We are very lucky to have this opportunity and appreciate the fact that our customers and partners are always pushing the envelope (and us) with our software.

This blog presents the lessons we have learned and the insight we have gained from our customers. The entries here will not be the realm of just one person, but instead are the voices of many on our team based on their unique experiences with customers and projects.

SharePoint Products Configuration Wizard May Fail After Installing SharePoint 2010 SP1 or Cumulative Updates

Symptoms

Installing SharePoint 2010 updates, Service Packs or a Cumulative Updates, are made up of two separate steps: Installing the SharePoint Update bits onto the servers (e.g. officeserver2010sp1-kb2460045-x64-fullfile-en-us.exe) and running the SharePoint Products Configuration Wizard (alternatively psconfig -cmd upgrade -inplace b2b –force) to configure (i.e. upgrade) the updated SharePoint components.

In some situations, the second step of the installation may result in a “Configuration Failed” error when there are components in the content database referencing “Missing Server Side Dependencies”.  In this scenario, the configuration (step 2) of the update actually completes 100%, with errors.  See sample “Configuration Failed” error below.

Cause

SharePoint 2010 (Server/Foundation) includes a built in SharePoint Health Analyzer, which can sometimes deem native SharePoint or 3rd party components in content databases to have “Missing Server Side Dependencies”.  When the SharePoint Products Configuration Wizard (alternatively psconfig -cmd upgrade -inplace b2b –force) is run after a SharePoint update, the same Health Analyzer is used to inform administrators that there are missing features or other components in the content database(s).  These missing pieces will prevent the components from being upgraded during the update configuration.  See sample errors from the upgrade logs below.

 

Upgrade Log:

Upgrade Errors Log:

In some cases, when the CorasWorks Suite has been installed into a SharePoint 2010 environment and then had solutions (i.e. WSPs) removed and/or list activations were created with version 10 or earlier of the CorasWorks Suite, “Missing Server Side Dependencies” found by the Health Analyzer can cause the SharePoint Products Configuration Wizard to return a “Configuration Failed” error.

Resolution

In this scenario, since CorasWorks components should not be updated by any SharePoint update, the “Configuration Failed” error is a false positive.

Although the “Configuration Failed” error is considered a false positive, there is a way to prevent the error from being encountered during the configuration of an update.  To prevent the error, the following steps must be followed PRIOR to running the SharePoint Products Configuration Wizard (alternatively psconfig -cmd upgrade -inplace b2b –force):

Ensure the SharePoint Farm does not have any CorasWorks “Missing Server Side Dependencies”

1. Open SharePoint 2010 Central Administration.

2. Go to the Review problems and solutions page of the SharePoint Health Analyzer (http://server:port/Lists/HealthReports/AllItems.aspx).

3. Under the Configuration Category, click on the “Missing Server Side Dependencies” list item.  If the category is not listed, then the issue described in this article is not applicable to the environment.

4. Once inside the “Missing Server Side Dependencies” page, look for entries referencing the CorasWorks Suite.

5. If any are found, follow the resolutions in the articles below to remove the “Missing Server Side Dependencies” entries.

6. Once the “Missing Server Side Dependencies” entries have been removed, the SharePoint Products Configuration Wizard (alternatively psconfig -cmd upgrade -inplace b2b –force) will conplete successfully.

Important: This behavior is new with SharePoint 2010 (Foundation/Server) and it affects all solutions including native Microsoft solutions and third party solutions.  However, the Resolutions described in this article are only intended for the specific scenarios affecting the CorasWorks Suite.

Please e-mail support@corasworks.net if you have any questions or issues.

Thanks,

Rodney

Missing server side dependencies in SharePoint Health Analyzer (SharePoint 2010) – Part II

Symptoms
In certain SharePoint 2010 (Server/Foundation) farms, the built in SharePoint Health Analyzer can log errors that indicate “Missing Server Side Dependencies” for missing feature(s) in the content database. Sample error message shown below.

Cause

When the CorasWorks Suite is installed into SharePoint, there are various solutions (WSP files) that get added to the SharePoint Solution Store and deployed to the servers in the farm.  These solutions provide a way to extend SharePoint via features, which can be activated selectively at the site collection basis.

If a feature that is part of the CorasWorks Suite (Basic or Advanced Components) has been activated in a site collection, this feature adds references to the solution that supports the feature in the content database.  If a solution required for an activated feature is removed from the environment, SharePoint will recognize that dependencies required for the feature to function as missing and will add an entry for the missing feature solution in the “Missing server side dependencies” section of the SharePoint Health Analyzer.

Resolution
In order to clear the “Missing Server Side Dependencies” errors from the SharePoint Health Analyzer, the solution(s) that is referenced in the “Missing server side dependencies” section of the SharePoint Health Analyzer must be reinstalled.  Provided below is a list of feature IDs for the CorasWorks Suite solutions.

Alternatively, the feature can also be forcefully removed from SharePoint using utilities such as the SharePoint Feature Administration and Clean Up Tool from CodePlex.  However, this is not recommended or supported by CorasWorks.

CorasWorks Feature IDs List:

Excel Format

Plain Text Format

Important: This behavior is new with SharePoint 2010 (Foundation/Server) and it affects all solutions including native Microsoft solutions and third party solutions.

Please e-mail support@corasworks.net if you have any questions or issues.

Thanks,

Rodney

Missing server side dependencies in SharePoint Health Analyzer (SharePoint 2010) – Part I

Symptoms

In certain SharePoint 2010 (Server/Foundation) farms, the built in SharePoint Health Analyzer can log errors that indicate “Missing Server Side Dependencies” for the CorasWorks.Workplace.Actions component within a content database. Sample error message shown below.

Cause

When a CorasWorks Suite list activation is created, a corresponding event receiver is also created, so that an action can be executed when an event meets certain conditions. At time the event receiver is created, a reference to the installed CorasWorks.Workplace.Actions DLL needs to be made in order for the event receiver to function correctly.

In versions of the CorasWorks Suite prior to version 11 (i.e. v10.x), any event receivers created permanently referenced the version of the CorasWorks.Workplace.Actions DLL that was on the servers at that time (i.e. Version=10.4.0.168, etc.). When the CorasWorks Suite is upgraded to a newer version, the version of CorasWorks.Workplace.Actions DLL is also upgraded and replaced. However, the event receivers maintain references to the previous version of the DLL.

Although both SharePoint and the CorasWorks Suite function normally, the SharePoint Health Analyzer flags the outdated DLL references in the event receivers as having “Missing Server Side Dependencies”. The reason they are considered to have missing server side dependencies is because the specific version of the DLL being referenced by the event receivers are no longer on the server.

Resolution

In order to clear the “Missing Server Side Dependencies” errors from the SharePoint Health Analyzer, the references to the outdated version of the CorasWorks.Workplace.Actions DLL in the event receivers must be upgraded to the latest version. To upgrade the event receivers, the following steps must be taken.

1. Download the “CWEventReceiverUpdate.zip” file to one of the SharePoint 2010 servers on the farm.

2. Extract the “CWEventReceiverUpdate.zip” to the file system.

3. Go inside the “CWEventReceiverUpdate” folder that was created after the extraction.

4. Using administrative privileges execute the “CWEventReceiverUpdate.bat” file. If necessary, right click on the .bat file and select “Run as administrator”.

Important: The user executing the batch file must have site collection privileges to all site collections that include event receivers that need to be upgraded.

5. Review the “Update.log” file to determine if any were upgraded.

This will not be an issue with versions of the CorasWorks Suite v11 or later.

Please e-mail support@corasworks.net if you have any questions or issues.

 

Thanks,

 

Rodney

Show Me How: Deploying the CorasWorks Client Controls program (MSI) via Group Policy

The following are instructions for deploying the CorasWorks Client Controls program (MSI) to computers in an Active Directory domain using a Group Policy. The components included in the CorasWorks Client Controls are the required client side components for the My Workplace for Outlook web part. The My Workplace for Outlook web part is part of the CorasWorks Workplace Suite version 9.

The instructions below were written against a Windows Server 2003 Active Directory Domain.

Step 1 – Create a Distribution Point

To assign a computer program, you must create a distribution point on the publishing server:

1. Log on to the server computer as an administrator.
2. Create a shared network folder where you will put the Microsoft Windows Installer package (.msi file) that you want to distribute.
3. Set permissions on the share to allow access to the distribution package.
4. Copy the “CorasWorks Client Controls Winter 2005.msi” to the distribution point (See image below).

Step 2 – Create a Group Policy Object

To create a Group Policy object (GPO) to use to distribute the software package:

1. Start the Active Directory Users and Computers snap-in. To do this, click Start, point to Administrative Tools, and then click Active Directory Users and Computers.
2. In the console tree, right-click your domain, and then click Properties.
3. Click the Group Policy tab, and then click New.
4. Type a name for this new policy (for example, CW Client Controls Install), and then press ENTER.
5. Click Properties, and then click the Security tab.
6. Click to clear the Apply Group Policy check box for the security groups that you want to prevent from having this policy applied.
7. Click to select the Apply Group Policy check box for the groups that you want this policy to apply to.
8. When you are finished, click OK.

Step 3 – Assign a Package

To assign a program to computers that are running Windows Server 2003, Windows 2000, Windows XP Professional, Windows Vista, and Windows 7 or to users who are logging on to one of these workstations:

1. Start the Active Directory Users and Computers snap-in. To do this, click Start, point to Administrative Tools, and then click Active Directory Users and Computers.

2. In the console tree, right-click your domain, and then click Properties.

3. Click the Group Policy tab, select the group policy object that you want, and then click Edit.

4. Under Computer Configuration, expand Software Settings.

5. Right-click Software installation, point to New, and then click Package.

6. In the Open dialog box, type the full Universal Naming Convention (UNC) path of the shared installer package that you want. For example, \\file server\share\CorasWorks Client Controls Winter 2005.msi.

Important: Do not use the Browse button to access the location. Make sure that you use the UNC path to the shared installer package.

7. Click Open.

8. Click Assigned, and then click OK. The package is listed in the right pane of the Group Policy window.

9. Close the Group Policy snap-in, click OK, and then quit the Active Directory Users and Computers snap-in.

10. When the client computer starts, the managed software package is automatically installed.

Step 4 – Adding Sites Hosting the My Workplace for Outlook Component to Internet Explorer’s Local Intranet Zone (Optional)

By default, any Internet Explorer add-ons generate a pop-up to install or accept an add-on to run on the browser. In most situations where users running the add-ons are administrators on the local machine this is not an issue. However, in highly secure environments where users don’t have administrative control of their systems, these pop-ups can pose a problem because the users do not have the privileges to either install or run an add-on. An administrator can overcome this limitation by adding the SharePoint site URLs running the My Workplace for Outlook web part to the Internet Explorer’s Local Intranet Zone via Group Policy:

1. Start the Active Directory Users and Computers snap-in. To do this, click Start, point to Administrative Tools, and then click Active Directory Users and Computers.

2. In the console tree, right-click your domain, and then click Properties.

3. Click the Group Policy tab, and then click New.

4. Select the CW Client Controls Install policy and click on the Edit button.

5. Under Computer Configuration, expand Administrative Templates.

6. Expand Windows Components.

7. Expand Internet Explorer.

8. Expand Internet Control Panel.

9. Select Security Page.

10. Double click on the Site to Zone Assignment List.

11. Select Enabled in the Site to Zone Assignment List Properties window.

12. Click on the Show button.

13. Click the Add button from the Show Contents window.

14. In the Add Item window enter the following values:

In the Enter the name of the item to be added field, enter the URLs running the My Workplace for Outlook web part.

In the Enter the value of the item to be added, enter the number 1.

15. Once all the required URLs have been added, click the OK button

16. Click the OK button.

17. Click the OK button.

18. Close the Group Policy Object Editor

19. Click the OK button.

20. When the client computer starts, the URLs added to the Local Intranet Zone via Group Policy will be added to the workstations’ browsers.

If you have any questions regarding these instructions please contact CorasWorks Support.

Sources: http://support.microsoft.com/kb/816102, http://www.makeuseof.com/tag/configure-trusted-sites-internet-explorer-group-policy, http://support.microsoft.com/kb/182569.

Common Alternate Access Mappings Issues

SharePoint is a very flexible platform and one of the ways it shows its flexibility is in its ability to have a web application’s content be accessible using various URLs, each of which could be configured to use different forms of authentication.  The way that SharePoint is able to host multiple URLs accessing the same content is with the use of something called an Alternate Access Mapping.  An Alternate Access Mapping (AAM) is a setting that allows an administrator to specify the URLs that are accessible to the SharePoint users as well as the URLs used internally by SharePoint during web requests.  In addition to these URL mappings, the AAMs settings also include something called Zones, which provide a way to configure different authentication mechanisms for accessing a web application.  The Zones included with the Alternate Access Mappings are Default, Intranet, Extranet, Internet, and Custom.  (This is an overly simplified version of the Alternate Access Mapping settings and I recommend reading more on the topic.  I’ve provided some useful links below to expedite your research.)

The proper configuration of Alternate Access Mapping settings in SharePoint (2003/2007/2010) are extreme important because CorasWorks software (all versions and products) can be affected by these settings.  This is true for any type of SharePoint deployment, but most importantly for environments using a Reverse Proxy configuration.  While working with clients we’ve identified some settings that tend to be problematic, due to either missing or erroneous configurations.  I will cover these in the next section.

Frequently Seen Alternate Access Mapping Settings Issues

Many organizations get a jump start on SharePoint by using many of the default settings that can be selected when configuring SharePoint.  This is ideal for proof of concept (test/dev) environments because a lot of planning isn’t required to get the environment up and running.  However user friendly this may be, the configuration settings aren’t always optimal for production environments.  Unfortunately, due to the nature of SharePoint and rapid changing business needs, many proof of concept environments become production and introduce many of the issues we see often.

Issue A – Using a Server Name in the Default Zone AAM URL

One of the things that the default configuration settings include is the server name as the main SharePoint web applications URL (i.e. http://server1) and identified as “SharePoint – 80” in IIS.  This setting also associates the server named (i.e. http://server1) URL with the Default Zone in the Alternate Access Mappings.  In most cases the URL with the server name isn’t acceptable and is replaced with something that is more descriptive of the SharePoint web application (i.e. http://intranet.company.net).

An issue often seen with the aforementioned configuration is with the Default Zone’s URL is removed (i.e. http://server1) and is replaced with the more descriptive URL (i.e. http://intranet.company.net).  Although this works for most things in SharePoint, there are often some portions of the web requests that continue to reference the original URL (i.e. http://server1), which may cause issues with the CorasWorks display wizard and aggregation rollups, among other things.  When these problems are encountered, the best way to resolve them is by adding back the original URL mapping (i.e. http://server1) that was found in the Default Zone AAM configuration.  Once the original URL mapping is back in the Default Zone, a second URL can be used to in one of the other Zones (e.g. Intranet, Extranet, Internet, and Custom) with the more descriptive name (i.e. http://intranet.company.net) to make SharePoint aware of the additional identity (i.e. combination of port, IP address, host header) for the web application.

Issue B – Non-Host Header Based Default Zone AAM URL

Another issue frequently seen with AAMs settings is when hardware load balancers are used with SharePoint and are configured to distribute host header (i.e. http://intranet.company.net) based web application traffic to the cluster nodes by using the servers’ IP addresses (i.e. http://10.1.1.X) instead of the host header based URL.  In such cases the AAM settings have been updated to replace the host header based URL with the IP address based URLs.  This URL replacement in the AAM may affect any of the Public Zones available in the Alternate Access Mappings and can affect the ability of accessing the CorasWorks display wizard and also prevent aggregation rollups.

In this scenario, the best way to ensure that the Alternate Access Mappings information is used properly by SharePoint is by designating the Default Zone AAM with the host header based URL (i.e. http://intranet.company.net) and if IP addresses are required for the load balancer to distribute traffic properly, then add the servers’ IP addresses (i.e. http://10.1.1.X) in any of the available AAM Zones (i.e. Intranet, Extranet, Internet, and Custom).  This setup is not required with most hardware load balancers, but it can be used as a work around if your server farm is smaller than 4 servers.  The reason 4 servers are mentioned is because the number of available Zones besides the Default Zone, which is used by the host header based URL, are 4 (i.e. Intranet, Extranet, Internet, and Custom).  Again, this is a work around and in some extreme cases a rebuild of a web application may be required.

Issue C – Misconfigured Reverse Proxy Settings (off-box SSL termination)

It is extremely important that SharePoint is configured according to the instructions provided in the following TechNet Article in order for CorasWorks software to function properly.  This includes the creation of the web application, configuration of the alternate access mappings, and creation of the firewall publishing policies for the web application.

The following article includes Reverse Proxy Publishing Instructions for Microsoft’s Internet Security & Acceleration Server (ISA).  Contact your firewall manufacturer for specifics on how to configure a Reverse Proxy publishing rule on non-ISA based Firewalls.  Reverse Proxy Publishing Instructions http://technet.microsoft.com/en-us/library/cc261814(office.12).aspx.

IMPORTANT:  When creating a Reverse Proxy Publishing Rule in ISA Server, ensure that the same type case is used for all the representations of the URLs.  For instance, if the Alternate Access Mappings in SharePoint uses http://intranet.company.net in the URL (for any Zone), the URL most use the same case in the Public Name (i.e. https://intranet.company.net) and not https://INTRANET.company.net.  If the type case does not match in settings of both SharePoint and the ISA Firewall, then the previously mentioned CorasWorks display wizard and aggregation rollups problems may be encountered.

Examples of Issues

Display Wizard Issue

Rollups Issue

Additional Resources:

Brief Summary of the Alternate Access Mapping settings (WSSV3/MOSS)

http://blogs.technet.com/b/tothesharepoint/archive/2008/08/26/3112518.aspx

Accessing Alternate Access Mapping Settings (WSSV3/MOSS)

http://technet.microsoft.com/en-us/library/cc263208(office.12).aspx

Accessing Alternate Access Mapping Settings (SharePoint Foundation 2010/SharePoint Server 2010)

http://technet.microsoft.com/en-us/library/cc261995.aspx#section4

Reverse Proxy Publishing Procedures – Step by Step Instructions (WSSV3/MOSS)

http://technet.microsoft.com/en-us/library/cc261814(office.12).aspx

If you have any questions please contact support@corasworks.net.

 

Interacting with Actions

With the release of the CorasWorks v11 Platform, we’ve introduced the ability to interact with CorasWorks Actions beyond the “Actions Dropdown” we’re all used to. Now, through defined methods, we can invoke any type of Action – with or without referencing an existing item – from anywhere.

Launching an Action is now as easy as loading a centralized Action page and passing in pre-defined parameters or even invoking a helper function to do it all for you. To best illustrate this, we’ve created a self-contained Site Template with a number of implementations in place for you to peel back and explore.

NOTE: The template does require you have CorasWorks v11 installed. You can download the template and post your comments/questions on the Forum here. To watch a video of this new capability in action (no pun intended), click here.

We look forward to hearing/seeing all the new & novel ways you extend your solutions with Actions anywhere!

Show Me How: Upgrading SharePoint 2007 based CorasWorks content to SharePoint 2010

Curious to see your SharePoint 2007 based CorasWorks applications in action running on SharePoint 2010? If so, you’re not the only one. Since SharePoint 2010 was released many customers have asked for guidance with upgrading their SharePoint 2007 based CorasWorks content to SharePoint 2010. This article was written as a quick and easy guide to help the curious minds with the upgrade and was written in a manner that simplifies the process.  I would recommend using these instructions for upgrading content in development and staging environments and ideally environments that can be scrapped and rebuilt.  As best practice, I always recommend using a more methodical approach when upgrading anything on a production environment.  A good framework to use when planning for a production farm upgrade is Microsoft’s Upgrade Cycle, which incorporates a multi-phased approach (Learn, Prepare, Test, Implement, and Validate) to allow IT Professionals and Developers thoroughly understand their environments before, during, and after an upgrade.  More information regarding the SharePoint 2010 upgrade process can be found here.

This document was written in the context of CorasWorks content and therefore instructions on the installation of SharePoint 2010 will be omitted as they are considered outside the scope.  The example included in this article uses two SharePoint deployments with SQL and SharePoint on separate servers and is applicable for both SharePoint Foundation 2010 and SharePoint Server 2010.

Upgrading SharePoint Content

In both SharePoint 2007 and SharePoint 2010 all of the web application content is stored in a web application’s content database(s). As in previous versions of SharePoint, in order to upgrade the content of a web application the content database(s) had to be upgraded. However, in the previous versions the process to upgrade a content database(s) was not the most user friendly.  In fact, the process was complex, cumbersome, and not to mention lengthy if multiple databases were being upgraded (upgrade was performed serially). In SharePoint 2010 the process has been simplified tremendously and improvements were made to support simultaneous upgrades of content databases (parallel).

The upgrade approach used in this upgrade scenario is the database attach upgrade, which takes a snapshot (via backup) of a web application’s content from a SharePoint 2007 farm and is migrated into a SharePoint 2010 environment.

I. SharePoint 2007 Requirements

In order for content to be successfully upgraded from SharePoint 2007 to SharePoint 2010 the SharePoint 2007 environment hosting the content must be on must be at least on Service Pack 2 (Version 12.0.0.6421).  More information on upgrading to SharePoint 2010 can be found here.

Validate that SharePoint meets the version minimum requirements.

1. Navigate to the web application which will be upgraded.

2. Click on “Site Actions” and select “Site Settings”.

3. Ensure that the version of SharePoint is 12.0.0.6421 or higher.

II. Determine the SharePoint 2007 content database name(s) to upgrade

In order to upgrade a web application to SharePoint 2010 we first have to figure out which content database the web application is using.  In this example I will be upgrading the content database belonging to a web application with the URL of http://sharepoint.cwtest.local.

The content databases associated with a web application can be viewed within Central Administration.  All the instructions in this section are to be performed on the SharePoint 2007 environment.

1. From the server hosting Central Administration open “Central Administration”.

2. Go to the “Application Management” tab.

3. Under the SharePoint Web Application Management section click on the “Content databases” link.

4. The web application with http://sharepoint.cwtest.local has one content database with the name of SharePoint_ContentDB.

III. Backing up SharePoint 2007 content

Once the version of SharePoint has been verified and the content database name has been determined, the next step is to backup the SharePoint 2007 content database(s) from SQL Server Management Studio.

In this example the content database being backed up is the SharePoint_ContentDB database.

1. From the backend SQL server hosting the SharePoint 2007 databases open “SQL Server Management Studio”.

2. Right click on the content database and select “Back Up”.

3. Once the “Back Up Database” window pops up, ensure that the “Database” source corresponds to the appropriate database and that the “Backup type” is listed as “Full”.

4. In the “Destination” field click on the “Add” button and select the destination location of the backup file.  I selected the default location as shown below.  Click the “OK” button once the destination has been selected.

IV. Restoring SharePoint 2007 Content

1. Once the backup has successfully completed and the backup file (.BAK file extension) has been created, move the backup file to the server hosting the SQL databases for the SharePoint 2010 farm.

2. From the backend SQL server hosting the SharePoint 2010 databases open “SQL Server Management Studio”.

3. Right click on “Databases” icon and select the “Restore Database” option.

4. When the “Restore Database” window opens, select “From Device” as the source and click on the ellipses (“…”) button to navigate to the location of the backup file.

5. Once the backup file and backup set have been selected, the database name can be specified.  In this case the backup was restored with the SharePoint2010_ContentDB database name.

6. After the backup has been successfully restored the SharePoint 2010 service accounts must be granted ownership permissions to the restored database.  In this example the Server Farm Account (CORASWORKS\sharepointsvc) and Application Pool Account (CORASWORKS\sharepointapp) were granted “Owner” permissions to the SharePoint2010_ContentDB database.  To do so expand the “Security” icon, locate the appropriate service account name and double click on it.

7. From within the “Login Properties” window click on the “User Mapping” option.

8. Locate the appropriate database (SharePoint2010_ContentDB), select it and check on the “db_owner” database role membership.  Click the “OK” button once the appropriate role has been selected.  Follow this process for all the appropriate service accounts.

V. Creating SharePoint 2010 Web Application

The procedure for attaching and upgrading the SharePoint 2007 content database to the SharePoint 2010 farm is a two step process.  The first step requires a new web application in the SharePoint 2010 farm to be built using the original web application URL (http://sharepoint.cwtest.local).  The second step takes the restored SharePoint 2007 content database and attaches to the SharePoint 2010 farm, which will also upgrade the database and associate it to the newly created web application.

1. To create a web application in the SharePoint 2010 farm open Central Administration and click on the “Application Management” link.

2. Under the “Web Applications” section click on the “Manage Web Applications” link.

3. From the “WebApplicationsList.aspx” page click on the “New” link.

4. In the “Create New Web Application” window populate the required fields.  The URL used when creating the web application should the same as the original URL, which in this case is http://sharepoint.cwtest.local.

5. Ensure that the application pool service account with ownership permissions to the restored content database is used when creating the web application pool.

6. In the “Database Name” field enter a descriptive name that will help to identify and locate the database quickly.  The database created in this step is temporary and will be replaced with the restored content database from the SharePoint 2007 environment.  The name used for the temporary database in this example is  Temporary_ContentDB.

7. Once all the appropriate fields have been filled out, click on the “OK” button.

8. On the “Application Created” window click “OK”.

VI. Removing temporary content database

1. In Central Administration click on the “Application Management” link.

2. From the “Application Management” page click on the “Manage content databases” link.

3. Once on the “Manage Content Databases” page click on the temporary content database link (i.e. Temporary_ContentDB).

4. If necessary, change the web application from the “Web Application” drop down (i.e. the URL displayed should be http://sharepoint.cwtest.local).

5. From the “Manage Content Database Settings” page, check the “Remove Content Database” check box and click on the “OK” button.

6. At this point you should be back on the “Manage Content Databases” page, which will no longer have the temporary content database associated with the web application.

 

VII. Attaching and upgrading SharePoint 2007 content database

In order to attach and upgrade the restored SharePoint 2007 database Power Shell (i.e. SharePoint 2010 Management Shell) or command prompt can be used.  For this example I will use command prompt, but more information on how to use the management shell can be found here.

1. On the server running SharePoint 2010 Central Administration open command prompt as an administrator.

2. Change directories to the 14 hive by typing “cd C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN” from the prompt.

3. To attach and upgrade the restored SharePoint 2007 content database type “stsadm –o addcontentdb –url http://sharepoint.cwtest.local –databasename SharePoint2010_ContentDB”.  Quick tip: This upgrade approach supports simultaneous content database upgrades.

4. Once the attach process is complete (100.00% should be shown), go back to the “Manage Content Databases” page and refresh it.  At this point, the newly attached content database should be associated with the web application.

5. If the source and destination SharePoint farms are on the same domain then the users from the original configuration should work without any issues.  If the source and destination farms are on different domains, then the Site Collection Administrator for the Site Collection(s) must be assigned.  This can be done from the “Change Site Collection Administrators” page in the “Site Collection” management, under the “Application Management” section in Central Administration.

VIII. Access upgraded content

Prior to accessing the upgraded content ensure the appropriate DNS entries have been configured for the sharepoint.cwtest.local host pointing to the SharePoint 2010 farm.

1. Once DNS resolution has been verified, open a browser window and navigate to http://sharepoint.cwtest.local web application.  The web application should be accessible and since the SharePoint 2010 environment doesn’t have the CorasWorks Suite installed, the pages will display some errors.

2. At this point, install the CorasWorks Suite according to the instructions provided with the installation files or the CorasWorks Community.

3. Once all appropriate CorasWorks components have been installed, the content should display without any errors.  It is important to note that interface will continue to display the SharePoint 2007 look and feel until a “Visual Upgrade” has been applied to the site(s).

4. To perform a “Visual Upgrade” click on the “Site Actions” link and select “Visual Upgrade”.

5. From the “Title, Description, and Icon” page select the appropriate “Visual Upgrade” option and click the “OK” button.  The recommended selection is the “Preview the updated user interface” option.

6. At this point the upgraded site’s look and feel can be upgraded permanently or rolled back to the SharePoint 2007 look and feel.  This setting can be set for a site, site collection, or content for the entire web application.

7. Any customized sites can also be upgraded to the SharePoint 2010 look and feel; however, it is recommended that any mission critical applications be thoroughly tested for upgrade incompatibilities.  Once the CorasWorks content is upgraded from SharePoint 2007 to SharePoint 2010, all SharePoint 2010 functionality will be available.  However, if you need the SharePoint 2010 look and feel for your CorasWorks applications contact CorasWorks for guidance on an upgrade path.

Conclusion

Hopefully these instructions provide some insight to the SharePoint 2010 upgrade process (at least one of the available approaches) and answer any questions you may have.  If you need additional information regarding the SharePoint 2010 upgrade or have any general questions please contact CorasWorks Support.

App Design Tip… Filter By Groups I Belong To (and more)

I’ve heard the request tons of times; can I not assign items to a Group but get a filtered view of all items assigned to Groups I’m a member of? It’s the [Me] filter on steroids – a way of seeing items that aren’t just assigned to you, but how about items assigned to Site Groups you’re a member of and AD Groups you’re a member of. Or maybe all items assigned to Site Groups, excluding items assigned to individuals. Or the inverse, all items assigned to individuals, excluding items assigned to Site Groups. Maybe you want all items assigned to members of a specific Site Group. Perhaps, on a site where permissions aren’t inherited, all items assigned to individuals that have permission to the site.

The fact is, there’s a collection of little known CAML tags that make all these scenarios very simple – and a big kudos and thank you to Mr. Cobeen, a customer of ours within a military command for getting me started on this trek to find all these.

First, the basics; we all know the typical types of filters we can create. You see them in your CorasWorks views and even native SharePoint List Views: this field equals that; this field is greater than ‘X’; field 1 is null; etc. Well, after seeing an example Mr. Cobeen shared and digging on MSDN, I found this article about what’s called the Membership element in CAML: http://msdn.microsoft.com/en-us/library/aa544234.aspx

This element allows you to set a Membership Type condition which is essentially telling the query to perform a specific type of filtering around groups. All you need to do is copy the examples below, substituting the name of the field within your List/Library that you want to query against. Where MSDN is light on content is around what each Type value does – so here you go :)

Membership Type Effect
SPWeb.AllUsers Will only return items assigned to individuals users; items assigned to a Group (Site Group or AD Group) will not be returned.Ex. <Where><Membership Type=”SPWeb.AllUsers”><FieldRef Name=”AssignedTo”/></Membership></Where>
SPGroup Use type equals “SPGroup”, along with an ID attribute for the ID of that Site Group, to return only items assigned to members of that specific Site Group. In this example, only items assigned to users that are members of the Site Group with ID 6 would be returned; to check a Group’s ID, go to that Group’s page under Users and Groups and look at the query string.
Ex. <Where><Membership Type=”SPGroup” ID=”6″><FieldRef Name=”AssignedTo”/></Membership></Where>
SPWeb.Groups Will only return items assigned to Site Groups (any Site Group); items assigned to individuals will not be returned.
Ex. <Where><Membership Type=”SPWeb.Groups”><FieldRef Name=”AssignedTo”/></Membership></Where>
SPWeb.Users Will only return items assigned to users who have permissions on the site. This only applies when the site where the list lives is NOT inheriting permissions; if that is the case, this query would only return items assigned to individuals who have permissions to said site.
Ex. <Where><Membership Type=”SPWeb.Users”><FieldRef Name=”AssignedTo”/></Membership></Where>
CurrentUserGroups(The Big One) This will return items that meet any of the following 3 criteria1. Items assigned directly to a SharePoint Site Group you’re a member of (i.e. Items assigned to the Owners site group, if you’re a member of it)

2. Items assigned directly to an AD Group you’re a member of (i.e. Items assigned to Domain\PowerUsers AD Group, if you’re a member of it)

3. Items assigned to a Site Group whose members include an AD Group you’re a member of (i.e. Items assigned to the Owners site group that you’re not explicitly a member of but that Domain\PowerUsers is)

Ex. <Where><Membership Type=”CurrentUserGroups”><FieldRef Name=”AssignedTo”/></Membership></Where>

There you have it; to apply these to any CorasWorks View, simply go to the Filter page within your Display Wizard and choose the radio button to define your CAML Manually – then paste in the appropriate CAML. And remember, if your field isn’t called “AssignedTo”, no problem, just substitute the correct column name.

One more quick tip; perhaps you want to use the Membership Type=CurrentUserGroups but with an OR filter to also catch any items assigned directly to you. Here you go!

<Where><Or>

<Membership Type=”CurrentUserGroups”><FieldRef Name=”AssignedTo”/></Membership>

<Eq><FieldRef Name=’AssignedTo’ /><Value Type=’User’>[Me]</Value></Eq>

</Or>

</Where>

 

SharePoint 2010 Browser Compatibility

Microsoft has made efforts to improve multiple browser support and developed SharePoint 2010 more standards friendly.  As such, the expected multi-browser functionality and support has reached levels not seen in previous versions of SharePoint.  Microsoft has classified browser functionality and support for various browsers into three categories, Level 1, Level 2, and Level 3 browsers.  The Level 1 compatible browsers support SharePoint 2010 fully and all functionality is available for use.  The Level 2 compatible browsers on the other hand provide the majority of the functionality with some exceptions.  As far as what these exceptions are, a detailed list of functionality can be found in the following linked TechNet articles: Plan browser support (SharePoint Foundation 2010) and Plan browser support (SharePoint Server 2010).  Finally, Level 3 browsers are the browsers not tested by the Microsoft product team.

In any case, below is the list of Level 1 and Level 2 browsers.  Hopefully the will come in handy when deciding what browser versions to support in your organization.

Level 1 Browsers (Supported)

Internet Explorer 7.x or higher (32bit on Windows platforms)

Firefox 3.x or higher (32bit on Windows platforms)

Level 2 Browsers (Supported with known limitations)

Internet Explorer 7.x or higher (64-bit on Windows platforms)

Firefox 3.x or higher (non-Windows platforms)

Safari 4.x or higher (non-Windows platforms)

As always, CorasWorks has made significant efforts and allocated large amounts of resources to ensure that our solutions provide the same level of browser support Microsoft provides for SharePoint.  Should you have any questions regarding browser compatibility, please post your questions in our Community Forums site or contact Support at support@corasworks.net.

Toolset Providers for Current and Prior Periods

On a recent engagement, I had a number of requirements to display data in a grid and/or chart that compared a current period from the same period one year ago.  The content was all coming from SharePoint lists.  As many of you know, the SharePoint Data Provider has some built in date filtering options.

These are from the Online Help for the SharePoint Data Provider:

•    [Today] – Today’s date

•    [CurrentWeekStart] – The first day in the current week

•    [CurrentWeekEnd] – The last day in the current week

•    [CurrentMonthStart] – The first day in the current month

•    [CurrentMonthEnd] – The last day in the current month

•    [CurrentYearStart] – The first day in the current year

•    [CurrentYearEnd] – The last day in the current year

•    [Quarter1Start] – The first day in the first quarter of the current year

•    [Quarter1End] – The last day in the first quarter of the current year

•    [Quarter2Start] – The first day in the second quarter of the current year

•    [Quarter2End] – The last day in the second quarter of the current year

•    [Quarter3Start] – The first day in the third quarter of the current year

•    [Quarter3End] – The last day in the third quarter of the current year

•    [Quarter4Start] – The first day in the fourth quarter of the current year

•    [Quarter4End] – The last day in the fourth quarter of the current year

•    [OneWeekAgoStart] – The first day of the previous week

•    [OneWeekAgoEnd] – The last day of the previous week

•    [TwoWeeksAgoStart] – The first day of the week before last

•    [TwoWeeksAgoEnd] – The last day of the week before last

•    [OneWeekFromNowStart] – The first day of next week

•    [OneWeekFromNowEnd] – The last day of next week

•    [TwoWeeksFromNowStart] – The first day of the week after next

•    [TwoWeeksFromNowEnd] – The last day of the week after next

•    [OneMonthAgoStart] – The first day of last month

•    [OneMonthAgoEnd] – The last day of last month

•    [OneMonthFromNowStart] – The first day of next month

•    [OneMonthFromNowEnd] – The last day of next month

 

My customer wanted the display to show several different periods based on today’s date.   They were Current/Prior Month, Current/Prior Quarter and Current/Prior Year.  And the Prior period was for same period last year.  For example, if the today’s date is March 11, 2010, then the following providers were needed:

Current/Prior Month = March 2010/March 2009

Current/Prior Quarter = Jan-Mar 2010/Jan-Mar 2009

Current/Prior Year = 2010/2009

So customer needed providers that would filter based on that criteria.  If my list item had a date of March 5, 2010, it would appear in the provider for Current Month, Current Quarter and Current Year.  If the list item had a date of February 12, 2010, it would appear in the provider for Current Quarter and Current Year but not current month because it’s March not February.  Well you get the idea.

So from our date filter options listed above, we only have several options for building our required providers.

•    [CurrentMonthStart] – The first day in the current month

•    [CurrentMonthEnd] – The last day in the current month

•    [CurrentYearStart] – The first day in the current year

•    [CurrentYearEnd] – The last day in the current year

Using the above filter options, we could produce a filter that gives us Current Month and Current Year based today’s date.  However, we have several other provider requirements to satisfy with no date filter options available to us.

So I decided to use a mashup to filter the SharePoint Data Provider to produce the filtered results that I needed.  I have included all three XSLT files below should you ever need to do something similar.

Current/Prior Month XSLT

<?xml version=”1.0″ encoding=”utf-8″ ?>

<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:ms=”urn:schemas-microsoft-com:xslt”>

<xsl:output method=”xml” omit-xml-declaration=”yes” />

<xsl:template match=”/”>

<NewDataSet>

<xsl:for-each select=”NewDataSet/Table1″>

<xsl:variable name=”currbeg”><xsl:call-template name=’FormatCurrentBeginDate’/></xsl:variable>

<xsl:variable name=”currend”><xsl:call-template name=’FormatCurrentEndDate’/></xsl:variable>

<xsl:variable name=”priorbeg”><xsl:call-template name=’FormatPriorBeginDate’/></xsl:variable>

<xsl:variable name=”priorend”><xsl:call-template name=’FormatPriorEndDate’/></xsl:variable>

<xsl:variable name=”od”>

<xsl:choose>

<xsl:when test=”Revised_x0020_Delivery != ””>

<xsl:call-template name=’FormatOrderDate’><xsl:with-param name=”orderdate” select=”Revised_x0020_Delivery”/></xsl:call-template>

</xsl:when>

<xsl:otherwise>

<xsl:call-template name=’FormatOrderDate’><xsl:with-param name=”orderdate” select=”Planned_x0020_Delivery”/></xsl:call-template>

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:if test=”$od &gt;= $currbeg and $od &lt;= $currend”>

<Table1>

<Site>

<xsl:value-of select=”Site”/>

</Site>

<OrderDate>

<xsl:value-of select=”$od”/>

</OrderDate>

<Current>

<xsl:value-of select=”Total_x0020_Billed”/>

</Current>

<Amount>

<xsl:value-of select=”Total_x0020_Billed”/>

</Amount>

<PivotColumn>Current</PivotColumn>

</Table1>

</xsl:if>

<xsl:if test=”$od &gt;= $priorbeg and $od &lt;= $priorend”>

<Table1>

<Site>

<xsl:value-of select=”Site”/>

</Site>

<OrderDate>

<xsl:value-of select=”$od”/>

</OrderDate>

<Prior>

<xsl:value-of select=”Total_x0020_Billed”/>

</Prior>

<Amount>

<xsl:value-of select=”Total_x0020_Billed”/>

</Amount>

<PivotColumn>Prior</PivotColumn>

</Table1>

</xsl:if>

</xsl:for-each>

<Table1>

<Site/>

<OrderDate/>

<Current>0</Current>

<Amount>0</Amount>

<PivotColumn>Current</PivotColumn>

</Table1>

<Table1>

<Site/>

<OrderDate/>

<Prior>0</Prior>

<Amount>0</Amount>

<PivotColumn>Prior</PivotColumn>

</Table1>

</NewDataSet>

</xsl:template>

<xsl:template name=”FormatCurrentBeginDate”>

<xsl:variable name=”extractedDate”>

<xsl:value-of select=”substring-before(‘[currentmonthstart]‘,’ ‘)” />

</xsl:variable>

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($extractedDate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year”/>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day”/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatCurrentEndDate”>

<xsl:variable name=”extractedDate”>

<xsl:value-of select=”substring-before(‘[currentmonthend]‘,’ ‘)” />

</xsl:variable>

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($extractedDate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year”/>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day”/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatPriorBeginDate”>

<xsl:variable name=”extractedDate”>

<xsl:value-of select=”substring-before(‘[currentmonthstart]‘,’ ‘)” />

</xsl:variable>

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($extractedDate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year – 1″/>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day”/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatPriorEndDate”>

<xsl:variable name=”extractedDate”>

<xsl:value-of select=”substring-before(‘[currentmonthend]‘,’ ‘)” />

</xsl:variable>

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($extractedDate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($extractedDate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year – 1″/>

<!– Subtracting 1 to get previous period. –>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day + 1″/>

<!– Adding 1 day to every month to account for a potential Leap Year.

Having an extra day for months other than February should not affect the result set –>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatOrderDate”>

<xsl:param name=”orderdate” />

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($orderdate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($orderdate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($orderdate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year”/>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day”/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

</xsl:stylesheet>

 

Current/Prior Quarter XSLT

 

<?xml version=”1.0″ encoding=”utf-8″ ?>

<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:ms=”urn:schemas-microsoft-com:xslt”>

<xsl:output method=”xml” omit-xml-declaration=”yes” />

<xsl:template match=”/”>

<NewDataSet>

<xsl:for-each select=”NewDataSet/Table1″>

<xsl:variable name=”currbeg”><xsl:call-template name=’FormatCurrentBeginDate’/></xsl:variable>

<xsl:variable name=”currend”><xsl:call-template name=’FormatCurrentEndDate’/></xsl:variable>

<xsl:variable name=”priorbeg”><xsl:call-template name=’FormatPriorBeginDate’/></xsl:variable>

<xsl:variable name=”priorend”><xsl:call-template name=’FormatPriorEndDate’/></xsl:variable>

<xsl:variable name=”od”>

<xsl:choose>

<xsl:when test=”Revised_x0020_Delivery != ””>

<xsl:call-template name=’FormatOrderDate’><xsl:with-param name=”orderdate” select=”Revised_x0020_Delivery”/></xsl:call-template>

</xsl:when>

<xsl:otherwise>

<xsl:call-template name=’FormatOrderDate’><xsl:with-param name=”orderdate” select=”Planned_x0020_Delivery”/></xsl:call-template>

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:if test=”$od &gt;= $currbeg and $od &lt;= $currend”>

<Table1>

<Site>

<xsl:value-of select=”Site”/>

</Site>

<OrderDate>

<xsl:value-of select=”$od”/>

</OrderDate>

<Current>

<xsl:value-of select=”Total_x0020_Billed”/>

</Current>

<Amount>

<xsl:value-of select=”Total_x0020_Billed”/>

</Amount>

<PivotColumn>Current</PivotColumn>

</Table1>

</xsl:if>

<xsl:if test=”$od &gt;= $priorbeg and $od &lt;= $priorend”>

<Table1>

<Site>

<xsl:value-of select=”Site”/>

</Site>

<OrderDate>

<xsl:value-of select=”$od”/>

</OrderDate>

<Prior>

<xsl:value-of select=”Total_x0020_Billed”/>

</Prior>

<Amount>

<xsl:value-of select=”Total_x0020_Billed”/>

</Amount>

<PivotColumn>Prior</PivotColumn>

</Table1>

</xsl:if>

</xsl:for-each>

<Table1>

<Site/>

<OrderDate/>

<Current>0</Current>

<Amount>0</Amount>

<PivotColumn>Current</PivotColumn>

</Table1>

<Table1>

<Site/>

<OrderDate/>

<Prior>0</Prior>

<Amount>0</Amount>

<PivotColumn>Prior</PivotColumn>

</Table1>

</NewDataSet>

</xsl:template>

<xsl:template name=”FormatCurrentBeginDate”>

<xsl:choose>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’1′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’2′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’3′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0101</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’4′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’5′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’6′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0401</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’7′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’8′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’9′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0701</xsl:text>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>1001</xsl:text>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatCurrentEndDate”>

<xsl:choose>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’1′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’2′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’3′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0331</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’4′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’5′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’6′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0630</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’7′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’8′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’9′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0930</xsl:text>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>1231</xsl:text>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatPriorBeginDate”>

<xsl:choose>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’1′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’2′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’3′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0101</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’4′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’5′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’6′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0401</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’7′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’8′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’9′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0701</xsl:text>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>1001</xsl:text>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatPriorEndDate”>

<xsl:choose>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’1′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’2′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’3′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0331</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’4′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’5′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’6′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0630</xsl:text>

</xsl:when>

<xsl:when test=”ms:format-date(‘[todayrfc]‘, ‘M’) = ’7′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’8′ or ms:format-date(‘[todayrfc]‘, ‘M’) = ’9′”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0930</xsl:text>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>1231</xsl:text>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

<xsl:template name=”FormatOrderDate”>

<xsl:param name=”orderdate” />

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($orderdate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($orderdate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($orderdate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year”/>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day”/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

</xsl:stylesheet>

 

 

 

Current/Prior Year XSLT

 

<?xml version=”1.0″ encoding=”utf-8″ ?>

<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:ms=”urn:schemas-microsoft-com:xslt”>

<xsl:output method=”xml” omit-xml-declaration=”yes” />

<xsl:template match=”/”>

<NewDataSet>

<xsl:for-each select=”NewDataSet/Table1″>

<xsl:variable name=”currbeg”><xsl:call-template name=’FormatCurrentBeginDate’/></xsl:variable>

<xsl:variable name=”currend”><xsl:call-template name=’FormatCurrentEndDate’/></xsl:variable>

<xsl:variable name=”priorbeg”><xsl:call-template name=’FormatPriorBeginDate’/></xsl:variable>

<xsl:variable name=”priorend”><xsl:call-template name=’FormatPriorEndDate’/></xsl:variable>

<xsl:variable name=”od”>

<xsl:choose>

<xsl:when test=”Revised_x0020_Delivery != ””>

<xsl:call-template name=’FormatOrderDate’><xsl:with-param name=”orderdate” select=”Revised_x0020_Delivery”/></xsl:call-template>

</xsl:when>

<xsl:otherwise>

<xsl:call-template name=’FormatOrderDate’><xsl:with-param name=”orderdate” select=”Planned_x0020_Delivery”/></xsl:call-template>

</xsl:otherwise>

</xsl:choose>

</xsl:variable>

<xsl:if test=”$od &gt;= $currbeg and $od &lt;= $currend”>

<Table1>

<Site>

<xsl:value-of select=”Site”/>

</Site>

<OrderDate>

<xsl:value-of select=”$od”/>

</OrderDate>

<Current>

<xsl:value-of select=”Total_x0020_Billed”/>

</Current>

<Amount>

<xsl:value-of select=”Total_x0020_Billed”/>

</Amount>

<PivotColumn>Current</PivotColumn>

</Table1>

</xsl:if>

<xsl:if test=”$od &gt;= $priorbeg and $od &lt;= $priorend”>

<Table1>

<Site>

<xsl:value-of select=”Site”/>

</Site>

<OrderDate>

<xsl:value-of select=”$od”/>

</OrderDate>

<Prior>

<xsl:value-of select=”Total_x0020_Billed”/>

</Prior>

<Amount>

<xsl:value-of select=”Total_x0020_Billed”/>

</Amount>

<PivotColumn>Prior</PivotColumn>

</Table1>

</xsl:if>

</xsl:for-each>

<Table1>

<Site/>

<OrderDate/>

<Current>0</Current>

<Amount>0</Amount>

<PivotColumn>Current</PivotColumn>

</Table1>

<Table1>

<Site/>

<OrderDate/>

<Prior>0</Prior>

<Amount>0</Amount>

<PivotColumn>Prior</PivotColumn>

</Table1>

</NewDataSet>

</xsl:template>

<xsl:template name=”FormatCurrentBeginDate”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>0101</xsl:text>

</xsl:template>

<xsl:template name=”FormatCurrentEndDate”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)”/>

<xsl:text>1231</xsl:text>

</xsl:template>

<xsl:template name=”FormatPriorBeginDate”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>0101</xsl:text>

</xsl:template>

<xsl:template name=”FormatPriorEndDate”>

<xsl:value-of select=”ms:format-date(‘[todayrfc]‘, ‘yyyy’)-1″/>

<xsl:text>1231</xsl:text>

</xsl:template>

<xsl:template name=”FormatOrderDate”>

<xsl:param name=”orderdate” />

<xsl:variable name=”month”>

<xsl:value-of select=”substring-before($orderdate,’/')” />

</xsl:variable>

<xsl:variable name=”day”>

<xsl:value-of select=”substring-before(substring-after($orderdate,’/'),’/')” />

</xsl:variable>

<xsl:variable name=”year”>

<xsl:value-of select=”substring-after(substring-after($orderdate,’/'),’/')” />

</xsl:variable>

<xsl:value-of select=”$year”/>

<xsl:choose>

<xsl:when test=”string-length($month) = 1″>0<xsl:value-of select=”$month”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$month”/>

</xsl:otherwise>

</xsl:choose>

<xsl:choose>

<xsl:when test=”string-length($day) = 1″>0<xsl:value-of select=”$day”/></xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$day”/>

</xsl:otherwise>

</xsl:choose>

</xsl:template>

</xsl:stylesheet>