Wednesday, December 31, 2008

Glengarry Glen-Christmas



Tuesday, December 23, 2008

Use Visualforce and Apex to Populate PDF Forms

Does your company's business process involve filling out PDF forms? If so, check out my recent post about using Visualforce and Apex to help automate the process of populating PDF forms: Use Visualforce and Apex to Populate PDF Forms.

Sunday, November 30, 2008

Visualforce Component Auto-Documentation

Have you noticed that Visualforce Custom Component attributes are automatically displayed in the Component Reference? I was pleasantly surprised to discover this the other day. Here are some screenshots that show an example:

Component Definition:

Visualforce Page Using the Component:

Component Reference:

This is small feature, but it's a great benefit for developers working with custom components, like the newly released Google Visualization components.

Wednesday, November 19, 2008

Valuable Dreamforce 2008 Sessions

Now that I have the shameless self-promotion out of the way, here are a few more links to some other really great Dreamforce session recordings:

Apex Code Deep Dive

Apex Test Coverage Best Practices Sites

Multitenant Magic: Under the Covers of the Force Platform Data Architecture

Meet the Platform Development Team

Dreamforce 2008 Session Recordings

All of the sessions from Dreamforce 2008 have been posted on the Community. Recordings of the sessions that I co-presented are now available. Let me know what you think.

Also, be sure to check out these two Google Visualization blog posts: Google

Wednesday, October 29, 2008

(Arguably) The Top 3 Reasons to Attend Dreamforce 2008

As you might be able to tell from some of my previous posts, I'm rather excited about Dreamforce 2008. What I didn't mention are my personal top 3 reasons for attending Dreamforce this year. In chronological order, they are:

Beyond S-Controls: Learn to Use Visualforce in Your Force Platform Apps
If you're familiar with S-Controls and want to know why Visualforce is so much more compelling, then this session is for you! Join Platform experts as they review the typical uses for S-Controls and explain why Visualforce is easier, faster, and more fun to use in your applications!

Monday November 3
4:45 p.m. - 5:45 p.m.

Presented By
Jesse Lorenz -
Jon Mountjoy -

Build Any UI for Any App Using Visualforce
Learn how to use the latest Platform innovation, Visualforce, to build any UI for any application. This technical introduction will include code walkthroughs and cover topics including components and common use cases.

Tuesday, November 4
2:00 p.m. - 3:00 p.m.

Presented By
Jotham Fisher-Smith - Surfwriter
Ron Hess -
Jesse Lorenz -

Elevate Your Platform Apps with the Google Visualization API
Looking to bring the power of the Google Visualization API to your apps? Attend this session to learn how to add rich charting and visualization capabilities to your apps in a session jointly presented by Google and experts.

Wednesday, November 5
11:30 a.m. - 12:30 p.m.

Presented By
Nir Bar-Lev - Google
Jesse Lorenz -
Itai Raz - Google

I hope to see you at Dreamforce and would love to chat after a session, or in the developer lounge!

Sunday, October 26, 2008

Tim O'Reilly on Web 2.0 and Cloud Computing

Insightful article by Tim O'Reilly. Some of my favorite quotes:

Platform as a Service: One step up from pure utility computing are platforms like Google AppEngine and Salesforce's, which hide machine instances behind higher-level APIs. Porting an application from one of these platforms to another is more like porting from Mac to Windows than from one Linux distribution to another.

The key question at this level remains: are there advantages to developers in one of these platforms from other developers being on the same platform? seems to me to have some ecosystem benefits, which means that the more developers are there, the better it is for both Salesforce and other application developers. I don't see that with AppEngine. 

