The Price List field is an interesting field in that it is a field has script that fires from it but you cannot see it from the form editor where you place your own scripts. I recently tried removing this field from an Opportunity and the Account form. The Account didn't show any repercussions but the Opportunity wouldn't allow me to add an Opportunity Product to the Opportunity.
With the Price List field missing I just got this random non-descript scripting error. When I added the field back and tried to add an Opportunity Product I received the error I expected of having no Price List set. The problem now became that when I tried to select a Price List for the Opportunity I couldn't see any Price Lists to choose from. Basically the script that was running and populating the filtered list of Price Lists had been removed when I removed the field from the form and it doesn't come back when I put it back onto the form.
The question now became how do I fix it? How do I get that script back. I have to give credit to Nahi for his post in the Microsoft.Crm.Public group who ran into this issue and posted the solution he found. He didn't go into the details, he just went over the process. I'm going to try and give you a little bit more.
Basically the idea was, grab the script from another entity or another system where the Price List had not been removed. The way to do that is to export the Opportunity and look through the entity XML for the missing script. Then copy and paste the script XML into the entity XML of the entity that had the Price List field removed from it. Save changes and reimport it back into CRM, publish and you're set. It worked great for me and I now no longer have any issues with the Opportunity, Price List or adding Opportunity Products.
The best way to find the script from the clean entity XML is to search for "Price List" and then look through to where you see the script next to one of your finds for "Price List". Here's the XML block that I found and added (it should go between the LABEL and CONTROL tags):
<events>
<event name="setadditionalparams" application="true" active="true">
<script>
<![CDATA[
var oLookup = event.srcElement;
AddTransactionCurrencyParam(oLookup);]]>
</script>
<dependencies>
<dependency id="transactioncurrencyid" />
</dependencies>
</event>
</events>
Hope this helps someone else out.
David Fronk
Dynamic Methods Inc.
Friday, March 28, 2008
Friday, March 21, 2008
CRM Document Management...the low budget way
For those of you who work in the small to medium business industry, keeping tabs on budget is key, and typically (though not always) you are asked to do deliver a hot rod on a moped budget, and/or you have to deliver in half the time you would like to spend to make the solution really solid.
When this is the case for my clients I do my best to give them something usable that may or may not do 100% of everything they requested but will get them by until they are ready to spend the time and money on the complete solution.
When implementing MSCRM, document management is one of the topics where "baby steps" are necessary. I am a fan of SharePoint for document management, most of my clients are as well. However, as soon as they see that rolling out SharePoint is a whole other implementation, with software, licenses, server, installation, design, training, etc, I find out that they aren't as big of fans as was originally thought. From a solution implementators' perspective, that's totally fine. The goal that I then have is to help get them ready for the complete solution, just when they as a company feel ready to make the jump.
In the mean time, the company still needs to have some kind of document management and of course they want it either directly inside of MSCRM or to integrate with it. Here are my "low budget solutions" for document management.
1. Use and FTP site
2. Use a file server, or a shared folder on a server with a sufficient amount of disc space
Now, remember this is "low budget" so that means that there will be a number of manual steps but keeping those to a minimum will go a long way. Also, these are work-arounds, not full solutions, so there will be limitations to each solution. These solutions are very similar upon implementation, it's just a matter of where the data is stored.
Using an FTP site will allow users to store files while local or remote to the network, whether the FTP site is hosted by the company or someone else will dependent on the needs are desires of the company you are implementing the solution for. You can then embed the FTP site in an IFRAME on a specific form or put a link on the left NavBar, or give them a button that will open it in a new window. However, opening to the main page of an FTP site (whether they have to log in or not is entirely up to you) then makes the users have to click more in order to drill down to the level at which he/she wants to store a given document. Here's the customization that can go a long way.
I did this as a button but the concept is the same for a NavBar item as well. Using an IFRAME is a bit different, but I'll go over an IFRAME solution shortly.
In the isv.config.xml document on the CRM server add a button to the desired form similar to the following XML:
<Button Title="FTP" ToolTip="View product images stored on FTP site" Icon="/_imgs/ico_18_debug.gif" JavaScript="window.open('ftp://fptserver/Clients/' + crmForm.all.name.DataValue + '/')" PassParams="0" WinParams="" WinMode="0" />
Using this code will require that the folder structure on the FTP site is maintained so that there is a folder for each client under a Client folder but users are now able to get to shared documents for a given client (or opportunity, product, project, etc) with a single click. For the end users, this is fantastic. For the admin to administrate this may not be as fun however. But through custom code one could maintain the folder structure if necessary. Again it depends on budget and timing.
Also, take note that you will need to use the JavaScript attribute because the Url attribute expects an HTTP link. Lastly, note that it will be absolutely necessary for you to put the "ftp://" full URL in the code, otherwise the link will be assumed to be HTTP.
Now, for a shared directory. The limitation here is that users have to be local, or on a VPN in order to access it. If that isn't that big of a deal to the client then this can be great solution for end users.
First, on the entity you are using, add an plain text attribute called "Shared Folder". Place it where you want on the form (I suggest a tab solely dedicated to file sharing, but to each his own). Then create an IFRAME. Name it FileShare (or whatever you want), allow for cross frame scripting, hide the display name, etc. Set the URL to be "about:blank".
Now add script to the onLoad of the form. Add the following:
if(crmForm.all.new_sharedfolder.DataValue != null && crmForm.all.new_sharedfolder.DataValue != "")
{
document.all.IFRAME_FileShare.src = crmForm.all.new_sharedfolder.DataValue;
}
else
{
document.all.IFRAME_FileShare.src = "about:blank";
}
Then all users have to do is type in the UNC path, or directory path to the directory desired. This could be scripted upon the creation of a form for a static path with a dynamic name at the end, much like the FTP example from above, but again remember that the folder structure will need to be maintained one way or another.
Examples:
UNC: \\fileservername\Clients
Directory path: Z:\Clients
If you use the directory path option then you will have to make sure that the drive is mapped correctly on the user's machine, otherwise it will break. Otherwise UNC works every time (as long as the computer is on the network).
There isn't any auto version control but it gives the users a place to store documents "inside" MSCRM in a form that they are used to and comfortable with. Once they out grow this then it's time to move onto a real document management solution. But until then, happy "low budget" coding!
David Fronk
Dynamic Methods Inc.
When this is the case for my clients I do my best to give them something usable that may or may not do 100% of everything they requested but will get them by until they are ready to spend the time and money on the complete solution.
When implementing MSCRM, document management is one of the topics where "baby steps" are necessary. I am a fan of SharePoint for document management, most of my clients are as well. However, as soon as they see that rolling out SharePoint is a whole other implementation, with software, licenses, server, installation, design, training, etc, I find out that they aren't as big of fans as was originally thought. From a solution implementators' perspective, that's totally fine. The goal that I then have is to help get them ready for the complete solution, just when they as a company feel ready to make the jump.
In the mean time, the company still needs to have some kind of document management and of course they want it either directly inside of MSCRM or to integrate with it. Here are my "low budget solutions" for document management.
1. Use and FTP site
2. Use a file server, or a shared folder on a server with a sufficient amount of disc space
Now, remember this is "low budget" so that means that there will be a number of manual steps but keeping those to a minimum will go a long way. Also, these are work-arounds, not full solutions, so there will be limitations to each solution. These solutions are very similar upon implementation, it's just a matter of where the data is stored.
Using an FTP site will allow users to store files while local or remote to the network, whether the FTP site is hosted by the company or someone else will dependent on the needs are desires of the company you are implementing the solution for. You can then embed the FTP site in an IFRAME on a specific form or put a link on the left NavBar, or give them a button that will open it in a new window. However, opening to the main page of an FTP site (whether they have to log in or not is entirely up to you) then makes the users have to click more in order to drill down to the level at which he/she wants to store a given document. Here's the customization that can go a long way.
I did this as a button but the concept is the same for a NavBar item as well. Using an IFRAME is a bit different, but I'll go over an IFRAME solution shortly.
In the isv.config.xml document on the CRM server add a button to the desired form similar to the following XML:
<Button Title="FTP" ToolTip="View product images stored on FTP site" Icon="/_imgs/ico_18_debug.gif" JavaScript="window.open('ftp://fptserver/Clients/' + crmForm.all.name.DataValue + '/')" PassParams="0" WinParams="" WinMode="0" />
Using this code will require that the folder structure on the FTP site is maintained so that there is a folder for each client under a Client folder but users are now able to get to shared documents for a given client (or opportunity, product, project, etc) with a single click. For the end users, this is fantastic. For the admin to administrate this may not be as fun however. But through custom code one could maintain the folder structure if necessary. Again it depends on budget and timing.
Also, take note that you will need to use the JavaScript attribute because the Url attribute expects an HTTP link. Lastly, note that it will be absolutely necessary for you to put the "ftp://" full URL in the code, otherwise the link will be assumed to be HTTP.
Now, for a shared directory. The limitation here is that users have to be local, or on a VPN in order to access it. If that isn't that big of a deal to the client then this can be great solution for end users.
First, on the entity you are using, add an plain text attribute called "Shared Folder". Place it where you want on the form (I suggest a tab solely dedicated to file sharing, but to each his own). Then create an IFRAME. Name it FileShare (or whatever you want), allow for cross frame scripting, hide the display name, etc. Set the URL to be "about:blank".
Now add script to the onLoad of the form. Add the following:
if(crmForm.all.new_sharedfolder.DataValue != null && crmForm.all.new_sharedfolder.DataValue != "")
{
document.all.IFRAME_FileShare.src = crmForm.all.new_sharedfolder.DataValue;
}
else
{
document.all.IFRAME_FileShare.src = "about:blank";
}
Then all users have to do is type in the UNC path, or directory path to the directory desired. This could be scripted upon the creation of a form for a static path with a dynamic name at the end, much like the FTP example from above, but again remember that the folder structure will need to be maintained one way or another.
Examples:
UNC: \\fileservername\Clients
Directory path: Z:\Clients
If you use the directory path option then you will have to make sure that the drive is mapped correctly on the user's machine, otherwise it will break. Otherwise UNC works every time (as long as the computer is on the network).
There isn't any auto version control but it gives the users a place to store documents "inside" MSCRM in a form that they are used to and comfortable with. Once they out grow this then it's time to move onto a real document management solution. But until then, happy "low budget" coding!
David Fronk
Dynamic Methods Inc.
Saturday, March 15, 2008
Allowing QuickFind to search Inactive records
In Microsoft CRM v3.0 there were certain entities that were allowed to search inactive records through the QuickFind/QuickSearch feature (the "Look For" query at the top of each main entity listing). Rollup 2 changed some of those entities that were capable of searching inactive records and now CRM v4.0 has made is so that the QuickFind/QuickSearch does not look for inactive records at all in any entities (at least in my testing, this is what I have found, if someone has found otherwise please let me know). Now, I won't say that I want this capability for every entity in the system but sometimes it might be nice. For instance, Cases has been an entity that has been requested that be allowed to search both active and inactive records.
What would be nice would be if there were some option that users could choose or set in their preferences, or even at the entity level, to allow or disallow the ability to search both active and inactive records. Something ask for in v5.0.
But until then there is hope. Depending on what version of CRM you are on depends on the solution you can implement.
CRM v3.0 involves modifying entity XML. CRM v4.0 requires a Plugin be written on the PreRetrieve method.
Today I'm going to talk about the CRM v3.0 modification. Technically this customization will work in CRM v4.0 as well, but let me be very clear when I state, THIS IS AN UNSUPPORTED CUSTOMIZATION. I cannot gaurantee that this will will break your upgrade or not, though I am very inclined to say that it will. Also, any repair or update could potentially undo your change as this customization requires you to modify the actual entity XML. So, if a patch or rollup doesn't include the entity XML then you should be pretty safe.
Steps:
1. Export the entity XML of the entity you wish to modify.
2. Copy your XML export file so that you have a backup to roll back to in case something goes wrong.
3. Open the XML file in your editor of choice and search for "Quick Find".
a. NOTE - don't let the XML fool you, it puts the name at the bottom of the "SavedQuery" XML chain, what you will be modifying should be above the name tag.
4. Remove the following filter from the Quick Find saved query:
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
</filter>
5. Locate the "iscustomizable" tag and change the "name" attribute to say "Yes" instead of "No".
6. Save your modified XML file
7. Upload your modified XML file into CRM
8. Publish Customizations
9. Refresh your page and test
That's it. Personally I think is a pretty safe "unsupported" customization because the worst that will happen in a repair or upgrade is the entity XML will get replaced. The customization is pretty localized to the Quick Find. If you modify other pieces of the entity XML you're on your own.
Good luck!
David Fronk
Dynamic Methods Inc.
What would be nice would be if there were some option that users could choose or set in their preferences, or even at the entity level, to allow or disallow the ability to search both active and inactive records. Something ask for in v5.0.
But until then there is hope. Depending on what version of CRM you are on depends on the solution you can implement.
CRM v3.0 involves modifying entity XML. CRM v4.0 requires a Plugin be written on the PreRetrieve method.
Today I'm going to talk about the CRM v3.0 modification. Technically this customization will work in CRM v4.0 as well, but let me be very clear when I state, THIS IS AN UNSUPPORTED CUSTOMIZATION. I cannot gaurantee that this will will break your upgrade or not, though I am very inclined to say that it will. Also, any repair or update could potentially undo your change as this customization requires you to modify the actual entity XML. So, if a patch or rollup doesn't include the entity XML then you should be pretty safe.
Steps:
1. Export the entity XML of the entity you wish to modify.
2. Copy your XML export file so that you have a backup to roll back to in case something goes wrong.
3. Open the XML file in your editor of choice and search for "Quick Find".
a. NOTE - don't let the XML fool you, it puts the name at the bottom of the "SavedQuery" XML chain, what you will be modifying should be above the name tag.
4. Remove the following filter from the Quick Find saved query:
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
</filter>
5. Locate the "iscustomizable" tag and change the "name" attribute to say "Yes" instead of "No".
6. Save your modified XML file
7. Upload your modified XML file into CRM
8. Publish Customizations
9. Refresh your page and test
That's it. Personally I think is a pretty safe "unsupported" customization because the worst that will happen in a repair or upgrade is the entity XML will get replaced. The customization is pretty localized to the Quick Find. If you modify other pieces of the entity XML you're on your own.
Good luck!
David Fronk
Dynamic Methods Inc.
Friday, March 07, 2008
Hiding a Section
Hiding a section has been an interesting customization to figure out. I definitely got help by reading through posts and groups, but then again, who doesn't? When hiding things in CRM typically it's done by referencing a specific control name, something like the tab number or the field name. Sections are strange in that they don't have any of the normal "English" identifiers that one would expect. It's actually reference directly through a GUID. Each section gets assigned a GUID upon creation, so writing code that is dynamic for hiding sections directly really wasn't pretty...or possible.
However, if you reference a section indirectly things actually get much easier. For example, everything in the CRM forms are contained within something larger. Fields are contained by Sections, which are contained by Tabs, which are contained by the web form itself. That means that there is a direct parent/child relationship between objects on the form. JScript has thought about this and allows you to reference ParentNode's through code.
With this new knowledge referencing sections actually becomes very easy. All that has to be done is make a reference to a field on the form and then get it's parent node and do what you need to do to it.
Here's the code:
document.getElementById("ownerid").parentNode.parentNode.style.display = "none";
You'll notice that I have to parentNode references, that's not a mistake, this is the progression on how to get to the section. Fields are actually contained by Labels and Labels are contained by Sections on a form. I didn't realize this until I tried using only the first parentNode reference. Play with it a bit and you'll see what I mean.
Then to make the section visible again just use empty quotes:
document.getElementById("ownerid").parentNode.parentNode.style.display = "";
And now you have full control over what to make visible to users upon any condition you want.
Happy coding!
David Fronk
Dynamic Methods Inc.
However, if you reference a section indirectly things actually get much easier. For example, everything in the CRM forms are contained within something larger. Fields are contained by Sections, which are contained by Tabs, which are contained by the web form itself. That means that there is a direct parent/child relationship between objects on the form. JScript has thought about this and allows you to reference ParentNode's through code.
With this new knowledge referencing sections actually becomes very easy. All that has to be done is make a reference to a field on the form and then get it's parent node and do what you need to do to it.
Here's the code:
document.getElementById("ownerid").parentNode.parentNode.style.display = "none";
You'll notice that I have to parentNode references, that's not a mistake, this is the progression on how to get to the section. Fields are actually contained by Labels and Labels are contained by Sections on a form. I didn't realize this until I tried using only the first parentNode reference. Play with it a bit and you'll see what I mean.
Then to make the section visible again just use empty quotes:
document.getElementById("ownerid").parentNode.parentNode.style.display = "";
And now you have full control over what to make visible to users upon any condition you want.
Happy coding!
David Fronk
Dynamic Methods Inc.
Friday, February 22, 2008
Internet Facing Deployment (IFD)
Originally when MSCRM 4.0 came out it appeared that in order to set up a site with an Internet Facing Deployment it could only be done through the install. Meaning, once installed you would have to uninstall and then reinstall in order to get the IFD working.
Microsoft has recently come out with a tool to change any existing site from IFD to regular On-Premise setup. And on top of that they even have a Knowledge Base article that steps you through using the tool and changing your site set up. I know there have been some other blog posts about this but Microsoft just updated their documents on February 15 of this year, so there have been some additions/changes to what was originally put out there.
Here is the link to the Knowledge Base article (the download link for the tool is in the Knowledge Base article):
Microsoft Knowledge Base Article 948779
For more information on how to deploy a site as IFD take a look at this document that Microsoft has posted:
Microsoft Dynamics CRM 4.0 Internet Facing Deployment Scenarios
If you aren't sure what IFD is, or what it does for you or your customers, let me give you my understanding of it as there is minimal documentation on what it is, only documentation on how to set it up. Basically the IFD sets up Forms over Active Directory Authentication to the MSCRM pages externally to your deployment. What does that do for you? Two things:
1. Users logging in externally will now see a sign in page where they don't have to input their domain, just their username and password. This is different from 3.0 in that MSCRM sites that were accessible over the internet would bring up the windows login prompt, requiring your domain and username.
2. It makes is so that you can use your Outlook client without a VPN. The Outlook client will first attempt to connect to the internal site, if it doesn't find it, it will kick over to the external address provided in the configuration wizard. As it tries to connect it will first try Active Directory Authentication, it will tell you that it fails and will attempt to connect using Forms over Active Directory Authentication.
So, I will be deploying IFD pretty much everywhere so that my clients can use their Outlook client without a VPN. I have clients who want to upgrade to MSCRM 4.0 just for that reason alone. So, knowing this and how to set up your MSCRM sites with it will be very important.
Good luck out there!
David Fronk
Dynamic Methods Inc.
Microsoft has recently come out with a tool to change any existing site from IFD to regular On-Premise setup. And on top of that they even have a Knowledge Base article that steps you through using the tool and changing your site set up. I know there have been some other blog posts about this but Microsoft just updated their documents on February 15 of this year, so there have been some additions/changes to what was originally put out there.
Here is the link to the Knowledge Base article (the download link for the tool is in the Knowledge Base article):
Microsoft Knowledge Base Article 948779
For more information on how to deploy a site as IFD take a look at this document that Microsoft has posted:
Microsoft Dynamics CRM 4.0 Internet Facing Deployment Scenarios
If you aren't sure what IFD is, or what it does for you or your customers, let me give you my understanding of it as there is minimal documentation on what it is, only documentation on how to set it up. Basically the IFD sets up Forms over Active Directory Authentication to the MSCRM pages externally to your deployment. What does that do for you? Two things:
1. Users logging in externally will now see a sign in page where they don't have to input their domain, just their username and password. This is different from 3.0 in that MSCRM sites that were accessible over the internet would bring up the windows login prompt, requiring your domain and username.
2. It makes is so that you can use your Outlook client without a VPN. The Outlook client will first attempt to connect to the internal site, if it doesn't find it, it will kick over to the external address provided in the configuration wizard. As it tries to connect it will first try Active Directory Authentication, it will tell you that it fails and will attempt to connect using Forms over Active Directory Authentication.
So, I will be deploying IFD pretty much everywhere so that my clients can use their Outlook client without a VPN. I have clients who want to upgrade to MSCRM 4.0 just for that reason alone. So, knowing this and how to set up your MSCRM sites with it will be very important.
Good luck out there!
David Fronk
Dynamic Methods Inc.
Friday, February 15, 2008
Figuring out the Email Router
I finally feel like I've got a good feeling and understanding of the new CRM email router. Most of understanding came from deploying it multiple times and reading multiple documents. I don't want to go into too much depth because each deployment is a bit different and the document links below will say everything that I would say...only better. However I will say a couple of things that I've learned.
There are a few new settings for users to choose from when setting up your user profile for email.
1. Forward Mailbox - just like 3.0, you need to set up a forwarding rule through the Rule Deployment Wizard.
2. Email Router - the email router looks directly at your mailbox and sucks everything in it up into CRM. So, if you have ten's of thousands of emails, tasks and appointments in your mailbox, you may either want to not choose this option or change your setting to this on Friday at 5pm. I once set multiple people to this setting in a short period of time and CRM came to a griding halt. Make sure your server can handle this kind of intake before you do it and do it in a reasonable deployment schedule
3. Outlook Client - this is what Outlook users should user
The Planning Implementation Guide goes into those definitions a little bit more so if you want to know more about their differences check there. It's not much in that doc but there are a couple of key definitions explained there.
Here are the links that should help you out with better understanding the Email Router:
Microsoft Dynamics CRM 4.0 E-mail Router Readme (On-Premise and Microsoft Dynamics CRM 4.0 Service Provider Editions)
Microsoft Dynamics CRM 4.0: How to configure the on-premise E-mail Router in different deployment scenarios
Microsoft Dynamics CRM 4.0 Implementation Guide
Hope this helps make sense of the new functionality and setup. I know it helped me.
David Fronk
Dynamic Methods Inc.
There are a few new settings for users to choose from when setting up your user profile for email.
1. Forward Mailbox - just like 3.0, you need to set up a forwarding rule through the Rule Deployment Wizard.
2. Email Router - the email router looks directly at your mailbox and sucks everything in it up into CRM. So, if you have ten's of thousands of emails, tasks and appointments in your mailbox, you may either want to not choose this option or change your setting to this on Friday at 5pm. I once set multiple people to this setting in a short period of time and CRM came to a griding halt. Make sure your server can handle this kind of intake before you do it and do it in a reasonable deployment schedule
3. Outlook Client - this is what Outlook users should user
The Planning Implementation Guide goes into those definitions a little bit more so if you want to know more about their differences check there. It's not much in that doc but there are a couple of key definitions explained there.
Here are the links that should help you out with better understanding the Email Router:
Microsoft Dynamics CRM 4.0 E-mail Router Readme (On-Premise and Microsoft Dynamics CRM 4.0 Service Provider Editions)
Microsoft Dynamics CRM 4.0: How to configure the on-premise E-mail Router in different deployment scenarios
Microsoft Dynamics CRM 4.0 Implementation Guide
Hope this helps make sense of the new functionality and setup. I know it helped me.
David Fronk
Dynamic Methods Inc.
Friday, February 08, 2008
Creating Saved Views that Advanced Find can't handle
Advanced Find is a fantastic tool. I train and train all of my end users on it as much as possible in the hopes that they will see the potential they have at their finger tips. You can always tell who is really getting it and who isn't too based on the questions they ask. Unfortunately some of the hardest questions to answer are the ones that are for the coolest queries. For instance, I've had users ask for a list of all Vendor's (custom entity) that don't have an activity associated to them in the last X number of months. This requires Advanced Find to query data that isn't there. Unfortunately this is the one major limitation of Advanced Find. It can only query existing data.
Don't lose hope yet though. Microsoft has provided some views for users like this out of the box. If you have ever seen the out of the box view for Accounts titled "Account: No Orders Last 6 Months" you'll notice that you cannot see nor create that query in Advanced Find. That's because the query is checking against data that isn't there, it's actually looking for null values. So, if Advanced Find can't do it then how did it get in there?
SavedQueries is the response that I give you. The SDK goes over them and explains them as giving you the ability to create your own saved queries that users will be able to use as views. There isn't much code on them in the SDK. I suppose that's because "technically" you can create a SavedQuery in 12 lines of code. The complex part about making a SavedQuery is figuring out the query to pull the data you want. I'll go over creating a SavedQuery and leave the data query to your own design.
The reason I say that you can "technically" create a SavedQuery in 12 lines of code is because that's how many lines you need to fill the SavedQuery object and then call the CreateRequest/Response methods to actually create the view. However, that assumes that you already have some query done and coded that you can pass into the SavedQuery. Allow me to explain a bit more with some code.
First off you need to create a new savedquery object:
savedquery sq = new savedquery();
Simple enough. Now, let's fill it's properties so that we can create it.
sq.name = "Name of View that will be seen by users";
sq.querytype = new CrmNumber();
//All custom SavedQueries must have a value of 0 (zero) for QueryType according to the SDK
sq.querytype.Value = 0;
//ReturnedTypeCode is the name not the objecttypecode
sq.returnedtypecode = EntityName.<entityName>.ToString();
Now, the last and most crucial part of the SavedQuery, the actual data query:
sq.fetchxml = queried.FetchXml;
Strangely enough the SavedQuery takes FetchXml...I thought that was out the door in MSCRM v3.0 but for some reason it is carried over even into MSCRM v4.0. Oh well, it is what it is. When I first saw this I thought I was going to have to pull out my MSCRM v1.2 SDK to remember how to build FetchXml that MSCRM will accept.
Luckily, however, I found two methods that saved me TONS of time:
QueryExpressionToFetchXml
FetchXmlToQueryExpression
Look those up in the SDK for code examples. But the short of the long is that once you have your RetrieveMultiple query all dialed in you just pass your query into the QueryExpressionToFetchXml method and it converts it for you. That's how I got my "queried.FetchXml" bit of code.
Once I had that all that was needed was to actually create it. And to do that I just follow the typical TargetCreate methodology. Then run the code and you'll see a new view in the object that you wrote your code for. You can then edit the sorting and columns but you'll notice that you cannot edit the filter, just like the "Accounts: No Orders Last 6 Months".
So, the great news is that essentially, if you can write it in SQL, you can write it in C# (or VB if that's what you like). And if you can write it in C#/VB then you can give the view to users in MSCRM. SQL's really a really powerful query tool, heck that's why it's Structure Query Language! So, saying that if you can do it in SQL means you can get it into MSCRM is a BIG deal for showing useful data/info/trends to users. Your other option is SRS, or some other fully custom web page. SRS is just a static list that isn't as easy to make the report able to have actions (update records) performed against it. And a totally custom web page will work as well, it's just typically a lot longer to turn around the dev and actual use of the page because there is now more things to build than just the query that was requested.
Have fun with this...I know I have been and remember, when in doubt, use that SDK, it's probably got something you haven't thought the system could do.
Happy coding!
David Fronk
Dynamic Methods Inc.
Don't lose hope yet though. Microsoft has provided some views for users like this out of the box. If you have ever seen the out of the box view for Accounts titled "Account: No Orders Last 6 Months" you'll notice that you cannot see nor create that query in Advanced Find. That's because the query is checking against data that isn't there, it's actually looking for null values. So, if Advanced Find can't do it then how did it get in there?
SavedQueries is the response that I give you. The SDK goes over them and explains them as giving you the ability to create your own saved queries that users will be able to use as views. There isn't much code on them in the SDK. I suppose that's because "technically" you can create a SavedQuery in 12 lines of code. The complex part about making a SavedQuery is figuring out the query to pull the data you want. I'll go over creating a SavedQuery and leave the data query to your own design.
The reason I say that you can "technically" create a SavedQuery in 12 lines of code is because that's how many lines you need to fill the SavedQuery object and then call the CreateRequest/Response methods to actually create the view. However, that assumes that you already have some query done and coded that you can pass into the SavedQuery. Allow me to explain a bit more with some code.
First off you need to create a new savedquery object:
savedquery sq = new savedquery();
Simple enough. Now, let's fill it's properties so that we can create it.
sq.name = "Name of View that will be seen by users";
sq.querytype = new CrmNumber();
//All custom SavedQueries must have a value of 0 (zero) for QueryType according to the SDK
sq.querytype.Value = 0;
//ReturnedTypeCode is the name not the objecttypecode
sq.returnedtypecode = EntityName.<entityName>.ToString();
Now, the last and most crucial part of the SavedQuery, the actual data query:
sq.fetchxml = queried.FetchXml;
Strangely enough the SavedQuery takes FetchXml...I thought that was out the door in MSCRM v3.0 but for some reason it is carried over even into MSCRM v4.0. Oh well, it is what it is. When I first saw this I thought I was going to have to pull out my MSCRM v1.2 SDK to remember how to build FetchXml that MSCRM will accept.
Luckily, however, I found two methods that saved me TONS of time:
QueryExpressionToFetchXml
FetchXmlToQueryExpression
Look those up in the SDK for code examples. But the short of the long is that once you have your RetrieveMultiple query all dialed in you just pass your query into the QueryExpressionToFetchXml method and it converts it for you. That's how I got my "queried.FetchXml" bit of code.
Once I had that all that was needed was to actually create it. And to do that I just follow the typical TargetCreate methodology. Then run the code and you'll see a new view in the object that you wrote your code for. You can then edit the sorting and columns but you'll notice that you cannot edit the filter, just like the "Accounts: No Orders Last 6 Months".
So, the great news is that essentially, if you can write it in SQL, you can write it in C# (or VB if that's what you like). And if you can write it in C#/VB then you can give the view to users in MSCRM. SQL's really a really powerful query tool, heck that's why it's Structure Query Language! So, saying that if you can do it in SQL means you can get it into MSCRM is a BIG deal for showing useful data/info/trends to users. Your other option is SRS, or some other fully custom web page. SRS is just a static list that isn't as easy to make the report able to have actions (update records) performed against it. And a totally custom web page will work as well, it's just typically a lot longer to turn around the dev and actual use of the page because there is now more things to build than just the query that was requested.
Have fun with this...I know I have been and remember, when in doubt, use that SDK, it's probably got something you haven't thought the system could do.
Happy coding!
David Fronk
Dynamic Methods Inc.
Subscribe to:
Posts (Atom)