Books regarding Dynamics CRM 4.0
Dynamics CRM Report Modification Walkthrough
Exporting a report
The first step is to download a report from Dynamics CRM. You can do this by browsing to the Workplace and open the reports are. In the grid select the report which you want to modify and press “Edit Report”.

Clicking on “Edit Report” will open the Report Detail page. On this page click “Actions” and select “Download Report”. This will let you download the *.rdl file which is the definition of the report. Save this file to some location on your hard drive.

Opening the report in Visual Studio 2005
Keep in mind that the report must be opened in an editor which supports the rdl for SQL Server 2005. For Visual Studio this is version 2005. With 2008 you cannot change report files for CRM. When you directly open the report in Visual Studio you will see that the xml viewer will be opened.

Although you can modify a report in XML, there is an easier way to modify reports in Visual Studio. You will first need to set up a project for Reports. In Visual Studio select the “Report Server Project” from the “Business Intelligence Projects” group. If this is not available, install the “Business Intelligence Development Studio Add-In for Visual Studio 2005” from the SQL Server installation CD.

From the “Solution Explorer” right click on “Reports” and add an existing Report. From the report selection screen select the report which you have saved in the previous step.

The report will now be added to the solution under the reports tree view item. When you open this report now, you will get into a mode in which you can modify the report.

Connecting to Dynamics CRM
The report does have three tabs for defining the dataset, modifying the layout and previewing the report output. The first step in changing a report is to change the dataset. Every report which is exported from Dynamics CRM does have a hardcoded data source set. This will need to be changed to your current environment before you can modify the report. To do this click on the “Data” tab. You will get the following error message.
A connection cannot be made to the database. Set and test the connection string:

This is the message specifying the situation as I have just described. Just click “OK” and let’s change the data source. To do this click on the “…” next to the dataset pick list.

This will give you the “Dataset” detail form. On this form click on “…” next to the data source picklist.

This will give you the “Data Source” detail form. On this screen click on Edit next to the connection string.

This will give you the “Connection Properties” detail form. On this page verify that the server name is correct. Also select the correct database name. This should be in the format of “organizationname_MSCRM”.

After clicking on “OK” several times you will get back to the main screen. This will be refreshed and more information will be visible now.
Changing the Query
Now that a connection is created you can change the query. Unfortunately there is not just a single query. There are multiple Datasets with each a separate query. You’ll first need to find the correct Dataset before you start changing the query. By looking at the queries you will probably be able to determine which dataset you should use. Most likely the query starts with the declaration of a dynamic query like “Declare @SQL Varchar(4000)”.
Once you have found the query you can modify the query. I do expect that the people reading this article do have knowledge of how to change these queries, if not than you might want to find somebody else to change the query for you.
Once the query is modified and does return the attributes you want to use in your report, then there is an important step you should execute. If you miss the following steps, then you’ll get this error messsage “An error occurred during the local report processing. The definition of the report '/User Summary' is invalid.”. For some reason Visual Studio removes the “Fields” from the dataset. This basically is the mapping between the attributes returned by the query and the variables used in the report. You can verify that the list of Fields is empty by opening the Dataset detail form (click on the “…” next to the dataset pick list). On the Dataset detail form click “Fields”.

You can manually enter each of the fields and values, but you can also let Visual Studio regenerate this list. To generate this list you can click the “Refresh Fields” in the Dataset toolbar.

Clicking this toolbar button will ask you to define query parameters.

This screen doesn’t automatically fill the default values, but the values are available in the report though. You can find the values which you should fill in here on the “Report Parameters”. You can access these from the “Layout“ tab. Somewhere on the layout screen right click outside of the report somewhere on the yellow piece. This will give you a context menu where you can select the “Report Parameters”.

On the “Report Parameters” form you can select the property on the left side on the screen and at the right bottom you can find the default value for the selected property.

Copy the default value and past this into the “Parameter Value” for the “Parameter Name”.

Now click “OK” and the query is changed AND you can use the selected attributes in the report layout editor.
Changing the Layout
The layout can be changed on the “Layout” tab of the report. There are many possibilities to change the layout, but I won’t dive into the Reporting Services possibilities. I will just show how to add the field which is added to the query, but for more information you should look into Reporting Services trainings.
To add a field to the result table select the table and right click on the header. You’ll now get a context menu which will allow you to add a row group. This is the value you need to select to add a column. In the “Expression” field you should select your newly added attribute in this format “=Fields!address1_fax.Value”. For the label you could add a Textbox from the toolbox and change its properties to match the existing labels, but you could also just copy an existing label and change the text value.

Previewing the Report
To review the report, just click the “Preview” tab. If necessary you can go back to the Layout or Data tab to change the report. When you are ready, then save the report to an *.rdl file.

Updating the report in CRM
In Dynamics CRM, go back to the Reports area in the Workplace module. In the grid select the report which you have just modified. In the toolbar click on “Edit Report”.

