tag:blogger.com,1999:blog-77987726536464252082024-02-19T04:51:39.000+03:00CRM ProgrammerSergey Kravchenko about Microsoft Dynamics CRM 4.0 implementation and development.hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.comBlogger65125tag:blogger.com,1999:blog-7798772653646425208.post-24890123615160540642010-07-27T19:00:00.002+04:002010-07-28T12:57:24.596+04:00TFS 2010 SharePoint Project Portal 403 ForbiddenWhen you try to open or create the workitem through the project portal you'll get an 403 forbidden error. This is because you have not enough privileges to the folder Inetpub\wwwroot\bin at the TFS server machine.<br />
<br />
Just set the next rights to the all domain users.<br />
<table style="width:auto;"><tr><td><a href="http://picasaweb.google.com/lh/photo/7Xy9_THhT_0hXKEWToix0w?feat=embedwebsite"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSWtkgOAarTuVChtAUFfsYXv9Q8-64FX7W31HdS7OewaLbqLJgQoTO5Wlw3DLb4ts61zVxwADlPFDspMMYn3aH2c1KFFEoOCAEVxI6McdWbrKcGjNjkkbpQ75LVlePXvArD8LSdaqTEtc/s800/tt_2.png" /></a></td></tr>
<tr><td style="font-family:arial,sans-serif; font-size:11px; text-align:right">From <a href="http://picasaweb.google.com/105195708958292872735/ITBlogPosts?feat=embedwebsite">IT Blog Posts</a></td></tr>
</table><br />
Via <a href="http://www.cnblogs.com/patrick/archive/2010/04/30/1725167.html">http://www.cnblogs.com/patrick/archive/2010/04/30/1725167.html</a>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-14069720802558913302010-06-22T19:33:00.006+04:002010-06-23T12:35:35.220+04:00How to hide a section or field by picklist valueThat code snippet will hides a section by name(label) or by label of any field wich is in this section.<br />
<pre class="brush:js">if(crmForm.all.new_1!=null)
{
var oField = crmForm.all.new_1;
// field to hide
var FieldToHide;
if(document.getElementById("IDENT") != null)
{
FieldToHide = document.getElementById("IDENT");
FieldToHide.style.display = "block";
}
// section to hide
var td = document.getElementsByTagName("td");
var tableH;
for(var i=0; i<td.length; i++)
{
// enter the correct section name
if(td[i].innerText == "Section name")
{
tableH = td[i].parentNode.parentNode.parentNode;
tableH.style.display = "block";
}
}
// here set the needed picklist value
if(oField.DataValue == 1)
{
// field to hide
if(FieldToHide != null)
{
FieldToHide.style.display = "none";
}
}
else
if(oField.DataValue == 3)
{
// section to hide
if(tableH != null)
{
tableH.style.display = "none";
}
}
}
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-56495482646429310802010-06-10T19:03:00.002+04:002010-06-10T19:03:07.390+04:00TooltipTo add a tooltip at some field on form, jast add next snippet with your changes to form On Load<br />
<br />
<pre class="brush:js">var ele = document.getElementById("firstname_c");
ele.title = "Name Name Name!";
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-63784065602314855892010-02-27T13:10:00.002+03:002010-02-27T13:10:49.749+03:00Get the localized names of all entities<pre class="brush:sql">select ObjectTypeCode, Name, LogicalName, l.Label
from MetadataSchema.Entity e left join
MetadataSchema.LocalizedLabel l on e.EntityId=l.ObjectId
where l.ObjectColumnName='LocalizedName'
and l.CustomizationLevel=1
union
select ObjectTypeCode, Name, LogicalName, l.Label
from MetadataSchema.Entity e left join
MetadataSchema.LocalizedLabel l on e.EntityId=l.ObjectId
where l.ObjectColumnName='LocalizedName'
and l.CustomizationLevel=0
and ObjectTypeCode not in
( select ObjectTypeCode
from MetadataSchema.Entity e left join
MetadataSchema.LocalizedLabel l on e.EntityId=l.ObjectId
where l.ObjectColumnName='LocalizedName'
and l.CustomizationLevel=1
)
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-23186931186562468682010-02-27T13:09:00.003+03:002010-02-27T13:17:19.404+03:00Get the params of all localized attributes and all picklist values<pre class="brush:sql">SELECT
e.Name as EntityName
,l.Label as 'Наименование атрибута', a.LogicalName ,at.Description as 'Тип атрибута' ,a.AttributeLogicalTypeId
,apv.Value as 'Значения пиклиста', lp.Label as 'Наименования пиклиста'
,[AttributeRequiredLevelId]
,[MaxLength]
,[MinValue]
,[MaxValue]
,LookupClass
,LookupStyle
,LookupBrowse
FROM
[NaviconGroup_MSCRM].[MetadataSchema].[Attribute] a
join MetadataSchema.Entity e on e.EntityId=a.EntityId
join MetadataSchema.AttributeTypes at on at.AttributeTypeId=a.AttributeTypeId
join MetadataSchema.LocalizedLabel l on l.ObjectId=a.AttributeId and l.ObjectColumnName='DisplayName'
left join MetadataSchema.AttributePicklistValue apv on apv.AttributeId=a.AttributeId
left join MetadataSchema.LocalizedLabel lp on lp.ObjectId=apv.AttributePicklistValueId
order by EntityName, l.Label, at.Description,apv.Value
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-55236350252940228582010-02-04T19:22:00.002+03:002010-02-05T12:38:44.957+03:00Get Picklist Value By Picklist NameI wrote some method to get picklist value by knowing picklist name.<br />
<br />
<pre class="brush:c#">namespace test
{
public class CrmServiceProvider
{
private WebMetadataService.MetadataService _MetaService = null;
///* Create a MetadataService end point */
private WebMetadataService.MetadataService MetaService
{
get
{
if (_MetaService == null)
{
_MetaService = new WebMetadataService.MetadataService();
_MetaService.Url = "http://localhost/mscrmservices/2007/metadataservice.asmx";
// Use a special user credentials
NetworkCredential cred = new NetworkCredential();
cred.Domain = ConfigurationManager.AppSettings["Domain"];
cred.UserName = ConfigurationManager.AppSettings["UserName"];
cred.Password = ConfigurationManager.AppSettings["PassWord"];
_MetaService.UseDefaultCredentials = false;
_MetaService.Credentials = cred;
_MetaService.UnsafeAuthenticatedConnectionSharing = true;
WebMetadataService.CrmAuthenticationToken token = new WebMetadataService.CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = ConfigurationManager.AppSettings["Organization"];
_MetaService.CrmAuthenticationTokenValue = token;
}
return _MetaService;
}
}
public int GetPicklistValueByPicklistName(string PicklistName, string EntityLogicalName, string LogicalName)
{
int retval = -1;
/* Retrieve the attribute metadata */
WebMetadataService.RetrieveAttributeRequest attributeRequest = new WebMetadataService.RetrieveAttributeRequest();
attributeRequest.EntityLogicalName = EntityLogicalName;
attributeRequest.LogicalName = LogicalName; //picklist
WebMetadataService.RetrieveAttributeResponse attributeResponse =
(WebMetadataService.RetrieveAttributeResponse)MetaService.Execute(attributeRequest);
/* Cast the attribute metadata to a picklist metadata */
WebMetadataService.PicklistAttributeMetadata picklist =
(WebMetadataService.PicklistAttributeMetadata)attributeResponse.AttributeMetadata;
foreach (WebMetadataService.Option op in picklist.Options)
{
if (op.Label.UserLocLabel.Label == PicklistName)
retval = op.Value.Value;
}
return retval;
}
}
}
</pre><br />
To call this method use the next construction:<br />
<pre class="brush:c#">int psv = GetPicklistValueByPaymentSystemName(categorycode, "account", "accountcategorycode");
if (psv > 0)
{
acc.accountcategorycode = new Picklist();
acc.accountcategorycode.Value = psv;
}
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-2010704671948723592009-12-21T16:51:00.002+03:002009-12-21T16:53:59.214+03:00Upgrade of javascript function to hide "Add Existing ..." buttonI improved the source code for one of my previous post — <a href="http://crmpro.blogspot.com/2009/08/remove-add-existing-button-from.html">Remove 'Add Existing...' button from associated view entities form</a>.<br />
<br />
<pre class="brush:js">function HideAssociatedViewButtons(areaPrefix, loadAreaId, buttonTitles,addAreaParams){
var navElement = document.getElementById(areaPrefix+loadAreaId);
if (navElement != null) {
navElement.onclick = function LoadAreaOverride(){
if(addAreaParams.length>0)
loadArea('area'+loadAreaId, addAreaParams[0]);
else
loadArea('area'+loadAreaId);
var iframeid='area' + loadAreaId + 'Frame';
HideViewButtons(document.getElementById(iframeid), buttonTitles);
}
}
}
function HideViewButtons(Iframe, buttonTitles) {
if (Iframe != null ) {
Iframe.onreadystatechange = function HideTitledButtons() {
if (Iframe.readyState == 'complete') {
var iFrame = frames[window.event.srcElement.id];
var liElements = iFrame.document.getElementsByTagName('li');
for (var j = 0; j < buttonTitles.length; j++) {
for (var i = 0; i < liElements.length; i++) {
if (liElements[i].getAttribute('title') == buttonTitles[j]) {
liElements[i].style.display = 'none';
break;
}
}
}
}
}
}
}
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-41632872895988757542009-12-03T18:52:00.001+03:002009-12-03T18:54:37.104+03:00On form load set some selected value for related entity pick-listI had to set the value for related entity pick-list — filter of date for Activities of some account, like it was default Selected value.<br />
<br />
<pre class="brush:javascript">SelectArea('Activities', 'scheduledend');
SelectArea('ActivityHistory', 'actualend');
function SelectArea(loadAreaId, selectId)
{
var navElement = document.getElementById('nav'+loadAreaId);
if (navElement != null)
{
navElement.onclick = function LoadAreaOverride() {
loadArea('area'+loadAreaId);
var iframeid = 'area'+loadAreaId + 'Frame';
var Iframe=document.getElementById(iframeid);
if (Iframe != null ) {
Iframe.onreadystatechange = function SetAllasDefault() {
if (Iframe.readyState == 'complete') {
var iFrame = frames[window.event.srcElement.id];
var oSelect = iFrame.document.getElementById(selectId);
var oOption = oSelect.options[oSelect.options.length-1];
oOption.selected = true;
oSelect.FireOnChange();
}
}
}
}
}
}
</pre>Put at form OnLoad() event;hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-38910333141983735622009-11-13T16:24:00.002+03:002009-11-13T16:35:24.217+03:00Passing parameters between MS CRM pluginsI was needed to pass a variable from one plugin to another. If you have a two plugin at pre and post stage registered for on entity, then you can use a <a href="http://msdn.microsoft.com/en-us/library/cc151094.aspx">SharedVariables</a> context property. But, if every plugins is a different assembly, and they are registered for a different entities... So, when the first plugin is firing, the second, which is starting after that, needed to know some information for redirecting it logic to another way.<br />
<br />
I had created some common assembly with helper methods and called it "Helper". Then I had created a static class with static variable and had put the value into it, at the first plugin execution runtime. In the second plugin I just get the value from the static common variable.<br />
<br />
And nothing about read\write DB operations.<br />
Helper assembly.<br />
<pre class="brush:c#">namespace Helper
{
public static class Keeper
{
private static bool _UpdateOppAfterHistory = true;
public static bool UpdateOppAfterHistory
{
get { return _UpdateOppAfterHistory; }
set { _UpdateOppAfterHistory = value; }
}
}
public class OpportunityHelper
{ ... }
}
</pre><br />
First firing plugin code<br />
<pre class="brush:c#">Keeper.UpdateOppAfterHistory = false;
OpportunityHelper.CreateOpportunityHistory(Opp,crmService);
// removing the flag to the back
Keeper.UpdateOppAfterHistory = true;
</pre><br />
Second firing plugin code<br />
<pre class="brush:c#">// common shared variable analysis
bool UpdateOppAfterHistory = Keeper.UpdateOppAfterHistory;
if (UpdateOppAfterHistory)
{ ... }
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-70962489821566547142009-11-10T12:37:00.000+03:002009-11-10T12:37:49.837+03:00How to hide an items of drop-down list?"We should not be able to choose some steps of Opportunity History, if the opportunity has no quotes or sales orders." - that was they said.<br />
<br />
And that was I wrote.<br />
<br />
<pre class="brush:javascript">var oService = null;
var oppid = null;
function FormOnLoad()
{
oService = new Ascentium_CrmService(null, null);
var oParentCrmForm = window.opener.parent.document.all.crmForm;
if(oParentCrmForm)
{
oppid = oParentCrmForm.ObjectId;
}
HideComboboxItems();
}
window.HideComboboxItems = function()
{
var newstep = document.getElementById("new_step");
if(newstep)
{
// checking opportunity for quotes
var sFetchXml ='<fetch mapping="logical" aggregate="true" version="1.0"><entity name="quote"><attribute name="quoteid" aggregate="count" alias="count" />'+
'<filter><condition attribute="opportunityid" operator="eq" value="'+oppid+'" /></filter></entity></fetch>';
var aoFetchResult = oService.Fetch(sFetchXml);
var quoteCount = 0;
if(aoFetchResult.length > 0)
{
quoteCount = aoFetchResult[0].attributes["count"].value;
}
// if no qoutes, then hiding items 4,5,6,7 of dropdown list
if(quoteCount == 0 )
{
var allDropDownElements = newstep.childNodes;
var lastnodevalue = allDropDownElements.length;
for(var i=lastnodevalue; i >= 4; i--)
{
newstep.options.remove(i);
}
}
else
{
// if there is some qoutes, then checking for salesorders
var sFetchXml ='&lr;fetch mapping="logical" aggregate="true" version="1.0"><entity name="salesorder"><attribute name="salesorderid" aggregate="count" alias="count" />'+
'<filter><condition attribute="opportunityid" operator="eq" value="'+oppid+'" /></filter></entity></fetch>';
var aoFetchResult = oService.Fetch(sFetchXml);
var SOCount = 0;
if(aoFetchResult.length > 0)
{
SOCount = aoFetchResult[0].attributes["count"].value;
}
// if no salesorders, then hiding items 6,7
if(SOCount == 0)
{
var allDropDownElements = newstep.childNodes;
var lastnodevalue = allDropDownElements.length;
for(var i=lastnodevalue; i >=6; i--)
{
newstep.options.remove(i);
}
}
}
}
}
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-10856932551119932242009-11-09T17:24:00.000+03:002009-11-09T17:24:40.417+03:00Salesorder Fulfill stateI was trying to catch the Fulfill state of sales order and my try was successful, with registering plugin to Update message at Child pipeline. But there was a one little problem - you can't get the salesorderdetail thru service. I don't know why, but the simple code like in "Example 1" was falling down with Generic SQL error x80044150.<br />
<br />
<pre class="brush:c#">// Example 1
QueryByAttribute qba = new QueryByAttribute();
qba.EntityName = EntityName.salesorderdetail.ToString();
qba.ColumnSet = new AllColumns();
qba.Attributes = new string[] { "salesorderid" };
qba.Values = new object[] { soid };
BusinessEntityCollection bec = crmService.RetrieveMultiple(qba);
</pre><br />
<br />
Then I was switch on the Fulfill Sdk Message and everything start working fine!<br />
<blockquote>1. open up the SdkMessage view, filter by Name and find the SdkMessageId<br />
2. open up the SdkMessageFilter view, filter by SdkMessageId you got from step 1.<br />
3. change IsCustomProcessingStepAllowed to 'True'<br />
</blockquote><br />
<pre class="brush:sql">update dbo.SdkMessageFilter
set IsCustomProcessingStepAllowed=1
where SdkMessageId=
(select top 1 SdkMessageId from dbo.SdkMessage where name ='Fulfill')
</pre><br />
I have a question, why the Fulfill message has been unplugged from customization?hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-14631780504097275002009-11-02T17:01:00.001+03:002009-11-02T17:02:13.890+03:00Parse XML date in CRM date with JavascriptA JavaScript function to parse an XML (ISO-8601) date string (e.g., "2008-01-18") that returns a JavaScript Date object.<br />
<br />
<pre class="brush:javascript">// parsing
function parseDate(xmlDate)
{
if (!/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}/.test(xmlDate)) {
throw new RangeError("xmlDate must be in ISO-8601 format YYYY-MM-DD.");
}
return new Date(xmlDate.substring(0,4), xmlDate.substring(5,7)-1, xmlDate.substring(8,10));
}
// and using
if(retrievedOpp.attributes["estimatedclosedate"] != null && retrievedOpp.attributes["estimatedclosedate"] != undefined){
crmForm.all.new_estimatedclosedate.DataValue = parseDate(retrievedOpp.attributes["estimatedclosedate"].value);}
</pre>Source <a href="http://dev.ektron.com/blogs.aspx?id=14140">http://dev.ektron.com/blogs.aspx?id=14140</a>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com1tag:blogger.com,1999:blog-7798772653646425208.post-64694286857498654262009-10-29T13:30:00.005+03:002009-10-29T14:47:18.974+03:00How to determine on which pipeline a plugin is executing - Parent or ChildeThe <i>InvocationSource</i> <b>property </b>is an integer value that you can use to determine whether the current plug-in is running in a child pipeline. <br />
<br />
<i>MessageInvocationSource</i> Values<br />
<table cellspacing="7px" ><tr style="background:#AAAAAA none repeat scroll 0 0;"><td >Field</td><td>Value</td><td>Description</td></tr>
<tr><td>Child</td><td> 1 </td><td>Specifies a child pipeline</td></tr>
<tr><td>Parent</td><td> 0 </td><td>Specifies a parent pipeline</td></tr>
</table>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-77167580915495428762009-10-20T12:15:00.005+04:002009-10-20T14:03:58.336+04:00MS CRM Fetch and Retrieve from javascriptThis code snippet was writing exactly like recommended in MSCRM SDK 4.09.<br />
I was put it in OnLoad() event of my account form, and in the lookup field(at my example - new_postalcodeid) at OnChange() event I was calling my function.<br />
<br />
There is two function that are doing the same work but with different methods.<br />
<br />
<pre class="brush:javascript">var authenticationHeader = GenerateAuthenticationHeader();
crmForm.all.address1_city.ForceSubmit = true;
window.GetRegionByIndex_Retrieve = function()
{
if (crmForm.all.new_postalcodeid.DataValue == null)
{
crmForm.all.address1_city.Disabled = false;
crmForm.all.address1_city.DataValue = "";
return;
}
var lookupItem = new Array;
lookupItem = crmForm.all.new_postalcodeid.DataValue;
if(lookupItem[0] != null)
{
// Prepare the SOAP message.
var xml = "<?xml version='1.0' encoding='utf-8'?>"+
"<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'"+
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"+
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>"+
authenticationHeader+
"<soap:Body>"+
"<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>"+
"<entityName>new_postalcode</entityName>"+
"<id>"+lookupItem[0].id+"</id>"+
"<columnSet xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1:ColumnSet'>"+
"<q1:Attributes>"+
"<q1:Attribute>new_regcityarea</q1:Attribute>"+
"</q1:Attributes>"+
"</columnSet>"+
"</Retrieve>"+
"</soap:Body>"+
"</soap:Envelope>";
// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result.
var resultXml = xHReq.responseXML;
// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert(msg);
}
// Display the retrieved value.
else
{
crmForm.all.address1_city.DataValue = resultXml.selectSingleNode("//q1:new_regcityarea").nodeTypedValue;
crmForm.all.address1_city.Disabled = true;
}
}
}
window.GetRegionByIndex_Fetch = function (){
if (crmForm.all.new_postalcodeid.DataValue == null)
{
crmForm.all.address1_city.Disabled = false;
crmForm.all.address1_city.DataValue = "";
return;
}
var lookupItem = new Array;
lookupItem = crmForm.all.new_postalcodeid.DataValue;
if(lookupItem[0] != null)
{
var xml = "<?xml version='1.0' encoding='utf-8'?>" +
"<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
" xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
authenticationHeader +
"<soap:Body>" +
"<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
"<fetchXml>" +
"&lt;fetch mapping='logical'&gt;" +
"&lt;entity name='new_postalcode'&gt;" +
"&lt;attribute name='new_postalcodeid'/&gt;"+
"&lt;attribute name='new_regcityarea'/&gt;"+
"&lt;filter type='and'&gt;"+
"&lt;condition attribute='new_postalcodeid' operator='eq' value='"+lookupItem[0].id+"'/&gt;"+
"&lt;/filter&gt;&lt;/entity&gt;&lt;/fetch&gt;" +
"</fetchXml>" +
"</Fetch>" +
" </soap:Body>" +
"</soap:Envelope>";
var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert(msg);
}
// Process and display the results.
else
{
// Capture the result and UnEncode it.
var resultSet = new String();
resultSet = resultXml.text;
resultSet.replace('&lt;','<');
resultSet.replace('&gt;','>');
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(resultSet);
var results = xmlDoc.getElementsByTagName('result');
for(i=0;i<results.length;i++)
{
crmForm.all.address1_city.DataValue = results[i].selectSingleNode('//new_regcityarea').nodeTypedValue;
}
crmForm.all.address1_city.Disabled = true;
}
}
}
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com1tag:blogger.com,1999:blog-7798772653646425208.post-55697623663723020392009-10-13T16:41:00.005+04:002009-10-13T16:51:32.926+04:00How to retrieve from many-to-many entity.If you need to retrieve something from many-to-many relationship entity, and there is no such entity in CRM, then you should use the FetchXml, instead of Query.<br />
<pre class="brush:c#">// Base bodel of FetchXml for get relationship entity
string fetchXML =
"<fetch distinct='false' mapping='logical'>" +
"<entity name='" + relationshipName + "'><filter type='and'>" +
"<condition attribute='" + relatedEntityName + "id' operator='eq' value='" + relatedId + "' />" +
"<condition attribute='" + typeEntityName + "id' operator='eq' value='" + profileId + "' />" +
"</filter></entity>" + "</fetch>";
</pre><br />
For example, next code snippet is checking a count of relations between the Account entity and New_Industry entity, wich relationship is many-to-many. To achieve this, I need to check the relationship entity - New_industry_account, wich is contains all of relation of our two entities.<br />
<pre class="brush:c#">ICrmService crmService = context.CreateCrmService(true);
// check for relation
#region FetchXML
string fetchXML =
"<fetch distinct='false' mapping='logical'>" +
"<entity name='new_industry_account'><filter type='and'>" +
"<condition attribute='accountid' operator='eq' value='" + accountid.ToString() + "' />" +
"</filter></entity></fetch>";
#endregion
string fetchresult = crmService.Fetch(fetchXML);
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(fetchresult);
XmlNodeList xnodlist = xmldoc.SelectNodes("resultset/result");
if (xnodlist.Count > 0) { return; }
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-83914067666885447582009-10-13T14:42:00.001+04:002009-10-13T15:02:00.678+04:00Update a number of custom attributes of DynamicEntity with TargetUpdateDynamic.This code I was used in plugins for updating the custom attributes using Microsoft.Crm.SDK.<br />
<br />
<pre class="brush:c#">using System;
using System.Collections.Generic;
using System.Collections;
// Microsoft Dynamics CRM namespaces
using Microsoft.Crm.Sdk;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.SdkTypeProxy;
...
// Extract the DynamicEntity from the request.
entity = (DynamicEntity)retrieved.BusinessEntity;
// declare a property array
ArrayList arrProps = new ArrayList();
// create some property
CrmBooleanProperty new_withindustry = new CrmBooleanProperty();
new_withindustry.Name="new_withindustry";
new_withindustry.Value= new CrmBoolean();
new_withindustry.Value.Value=true;
arrProps.Add(new_withindustry);
// create another property
CrmMoneyProperty new_industrydeal = new CrmMoneyProperty();
new_industrydeal.Name = "new_industrydeal";
new_industrydeal.Value = new CrmMoney();
new_industrydeal.Value.Value = 12345.0m;
arrProps.Add(new_industrydeal);
// Update the properties array on the DynamicEntity.
entity.Properties.AddRange((Property[])arrProps.ToArray(typeof(Property)));
// Create the update target.
TargetUpdateDynamic updateDynamic = new TargetUpdateDynamic();
// Set the properties of the target.
updateDynamic.Entity = entity;
// Create the update request object.
UpdateRequest update = new UpdateRequest();
// Set request properties.
update.Target = updateDynamic;
// Execute the request.
UpdateResponse updated = (UpdateResponse)crmService.Execute(update);
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-24948688282509991602009-10-13T02:01:00.001+04:002009-10-13T02:03:30.163+04:00Dynamic hyperlink in Reporting Services 2008I had a custom entity - project and was needed to open a project card from the report.<br />
So I had done exactly as saying in <a href="http://msdn.microsoft.com/en-us/library/ms157159.aspx">http://msdn.microsoft.com/en-us/library/ms157159.aspx</a> and in the expression field of hyperlink I was typed next<br />
<br />
="http://SERVERNAME/ORGANIZATIONNAME/userdefined/edit.aspx?id=%7b" & Fields!projectid.Value.ToString() & "%7d&etc=10005"<br />
<br />
SERVERNAME and ORGANIZATIONNAME must be replaced with your crm values.hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-23492206142371981232009-10-12T16:05:00.008+04:002009-10-13T15:53:31.704+04:00Registering plugins for event on many-to-many entitiesI found that from the box MS CRM 4.0 are not supported the events on many-to-many relationship entities(bridge entities). But Aaron Elder has hack it.<br />
<br />
All you need is just register it at AssociateEntities or DiassociateEntities event with empty Primary and Secondary Entity fields.<br />
<br />
<pre class="brush:sql">-- ============================================================================
-- Enable Associate and Disassociate Plug-in Events Script v1.0
-- ----------------------------------------------------------------------------
-- (c) 2009 Aaron Elder
-- ============================================================================
-- DISCLAIMER:
-- This script is provided "AS IS" with no warranties, and confers no rights.
-- ============================================================================
-- While this is obviously "unsupported", I think the fact that these events
-- are not available is a bug and hopefully it will be fixed in a rollup.
-- ============================================================================
USE AscentiumCrmDev_MSCRM
GO
-- Find the deployments SDK Filter ID for the
-- Associate and Disassociate Entity SDK Messages
DECLARE @DisassociateEntitiesFilterId uniqueidentifier
DECLARE @AssociateEntitiesFilterId uniqueidentifier
SET @DisassociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'DisassociateEntities')
SET @AssociateEntitiesFilterId = (SELECT SdkMessageId FROM SdkMessageBase WHERE [Name] = 'AssociateEntities')
-- Enable the Associate and Disassociate Filters to be valid for custom processing
-- Custom Processing means "you register plug-ins against it"
-- Note: We only do this for the "generic" (OTC == 0) case, just to be safer
UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1
WHERE SdkMessageId = @DisassociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
UPDATE SdkMessageFilterBase SET IsCustomProcessingStepAllowed = 1
WHERE SdkMessageId = @AssociateEntitiesFilterId AND PrimaryObjectTypeCode = 0
</pre>(C)<a href="http://consulting.ascentium.com/blog/crm/Post533.aspx"><br />
http://consulting.ascentium.com/blog/crm/Post533.aspx</a>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com2tag:blogger.com,1999:blog-7798772653646425208.post-85507385063219235312009-10-07T17:58:00.005+04:002009-10-08T14:48:22.944+04:00Window redirect and closeThis was the window that was opened from CRM form menu (ISV.Config.xml). The window has received some parameters and then redirected to another window, which is preparing and opening the MS Word document, but the pop-up window was still open - this is rude. So, I've closed it.<br />
<br />
<pre class="brush:js">// call this code on body onload event
function redirect()
{
// needed URL of pop-up window or modify current location URL
window.opener.location = window.location.href.replace(/Default2/, "Default");
window.top.close();
}
</pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-28574073171777879522009-10-07T17:36:00.004+04:002009-10-07T18:02:07.707+04:00Close window from server-side<pre class="brush:c#">// closethe page if successful update
RegisterStartupScript("load", "<" + "script type=\"text/javascript\">\n" +
"self.close();\n" +
"<" + "/script>");
</pre><br />
<pre class="brush:vb">Dim strscript As String = "<"+"script language=javascript>window.top.close();<"+"/script>"
If (Not ClientScript.IsStartupScriptRegistered("clientScript")) Then
ClientScript.RegisterStartupScript(Page.GetType(), "clientScript", strscript)
End If
</pre><br />
<pre class="brush:c#">System.Text.StringBuilder sb = System.Text.StringBuilder ();
sb.Append("<script type='javascript'>");
sb.Append("this.close(); window.open('www.mysite.com','_blank'); ");
sb.Append("</script>");
if(!IsClientScriptRegistered("myScript",sb.ToString())
this.RegisterClientScriptBlock("myScript",sb.ToString());
</pre><br />
All of code was found in Internethyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com2tag:blogger.com,1999:blog-7798772653646425208.post-14919161935262337022009-10-05T19:28:00.002+04:002009-10-05T19:31:15.656+04:00Mask the phone fieldsI was need some mask on the "mobilephone" field in contact card. So I was combine some google search result with my experience and got next code:<br />
<pre class="brush:js">//base maskphone function
window.applyMask = function()
{
// var of fields wich must be masked
var ele = document.getElementById("mobilephone");
var FormatPhoneHandler=function()
{
var PH = this.value;
var re = /\D/g;
// +7 - this is country code of Russia, so this is decision only for one country
PH = PH.replace("+7","");
PH = PH.replace(re,"");
if(PH.length <1)
{
this.value = "";
}
else if(PH.length <= 3)
{
this.value = "+7 (" + PH;
}
else if(PH.length > 3 && PH.length <= 6)
{
this.value = "+7 (" + PH.substring(0,3) + ") " + PH.substring(3,6);
}
else if(PH.length > 6)
{
this.value = "+7 (" + PH.substring(0,3) + ") " + PH.substring(3,6) + "-" + PH.substring(6,10);
}
}
ele.onkeyup = FormatPhoneHandler;
}
// turn it on
applyMask();
</pre><br />
Place this code in onLoad event in the entity wich you need and don't forget change names of the field for the right one.hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-43319623736260229452009-08-20T16:50:00.004+04:002009-08-20T17:15:41.732+04:00Embeded notificationWe were needed some kind of notify message for user without any pop-up or an alerts.<br /><br /><pre class="brush:javascript"><br />function CreateRequestObject() {<br /> if (window.XMLHttpRequest) {<br /> try {<br /> return new XMLHttpRequest();<br /> } catch (e) { }<br /> } else if (window.ActiveXObject) {<br /> try {<br /> return new ActiveXObject('Msxml2.XMLHTTP');<br /> } catch (e) {<br /> try {<br /> return new ActiveXObject('Microsoft.XMLHTTP');<br /> } catch (e) { }<br /> }<br /> }<br /> return null;<br />}<br /><br />function RetrieveEntity(sEntityName, GUID, sAttributeNames) {<br /> var attributes = "";<br /> if (sAttributeNames.length == 0)<br /> return null;<br /> for (var i = 0; i < sAttributeNames.length; i++) {<br /> attributes += "<cs:Attribute>" + sAttributeNames[i] + "</cs:Attribute>";<br /> }<br /> var soapBody = "<soap:Body>" +<br /> "<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +<br /> "<entityName>" + sEntityName + "</entityName>" +<br /> "<id>" + GUID + "</id>" +<br /> "<columnSet xmlns:cs='http://schemas.microsoft.com/crm/2006/Query' xsi:type='cs:ColumnSet'>" +<br /> "<cs:Attributes>" + attributes + "</cs:Attributes>" +<br /> "</columnSet>" +<br /> "</Retrieve>" +<br /> "</soap:Body>";<br /> var soapXml = "<soap:Envelope " +<br /> "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +<br /> "xmlns:xsd='http://www.w3.org/2001/XMLSchema' " +<br /> "xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>";<br /> soapXml += GenerateAuthenticationHeader();<br /> soapXml += soapBody;<br /> soapXml += "</soap:Envelope>";<br /><br /> xmlhttp = CreateRequestObject();<br /> xmlhttp.open("POST", "/mscrmservices/2007/crmservice.asmx", false);<br /> xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");<br /> xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");<br /> xmlhttp.setRequestHeader("Content-Length", soapXml.length);<br /> xmlhttp.send(soapXml);<br /><br /> // Capture the result.<br /> var resultXml = xmlhttp.responseXML;<br /> // Check for errors.<br /> var errorCount = resultXml.selectNodes('//error').length;<br /> if (errorCount != 0) {<br /> var msg = resultXml.selectSingleNode('//description').nodeTypedValue;<br /> alert(msg);<br /> return null;<br /> }<br /> // Display the retrieved value.<br /> else {<br /> var retEntityValues = new Array();<br /> var retrieveNodes = resultXml.selectNodes("soap:Envelope/soap:Body/RetrieveResponse/RetrieveResult/q1:*");<br /> for (var i = 0; i < retrieveNodes.length; i++) {<br /> var nodeName = retrieveNodes[0].baseName;<br /> var nodeValue = retrieveNodes[0].nodeTypedValue;<br /> retEntityValues[nodeName] = nodeValue;<br /> }<br /> return retEntityValues<br /> }<br />}<br /><br />function AddNotification(noticationId, text) {<br /> if (crmForm.all.Notifications.all[noticationId] != null)<br /> crmForm.all.Notifications.all[noticationId + '_text'].innerHTML = text;<br /> else {<br /> crmForm.all.Notifications.innerHTML += '<DIV class="Notification" id="' + noticationId + '" Order="0" Severity="1" Source="Client" NotificationId="' + noticationId + '"><TABLE cellSpacing="0" cellPadding="0"><TBODY><TR><TD vAlign="top"><IMG class="ms-crm-Lookup-Item" alt="" src="/_imgs/error/notif_icn_crit16.png" /></TD><TD><SPAN id="' + noticationId + '_text">' + text + '</SPAN></TD></TR></TBODY></TABLE></DIV>';<br /> crmForm.all.Notifications.style.display = 'block';<br /> }<br />}<br /><br />function RemoveNotification(noticationId) {<br /> if (crmForm.all.Notifications.all[noticationId] != null) {<br /> crmForm.all.Notifications.all[noticationId].removeNode(true);<br /> if (crmForm.all.Notifications.childNodes.length == 0)<br /> crmForm.all.Notifications.style.display = 'none';<br /> }<br />}<br /><br />var customer = crmForm.all.customerid;<br />if (customer.DataValue != null && customer.DataValue[0].typename == 'account') {<br /> var cs = new Array();<br /> cs[0] = 'new_attention';<br /> var acc = RetrieveEntity('account', customer.DataValue[0].id, cs);<br /> if (acc != null && acc['new_attention'] == 1) {<br /> AddNotification('NotificationAccount', 'Клиент требует внимания! Для более подробной информации перейдите в карточку клиента.');<br /> crmForm.all.customerid_d.getElementsByTagName('SPAN')[0].style.color = 'Red';<br /> }<br /> else {<br /> RemoveNotification('NotificationAccount');<br /> }<br />}<br />else {<br /> RemoveNotification('NotificationAccount');<br />}<br /></pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com2tag:blogger.com,1999:blog-7798772653646425208.post-87275795319271792962009-08-19T15:27:00.001+04:002009-08-19T15:30:32.941+04:00Get contact status in custom extended marketing list<pre class="brush:sql"><br />declare @contactid uniqueidentifier<br />declare @campaignactivityid uniqueidentifier<br />-- some Guids<br />set @contactid='48CF39EE-AA8C-DE11-A526-000C2989FA53'<br />set @campaignactivityid='72CE8156-AD8C-DE11-A526-000C2989FA53'<br /><br />select exL.New_ExtMarketingListsElementId, exL.New_contactStatus<br />from dbo.New_ExtMarketingListsElementExtensionBase exL<br /> JOIN dbo.ContactBase cnt ON exL.new_contact=cnt.ContactId<br /> JOIN dbo.ListBase lst ON exL.new_list=lst.ListId<br /> JOIN dbo.CampaignActivityItemBase cai ON lst.ListId=cai.ItemId<br />where cnt.ContactId=@contactid <br /> and cai.CampaignActivityId=@campaignactivityid<br /></pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-12507946908219410552009-08-19T15:21:00.005+04:002009-08-19T15:27:01.283+04:00How to get Marketing Lists by Campaign Activity Id<pre class="brush:sql"><br />declare @campaignactivityid uniqueidentifier<br />-- an example GUID<br />set @campaignactivityid='72CE8156-AD8C-DE11-A526-000C2989FA53'<br /><br />-- связь между маркетинговым списком и кампанией осуществляется через промежуточную таблицу CampaignActivityItemBase<br />select * <br />from dbo.CampaignActivityItemBase cai<br /> JOIN dbo.ListBase lb ON lb.ListId=cai.ItemId<br />where cai.CampaignActivityId=@campaignactivityid<br /></pre>hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0tag:blogger.com,1999:blog-7798772653646425208.post-56715498339788597752009-08-13T13:31:00.007+04:002009-08-13T13:45:14.366+04:00Remove 'Add Existing...' button from associated view entities formI was found this code at Dave Hawes blog — <a href="http://blog.davehawes.com/post/2008/04/23/MSCRM-4-Remove-Add-Existing-xxxxx-button.aspx">http://blog.davehawes.com/post/2008/04/23/MSCRM-4-Remove-Add-Existing-xxxxx-button.aspx</a><br />This code should be added to onLoad event for the form of the entity where you want to hide buttons for the associated views of other entities.<br /><br /><pre class="brush:js"><br />HideAssociatedViewButtons('new_account_new_accountclassificate', ['Добавить к этой записи существующий объект Классификация организации']); <br /> <br />function HideAssociatedViewButtons(loadAreaId, buttonTitles){<br /> var navElement = document.getElementById('nav_' + loadAreaId); <br /> if (navElement != null) {<br /> navElement.onclick = function LoadAreaOverride() {<br /> loadArea(loadAreaId);<br /> HideViewButtons(document.getElementById(loadAreaId + 'Frame'), buttonTitles);<br /> }<br /> }<br />}<br /> <br />function HideViewButtons(Iframe, buttonTitles) { <br /> if (Iframe != null ) {<br /> Iframe.onreadystatechange = function HideTitledButtons() { <br /> if (Iframe.readyState == 'complete') { <br /> var iFrame = frames[window.event.srcElement.id]; <br /> var liElements = iFrame.document.getElementsByTagName('li'); <br /> <br /> for (var j = 0; j < buttonTitles.length; j++) { <br /> for (var i = 0; i < liElements.length; i++) { <br /> if (liElements[i].getAttribute('title') == buttonTitles[j]) { <br /> liElements[i].style.display = 'none'; <br /> break; <br /> }<br /> } <br /> } <br /> } <br /> } <br /> }<br />} <br /></pre><br />Publishing it here for memory.hyperhttp://www.blogger.com/profile/16996652523024990008noreply@blogger.com0