Knowledge found and lost while working with Microsoft Dynamics CRM
RSS icon Home icon
  • My pants were on fire and my ass was catchin

    Posted on February 18th, 2006 Mitch Milam Print Print 1 comment

    A funny thing happened to me last week.  What started out as a typical lunch with friends took a completely and unforeseen turn to the unbelievable.

    It all started as I headed to lunch with three friends at one of our favorite eateries.

    Not quite half way there, I noticed a rather warm sensation developing on my thighs and buttocks.  I found this to be quite surprising. While I must admit my thighs and buttocks have been known to become inflamed, it does not usually occur when I’m in an automobile with an outside temperature of forty degrees or so.

    “What, oh what, could be the problem,” I thought.  Actually I was just a little bit more vocal than that – yelling out something to the effect of “What the hell’s going on!”  It turns out that I’m rather sensitive about my thighs and buttocks being abnormally warmed.  Oh well; live and learn.  Life is but an adventure.

    Anyway, there were at least three separate conversations occurring at this moment.  All of which stopped when I became rather animated.

    My very first thought was that my so-called friend, the owner of the vehicle, was attempting to kill me – albeit slowly and unusually.  All I could determine was that he had wired the battery to my seat in a vain attempt at electrocution. 

    Either that or he had developed a “Fiendish Thingy” which relyed on Microwaves that were slowly but surely altering the chromostones of my yet unhatched offspring.

    Either way, I was quickly becoming excitable.

    About the time I was readying myself for a progeny-saving plunge out the truck door, it occurred to me that this was a fairly new vehicle and had all sorts of wonderful gadgets, features, and doo-dahs.

    Still in my excited state, with my voice raised to the limit of hearing for dogs, Moms, and very small children, I shouted “Does this truck have a passenger-side seat-warmer?”  “Why, yes it does.” Came the answer.  “Is it on?” I queried.  “I don’t know.  Probably.” Was the response.  “Well how the hell do I turn it off?”  The instructions were provided, followed to the letter, and at long last the ambient temperature of my buttocks returned to normal.  Whew!

    Lunch continued on as usual and though I have a fairly decent explanation of the event, I have yet to rule out an assassination attempt.  You just never can tell who your friends are these days.

    Copyright © 2000 by Mitch Milam

     

    Tall Tales
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,852 views
  • Some people have too much time on their hands

    Posted on February 18th, 2006 Mitch Milam Print Print No comments

    I was just watching a show on the Science Channel where they showed the guys who ride bicycles downhill on a snow-covered mountain.

    One guy had just achieved his personal best of ONE HUNDRED AND SEVEN FREAKING MILES AN HOUR.  On a bicycle.  In the snow.  And did I mention down the side of a mountain?  In the snow? 

    Do you know how you stop yourself on the snow should you happen to fall off the damn bike at 107 MPH?

    YOU DON'T.

    You keep moving until inertia and drag cancel each other out or you hit the side of a '73 Chevy pickup that's been left at the edge of the field because somebody put freaking SNOW on top of it and you don't know it's there.

    Or you hit a tree.  From personal experience, I can tell you that trees are nature's solution to inertial dampening.

    Also notice I said guys, and not people.  I didn't see any women doing this so-called sport.  Girls are probably way too smart of such foolishness.

     

    Meanderings
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,691 views
  • Understanding Entity Ownership in MSCRM 3.0

    Posted on February 18th, 2006 Mitch Milam Print Print 2 comments

    When you create a new Entity within MSCRM you have a choice to make regarding the ownership of that Entity.

    From the MSCRM 3.0 Help File:

    In the Ownership list, select either:

    • User
      Records for this entity can be owned by individual users. For example contact records are set to User.–   OR –
    • Organization
      Records for this entity are used for reference by all Microsoft CRM users, and so are not owned by individual users. For example, product records are set to Organization.

     

    While attending an MSCRM Troubleshooting class last week, I learned something that isn't readily apparant when you are creating enties:

    In order for a custom entity to be available to the CRM Workflow module, it must be created with an ownership of User.

    This was news to me, and unfortunately, unwelcome news. I had just created 12 custom Entities that had a combined total of over 100 Attributes and Relationships out the wazzoo. Since you can't change the Ownership type after creation, I was looking at spending a few hours deleting my existing Entities and recreating them from scratch. 

    And after thinking about it, I understand why the ownership requirement for workflow exists, I just wish it had been better documented.

    Anyway, I was thinking ( mustly hoping ) that there just had to be a way to alter the definition of the Entity without having to manually recreate it.  It turns out, there is, but it is a bit of work.

     

    The following information is provided as-is, without any warranty, either expressed or implied.

    It is probably unsupported by Microsoft as well.

    Use this information for reference and as a last-resort.  

     

    How Entities are Organized 

    With the exception of three Attributes, the tables of a User Owned Entity and an Organizational Owned Entity are exactly alike. The following table contains the Attributes created when you create both types of Entities. Those in bold are specific to that Ownership type.

    Organization Ownership User Ownership
    Name Type Name Type
    createdby lookup createdby lookup
    createdon datetime createdon datetime
    createdon datetime createdon datetime
    modifiedby lookup modifiedby lookup
    modifiedon datetime modifiedon datetime
    new_2blankoid primarykey new_2blankoid primarykey
    new_name nvarchar new_name nvarchar
    statecode state statecode state
    statuscode status statuscode status
    organizationid lookup ownerid owner
        owningbusinessunit lookup

    So, how do we convert an Entity from one ownership type to another as cleanly as possible and keeping the destruction to a minimum?  I've successfully performed the following steps and have seen no side effects.

    Step 1: Back up your CRM databases.

    Step 2: Export All Customizations.

    Even though you may only be working with one or two Entities, I feel it is best that all Entities be included in the export to ensure that we don't miss anything.

    Step 3: Make a backup copy of your exported customizations.

    Just in case your edits do not work as planned.

    Step 4: Delete the custom entity that needs to be reassigned Ownership.

    Sorry, there is just no way around this step. The Import Customizations process only adds data and changes, it will not delete anything, and we must delete attributes.  That means data loss.

    Step 5: Open the exported customizations in WordPad.

    Or whatever your favorite XML editor is.  Just remember how picky CRM 3.0 is about its XML format.  Personally, I use WordPad because it doesn't introduce additional line feed characters that so offend CRM.

    Note: Steps 6 – 8 will be repeated for each Entity that needs to be altered.

    Note 2: DO NOT attempt to copy the following XML from this blog and insert it into your CRM Export file. It will break the file and you will be unable to import it.  I would suggest Exporting a single Entity with User Ownership and have that open in a separate WordPad instance to copy the code from.

    Step 6: Change the ownership type.

    Find the following code: 

    <OwnershipTypeMask>OrgOwned</OwnershipTypeMask>
    And replace it with the following:

    <OwnershipTypeMask>UserOwned</OwnershipTypeMask>
     

    Step 7:  Remove the Organization Attributes and Insert the User Attributes

    DELETE THE FOLLOWING CODE

    <attribute PhysicalName="OrganizationId">
    <Type>lookup</Type>
    <ValidForReadApi>1</ValidForReadApi>
    <ReferencedEntityObjectTypeCode>1019
    </ReferencedEntityObjectTypeCode>
    <Description>Unique identifier for the organization</Description>
    </attribute>
    INSERT THE FOLLOWING CODE

    <attribute PhysicalName="OwnerId">
    <Type>owner</Type>
    <IsNullable>0</IsNullable>
    <ValidForCreateApi>1</ValidForCreateApi>
    <ValidForUpdateApi>1</ValidForUpdateApi>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <DisplayMask>ValidForAdvancedFind|ValidForForm|ValidForGrid
    </DisplayMask>
    <Description>Owner Id</Description>
    </attribute>
    <attribute PhysicalName="OwnerIdDsc">
    <Type>int</Type>
    <IsNullable>0</IsNullable>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <AttributeOf>OwnerId</AttributeOf>
    <XmlAbbreviation>dsc</XmlAbbreviation>
    <Description />
    </attribute>
    <attribute PhysicalName="OwnerIdName">
    <Type>nvarchar</Type>
    <Length>320</Length>
    <IsNullable>0</IsNullable>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <AttributeOf>OwnerId</AttributeOf>
    <XmlAbbreviation>name</XmlAbbreviation>
    <IsSortAttribute>1</IsSortAttribute>
    <Description>Name of the owner</Description>
    </attribute>
    <attribute PhysicalName="OwnerIdType">
    <Type>int</Type>
    <ValidForCreateApi>1</ValidForCreateApi>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <DisplayMask>ObjectTypeCode</DisplayMask>
    <AttributeOf>OwnerId</AttributeOf>
    <XmlAbbreviation>type</XmlAbbreviation>
    <Description>Owner Id Type</Description>
    </attribute>
    <attribute PhysicalName="OwningBusinessUnit">
    <Type>lookup</Type>
    <ValidForReadApi>1</ValidForReadApi>
    <ReferencedEntityObjectTypeCode>10
    </ReferencedEntityObjectTypeCode>
    <Description>Unique identifier for the business unit that owns the record</Description>
    </attribute>
    <attribute PhysicalName="OwningUser">
    <Type>lookup</Type>
    <ValidForCreateApi>1</ValidForCreateApi>
    <ValidForUpdateApi>1</ValidForUpdateApi>
    <ValidForReadApi>1</ValidForReadApi>
    <ReferencedEntityObjectTypeCode>8
    </ReferencedEntityObjectTypeCode>
    <AggregateOf>OwnerId</AggregateOf>
    <Description>Unique identifier for the user that owns the record.</Description>
    </attribute>
     

    Step 8: Change the form fields from Organization to User. 

    DELETE THE FOLLOWING

    <field name="organizationid" requiredlevel="na">
    <displaynames>
    <displayname description="Organization Id" languagecode="1033" />
    </displaynames>
    </field>
    INSERT THE FOLLOWING

    <field name="ownerid" requiredlevel="na">
    <displaynames>
    <displayname description="Owner" languagecode="1033" />
    </displaynames>
    </field>
    <field name="owningbusinessunit" requiredlevel="na">
    <displaynames>
    <displayname description="Owning Business Unit" languagecode="1033" />
    </displaynames>
    </field>

    Step 9: Save and close the Export file

    Step 10: Import the modified Exported customizations

    Step 11: Publish All Customizations

    Do this before you do anything else with the system as it will ensure that all of the data is completely replication throughout the CRM 3.0 system.

    Finished.

    Just to make sure everything is fine within the CRM 3.0 system, I perform the additional steps:

    Step 12: Add a temporary Attribute to the altered Entity.

    This is really just to make sure that the CRM Entity modification process still functions as expected.

    Step 13: Add that Attribute to the data entry Form.

    Step 14: Publish the Entity

    Step 15: Create and save a new record for the altered Entity.

    Step 16: Delete the temporary Attribute from the Entity.

    Step 17: Publish the Entity.

    Really Finished.

     

    Good luck and if you find any issues, please let me know.

     

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 4.33 out of 5)
    Loading ... Loading ...
    5,178 views
  • MSCRM 3.0 Entity Deletion Caveats

    Posted on February 18th, 2006 Mitch Milam Print Print No comments

    Deleting Entities from within MSCRM 3.0 is fairly staightforward but you need to keep the following things in mind:

    • You can't delete system Entities.
    • You can't delete an Entity if it is being referenced on a Form of another Entity. An error message will be displayed alerting you to the references to that Entity.

    To accomplish this, you must perform the following steps:

    1. Edit the form that contains the reference to the Entity that you wish to delete. ( This is usually a Lookup field produced by adding a Relationship between two Entities. )
    2. Remove the Lookup field and save the Form.
    3. Save the Entity.
    4. Publish the Entity.
    5. Select the Entity you wish to Delete and click the Delete button.
    6. Repeat steps 1-5 until you actually delete the Entity.
    • As a safety measure, select More Actions, then Publish All Customizations, so that you can be sure that the entire CRM system has been notified of any changes you have made.

     

     

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,609 views
  • MSCRM 3.0 Exporting and Importing Customization Notes

    Posted on February 18th, 2006 Mitch Milam Print Print 6 comments

    MSCRM 3.0 allows you to Export customizations from one system and Import those same customizations into another system.  This is handy should you have separate development and test environments and need to move configurations between the two.

    You can also Export customizations such as the Site Map and ISV.Config file, perform required modifications, and Import the altered files back into the same system.

    However, there are a few caveats to keep in mind when performing these processes:

    • Imported customizations are not automatically published, so you mush manually publish the changes.
    • If you are making sweeping changes to the system, i.e., making many entity modificiations, it is sometimes necessary to Publish those changes immediately after the Import, in order for the system to become fully aware of them.

    I have seen instances where I was unable to edit an Entity after Import. I first had to Publish that Entity, then edit it.

    • If you export a large number of Entities ( or All of them ), the Import may fail with a SQL error if you choose to Import All Customizations. The work around it to just select all of the Entities then select More Actions, Import Selected Customizations.
    • Relationships between Entities are not maintained unless you export all of the related Entities together.For example, let's say you have a custom Entity called Jobs that is related to an Entity called Time.  If you Export Jobs from one CRM system, and Import it into another CRM system, the Relationship with the Time Entity will be lost, because the information was not Exported from the original CRM system. Even if you later Exported and Imported the Time Entity, the Relationship would still not exist.Exporting both Jobs and Time Entities will ensure that the relationships will be maintained during the process.
    • There are two Entities that, if improperly altered, can cause the MSCRM system to fail to load and/or function properly: Site Map and ISV.Config.  If you have made massive changes to the CRM system and are Importing the entire system, you wish way to perform a two-stage Import and Import those two Entities in the second stage.
    • If you import customizations including an ISV.Config file that contains errors, the import will succeed, but Microsoft CRM will not start, and the following error will be displayed “SiteMap error.”Workaround: In your browser, open
      http://[microsoft_crm_servername]/tools/systemcustomization/
      ImportCustomizations/importCustomizations.aspx

      and import a corrected ISV.Config file.
    • If you are moving your configuration from a Development CRM system to an existing Production CRM system and have changed the Type of an Attribute ( say from a nvarchar to an int ), you will need to delete the Attribute from the Entity on the Production CRM system before you attempt the Import. Otherwise, the Import will more than likely fail because the Import will not alter the Attribute Type and SQL Server will generate an error when it finds an nvarchar when it expects an int.

    Note: I am going to assume that I don't need to tell you that you'll loose data when you delete the Attribute – so plan ahead for that.

     

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    3,807 views
  • Researching MSCRM 3.0 Internals

    Posted on February 18th, 2006 Mitch Milam Print Print No comments

    In the Microsoft Business Solutions CRM Developer Newsgroup, Arne Janning gave an excellent suggestion for those of you with developer inclinations and a willingness to explore the MSCRM system to learn more about its inner-workings.

    Open Notepad and create a file that looks like this:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
      <ItemGroup>
        <Item Include="*/**" />
      </ItemGroup>
    </Project>
     
     

    Note: If you copy and paste the above text into notepad or VS2005, make sure the double-quotes are normal double-quotes and not the special "pretty" quotes. VS doesn't like the fancy quotes and will give you errors when you attempt to open the file.

    Save this with a .csproj extension in the root-folder of your MSCRM web site. Load Visual Studio 2005, select Open Project, navigate to the MSCRM web site then double-click on the .csproj file.Just don't do anything unwise like saving any of the files. We don't want to run the risk of upsetting CRM in any way – or damaging the files and rendering the site unusable.

    I also hope I don't need to state that it is a really bad idea to do this to a production server, do I?

     

    References:

    CRM Developer Newsgroup Post

     

     

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,954 views
  • Including custom JavaScript files in MSCRM 3.0

    Posted on February 18th, 2006 Mitch Milam Print Print 7 comments

    The more you get into MSCRM development, the more you will probably realize that you are writing quite a bit of JavaScript to control various aspects of the CRM Client experience.  As most programmers find, the more code you write, the more you write code.  You also start developing a code library containing your most often used functions so that you don't have to rewrite them each time you need them.

    In most programming languages, the concept of an Include File exists. Include files are usually referenced at the beginning of your source code file and are merely instructions to your compiler, interpreter, or whatever, to include the contents of that file within your program. 

    This allows you to create a library of related sub-routines or functions that can be referenced from any number of other programs. Since you only have one copy of those routines, it cuts down on your maintenance requirements.

    So how does any of this relate to MSCRM?

    MSCRM version 3.0 gives you the ability to peform actions when the value of a form field changes – the OnChange Event.  This allows you to take action whenever a user changes a particular form.  Take a look at this example:

    The OnChange events for both Price and Quantity contain the following JavaScript code to automatically add the two fields together:

    crmForm.all.new_total.DataValue=
    crmForm.all.new_price.DataValue*
    crmForm.all.new_quantity.DataValue 

    This is really not very much code and there are really only two fields involved so it's pretty easy to maintain.  But, what happens if you have five or ten fields to calculate. That really becomes work at that point, and it can create a maintenance nightmare as well.

    You can solve this problem by putting the above JavaScript into a file on disk and include that file in the Form's OnLoad event.  Here's how it will work:

     

    Create the .js file:

    Open Notepad and copy the following Javascript into it

    function OrderFormAdd()
    {
       crmForm.all.new_total.DataValue=
       crmForm.all.new_price.DataValue*
       crmForm.all.new_quantity.DataValue 
    }

    Save this file as myfunctions.js and place it in a directory below your MSCRM web directory called myscripts.

     

    Reference your .js file:

    In the OnLoad event of your Form, include the following code: 

    var script = document.createElement('script');
    script.language = 'javascript';
    script.src = '/myscripts/myfunctions.js';
    document.getElementsByTagName('head')[0].appendChild(script);

     

    Update the OnChange Events:

    Now we need to update the OnChange events for the Price and Quantity fields. Remove the existing JavaScript and replace it with the following:

    OrderFormAdd();

     

    Save and publish your form and you are done.  From now on, any time you need to modify the calculation on the Order Form, just edit the myfunctions.js file. No additional work needs to be done to the CRM Form.

    Note:

    • If you make a change to the .js file and you don't see the change take effect, delete your browser's temporary Internet files and try it again. The client can cache the .js and it will be using the older copy instead of the newly updated master copy.

     

    Using Included Functions in the Form OnLoad Event:

    It was pointed out by "Alex" who wrote the actual JavaScript include code that it is possible to run into a timing issue because the include file has not yet finished appending to the CRM Form.  This is really only a problem if you need to access a function from your include file from within the OnLoad event.

    To circumvent this issue, we need to wait for the script's state to change to "loaded" before any functions in the include file can be accessed:

    var script = document.createElement('script');
    script.language = 'javascript';
    script.src = '/myscripts/myfunctions.js';
    document.getElementsByTagName('head')[0].appendChild(script);

    var f = function()
    {
      if (event.srcElement.readyState == "loaded")
       SomeFunction(); // some function from MyFunctions.js
    }

    script.attachEvent("onreadystatechange", f);

     

    Additional Notes:

    This solution will not work if you have the CRM 3.0 Outlook Laptop Client deployed. This is because the Laptop client utilizes a local Web server and if physically disconnected from the main CRM web server, the JavaScript file will be unavailable and a script error on the page will result.

    In addition, since the JavaScript file is not actually part of the CRM system, it is not replicated to the Laptop client during syncronization.

    Michaeljon Miller has a post discussing CRM SDK access while offline.

     

    References:

    The JavaScript code for this article was taken from a newsgroup conversation between Ronald Lemmen and "Alex."  Please consult the original thread for context.

    CRM Developer Newsgroup Post

    Using the CRM SDK offline

     

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 4.50 out of 5)
    Loading ... Loading ...
    9,340 views
  • Emoticons: the next generation

    Posted on February 18th, 2006 Mitch Milam Print Print No comments

    Ok, this is not something that my Mom would like nor understand, but most people will think it's funny.

    Assicons

     

     

    Meanderings
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    873 views
  • Many to Many in Microsoft CRM 3.0

    Posted on February 18th, 2006 Mitch Milam Print Print No comments

    Ben Vollmer has written an excellent article describing how to create a pseudo many-to-many relationship within MSCRM 3.0.

    In case you didn't know, MSCRM 3.0 doesn't natively support many-to-many, or one-to-one relationships and as Ben states: it's "One of the things that has driven a few newer partners who are used to other CRM Systems bonkers…"

    Check out Ben's article should you need to create a many-to-many relationship.

    Customization, Dynamics CRM
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,815 views
  • A watch that even I would like to own

    Posted on February 18th, 2006 Mitch Milam Print Print No comments

    [via OhGizmo ]

    I'm really not a techno-geek like a lot of my friends, but this watch is pretty cool: 

    Taluswatch

    It's called the Talus Abouttime.  They also have a watch called the Talus Timeline, but I don't think it's nearly as cool as Abouttime.

    Visit The Talus Watches for a demo.

     

    Misc
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,758 views