14

Tôi đang làm việc trên một số tùy chỉnh trực tuyến CRM 2011 và tôi cần có một thực thể bằng cách sử dụng javascript.CRM 2011: Bắt thực thể với Javascript

Pháp nhân tôi cần sẽ dựa trên giá trị ID của một trường khác (thực thể Liên hệ) - ID liên hệ này tôi có thể bị phạt.

Pháp nhân tôi muốn là một thực thể tùy chỉnh. Có thể có nhiều trận đấu dựa trên liên hệ ID vì vậy tôi chỉ muốn được là người đầu tiên trong danh sách (theo thứ tự không quan trọng)

Cho đến nay tôi đã nhìn vào một số cách để làm điều này ...

  • OData - tôi không thể tìm thấy đủ các ví dụ về vấn đề này như những gì biểu thức truy vấn tôi có thể tạo ra, tôi cũng không biết nếu/làm thế nào để thực hiện tác phẩm này với thực thể tùy chỉnh

  • FetchXML - tôi có thể tạo ra một truy vấn FetchXML tốt đẹp bằng cách sử dụng "tìm kiếm nâng cao" được tích hợp sẵn và sẽ rất vui khi gọi điều này từ javascript nếu có ai có thể trợ giúp? Tôi đã tìm thấy một câu trả lời đầy hứa hẹn here nhưng tôi không thể thấy dữ liệu trả về "kết quả" đã được đặt như thế nào (chức năng Service.Fetch)

  • Yêu cầu SOAP - Điều đầu tiên tôi đã thử là một phương pháp tương tự như tôi có thể thực hiện trong CRM 4 nhưng điều này dường như không hoạt động. Mặc dù yêu cầu thực thi, dữ liệu kết quả của tôi dường như trống. Đây là tất cả tôi có mã cho vì vậy nếu có ai có thể phát hiện một vấn đề với mã dưới đây thì đó sẽ là tuyệt vời.

EDIT: Tôi đã phát hiện một số dữ liệu truy vấn dư thừa (Tôi đã loại bỏ liên kết mở thẻ nhưng lại thẻ đóng) - kể từ khi loại bỏ này bây giờ tôi có được dữ liệu kết quả XML ... Tuy nhiên, mệnh đề where không dường như áp dụng (chỉ nhận được danh sách tất cả các đối tượng)

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\">" + 
    GenerateAuthenticationHeader() + 
    "<soap:Body>" + 
    "<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" + 
    "<query xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:QueryExpression\">" + 
    "<q1:EntityName>new_vehicle</q1:EntityName>" + 
    "<q1:ColumnSet xsi:type='q1:ColumnSet'>" + 
    "<q1:Attributes>" + 
    "<q1:Attribute>new_vehicleid</q1:Attribute>" + 
    "<q1:Attribute>new_primarydriver</q1:Attribute>" + 
    "<q1:Attribute>statuscode</q1:Attribute>" + 
    "<q1:Attribute>new_registration</q1:Attribute>" + 
    "</q1:Attributes>" + 
    "</q1:ColumnSet>" + 
    "<q1:Distinct>false</q1:Distinct>" + 

    "<q1:Conditions>" + 

        "<q1:Condition>" + 
        "<q1:AttributeName>new_primarydriver</q1:AttributeName>" + 
    "<q1:Operator>Equal</q1:Operator>" + 
    "<q1:Values>" + 
    "<q1:Value xmlns:q2='http://microsoft.com/wsdl/types/' xsi:type='q2:guid'>" + 
    customerID + 
    "</q1:Value></q1:Values></q1:Condition>" + 

    "</q1:Conditions>" + 

    "</query></RetrieveMultiple>" + 
    "</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/RetrieveMultiple"); 
    xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); 
    xmlHttpRequest.setRequestHeader("Content-Length", xml.length); 
    xmlHttpRequest.send(xml); 

    var result = xmlHttpRequest.responseXML.xml; 
    var doc = new ActiveXObject("MSXML2.DOMDocument"); 
    doc.async = false; 
    doc.loadXML(result); 

    var id = doc.selectSingleNode("//new_vehicleid"); 
    var registration = doc.selectSingleNode("//new_registration"); 

    if(id == null) 
     return null; 

    var vehicle = new Array(); 
        value[0] = new Object(); 
        value[0].id = id; 
        value[0].name = registration; 
        value[0].entityType = "new_vehicle"; 

    return vehicle; 

xin lỗi về mã bưu điện lớn nhưng hy vọng ai đó có một sự hiểu biết tốt hơn có thể giúp

Trả lời

28

Thứ nhất, nhờ vào GlennFerrieLive cho bài trả lời của mình. Các mẫu tôi tìm thấy với Dynamics CRM 2011 SDK (cũng chỉ là một trong những đặc biệt) thực sự giúp đỡ và phân tích cú pháp JSON bao gồm là hoàn hảo cho công việc!

Tôi đăng câu trả lời này để đưa ra một ví dụ đầy đủ về cách tôi đã làm điều đó với một số nhận xét quan trọng cần chú ý đến mà có thể không rõ ràng từ ví dụ về SDK.


Hãy chọn giá trị ID từ lĩnh vực tra cứu

Mục đích của nhiệm vụ của tôi là sử dụng javascript để có được thiết lập một lĩnh vực tra cứu, dựa trên dữ liệu được chọn của một thực thể tra cứu. Thực thể cần đặt là "new_vehicle" và đối tượng cần truy vấn là "khách hàng".

Công việc đầu tiên là lấy giá trị ID của trường tra cứu địa chỉ liên hệ ...

var customerItem = Xrm.Page.getAttribute("customerid").getValue(); 
var customerID = customerItem[0].id; 