Ideally, the user's data becomes more valuable because it is in the same space as other users' data. This is why a listing on craigslist or ebay is more powerful than a listing on an individual blog, why a listing on amazon is more powerful than a listing on Joe's bookstore. [Also why features like Salesforce to Salesforce have such potential.]
This top level of cloud computing definitely has network effects. If I had to place a bet, it would be that the application-level developer ecosystems eventually work their way back down the stack towards the infrastructure level, and the two meet in the middle. In fact, you can argue that that's what has already done, and thus represents the shape of things. It's a platform I have a strong feeling I (and anyone else interested in the evolution of the cloud platform) ought to be paying more attention to.
What we learned from the history of the IBM personal computer -- a commodity platform built from off-the-shelf parts -- was that it drained value out of the hardware ecosystem, turning it into a low-margin business. But profits didn't go away. Instead, through something that Clayton Christensen calls "the law of conservation of attractive profits," value migrated elsewhere, from hardware to software, from IBM to Microsoft. 
So when Larry Ellison says that cloud computing and open source won't produce many hugely profitable companies, he's right, but only if you look at the pure software layer. This is a lot like saying that the PC wouldn't produce many hugely profitable companies, and looking only at hardware vendors! First Microsoft, and now Google give the lie to Ellison's analysis. The big winners are those who best grasp the rules of the new platform.
The utility layer of cloud computing will be just that, a utility, without outsized profits.

Sunday, October 19, 2008

A Lesson in Crossing the Chasm from Steve Jobs

Steve states the fundamental questions right from the start: "Who is our target customer? Why are they selecting our product over the competition's? What distribution channels are we going to use?"


Saturday, October 18, 2008

12 Reasons to Attend Dreamforce 2008

Eight great (official) reasons for developers to attend Dreamforce 2008:
  • Platform Keynote - Kick off the conference with Chairman & CEO Marc Benioff's ever-surprising platform address.

  • State of the Union - Get a complete overview of the latest technologies and the powerful ecosystem that goes with it.

  • In-Depth, Practical Content - experts are ready and waiting to teach you everything you need to build out-of-this-world apps.

  • Sessions Galore - We’ve got 40+ sessions on technologies, complete with hands-on demos and practical guidance.

  • The Zone - Drop in anytime to speak 1:1 with technical experts, network, or get the new high score in the Nintendo Wii Tournament.

  • Immersion Lab - Get answers to your burning questions through tutorials or 1:1 guidance from our lab staffers.

  • Monday Night Hackathon - You’ll be inspired to build great things with the exclusive cutting-edge technologies announced on Monday, so spend the evening working directly with our top experts and the rest of the developer community to make your ideas a reality! It’s a collaborative coding marathon event, only at Dreamforce.

  • Technology Preview - Be the first to get hands-on with the very latest technology, announced exclusively at Dreamforce!
If those reasons didn't convince you to sign up, Jeff Grosse over at CRM FYI put together another great list of reasons why you have to be at Dreamforce 2008. Here are four of my favorites from Jeff's list:
  • 250+ partners will be at Dreamforce.

  • Neil Young will be part of a keynote address.

  • Cloud Crawl - Based on the great success of last year’s App Crawl, the ante is upped this year with a Cloud Crawl.

  • Journey! Foo Fighters!
Stay tuned for three more reasons...

Monday, October 13, 2008

Sunday, October 12, 2008

SaaS Competitive Advantage: Capital Expenditure

"If credit remains tight, then one of the first things businesses are going to cut is capital expenditure — either because they can’t stomach the risk, or because they can’t raise the finance. The upside for SaaS vendors is that those cash-strapped businesses will find the pay-as-you-go SaaS model highly appealing — especially if it helps deliver operational cost savings at the same time. So while the credit crunch seems certain to harm the front-loaded cost model of conventional software sales, SaaS should continue to grow by picking up some of those canceled projects."

Wednesday, October 08, 2008

Visualforce Tip: How to Determine a Hostname

It isn't entirely obvious how a developer can determine the hostname (server url) portion of the absolute path for a Visualforce page via Apex. Luckily, it is rather easy to do.

You might have already figured out that the PageReference class's getUrl() method will return the relative path for your Visualforce page:

Once you have the relative path for the page, then there's just one remaining trick to discover - the Map returned by the PageReference class's getHeaders() method contains a 'Host' key whose associated value is the hostname for your salesforce org:

The complete code for constructing the absolute path for a Visualforce page is below:

String hostname = ApexPages.currentPage().getHeaders().get('Host');
String pageUrl = ApexPages.currentPage().getUrl();
String absolutePath = 'https://' + hostname + pageUrl;
system.debug(absolutePath); //example output: ''

Thursday, September 25, 2008

Visualforce Tip: Custom Components + DML

I built a Visualforce custom component today and ran in to (what should have been) a fairly trivial problem.

