Pages

Showing posts with label Workflow. Show all posts
Showing posts with label Workflow. Show all posts

Monday, February 3, 2014

Debugging Workflow Plugins in CRM Online

The Plugin Registration Tool has some important features to enable the effective troubleshooting of workflow plugins (and plugins in general). The following posts contain useful walkthroughs of these debugging features:

Debugging standard plugins:


Debugging workflow plugins:

But sometimes I find that adding good old-fashioned trace statements to the plugin code can also come in very handy.

The following illustrates this form of debugging for workflow plugins:

  1. Add the ITracingService reference
  2. Output trace information at various points
  3. Throw an exception to force the trace information to be output


The plugin will fail as you have forced an error by throwing an exception. And you can now go into the failed workflow and view the trace information that was outputted. 


Monday, January 27, 2014

Workflow FetchXml Query

Out of the box, workflow does a pretty good job of allowing you to specify test conditions to perform the appropriate branching logic. For example, say you wanted to determine whether a contact's parent account has a credit hold - well... configuration-wise requirements don't get much simpler than this.



Now let's add a wrinkle. Let's say you have an account hierarchy such that you wish to determine whether the contact's grandparent account (i.e. the parent account of the contact parent account) has a credit hold in order to make the necessary branching decision. This minor change in requirement of just pushing the test condition up one level cannot be achieved with the out of the box workflow tools. This is because the workflow Check Condition (and for that matter Wait Condition too) can only interrogate attributes of the current record and of parent records. Any relationship beyond that definition cannot be queried using the standard CRM workflow UI tools.

Fortunately we have a way of breaking out of this box using workflow plugins. I have created a plugin and published it on CodePlex that allows you to pass in a FetchXml query that will be evaluated. The plugin will return to the workflow whether the said FetchXml query returns results and can therefore be used to take necessary branching logic.

Let's use the example above to illustrate how this works.

First define a FetchXml query that will perform the evaluation that you are looking to do (you can use the Advanced Find "Download Fetch XML" to help you with constructing this query). In our case this would be as follows:

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">  <entity name="contact">    <attribute name="fullname" />    <attribute name="telephone1" />    <attribute name="contactid" />    <order attribute="fullname" descending="false" />    <filter type="and">      <condition attribute="contactid" operator="eq" value="{0}" />    </filter>    <link-entity name="account" from="accountid" to="accountid" alias="ae">      <link-entity name="account" from="accountid" to="parentaccountid" alias="af">        <filter type="and">          <condition attribute="creditonhold" operator="eq" value="1" />        </filter>      </link-entity>    </link-entity>  </entity></fetch>

NB: If you wish to pass in the current record's context as one of the filter criteria make sure that the following is included in FetchXml's condition clause (the attribute should be primary key of the entity that this workflow is running against):

<condition attribute="contactid" operator="eq" value="{0}" />

Now create a workflow and add the FetchXmlQuery step:



Pass in the FetchXml as a parameter to the FetchXmlQuery plugin:


And then define the rest of your branching logic based the results of this query.

If you have configured this correctly, you should be able to see the following results:


  • When the contact's grandparent account has a credit hold



  • When the contact's grandparent account does not have a credit hold


Wednesday, January 8, 2014

Workflow: Comparing Two Null Fields

You can use the Check or Wait Condition in workflow to compare one field to another field. However if both fields are null then the comparison evaluates to false. For example, say we compare "street 3" of the contact to "street 3 of the parent contact record - if both of these fields are not populated then the comparison evaluates to false rather than true. The following workflow snippet illustrates this phenomenon:



Typically that's what happens when comparing nulls from a database perspective because when you compare null to null you are essentially comparing an "unknown" value to another "unknown" value rather than "nothing" to "nothing" (nothing = nothing; whereas an unknown value cannot be said to equal another unknown value). CRM workflow behaves accordingly. I'm not sure that I would have designed it this way as most humans would look at two empty address fields and you would have a hard time convincing them that they in fact have different values which is what the workflow evaluation is essentially telling them. However this is how it has been designed, so null values need to be taken into account when designing such comparisons.