On the Report detail form select the saved report definition file by using the browse button for the file location. Now press “Save” or “Save and Close” and your report is updated with your new definition file. From CRM you can now run the updated report.
More Convergence!
Tuesday 18: 17:30-19:00 MS Pavillion CRM Booth Kiosks 33-36
Wednesday 19: 17:00-18:30 MS Pavillion CRM Booth Kiosks 33-36
Thursday 20: 9:30-11:30 MS Pavillion CRM Booth Kiosks 33-36
Thursday 20: 12:00-13:00 Hall B5.2 - Ask the Community Experts session
For the session on thursday we're still looking for more questions. See my previous post about the convergence for more details: Convergence - Ask the expert.
See you in Copenhagen!
Convergence - Ask the expert
That session is going to be one of the most interactive sessions of the Convergence. On stage will be my fellow MVP's as well as myself answering questions from the audience. Feel free to drop by and ask any question. Also, you can let us know your questions upfront on this forum discussion:
http://forums.microsoft.com/Dynamics/ShowPost.aspx?PostID=4064067&SiteID=27&mode=1
Let me know if you'll be in Copenhagen as well. I look forward drinking a beer with my fellow CRM people!
CRM 5.0 Features
Social Media and CRM
Although we're in the middle of web 2.0, most companies do not integrate social media in their organizations, including CRM. Avanade has concluded this based on a research which has been conducted under more than 500 global executives.
There are a lot of interesting facts published in the press release which can be downloaded from the CRM Social Media website of Avanade.
Get rid of "Do you want to close this window?"
The webpage you are viewing is trying to close the window.
Do you want to close this window?
yes no
This message does appear in CRM 4.0 only when you are using Internet Explorer 7.0 and you have enabled the application mode setting. Nevertheless, it is an anoying message which you can get away!
To get rid of this message open the default.aspx file which resides in the root of the CRM website. In this file there are these three lines of code:
var oMe = window.self;
oMe.opener = window.self;
oMe.close();
Modify the second line of this snippet and end up with these three lines:
var oMe = window.self;
oMe.open('','_self','');
oMe.close();
You now will not have the message anymore. Keep in mind that any update or migration might remove this change, but you should be able to reapply the change easily again.
Overview of CRM 4.0 Training & development collateral
Official Courseware available now
These training courses are the Microsoft Dynamics Official Curriculum currently available for CRM 4.0 now, either as soft-copy downloads, ordered hard copy – or you can schedule classroom training.
Download them directly via https://mbs.microsoft.com/partnersource/communities/training/trainingmaterials/student or https://mbs.microsoft.com/customersource/training/trainingmaterials/student/ for customer source access.
Extending Microsoft Dynamics CRM 4.0 - Course Number 8969
This three-day training material provides individuals with the knowledge and skills to develop extensions for Microsoft Dynamics CRM. The training material focuses on extension methods documented in the Microsoft Dynamics CRM SDK.It also includes content on Microsoft Dynamics CRM Web Service programming, creating and configuring Custom Workflow Activities and Plug-ins, advanced client-side scripting, application integration capabilities and how to create a customer portal solution that connects Microsoft Dynamics CRM to the Internet.
Administration in Microsoft Dynamics CRM 4.0 - Course Number 80002
This training material, Administration in Microsoft Dynamics CRM 4.0, provides individuals with the necessary techniques to plan, develop, apply, and examine administrative tasks within Microsoft Dynamics CRM 4.0.
Workflow in Microsoft Dynamics CRM 4.0 - Course Number 80003
This training material describes how to create, run, and monitor workflows to automate business processes. The training material emphasizes out-of-box workflow functionality. The training material includes the following topics:Basic concepts Creating a basic workflow Design process Update triggers Conditional branching Advanced workflows Multi-stage workflows Monitoring workflows Workflow securityThe training material also focuses on using workflows in Microsoft Dynamics CRM 4.0 to automate the following business processes:Sales process Lead promotion Probable revenueThe following topics are not covered in detail in this training material, but are introduced to provide individuals with insight into potential advanced workflow topics:Extending workflows with custom assemblies Upgrading workflows Data migration and workflows
Customization and Configuration in Microsoft Dynamics CRM 4.0 - Course Number 8912
This three-day training material provides individuals with the tools to configure and customize Microsoft Dynamics CRM 4.0. Configuration topics include setting up business management functions such as:Business units Users Teams Security privileges and roles System Settings Multilingual User Interface Language Packs Currency Exchange Rates Multiple OrganizationsThe training material also focuses on using the Microsoft Dynamics CRM 4.0 Customization tools to customize the following system components:Forms Views Entities Attributes Relationships Entity MappingsThe following customization topics are outside the scope of this training material, but are introduced here to provide individuals with insight into potential advanced customization features:Application Event Programming Client Extensions Workflow SiteMap URL Addressable Forms IFrames SDK
Applications in Microsoft Dynamics CRM 4.0 - Course Number 8913
This three-day training material explores the Microsoft Dynamics CRM application from a user's perspective. Application functionality covered in the training material includes: Sales Management Marketing Automation Service Management Service Scheduling
What’s New in Microsoft Dynamics CRM 4.0 - Course Number 8910
This one-day training material provides individuals with the knowledge and skills to begin planning for Microsoft Dynamics CRM 4.0.
Installation and Deployment in Microsoft Dynamics CRM 4.0 - Course Number 8911
This three-day training material provides individuals with the tools to install and configure Microsoft Dynamics CRM 4.0. The training material focuses on the components used within a Microsoft Dynamics CRM deployment, the hardware and software requirements needed to successfully deploy Microsoft Dynamics CRM, and the installation instructions for the primary Microsoft Dynamics CRM components: the Microsoft Dynamics CRM Server, the E-Mail Router, and Microsoft Dynamics CRM for Office Outlook.
E-Learning available now
Note that for an individual to view the E-Learning online, they’ll have to be set up as a user in PartnerSource/CustomerSource. Some partners or customers prefer to download the E-Learning courses for their trainees instead, and have the trainees view them offline
This query will bring up all E-Learning courses (57 is the current count) – but note that they map pretty consistently to individual chapters of the Official Courseware, so the content of the Official Courseware and E-Learning are similar:
http://dynamics.microsoftelearning.com/catalog/default.aspx?view=catalog&filterView=basic&productFilter=Microsoft%20Dynamics%20CRM%204.0&productFilterDisabledValue=&seriesFilter=def-0&seriesFilterDisabledValue=&collectionFilter=def-0&collectionFilterDisabledValue=&searchAction=filter&sortColumnId=&sortOrderAscDsc=&pageNumber=
You can filter this further to essentially get E-Learning versions of the Official Courseware training courses listed above. The right column lists appropriate audiences, such as Desktop and End-User Support Professionals, Developers, IT Professional
Dynamics CRM 4.0 collateral from the Microsoft Download Center
All available via http://www.microsoft.com/downloads/results.aspx?freetext=&productID=835909D0-A755-41FF-93CD-F5207C609EF5&DisplayLang=en
A minor subset of the 155 items available via the Download Center URL provided above
Microsoft Dynamics CRM 4.0 Implementation Guide
This guide contains comprehensive information about how to plan, install, and maintain Microsoft Dynamics CRM 4.0.
Microsoft Dynamics CRM 4.0 SDK
This package contains the complete software development kit for Microsoft Dynamics CRM 4.0.
Microsoft Dynamics CRM 4.0 Logical Database Diagrams
A series of diagrams showing the logical database structure for Microsoft CRM 4.0.
Microsoft Dynamics CRM 4.0 Internet Facing Deployment Scenarios
This document covers how to set up the Microsoft Dynamics CRM 4.0 Web site to make it available from the Internet.
Microsoft Dynamics CRM 4.0 ISV White Paper
How to create business applications for Microsoft Dynamics CRM 4.0.
Microsoft Dynamics CRM 4.0 Data Migration Manager
Using the Microsoft Dynamics CRM 4.0 Data Migration Manager, you can convert and upload data from another CRM system to Microsoft Dynamics CRM 4.0.
Optimizing and Maintaining Microsoft Dynamics CRM 4.0
This white paper details techniques, considerations, and best practices for optimizing and maintaining the performance of Microsoft Dynamics CRM 4.0 implementations.
Offline and Online Synchronization in Microsoft Dynamics CRM
This "nuts and bolts" white paper details the Offline and Online synchronization processes in Microsoft Dynamics CRM 4.0.
How to configure the Microsoft Dynamics CRM 4.0 On-premise and Online E-mail Router in different deployment scenarios
This document lists steps to configure Microsoft Dynamics CRM 4.0 e-mail in different deployment scenarios.
Microsoft Dynamics CRM 4.0 Performance and Scalability
Microsoft, together with Unisys Corporation, completed benchmark testing of Microsoft Dynamics CRM 4.0 running on Microsoft® Windows Server® 2008 operating system and Microsoft SQL Server® 2008 database software. Benchmark results demonstrate that Microsoft Dynamics CRM can scale to meet the needs of an enterprise.
Microsoft Dynamics CRM 4.0 Deployment SDK
SDK for customizing deployments for Microsoft Dynamics CRM 4.0.
Microsoft Dynamics CRM 4.0 Suggested Hardware for Deployments of up to 500 Concurrent Users
Describes general hardware sizing information that will support Microsoft Dynamics CRM version 4.0 with up to 500 concurrent users in a single deployment on-premise model.
SEE ALSO:
Microsoft Dynamics CRM Developer Center
Access to SDK-related information, including access to CRM developers, etc.
Microsoft CRM Blog
Very useful, target, in-depth knowledge shared by program managers, developers, and testers from the CRM Product Group as well as other sources
Hope this is useful.
Get the latest hotfixes for the CRM 4.0 outlook client
The following issues are discussed:
1. Outlook hangs during initialization (progress toolbar displays “Loading…” and never finishes)
2. With E-mail Auto Promotion Enabled, Outlook may not close cleanly/properly.
3. Contacts with birthdays earlier than 1/1/1970 causes Outlook to crash
4. Items in Shared Calendars will report Sync Issues
5. Cannot Promote an E-mail where the name of the attached file contains a ‘&’ symbol.
6. Selecting Dismiss on Outlook Calendar reminder for Service Activity causes record to change Status Reason back to default value for that record.
7. OWA Sent Emails Get Stuck in Outlook Draft Folder When Outlook Is Open And CRMADDIN is Enabled
8. Microsoft Outlook stops responding when you open, close, reply to, or forward e-mail messages in the Microsoft Dynamics CRM 4.0 client for Outlook
9. CRM Outlook client and/or Desktop Client hangs in presence of other Outlook add-ins
10. Phone call activity due time is changed after the activity is snoozed or dismissed.
There is a cumulative hotfix which does fix each of these as well: Download
Custom entities and attributes in a plug-in
To retrieve records based on some attribute values you could use a piece of code like this:
// Create the QueryByAttribute object.
QueryByAttribute query = new QueryByAttribute();
query.ColumnSet = new AllColumns();
query.EntityName = "new_customentity";
query.Attributes = new string[] { "new_customentityid" };
query.Values = new string[] { customEntityId };
// Create the request.
RetrieveMultipleRequest request = new RetrieveMultipleRequest();
// Set the request properties.
request.Query = query;
request.ReturnDynamicEntities = true;
// Execute the request.
RetrieveMultipleResponse response = (RetrieveMultipleResponse)service.Execute(request);
One of the most important details in this piece of code is this line:
request.ReturnDynamicEntities = true;
If you forget this line, you'll end up with this error message:
System.InvalidOperationException was unhandled by user code Message="There is an error in XML document (1, 509)." Source="System.Xml" StackTrace: at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle) at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at Microsoft.Crm.SdkTypeProxy.CrmService.Execute(Request Request) at Microsoft.Crm.Asynchronous.SdkTypeProxyCrmServiceWrapper.Execute(Object request) at ...your assembly information...
So, don't forget the ReturnDynamicEntities attribute and you should be fine to go!
Unauthorized error after deploying your custom application
Server Error in '/ISV/CustomApplication' Application.
The request failed with HTTP status 401: Unauthorized. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Net.WebException: The request failed with HTTP status 401: Unauthorized.Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace:
[WebException: The request failed with HTTP status 401: Unauthorized.]
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) +551137
System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +204
Microsoft.Crm.Metadata.MetadataWebService.GetDataSet() +31
Microsoft.Crm.Metadata.DynamicMetadataCacheLoader.LoadDataSetFromWebService(Guid orgId) +301
Microsoft.Crm.Metadata.DynamicMetadataCacheLoader.LoadCacheFromWebService(LoadMasks masks, Guid organizationId) +40
Microsoft.Crm.Metadata.DynamicMetadataCacheFactory.LoadMetadataCache(LoadMethod method, CacheType type, IOrganizationContext context) +418
Microsoft.Crm.Metadata.MetadataCache.LoadCache(IOrganizationContext context) +324
Microsoft.Crm.Metadata.MetadataCache.GetInstance(IOrganizationContext context) +386
Microsoft.Crm.BusinessEntities.BusinessEntityMoniker..ctor(Guid id, String entityName, Guid organizationId) +115
Microsoft.Crm.Caching.UserDataCacheLoader.LoadCacheData(Guid key, ExecutionContext context) +323
Microsoft.Crm.Caching.ObjectModelCacheLoader`2.LoadCacheData(TKey key, IOrganizationContext context) +389
Microsoft.Crm.Caching.BasicCrmCache`2.CreateEntry(TKey key, IOrganizationContext context) +82
Microsoft.Crm.Caching.BasicCrmCache`2.LookupEntry(TKey key, IOrganizationContext context) +108
Microsoft.Crm.BusinessEntities.SecurityLibrary.GetUserInfoInternal(WindowsIdentity identity, IOrganizationContext context, UserAuth& userInfo) +344
Microsoft.Crm.BusinessEntities.SecurityLibrary.GetCallerAndBusinessGuidsFromThread(WindowsIdentity identity, Guid organizationId) +194
Microsoft.Crm.Authentication.CrmWindowsIdentity..ctor(WindowsIdentity innerIdentity, Boolean publishCrmUser, Guid organizationId) +279
Microsoft.Crm.Authentication.WindowsAuthenticationProvider.Authenticate(HttpApplication application) +605
Microsoft.Crm.Authentication.AuthenticationStep.Authenticate(HttpApplication application) +125
Microsoft.Crm.Authentication.AuthenticationPipeline.Authenticate(HttpApplication application) +66
Microsoft.Crm.Authentication.AuthenticationEngine.Execute(Object sender, EventArgs e) +513
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433
After quite a search I managed to find this blog. There I learned that CRM is using an HttpModule for multitenancy. The http module will be called with an anonymous user account and will fail when it's requesting the metadata webservice. To make your own app working, you'll need to remove the HttpModule from being loaded. A copy paste piece from Cesar de la Torre's blog:
This is what you have to add to your own web.con file:
<system.web>
<httpModules>
<clear/>
</httpModules>
Also, if you are not using any CRM 4.0 Titan assembly within your app, you can also get rid of all the references, adding also the following:
<assemblies>
<clear/>
<add assembly="*"/>
Personally I prefer the removal of only the exact names instead of a generic "clear". What I ended up using is:
<httpModules>
<remove name ="CrmAuthentication"/>
<remove name ="MapOrg"/>
</httpModules>
If any of you finds a better approach I'm glad to hear that. Until then I'll be using this approach.
Convert lead to contact, account and/or opportunity programmatically
Guid entityId = service.Create(rps.Entity);
Today I needed some code which does convert a lead to a contact programmatically. Instead of just building, I first asked my mate Google if he knew how to do that. Kind as Google is, he told me that he didn't know, but he knew that Cem Onvar knows that. Cem has published the code on the codeproject website.
Basically it comes down to two steps. The first step is to disable the lead. This can be done by using the SetStateLeadRequest. The second step is to use an request class which is quite rare. It's the InitializeFromRequest class. On this class you can set the EntityMoniker attribute to the lead which you just disabled. On the same request you'll need to set the target entityname to the name of the entity you wish to convert the lead into (contact, account or opportunity) and you'll need to set the TargetFieldType. This would most likely be TargetFieldType.All. Now execute that request and you're done.
For the direct code look at the codeproject site.
Keep in mind that you can use this approach for all kind of conversions.
Plug-in not working
Error:
There are multiple reasons why this error can occur. These reasons include:
- The plug-in is registered on disk, but the file is not located in the correct location (drive:\crm server folder\server\bin\assembly\). Keep in mind that if you use the registration tool that the plug-in will be registered, but the file will not be placed in the right location. This is a manual step.
- The plug-in is registered on disk and the file is located in the correct location, but the security settings are not correctly set on the assembly file. Once you have copied the file to the \server\bin\assembly folder, make sure that you check the permissions of the file. The user which is used to run the application pool in which CRM is running, should have read & execute rights. You can set this by going to the folder and right click on your plugin its dll file. Then press "Properties". Go to the tab "Security" and add the user which is used for the application pool. This user you can figure out in the IISManager. There look at the properties of the CRM website to find out which application pool is used. Then look in the application pool's properties to find out the identity. Most likely this is "Network Service" but it could be changed in your situation.
After setting the security settings, make sure to perform an IISreset.
- Your environment exists out of multiple servers and the plugin is registered on disk. In this situation make sure that the file is placed in the \server\bin\assembly folder on all servers. Also the security should be set correctly (see other possible reason).
Error:
Possible reasons for this error include
- The code does use a reference to the webservices, but uses credentials which do not have enough privileges in CRM
- The plug-in does is created for the non default instance. In this case, look at the following kb article: http://support.microsoft.com/kb/948746. From there you can request a hotfix for this issue.
Error:
This error shows up even though the user is a System Administrator. The cause is that the user is not a member of the Deployment Administrators group in CRM Deployment Manager. Once you have added yourself to that group it will work. Keep in mind that you will need to login as an administrator to be able to open the Deployment Manager.
Error:
This error seems to come from a piece of code in the synchronous plug-in framework which forces the CrmService to use the localhost. George has written a post on the logic behind this.
http://crm.georged.id.au/post/2008/02/22/Synchronous-plugins-want-localhost.aspx
The solution is to either run the plug-in asynchronous or otherwise make the webservice available from the localhost.
Update: There is a hotfix available for this issue now: http://support.microsoft.com/kb/950542
As soon as I run into other issues with plug-ins, I'll definitely add them to this list.
Javascript Files and Caching
There is one issue though when doing so. When the file has been changed on the server, it will still be cached on the client's machines. You can force Internet Explorer to check the Javascript file to see if it has been changed. One of my German colleagues (Christian Niss) has learned me that it is possible to modify the iis-cache settings for just the javascript file.
If you switch off "enable content expiration" and add a custom http header for the javascript file only:
Cache-Control: max-age=259200, must-revalidate
It should set client side caching of the file to three days (259200 sec), but each time the script is being used the browser must check if a more recent file is available on the server.
Good luck with caching!
Not all emails are sent from MailMerge
Apparently only 800 contacts had an email address specified, so that already is causing half of the issue. The second half was harder to find, especially because there was no error message anywhere.
The root cause of this issue appeared to be that the bit field for 'donotsendmm' has been set to NULL. Although the default is 'yes', the field had no value because the records were created in an import program instead of the UI. In this import program the default values were not set for the 'allow marketing' attribute. After setting the allow marketing to true, the emails were sent.
Hint: To update all the records in bulk on a supported way, Nico created a workflow rule which updates that field to set it to true. Then perform an advanced find to select the records for which the field has not been set to false and run the workflow on all the records on the page. You will then update 250 records in each run. You can set the record amount visible in your personal options in CRM.
Creating an activity report which includes the related people
The only attributes which you can select in the grid are the attributes which are belonging to the entity activitypointer. These include the activityid, startdate, statecode, but also the regardingobjectid. So the question is, how to get the to, from, cc etc. For this you can use the function which I have posted in my previous post. This function accepts an ActivityID and an ActivityPartyType. So what is this type? Look at this page: ActivityPartyType. You will find a list of values mapped to what kind of field you want to add to your report.
By using that function you can create your query for the report. An example would be:
SELECT
activityid, activitytypecode, scheduledstart, subject, owneridname, statecodename,
regardingobjectidname,
(SELECT DBO.fn_PGGM_GetActivityPartyList(activityid, 1)) [to],
(SELECT DBO.fn_PGGM_GetActivityPartyList(activityid, 2)) [from],
(SELECT DBO.fn_PGGM_GetActivityPartyList(activityid, 5)) [required]
FROM
filteredactivitypointer
This query does select some default attributes and it adds the regarding, to, from and required fields. Add this query to the generation of a report and you'll be set to go.
Note: make sure that the function gets added to your database and assign the correct rights. See the post around the function for details.
Happy reporting!
Transform a table column into a CSV field in SQL Server
Msg 512, Level 16, State 1, Line 2
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
What I like to do, is to transform the result table column into a single field separated by a ; sign. Earlier on I used to create a huge function which used cursors etc. Then a colleague of mine told me how to use C# code in SQL server which seemed to be a neater solution.
Today I have found a new approach. This uses a function again, but it is very simple. Here's the function:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Ronald Lemmen
-- Create date: 4 July 2008
-- Description: Function to return the people in CSV format belonging to a activity based on the activity party type code
-- =============================================
CREATE FUNCTION fn_RL_GetActivityPartyList
(
@ActivityId uniqueidentifier,
@ActivityPartyType int
)
RETURNS nvarchar(3000)
AS
BEGIN
DECLARE @result nvarchar(3000)
SET @result = ''
SELECT @result = Coalesce(@result + ';', '') + partyidname from filteredactivityparty party where party.activityid = @ActivityId and party.participationtypemask = @ActivityPartyType
RETURN SUBSTRING(@result ,2, LEN(@result))
END
GO
The @result will get filled by the SELECT query with the values from the filteredactivityparty table separated by a ;. The first character is a ; as well and therefore I do remove this one in the RETURN statement.
After the + in the SELECT query you can place your own query. This example is just extremely useful in my next post :)
Make sure that you do grant access to the correct people in order to use this function. In the case of a CRM report, add the reporting group. See the below example, but make sure that you do change the guid to the guid which is valid for your system.
GRANT EXECUTE ON [dbo].[fn_PGGM_GetActivityPartyList] TO [PGGM-INTRA\ReportingGroup {05e0584a-1d94-424c-8014-c2f3b1b92ccc}]
GO
Happy reporting!
Determine the logged in user
The first one is that you are not allowed to use the <%= approach anymore. You do now have to use the function:
The second reason is that the variable "Microsoft.Crm.Security.User.Current.UserAuth.UserId" does not exist anymore. Microsoft has changed the internal structure of how they work with the current user. You now should use this "Microsoft.Crm.Security.User.Current.SystemUserId.ToString()". These two changes lead to the following code
<script language="javascript">
var loggedInUser = '<%Page.Response.Write(Microsoft.Crm.Security.User.Current.SystemUserId.ToString())%>';
</script>
If you do have a single mistake in the aspx page you are changing, then you'll get the following error:
The VirtualPathProvider returned a VirtualFile object with VirtualPath set to '/MicrosoftCRM/sfa/accts/edit.aspx' instead of the expected '//MicrosoftCRM/sfa/accts/edit.aspx'
This has nothing to do with the VirtualPathProvider, it's just that you have a mistake in your aspx page.
Good luck!
MVP for the 3rd consecutive year
As a reward for community work last year, Microsoft has again reawarded me the Microsoft CRM MVP! I am very much pleased with this award because as one of my colleagues said: Getting to the top is hard, but staying there is even harder!
Last year I have spend a lot of time on doing community work again. I have spend a lot of time preparing for presentations like deepdive sessions and CRM 4.0 presentations. Furthermore this blog has been extended with quite some posts. And although there were not as much posts from me as in the year before, I did do spend a lot of time on the newsgroups en forums to help out people.
Once again I would like to encourage all of you to share your knowledge. Answer questions in newsgroups and forums. Or prepare a presentation about something you have been working on and share this with your colleagues. My girlfriend has a t-shirt which says: "Knowledge is power". I agree with that, but I am confident that sharing knowledge is even more powerfull!
See you around in the communities!
UPDATE: Have a drink with your fellow CRM consultants
See you there!
If you're not from the Netherlands, then use this as an example and set up such a similar event. It's always nice to have some drinks with CRM consultants right?
UPDATE:
The date has been changed to the 21st of August.
Windows Home Server
Of course there's the most important feature: Backup. Every night the WHS server wakes up all of my pc's and laptops and makes a backup. Once my work laptop was stolen and I did lose data... I had a hard time back then, but that won't happen again. My laptop might still get stolen, that's a risk of living near Amsterdam, but I won't ever my data again.
The second feature I really like, is the ability to have a share to place your files on. By default it creates different folders like Photos, Music, Movies etc. And there's an even greater feature related to that. Some of you probably have a server at home as well. You have to admit that you have been struggling with harddrives and free spaces right? Well, I've added several harddisks to this machine and it just combines them all to one virtual harddrive. There's never the problem that one harddrive is full. Just add a harddrive and you can add files to the shares again.
Then there's the feature of accessing your server from the internet. You can easily set up the server to be accessible from the internet. Microsoft even offers a friendly url like: http://Yourserver.homeserver.com. From this site you can access your shares and even remote desktop to your home computers, if they support RDP.
Now it would be great to have CRM on this installed as well right? It would be wonderful to have your own home CRM system which contains all the addresses of your friends, birthdays etc. Integrate this with Facebook and Linked-in to always be up to date. Also use a mobile solution to have the data integrate with your phone and then we're living in a utopia right? I think it would be great that if I end up with my car somewhere in Spain and I do know somebody in Barcelona, that I can search for my friend in my crm system, click the button "use address in TomTom" and drive there to say "HI!". That would be awesome.
But thats not possible, yet. WHS isn't designed to be an Domain Controller or even part of a domain. Doing so appears to be possible but it is very much unsupported. I'll dig a bit into this after the Power Pack 1 has been released. For the users who wan't to have AD and install CRM at home now, they should go and get Windows SBS and get it running in your home. Not only is this product a lot more expensive, it also doesn't have some of the neat featurs of WHS.
In short, Windows Home Server is a great product for what it's designed for: Allowing the home users to have a centralized place for their files and backups.
Resizing windows
window.moveTo(0,0);
window.resizeTo(screen.availWidth, screen.availHeight);
Also, when you open a custom page you can also set the window size by using the same javascript function. In your code you can use the following function in the Page.OnLoad() to set the window size to match your requirements:
private void SetWindowSize(int iWidth, int iHeight)
{
StringBuilder sbResizeScript = new StringBuilder();
sbResizeScript.Append("\n");
ClientScript.RegisterClientScriptBlock(this.GetType(), "ResizeScript", sbResizeScript.ToString());
}
Happy resizing!
Stopping and continuing a save event
On that page you will see that you can stop the onsave event by setting the 'event.returnValue = false'. Don't forget to follow that line with a 'return false'. This will cause the save procedure to stop right at that point. Otherwise statements after that will still be executed.
To call the save event from your javascript code, you can use the javascript functions crmForm.Save(); and crmForm.SaveAndClose(). By looking at the 'event.Mode' you can determine which event was executed before. If the code is 1, then it is a crmForm.Save(); or it is 2 for a crmForm.SaveAndClose(). There's only one small issue. There can be other save events as well. There's the 'save and new', 'save as completed', and also the 'send' for emails. Below is a list of save events with the corresponding javascript functions to call. Once again, this is not documented in the SDK, so this might change with a hotfix or new version.
Save
Code: 1
Function: crmForm.Save();
SaveAndClose
Code: 2
Function: crmForm.SaveAndClose();
Send
Code: 7
Function: send();
SaveAsCompleted
Code: 58
Function: SaveAsCompleted();
SaveAndNew
Code: 59
Function: crmForm.SubmitCrmForm(59, true, true, false);
Good luck!
Import CSV file to DataTable
class CSVReader
{
public System.Data.DataTable GetDataTable(string strFileName)
{
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + System.IO.Path.GetDirectoryName(strFileName) + "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\"");
conn.Open();
string strQuery = "SELECT * FROM [" + System.IO.Path.GetFileName(strFileName) + "]";
System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter(strQuery, conn);
System.Data.DataSet ds = new System.Data.DataSet("CSV File");
adapter.Fill(ds);
return ds.Tables[0];
}
}
You can then use this class together with a code like this:
private void YourFunction()
{
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
CSVReader reader = new CSVReader();
DataTable dt = reader.GetDataTable("C:\\CoffeeContacts.csv");
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow dr = dt.Rows[i];
account acc = new account();
acc.name = dr["Company"].ToString();
service.Create(acc);
}
}
ForceSubmit in ASP.Net
function disableFields(field1, field2){
field1.disabled = true;
field2.disabled = true;
}
<asp:DropDownList ID="ddl1" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl2, form1.ddl3);">
<asp:DropDownList ID="ddl2" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl1, form1.ddl3);">
<asp:DropDownList ID="ddl3" runat="server" AutoPostBack="true" onchange="disableField(form1.ddl1, form1.ddl2);">
This works perfectly, but... After a postback, the values of the selected picklists are gone! This seems like the same behavior as the disabled fields in CRM. In CRM you can solve this by setting the attribute ForceSubmit to true on the attribute, but I did not know of such an attribute.
Apparently there is such behaviour built into ASP.NET 2.0. In order to enable the submission of disabled form elements, you need to put this line in the Page_Load:
Page.Form.SubmitDisabledControls = true;
For more information on this attribute, check MSDN
Happy disabling!
Javascript and IFrames
Deselecte the option "restrict cross site scripting" (in dutch "Het uitvoeren van scripts tussen frames beperken")
That usually saves a lot of troubles.
Furthermore, the next step is to create JavaScripts. One which I use quite often, is one which allows me to access a value in the IFrame. This is useful in onSave routines to copy data from the iframe to any of the CRM attributes. This is the code which I use:
crmForm.all.name.DataValue = crmForm.all.IFRAME_CustomIFrame.Document.formname.name.value;
In this example you do need to change the name of the attribute to which you want to save the data to (crmForm.all.name -> crmForm.all.yourSchemaName). The next modification is to change the name of the IFrame. When setting up an IFrame, you do supply a name. Change the IFRAME_CustomIFrame to IFRAME_YourIFrameName. Then on your custom html or aspx page, you do need to access the variable. That you can do by specifying the name of the form followed by the name of the attribute.
For other examples, look at the page of Jonas Deibe Playing around with iframes or Michael Höhne More JavaScript Code.
VPC CRM 4.0
CrmDateTime conversion to DateTime
Convert.ToDateTime(crmdatetime.Value)
DateTime.Parse(crmdatetime.Value)
For more information on the CrmDateTime, look in the SDK:
http://msdn2.microsoft.com/en-us/library/aa613542.aspx
Logo Dynamics
http://www.microsoft.com/Presspass/gallery/ms-logos.mspx?FINISH=YES
It includes logo's for most Microsoft products including Visual Studio, Office, Windows and of course Dynamics.
Dynamics CRM and NAV Integration
For more info look at: http://www.scribesoftware.com/microsoft-dynamics-nav.asp
Or join any of the following webinars:
Announcing the Scribe Adapter for Microsoft Dynamics NAV
Tuesday, February 19, 2008 11:00a.m. US ET/4p.m. GBT
https://scribesoft.ilinc.com/register/szvfbk
Announcing the Scribe Adapter for Microsoft Dynamics NAV
Tuesday, February 26, 2008 11:00a.m. US ET/4p.m. GBT
https://scribesoft.ilinc.com/register/mcpsst
There are more companies who have created an integration between Microsoft Dynamics CRM and NAV. I haven't performed research on which exist, but I've seen some in the comments section already *smile*
Unable to browse for Active directory objects
Unable to browse for Active directory objects
This error message can appear when you press "Browse" after selecting the Organizational Unit in Active Directory. There are some possible solutions which could cause this issue. Think about the following:
- Are you logged in with an account to the domain instead of the local machine
- Is the server member of the domain
- Are you logged as a user with sufficient rights in CRM? If possible, try to use a domain admin.
There has been posted a possible solution to the public newsgroups as well by Merlin:
I was installing on a fresh domain within the same network, and got this error. I set up the new domain's DNS and still got the error. However, since I was on the same network subnet, my servers were getting their DNS from the primary domain's DNS server, which had no knowledge of my test domain's domain controller. So I turned on zone transfers between the 2 domains. Now my servers can find their domain controller via DNS and I can browse that domain's AD.
Hope this helps you further!
Overriddencreatedon
Well these kind of situations are now history. The CRM development team has silently introduced a new feature. While performing an insert, you can set the attribute overriddencreatedon field. The value of this field will be used to set the record's created on attribute. So now you can import records in the history! A small feature which will make many people happy.
AttributeInfo.TypeName(int) != AttributeMetadata.Type.Name(float)
Error: lead: AttributeInfo.TypeName(int) != AttributeMetadata.Type.Name(float)
The cause of this error is a mismatch in attribute type. Usually a field has been removed in the other environment and has been recreated with another attribute type. The type in your destination CRM system of an attribute is the type displayed in the right side of the != statement. In the example above float. The type in the import file is the type displayed on the left side of the != statement. This is int in the example above. In order to get rid of this error message and to import the entity, you will need to remove the attribute from the destination system.
In the list of attributes, search for a custom attribute which has the same type as displayed on the right side of the equation. Determine if there is any of these which has been changed. Delete this attribute and import the entity again. Keep in mind that the attribute must be removed from the form first (also the published form) before it can be removed from the attribute list. Another thing to keep in mind, is that when you perform this action on a production system, that the data in the attribute will be removed. Since this is not recoverable, you should first perform the removal of the attribute by following the next steps:
- create a new custom temporary attribute
- copy the data from the old attribute to the temporary attribute for each record
- remove the attribute
- import the entity (and with that the new attribute)
- copy the data from the temporary attribute to the new attribute for each record
- remove the temporary attribute
If there are many custom attributes, it might be hard to locate which of these is causing the error to appear. Unfortunately the name is not in the error description and also the event viewer and tracing does not mention the exact attribute name. To find out which of the attributes is causing the error, you should start the database profiler. Start a new trace and run the import. As soon as the error shows up, stop the tracing. In the trace search for the last occurence of:
exec sp_executesql N'SELECT T1.AttributeId AS attributeid
When you have found this record, copy the whe query. When you run this query in the SQL Server Management Studio, then only a single record should be returned. One of the attributes in the result is the name attribute. This is the attribute which is changed and will need to be removed.
Disclaimer: Only perform actions on the database if you are comfortable with the technologies. Incorrect SQL statements can corrupt your database and cause mayor dataloss. Always make a backup before performing database queries against your CRM database.
Dynamics CRM 4.0 Test Data
Failure at Microsoft.crm.setup.common.registerasyncserviceAction
The reason why I got this error message was because I had just uninstalled CRM and tried to install it again. I did not think about a wise lesson I had once learned from a German guy. He said "Ein reboot macht immer gut". So after a restart of the server I have tried to install again and now it works like a charm.
Another thing to try, is to manually start the Async service for CRM and then retry the action.
If this doesn't work for you, make sure to check the log file regarding this service. You can find it on this location:
C:\Documents and Settings\{username}\Application Data\Microsoft\MSCRM\Logs\CrmAsyncService.log
Good luck installing CRM!
Happy new year!
After a nice holiday of more than a month, I'm back in the office. Whole december I've been free and doing as least work related stuff as possible. And I have succeeded in that quite good. Except for answering some questions, helping some colleagues out, writing an article for the CRM Team Blog, giving a presentation on CRM 4.0 for my Dutch colleagues, I have not done much work related stuff.
Okay, maybe I did do a bit much CRM related stuff in my holidays, but I have spend time the correct way as well. I've visited Hannover (Germany) for Christmas shopping, went to Austria on Holidays and moved houses. Unfortunatly the month is of free time is over and I need to get back to work.
In fact, I'm in the Munich office for the coming 3 weeks. Here I'll be working on a nice data migration from Salesforce to MS CRM 4.0 by using Scribe Insight. If you happen to be in Munich, please let me know and we can have a beer!
I hope that everybody has enjoyed the christmas time as much as I have done so and I wish everybody a great new year!
Ronald