As you can see below, my Visualforce custom component has a CommandLink and the controller has a corresponding action method that updates a field on the displayed Contact record.

<apex:commandlink value="Associate External Id to Contact" action="{!associate}">

Action Method:
public PageReference associate()

c.ExternalId__c = ExternalId;
update c;

return ApexPages.currentPage();

There's not much complexity here, but every time I clicked on the ComandLink, I kept getting this error:

System.Exception: DML currently not allowed

I had read the documentation, scoured the message boards, thoroughly searched the wiki and was about to submit my own question to the message boards when I gave the documentation one last look. To my joy/chagrin, I discovered the allowDML attribute on the Visualforce component standard component. It has this description:

If this attribute is set to true, you can include DML within the component. The default is false.

Here's what my component tag looks like now:
<apex:component controller="MyContactController" allowDML="true">

Sunday, September 07, 2008

Deploy Applications to Production Faster

I have a post over on the blog titled "Deploying Applications to Production Faster." It was inspired by Steve Andersen's post about how he used the IDE to reduce his deployment process from 8 hours to 2 hours.

The Migration Tool is another useful tool for deploying from one environment to another. Both tools leverage the powerful Metadata API.

Friday, August 29, 2008

Wallstrip's / Glengarry Glen Ross Spoof

"I call this mama the upwardly mobile."


Wednesday, August 20, 2008

PaaS Platforms Use Proven Architectures

"These companies [Amazon, Google,] have designed, implemented, and most importantly, run their critical business operations on these platforms. That in and of itself is more important than all the vaporware and marketing hype any other vendor comes up with. Rather than having to get customers to believe that a solution works via marketing and then force it down their IT staff's throats, Google and Amazon are basically saying 'Hey why not use stuff that we use and have proven can scale up to handle huge loads and huge amounts of data?'


I can base my decision to use a Google or Amazon service based on their actual track record in delivering these services and eating their own dog food, since they are trying to monetize their existing investment in proven highly distributed and scalable infrastructures."

Tuesday, August 19, 2008 Acquires InStranet

I've had a couple of customers that implemented the Customer Service & Support application, but couldn't be convinced to decommission their old support system because they wanted to keep using their existing Knowledge Base.'s acquisition of InStranet is great news and should resolve this objection. The InStranet Knowledge Base has an outstanding reputation and I'm thrilled that the Customer Service & Support story continues to improve.

Friday, August 15, 2008

"Apex Code Is Not a Niche Tool"

"[Apex Code] is not a niche tool for a proprietary platform -- rather, it's a Java-like language with an Eclipse-based tool ecosystem and excellent facilities for unleashing immense gains in developer productivity and enterprise project success."

Wednesday, August 13, 2008

"Mere Marketing"

"For those who pooh-pooh Microsoft's success as "mere marketing" I have a suggestion: You need to get into this "mere marketing" business. It has a way of driving adoption. It matters."

Tuesday, August 12, 2008

"Lots of People Have Opinions About Platforms"

"Lots and lots of people have opinions about platforms, but the people whose opinions matter are programmers, and people who can make decisions about what programmers program."

Tuesday, July 22, 2008

Wishing Analytic Snapshots Supported Summary Reports

If Analytic Snapshots supported Summary Reports, I could avoid exporting to Excel, replacing a bunch of text and pasting in a bunch of formulas in order to perform the calculations that I need.

I'm not the only one either - vote up the idea: Summary Fields in Analytic Snapshots.