Out of the box  workflow does not have the equivalent to the SQL isnull conversion function which allows you to specify what null "means" and therefore perform a simple comparison (e.g. isnull(field1,'x') = isnull(field2,'x') will evaluate to true if both field1 and field2 are null since in that event they are both converted to "x" and of course x=x).

So one option is to create a workflow plugin that will perform this logic.

In the absence of such a plugin, you could use the following workflow logic to essentially implement this isnull comparison feature. It does tend to make the workflow a little longer... especially if there are multiple conditions to be evaluated as then you need to perform this comparison block for each field be compared. But it does tend to do the trick.



The basic comparison logic is that when the condition evaluates to true then "do nothing". If it evaluates to false, then perform the action associated with a false evaluation and stop processing. At the end of the comparisons, perform the action associated with a true evaluation as if the workflow got to this point, it must have passed all comparisons.


Tuesday, January 7, 2014

CRM Online Bulk Update Options

Having previously discussed the challenges with running bulk updates in CRM Online, I thought it would only be right to follow up with a post that provides some guidelines for doing so in the event that this is required. For simple updates you can obviously use the multi-edit feature and for slightly more complex requirements you can obviously use the "re-import from Excel" technique whereby you can export the data, making changes to the data and then import it back into CRM. And finally, if you have third party tools available such as Scribe Online or Scribe Insight you can obviously use those to cover pretty much any update requirement you have.

But what options do you have in the absence of such tools in cases where the update is beyond the complexity of the simple tools provided by CRM without having to resort to programming techniques to achieve the objective?

One alternative is to combine the power of workflow with the "re-import from Excel" technique.

CRM workflow is pretty powerful these days providing a lot of capability of manipulating CRM data using standard workflow actions and freely available codeplex solutions. So assuming your update requirement can be constructed via a workflow all you need to do is to "trigger" that workflow to run against all the records you want it to run against.

This can be achieved as follows:


  • Create a custom text attribute called something like "Temp Workflow Update" 
  • Create your workflow to trigger off the "field change" of this field
  • Construct an Advanced Find query that retrieves the subset of records you want to update and include the "Temp Workflow Update" field in the columns

  • Export the rows for re-import


  • Go into the Excel file and add some text value to your "Temp Workflow Update" field, copy down, save and re-import


  • This re-import should now trigger the workflow which will carry out the update that you configured it to perform.



Friday, December 27, 2013

CRM Manipulation Library Date Calculation Issue

Speaking of the CRM Manipulation Library solution, I encountered an issue with the date calculation logic. Specifically with regards to the somewhat misleadingly named "Add Days" function. Misleading in that if you look at the function, you will notice that in addition to the capability of adding days, you can also use this to add years, months, weeks, hours and minutes to a given date.


This is an important clarification as adding a month to date is not always going to be the same as adding 30 days to a date. Similarly for years (as in the case of a leap year). And obviously being able to specify the more granular hour and minute parameters is also helpful. We probably could have worked around not having the week parameter but it does make life a little easier by not having to perform additional calculations.

