簡體   English   中英

CRM 2011-如何根據屬性值設置默認表單(不使用Javascript)?

[英]Crm 2011 - How to set a default form depending on attribute value (without using Javascript)?

我有一個讓我發瘋的要求:我們為聯系人實體提供8種不同的形式。 我們還有一個包含8個選項的選擇列表。 這樣做的想法是,基於所選的選項,我們可以打開該聯系人記錄,默認情況下不使用JAVASCRIPT而是顯示特定表格,以避免性能問題(每個記錄必須加載兩次)。 例:

形式:
表格1
表格2
表格3

選擇清單值-默認格式:

表格1
表格2
表格3

如果選擇了表格3(選擇列表值),則下次我打開該記錄時,默認情況下應顯示表格3。

如果選擇了Form 1(選擇列表值),則下次我打開該記錄時,默認情況下應顯示Form 1。

我已經在RetrieveFilteredForms消息中的systemform實體處注冊了一個插件,更新了userentityuisettings表,並且我能夠設置每次打開記錄時都會顯示的“ DEFAULT”,無論最后打開的表單是什么。

我已經在聯系人實體中注冊了一個插件,在“檢索消息”中,更新了userentityuisettings表,但是我發現Crm僅查詢該表。如果沒有更新屬性,則以下時間Crm采用默認形式從以下位置打開值:緩存。

這是一個老問題,但是由於在我搜索此問題時即將提出,因此我想添加我的解決方案。

我們使用Dynamics CRM2013。據我所知,2011年的更高版本也支持此技術。

打開實體時顯示的表單由以下幾項決定:默認表單,表單的安全角色和后備設置以及當前用戶對該實體使用的最后表單。 我們有一個與問詢者類似的問題,我們希望根據表格的值顯示不同的帳戶表格。 我們也厭倦了javascript技術不斷受到的不斷重載/刷新。