Truy vấn một thực thể sử dụng một ID

Tiếp theo là phần mà tôi đã sử dụng các giá trị ID khách hàng để tìm ra chiếc xe đang được gán cho họ (đơn vị tôi muốn sử dụng để đặt trường tra cứu).

Vấn đề đầu tiên tôi thấy được rằng khi truy vấn với OData, giá trị ID dường như không làm việc với dấu ngoặc nhọn {} - do đó, những cần phải được loại bỏ ...

customerID = customerID.replace('{', '').replace('}', ''); 

Tiếp theo chúng tôi nhận được oDataPath ...

var oDataPath = Xrm.Page.context.getServerUrl() + "/xrmservices/2011/organizationdata.svc"; 

Sau đó, chúng ta có thể xây dựng các truy vấn OData ...

var filter = "/new_vehicleSet?" + 
    "$select=new_vehicleId,new_Registration" + 
    "&$filter=new_PrimaryDriver/Id eq (guid'" + customerID + "')" + 
    "&$orderby=new_LastAllocationDate desc" + 
    "&$top=1"; 

CHÚ Ý: có một coupl e điều quan trọng cần lưu ý ở đây ...

  1. Khi sử dụng một giá trị guid bạn một cách rõ ràng phải nói đó là một guid sử dụng (guid'xxx')
  2. Khi lọc theo một thực thể tra cứu (ví dụ new_PrimaryDriver), bạn phải thêm giá trị để truy vấn (ví dụ Id) - điều này dẫn đến new_PrimaryDriver/Id

Một khi chúng ta đã thiết lập truy vấn, chúng tôi có thể yêu cầu các dữ liệu như sau ...

var retrieveRecordsReq = new XMLHttpRequest(); 
retrieveRecordsReq.open("GET", oDataPath + filter, true); 
retrieveRecordsReq.setRequestHeader("Accept", "application/json"); 
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
retrieveRecordsReq.onreadystatechange = function() { 
    if (this.readyState == 4) { 
     if (this.status == 200) { 
      var retrievedRecords = JSON.parse(retrieveRecordsReq.responseText).d; 
      if(retrievedRecords.results.length > 0) 
      { 
       var vehicle = retrievedRecords.results[0]; 
       SetLookup("new_replacedvehicle", vehicle.new_vehicleId, vehicle.new_Registration, "new_vehicle"); 
      } 
     } 
    } 
}; 
retrieveRecordsReq.send(); 

Note rằng đây là một cuộc gọi không đồng bộ và hàm onreadystatechange sẽ được xử lý khi hoàn thành, trong hàm này chúng ta thực hiện một vài kiểm tra để xem nó có thành công hay không và chúng tôi phân tích cú pháp dữ liệu JSON kết quả - hàm JSON.Parse đã được đưa vào cuối bài đăng này (nhưng có sẵn từ số SDK)


Thiết lập một lĩnh vực tra cứu bằng cách sử dụng thực thể truy vấn trên

Chức năng khác để làm cho lưu ý ở đây là SetLookup mà chỉ là một chức năng helper đơn giản tôi đã thêm để thiết lập một lĩnh vực tra cứu. Đây là như sau ...

function SetLookup(fieldName, idValue, textValue, typeValue) 
{ 
    var value = new Array(); 
    value[0] = new Object(); 
    value[0].id = idValue; 
    value[0].name = textValue; 
    value[0].typename = typeValue; 

    Xrm.Page.getAttribute(fieldName).setValue(value); 
} 

chức năng phân tích cú pháp JSON

Đây là chức năng helper JSON đã được sử dụng trong đoạn code trên (JSON.parse), dán như nó đã được tìm thấy trong các SDK ...

if (!this.JSON) { this.JSON = {}; } (function() { function f(n) { return n < 10 ? '0' + n : n; } if (typeof Date.prototype.toJSON !== 'function') { Date.prototype.toJSON = function (key) { return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z' : null; }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) { return this.valueOf(); }; } var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' }, rep; function quote(string) { escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { var i, k, v, length, mind = gap, partial, value = holder[key]; if (value && typeof value === 'object' && typeof value.toJSON === 'function') { value = value.toJSON(key); } if (typeof rep === 'function') { value = rep.call(holder, key, value); } switch (typeof value) { case 'string': return quote(value); case 'number': return isFinite(value) ? String(value) : 'null'; case 'boolean': case 'null': return String(value); case 'object': if (!value) { return 'null'; } gap += indent; partial = []; if (Object.prototype.toString.apply(value) === '[object Array]') { length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || 'null'; } v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } if (rep && typeof rep === 'object') { length = rep.length; for (i = 0; i < length; i += 1) { k = rep[i]; if (typeof k === 'string') { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } if (typeof JSON.stringify !== 'function') { JSON.stringify = function (value, replacer, space) { var i; gap = ''; indent = ''; if (typeof space === 'number') { for (i = 0; i < space; i += 1) { indent += ' '; } } else if (typeof space === 'string') { indent = space; } rep = replacer; if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { throw new Error('JSON.stringify'); } return str('', { '': value }); }; } if (typeof JSON.parse !== 'function') { JSON.parse = function (text, reviver) { var j; function walk(holder, key) { var k, v, value = holder[key]; if (value && typeof value === 'object') { for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } } } } return reviver.call(holder, key, value); } text = String(text); cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }); } if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { j = eval('(' + text + ')'); return typeof reviver === 'function' ? walk({ '': j }, '') : j; } throw new SyntaxError('JSON.parse'); }; } }()); 
+0

CRM Dynamics ?, không mua nó nếu bạn cần tùy chỉnh: D Yêu cầu đơn giản, triển khai phức tạp ... – Legends

Các vấn đề liên quan