I decided to develop custom activity which will give possibility to format those output.
This activity has two inputs - datetime value to format (CrmDateTime property) and format (string property) and one output - formatted datetime (string). Code of custom action:
using System;
using System.Text;
using System.Collections.Generic;
using System.Workflow.Activities;
using Microsoft.Crm.Workflow;
using System.Workflow.ComponentModel;
using Microsoft.Crm.Sdk;
namespace DateTimeFormatting
{
[CrmWorkflowActivity("Formats date time with required format", "Formatting Routines")]
public class FormatDateTime : SequenceActivity
{
protected override System.Workflow.ComponentModel.ActivityExecutionStatus Execute(System.Workflow.ComponentModel.ActivityExecutionContext executionContext)
{
string result = string.Empty;
if (!string.IsNullOrEmpty(DateFormat) && datetime != null)
{
result = DateTime.Parse(datetime.Value).ToString(DateFormat);
}
Result = result;
return ActivityExecutionStatus.Closed;
}
public static DependencyProperty DateFormatProperty = DependencyProperty.Register("DateFormat", typeof(string), typeof(FormatDateTime));
[CrmInput("Format of DateTime")]
public string DateFormat
{
get
{
return (string)base.GetValue(DateFormatProperty);
}
set
{
base.SetValue(DateFormatProperty, value);
}
}
public static DependencyProperty datetimeProperty = DependencyProperty.Register("datetime", typeof(CrmDateTime), typeof(FormatDateTime));
[CrmInput("DateTime to format")]
public CrmDateTime datetime
{
get
{
return (CrmDateTime)base.GetValue(datetimeProperty);
}
set
{
base.SetValue(datetimeProperty, value);
}
}
public static DependencyProperty ResultProperty = DependencyProperty.Register("Result", typeof(string), typeof(FormatDateTime));
[CrmOutput("Formatted DateTime")]
public string Result
{
get
{
return (string)base.GetValue(ResultProperty);
}
set
{
base.SetValue(ResultProperty, value);
}
}
}
}
Following screenshots show how to use this action:
1. Insert this action before using the result of formatting:
2. Click "Set Properties" button to insert datetime and format:
3. Fill "Format of DateTime" and "DateTime to Format" fields:
4. Add some workflow step formatted datetime to be used (for example sending email):
Save step and save and publish workflow. Result of work of this workflow:
Sourcecode:
Works Great! Thanks a lot Andriy! You've made my users very happy!
ReplyDeleteAndriy - can you tell me where your C# code goes or how you have compiled it? The solution is great and I'd like to implement it but not sure about the custom code.
ReplyDeleteHello, Brenden. Actually C# is placed on a blog as a sample what and how can be done in CRM. You can just download compiled version of assembly at the end of post and register it on your system using PluginRegistration tool.
ReplyDeleteHi,
ReplyDeleteI would like to do something similar. I am trying to remove the time from a datetime attribute in an email created by a workflow. Even though the attribute is set to "Date Only", in my email created by the workflow, the time is displayed after the date.
Hello, Deene.
ReplyDeleteIn this case you should build code proposed in the article and install the library using pluginregistrator. This will give you additional possibility in workflows - to format datetime fields as you want.
If you have questions you can drop me an email. You can find my address in my profile.
Hi Andriy
ReplyDeleteThis is just what I needed! Greate work!
But I'm not sure how to register this with CRM Plugin Registration Tool 2.2. I'm connected to CRM server and trying to follow the tools guide on how to register plugin. But what to fill in??
Best regards,
Henrik
PS.
ReplyDeleteI forgot to ask: Do you have a guide on how to register this plugin or plugin in general? And by the way, don't seem to find compiled assembly here in blog?
Hello. Here is text description how to register custom workflow activities - http://msdn.microsoft.com/en-us/library/ee704600.aspx
ReplyDeleteIf you will have other question - don't hesitate to ask.
Hi there,
ReplyDeleteI'm getting the following error on registration
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Workflow.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
at System.Reflection.Assembly._GetExportedTypes()
at System.Reflection.Assembly.GetExportedTypes()
at PluginRegistrationTool.AssemblyReader.RetrievePluginsFromAssembly(String path)
at PluginRegistrationTool.AssemblyReader.RetrievePluginsFromAssembly(String path)
at PluginRegistrationTool.RegistrationHelper.RetrievePluginsFromAssembly(String pathToAssembly)
at PluginRegistrationTool.PluginRegistrationForm.btnLoadAssembly_Click(Object sender, EventArgs e)
Any idea whats wrong?
Hello Jack,
ReplyDeleteI assume that you have problems with .Net framework. What versions do you have installed?
Hi Andriy,
ReplyDeleteIt was a .net framework issue, i got the plugin registered now. What inputs can the "Format of datetime" condition in the workflow take? dd/mm didnt seem to workf for me!
Hello Jack,
ReplyDeleteYou can see sample here - http://1.bp.blogspot.com/_73OmG38HHME/TBlT30eujxI/AAAAAAAAAmg/ZCibtud_J-Y/s1600/DateFormat3.JPG
One quick note - mm - will return minutes. To set months you should use MM instead of mm.
Is there a way to return the french when I use the MMMM (Month name) or ?
ReplyDeleteHello Richard,
ReplyDeleteI believe it is possible but you will have to redevelop your code and use other DateTime.ToString method which retrieves format and IFormatProvider parameters - http://msdn.microsoft.com/en-us/library/8tfzyc64.aspx In this provider you can set French locale.
I took the liberty to update the code to .net4 for use with CRM 2011.
ReplyDeleteKind regards, Vincent Pannenborg
using System;
using System.Activities;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
namespace FormatDateTime2011
{
public sealed class DateTimeHandler : CodeActivity
{
// Input property
[RequiredArgument]
[Input("Format of DateTime")]
public InArgument InputDateFormat { get; set; }
// Input property
[RequiredArgument]
[Input("DateTime to format")]
public InArgument InputDateTime { get; set; }
// Output property
[Output("Formatted DateTime")]
public OutArgument OutputResult { get; set; }
protected override void Execute(CodeActivityContext executionContext)
{
string DateFormat = InputDateFormat.Get(executionContext);
DateTime datetime = InputDateTime.Get(executionContext).ToLocalTime();
string result = string.Empty;
CultureInfo provider = CultureInfo.InvariantCulture;
if (!string.IsNullOrEmpty(DateFormat) && datetime != null)
{
result = datetime.ToString(DateFormat, provider);
}
OutputResult.Set(executionContext, result);
}
}
}
edit: "using Microsoft.Xrm.Sdk.Query;" can be left out
ReplyDelete