CRM Reporting Tips And Hints – II. CRMAF binding not working
There is an automated way of binding the current record context to reports in CRM using “magic” prefix CRMAF_ in CRM 4.0. In theory it should work like a charm, and in most of the times it does. But there are some pitfalls and CRMAF prefix appears to be ignored. I personally prefer working in Visual Studio (Microsoft Business Intelligence Studio), so the article refers to this environment.
1. How to use CRMAF prefix binding.
- create a custom report
- create a well-formed SQL using CRMAF_ prefix
- deploy it to CRM and binding the context of single record should happen automatically.
2. Common problems
- no rows are returned
- not an expected row is returned
- other
3. Best practice
- Check if SQLquery is well formed. Always use filtered views if possible – you keep the user rights context correct. It should read similar to this (you can use exactly this one for testing):
SELECT accountid, name FROM FilteredAccount AS CRMAF_FilteredAccount
- Check if the SQL query returns expected results. Make sure there are records in corresponding table(s) e.g. Accounts. Copy and paste SQL query into SQL Server Management Studio and execute the query against your CRM DB (e.g. MicrosoftCRM_MSCRM).
- Drag and drop several fields to Report Layout Pane and preview the report. Visual Studio does not provide any context binding in Preview so you always get the first record from the query results. You may try passing a condition into SQL query. Paste in the GUID for your account (e.g. retrieved from DB) and pressing the button View Report will display the report for corresponding account. Just remember to remove it when done with testing!
SELECT accountid, name FROM FilteredAccount AS CRMAF_FilteredAccount WHERE accountid = 'D54D44AD-36D0-DC11-AA32-0003FF33509E'
- When uploading the report to CRM make sure you selected:
- Existing File for report type
- File location is correct to your custom report
- Categories input box is filled in with corresponding report area
- Related Record Types input box is set to appropriate record: e.g. Accounts
- Display In input box is filled in with Forms for related record types as well – so that the report is displayed in the context of the entity record if that is what you want.
- Language pick appropriate one
- Save and test on a given entity
4. Tricks – when CRMAF prefix is not working
Of course there are reports much more complicated than the example above and using CRMAF gets tricky when using advanced SQL queries. Following example is definitely not the most sophisticated one but in general it covers the principle.
SELECT name, 'do no email' AS Expr1, donotemailname FROM FilteredAccount AS CRMAF_FilteredAccount UNION SELECT name, 'do not fax' AS Expr1, donotfaxname FROM FilteredAccount AS CRMAF_FilteredAccount
Union in query breaks Visual Studio Query design feature – you cannot see and manipulate tables in visual manner – clicking and selecting columns in design pane. Alright it doesn’t matter that much. What is worse – is that you might expect binding to be working the same way it did for single query. Not really. It returns all the account records not just the one that should treated in context… What?!
Brief look at the actual SQL issued by CRM against the DB shows that in case of a single select (As designed in Visual Studio)
Query as designed:
SELECT name, 'do no email' AS Expr1, donotemailname FROM FilteredAccount AS CRMAF_FilteredAccount
it looks like this (As actual query against DB – binding is visible):
Query as interpreted:
SELECT name, 'do no email' AS Expr1, donotemailname FROM (SELECT account0.* FROM FilteredAccount AS account0 WHERE (account0.accountid = N'{D14D44AD-36D0-DC11-AA32-0003FF33509E}')) AS CRMAF_FilteredAccount
Whereas UNION, or better to say multiple instances of magic CRMAF_ binding formula are just matched once and ignored later as seen here:
Query as designed:
SELECT name, 'do no email' AS Expr1, donotemailname FROM FilteredAccount AS CRMAF_FilteredAccount UNION SELECT name, 'do not fax' AS Expr1, donotfaxname FROM FilteredAccount AS CRMAF_FilteredAccount
Query as interpreted:
SELECT name, 'do no email' AS Expr1, donotemailname FROM (SELECT account0.* FROM FilteredAccount AS account0 WHERE (account0.accountid = N'{D14D44AD-36D0-DC11-AA32-0003FF33509E}')) AS CRMAF_FilteredAccount UNION SELECT name, 'do not fax' AS Expr1, donotfaxname FROM FilteredAccount AS CRMAF_FilteredAccount
If you think you can cheat it with something simlar to this, forget it, it is ignored completely…:
SELECT name, Expr1, donotemailname FROM (SELECT name, 'do no email' AS Expr1, donotemailname FROM FilteredAccount UNION SELECT name, 'do not fax' AS Expr1, donotfaxname FROM FilteredAccount AS FilteredAccount_1 ) AS CRMAF_FilteredAccount
What should you do then? Break it into pieces!.
1. Make one simple dataset where you retrieve only accountid similar to 1st example. Be sure it is the first one in datasets order. You can modify the XML code of the report to do that if you happen to have the previus dataset in place already.
SELECT accountid, name FROM FilteredAccount AS CRMAF_FilteredAccount
2. Add new report parameter e.g. CRM_accountid and set its default value to the dataset / valuefield of the dataset / valuefield from step 1
3. Create (Modify) the 2nd dataset with the “complicated” query and use the parameter inside:
SELECT name, Expr1, donotemailname FROM (SELECT accountid, name, 'do no email' AS Expr1, donotemailname FROM FilteredAccount UNION SELECT accountid, name, 'do not fax' AS Expr1, donotfaxname FROM FilteredAccount AS FilteredAccount_1) AS fac WHERE (accountid = @CRM_accountid)
4. Enjoy
Works great! thanx
Hi,
I need to create a customized “Print Order Product” Report for Order Product (Salesorderdetail) record. I have created a SSRS Report and its working fine in VS but when I deploy in CRM and Run the Report I get the error
“You do not have previliges to view this report. Please contact your administrator”.
How can I create a standalone report for individual order product item?
Thanks in advance
Hi, the problem you have is related to user rights. VS is not performing user rights check, therefore you are able to create and run any report. The problem comes when you deploy it to Reportserver through CRM. You have to check user rights for running the report in Reportserver. Check this> http:///Reports, there is a management console for reports. In there you check for report properties / security under corresponding node (Home / / 4.0) and make sure there is either username or group with sufficient privileges assigned to report in roles Browser / Browser for Microsoft CRM.
Most likely you do not have correctly assigned users that are trying to run the report to ReportingGroup and SQLAccessGroup or you are trying to use other than FilteredViews for your sql queries.
Cheers
HI ,
What to be do when dealing with multiple entities with multiple records
Can you please describe your problem in detail? From your question it is not really obvious what you are trying to solve.
I’ve seen a lot of solutions to this issue, especially unions, including building the string up as a variable and calling an exec. The simplist answer (which hasn’t failed me yet, although there may be exceptions) is to use different aliases.
Eg, your example,
SELECT name, ‘do no email’ AS Expr1, donotemailname
FROM FilteredAccount AS CRMAF_FilteredAccount
UNION
SELECT name, ‘do not fax’ AS Expr1, donotfaxname
FROM FilteredAccount AS CRMAF_FilteredAccount
Filters correctly if expressed as
SELECT name, ‘do no email’ AS Expr1, donotemailname
FROM FilteredAccount AS CRMAF_acc
UNION
SELECT name, ‘do not fax’ AS Expr1, donotfaxname
FROM FilteredAccount AS CRMAF_acc2
What does this actually return if the account has both ‘do not email’ and ‘do not fax’? Does it return two records or one record with the first ‘do not email’?
Also, is there anything you can do if the parameter is blank? WHERE (accountid = @CRM_accountid)
Yes, of course it joins the results from both queries, therefore you get the accounts in the resultset twice. It was meant as an easy to follow example for CRMAF_ feature failing in certain situations, not as a piece of brilliant business logic
. If you need to return only one row per account, you definitely do not need to make unions. Well, the second question is bit different – you are not supposed to have the accountid empty. The purpose of the CRMAF_ binding is that you are currently on a given record and you want to filter the results according to the selected record. However there is an option to set the default value for the parameter in Reporting Services – that can be a quick solution to your problem.
Hi,
Interesting read. Sort of had the general idea of how it works but it is always good to see it all in the open.
I have had some issues with CRMAF returning all rows (hence not filtering) on certain environments, when executing the report through Outlook, but not through IE and only for account. When trying to narrow it down I found that even the built in report (CRM 4.0) didn’t work properly with the CRMAF logic. The simplest possible SQL using this in a report still breaks. Any ideas what might be wrong?
Well, in MSCRM framework – you never know… Sometimes it is user typo, sometimes the query translation mechanism fails to recognize CRMAF binding prefix correctly, sometimes it doesn’t work for apparent reason. (rollup problem, Outlook versions, Outlook MSCRM plugin versions, particular customizations). You should probably start down on a SQL log level. Log the SQL statements CRM issues against DB and you will see what is really executed. From there you can start next experiments with modification of the statement etc. You may as well send us the statement with more detailed description of the solution you are trying to get working. We can give it a shot in some free time.
Thanks for the instructions. Unfortunately your page didn´t bring the solution for me. My problem was that I had everything in place like you described it. It didn´t work. I tried everything. While I read through your post I had an idea and it worked.
The problem is: When you first create a report without the CRMAF_ prefix and put it into the CRM it is used on all records of this entity. But if you want to change this you must delete and create the report again. If you only upload a new .rdl file it won´t work because CRM seems to remember your first decision…
Best regards
Martin Schlender