Monday, July 17, 2017

Dynamics CRM–Where is Status transition data stored in the DB

I was curious as to how status transition data is stored in the database for CRM and here is what I found:

The data is stored in the AttributePicklistValue table in the field “TransitionData” as string that represents xml

The XML looks like this:

<allowedtransitions xmlns="">
     <allowedtransition sourcestatusid="803000000" tostatusid="803000001" />
     <allowedtransition sourcestatusid="803000000" tostatusid="803000002" />
     <allowedtransition sourcestatusid="803000000" tostatusid="2" />

Here is some SQL that allows you to pull the data.

FROM Entity e
      JOIN Attribute a ON a.EntityId = e.EntityId
      JOIN AttributePicklistValue apv ON apv.OptionSetId = a.OptionSetId
      JOIN StringMap sm ON sm.ObjectTypeCode = e.ObjectTypeCode
                           AND sm.AttributeValue = apv.value
WHERE LEN(apv.TransitionData) > 0
ORDER BY e.LogicalName,

Here is a query that can pull back the OptionSets and their corresponding values

SELECT o.Name,
FROM AttributePicklistValueAsIfPublishedView v
      INNER JOIN LocalizedLabelAsIfPublishedView l ON v.AttributePicklistValueId = l.ObjectId
                                                      AND l.ObjectColumnName = 'DisplayName'
      INNER JOIN OptionSetAsIfPublishedView o ON v.OptionSetId = o.OptionSetId
WHERE LIKE 'opportunity_%'
ORDER BY o.Name;

Finally, the correct way to get at this data is via the service and here is the sample code: Retrieve valid status transitions

Friday, July 14, 2017

Debugging dynamic scripts injected into CRM Ribbon

If you need to debug javascript code thats invoked via the ribbon and the javascript is getting injected dynamically into the page, then you need a way to stop at a breakpoint.

One thing you can do is add a line at the top of your script with the following code:

This will cause the debugger to stop at that line and you can then work your way through the file.

But an even cooler way to do it (when using Google Chrome) is to add the following line at the very bottom:

//# sourceURL=dynamicScript.js

Now, when the code gets injected into Chrome, you will find it in the “Sources” tab.


You can name the file anything, and so if you have multiple points of injection, you can name each one differently.
Your breakpoints are preserved across reloads of the page (which is unlike using the debugger statement).
You need to look under the (no domain) header for the file.

And when using the log, use this function:

function logToConsole(message) { if (typeof console != 'undefined') { console.log(message); } }

Note: the reason I dont override log function is because I want to play nice with other JS scripts that maybe getting loaded within CRM. You need to use this especially in IE, as when the debugger is not shown, the console object can be null.

Saturday, July 08, 2017

Taking apart the Ryobi Expand-it string trimmer head

For some reason my Ryobi Expand-it electric trimmer head got stuck and would no longer spool out its line. I tried to take apart the head, but unfortunately, the instructions were not very clear.

It turns out that you turn the red knob right (in the same direction as the “Wind” arrows), when you have the bottom of the trimmer head facing you.


And obviously to tighten it, you turn it to the left. (Its the opposite of the righty tighty and lefty loosey rule!)

Also, I found that its a lot easier to refill the reel, once you take apart the head.