Dynamics CRM中Xrm.WebApi检测重复账户名报错求助
Dynamics CRM 账户名去空格重复检测(JS实现)
问题根源
Dynamics 365 Web API的OData查询不支持在contains函数中嵌套replace操作,这是你遇到报错的核心原因。以下提供两种可行的实现方案:
方案一:前端查询后过滤(适合小数据量场景)
先拉取所有活跃账户,在前端完成去空格后的匹配逻辑,避开OData查询的限制。
var isValidationNeeded = true; // 标记是否需要重复验证,避免循环触发 function checkForDuplicateAccountNames(executionContext) { var formContext = executionContext.getFormContext(); var currentAccountId = formContext.data.entity.getId(); var accountName = formContext.getAttribute("name").getValue()?.replace(/\s+/g, '') || ''; // 无账户名或已跳过验证时直接返回 if (!accountName || !isValidationNeeded) return; executionContext.getEventArgs().preventDefault(); // 查询所有活跃账户 var query = "?$select=name&$filter=statecode eq 0"; Xrm.WebApi.retrieveMultipleRecords("account", query).then( function success(result) { var hasDuplicate = false; // 遍历结果,去空格后匹配,排除当前编辑的记录(更新场景) result.entities.forEach(function(account) { var existingName = account.name.replace(/\s+/g, ''); if (existingName === accountName && account.accountid !== currentAccountId) { hasDuplicate = true; } }); if (hasDuplicate) { var confirmStrings = { text: "存在同名账户(已忽略空格),是否继续创建/更新?" }; var confirmOptions = { height: 200, width: 450 }; Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then( function (dialogResult) { if (dialogResult.confirmed) { isValidationNeeded = false; formContext.data.entity.save(); } }, function (error) { console.error("确认框错误:", error.message); } ); } else { isValidationNeeded = false; formContext.data.entity.save(); } }, function error(error) { console.error("查询账户错误:", error.message); // 查询失败时允许保存,可根据业务需求调整 isValidationNeeded = false; formContext.data.entity.save(); } ); }
方案二:使用计算字段(推荐,适合大数据量场景)
通过实体计算字段提前处理账户名的空格,将OData查询逻辑简化为普通匹配,性能更优。
步骤1:创建计算字段
- 在Account实体中新增单行文本类型的计算字段,示例名称:
name_without_spaces - 设置计算规则:
REPLACE(name, " ", "")(自动移除账户名中的所有空格) - 发布实体变更
步骤2:修改JS查询逻辑
var isValidationNeeded = true; function checkForDuplicateAccountNames(executionContext) { var formContext = executionContext.getFormContext(); var currentAccountId = formContext.data.entity.getId(); var accountName = formContext.getAttribute("name").getValue()?.replace(/\s+/g, '') || ''; if (!accountName || !isValidationNeeded) return; executionContext.getEventArgs().preventDefault(); // 构建过滤条件,排除当前编辑的记录 var filter = "name_without_spaces eq '" + accountName + "' and statecode eq 0"; if (currentAccountId) { filter += " and accountid ne " + currentAccountId.replace(/[{}]/g, ''); } var query = "?$select=name&$filter=" + encodeURIComponent(filter); Xrm.WebApi.retrieveMultipleRecords("account", query).then( function success(result) { if (result.entities.length > 0) { var confirmStrings = { text: "存在同名账户(已忽略空格),是否继续创建/更新?" }; var confirmOptions = { height: 200, width: 450 }; Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then( function (dialogResult) { if (dialogResult.confirmed) { isValidationNeeded = false; formContext.data.entity.save(); } }, function (error) { console.error("确认框错误:", error.message); } ); } else { isValidationNeeded = false; formContext.data.entity.save(); } }, function error(error) { console.error("查询账户错误:", error.message); isValidationNeeded = false; formContext.data.entity.save(); } ); }
通用注意事项
- 表单事件绑定:将函数绑定到Account表单的**保存(执行前)**事件,勾选“传递执行上下文”
- 避免循环触发:
isValidationNeeded变量用于标记已通过验证,防止保存时重复执行检测逻辑 - 更新场景兼容:通过
currentAccountId排除当前编辑的记录,避免误判为重复 - 特殊字符处理:方案二中使用
encodeURIComponent转义过滤条件,防止特殊字符导致查询失败
内容的提问来源于stack exchange,提问作者Bhaskar Sharma
相关产品推荐
相关产品推荐

