Ayaz Ahmad [MVP - MSCRM]

MSCRM Blog

File Attachment to Notes - Dynamics CRM 4.0

Posted by Ayaz Ahmad [MVP - MSCRM] on June 11, 2008

In Dynamics CRM 4.0, file attachment to entities is pretty simple as compared to CRM 3.0. UploadFromBase64DataAnnotationRequest and UploadFromBase64DataAnnotationResponse object are both deprecated. Instead a new attribute has been introduces in annotation object with documentbody that accepts string in base64 encoding. Please find the below sample:

 

Reading file data into Byte array and then converting it to base64. Since I am using in memory object of StringBuilder class so I have just used str.ToString() to return string.

 

Byte[] data;

 ASCIIEncoding encode = new ASCIIEncoding();

data = encode.GetBytes(str.ToString());

string b64 = Convert.ToBase64String(data);

 

Next, simply create the annotation entity and set the attributes as below:

annotation note = new annotation();           

           

note.subject = “Test Export”;

note.filename = “exported.txt”;

note.mimetype = “text/html”;

note.documentbody = b64;

 

note.objectid = new Lookup();

note.objectid.type = “new_export”;

note.objectid.Value = entityid;

note.objecttypecode = new EntityNameReference();

note.objecttypecode.Value = “new_export”;

                       

Guid annotationId = service.Create(note);

 

Posted in CRM Development, MSCRM General | Tagged: , , , , | 1 Comment »

Auto Numbers in MSCRM

Posted by Ayaz Ahmad [MVP - MSCRM] on May 2, 2008

Last week I have been looking for the best approach to use auto numbers in Microsoft Dynamics CRM. After discussion with my peers I have come to the following possible options that can be used for auto numbering. Although these may not be the efficient techniques to get auto number work in CRM but they are all workable solutions.

Option 1:

Very simple, supported and mostly acceptable way of auto numbering is to read the attribute Max value and then add 1 to get next auto number. For example you have a custom entity named Project and you want to auto number Project_Ref_Number attribute.  But do not retrieve all records. Just retrieve the record with maximum number value by using following two properties of PageInfo Class in SDK and set descending order.

PageInfo.Count = 1;
PageInfo.PageNumber = 1;

One more consideration should be taken in account to register your auto number plugin to at PreCreate rather at PostCreate.

Issues:

In multi-user environment, this approach can come up with duplicate numbers in Project_Ref_Number when more than one user is creating project records.

Option 2:

This technique requires a bit more work but still supported way of doing things and all the time you will be getting 100% unique number.

You need to create a new table for project entity in a different database and not in CRM default database.

create table dbo.ProjectNumbers
(
 Project_Ref_Number int identity(1,1) primary key clustered,
 Projectid uniqueidentifier not null
)
go

Create a stored procedure for inserting a record into new database. This will increase the performance of your insert query.

create procedure dbo.proc_new_ProjectNumber

@ProjectId uniqueidentifier,

@Project_Ref_Number int output

as

insert into dbo.ProjectNumber

(

 ProjectId

)

values

(

 @ProjectId

)

select @Project_Ref_Number = scope_identity()

go

 

In your Plugin/Callout:

1.   Access you database using ADO.NET

2.   Execute stored procedure and get next number from returned results

3.   Set the value of the returned number to target entity attribute approperiatly.

4.   All Done

Issues:

1.   You have to setup database.

2.   You have to read and insert into external database.

Option 3:

This option used a lock mechanism on a text file placed somewhere at your webserver. You can create one file to store next number for all entities or you can create one file for each entity. In your Plugin/Callout:

1.   Put a lock on file.

2.   Read the file and read the number there.

3.   Update the number by adding 1.

4.   Release the lock.

5.   Use this number and set your target entity attribute appropriately.

string ProjectAutoNumber = “FilePath”

lock(this)

{

                                       

TextReader textReader = File.OpenText(ProjectAutoNumber);

AutoNumber = textReader.ReadLine();

textReader.Close();

AutoNumber = (long.Parse(AutoNumber) + 1).ToString();

TextWriter textWriter = File.CreateText(ProjectAutoNumber);

textWriter.WriteLine(AutoNumber);

textWriter.Close();

}

 

Issues:

1.   Resource locking

2.   File system Read/write cost

Although all these options work well but I am still looking for some more robust solution. Ideally I am looking for something like GUID. GUID’s are instantly available and 100% unique.

For your suggestions and improvements, please comment.

Posted in CRM Development, MSCRM General | Tagged: , , , | 11 Comments »

Proximity Search in MapPoint – Drawing Microsoft Dynamics CRM data on Maps

Posted by Ayaz Ahmad [MVP - MSCRM] on February 14, 2008

Proximity Search allows you to find businesses located around a reference point you provide. For example, hotels or restaurants can provide the nearest location of all automatic teller machines (ATMs). Or a manufacturing company can list all gas stations within a short drive from a supply center. Or a retail outlet can allow website visitors to search for stores that are open early or stores that handle return items. Or you can locate your potential customers nearby an existing customer.

Proximity Searches can be utilized in MSCRM to get maximum benefit of customer data. For example, you can draw your potential customers nearby an existing customer so that you can analyze and refer your potential leads and opportunities to existing customer to get maximum business benefits. In below section, I will demonstrate the idea by showing code snippets and pictures.

The FindServiceSoap.FindNearby method is a powerful feature of the MapPoint Web Service SOAP API. Using the FindNearby method, you can add the power of proximity searching to your Web site or solution. You can perform proximity searches on regularly-updated commercial data, such as Yellow Pages listings, which are included with a MapPoint Web Service subscription. Additionally, you can upload custom data and use FindNearby in custom store-locator and brand-finder applications.
For further information on how to use this method, please refer MSDN article at http://msdn2.microsoft.com/en-us/library/ms980179.aspx.

Here are the possible steps to follow in order to draw the above example.

steps.jpg

Following code snippets will help you in understanding different steps involved in calling FindNearBy method.

Get Longitude and Latitude for Existing Customer using Find Service