Anyway, the issue that I encountered is that ironically if you do not specify a non-zero "Days To Add" value and just supply one of the other parameters, the calculation will not work. That is, if we were to specify parameters in the screenshot above (where we're trying to add years to the date) it would not work.

Luckily there is a simple workaround solution. Below is the same function call except we trick it by subtracting a day value and then cancel it out by passing in the equivalent days in the week parameter.

If you needed to use the week parameter, then you could similarly pass in 24 hours and cancel it out by passing -1 to the day parameter.


Thursday, April 11, 2013

Searching Workflow Processes

I was recently upgrading a 4.0 environment to 2011 and in the process I needed to identify cases where workflow plugins were used to ensure that they were compatible with the upgraded version. The problem is how do you go about finding which workflows use a specific workflow plugin?

The answer is fairly straight-forward and is useful not only for upgrade scenarios but in other cases where you might be searching for a particular workflow that has a specific condition, action, or workflow plugin. That is, you can use this as a general purpose mechanism for finding workflows with a particular clause.

Let's start with identifying workflow plugins. For example, let's say that I want to find workflows that use the following workflow plugins:



The following query will find cases where the GetDate method is used. You could similarly search for the other methods by simply replacing the search clause.

select distinct  name from FilteredWorkflow
where statecodename = 'Published'
and activities like  '%DateUtilities%'
and activities like  '%GetDate%'

This returns with a result of "App Server Install". And sure enough if I open up that workflow in CRM, I see that the workflow plugin is called.



Alternatively let's say I was searching for another clause within the workflow e.g. 

select distinct  name from FilteredWorkflow
where statecodename = 'Published'
and activities like  '%region= Australia%'

Once again this also returns the "App Server Install" workflow and if I scroll a little further down I will see that also in the workflow:



By now you should be getting the idea. But interestingly if you tried the same search in a CRM 2011 environment you will not get any results returned. To make it work in 2011, you will need to tweak the queries very slightly replacing the "Activities" column with the "Xaml" column. The following will now work in your CRM 2011 environment:

select distinct  name from FilteredWorkflow
where statecodename = 'Published'
and Xaml like  '%DateUtilities%'
and Xaml like  '%GetDate%'

select distinct  name from FilteredWorkflow
where statecodename = 'Published'
and Xaml like  '%region= Australia%'

Tuesday, March 27, 2012

Views and Filters Toolkit

This codeplex project provides some very useful tools for manipulating views in MSCRM. Documentation of the various scenarios that this tool can handle is available in the code plex page and there is also ample documentation and use cases in the creator's blog.

For example, this can come in handy if you wish to push out and maintain a set of views to user groups. That is, similar to system views but rather than publishing organization-wide you can use this tool to push it out to a select group of users, department, business unit etc. Of course you could also achieve this by sharing a personal view with a list of users or teams - this therefore provides another option for achieving a similar objective. The main difference would be that although sharing would essentially share one view with multiple users such that if any of those users changed the view definition it would update the definition for everyone, whereas the tool would create an individual copy for each. There might be reasons for using both approaches although sharing would probably be the better approach most of the time.

One of the most useful features is the ability to centrally control the Outlook Filters. I say this with a bit of a caveat which will be explained at the end of this post (before going through the configuration steps you may want to review that caveat). By default Outlook Filters are configured individually on the user's desktop. So if you need to modify the default Outlook or Offline filter, you will need to modify the filter on each computer individually. This has long been a pet peeve of mine.

With this toolkit, you can define locally the Outlook download rule and deploy it globally (or targeted to users, teams etc.). The basic deployment scenario is as follows:

  1. Define your personal view
  2. Create a workflow that looks something like the screenshot below (refer to the detailed instructions for specific settings, although the only information that you'll need to change to make this work will be the values for Personal and System View Name to match the names you have used)
  3. Manually run this workflow on the users to whom you wish to copy the view



Once you have done so, you will now find the view that you defined copy to the "System Filters" tab in the user's Outlook Filters (and/or Offline Filters depending on your deployment scenario).



Works like a charm, doesn't it? Well almost... and here comes the aforementioned caveat. There is a fatal flaw based on my experience that I'm currently working with Microsoft support to fix.

The issue seems to be that while you can use the system view, the default "My Outlook Contacts" view is still required. To quote from Microsoft support:

As I have found in other instances, when the My Outlook Contacts filter is disabled or deleted, it will cause contacts to lose their GUIDs and will also break the crmLinkState. Therefore, in order to guarantee that contact sync properly between CRM and Outlook, the My Outlook Contacts  filter must be present and enabled.

Which for all intents and purposes negates the efficiences gained from using the System Filter approach - at least as far as I can tell. If anyone has a different perspective on this and has found that it does work in their environment I'd love to hear about it.

Update: This issue seems to be confirmed by this post and was resolved with UR5.

So what's the point of blogging about a feature that essentially doesn't work?

  1. It would appear based on the referenced post that this feature can be leveraged and this post serves to point out the issues encountered that might perhaps give a heads up to others who might be looking to configure this option and/or troubleshooting Outlook sync issues.
  2. I have to believe that this is something that will be plugged in the near future and I'm tracking it closely (and giving the support folks a little bit of a hard time) in order to facilitate resolution and therefore wanted to document while it's still relatively fresh in my head. And once fixed this post can serve as a reference to a working function.

One last thing to mention is that it would also be nice to be able to globally deactivate the default "My Outlook Contacts" as even with a working solution there is still a manual step to go into the client and disable the rule so it doesn't interfere with the deployed system rule. Perhaps that can be done using the toolkit - I haven't looked into it. Will try to do so once this issue is (hopefully) resolved.

Thursday, January 12, 2012

CRM 2011: Distribute Workflow

A few months ago I extolled the virtues of the distribute workflow in CRM 4.0 and wondered when it might become available for CRM 2011. Well the good news is that I recently discovered that this has now become available for CRM 2011 and can be downloaded from codeplex.

To install into your environment, all you need to do is to import the managed solution from the codeplex downloads page into your environment and once you have done so it will start showing up in the Add Step menu of the Workflow and Dialog process editor.



The codeplex site also contains pretty good documentation for configuring this option. It walks through a use case scenario for setting all cases for a particular customer to high.

There are many other scenarios where this workflow plugin can come in handy. Previously you might have gone about solving a requirement such as that presented by the use case by developing a custom plugin solution. With the distribute workflow it can be done via configuration and it is flexible in that you can specify under which specific conditions you want it to run by employing the use of some simple check conditions in the body of the workflow.

I'll provide another use case example that can further sharpen this point. Let's say you wish to close all open Campaign Responses automatically once the parent Campaign is completed. The distribute workflow can easily be used to accomplish this via simple configuration.

First design a simple manual workflow against the Campaign Response that:
  1. Evaluates whether the Campaign Response is open
  2. Changes the status of the Campaign Response to Closed



Then design another simple workflow against the parent Campaign that is triggered when the status is changed that does the following:

  1. Evaulates whether the Status Reason has changed to Completed
  2. Executes the Distribute Workflow which will call the workflow above for each child Campaign Response


And that is all there is to do.

Thursday, December 8, 2011

CRM 2011: Cannot unregister workflow PlugIn

In a previous post I covered an issue I faced with regards to being unable to unregister a regular plugin. I subsequently had some additional difficulty in unregistering some other plugins that were also carried over from the upgraded 4.0 installation.

In this case, the plugins turned out to be workflow plugins. That is, plugins that are used to extend the workflow (or Process in CRM 2011 speak) functionality.

The error message that was shown contained some text that looked like this:
>Crm Exception: Message: The PluginType(a222ddda-c78e-45c8-91f9-fa06359ac29d) component cannot be deleted because it is referenced by 1 other components. For a list of referenced components, use the RetrieveDependenciesForDeleteRequest., ErrorCode: -2147160033
[2011-12-06 12:03:51.118] Process: w3wp |Organization:9dd6ac5e-4be6-46f9-af58-7caed1001d66 |Thread:   31 |Category: Platform |User: 6b51be4f-7308-dc11-9e28-00188be6f91e |Level: Info | MiniDump.CreateDumpInternal
The key phrase of course being the "reference" issue which I have highlighted.

The only dependencies that I could think of for a workflow plugin are in fact the Process definitions and Process instances. 

I first started out by cancelling all Processes that were in a "Wait" state using Advanced Find as they could be referencing the said plugins.


However after this step, the plugin could still not be unregistered. So my next step was to disable the active Process definitions. 

That still did not bring along the desired results. Only once the calls to the plugin were removed from the Process definitions was I able to finally unregister the plugin.

Although it would be nicer if a better error message were issued highlighting the specific dependency issues (in plain English preferably), I cannot complain too much about the fact that Microsoft is in fact enforcing this dependency logic. Although it took a while to go through the above steps, it is still preferable to having to deal with the fallout of broken Process definitions and instances down the line. And of course being in an upgrade environment, this also helps ensure that certain plugins may require tweaking as part of the upgrade process. 

The only remaining step is of course to note all the above steps as far as cut over planning is concerned.

Monday, June 20, 2011

Infinite Loop Detection

This may be another candidate for the "if I had a penny..." series. It's not a new item but I've come across it enough times that I thought I'd bring attention to it.

Microsoft implemented an "infinite loop detection" mechanism within the workflow process. For example, it's possible for you to design "Workflow 1" that calls "Workflow 2" and then "Workflow 2" calls "Workflow 1" again, such that the workflow - once initiated will theoretically never end. And if these workflows are designed to call each other within moments of being initiated, things could potentially spiral out of control. And it is presumably for this scenario that Microsoft implemented it's "Infinite Loop Detection" mechanism.

You will have encountered this error when you open up a failed workflow and find the "workflow job was canceled because the workflow that started it included an infinite loop" message.


According to literature I've read on this topic, this error only occurs when  "a workflow calls itself (on the same entity) more than 7 times in an hour, the 8th instance will fail with the error..."

While in principle this may be a good mechanism, there are times when it gets in the way of good design. In fact, it can be argued that Microsoft puts such mechanisms into place as the lowest common denominator. Meaning that as Microsoft CRM is essentially a product that is designed for the masses and therefore there is no guarantee that those who "configure" CRM will be responsible enough to make wise decisions. In fact, CRM greatest strength could also - in the wrong hands - be its greatest weakness. That is, the application is so easy to customize/configure that you certainly do not have to be highly trained or technically qualified consultant in order to configure the system. But in the inimitable words of Spiderman: "with great power comes great responsibility". And therein lies the risk because when it comes to system design it is the THINKING - both short and long term - that is paramount. And therefore beyond the capability of being able to perform configuration/customizations on the system it is crucial to know when to add a new attributes, vs. entity, vs. relationship etc. etc. This topic clearly requires further development - perhaps for another time - but I digress, time to reel it in...

The point is that Microsoft - who knows that the product will equally be at the mercy of both the talented and not so talented (when it comes to technology) and that it's impossible to control who will have the keys to the kingdom at any given moment - has put in controls to protect the people from themselves. And this is but one example (another much better example is Microsoft's strict policy of not allowing direct updates to the CRM database - definitely a topic for another time).

Back to the issue at hand - it is perfectly good design to have multiple workflows calling each other. In fact, it could even be a recommended due to the modularity of such a design approach. But yet, if you do so you may hit up against this issue even though your human decision making skills are better than that of a computer in terms of detecting infinite loops - at least in this case.

And the "penny moment" here is - why didn't Microsoft recognize this might happen and give the end user the ability to override the behavior either through a global setting or through a specific workflow setting? Maybe this has been implemented in a different way in CRM 2011 - I haven't had a chance to check. Anyone?

In this case, the absence of such a setting is not that critical as I think the likelihood is that encountering this error is likely to be the result of testing rather than something that would occur in the real world. Because in the real world it is probably unlikely that you'd want to process more than 7 workflow steps in an hour. At least in theory, but even encountering this error in a test environment can be a pain.

Although there apparently is no setting to override this behavior, there is an ability to increase the threshold from 8 as described in this article. I am not sure if there is an upper limit - I remember at one point trying to increase it but still being dogged by the issue at an upper limit. If there's no upper limit, then indeed setting this threshold to a very high number would give a way to override this setting in which case I don't get my penny...

Tuesday, June 14, 2011

Auto assign via URL

We were faced with the challenge of being able to auto assign a record as soon as a user clicks on an email containing a link to the record:



I am sure that there is more than one way to accomplish this but the challenge was to differentiate between a user opening the record using the URL from the email versus opening the ticket from standard UI navigation (in which case we would want to suppress the auto-assign functionality).

The best way to achieve this seemed to be by adding a custom URL parameter that we could then manipulate via jscript to perform the necessary processing. However by default if you try and add custom parameters, the form will error out when you try and load.

Luckily, I discovered a blog entry which explained how to go about enabling the feature in the application. Believe it or not, you have to add a registry setting in order to allow this. I am not sure why there would be reason to suppress this in the first place but then again - if I had penny for every time I've wondered why certain features were designed in certain ways (MSCRM and beyond)...

Once this setting was in place, I could then add a URL via workflow containing the custom parameter:


And bob's your uncle! Well almost - of course you need to design the jscript on the form to retrieve the URL parameter (use the code snippet from the referenced blog) and perform the necessary logic to apply the update.

Wednesday, June 1, 2011

The infamous No Attribute error

You have no doubt come across this error. While working on some enhancement you might be working in a CRM Form and receive the following upon saving:


Or you might notice that a workflow has failed and when you open it up, you’ll similarly see:


How would you troubleshoot something like this? This may vary depending on the circumstance but here are a suggested set of steps. Let’s assume the No Attribute error was received in a workflow process as shown in the second screenshot above.



  • Go into the form and attempt to update the same field that the workflow is trying to update. Chances are that you’ll get the No Attribute error as shown in the first screenshot above.
  • Assuming you received this error while saving on the form, use the CRM Diag tool to trace the error:
    • Open up the CRM Diag Tool
    • Click Enable on the tracing just before reproducing the error
    • Reproduce the error
    • Turn off tracing
    • Find the trace files under the Microsoft Dynamics CRM\Trace folder and open up
  • In the trace file search terms like “Error Report:”, “Error Message:” – this should bring you to the part dealing with the error that occurred
  • Doing the above you may come up with something like this:


>MSCRM Error Report:--------------------------------------------------------------------------------------------------------Error: 'Incident' entity doesn't contain attribute with Name = 'ci_deptsystemuserid'.


  • The above identifies the offending attribute therefore search through your plugins and associated images to see if this field is referenced and remove
  • For example, in our case, the attribute is referenced via a custom audit plugin that we developed (in CRM 4.0 prior to the advent of the out of the box version of CRM 2011) that was auditing the field in question:


  • Then again, if the attribute wasn’t deleted, we wouldn’t have hit this issue in the first place. However I have already espoused the virtues of keeping the system nice and clean in a former post and therefore I think it’s well worth the effort.

Wednesday, May 18, 2011

Distribute Workflow for CRM 2011

In CRM 4.0, a wonderful little free workflow plugin was introduced that allowed workflows to be distributed. This can be downloaded from codeplex. The idea behind this workflow plugin is simple and effective. For example, say after completing a campaign, I wanted to generate a follow up activity on each opportunity generated from the campaign, I could create a single workflow against the parent campaign monitoring the campaign status and as soon it was completed, I could generate workflows to be kicked off for each of the child opportunities. So one workflow could spawn sub-workflows for all it's children. Useful in many different scenarios.

The functionality described above was not out of the box in 4.0 and I don't believe it is out of the box in CRM 2011 either (please enlighten me if I'm wrong as I haven't researched this to the Nth degree). So why am I mentioning this?

Well in light of my previous blog entry which discussed limitations with CRM 2011 Online - one of the limitations was that workflow plugins are not supported... And guess what - the utility mentioned above is in fact a workflow plugin which means that if you've deployed this feature in your on premise installation, you may have difficulty replicating this functionality if you decide to move to CRM 2011. So either you will need to dispense with the functionality or come up with another creative way for handling the requirement. Of course, upgrading to CRM 2011 on premise does not present the same challenge, since workflow plugins can be added in that case.

If anyone is aware of a way of executing the workflow distribution logic in CRM 2011 Online in a simple and elegant manner as the aforementioned plugin enabled - your input would be appreciated.

MSCRM 2011 - Going into the Cloud Considerations

In CRM 4.0 there were some major limitations if you decided to go into the cloud with CRM Online (vs. On Premise) that required careful consideration. A good detailed comparison can be viewed here.

However, from a practical point of view, the following were the most significant high level limitations:

  • Reporting - custom reports are limited to out of the box views, the report wizard or you could create with significantly greater difficulty some aspx type reporting using FetchXML
  • Plugins - no ability to add custom extensions to the application

The good news is that CRM 2011 Online has overcome these limitations to a large extent. However not completely:

  • Reporting - custom reports can now be created using a FetchXML extension to BIDS. You can find a good introduction of this capability here. While this does provide a good workaround solution it should be mentioned that you are still limited to the FetchXML framework. That is you can only retrieve data from CRM in ways that FetchXML will allow you to. FetchXML was limited to relatively simple queries in 4.0 and the good news is that it's been expanded to be able to include aggregate functions such as GROUP BY which are important when it comes to reporting. However FetchXML is still bound to be more restrictive than it's SQL counterpart - the latter can be manipulated in virtually limitless ways, if not by a SQL statement, then by employing the use of cursors, dynamic SQL etc. to achieve the desired result set. 
  • Workflow plugins - while standard "trigger" plugins can now be added to the CRM 2011 Online deployment, you are still unable to deploy workflow plugins. A "trigger" plugin is executed synchronously or asynchronously as a direct result of an event (update, insert, delete) that is made to an entity (for example, good for validation, calculation etc. logic). A workflow plugin is executed by the workflow engine which is useful if an advanced function needs to be called as a result of a more protracted workflow that gets generated due to some condition in the environment. Although through some fancy footwork it should be possible to leverage the "trigger" plugin to work around this limitation (for example, creating a custom entity that gets updated by the workflow and "trigger" plugins are designed against inserts to the custom entity - just theorizing)

In summary, while the workflow plugin limitation is not optimal I do believe it can be worked around. However if your organization has complex reporting (read: above average) or if you are upgrading an existing installation where reports have employed dynamic/advanced reporting techniques or need to join to data that sits outside of the CRM database, then you may want to give this further consideration before moving into the cloud.

One final point, if you are upgrading your existing on premise installation and you have many custom reports that have been written, you'll need to consider the effort that it will take converting those to the FetchXML cloud model equivalent.

Tuesday, May 17, 2011

System attribute cannot be delete because it used in one or more workflows

This follows my previous blog entry on Removing Artifacts.


MSCRM does a pretty good job so that you don't get into trouble when removing attributes from the system. Before you will be allowed to do so, it will verify that the attribute is not being used in any published form, view, or workflow in the system. For forms and views, the error message explains quite clearly which form/view needs to be updated before the attribute can be removed.


However when it comes to workflows, you just get the following generic error:



If you have hundreds of workflows it can be quite a daunting task to locate the offending one. So how can the workflows be identified? Query the database. You can use the following query to get you going:


select distinct name fromworkflow
where rules like '%custom_attributename%'
and deletionstatecode = 0
and statecode = 1
and primaryentity = 112



One thing to be cautious of is that there may also be active workflow instances that reference the field that you are removing and CRM does not (in my experience) prevent the attribute from being removed on account of an active worklow instance. Only published workflow definitions that reference a particular attribute will be prevent that attribute from being deleted. This means that you should take into consideration the impact that deleting an attribute will have on active workflows that might be running. If you do so and there is an active workflow instance, you can expect to see something like the following appear in your workflow:

A similar "invalid condition" will be shown in any unpublished/draft workflow definitions that reference the deleted field.

To help prevent such a scenario from occurring, you can also query the database to discover workflow instances of the published workflow definition that you identified in the above query:


select statuscode from AsyncOperation
where Name like 'name of workflow'
and statuscode in (0,10,20,21)

As perhaps a better alternative, you can also use the CRM Advanced Find to query these records and take the appropriate action: