<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeff Douglas - Technology, Coding and Bears... OH MY! &#187; Apex</title>
	<atom:link href="http://blog.jeffdouglas.com/category/technology/apex/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jeffdouglas.com</link>
	<description>Get your head out of your #@! and into the clouds!</description>
	<lastBuildDate>Thu, 02 Feb 2012 11:57:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Video &#8211; Debugging Apex Tools and Techniques (DF11)</title>
		<link>http://blog.jeffdouglas.com/2011/10/24/debugging-apex-tools-and-techniques/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=debugging-apex-tools-and-techniques</link>
		<comments>http://blog.jeffdouglas.com/2011/10/24/debugging-apex-tools-and-techniques/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 12:00:43 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=4221</guid>
		<description><![CDATA[The new System Log (aka Apex CSI) is a cool new part of Winter 12 that significantly reduces the pain of debugging Force.com applications. This is a great video from Dreamforce 11 showing you how to use the new console to debug code, set &#8220;breakpoints&#8221; and examine heap variables and more. www.youtube.com/watch?v=Hl2cY7eW2Ko]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F10%2F24%2Fdebugging-apex-tools-and-techniques%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F10%2F24%2Fdebugging-apex-tools-and-techniques%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The new System Log (aka Apex CSI) is a cool new part of Winter 12 that significantly reduces the pain of debugging Force.com applications. This is a great video from Dreamforce 11 showing you how to use the new console to debug code, set &#8220;breakpoints&#8221; and examine heap variables and more. </p>
<p><span class="youtube">
<object width="560" height="340">
<param name="movie" value="http://www.youtube.com/v/Hl2cY7eW2Ko?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="opaque" src="http://www.youtube.com/v/Hl2cY7eW2Ko?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="560" height="340"></embed>
<param name="wmode" value="opaque" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=Hl2cY7eW2Ko&fmt=18">www.youtube.com/watch?v=Hl2cY7eW2Ko</a></p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/10/24/debugging-apex-tools-and-techniques/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Salesforce Trigger when Rollups Summaries Not Possible</title>
		<link>http://blog.jeffdouglas.com/2011/08/23/salesforce-trigger-when-rollups-summaries-not-possible/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=salesforce-trigger-when-rollups-summaries-not-possible</link>
		<comments>http://blog.jeffdouglas.com/2011/08/23/salesforce-trigger-when-rollups-summaries-not-possible/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 11:15:31 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=4118</guid>
		<description><![CDATA[Master-Details relationships in Force.com  are very handy but don&#8217;t fit every scenario. For instance, it&#8217;s not possible to implement a rollup summary on formula field or text fields. Here&#8217;s a small trigger that you can use for a starter for these types of situations. The code for each class is available at GitHub for your [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F08%2F23%2Fsalesforce-trigger-when-rollups-summaries-not-possible%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F08%2F23%2Fsalesforce-trigger-when-rollups-summaries-not-possible%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://www.salesforce.com/us/developer/docs/api/Content/relationships_among_objects.htm">Master-Details relationships</a> in Force.com  are very handy but don&#8217;t fit every scenario. For instance, it&#8217;s not possible to implement a rollup summary on formula field or text fields. Here&#8217;s a small trigger that you can use for a starter for these types of situations. The code for each class is available at <a href="https://github.com/jeffdonthemic/Blog-Sample-Code">GitHub</a> for your forking pleasure.</p>
<p>So here&#8217;s the (not very useful) use case. Sales Order is the Master object which can have multiple Sales Order Items (detail object). The Sales Order Item has a &#8220;primary&#8221; Boolean field and a &#8220;purchased country&#8221; field. Each time Sales Order Items are inserted or updated, if the Sales Order Item is marked as &#8220;primary&#8221; then the value of &#8220;purchased country&#8221; is written into the &#8220;primary country&#8221; field on the Sales Order. I&#8217;m assuming that there can only be one Sales Order Item per Sales Order that is marked as primary. Essentially this is just a quick reference on the Sales Order to see which country is primary on any of the multiple Sales Order Items. Not very useful but illustrative.</p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/sales-order-item.png" rel="lightbox[4118]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/sales-order-item.png" alt="" title="sales-order-item" width="500" class="aligncenter size-full wp-image-4121" /></a></p>
<p>The code is broken down into a Trigger and an Apex &#8220;handler&#8221; class that implements the actual functionality. It&#8217;s <a href="http://blog.jeffdouglas.com/2010/10/21/force-com-programming-best-practices/">best practice</a> to only have one trigger for each object and to avoid complex logic in triggers. To simplify testing and resuse, triggers should delegate to Apex classes which contain the actual execution logic. See <a href="http://www.embracingthecloud.com/2010/07/08/ASimpleTriggerTemplateForSalesforce.aspx">Mike Leach’s excellent trigger template</a> for more info.</p>
<p><strong>SalesOrderItemTrigger</strong> (<a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/triggers/SalesOrderItemTrigger.trigger">source on GitHub</a>) - Implements trigger functionality for Sales Order Items. Delegates responsibility to SalesOrderItemTriggerHandler.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">trigger SalesOrderItemTrigger on Sales_Order_Item__c (after insert, after update) {
&nbsp;
  SalesOrderItemTriggerHandler handler = new SalesOrderItemTriggerHandler();
&nbsp;
  if(Trigger.isInsert &amp;&amp; Trigger.isAfter) {
    handler.OnAfterInsert(Trigger.new);
&nbsp;
  } else if(Trigger.isUpdate &amp;&amp; Trigger.isAfter) { 
    handler.OnAfterUpdate(Trigger.old, Trigger.new, Trigger.oldMap, Trigger.newMap);
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>SalesOrderItemTriggerHandler</strong> (<a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/classes/SalesOrderItemTriggerHandler.cls">source on GitHub</a>) - Implements the functionality for the sales order item trigger after insert and after update. Looks at each sales order item and if it is marked as primary_item__c then moves the primary_country__c value from the sales order item to the associated sales order&#8217;s primary_country__c field.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class SalesOrderItemTriggerHandler {
&nbsp;
  // update the primary country when new records are inserted from trigger
  public void OnAfterInsert(List&lt;Sales_Order_Item__c&gt; newRecords){
    updatePrimaryCountry(newRecords); 
  }
&nbsp;
  // update the primary country when records are updated from trigger  
  public void OnAfterUpdate(List&lt;Sales_Order_Item__c&gt; oldRecords, 
      List&lt;Sales_Order_Item__c&gt; updatedRecords,  Map&lt;ID, Sales_Order_Item__c&gt; oldMap, 
      Map&lt;ID, Sales_Order_Item__c&gt; newMap){
    updatePrimaryCountry(updatedRecords); 
  }
&nbsp;
  // updates the sales order with the primary purchased country for the item
  private void updatePrimaryCountry(List&lt;Sales_Order_Item__c&gt; newRecords) {
&nbsp;
    // create a new map to hold the sales order id / country values
    Map&lt;ID,String&gt; salesOrderCountryMap = new Map&lt;ID,String&gt;();
&nbsp;
    // if an item is marked as primary, add the purchased country
    // to the map where the sales order id is the key 
    for (Sales_Order_Item__c soi : newRecords) {
      if (soi.Primary_Item__c)
        salesOrderCountryMap.put(soi.Sales_Order__c,soi.Purchased_Country__c);
    } 
&nbsp;
    // query for the sale orders in the context to update
    List&lt;Sales_Order__c&gt; orders = [select id, Primary_Country__c from Sales_Order__c 
      where id IN :salesOrderCountryMap.keyset()];
&nbsp;
    // add the primary country to the sales order. find it in the map
    // using the sales order's id as the key
    for (Sales_Order__c so : orders)
      so.Primary_Country__c = salesOrderCountryMap.get(so.id);
&nbsp;
    // commit the records 
    update orders;
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>Test_SalesOrderItemTriggerHandler</strong> (<a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/classes/Test_SalesOrderItemTriggerHandler.cls">source on GitHub</a>) - Test class for SalesOrderItemTrigger and SalesOrderItemTriggerHandler. Achieves 100% code coverage.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">@isTest
private class Test_SalesOrderItemTriggerHandler {
&nbsp;
  private static Sales_Order__c so1;
  private static Sales_Order__c so2;
&nbsp;
  // set up our data for each test method
  static {
&nbsp;
  	Contact c = new Contact(firstname='test',lastname='test',email='no@email.com');
  	insert c;
&nbsp;
    so1 = new Sales_Order__c(name='test1',Delivery_Name__c=c.id);
    so2 = new Sales_Order__c(name='test2',Delivery_Name__c=c.id);
&nbsp;
    insert new List&lt;Sales_Order__c&gt;{so1,so2};
&nbsp;
  }
&nbsp;
  static testMethod void testNewRecords() {
&nbsp;
    Sales_Order_Item__c soi1 = new Sales_Order_Item__c();
    soi1.Sales_Order__c = so1.id;
    soi1.Quantity__c = 1;
    soi1.Description__c = 'test';
    soi1.Purchased_Country__c = 'Germany';
&nbsp;
    Sales_Order_Item__c soi2 = new Sales_Order_Item__c();
    soi2.Sales_Order__c = so1.id;
    soi2.Quantity__c = 1;
    soi2.Description__c = 'test';
    soi2.Purchased_Country__c = 'France';
    soi2.Primary_Item__c = true;
&nbsp;
    Sales_Order_Item__c soi3 = new Sales_Order_Item__c();
    soi3.Sales_Order__c = so2.id;
    soi3.Quantity__c = 1;
    soi3.Description__c = 'test';
    soi3.Purchased_Country__c = 'Germany';
    soi3.Primary_Item__c = true;
&nbsp;
    Sales_Order_Item__c soi4 = new Sales_Order_Item__c();
    soi4.Sales_Order__c = so2.id;
    soi4.Quantity__c = 1;
    soi4.Description__c = 'test';
    soi4.Purchased_Country__c = 'Germany';
&nbsp;
    Sales_Order_Item__c soi5 = new Sales_Order_Item__c();
    soi5.Sales_Order__c = so2.id;
    soi5.Quantity__c = 1;
    soi5.Description__c = 'test';
    soi5.Purchased_Country__c = 'Italy';
&nbsp;
    insert new List&lt;Sales_Order_Item__c&gt;{soi1,soi2,soi3,soi4,soi5}; 
&nbsp;
    System.assertEquals(2,[select count() from Sales_Order_Item__c where Sales_Order__c = :so1.id]);
    System.assertEquals(3,[select count() from Sales_Order_Item__c where Sales_Order__c = :so2.id]); 
&nbsp;
    System.assertEquals('France',[select primary_country__c from Sales_Order__c where id = :so1.id].primary_country__c);
    System.assertEquals('Germany',[select primary_country__c from Sales_Order__c where id = :so2.id].primary_country__c);
&nbsp;
  }
&nbsp;
  static testMethod void testUpdatedRecords() {
&nbsp;
    Sales_Order_Item__c soi1 = new Sales_Order_Item__c();
    soi1.Sales_Order__c = so1.id;
    soi1.Quantity__c = 1;
    soi1.Description__c = 'test';
    soi1.Purchased_Country__c = 'Germany';
&nbsp;
    Sales_Order_Item__c soi2 = new Sales_Order_Item__c();
    soi2.Sales_Order__c = so1.id;
    soi2.Quantity__c = 1;
    soi2.Description__c = 'test';
    soi2.Purchased_Country__c = 'France';
    soi2.Primary_Item__c = true;
&nbsp;
    insert new List&lt;Sales_Order_Item__c&gt;{soi1,soi2}; 
&nbsp;
    // assert that the country = France
    System.assertEquals('France',[select primary_country__c from Sales_Order__c where id = :so1.id].primary_country__c);
&nbsp;
    List&lt;Sales_Order_Item__c&gt; items = [select id, purchased_country__c from Sales_Order_Item__c 
      where Sales_Order__c = :so1.id and primary_item__c = true];
    // change the primary country on the sales order item. should trigger update
    items.get(0).purchased_country__c = 'Denmark';
&nbsp;
    update items;
    // assert that the country was successfully changed to Denmark
    System.assertEquals('Denmark',[select primary_country__c from Sales_Order__c where id = :so1.id].primary_country__c);
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/08/23/salesforce-trigger-when-rollups-summaries-not-possible/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Roll Your Own Salesforce &#8220;Lookup&#8221; Popup Window</title>
		<link>http://blog.jeffdouglas.com/2011/08/12/roll-your-own-salesforce-lookup-popup-window/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=roll-your-own-salesforce-lookup-popup-window</link>
		<comments>http://blog.jeffdouglas.com/2011/08/12/roll-your-own-salesforce-lookup-popup-window/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 12:18:48 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=4087</guid>
		<description><![CDATA[Let&#8217;s talk about the standard salesforce.com &#8220;lookup&#8221; popup window for a few minutes. You know what I&#8217;m talking about.. this button right here It&#8217;s a handy little button that pops up whenever you need to search for related records. It does a pretty good job but it has some serious drawbacks: It&#8217;s virtually impossible to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F08%2F12%2Froll-your-own-salesforce-lookup-popup-window%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F08%2F12%2Froll-your-own-salesforce-lookup-popup-window%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Let&#8217;s talk about the standard salesforce.com &#8220;lookup&#8221; popup window for a few minutes. You know what I&#8217;m talking about.. this button right here</p>
<p><img title="custom-lookup-button.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/custom-lookup-button.png" border="0" alt="Custom lookup button" width="292" height="116" /></p>
<p>It&#8217;s a handy little button that pops up whenever you need to search for related records. It does a pretty good job but it has some serious drawbacks:</p>
<ol>
<li>It&#8217;s virtually impossible to modify your search criteria. What if you want your users to do some crazy search based upon custom logic or search a field that is not typically available? Sorry&#8230; you are out of luck. Not possible.</li>
<li>It&#8217;s terrible for creating new records. Let&#8217;s say that a user searches for a specific related record and it (absolutely) doesn&#8217;t exist. To create the new record they need to close the lookup window, navigate to the tab to create the new related record, create the new record, then go back to the original record they were either editing or creating, pop up the lookup window again and find their newly created record. Wow! That&#8217;s a lot of work. </li>
<li>&#8220;Quick Create&#8221; is evil! You can enable the &#8220;Quick Create&#8221; option for an entire org but don&#8217;t do it! It displays, by default, on the tab home pages for leads, accounts, contacts, forecasts, and opportunities! The major problems are that you can only create new records for these 5 objects (what about the other ones!?), you can&#8217;t customize the fields on the page and validation rules don&#8217;t fire (can you say, &#8220;bad data&#8221;). </li>
</ol>
<p><img title="custom-lookup.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/custom-lookup.png" border="0" alt="Quick Create is Bad" width="500" height="466" /></p>
<h3>Here&#8217;s the Solution!</h3>
<p>I have some good news and some bad news. For standard page layouts I can&#8217;t help you. Go vote for <a href="http://success.salesforce.com/ideaView?id=08730000000IYRFAA4">this idea</a> and <a href="http://success.salesforce.com/ideaview?id=08730000000IYB1AAO">this idea</a>. However, for Visualforce page I have a solution to all of these problems with code!</p>
<p><img title="custom-lookup1.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/custom-lookup1.png" border="0" alt="Custom Lookup" width="500" height="250" /></p>
<p>Here&#8217;s how it looks. It may be easier to watch it full screen at <a href="http://www.youtube.com/watch?v=CGeFt6hdgRY">YouTube</a>.</p>
<p><span class="youtube">
<object width="560" height="340">
<param name="movie" value="http://www.youtube.com/v/CGeFt6hdgRY?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="opaque" src="http://www.youtube.com/v/CGeFt6hdgRY?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="560" height="340"></embed>
<param name="wmode" value="opaque" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=CGeFt6hdgRY&fmt=18">www.youtube.com/watch?v=CGeFt6hdgRY</a></p></p>
<p>Here&#8217;s the code you need to accomplish this. You need two Visualforce pages (the record you are editing and the popup window) and two Apex controllers (a simple one for the record you are editing and the controller for the search and new record popup).</p>
<p><strong>MyCustomLookupController</strong> - <a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/classes/MyCustomLookupController.cls">code at github</a></p>
<p>Here&#8217;s the Apex controller for the record you are either creating or editing. This is an extremely simple controller that just creates a new contact so you can use the lookup for the related account field.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class MyCustomLookupController {
&nbsp;
  public Contact contact {get;set;}
&nbsp;
  public MyCustomLookupController() {
    contact = new Contact();
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>MyCustomLookup</strong> - <a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/pages/MyCustomLookup.page">code at github</a></p>
<p>This is the &#8220;magical&#8221; Visualforce page that uses jQuery to intercept the popup and instead of showing the standard salesforce.com pop, shows our custom popup instead. The user experience is seamless.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">&lt;apex:page controller=&quot;MyCustomLookupController&quot; id=&quot;Page&quot; tabstyle=&quot;Contact&quot;&gt;
&nbsp;
  &lt;script type=&quot;text/javascript&quot;&gt; 
  function openLookup(baseURL, width, modified, searchParam){
    var originalbaseURL = baseURL;
    var originalwidth = width;
    var originalmodified = modified;
    var originalsearchParam = searchParam;
&nbsp;
    var lookupType = baseURL.substr(baseURL.length-3, 3);
    if (modified == '1') baseURL = baseURL + searchParam;
&nbsp;
    var isCustomLookup = false;
&nbsp;
    // Following &quot;001&quot; is the lookup type for Account object so change this as per your standard or custom object
    if(lookupType == &quot;001&quot;){
&nbsp;
      var urlArr = baseURL.split(&quot;&amp;&quot;);
      var txtId = '';
      if(urlArr.length &gt; 2) {
        urlArr = urlArr[1].split('=');
        txtId = urlArr[1];
      }
&nbsp;
      // Following is the url of Custom Lookup page. You need to change that accordingly
      baseURL = &quot;/apex/CustomAccountLookup?txt=&quot; + txtId;
&nbsp;
      // Following is the id of apex:form control &quot;myForm&quot;. You need to change that accordingly
      baseURL = baseURL + &quot;&amp;frm=&quot; + escapeUTF(&quot;{!$Component.myForm}&quot;);
      if (modified == '1') {
        baseURL = baseURL + &quot;&amp;lksearch=&quot; + searchParam;
      }
&nbsp;
      // Following is the ID of inputField that is the lookup to be customized as custom lookup
      if(txtId.indexOf('Account') &gt; -1 ){
        isCustomLookup = true;
      }
    }
&nbsp;
&nbsp;
    if(isCustomLookup == true){
      openPopup(baseURL, &quot;lookup&quot;, 350, 480, &quot;width=&quot;+width+&quot;,height=480,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no&quot;, true);
    }
    else {
      if (modified == '1') originalbaseURL = originalbaseURL + originalsearchParam;
      openPopup(originalbaseURL, &quot;lookup&quot;, 350, 480, &quot;width=&quot;+originalwidth+&quot;,height=480,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no&quot;, true);
    } 
  }
&lt;/script&gt;
&nbsp;
&lt;apex:sectionHeader title=&quot;Demo&quot;  subtitle=&quot;Custom Lookup&quot; /&gt;
&nbsp;
  &lt;apex:form id=&quot;myForm&quot;&gt;  
    &lt;apex:PageBlock id=&quot;PageBlock&quot;&gt;    
      &lt;apex:pageBlockSection columns=&quot;1&quot; title=&quot;Custom Lookup&quot;&gt;
        &lt;apex:inputField id=&quot;Account&quot; value=&quot;{!contact.AccountId}&quot;  /&gt;
      &lt;/apex:pageBlockSection&gt;
    &lt;/apex:PageBlock&gt;
  &lt;/apex:form&gt;
&nbsp;
&lt;/apex:page&gt;</pre></td></tr></table></div>

</p>
<p><strong>CustomAccountLookupController</strong> - <a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/classes/CustomAccountLookupController.cls">code at github</a></p>
<p>The Apex controller for the custom popup window is yours to customize. I know what you are thinking, &#8220;Free at last! Free at last! Thank God Almighty, we are free at last!&#8221; This class has all of your custom search functionality plus the method to create a new account. This is demo code so the search is very limited and does not prevent <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dynamic_soql.htm">soql injections</a>.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class CustomAccountLookupController {
&nbsp;
  public Account account {get;set;} // new account to create
  public List&lt;Account&gt; results{get;set;} // search results
  public string searchString{get;set;} // search keyword
&nbsp;
  public CustomAccountLookupController() {
    account = new Account();
    // get the current search string
    searchString = System.currentPageReference().getParameters().get('lksrch');
    runSearch();  
  }
&nbsp;
  // performs the keyword search
  public PageReference search() {
    runSearch();
    return null;
  }
&nbsp;
  // prepare the query and issue the search command
  private void runSearch() {
    // TODO prepare query string for complex serarches &amp; prevent injections
    results = performSearch(searchString);               
  } 
&nbsp;
  // run the search and return the records found. 
  private List&lt;Account&gt; performSearch(string searchString) {
&nbsp;
    String soql = 'select id, name from account';
    if(searchString != '' &amp;&amp; searchString != null)
      soql = soql +  ' where name LIKE \'%' + searchString +'%\'';
    soql = soql + ' limit 25';
    System.debug(soql);
    return database.query(soql); 
&nbsp;
  }
&nbsp;
  // save the new account record
  public PageReference saveAccount() {
    insert account;
    // reset the account
    account = new Account();
    return null;
  }
&nbsp;
  // used by the visualforce page to send the link to the right dom element
  public string getFormTag() {
    return System.currentPageReference().getParameters().get('frm');
  }
&nbsp;
  // used by the visualforce page to send the link to the right dom element for the text box
  public string getTextBox() {
    return System.currentPageReference().getParameters().get('txt');
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>CustomAccountLookup</strong> - <a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/pages/CustomAccountLookup.page">code at github</a></p>
<p>Any finally the Visualforce page for the popup itself. It contains a tabbed interface easily allowing a user to search for records and create new ones. Make sure you look at the code for the second tab for creating a new record. I have better things to do than change the fields on the input form every time a new field is created or something is made required. The solution is to use <a href="http://www.salesforce.com/us/developer/docs/pages/Content/pages_dynamic_vf_field_sets.htm">field sets</a>! So when an administrator makes a change, they can simply update the field set and the popup reflects the change accordingly. Life is good.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">&lt;apex:page controller=&quot;CustomAccountLookupController&quot;
  title=&quot;Search&quot; 
  showHeader=&quot;false&quot; 
  sideBar=&quot;false&quot; 
  tabStyle=&quot;Account&quot; 
  id=&quot;pg&quot;&gt;
&nbsp;
  &lt;apex:form &gt;
  &lt;apex:outputPanel id=&quot;page&quot; layout=&quot;block&quot; style=&quot;margin:5px;padding:10px;padding-top:2px;&quot;&gt;
    &lt;apex:tabPanel switchType=&quot;client&quot; selectedTab=&quot;name1&quot; id=&quot;tabbedPanel&quot;&gt;
&nbsp;
      &lt;!-- SEARCH TAB --&gt;
      &lt;apex:tab label=&quot;Search&quot; name=&quot;tab1&quot; id=&quot;tabOne&quot;&gt;
&nbsp;
        &lt;apex:actionRegion &gt;  
          &lt;apex:outputPanel id=&quot;top&quot; layout=&quot;block&quot; style=&quot;margin:5px;padding:10px;padding-top:2px;&quot;&gt;
            &lt;apex:outputLabel value=&quot;Search&quot; style=&quot;font-weight:Bold;padding-right:10px;&quot; for=&quot;txtSearch&quot;/&gt;
            &lt;apex:inputText id=&quot;txtSearch&quot; value=&quot;{!searchString}&quot; /&gt;
              &lt;span style=&quot;padding-left:5px&quot;&gt;&lt;apex:commandButton id=&quot;btnGo&quot; value=&quot;Go&quot; action=&quot;{!Search}&quot; rerender=&quot;searchResults&quot;&gt;&lt;/apex:commandButton&gt;&lt;/span&gt;
          &lt;/apex:outputPanel&gt;
&nbsp;
          &lt;apex:outputPanel id=&quot;pnlSearchResults&quot; style=&quot;margin:10px;height:350px;overflow-Y:auto;&quot; layout=&quot;block&quot;&gt;
            &lt;apex:pageBlock id=&quot;searchResults&quot;&gt; 
              &lt;apex:pageBlockTable value=&quot;{!results}&quot; var=&quot;a&quot; id=&quot;tblResults&quot;&gt;
                &lt;apex:column &gt;
                  &lt;apex:facet name=&quot;header&quot;&gt;
                    &lt;apex:outputPanel &gt;Name&lt;/apex:outputPanel&gt;
                  &lt;/apex:facet&gt;
                   &lt;apex:outputLink value=&quot;javascript:top.window.opener.lookupPick2('{!FormTag}','{!TextBox}_lkid','{!TextBox}','{!a.Id}','{!a.Name}', false)&quot; rendered=&quot;{!NOT(ISNULL(a.Id))}&quot;&gt;{!a.Name}&lt;/apex:outputLink&gt;     
                &lt;/apex:column&gt;
              &lt;/apex:pageBlockTable&gt;
            &lt;/apex:pageBlock&gt;
          &lt;/apex:outputPanel&gt;
        &lt;/apex:actionRegion&gt;
&nbsp;
      &lt;/apex:tab&gt;
&nbsp;
      &lt;!-- NEW ACCOUNT TAB --&gt;
      &lt;apex:tab label=&quot;New Account&quot; name=&quot;tab2&quot; id=&quot;tabTwo&quot;&gt;
&nbsp;
        &lt;apex:pageBlock id=&quot;newAccount&quot; title=&quot;New Account&quot; &gt;
&nbsp;
          &lt;apex:pageBlockButtons &gt;
            &lt;apex:commandButton action=&quot;{!saveAccount}&quot; value=&quot;Save&quot;/&gt;
          &lt;/apex:pageBlockButtons&gt;
          &lt;apex:pageMessages /&gt;
&nbsp;
          &lt;apex:pageBlockSection columns=&quot;2&quot;&gt;
            &lt;apex:repeat value=&quot;{!$ObjectType.Account.FieldSets.CustomAccountLookup}&quot; var=&quot;f&quot;&gt;
              &lt;apex:inputField value=&quot;{!Account[f]}&quot;/&gt;
            &lt;/apex:repeat&gt;
          &lt;/apex:pageBlockSection&gt; 
        &lt;/apex:pageBlock&gt;
&nbsp;
      &lt;/apex:tab&gt;
    &lt;/apex:tabPanel&gt;
  &lt;/apex:outputPanel&gt;
  &lt;/apex:form&gt;
&lt;/apex:page&gt;</pre></td></tr></table></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/08/12/roll-your-own-salesforce-lookup-popup-window/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>OpportunityAccessLevel Not Writable</title>
		<link>http://blog.jeffdouglas.com/2011/03/17/opportunityaccesslevel-not-writable/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=opportunityaccesslevel-not-writable</link>
		<comments>http://blog.jeffdouglas.com/2011/03/17/opportunityaccesslevel-not-writable/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 10:40:44 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3767</guid>
		<description><![CDATA[I was working on a project the other day where I needed to dynamically add users to an opportunity&#8217;s Sales Team (OpportunityTeamMember object) so that users who do not normally have access to an opportunity based upon Org-wide security settings can work on the opportunity with other team members. One of the advantages of Sales [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F17%2Fopportunityaccesslevel-not-writable%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F17%2Fopportunityaccesslevel-not-writable%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I was working on a project the other day where I needed to dynamically add users to an opportunity&#8217;s Sales Team (OpportunityTeamMember object) so that users who do not normally have access to an opportunity based upon Org-wide security settings can work on the opportunity with other team members. One of the advantages of Sales Teams is that you can specify the level of access that each team member has for the opportunity. Some team members may need read/write access while others may just need read-only access.</p>
<p>From the opportunity page layout you can add a new team member and specify their access level and role.</p>
<p><img title="sales-team.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/03/sales-team.png" border="0" alt="Sales team" width="500" height="186" /></p>
<p>However, by default when you create a new team member via Apex, the platform grants them read-only access. So I tried to specify grant &#8220;Edit&#8221; (read/write) access with the following code.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">OpportunityTeamMember member = new OpportunityTeamMember();
member.OpportunityId = SomeOpp.Id;
member.UserId = SomeUser.Id;
mmember.TeamMemberRole = 'Sales Rep';
member.OpportunityAccessLevel = 'Edit';</pre></td></tr></table></div>

</p>
<p>Specifying the OpportunityAccessLevel threw the following error when saving my class:</p>
<blockquote><p>Save error: Field is not writable: OpportunityTeamMember.OpportunityAccessLevel</p></blockquote>
<p>To be fair, <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_opportunityteammember.htm" target="_blank">the docs</a> state that OpportunityAccessLevel is not creatable but it used to be with earlier versions of the API so I <em><strong>really</strong></em> wanted this to work and it was screwing up my day.</p>
<p>So here&#8217;s the solution that I can up with in case anyone is looking for a answers. You need to add the team members to the opportunity and then update the sharing access to the opportunity for these users.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">OpportunityTeamMember member = new OpportunityTeamMember();
member.OpportunityId = SomeOpp.Id;
member.UserId = SomeUser.Id;
mmember.TeamMemberRole = 'Sales Rep';
&nbsp;
insert member;
&nbsp;
// get all of the team members' sharing records
List&lt;OpportunityShare&gt; shares = [select Id, OpportunityAccessLevel, 
  RowCause from OpportunityShare where OpportunityId IN :SomeSetOfOpptyIds 
  and RowCause = 'Team'];
&nbsp;
// set all team members access to read/write
for (OpportunityShare share : shares) 
  share.OpportunityAccessLevel = 'Edit';
&nbsp;
update shares;</pre></td></tr></table></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/03/17/opportunityaccesslevel-not-writable/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Dynamically Group &amp; Display Query Results</title>
		<link>http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=dynamically-group-display-query-results</link>
		<comments>http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 10:55:14 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3737</guid>
		<description><![CDATA[I was working on a Visualforce page that displays the results of a query in separate PageBlock sections based upon a value in the query results. I ran into a small issue which took about an hour or so to solve, so I thought it might make descent blog fodder. The requirement for the page [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F02%2Fdynamically-group-display-query-results%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F02%2Fdynamically-group-display-query-results%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I was working on a Visualforce page that displays the results of a query in separate PageBlock sections based upon a value in the query results. I ran into a small issue which took about an hour or so to solve, so I thought it might make descent blog fodder. </p>
<p>The requirement for the page was to query for records and then display them grouped in sections in a Visualforce page based upon whatever values (in this case BillingState) are returned in the results. If additional states were added, then the Visualforce page should be able to add those new sections without changes to the code. Here&#8217;s a screenshot of the sample solution that I came up with but you can also<a href="http://jeffdouglas-developer-edition.na5.force.com/examples/DisplaySections" target="_blank"> run this sample on my Developer Site</a>:</p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/03/group-by-value.png" rel="lightbox[3737]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/03/group-by-value-300x283.png" alt="" title="group-by-value" width="300" height="283" class="alignnone size-medium wp-image-3738" /></a></p>
<p>Here&#8217;s the code for the Visualforce page. I&#8217;ve made it as bare as possible but you can see that it iterates over the array of states to display the pageBlock sections and then displays the record if the state matches the current blockSection&#8217;s state.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">&lt;apex:page controller=&quot;DisplaySectionsController&quot; action=&quot;{!load}&quot; sidebar=&quot;false&quot;&gt;
  &lt;apex:sectionHeader title=&quot;My Sample Display Page&quot; subtitle=&quot;Group by States&quot; 
    description=&quot;This page shows how you can dynamically group results by field value.&quot;/&gt;
&nbsp;
  &lt;apex:repeat value=&quot;{!states}&quot; var=&quot;state&quot;&gt;
&nbsp;
    &lt;apex:pageBlock title=&quot;{!state}&quot;&gt;
&nbsp;
      &lt;apex:repeat value=&quot;{!accounts}&quot; var=&quot;account&quot;&gt; 
&nbsp;
        &lt;apex:outputPanel rendered=&quot;{!IF(state=account.BillingState,true,false)}&quot;&gt;
        {!account.Name} - {!account.BillingState}&lt;br/&gt;
        &lt;/apex:outputPanel&gt;
&nbsp;
      &lt;/apex:repeat&gt;
&nbsp;
    &lt;/apex:pageBlock&gt;
&nbsp;
  &lt;/apex:repeat&gt;
&nbsp;
&lt;/apex:page&gt;</pre></td></tr></table></div>

<p>The Controller exposes two collections to the Visualforce page: the list of Accounts and the array of States.  Here&#8217;s the issue that I ran into. Since I wanted to have a collection of unique state names, I originally added each state to a Set and simply returned the Set to the Visualforce page (instead of the array) to display the pageBlock sections. However, returning the Set gave me a compile error at line 11 in the Visualforce page:</p>
<blockquote><p>Save error: Incorrect parameter for operator &#8216;=&#8217;. Expected Text, received Object</p></blockquote>
<p>The problem is that even though the Set is a collection of Strings, it is actually an object underneath the covers and throws a comparison error. Therefore you have to return the states as an array of strings for the code to compile and run properly.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class DisplaySectionsController {
&nbsp;
  public List&lt;Account&gt; accounts {get;set;}  
  public String[] states {get;set;}
&nbsp;
  public void load() {
&nbsp;
    // for demo purposes limit the states  
    accounts = [Select ID, Name, BillingState From Account 
      Where BillingState IN ('CA','NY','FL')];
&nbsp;
    // dynamically create set of unique states from query
    Set&lt;String&gt; stateSet = new Set&lt;String&gt;();
    for (Account a : accounts)
      stateSet.add(a.BillingState);
&nbsp;
    // convert the set into a string array  
    states = new String[stateSet.size()];
    Integer i = 0;
    for (String state : stateSet) { 
      states[i] = state;
      i++;
    }
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Fun with Salesforce Collections</title>
		<link>http://blog.jeffdouglas.com/2011/01/06/fun-with-salesforce-collections/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=fun-with-salesforce-collections</link>
		<comments>http://blog.jeffdouglas.com/2011/01/06/fun-with-salesforce-collections/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 15:51:08 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3474</guid>
		<description><![CDATA[The Apex language provides developers with three classes (Set, List and Map) that make it easier to handle collections of objects. In a sense these collections work somewhat like arrays, except their size can change dynamically, and they have more advanced behaviors and easier access methods than arrays. If you are familiar with the Java [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F01%2F06%2Ffun-with-salesforce-collections%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F01%2F06%2Ffun-with-salesforce-collections%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>The Apex language provides developers with three classes (Set, List and Map) that make it easier to handle collections of objects. In a sense these collections work somewhat like arrays, except their size can change dynamically, and they have more advanced behaviors and easier access methods than arrays. If you are familiar with the Java Collections API then these should feel very warm and cozy. Each collection has characteristics that make it applicable in certain situations and we&#8217;ll cover these in detail. We&#8217;ll talk about each of the collections, their features, how they are typically used and show some sample code that you can execute in your org. </p>
<p><strong>Note:</strong> Salesforce.com recently made an important change to collections. There is no longer a limit on the number of items a collection can hold. However, there is a general limit on <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm#total_heap_size_limit_desc" target="_blank">heap size</a>.</p>
<p>I tried to fit virtually everything that I could about collections onto a single blog post hoping it will make good Evernote fodder. If I left something out, please drop a comment below.</p>
<h3>Set</h3>
<p>A set is a collection of unique, unordered elements. It can contain <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_primitives.htm" target="_blank">primitive data types</a> (String, Integer, Date, etc) or sObjects. If you need ordered elements use a List instead. You typically see Sets used to store collections of IDs that you want to use in a SOQL query.</p>
<p>The basic syntax for creating a new Set is:</p>
<p><i>Set&lt;datatype&gt;  set_name<br />
&nbsp;&nbsp;&nbsp;[= new Set&lt;datatype&gt;();] |<br />
&nbsp;&nbsp;&nbsp;[= new Set&lt;datatype&gt;{value [, value2. . .] };] |;</i></p>
<p>Examples: </p>
<p>Set&lt;String&gt; s = new Set&lt;String&gt;();<br />
Set&lt;String&gt; s = new Set&lt;String&gt;{&#8216;Jon&#8217;, &#8216;Quinton&#8217;, &#8216;Reid&#8217;};</p>
<p>As mentioned before one of the main characteristics of a Set is the uniqueness of elements. You can safely try to add the same element (e.g., 100, &#8216;c&#8217;, 125.25) to a Set more than once and it will just disregard the duplicate (without throwing an Exception). However, there is a slight twist when dealing with sObjects. Uniqueness of sObjects is determined by comparing fields in the objects. The following code will result in only one element in the Set.</p>
<p>Account acct1 = new account(Name=&#8217;ACME Corp&#8217;);<br />
Account acct2 = new account(Name=&#8217;ACME Corp&#8217;);<br />
Set&lt;Account&gt; s = new Set&lt;Account&gt;{acct1, acct2}; // Set will only contain 1 element</p>
<p>Different field values cause the objects to become unique.</p>
<p>Account acct1 = new account(Name=&#8217;ACME Corp&#8217;, BillingAddress=&#8217;100 Main&#8217;);<br />
Account acct2 = new account(Name=&#8217;ACME Corp&#8217;);<br />
Set&lt;Account&gt; s = new Set&lt;Account&gt;{acct1, acct2}; // Set will only contain 2 elements</p>
<p><strong>Set Methods</strong><br />
There are a number Set methods so <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_set.htm" target="_blank">check out the docs</a> for a complete list, but here are some of the more common ones you might use. You can paste the following snippet of code into your browser&#8217;s System Log and run it anonymously.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">// create a new set with 3 elements
Set&lt;String&gt; s = new Set&lt;String&gt;{'Jon', 'Quinton', 'Reid'};
// adds an element IF not already present
s.add('Sandeep');
// adds an element IF not already present
s.add('Sandeep'); 
// return the number of elements
System.debug('=== number of elements: ' + s.size()); 
// removes the element if present
s.remove('Reid'); 
 // return the number of elements
System.debug('=== number of elements: ' + s.size());
// returns true if the set contains the specified element
System.debug('=== set contains element Jon: ' + s.contains('Jon')); 
// output all elements in the set
for (String str : s) 
  // outputs an element
  System.debug('=== element : ' + str); 
// makes a duplicate of the set
Set&lt;String&gt; s1 = s.clone(); 
// displays the contents of the set
System.debug('=== contents of s1: ' + s1); 
// removes all elements
s1.clear(); 
// returns true if the set has zero elements
System.debug('=== is the s1 set empty? ' + s1.isEmpty());</pre></td></tr></table></div>

<p>You should see the following (abbreviated) output:</p>
<p>DEBUG|=== number of elements: 4<br />
DEBUG|=== number of elements: 3<br />
DEBUG|=== set contains element Jon: true<br />
DEBUG|=== element : Jon<br />
DEBUG|=== element : Quinton<br />
DEBUG|=== element : Sandeep<br />
DEBUG|=== contents of s1: {Jon, Quinton, Sandeep}<br />
DEBUG|=== is the s1 set empty? true</p>
<p>Commonly you&#8217;ll see developers construct a Set of IDs from a query, trigger context, etc. and then use it as part of the WHERE clause in their SOQL query:</p>
<p>Set&lt;ID&gt; ids = new Set&lt;ID&gt;{&#8217;0017000000cBlbwAAC&#8217;,&#8217;0017000000cBXCWAA4&#8242;};<br />
List&lt;Account&gt; accounts = [Select Name From Account Where Id = :ids];</p>
<h3>List</h3>
<p>Lists are the mostly widely used collection so learn to love them (I do!!). A List is a collection of primitives, user-defined objects, sObjects, Apex objects or other collections (can be multidimensional up to 5 levels). Use a List (as opposed to a Set) when the sequence of elements is important. You can also have duplicate elements in a List. List are zero-based so the first element in the List is always 0.</p>
<p>The basic syntax for creating a new List is:</p>
<p><em>List &lt;datatype&gt;  list_name<br />
&nbsp;&nbsp;&nbsp;[= new List&lt;datatype&gt;();] |<br />
&nbsp;&nbsp;&nbsp;[=new List&lt;datatype&gt;{value [, value2. . .]};] |;</em></p>
<p>Examples:</p>
<p>List&lt;Integer&gt; s = new List&lt;Integer&gt;();<br />
List&lt;String&gt; s = new List&lt;String&gt;{&#8216;Jon&#8217;, &#8216;Quinton&#8217;, &#8216;Reid&#8217;};</p>
<p>// Create a nested List of Sets<br />
List&lt;List&lt;Set&lt;String&gt;&gt;&gt; s2 = new List&lt;List&lt;Set&lt;String&gt;&gt;&gt;();</p>
<p>// Create a List of contact records from a SOQL query<br />
List&lt;Contacts&gt; contacts = [SELECT Id, FirstName, LastName FROM Contact LIMIT 10]; </p>
<p>Lists and Arrays are pretty much interchangeable and you can mix and match them:</p>
<p>List&lt;Contact&gt; contacts = newContact[] {new(), newContact()};</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">List&lt;String&gt; s = new List&lt;String&gt;{'Jon', 'Quinton', 'Reid'};
String[] s1 = new String[]{'Jon', 'Quinton', 'Reid'};
System.debug('=== ' + s.get(0));
System.debug('=== ' + s1.get(0));
System.debug('=== ' + s[0]);
System.debug('=== ' + s1[0]);</pre></td></tr></table></div>

<p>You should see the following (abbreviated) output:</p>
<p>DEBUG|=== Jon<br />
DEBUG|=== Jon<br />
DEBUG|=== Jon<br />
DEBUG|=== Jon</p>
<p><strong>List Methods</strong><br />
There are a number List methods so <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_list.htm" target="_blank">check out the docs</a> for a complete list, but here are some of the more common ones you might use. You can paste the following snippet of code into your browser&#8217;s System Log and run it anonymously.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">List&lt;String&gt; s = new List&lt;String&gt;{'Jon', 'Quinton', 'Reid'};
// adds an element
s.add('Sandeep'); 
// adds an element
s.add('Sandeep'); 
// return the number of elements
System.debug('=== number of elements: ' + s.size());
// displays the first element 
System.debug('=== first element: ' + s.get(0)); 
// removes the first element
s.remove(0); 
// return the number of elements
System.debug('=== number of elements: ' + s.size()); 
// makes a duplicate of the set
List&lt;String&gt; s1 = s.clone(); 
// displays the contents of the set
System.debug('=== contents of s1: ' + s1); 
// replace the last instance of 'Sandeep' with 'Pat'
s1.set(3,'Pat'); // displays the contents of the set
System.debug('=== contents of s1: ' + s1); 
// sorts the items in ascending (primitave only)
s1.sort(); 
// displays the contents of the set
System.debug('=== sorted contents of s1: ' + s1); 
// removes all elements
s.clear(); 
// returns true if the set has zero elements
System.debug('=== is the list empty? ' + s.isEmpty());</pre></td></tr></table></div>

<p>You should see the following (abbreviated) output:</p>
<p>DEBUG|=== number of elements: 5<br />
DEBUG|=== first element: Jon<br />
DEBUG|=== number of elements: 4<br />
DEBUG|=== contents of s1: (Quinton, Reid, Sandeep, Sandeep)<br />
DEBUG|=== contents of s1: (Quinton, Reid, Sandeep, Pat)<br />
DEBUG|=== sorted contents of s1: (Pat, Quinton, Reid, Sandeep)<br />
DEBUG|=== is the list empty? true</p>
<p>You can use a List of Strings in the same sort of way you would a Set as part of a SOQL query:</p>
<p>List&lt;String&gt; ids = new List&lt;String&gt;{&#8217;0017000000cBlbwAAC&#8217;,&#8217;0017000000cBXCWAA4&#8242;};<br />
List&lt;Account&gt; accounts = [Select Name From Account Where Id IN :ids];</p>
<p>Since SOQL queries return Lists of records, you can use them directly for iteration:</p>
<p>for (Account a : [Select Id, Name From Account Limit 2]) {<br />
&nbsp;&nbsp;System.debug(&#8216;=== &#8216; + a.Name);<br />
}</p>
<p>You can also use the List in a traditional for loop:</p>
<p>List&lt;Account&gt; accounts = [Select Id, Name From Account Limit 2];<br />
for (Integer i=0;i&lt;accounts.size();i++) {<br />
&nbsp;&nbsp;System.debug(&#8216;=== &#8216; + accounts.get(i).Name);<br />
}</p>
<h3>Map</h3>
<p>A Map is a collection of key-value pairs. Keys can be any primitive data type while values can include primitives, Apex objects, sObjects and other collections. Use a map when you want to quickly find something by a key. Each key must be unique but you can have duplicate values in your Map.</p>
<p>The basic syntax for creating a new Map is:</p>
<p><em>Map&lt;key_datatype, value_datatype&gt;  map_name<br />
&nbsp;&nbsp;&nbsp;[=new map&lt;key_datatype, value_datatype&gt;();] |<br />
&nbsp;&nbsp;&nbsp;[=new map&lt;key_datatype, value_datatype&gt;<br />
&nbsp;&nbsp;&nbsp;{key1_value =&gt;  value1_value<br />
&nbsp;&nbsp;&nbsp;[, key2_value =&gt;  value2_value. . .]};] |;</em></p>
<p>Examples:</p>
<p>Map&lt;Integer, String&gt; m = new Map&lt;Integer, String&gt;{5 =&gt; &#8216;Jon&#8217;, 6 =&gt; &#8216;Quinton&#8217;, 1 =&gt; &#8216;Reid&#8217;};<br />
Map&lt;ID, Set&lt;String&gt;&gt; m = new Map&lt;D, Set&lt;String&gt;&gt;();<br />
// creates a map where the key is the ID of the record<br />
Map&lt;Id,Account&gt; aMap = new Map&lt;Id, Account&gt;([Select Id, Name From Account LIMIT 2]);</p>
<p><strong>Map Methods</strong><br />
There are a number Map methods so <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_map.htm" target="_blank">check out the docs</a> for a complete list, but here are some of the more common ones you might use. You can paste the following snippet of code into your browser&#8217;s System Log and run it anonymously.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Map m = new Map{5 =&gt; 'Jon', 6 =&gt; 'Quinton', 1 =&gt; 'Reid'};
// displays all keys
System.debug('=== all keys in the map: ' + m.keySet()); 
// displays all values
System.debug('=== all values in the map (as a List): ' + m.values()); 
// does the key exist?
System.debug('=== does key 6 exist?: ' + m.containsKey(6)); 
// fetches the value for the key
System.debug('=== value for key 6: ' + m.get(6)); 
// adds a new key/value pair
m.put(3,'Dave'); 
// returns the number of elements
System.debug('=== size after adding Dave: ' + m.size()); 
// removes an element
m.remove(5); 
System.debug('=== size after removing Jon: ' + m.size());
// clones the map
Map m1 = m.clone(); 
System.debug('=== cloned m1: ' + m1);
// removes all elements
m.clear(); 
// returns true if zero elements
System.debug('=== is m empty? ' + m.isEmpty());</pre></td></tr></table></div>

<p>You should see the following (abbreviated) output:</p>
<p>DEBUG|=== all keys in the map: {1, 5, 6}<br />
DEBUG|=== all values in the map (as a List): (Reid, Jon, Quinton)<br />
DEBUG|=== does key 6 exist?: true<br />
DEBUG|=== value for key 6:  Quinton<br />
DEBUG|=== size after adding Dave: 4<br />
DEBUG|=== size after removing Jon: 3<br />
DEBUG|=== cloned m1: {1=Reid, 3=Dave, 6=Quinton}<br />
DEBUG|=== is m empty? true</p>
<p>Maps are used very frequently to store records that you want to process or as containers for &#8220;lookup&#8221; data. It&#8217;s very common to query for records and store them in a Map so that you can &#8220;do something&#8221; with them. The query below creates a Map for you where the key is the ID of the record. This makes it easy to find the record in the Map based upon the ID. You can paste the following snippet of code into your browser&#8217;s System Log and run it anonymously.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">Map&lt;Id,Account&gt; accountMap = new Map&lt;Id, Account&gt;(
  [Select Id, Name From Account LIMIT 2]);
System.debug('=== ' + accountMap);
// keySet() returns a Set we can iterate through
for (Id id : accountMap.keySet()) {
  System.debug('=== ' + accountMap.get(id).Name);
}</pre></td></tr></table></div>

<p>You&#8217;ll use Maps quite a bit when writing triggers. For before update and after update triggers there are two trigger context variables named oldMap and newMap. The oldMap contains a list of sObject before they were modified. The newMap contains a list of sObject with the updated values. You typically use these Maps to make some sort of comparison inside the trigger:</p>
<p>for (Id id : Trigger.newMap.keySet()) {<br />
&nbsp;&nbsp;if (Trigger.oldMap.get(id).LastName != Trigger.newMap.get(id).LastName) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.debug(&#8216;=== the last name has changed!!&#8217;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;// handle the name change somehow<br />
&nbsp;&nbsp;}<br />
}</p>
<p>Maps are also used extensively to stay within governors and limits. The following is code from <a href="http://blog.jeffdouglas.com/2009/04/20/writing-bulk-triggers-for-salesforce/" target="_blank">Writing Bulk Triggers in Salesforce.com</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">trigger AddOwnerColor on Account (before insert, before update) {
&nbsp;
  // create a set of all the unique ownerIds
  Set&lt;id&gt; ownerIds = new Set&lt;id&gt;();
  for (Account a : Trigger.new)
      ownerIds.add(a.OwnerId);  
&nbsp;
  // query for all the User records for the unique userIds in the records
  // create a map for a lookup / hash table for the user info
  Map&lt;id, User&gt; owners = new Map&lt;id, User&gt;([Select Favorite_Color__c from User Where Id in :ownerIds]); 
&nbsp;
  // iterate over the list of records being processed in the trigger and
  // set the color before being inserted or updated
  for (Account a : Trigger.new)
      a.Owner_Favorite_Color__c = owners.get(a.OwnerId).Favorite_Color__c;
&nbsp;
}</pre></td></tr></table></div>

<p><strong>Modifying Collection Elements</strong><br />
Modifying a collection&#8217;s elements while iterating through that collection is not supported and will throw an error. To add or remove elements for a collection,  while iterating over the collection, create a new temporary list with these elements. Then simply add or remove them after you are finished iterating the collection.</p>
<p><strong>Custom Iterators</strong><br />
Apex has the ability to create <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_iterable.htm" target="_blank">custom Iterators</a> but that is a little beyond the scope of this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/01/06/fun-with-salesforce-collections/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Force.com Programming Best Practices</title>
		<link>http://blog.jeffdouglas.com/2010/10/21/force-com-programming-best-practices/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=force-com-programming-best-practices</link>
		<comments>http://blog.jeffdouglas.com/2010/10/21/force-com-programming-best-practices/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 11:56:18 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Salesforce Handbook]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3301</guid>
		<description><![CDATA[  ﻿Wes and I are adding a few more topics to our Salesforce Handbook before we put it to bed and I thought a great topic would be programming best practices. I&#8217;ve never seen a &#8220;complete&#8221; list of best practices so I thought I would put something together based upon my experiences. I know I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F10%2F21%2Fforce-com-programming-best-practices%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F10%2F21%2Fforce-com-programming-best-practices%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p> </p>
<p>﻿Wes and I are adding a few more topics to our <a href="http://salesforcehandbook.wordpress.com/">Salesforce Handbook</a> before we put it to bed and I thought a great topic would be programming best practices. I&#8217;ve never seen a &#8220;complete&#8221; list of best practices so I thought I would put something together based upon my experiences. I know I&#8217;ve left some out, so if you have any to add, please chime in and we may include them in the book.</p>
<p><strong>Apex</strong></p>
<ul>
<li>Since Apex is case insensitive you can write it however you&#8217;d like. However, to increase readability, follow Java capitalization standards and use two spaces instead of tabs for indentation.</li>
<li>Use Asychronous Apex (@future annotation) for logic that does not need to be executed synchronous. </li>
<li>Asychronous Apex should be &#8220;bulkified&#8221;.</li>
<li>Apex code must provide proper exception handling.</li>
<li>Prevent SOQL and SOSL injection attacks by using static queries, binding variables or the escapeSingleQuotes method.</li>
<li>When querying large data sets, use a <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_SOQL_VLSQ.htm">SOQL &#8220;for&#8221; loop</a> </li>
<li>Use SOSL over SOQL where possible &#8211; it&#8217;s much faster.</li>
<li>Use Apex Limits Methods to avoid hitting governor exceptions.</li>
<li>No SOQL or SOSL queries inside loops</li>
<li>No DML statements inside loops</li>
<li>No Async (@future) methods inside loops</li>
<li>Do not use hardcoded IDs</li>
</ul>
<p> </p>
<p><strong>Triggers</strong></p>
<ul>
<li>There should only be one trigger for each object.</li>
<li>Avoid complex logic in triggers. To simplify testing and resuse, triggers should delegate to Apex classes which contain the actual execution logic. See Mike Leach&#8217;s <a href="http://www.embracingthecloud.com/2010/07/08/ASimpleTriggerTemplateForSalesforce.aspx">excellent trigger template</a> for more info.</li>
<li>Bulkify any &#8220;helper&#8221; classes and/or methods.</li>
<li>Trigers should be &#8220;bulkified&#8221; and be able to process up to 200 records for each call.</li>
<li>Execute DML statements using collections instead of individual records per DML statement.</li>
<li>Use Collections in SOQL &#8220;WHERE&#8221; clauses to retrieve all records back in single query</li>
<li>Use a consistent naming convention including the object name (e.g., AccountTrigger)</li>
</ul>
<p> </p>
<p><strong>Visualforce</strong></p>
<ul>
<li>Do not hardcode picklists in Visualforce pages; include them in the controller instead.</li>
<li>Javascript and CSS should be included as Static Resources allowing the browser to cache them.</li>
<li>Reference CSS at the top and JavaScript a the bottom of Visualforce pages as this provides for faster page loads.</li>
<li>Mark controller variables as &#8220;transient&#8221; if they are not needed between server calls. This will make your page load faster as it reduces the size of the View State. </li>
<li>Use &lt;apex:repeat&gt; to iterate over large collections.</li>
<li>Use the cache attribute with the &lt;apex:page&gt; component to take advantage CDN caching when appropriate</li>
</ul>
<p> </p>
<p><strong>Unit Testing</strong></p>
<ul>
<li>Use a consistent naming convention including &#8220;Test&#8221; and the name of the class being tested (e.g., Test_AccountTrigger)</li>
<li>Test classes should use the @isTest annotation</li>
<li>Test methods should craete all data needed for the method and not rely on data currently in the Org. </li>
<li>Use System.assert liberally to prove that code behaves as expected.</li>
<li>Test each branch of conditional logic</li>
<li>Write test methods that both pass and fail for certain conditions and test for boundary conditions.</li>
<li>Test triggers to process 200 records &#8211; make sure your code is &#8220;bulkified&#8221; for 200 records and doesn&#8217;t throw the dreaded &#8220;Too many SOQL queries: 21&#8243; exception.</li>
<li>When testing for governor limits, use Test.startTest and Test.stopTest and the Limit class instead of hard-coding governor limits.</li>
<li>Use System.runAs() to execute code as a specific user to test for sharing rules (but not CRUD or FLS permissions)</li>
<li>Execute tests with the Force.com IDE and not the salesforce.com UI. We&#8217;ve seen misleading code coverage results when running from the salesforce.com UI.</li>
<li>Run the <a href="http://security.force.com/sourcescanner">Force.com Security Source Scanner</a> to test your Org for a number of security and code quality issues (e.g., Cross Site Scripting, Access Control Issues, Frame Spoofing)</li>
</ul>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/10/21/force-com-programming-best-practices/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Error &#8211; Portal account owner must have a role??</title>
		<link>http://blog.jeffdouglas.com/2010/09/02/error-portal-account-owner-must-have-a-role/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=error-portal-account-owner-must-have-a-role</link>
		<comments>http://blog.jeffdouglas.com/2010/09/02/error-portal-account-owner-must-have-a-role/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 14:05:08 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3170</guid>
		<description><![CDATA[I wrote the following test class for a PRM deployment and received this crazy error when running the test: System.DmlException: Insert failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, portal account owner must have a role: [] I searched the message boards but couldn&#8217;t find any reference to the real culprit. My original thought [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F09%2F02%2Ferror-portal-account-owner-must-have-a-role%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F09%2F02%2Ferror-portal-account-owner-must-have-a-role%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I wrote the following test class for a PRM deployment and received this crazy error when running the test:</p>
<p><em><strong>System.DmlException: Insert failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, portal account owner must have a role: []</strong></em></p>
<p>I searched the message boards but couldn&#8217;t find any reference to the real culprit. My original thought was that the user being created was causing an error somehow. However, <strong>the real problem was that <em>my</em> user was not assigned a role</strong>. Hopefully this post saves someone some time tracking down the solution.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">  Account a = new Account(Name='Test Account Name');
  insert a;
&nbsp;
  Contact c = new Contact(LastName = 'Contact Last Name', AccountId = a.id);
  insert c;
&nbsp;
  User user = new User();
  user.ProfileID = [Select Id From Profile Where Name='Some Profile'].id;
  user.EmailEncodingKey = 'ISO-8859-1';
  user.LanguageLocaleKey = 'en_US';
  user.TimeZoneSidKey = 'America/New_York';
  user.LocaleSidKey = 'en_US';
  user.FirstName = 'first';
  user.LastName = 'last';
  user.Username = 'test@appirio.com';   
  user.CommunityNickname = 'testUser123';
  user.Alias = 't1';
  user.Email = 'no@email.com';
  user.IsActive = true;
  user.ContactId = c.Id;
&nbsp;
  insert user;
&nbsp;
  System.RunAs(user) {
    // do all of my tests
  }</pre></td></tr></table></div>

<p>You will also see this same error (for the same reason) when trying to enable a contact as a partner or customer portal user.</p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/09/portal-user-error.png" rel="lightbox[3170]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2010/09/portal-user-error.png" alt="" title="portal-user-error" width="540" height="106" class="alignnone size-full wp-image-3234" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/09/02/error-portal-account-owner-must-have-a-role/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Managing the Heap in Salesforce.com</title>
		<link>http://blog.jeffdouglas.com/2010/08/16/managing-the-heap-in-salesforce-com/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=managing-the-heap-in-salesforce-com</link>
		<comments>http://blog.jeffdouglas.com/2010/08/16/managing-the-heap-in-salesforce-com/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 11:42:50 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3111</guid>
		<description><![CDATA[With the Spring &#8217;10 release, Salesforce.com removed the limit on the number of items a collection can hold. So now, instead of ensuring that your collections contain no more than 1000 items, you have to monitor your heap size. Here are some strategies on how to write Apex scripts that run within these limits. First [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F08%2F16%2Fmanaging-the-heap-in-salesforce-com%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F08%2F16%2Fmanaging-the-heap-in-salesforce-com%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://blog.jeffdouglas.com/2010/08/16/managing-the-heap-in-salesforce-com/heap1/" rel="attachment wp-att-3120"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2010/08/heap1-150x150.jpg" alt="" title="heap1" width="150" height="150" class="alignleft size-thumbnail wp-image-3120" /></a>With the <a href="http://blog.jeffdouglas.com/2010/01/12/my-favorite-salesforce-com-spring-10-features/" target="_blank">Spring &#8217;10</a> release, Salesforce.com removed the limit on the number of items a collection can hold. So now, instead of ensuring that your collections contain no more than 1000 items, you have to monitor your heap size. Here are some strategies on how to write Apex scripts that run within these limits.</p>
<p>First of all, what is the heap? Dynamic memory allocation (also known as heap-based memory allocation) is the allocation of memory storage for use in a computer program during the runtime of that program. In Apex the heap is the reference to the amount of memory used by your reachable objects for a given script and request. When you create objects in your Apex code, memory is allocated to store these objects. </p>
<p>As with many other things in Force.com, there are <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm" target="_blank">governors and limits</a> that prevent you from hijacking the heap and degrading the performance of other running applications. The heap limit is calculated at runtime and differs on how your code is invoked:</p>
<ul>
<li>Triggers &#8211; 300,000 bytes</li>
<li>Anonymous Blocks, Visualforce Controllers, or WSDL Methods &#8211; 3,000,000 bytes</li>
<li>Tests &#8211; 1,500,000 bytes</li>
</ul>
<p>These limits also scale with trigger batch sizes:</p>
<ul>
<li>For 1-40 records, the normal limits apply</li>
<li>For 41-80 records, two times the normal limits apply</li>
<li>For 81-120 records, three times the normal limits apply</li>
<li>For 121-160 records, four times the normal limits apply</li>
<li>For 161 or more records, five times the normal limits apply</li>
</ul>
<p>Luckily Salesforce.com increased the heap size limits in <a href="http://blog.jeffdouglas.com/2010/07/07/my-favorite-salesforce-com-summer-10-features/" target="_blank">Summer &#8217;10</a> but you still may run into some issues. Here are a few things you can do to write heap-friendly code.</p>
<p><strong>Watch the Heap</strong></p>
<p>When your scripts run you can view the heap size in the debug logs. If you notice your heap approaching the limit, you will need to investigate why and try to refactor your code accordingly. </p>
<p><img src="http://blog.jeffdouglas.com/wp-content/uploads/2010/08/heap.png" alt="" width="290" height="241" /></p>
<p><strong>Use the Transient Keyword</strong></p>
<p>Try using the &#8220;Transient&#8221; keyword with variables in your controllers and extensions. The transient keyword is used to declare instance variables that cannot be saved, and shouldn&#8217;t be transmitted as part of the view state for a Visualforce page.</p>
<p><strong>Use Limit Methods</strong></p>
<p>Use heap limits methods in your Apex code to monitor/manage the heap during execution.</p>
<ul>
<li><strong>Limits.getHeapSize()</strong> &#8211; Returns the approximate amount of memory (in bytes) that has been used for the heap in the current context.</li>
<li><strong>Limits.getLimitHeapSize()</strong> &#8211; Returns the total amount of memory (in bytes) that can be used for the heap in the current context.</li>
</ul>
<p>
// check the heap size at runtime<br />
if (Limits.getHeapSize &gt; 275000) {<br />
&nbsp;&nbsp;&nbsp;&nbsp; // implement logic to reduce<br />
}</p>
<p>One strategy to reduce heap size during runtime is to remove items from the collection as you iterate over it.</p>
<p><strong>Put Your Objects on a Diet</strong></p>
<p>If the objects in your collection contain related objects (i.e., Account objects with a number of related Contacts for each) make sure the related objects only contain the fields that are actually needed by your script.</p>
<p><strong>Use SOQL For Loops</strong></p>
<p>SOQL &#8220;for&#8221; loops differ from standard SOQL statements because of the method they use to retrieve sObjects. To avoid heap size limits, developers should always use a SOQL &#8220;for&#8221; loop to process query results that return many records. SOQL &#8220;for&#8221; loops retrieve all sObjects in a query and process multiple batches of records through the use of internal calls to query and queryMore.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">for (List&lt;Contact&gt; contacts : [select id, firstname, lastname 
  from contact where billingState = 'NY']) {
&nbsp;
  // implement your code to modify records in this batch
&nbsp;
  // commit this batch of 200 records
  update contacts;
}</pre></td></tr></table></div>

<p><strong>Note:</strong> There used to be a strategy for dealing with heap intensive scripts by moving them asynchronous, @Future methods. However, since the heap limits were increased in Summer &#8217;10 this is no longer a reason to simply use @Future method as the limits are the same. </p>
<p>Any other ideas on how to effectively manage the heap?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/08/16/managing-the-heap-in-salesforce-com/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Using the Salesforce.com OAuth Playground</title>
		<link>http://blog.jeffdouglas.com/2010/07/28/using-the-salesforce-oauth-playground/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-the-salesforce-oauth-playground</link>
		<comments>http://blog.jeffdouglas.com/2010/07/28/using-the-salesforce-oauth-playground/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 12:39:25 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=2968</guid>
		<description><![CDATA[﻿My article on developer.force.com, Using OAuth to Authorize External Applications, shows how to develop external Java applications that use OAuth to access your Saleforce.com data. But what if you want to do the opposite? What if you need to write an application on the Force.com platform that uses your data from Google, Twitter, LinkedIn or [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F07%2F28%2Fusing-the-salesforce-oauth-playground%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2010%2F07%2F28%2Fusing-the-salesforce-oauth-playground%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>﻿My article on developer.force.com, <a href="http://wiki.developerforce.com/index.php/Using_OAuth_to_Authorize_External_Applications">Using OAuth to Authorize External Applications</a>, shows how to develop external Java applications that use OAuth to access your Saleforce.com data. But what if you want to do the opposite? What if you need to write an application on the Force.com platform that uses your data from Google, Twitter, LinkedIn or TripIt using OAuth? Luckily <a href="http://twitter.com/jesperfj">Jesper Jorgenson</a> at Salesforce.com posted an open source project called <a href="http://code.google.com/p/sfdc-oauth-playground/">sfdc-oauth-playground</a> which is a generic consumer implementation of OAuth as a Force.com App.</p>
<p>The main purpose of this beta project is to show you how to write OAuth signed requests in Apex. There is a managed packaged you can install into your org but if you really want to dig into the guts of OAuth (and who doesn&#8217;t??) you&#8217;ll need to download and install the source code from the project. The managed package doesn&#8217;t afford you to opportunity to modify code or view granular debug statements.</p>
<p>Jesper doesn&#8217;t provide much documentation for the project so I&#8217;ve put together a short video showing how to get started using Google Accounts and Blogger. Unfortunately different providers implement OAuth to their own liking so you sometimes have to make modifications to the requests being sent over the wire. I ran into a number of issues so hopefully this will assist you in getting up and running with OAuth.</p>
<p><span class="youtube">
<object width="560" height="340">
<param name="movie" value="http://www.youtube.com/v/sXJxG6zWSZA?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1&#038;hd=1&#038;w=600]" />
<param name="allowFullScreen" value="true" />
<embed wmode="opaque" src="http://www.youtube.com/v/sXJxG6zWSZA?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1&#038;hd=1&#038;w=600]" type="application/x-shockwave-flash" allowfullscreen="true" width="560" height="340"></embed>
<param name="wmode" value="opaque" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=sXJxG6zWSZA&fmt=18">www.youtube.com/watch?v=sXJxG6zWSZA</a></p></p>
<p> </p>
<p>﻿In case you don&#8217;t have time for the video, here are a couple of screenshots outlining the process using the OAuth Consumer Playground application from the managed package.</p>
<p><strong>﻿Create a new OAuth Service (e.g., Blogger) with various URLs for accessing services</strong></p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-unauthorized1_large.png" rel="lightbox[2968]"><img title="oauth-service-unauthorized.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-unauthorized1.png" border="0" alt="oauth-service-unauthorized.png" width="400" height="308" /></a></p>
<p> </p>
<p>﻿<strong>Authorize Salesforce access to Blogger</strong></p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-preauth1_large.png" rel="lightbox[2968]"><img title="oauth-service-preauth.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-preauth1.png" border="0" alt="oauth-service-preauth.png" width="400" height="266" /></a></p>
<p> </p>
<p><strong>﻿Grant access to Blogger</strong></p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-blogger_large.png" rel="lightbox[2968]"><img title="oauth-service-blogger.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-blogger.png" border="0" alt="oauth-service-blogger.png" width="400" height="266" /></a></p>
<p> </p>
<p><strong>﻿Authorization confirmation</strong></p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-auth_large.png" rel="lightbox[2968]"><img title="oauth-service-auth.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-auth.png" border="0" alt="oauth-service-auth.png" width="400" height="266" /></a></p>
<p> </p>
<p>﻿<strong>OAuth Service access tokens</strong></p>
<p><a href=""http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-authorized_large.png"><img title="oauth-service-authorized.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-authorized.png" border="0" alt="oauth-service-authorized.png" width="400" height="308" /></a></p>
<p> </p>
<p><strong>﻿Testing the service</strong></p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-test_large.png" rel="lightbox[2968]"><img title="oauth-service-test.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/07/oauth-service-test.png" border="0" alt="oauth-service-test.png" width="400" height="333" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/07/28/using-the-salesforce-oauth-playground/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