//Find Address Longitude and latitude
FindServiceSoap FindService = new FindServiceSoap ();
FindService.Credentials = new NetworkCredential(”", “”);
FindService.PreAuthenticate = true; FindAddressSpecification spec = new FindAddressSpecification();
spec.InputAddress = new Address();
spec.InputAddress.AddressLine = mAddress.Line1;
spec.InputAddress.CountryRegion = mAddress.Country;
spec.InputAddress.Subdivision = mAddress.StateProvince;
spec.InputAddress.PrimaryCity = mAddress.City;
spec.InputAddress.PostalCode = mAddress.Postalcode; 
spec.DataSourceName = “MapPoint.NA”;
FindResults results = FindService.FindAddress(spec);


Specifying Search Distance and Longitude and Latitude of Origin point and custom Database from where to search for nearby points

FindNearbySpecification myFindSpec = new FindNearbySpecification();//Specify the data source.
myFindSpec.DataSourceName = “Mappoint.InstallerAccounts”; 
//Specify the latitude and longitude.
myLatLong.Latitude = 47.63873;
myLatLong.Longitude = -122.131;
myFindSpec.LatLong = myLatLong; 
//Specify the distance.
myFindSpec.Distance = 10;


Limit the number of records returned by specifying the Range property

//Set the Range property.
myRange.StartIndex = 0;
myRange.Count = 10;
myFindOptions.Range = myRange; 
myFindSpec.Options = myFindOptions;


Return only the Properties you are interested in otherwise it will return all the properties from your custom database uploaded in MapPoint

//Return only the properties that we’re interested in.
myPropertyNames[0] = “Name”;
myPropertyNames[1] = “AddressLine”;
myPropertyNames[2] = “PrimaryCity”;
myPropertyNames[3] = “RelationshipType”;
myPropertyNames[4] = “longitude/latitude”; 
myFindFilter.PropertyNames = myPropertyNames; 
myFindSpec.Filter = myFindFilter;


Specify Filter Expressions to return desired data depending on the entity properties

//Specify the text of the Expression.
string myText = “(RlationshipType = {0}  AND ” +“Rating >  {1} “;
myFilterExpression.Text = myText; 
//Set the paramater values to match the placeholders
//in the Text
string.
object[] myParameters = new object[2];
string myFirstParameter = “Installers”;
myParameters[0] = myFirstParameter;
int mySecondParameter = 25;
myParameters[1] = mySecondParameter;
myFilterExpression.Parameters = myParameters;
myFindFilter.Expression = myFilterExpression;
myFindSpec.Filter = myFindFilter;
 Perform Proximity Search using FindNearby Method
myFindResults = myFindService.FindNearby(myFindSpec);


Find result contains potential customers who reside nearby the existing customer. This also specifies their longitude and latitude data. Now you can simple follow my previous post regarding MSCRM integration with MapPoint to draw these potential customers and existing customer to Map.
http://ayazahmad.wordpress.com/2007/06/12/mscrm-and-mappoint-integration-a-picture-is-worth-a-thousand-words/

Possible MapPoint Integrations with Microsoft Dynamics CRM1.       Store locators
2.       Branch Finders
3.       Drawing Customers to analyze Customers
4.       Lead/Opportunity Analysis per Region
5.       Driving Directions
6.       Order Tracking/shipment Tracking
7.       Finding Points of Interests in a specific route  

Posted in CRM Development, CRM Integrations | 2 Comments »

Generate Excel 2007 Sheets from MSCRM Data – OpenXML Show

Posted by Ayaz Ahmad [MVP - MSCRM] on August 23, 2007

Office Open XML is an XML-based file format specification for electronic documents such as memos, reports, books, spreadsheets, charts, presentations and word processing documents. The specification has been developed by Microsoft as a successor of its binary office file formats and was published by Ecma International as the Ecma 376 standard in December 2006. The format specification is available for free at Ecma International. 

Let me introduce you the technique I have used to generate the Excel 2007 sheet from CRM data. I have downloaded an Excel package. ExcelPackage provides server-side generation of Excel 2007 spreadsheets. See http://www.codeplex.com/ExcelPackage for details. 

Specifying Output Directory and Template Directory

 Output directory is where you place the generated excel file and Template  directory is where you place the template file. Template file is simply a .xlsx file without data. Use following code to specify both directories. 

DirectoryInfo outputDir = new DirectoryInfo(@”\GenerateExcel\output”);
DirectoryInfo templateDir = new DirectoryInfo(@”\GenerateExcel\templates”); 
FileInfo newFile = new FileInfo(outputDir.FullName + @”\File-” + strRecordID + “.xlsx”);
FileInfo template = new FileInfo(templateDir.FullName + @”\TempReport.xlsx”);
if (!template.Exists)         
throw new Exception(”Template file does not exist! i.e. template.xlsx”);
 

Write data to Excel File 

ExcelPackage contains library functions for accessing worksheet, cells etc. For details please have a look into the Excel package code. Uses following code to write data to individual cell in excel worksheet. 

using (ExcelPackage xlPackage = new ExcelPackage(newFile, template))     

{           
try
           
{
               
 
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets["Sheet1"];
               
if (worksheet != null)
               
{
                   
worksheet.Cell(2, 9).Value = ClearText(strData);                   
                   
xlPackage.Save();
               
}
           
}
           
catch (Exception ex)
           
{
            }         
}
 

Adding Rows to Sheet          

worksheet.InsertRow(iRow); 

Return Excel File for Download 

Simply redirect the response object in ASP.NET to the excel file generated. 

Response.Redirect(”http://” + Request.Url.Host + “:” + Request.Url.Port + “/” + “GenerateExcel/output/” + newFile.Name); 

All cell styles, formates and pictures objects that you set once in Template will remain the same in the generated file. 

Please find below my sample quote geneation application. I have placed a button at Quotes toolbar named Generate Quote. It will generate quote report in excel 2007 with the Quote data from crm currently selected.

 pic1.jpg 

My program fetches data from MSCRM through web services and populated my Excel sheet. It then returns my generated excel sheet with options to open or download.

pic2.jpg

Posted in CRM Integrations | Tagged: , | 13 Comments »

MSCRM and MapPoint Integration - A picture is worth a thousand words.

Posted by Ayaz Ahmad [MVP - MSCRM] on June 12, 2007

Microsoft Provides MapPoint Web Service to enrich application with mapping functionality. It allows you to integrate maps, driving directions, order tracking and proximity searches into a wide range of solutions.

For those of you who want to start using MapPoint for test and development purposes you can sign up for a free developer account here:

htt
ps://mappoint-css.partners.extranet.microsoft.com/MwsSignup/Eval.aspx

With a developer account, you get full access to the MapPoint Web Service APIs and staging environment, which you can use to build applications for trial, demonstration, and proof-of-concept purposes.

Overview

Overview

Microsoft Dynamics CRM Account entity already has longitude and latitude parameters for address. But mostly organizations don’t use those parameters. MapPoint web service provides FindAddress service to resolve addresses and returns longitude and latitude parameter as shown in the code snippet below. 


Find Address Longitude and Latitude FindServiceSoap FindService = new FindServiceSoap ();
FindService.Credentials = new NetworkCredential(”", “”);
FindService.PreAuthenticate = true;
MyAddress mAddress = new MyAddress();

mAddress = (MyAddress)addresses[i];

FindAddressSpecification spec = new FindAddressSpecification();
spec.InputAddress = new Address();
spec.InputAddress.AddressLine = mAddress.Line1;
spec.InputAddress.CountryRegion = mAddress.Country;
spec.InputAddress.Subdivision = mAddress.StateProvince;
spec.InputAddress.PrimaryCity = mAddress.City;
spec.InputAddress.PostalCode = mAddress.Postalcode;
spec.DataSourceName = “MapPoint.NA”;
FindResults results = FindService.FindAddress(spec);

Populating Location and Pushpin Array 

Location and pushpins objects require longitude and latitude values for address. Following code is used to populate Location and Pushpin objects of MapPoint API. 


Location[] myLocation = new Location[addresses.Count];
myLocation[i] = new Location();
myLocation[i].LatLong = new LatLong();
myLocation[i].LatLong = results.Results[0].FoundLocation.LatLong;
Pushpin[] pushpins = new Pushpin [addresses.Count]; pushpins[i] = new Pushpin();
pushpins[i].PinID = “pin0″;
pushpins[i].IconName = “0″;
pushpins[i].Label = mAddress.Name;
pushpins[i].IconDataSource = “MapPoint.Icons”;
pushpins[i].LatLong = results.Results[0].FoundLocation.LatLong;
There is no simple way to provide hyperlink at Pushpins, although Pushpin label and icon can be set to custom settings. Getting image and automatic zoom based on the geography covered by the addresses

MapPoint Web Service provides Render Service API to automatic zoom based on the geography covered by addresses. Here is the code snippet to do this:

//Call MapPoint Render Web Service RenderServiceSoap RenderService = new RenderServiceSoap();
RenderService.Credentials = new NetworkCredential(”", “”);
MapViewRepresentations mvRep = RenderService.GetBestMapView(myLocation,”MapPoint.NA”);
mviews[0] = new ViewByBoundingRectangle();
mviews[0] = mvRep.ByBoundingRectangle;
MapSpecification mspec = new MapSpecification();
mspec.Options = moptions;
mspec.Views = mviews;
mspec.Pushpins = pushpins;
mspec.DataSourceName = “MapPoint.NA”;

MapImage[] image = RenderService.GetMap(mspec);

So the final image can be displayed in some ASP.NET page to show in Microsoft Dynamics CRM. Please find below my integration of MapPoint web service with MSCRM. One can select Accounts to be plotted on MapPoint and click Show Accounts Map Button at Account Entity grid toolbar.  All selected accounts will be plotted on the MapPoint in a new web dialog with Invalid addresses at the bottom.  

Step 1 


 Here is the final Image generated in Web Dialog:
Step 2 For any comments or suggestion do let me know. Your suggestions and comments are valuable for me. Thanks!

Posted in CRM Deployement, CRM Development, CRM Integrations, MSCRM General | Tagged: , , | 11 Comments »

MS CRM and SharePoint 2007 Integration

Posted by Ayaz Ahmad [MVP - MSCRM] on May 8, 2007

Here is a very nice article by one of my colleagues,  Rehman Gul, on MS CRM and MOSS 2007 integration. I thought to share this with all of you….you can also find the article on his blog @ http://rehmangul.wordpress.com/2007/05/08/ms-crm-and-sharepoint-2007-integration/ 

SharePoint 2007 provides integration with quite a few Microsoft products including Dynamics, SQL Server Reporting Services, PerformancePoint, etc. Today, we will specifically talk about SharePoint’s integration with MS CRM. Here is the press release from Microsoft announcing the ability of SharePoint to provide tight integration with MS CRM environment: 

http://www.microsoft.com/presspass/press/2007/mar07/03-12Day1DynamicsOfficePR.mspx

Lets have a walkthrough of how can we connect with MS CRM using SharePoint’s Business Data Catalog (BDC) and Web Parts.

First of all we need an XML definition file to connect with CRM Database. Writing these files is difficult and error prone. You can easily find tools over the internet that will provide you with the ability to create Application Definitions for MOSS 2007. One such tool could be found here.

Here is the file I am going to use for the purpose of this exercise. This sample metadata XML defines various entities for MS CRM 3.0 database. If you have downloaded Dynamics Snap-ins, you can get one such file already present on your disk. If you intend to use the file that I am using, remember to change the Server and Database Names in it. They have been marked within the file…changes are required at the line 27 and 29.First of all we need to import this definition file to MOSS (Microsoft Office SharePoint Server) 2007.

Go to central Administration. It is usually created at the port 12779. The Url should look something like this:

 

 http://moss:12779/default.aspx  

untitledb.jpg

On the left Navigation Column click “SharedServices1” link. If its not there, you can create one clicking “Shared Services Administration” link on the left navigation column. “SharedServices1” site should look like this:

untitled1b.jpg

Under “Business Data Catalog” click “Import application definition”. Following screen appears:

untitled2b.jpg

Browse and select the definition file from your disk. Keep the default settings and click “Import”. This will initiate the upload process and take some time.

untitled3b.jpg 

After the file has been uploaded you can view the file clicking “View applications” under “Business Data Catalog”.

untitled4b.jpg

Now go to the site where you want to provide CRM connectivity. Click “ Site Actions” and “Edit Page”.

untitled5b1.jpg

Click “Add a Web Part”.

untitled6b1.jpg

From the list select “Business Data List” web part and click “Add”.

untitled7b.jpg

Click “open the tool pane” link in the “Business Data List” web part.

untitled8b.jpg

Click “Browse” icon right next to the “Type” text box displayed on the right top.

untitled9b.jpg

Select any “Business Data Type” and click “Ok”. 

untitled10b.jpg

Click “Ok” at the bottom of the options displayed in the right column. 

untitled12b.jpg Here is what you should see:

untitled13b.jpg
Just add the value in the empty text box that you want to fetch from the CRM Database and click “Retrieve Data”. You are connected to MS CRM through your MOSS 2007.Hope you enjoyed this post….I’ll continue on SharePoint’s integration with other Microsoft Products….hope to see you again….it’s bye for now…… :)

Posted in CRM Deployement, CRM Development, CRM Integrations | Tagged: , , | 8 Comments »

VPC Development Environment for Microsoft Dynamics CRM 3.0 Projects

Posted by Ayaz Ahmad [MVP - MSCRM] on May 4, 2007

After collapse of my QA server, I have been searching for various developments environment options for Microsoft Dynamics CRM 3.0 projects. As per my findings and discussion with other peer developers, most of them are using Virtual PC images for their development tasks. This is also recommended by Microsoft and a download at Microsoft website regarding VPC image is also available.  This will benefit in various ways: 

  1. Developers will not be dependant on other developers in performing their Customization tasks at the same time. In this way overlapping of customizations done by developers can refrained.
  2. In case of multiple clients, it’s the ideal option as we are not going to setup our QA server and Development Server for every client.
  3. Building new test environment will be a Zero copy deployment.
  4. One has the options to cut down Development Server cost by just adding more RAM to developer PCs.
  5. One can test various components developed by other vendors with no impact over our QA server and Development server.
  6. One can test various integration scenarios with no impact over QA and Development Server.
  7. Maintaining Microsoft Dynamics CRM server would be just as easy as importing and exporting Customizations to fresh VPC image.

If you have any issues regarding VPC please do comment. Thanks!

Posted in CRM Deployement, MSCRM General | Tagged: , | 7 Comments »

Setting Default View for Account Activities???

Posted by Ayaz Ahmad [MVP - MSCRM] on April 23, 2007

 I have been searching a lot in Newsgroups and forums to find this issue. Issue is “How can I set the default view when I open certain Account Activities”. The default view set is “Next 30 Days” as given in the picture below. I want to set this to “All Activities”. I am looking for any supported and unsupported way of doing this task. I have been told my some MSCRM experts that it is a common issue and I will not be able to set this as this is all set by managed code.