Wednesday, April 18, 2012

Outlook Macro

We use a 3rd party product to integrate Salesforce.com with Outlook.  The client that we use is a add-in for Outlook and for contact integration, it relies on the contact's MessageClass property's value to be "IPM.Contact".  We've seen various products change the MessageClass from IPM.Contact to something else, like IPM.Contact.olTrans (for card scanners).  Blackberry will also change the MessageClass in some cases.  As a result, our add-in is not able to synch certain contacts with Salesforce.com.  To get around this, I created a small macro based on some sources I've seen online to flip the MessageClass and exposed the macro as a button within the Contact ribbon in Outlook 2010.  Below is the source code to change the MessageClass:




Sub Convert2Native()

Dim objApp As Outlook.Application
Dim objNS As NameSpace
Dim objSelection As Outlook.Selection
Dim objItem As ContactItem
Dim debugMode As String
Dim VarFileName As String


Set objApp = CreateObject("Outlook.Application")
Set objNS = objApp.GetNamespace("MAPI")
Set objSelection = objApp.ActiveExplorer.Selection

debugMode = "no"

'setup logging
VarFileName = "C:\OutlookConvert2NativeLog" & "_" & Year(Now) & "_" & Month(Now) & "_" & Day(Now) & "_" & Hour(Now) & Minute(Now) & Second(Now) & ".txt"
Open VarFileName For Append As #2
Print #2, "Opening logging"
 
Print #2, "debugMode = " & debugMode
 
MsgBox "Converting " & objSelection.Count
Print #2, "Converting " & objSelection.Count


If debugMode = "yes" Then
    For Each objItem In objSelection
        If objItem.MessageClass = "IPM.Contact" Then
            Print #2, "Converted Contact " & objItem.LastName & " from MessageClass " & objItem.MessageClass
            objItem.MessageClass = "IPM.Contact.olTrans"
            objItem.Save
        Else
            Print #2, "Did not convert Contact " & objItem.LastName & " from MessageClass " & objItem.MessageClass
        End If
    Next
Else
    For Each objItem In objSelection
        If objItem.MessageClass <> "IPM.Contact" And objItem.MessageClass <> "IPM.Contact.SD.Contact" And objItem.MessageClass <> "IPM.Contact.SD.Contact.Private" Then
            Print #2, "Converted Contact " & objItem.LastName & " from MessageClass " & objItem.MessageClass
            objItem.MessageClass = "IPM.Contact"
            objItem.Save
        Else
            Print #2, "Did not convert Contact " & objItem.LastName & " from MessageClass " & objItem.MessageClass
        End If
    Next
End If

Close #2

End Sub
-------------------
Sources (thank you!):
http://msdn.microsoft.com/en-us/library/ee814736.aspx

http://ideasmiths.wordpress.com/2007/07/17/solution-macro-program-to-change-some-fields-in-outlook-2007-contacts-in-bulk/



Monday, January 9, 2012

Spring 2012

I was thumbing through the Spring 2012 release and for the first time since Chatter was released, I was impressed with the haul of changes.




Here are some highlights coming in early February to a Salesforce instance near you:

Salesforce for Outlook

  • We use a Outlook plug-in that synchronizes Salesforce contacts, events, etc with Salesforce but it is neither Salesforce for Outlook nor Connect for Outlook.  The primary driver for going with a 3rd party's solution was the inability of Salesforce for Outlook users to discriminate between private and public Contacts and tasks/meetings.  Salesforce has finally addressed this shortcoming, over 2 years since the Salesforce for Outlook plug in was released.

Workflows

  • We'll have to see exactly how this works and the limitations around it but one of the potentially more significant changes coming in Spring 12 is the cross-object workflow.  Hopefully, we can avoid the need to write triggers for basic field updates.  Again, this is one that has been in the pipeline for years and glad to see Salesforce finally address it.

Reports

  • It's hilarious to me that Salesforce no longer calls these "reports" but rather has latched onto the buzz around "Analytics".  Whatever it is, they've improved the service markedly.  The most notable improvements to me are the following:
    • You can now run an exception report like "Account without Opportunities".  To do this previously, you almost certainly had to export the results of two different reports into Access, Excel, or SQL Server.  You'll see this tagged in the documentation under "Cross Filters".
    •  The other significant improvement should now allow us to create reports like Opportunities with Activities and Contacts.  Previously, you could have Parent -> Child -> Grandchild, but not Parent -> Child -> Sibling.  Again, we'll see how this actually looks soon, but this is potentially a big improvement.

Apex

  • A couple notable changes for developers to keep an eye on:
    • The number of schedule Apex jobs has been increased from 10 to 25.
    • Test methods can no longer use existing customer data (with the exception of user/profile and record type).  This means all test methods will now need to create new data.  It looks like they've created an exception but for those of us w/ existing non-compliant code, we'll have to do some retrofitting with the "SeeAllData" property.

 

Thursday, December 29, 2011

It is frustrating how difficult it can be to trace down permission-related issues in Salesforce.  Without any clues from the debug log regarding the sharing rules or permissions that are applied when attempting to access/edit a record, the process of elimination in debugging user permissions can be time consuming.

Thank goodness for Google.

We want to allow our sales staff to take ownership of contact records that are created in Salesforce via an integration with our accounting software.  These records, by default, are owned by a system user account, which in our current implementation, does not have a role.

Based on my initial research, I found that there were a couple "nuclear" options:

  1. Give the sales user profile, the permission Modify All for the Contact object
  2. Give the sales user profile, the permission Transfer Records
Neither of these options were appealing to me so I kept searching and finally came across this Salesforce message board:


In one of the posts where a user has paraphrased (I suppose) some documentation somewhere, this blurb got my attention:

  • "Standard Users can transfer ownership of any lead, contact, account, case or opportunity record that he/she owns or that is owned by a user below him/her in the role hierarchy (except campaigns). "

Through some testing, I've confirmed that this would potentially solve our problem, but I am still frustrated with how poor Salesforce's debugging and documentation is when it comes to permissions.  While verifying the statement above regarding the role hierarchy, I came across this official doc:


And of course:
  • "The role hierarchy is not maintained with sharing records. Instead, role hierarchy access is derived at runtime."

Wednesday, November 30, 2011

Buyer Beware

Have you ever interviewed a contractor over the phone and agreed to bring them on the job site only to discover that they knew alot less than your interview might suggest?

A few years ago while doing Siebel work, I was tasked with finding a contractor to augment our staff to hit a critical deadline.  Myself and a colleague ran the candidate through the gauntlet asking very technical, very specific Siebel questions.  While language skills were not the candidates best quality, he seemed to know the material and so we agreed to bring him on site.  When he arrived and we provisioned accounts for him, we expected him to hit the ground running.  Instead, we ended up explaining very basic CRM concepts to him and found out that he was asking other contractors similarly basic Siebel questions.  I was furious and asked my manager to let him go.  She insisted that he stay because "he's already signed an apartment lease".

I recently learned from a friend in India that this practice of "proxy interviewing" exists and very well qualified people are approached with a good sum of money to interview on behalf of someone else.  While my experience with this suggested that this happened in our field, I was shocked to hear it confirmed from a reliable source.  Regardless of the motivations of either person, this is fraud and completely reprehensible to me.  My advice to anyone interviewing a technical contractor: do not assume that a good phone interview is enough.  Interview the candidate in person.


Wednesday, November 23, 2011

Where *not* to find salesforce help!

Our business partners recently requested that we relabel the out-of-the-box Note and Attachments object in Salesforce.  I had heard a rumor that salesforce could do some back end changes that were not possible through the Setup config and had searched the internet far and wide.  I had even posted a question on several LinkedIn forums, where the only two responses were 1) a pitch for consulting services and 2) this:
Anyway, after opening two cases and escalating one to tier 3, I finally got a definitive answer that it was not possible.  My case owner had actually queried every salesforce instance for any changes to this label across all of their customers and had confirmed that it was not possible without creating a custom VF page.

Friday, November 11, 2011

CastIron and your org's schema

I recently built a orchestration to go through our salesforce org and write to a salesforce object all of the object names and labels, field names and label, and field lengths and data types.  The orchestration was pretty easy to build and has been incredibly useful to provide a data dictionary to our business partners.  Its a different way to use castiron and something to consider if you need to do any data mapping or data migration activities.

Here's the recipe:
1 enterprise salesforce wsdl - this is your org's wsdl w/ all of its customizations
1 castiron dev studio
1 custom salesforce object to hold your object name, field names, length, data type, etc

Use the built in CastIron connector to salesforce to log in and use the session id in your subsequent webservice calls (where the enterprise wsdl was used to define the endpoint).  Once you've logged in you should be able to describe all objects, iterate through each object, and grab the details you want.  The last step is a the insert to your custom salesforce object where you map the object and its details.

Wednesday, October 26, 2011

Salesforce Permission Sets Are Great!

How many times have you had a requirement that applied to all people of a particular profile except maybe one or two?  For example, you have a sales team profile which most people fit into but you have one power user who may need access to a power user only field.  Prior to permission sets, you'd need to keep two different profiles tied to two different page layouts to hide one field.  With permission sets, you can make the special field available to individual users and keep one layout, one profile.

Here's how you'd build this:
1. Create your new custom field
2. Do not give any profile permission to Read/Edit
3. Add the field to your page layout
4. Create a new permission set
5. Choose Object and Field Permissions
6. Find your Object and Field and set Read/Edit access to TRUE for your field
7. Associate the permission set to your power user
8. Enjoy!

One thing to keep in mind is that permission sets are additive, so these are a great way to extend your base functionality for special users.