[Update: This idea is going to be implemented as a part of the Spring '09 release!]

Thursday, July 10, 2008

Visualforce Helps Developers Build Interesting Applications Faster

I've written before about how programming in Apex allows developers to be much more productive. Visualforce similarly helps developers avoid writing a lot of boring code.

If Visualforce and Apex were a typical development platform, the canonical way of populating a data bound picklist would be something like this:

Visualforce markup:

<apex:outputLabel value="Category" for="expenseCategory"/>
<apex:selectList multiselect="false" id="expenseCategory" required="true" size="1" value="{!expense.Category__c}">
<apex:selectOptions value="{!ExpenseCategories}"/>

With the following controller code:
public List getExpenseCategories()
Map allObjectTypesMap = Schema.getGlobalDescribe();
Schema.DescribeFieldResult f = Schema.sObjectType.Expense__c.fields.Category__c;
List options = new List();
options.add(new SelectOption('--None--', '--None--'));
for(Schema.PicklistEntry ple : f.getPicklistValues())
options.add(new SelectOption(ple.getValue(), ple.getLabel()));

One of the benefits of developing on the platform is that it is very data-driven and has native access to your application's metadata. As a result, the code below is equivalent to the code written above and is much less verbose:

<apex:inputField id="expenseCategory" required="true" value="{!expense.Category__c}"/>

As a result, developers can spend their time building really interesting applications and let the platform worry about the plumbing.

Monday, July 07, 2008

Don't worry about losing your laptop.

I've received two letters in the past year from former employers alerting me that they had lost a computer that contained some of my confidential information. Apparently, I'm not alone - according to a Dell survey, 12,000 laptops are lost at airports alone every week. Over 50% of those laptops are purported to have sensitive corporate data on them. The vast majority of these lost laptops are never reunited with their owners.

I'm surprised that so many corporate Information Security teams place so much faith in the ability of their users to safeguard important corporate information. Individual employees shouldn't be solely responsible for guarding important information. The bulk of that burden should be left to security professionals.

Corporate InfoSec teams should be using SaaS applications to house a lot more of their sensitive data than they are currently. The InfoSec professionals employed by SaaS vendors are much more skilled at protecting data than the average employee is and by using SaaS applications, confidential data isn't stored on individual employee computers and therefore can't be lost. Don't worry about losing your laptop - use SaaS applications instead.

Sunday, May 25, 2008

SaaS Competitive Advantage

I've pointed out previously how Salesforce2Salesforce is functionality that an on-premise software vendor could never deliver. Google Docs Live Forms is another great example of simple, elegant functionality that can only be delivered by Software as a Service.

Wednesday, May 14, 2008

CODA 2go

I've been enjoying the CODA 2go blog. It's been interesting to see some of the process of developing the first large-scale enterprise application on the platform. It was especially exciting to see CODA 2go launch last week at Dreamforce Europe. Check out their demo here:

CODA's efforts are clearly pushing the platform in new directions and I hope that other developers will also blog about their development experiences as well. I can't wait to test-drive CODA 2go.

Friday, May 02, 2008

Unit Testing

Writing unit tests may be a bit of an acquired taste, but I don't think that the value of writing them can be overstated for any moderately complex software project.

Having a full suites of well-written unit tests gives developers the peace of mind to confidently refactor code that isn't their own, or to refactor code that they have written but are no longer happy with.

Writing unit tests before writing the actual code has an added benefit as well. It provides a developer with an extra opportunity to think about how clients of the code are going to use it. This in turn helps identify potential bugs much earlier in the development cycle.

Add it all up, and the end result is that the act of writing unit tests results in higher quality code. The popularity of NUnit helped Microsoft realize this, which is why Visual Studio 2005 Team System delivered integrated unit testing tools. came to the same conclusion about the importance of unit testing and made it a fundamental component of Apex, their on demand programming language. Writing unit tests for Apex is a remarkably simple task, which is good, because Apex is the first programming language to require developers to write unit tests for their code - a minimum of 75% code coverage is required for all production Apex code. I anticipate that more languages will begin to follow suit, especially those designed to run in multi-tenant environments.

Having seen the value of unit testing personally and having seen the industry's acceptance of the value of unit testing, it's a bit surprising that more university computer science curriculums don't emphasize writing unit tests. Maybe it's because the teaching assistants like keeping their unit testing harnesses a secret...

Thursday, April 17, 2008

Summer '08

Wow! Lots of good stuff coming in the next release - Your Ideas in Summer '08.

These are the ones that I'm looking forward to the most:

  • Filter on Lookup - This should save a lot of people from having to write custom S-Controls to do the filtering.
  • In-line Editing for Views - This should solve a lot of requests for 'Excel-like' editing functionality. (I wonder if this will allow users to edit Related List values as well.)
  • Cross-Object Formula Fields - It will be great to be able to pull some data down from parent objects. (I wonder if this feature will work with Validation Rules as well.)
  • Many to Many Relationships - Custom Report Types solve this problem (see my post here) but it would be really cool if creating Many to Many relationships became even easier to do.
  • Asynchronous Apex - This should add a lot of flexibility, especially in conjunction with making web service callouts from Apex.

Some other solid new features:

Wednesday, April 16, 2008

Update Collision Detection

Have you ever wondered what happens when two people try to modify the same record in

For example, what would happen in this scenario?

1. Sales Rep Bill Smith has a Contact, Jesse Cochran.

2. Sales Rep Bill learns that he needs to update Jesse's last name to Katsopolis.

3. At the same time, another Sales Rep, Roger Jones, learns that he needs to update the company that Jesse works for and that Jesse has a new title.

4. Sales Rep Bill saves his changes.

5. Sales Rep Roger tries to save his changes - and fails.

This is due to a feature called Update Collision Detection that was introduced in the Summer '07 release of salesforce. It's not a super glamorous bit of functionality, but it should let some folks sleep better at night knowing that it's there.

Also, if you're interested in why Jesse changed his last name from Cochran to Katsopolis, you'll want to check out his wikipedia entry:

Sunday, April 13, 2008

Innovator's Dilemma

I drank the Kool-Aid a long time ago - I'm convinced that Software as a service (SaaS) is the next phase in the computing revolution. A lot of established software vendors aren't so sure:

The future is a combination of local software and Internet services interacting with one another. Software makes services better and services make software better. And by bringing together the best of both worlds, we maximize choice, flexibility and capabilities for our customers. We describe this evolutionary path in our industry as Software + Services.


SAP has pioneered the “isolated-tenancy” model that combines the high availability and low risk of a single-tenancy approach with the efficiencies and deployment speed of a multi-tenancy architecture.


Today's CRM deployment options include:
  • On-premises CRM
  • Privately managed on-demand CRM
  • Shared on-demand CRM
  • Hybrid CRM

These companies are trying to convince potential customers that SaaS is a feature, or an option, instead of the way of life that it clearly is. Microsoft, Oracle and SAP are caught in the classic innovator's dilemma - they can see the future clearly, but they can't invest fully in SaaS because doing so would cannibalize their packaged software revenue streams.

History has not been kind to established industry leaders when a disruptive innovation comes along - just ask Kodak.

Wednesday, April 09, 2008 cron

Time-based workflows in salesforce currently execute relative to a time. For example, you can use them to to schedule a task for the case owner to follow up with the customer two days after a
case is closed.

It's not currently possible to schedule time-based workflows to execute at a particular time every day - like a cron job would. For that, we'd need to add some secret sauce to time-based workflows.

The Apex trigger below will populate a custom DateTime field called Midnight_Local_Time__c with, you guessed it, midnight - local time for the running user. In conjunction with a time-based workflow, this trigger would allow you to do things like lock all 'Closed' Case records at midnight
trigger Case_PopulateMidnightLocalTime on Case (after update)
List cases = new List();
for(Case c : [SELECT CreatedDate FROM Case WHERE Id IN AND IsClosed = true AND Midnight_Local_Time__c = null])
CaseTriggerHelper.SetMidnightTime(c, c.CreatedDate);


update cases;

public static void SetMidnightTime(Case c, DateTime dt)
// SFDC defaults 'Midnight' to the 'Time' for this call to newInstance();
DateTime midnightLocalTime = DateTime.newInstance(dt.year(), dt.month(),;
midnightLocalTime = midnightLocalTime.addDays(1).addMinutes(-1);
c.Midnight_Local_Time__c = midnightLocalTime;
If you use this, you'll want to keep in mind that there are limitations around time-based workflows and triggers though:
  • Time-based workflows aren't guaranteed to execute exactly on time, there could be a significant delay in their execution.

  • Unlimited Edition is limited to 20,000 time triggers per org

  • Enterprise Edition is limited to 10,000 time triggers per org
Linvio's CronKit appears to be a useful solution to this problem as well.

Wednesday, April 02, 2008

"No" - In So Many Words

Update January 26, 2014: Jared Spool conveys my thoughts much more clearly in his Beans and Noses post.

Update April 24, 2008: I've been revising this post regularly over the past month. I think that it expresses how I feel about saying "No" to a client, but I reserve the right to modify this post, and my opinion, in the future. Also, I do think that it can be appropriate to tell our clients "No" on occasion, but those scenarios are a topic for another day.

As an IT software engineer, and even as a newbie technology consultant, I didn't realize that my relationships with my clients required a relatively high degree of finesse. I had become accustomed to having very candid conversations with other technical people about what was technologically feasible for a given project. We regularly used the word "No" in these conversations. And we regularly used the word "No" when talking with the business about their requests. Looking back though leads me to believe that telling the business "No" probably hurt my teams' reputation - saying "No" to each other was probably counter-productive in some cases as well.

I've worked with clients whose project goals were to improve customer satisfaction, or to reduce operating expenses, or even to introduce new product lines. At the core, all of these project goals boil down to a desire to improve the business. Our job as technology experts is to provide the business with the tools that they need to accomplish their goals. And just in the way that a carpenter wouldn't like using a hammer that refused to pound nails, our business clients don't like technology experts that refuse to help improve the business by saying "No".

I have learned that it can be much more effective to be indirect and to guide the client to the conclusion that they don't really want to implement their request. Some of my favorite ways of doing this are:
  • "How important is this request compared to the others that we've identified?"
  • "Can you tell me more about why you want to do X?"
  • "That's a great idea, we can do that - have you considered how it will impact Y?"
  • "We can do that, but it will probably increase our timeline/cost." (optional: "Are you willing to accept that?")
  • "That makes a lot of sense, we can definitely do that, but we will probably have to cut out another feature." (optional: Which feature can we remove?")
Customers can request crazy, even impossible, things sometimes, but I've found that my relationships are much more productive if I can think of creative ways to get the customer to consider their request in a different light. The customer may not always be right, but that doesn't mean that we have to tell them that they're wrong.

Thursday, March 06, 2008

Speaking of Platforms...

My last post made me realize that I haven't already pointed out Marc Andreessen's excellent essay: The three kinds of platforms you meet on the internet.

And if the essay itself wasn't reward enough, check this out:

Get Your Org Under Version Control

Jeff Atwood, a software engineering hero to many, recently wrote about version control for databases.

His post spurred me to use the IDE to put my latest project under version control. It's dead simple to utilize a version control system for your entire salesforce application now: S-Controls, Apex code and salesforce schema included. (Here are the instructions for Subversion: Code Share)

If being able to define a database, build complex logic and create a sophisticated user interface wasn't enough to convince everyone that is a true development platform, the development environment just made it a little bit harder to deny.

And the whole platform is delivered as a service...

Saturday, February 23, 2008

V-shaped (Junction Object) Reports

Custom Report Types are incredibly powerful, but one feature that you might not know about, is the ability to "go back up" the object hierarchy.

Let's imagine that your business has a call center and that every once in a while one of your products breaks. When this happens, the affected customer will call your 1-800 number and ask for a replacement product. As a company, you're happy to oblige, but you want to run a report on Cases, Replacement Orders and Products to try and detect breakage patterns. With traditional salesforce reports, you'd be stuck, because the object relationship is V-shaped:

Using standard salesforce reports, you could easily run a report on Cases and Replacement Orders, but you wouldn't be able to "go back up" to get any Product fields beyond the name of the Product being replaced.

Allow me to introduce you to the little-known hero of our story, the "Add fields related via lookup" hyperlink for Custom Reports:

The "Add fields related via lookup" hyperlink will allow you to add fields from the Product table to your report on Cases and Replacement Orders.

And now you'll be able to save the company untold millions by detecting product breakage patterns - all thanks to one little hyperlink.

If you want to build a similar report in your salesforce org, you'll need to define a custom report type with one or more related objects:

Once you've defined your custom report, the next two steps are just a matter of clicking on the "Edit Layout" button and the "Add fields related via lookup" link. Happy Reporting!

Saturday, February 09, 2008

Favorite HTML/JavaScript Resources

Microsoft's HTML and DHTML Reference. It's saved me hundreds of times - and it's a lot more up to date than my 1998 version of HTML: The Definitive Guide.

DevGuru: JavaScript. Simple and straightforward JavaScript reference.

W3Schools JavaScript Tutorial. Easy to understand examples - that you can experiment with!

Friday, January 25, 2008

Spring '08

My favorite new feature is not Dashboard Scheduling or Apex Code in EE or even Outer-Join Reporting - it's the improved user interface for building list views. I'm creating list views like never before!