我發現了一些博客文章(特別是這篇文章: http : //gonzaloruizcrm.blogspot.com/2014/11/avoiding-form-reload-when-switching-crm.html ),其中提到可以將插件編寫為實體的檢索,使您可以從UserEntityUISettings中讀取值(LastViewedFormXml),該值存儲上一次使用的表單。 如果不是您想要的形式,則可以輸入所需的值。 這樣可以避免JavaScript表單刷新。

我不得不修改我發現的示例中的一些代碼才能使其正常工作,但是我對結果感到滿意。 您需要使用CrmSvcUtil生成實體類並將其包含在項目中。 您可以從表單編輯器的URL獲取表單指南。

using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;

namespace CRM.Plugin.AccountFormSwitcher
{
    public class Plugin : IPlugin
    {
        public enum accountType
        {
            Customer =  100000000,
            Vendor =     100000001,
            Partner = 100000002,
            Other =    100000003
        }

        public const string CustomerAccountFormId = "00000000-E53C-4DF4-BC99-93856EDD168C";
        public const string VendorAccountFormId = "00000000-E49E-4197-AB5E-F353EF0E806E";
        public const string PartnerAccountFormId = "00000000-B8C6-4E2B-B84E-729AA11ABE61";
        public const string GenericAccountFormId = "00000000-8F42-454E-8E2A-F8196B0419AF";

        public const string AccountTypeAttributeName = "cf_accounttype";

        public void Execute(IServiceProvider serviceProvider)
        {
            if (serviceProvider == null)
            {
                throw new ArgumentNullException("serviceProvider");
            }

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            var pluginContext = (IPluginExecutionContext)context;
            if (pluginContext.Stage == 20) //pre-operation stage
            {
                var columns = (ColumnSet)pluginContext.InputParameters["ColumnSet"];
                if (!columns.Columns.Contains(AccountTypeAttributeName))
                    columns.AddColumn(AccountTypeAttributeName);
            }
            else if (pluginContext.Stage == 40) //post-operation stage
            {
                EntityReference currentEntity = (EntityReference)context.InputParameters["Target"];
                if (currentEntity == null)
                    return;

                var query = new QueryExpression(Account.EntityLogicalName);
                query.Criteria.AddCondition("accountid", ConditionOperator.Equal, currentEntity.Id);
                query.ColumnSet = new ColumnSet(AccountTypeAttributeName);
                var accounts = service.RetrieveMultiple(query).Entities;
                Account currentAccount = (Account)accounts[0];

                SetForm(currentAccount, service, context.UserId);
            }
        }

        private void SetForm(Account account, IOrganizationService service, Guid userId)
        {
            var query = new QueryExpression(UserEntityUISettings.EntityLogicalName);
            query.Criteria.AddCondition("ownerid", ConditionOperator.Equal, userId);
            query.Criteria.AddCondition("objecttypecode", ConditionOperator.Equal, Account.EntityTypeCode);
            query.ColumnSet = new ColumnSet("lastviewedformxml");
            var settings = service.RetrieveMultiple(query).Entities;

            // Some users such as SYSTEM have no UserEntityUISettings, so skip.
            if (settings == null || settings.Count != 1 || account.cf_AccountType == null) return;

            var setting = settings[0].ToEntity<UserEntityUISettings>();
            string formToUse;
            switch ((accountType)account.cf_AccountType.Value)
            {
                case accountType.Customer:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", CustomerAccountFormId);
                    break;
                case accountType.Vendor:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", VendorAccountFormId);
                    break;
                case accountType.Partner:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", PartnerAccountFormId);
                    break;
                case accountType.Other:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", GenericAccountFormId);
                    break;
                default:
                    formToUse = String.Format("<MRUForm><Form Type=\"Main\" Id=\"{0}\" /></MRUForm>", GenericAccountFormId);
                    return;
            }

            // Only update if the last viewed form is not the one required for the given opportunity type
            if (!formToUse.Equals(setting.LastViewedFormXml, StringComparison.InvariantCultureIgnoreCase))
            {
                var s = new UserEntityUISettings { Id = setting.Id, LastViewedFormXml = formToUse };
                service.Update(s);
            }
        }
    }
}

為了解決詢問者的問題,它只咨詢了UserEntityUISettings一次,所以我不確定為什么會這樣。 但是,為什么在更改觸發屬性時不使用javascript更改表單? 那就是我所做的事情,但我並未遇到插件未顯示所需功能的任何問題。

編輯:OP指定后,他需要沒有javascript的解決方案,我保留此答復以供將來參考。

您可以使用javascript,在OnLoad事件中檢查選擇列表值並導航到所需的表單。 檢查此代碼作為示例

var value = Xrm.Page.getAttribute("new_optionset").getValue();

switch(value) {
case 100000000:
   Xrm.Page.ui.formSelector.items.get(0).navigate();
   break;
case 100000001:
   Xrm.Page.ui.formSelector.items.get(1).navigate();
   break;
case 100000002:
   Xrm.Page.ui.formSelector.items.get(2).navigate();
   break;
/// ... other cases here
default:
   // default form to open when there is no value
   Xrm.Page.ui.formSelector.items.get(0).navigate();
}

這是一個古老的東西,但是一個好東西。...我使用CRM規則來生成“隱藏選項卡”和“顯示選項卡”操作,這些操作本質上顯示了每個用戶角色不同的形式。

腳步:

  1. 用您要顯示的所有字段創建一個大規模的表單(如果您已經有很多表單,則將包括所有表單中的所有字段)。
  2. 將表單組織成TABS,每個選項卡顯示“一種表單”的數據價值。 (每個用戶組也可以有許多TABS)。 通常,我創建一個“常規”選項卡,其中設置了關鍵選項,將設置表單的其余部分,以及角色/用戶組/表單之間常見的任何字段,例如狀態,名稱等... 3)通過在管理用戶界面中取消選中那些標簽表單屬性表單上的可見框,可以隱藏除“常規”標簽之外的所有標簽。 4)使用CRM規則(crm-rules.com),然后可以使用該表單以及其中的所有選項卡和部分引入元數據。 然后,您只需要為要顯示的每個“表單”編寫一條規則即可。每條規則都采用以下格式:

    • 如果User_Role包含“銷售”,則“顯示”選項卡:“銷售”
    • 如果User_Role包含“營銷”,則顯示選項卡:營銷

當然,您也可以使用選項集或表單上的任何字段作為條件來執行此操作。此方法的好處之一是,如果用戶跨越角色邊界(或某些用戶是安全角色的一部分),可以訪問多個表格),這種技術可以同時顯示兩個表格...

HTH有人,CRM規則(www.crm-rules.com)生成JavaScript來實現此目標...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM