<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUQGR3w8eyp7ImA9WhRUGUs.&quot;"><id>tag:blogger.com,1999:blog-25912180</id><updated>2012-01-30T17:48:46.273-06:00</updated><category term="xml" /><category term="del.icio.us" /><category term="vba" /><category term="iis" /><category term="office" /><category term="javascript" /><category term="crd" /><category term="windows service" /><category term="ACT" /><category term="sip" /><category term="web services" /><category term="regular expression" /><category term="ssis" /><category term="sql server" /><category term="visual studio" /><category term="c#" /><category term="pgp" /><category term="ipod" /><category term="asp.net" /><category term="windows" /><category term="crystal reports" /><category term="calcs" /><category term="extjs" /><category term="business objects" /><category term="google apps" /><category term="web.config" /><title type="text">Rob Lieving</title><subtitle type="html">Technology for Investment Management</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://rlieving.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://rlieving.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>58</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/RobsSpace" /><feedburner:info uri="robsspace" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEACQXY5fip7ImA9WhZRFUg.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-5813141342000862085</id><published>2011-04-11T16:18:00.001-05:00</published><updated>2011-04-11T16:19:20.826-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-11T16:19:20.826-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="iis" /><title>IIS6 to IIS7 - Catching Ajax errors</title><content type="html">&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: 'lucida grande', verdana, sans-serif; font-size: 14px; line-height: 19px;"&gt;The way Ajax errors are sent to the browser has changed between IIS6 and IIS7. Errors used to be sent automatically and you could parse the XML on the client. Now, the developer is required to do a little more work because IIS traps the error and stops code execution before reaching the end of the method.&lt;/span&gt;&lt;br /&gt;
&lt;div style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: 'lucida grande', verdana, sans-serif; font-size: 14px; line-height: 19px; margin-bottom: 14px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;For example, the Ext JS Ajax call takes an object with 5 parameters: method, url, params, success and failure. The last parameter is a callback function that is executed if the server sends back a failure.&lt;/div&gt;&lt;div style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: 'lucida grande', verdana, sans-serif; font-size: 14px; line-height: 19px; margin-bottom: 14px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;The good news is that you have to make a small change to the server-side code (only). Another piece of good news is that the code is generic - the snippet will work with most web methods.&lt;/div&gt;&lt;div style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: 'lucida grande', verdana, sans-serif; font-size: 14px; line-height: 19px; margin-bottom: 14px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;To make it work, create a try... block around the code that may throw an error. (This example is written in C#.) Next, add the following catch block:&lt;/div&gt;&lt;div style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: 'lucida grande', verdana, sans-serif; font-size: 14px; line-height: 19px; margin-bottom: 14px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;hr /&gt;catch (Exception e) {&lt;/div&gt;&lt;div style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; border-collapse: collapse; font-family: 'lucida grande', verdana, sans-serif; font-size: 14px; line-height: 19px; margin-bottom: 14px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;HttpResponse Response = HttpContext.Current.Response;&lt;br /&gt;
Response.StatusCode = 500;&lt;br /&gt;
Response.Write(e.Message);&lt;br /&gt;
HttpContext.Current.ApplicationInstance.CompleteRequest();&lt;br /&gt;
Response.End();&lt;br /&gt;
}&lt;br /&gt;
&lt;hr /&gt;The code above intercepts the error and returns it to the client. If you already had Ajax code listening for failure, you will not have to change the client side at all.&lt;br /&gt;
&lt;br /&gt;
Note: Special thanks to &lt;a href="http://west-wind.com/weblog/posts/745738.aspx"&gt;this blog post&lt;/a&gt; by Rick Strahl.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-5813141342000862085?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/jL5IskKIiLo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5813141342000862085?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5813141342000862085?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/jL5IskKIiLo/iis6-to-iis7-catching-ajax-errors.html" title="IIS6 to IIS7 - Catching Ajax errors" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2011/04/iis6-to-iis7-catching-ajax-errors.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MDSXs4fyp7ImA9WhZSE08.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-9140682513888159905</id><published>2011-03-28T11:09:00.002-05:00</published><updated>2011-03-28T11:24:38.537-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-28T11:24:38.537-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><title>Ext JS - Mixed Collection Extension</title><content type="html">At the top of my wish list for Ext JS is some recursive container search logic.  There are times when you need to access a control on a form and can get it via a search term.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;In this case, I wanted to look for the control with a tab index of one greater than the current control.&amp;nbsp;Ext.getCmp would make one control dependent on another. &amp;nbsp;This logic enables me to find the next control in the container by searching for by property for the next largest tabIndex property.&lt;br /&gt;
&lt;br /&gt;
This extension will recursively search an Ext JS (v 2.x) mixed collection for the first object that has the property you are looking for. &amp;nbsp;The new method is called 'findByProperty'.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;/* Extends the mixed collection object and recursively finds an object */&lt;br /&gt;
&lt;br /&gt;
Ext.override(Ext.util.MixedCollection, {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;findByProperty: function (property, value, defaultValue) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var obj = defaultValue,&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;notFound = true,&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;find = function (itm, idx, len) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (itm.items) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.items.each(find);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (itm[property] &amp;amp;&amp;amp; itm[property] === value) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;obj = itm;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;notFound = false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return notFound;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;};&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.each(find);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return obj;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;Where:&lt;br /&gt;
&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;property&lt;/b&gt; is the string property you are looking for&lt;/li&gt;
&lt;li&gt;&lt;b&gt;value&lt;/b&gt; is the property value&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;defaultValue&lt;/b&gt; is the optional value to be returned if nothing is found&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-9140682513888159905?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/OyQb98Rd_Js" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/9140682513888159905?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/9140682513888159905?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/OyQb98Rd_Js/ext-js-mixed-collection-extension.html" title="Ext JS - Mixed Collection Extension" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2011/03/ext-js-mixed-collection-extension.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQBQ3c9eyp7ImA9WhZTF0w.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-4190502995679933902</id><published>2011-03-21T09:39:00.000-05:00</published><updated>2011-03-21T09:39:12.963-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-21T09:39:12.963-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><title>Ext JS: relayEvents</title><content type="html">I have found that the relayEvents method in Ext JS (2.x) is one of the most useful and code-saving techniques one can use. &amp;nbsp;The purpose of the method is to allow one object to listen to the custom events of another object.&lt;br /&gt;
&lt;br /&gt;
I have found that the documentation is not that good, which can make somewhat RelayEvents hard to use. &amp;nbsp;Here is my shorthand to make is easy:&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;b&gt;listener&lt;/b&gt;.relayEvents(&lt;b&gt;broadcaster&lt;/b&gt;, ['custom event a', 'custom event b']);&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;listener&lt;/b&gt;: The object listening for events. &amp;nbsp;Register the array events in the listeners collection of the object&lt;/li&gt;
&lt;li&gt;&lt;b&gt;broadcaster:&lt;/b&gt; The object firing the events. &amp;nbsp;To fire the event use the fireEvent('custom event a') method within the broadcaster to fire the event&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-4190502995679933902?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/BFBflToNHVI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/4190502995679933902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/4190502995679933902?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/BFBflToNHVI/ext-js-relayevents.html" title="Ext JS: relayEvents" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2011/03/ext-js-relayevents.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4ER3g_cSp7ImA9Wx9aF0o.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-5121229109869360518</id><published>2011-03-10T11:15:00.001-06:00</published><updated>2011-03-10T11:41:46.649-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-10T11:41:46.649-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><title>Override setValue in Ext JS</title><content type="html">I am working with Ext JS 2.x and have the need to format numeric values, such as percentages and comma delimited values.&lt;br /&gt;
&lt;br /&gt;
The best way I know to format the numbers is to override the setValue function of the field.  My original plan was to put the formatting in the 'change' event, but calling the setValue in the code does not call this event.&lt;br /&gt;
&lt;br /&gt;
The way to override setValue method is easy, but not obvious.  The directions are as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;[Namespace].form.[FieldName] = Ext.extend(Ext.form.Field {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;constructor: function (config) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// constructor logic here&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;[Namespace].form.[FieldName].superclass.constructor.apply(this, arguments);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;},&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;setValue: function (val) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// format logic here for val argument&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return [Namespace].form.[FieldName].superclass.SetValue.call(this, val);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;hr /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-5121229109869360518?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/8hFzp78POuA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5121229109869360518?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5121229109869360518?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/8hFzp78POuA/override-setvalue-in-ext-js.html" title="Override setValue in Ext JS" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2011/03/override-setvalue-in-ext-js.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUABRHk7eSp7ImA9Wx9bGU8.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-5645848998948293090</id><published>2011-02-28T14:09:00.000-06:00</published><updated>2011-02-28T14:09:15.701-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-28T14:09:15.701-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iis" /><title>Fixing IIS Error 401.2 - Unauthorized Access</title><content type="html">I have developed several applications in Ext JS and recently noticed that all my server calls for a grid made two calls to the server.  The first call was a fail, but the second call succeeded. This happens so quickly that the user is not even aware of the issue, but I wanted to track it down anyway.&lt;br /&gt;
&lt;br /&gt;
I examined the HTTP traffic using Fiddler, and found this error in the header of the failed call:&lt;br /&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;blockquote&gt;&lt;strong&gt;You are not authorized to view this page&lt;/strong&gt;&lt;br /&gt;
You do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to accept.&lt;br /&gt;
---&lt;br /&gt;
&lt;p&gt;Please try the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Contact the Web site administrator if you believe you should be able to view this directory or page.&lt;/li&gt;
&lt;li&gt;Click the &lt;a href="javascript:location.reload()"&gt;Refresh&lt;/a&gt; button to try again with different credentials.&lt;/li&gt;
&lt;/ul&gt;&lt;strong&gt;HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration.&lt;br&gt;Internet Information Services (IIS)&lt;/strong&gt;&lt;br /&gt;
---&lt;br /&gt;
&lt;p&gt;Technical Information (for support personnel)&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Go to &lt;a href="http://go.microsoft.com/fwlink/?linkid=8180"&gt;Microsoft Product Support Services&lt;/a&gt; and perform a title search for the words &lt;b&gt;HTTP&lt;/b&gt; and &lt;b&gt;401&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;Open &lt;b&gt;IIS Help&lt;/b&gt;, which is accessible in IIS Manager (inetmgr),&lt;br /&gt;
 and search for topics titled &lt;b&gt;About Security&lt;/b&gt;, &lt;b&gt;Authentication&lt;/b&gt;, and &lt;b&gt;About Custom Error Messages&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;br /&gt;
This problem was happening in IIS6 on Win2K3, but I actually observed it happening on II7 on Win2K8 R2.  I found a clue on &lt;a href="http://social.technet.microsoft.com/Forums/en-US/winserversecurity/thread/c9239a89-fbee-4adc-b72f-7a6a9648331f/#d092afcc-1893-4fc6-b79d-1348717415fb"&gt;this website&lt;/a&gt;, which recommended changing the order of IIS's method for authentication.  Unfortunately for me, this post talked about a UI fix that does not appear to be valid for my version of IIS.&lt;br /&gt;
&lt;br /&gt;
Changing the order of authentication is the answer however, although it needs to be done directly in the ApplicationHost.config file.  The fix for this issue is as follows:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Find the ApplicationHost.config file in C:\Windows\System32\inetserv\config.&lt;/li&gt;
&lt;li&gt;Copy file to new folder.&lt;/li&gt;
&lt;li&gt;Open config file in Notepad.  Search for NTLM.  You will find it in the windowsAuthentication/providers section of the file.  The value "Negotiate" will be listed ABOVE NTLM&lt;/li&gt;
&lt;li&gt;Copy the entire XML line so that NTLM is the first on the list of providers.&lt;/li&gt;
&lt;li&gt;Restart the World Wide Web Publishing service.  Once that is done, the issue goes away.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-5645848998948293090?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/Dmi56HL8VCQ" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5645848998948293090?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5645848998948293090?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/Dmi56HL8VCQ/fixing-iis-error-4012-unauthorized.html" title="Fixing IIS Error 401.2 - Unauthorized Access" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2011/02/fixing-iis-error-4012-unauthorized.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4BSXwyfSp7ImA9Wx5UFUU.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-7038395299147638802</id><published>2010-10-20T08:54:00.002-05:00</published><updated>2010-10-20T08:55:58.295-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-20T08:55:58.295-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="crystal reports" /><title>Simulate Report Alerts in Crystal Reports 2008 Server</title><content type="html">Working with Crystal Reports can be tricky. &amp;nbsp;Anyone who publishes the reports on a BOE Server or Crystal Reports 2008 server has to relearn some of the aspects of the reports to create similar functionality to the desktop application.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Recently I was asked to implement an alerting scheme in a crystal report that was published to the server. &amp;nbsp;Since online reports do not support alerts the same way desktop reports do, this is a tricky problem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The way we decided to do it was to put the alert in the report header. &amp;nbsp;We then tested for the condition that would trigger an alert. &amp;nbsp;If the condition was triggered, we made the report header visible. &amp;nbsp;Otherwise, we hid the report header.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;This is accomplished with three formulas:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;The first formula declares the test variable and initializes the value to false.&lt;/li&gt;
&lt;li&gt;The second formula is placed in the details section of the report. &amp;nbsp;This formula tests for the condition and, if triggered, sets the test variable to true. &amp;nbsp;This formula uses the Crystal &lt;b&gt;WhileReadingRecords&lt;/b&gt; function.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The final formula evaluates the test variable. &amp;nbsp;If true, the header is made visible (with a warning message), otherwise it is hidden. &amp;nbsp;This function uses the Crystal &lt;b&gt;EvaluateAfter&lt;/b&gt; function.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Here's exactly how it works.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Create a new formula called &lt;b&gt;Declare Globals&lt;/b&gt;. &amp;nbsp;The code in this formula is as follows. &amp;nbsp;Place this formula in the header and make it invisible. &amp;nbsp;T is the test variable, and the test is&amp;nbsp;initialized&amp;nbsp;to false.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;@Declare Globals code - placed in header&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;hr /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;global booleanvar&lt;/span&gt; t; &amp;nbsp;// t is for test&lt;/div&gt;&lt;div&gt;t:= &lt;span class="Apple-style-span" style="color: blue;"&gt;false&lt;/span&gt;;&lt;/div&gt;&lt;hr /&gt;&lt;br /&gt;
&lt;br /&gt;
Next, create another formula called &lt;b&gt;Test Records&lt;/b&gt;. &amp;nbsp;In this example, the test is done in SQL, but it could be done in the report. &amp;nbsp;The only result of the test is to set the test variable to true if the test is triggered. &amp;nbsp;This code should be placed in the details section of the report and again made invisible.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;@Test Records code - placed in details&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;hr /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;global booleanvar&lt;/span&gt; t; // reference the variable declared in the header&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;whilereadingrecords&lt;/span&gt;;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;if&amp;nbsp;&lt;/span&gt;({tblData.bad_data} = -1) &lt;span class="Apple-style-span" style="color: blue;"&gt;then&lt;/span&gt; t := &lt;span class="Apple-style-span" style="color: blue;"&gt;true&lt;/span&gt;;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Finally, go into Section Expert on the report and choose Report Header &amp;gt; Common tab &amp;gt; Suppress (No Drill Down). &amp;nbsp;Un-check Suppress and click the formula editor button next to Suppress. &amp;nbsp;Evaluate t and show/hide the report header based on the value of the test variable. &amp;nbsp;The report header should have the warning in it in big red letters to alert the user.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;b&gt;Code placed in the Report Header&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;hr /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;global booleanvar&lt;/span&gt;&amp;nbsp;t; // reference the variable declared in the header&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;evaluateafter&lt;/span&gt;({@Test Records});&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;not&amp;nbsp;&lt;/span&gt;t;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;hr /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-7038395299147638802?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/RenNyIfeEG0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/7038395299147638802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/7038395299147638802?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/RenNyIfeEG0/simulate-report-alerts-in-crystal.html" title="Simulate Report Alerts in Crystal Reports 2008 Server" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/10/simulate-report-alerts-in-crystal.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AHQXk4eCp7ImA9Wx5VE0o.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-5378620123397985292</id><published>2010-10-06T09:35:00.000-05:00</published><updated>2010-10-06T09:35:30.730-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-06T09:35:30.730-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql server" /><title>SQL Server Error 15023: 'User already exists in current database'</title><content type="html">I received this error when copying a database from one server to another and then tried to bring up a web application. &amp;nbsp;The system user that came over with the database was orphaned from the existing login.&lt;br /&gt;
&lt;br /&gt;
The solution is relatively easy (for one login). &amp;nbsp;Use the &lt;b&gt;sp_change_users_login&lt;/b&gt; with the &lt;b&gt;'update_one'&lt;/b&gt; option. &amp;nbsp;This will directly map the user to the SQL login.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;exec sp_change_users_login 'update_one', '[your database user]', '[the SQL login]'&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
Thanks to &lt;a href="http://blog.sqlauthority.com/2007/02/15/sql-server-fix-error-15023-user-already-exists-in-current-database/"&gt;Pinal Dave's&lt;/a&gt; article on this subject.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-5378620123397985292?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/_HYNbClGZO8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5378620123397985292?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5378620123397985292?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/_HYNbClGZO8/sql-server-error-15023-user-already.html" title="SQL Server Error 15023: 'User already exists in current database'" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/10/sql-server-error-15023-user-already.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QFQHw4cSp7ImA9Wx5RGUk.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-6690887704434559682</id><published>2010-08-27T15:35:00.000-05:00</published><updated>2010-08-27T15:35:11.239-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-27T15:35:11.239-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="web services" /><title>Solving the ASP.Net Double Hop problem</title><content type="html">This article is in debt to Andrew Hay's &lt;a href="http://www.andrewdothay.net/blog/2007/11/10/DoubleHopDisaster.aspx" target="_blank"&gt;excellent writeup&lt;/a&gt; on how he solved his double-hop problem.&lt;br /&gt;
&lt;br /&gt;
The double-hop problem occurs when a central application calls a web-service on a second server, but the credentials are not passed to the second server, causing the web-service call to fail. &amp;nbsp;This is because IIS does not pass on the credentials to the second machine. &lt;br /&gt;
&lt;br /&gt;
When this happens you will see the error:&lt;br /&gt;
&lt;blockquote&gt;&lt;hr /&gt;&lt;b&gt;System.Net.WebException: The request failed with HTTP status 401: Unauthorized at...&lt;/b&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;/blockquote&gt;The worst part of this error is that the web service will work from your machine, but not when you move it to the server for testing.&lt;br /&gt;
&lt;br /&gt;
The double-hop will most likely happen if you use the CredentialCache.DefaultNetworkCredentials or CredentialCache.DefaultCredentials to authenticate the service call.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Problem Solved: System.Net.NetworkCredential&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The fix is relatively simple:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Create a new System.Net.NetworkCredential that uses a service account. &amp;nbsp;Use this to authenticate the service call.&lt;/li&gt;
&lt;li&gt;Add the service account to the users group on the target server where the web service is located.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
The pseudo code looks like this:&lt;br /&gt;
&lt;hr /&gt;&lt;blockquote&gt;Dataset ds = new DataSet("Grid");&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;using(MyService ws = new MyService) {&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; char[] delim = ";".ToCharArray();&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; string[] creds = ConfiigurationManager.AppSettings["ServiceAcct"].Split(delim);&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; ws.Credentials = new System.Net.NetworkCredential(creds[0], creds[1], creds[2]);&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; ds = ws.getDataSet(arg1, arg2);&lt;/blockquote&gt;&lt;blockquote&gt;}&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;return ds;&amp;nbsp;&lt;/blockquote&gt;&lt;hr /&gt;&lt;br /&gt;
The Web.Config would have an application setting of "ServiceAccount" with the value "User;Password;Domain".&lt;br /&gt;
&lt;br /&gt;
Follow up with adding the service account to the Users Group on the machine that hosts the web service. &amp;nbsp;This should solve the&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-6690887704434559682?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/NGUj3oz1oFU" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/6690887704434559682?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/6690887704434559682?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/NGUj3oz1oFU/solving-aspnet-double-hop-problem.html" title="Solving the ASP.Net Double Hop problem" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/08/solving-aspnet-double-hop-problem.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEABQ308eSp7ImA9WxBbGUw.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-3907608354711987158</id><published>2010-03-17T21:13:00.013-05:00</published><updated>2010-03-18T07:52:32.371-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-18T07:52:32.371-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><title>ASP.Net Data meets Ext JS: Ext.net – Store and GroupingStore</title><content type="html">&lt;hr /&gt;&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Download the source code for Ext.net &lt;a href="http://extjsdata.codeplex.com/releases/view/40941"&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;p&gt;&lt;h3&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;/h3&gt;&lt;/p&gt;Ext JS is my front-end platform of choice for all my ASP.Net applications.&amp;nbsp; The reasons are simple – Ext JS gives the developer more control, supports better coding practices, and takes better advantage of the IIS platform than native ASP development options.&amp;nbsp; But how could that be?&lt;br /&gt;
&lt;br /&gt;
First, there is the question of control.&amp;nbsp; ASP controls are not open source.&amp;nbsp; It’s hard for the developer to understand what is going on under the covers without extensive study.&amp;nbsp; When will the page refresh?&amp;nbsp; When will the control talk to the server?&amp;nbsp; How can I give the control a different look?&amp;nbsp; Why is that Microsoft object emitting CSS?&amp;nbsp; Many of these questions are difficult for most people to understand and take valuable time to understand.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Ext JS controls are open source and have a rich, well documented event model.&amp;nbsp; You can read the code directly if you need to.&amp;nbsp; Ext JS controls don’t make unexpected calls to the server or emit unexpected code&amp;nbsp; The developer controls how data is piped from the sever to the screen, which makes it easier to control events and identify performance bottlenecks.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Simply put, the developer has complete control over everything that call that happens on the client.&amp;nbsp; There are not many mysteries. And aspects that annoy you can be fixed at programming time by looking at the source code.&lt;br /&gt;
&lt;br /&gt;
Secondly, I have always been bothered by the mixed metaphor of ASP.Net development.&amp;nbsp; What’s on the browser?&amp;nbsp; What’s on the server?&amp;nbsp; Do I code this control with HTML or C#?&amp;nbsp; For all the remarkable work Microsoft did to make the process seem like coding a Visual Basic application (it is truly amazing), the actual results can be bizarre and fragmented.&amp;nbsp; .Net languages appear on the page with HTML, which then might have additional code capturing events somewhere else.&amp;nbsp; The page object model is complex, and ASP developers have to learn when and how to place each control on the page to &lt;br /&gt;
&lt;br /&gt;
Ext JS controls are coded entirely in JavaScript and the separation between browser and server is clearly defined.&amp;nbsp; There is no half-HTML/half C# (or VB.Net) control that lives partially in code-behind and partially on the page.&amp;nbsp; There is no reason to carefully wedge control-code between page events to get everything working correctly.&lt;br /&gt;
&lt;br /&gt;
This complete separation tends to drive business logic off the page and back onto the server where it belongs.&amp;nbsp; My personal preference is to keep the server code and UI code as separate as possible.&amp;nbsp; Ext JS enables the developer to keep the server-side code simple and clean.&amp;nbsp; Simply write your UI in JavaScript and expose the web services for the page.&amp;nbsp; This approach also simplifies testing because the developer can easily identify and test the logic used in each page.&lt;br /&gt;
&lt;br /&gt;
Finally, Ext JS makes it possible to leverage the absolute strength of IIS, which is delivering web services.&amp;nbsp; It has always struck me as strange that ASP.Net controls do not explicitly consume services.&amp;nbsp; In an effort to make the communication seamless, Microsoft actually minimizes the strengths of exposing SOAP services.&amp;nbsp; This, in turn, leads to code-bloat, because the developer has to write custom code to deliver data to ASP.Net controls and then additional code to deliver data to other applications.&lt;br /&gt;
&lt;br /&gt;
Despite all these advantages, communication between Ext JS and ASP web services can be tedious.&amp;nbsp; Ext JS was written by people who are clearly oriented towards JSON data delivery.&amp;nbsp; And why not?&amp;nbsp; It’s lightweight and native to JavaScript.&amp;nbsp; There is the XML reader, but the average .Net/Ext JS developer still has to write tedious (and needless) code to parse the data into stores.&lt;br /&gt;
&lt;br /&gt;
But IIS (.Net) is an XML-oriented language.&amp;nbsp; It does not serve JSON without specialized server-side code and some hacking.&amp;nbsp; What if you work in a corporate environment that does not allow non-standard software to be installed on the server?&amp;nbsp; Shouldn’t the goal of the programmer be to stick to the standards and also leverage what each piece of software does best?&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;&lt;h3&gt;Ext.net.Store and Ext.net.GroupingStore&lt;/h3&gt;&lt;/p&gt;Ext JS.net started with simple questions.&amp;nbsp; Why should I write JavaScript code to describe my data structures, when an ASP.Net web services already delivers that data to my page?&amp;nbsp; Would my code be less coupled if I worried more about the UI and less about the structure of the data coming to my page?&amp;nbsp; &lt;br /&gt;
The result is &lt;strong&gt;Ext.net.Store&lt;/strong&gt; and &lt;strong&gt;Ext.net.GroupingStore&lt;/strong&gt;.&amp;nbsp; The goals of this project are as follows:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Reduce boilerplate code – on the server and the page &lt;/li&gt;
&lt;li&gt;Increase web service reuse/simplify server-side code &lt;/li&gt;
&lt;li&gt;Simplify data transport and consumption &lt;/li&gt;
&lt;/ul&gt;Table names and data types have already been written and defined on the server – why write them again?&lt;br /&gt;
&lt;h4&gt;How does Ext.net work?&amp;nbsp; &lt;/h4&gt;The Ext.Net stores intercept the XML returned from a web-service call and build the data set before the store is completely initialized.&amp;nbsp; This means that the data definition that is defined on the server and delivered in the web service automatically becomes the data definition in the store.&amp;nbsp; &lt;br /&gt;
In order to take advantage of the store, the programmer simply exposes an ADO DataSet as the return data type.&amp;nbsp; Ext.Net stores consumes the meta-data, builds a table definition and then populates it with the service data.&lt;br /&gt;
&lt;br /&gt;
On the server, create a standard data set.&amp;nbsp; The names of the tables do not matter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;IIS Server Side Code - C#&lt;/strong&gt; &lt;br /&gt;
&lt;hr /&gt;[WebMethod] &lt;br /&gt;
&amp;nbsp; public DataSet TableData() &lt;br /&gt;
&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DataSet ds = new DataSet("ds");&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string cnStr = ConfigurationManager.ConnectionStrings["local"].ToString(); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (SqlConnection cn = new SqlConnection(cnStr)) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string strSQL = "SELECT * FROM tblDataVals"; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (SqlDataAdapter da = new SqlDataAdapter(strSQL, cn)) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; da.Fill(ds, "data"); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strSQL = "SELECT COUNT(*) FROM tblDataVals"; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (SqlDataAdapter da = new SqlDataAdapter(strSQL, cn)) &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; da.Fill(ds, "count"); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cn.Close(); &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ds; &lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
The client-side JavaScript is just as simple.&amp;nbsp; In your HTML add a reference to Ext.net.Store.&amp;nbsp; Make sure the reference appears after the references to ExtJs code.&lt;br /&gt;
&lt;br /&gt;
Declare a store by using Ext.net.Store or Ext.net.GroupingStore wherever you would declare a store.&amp;nbsp; All of the config parameters are the same, with very few differences.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Ext.net.Store and Ext.net.GroupingStore will create a reader automatically, so you do not have to declare an XMLReader or any record definitions.&amp;nbsp; On large grids, this will save considerable code.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
There is one extra parameter to add to the grid – &lt;strong&gt;net&lt;/strong&gt;. The &lt;strong&gt;net&lt;/strong&gt; object has 3 fields:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;dataTable (string):&lt;/strong&gt; The name of the table that contains the data.&amp;nbsp; This will be translated into the store data. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;dataTableId (string):&lt;/strong&gt; The name of the field that contains the id of the data table. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;totalRecords (string):&lt;/strong&gt; The name of the table that contains the data count.&amp;nbsp; This parameter is optional. &lt;/li&gt;
&lt;/ul&gt;Below is a sample store declaration.&amp;nbsp; Note that there is no record definition because it is created at run time.&amp;nbsp; &lt;br /&gt;
A big benefit to this is that the service can change and the grid will keep on working as it did before.&amp;nbsp; For large grids, you also save re-coding record definitions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Sample Ext.net.Store declaration in JavaScript&lt;/strong&gt; &lt;br /&gt;
&lt;hr /&gt;var s = new Ext.net.Store({&lt;br /&gt;
&lt;blockquote&gt;&lt;strong&gt;net:&lt;/strong&gt; {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataTable: 'data',&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataTableId: 'id',&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; totalRecords: 'count'&lt;br /&gt;
},&lt;br /&gt;
&amp;nbsp;&lt;strong&gt; remoteSort:&lt;/strong&gt; true,&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;sortInfo:&lt;/strong&gt; { sort: 'fname', dir: 'ASC' },&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;proxy:&lt;/strong&gt; new Ext.data.HttpProxy({&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; url: 'EmployeeServices.asmx/GetEmployees',&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method: 'GET'&lt;br /&gt;
&amp;nbsp; }),&lt;br /&gt;
&amp;nbsp; &lt;strong&gt;storeId:&lt;/strong&gt; 'empStore'&lt;/blockquote&gt;});&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;br /&gt;
The source code for Ext.net.Store and Ext.net.GroupingStore can be downloaded for free from &lt;a bitly="BITLY_PROCESSED" href="http://extjsdata.codeplex.com/"&gt;http://extjsdata.codeplex.com/&lt;/a&gt;.&amp;nbsp; The code has been tested with Firefox 3.5+ and IE7+.&amp;nbsp; It was designed to be compatible with ExtJs Framework 2.2, but also works with 3.1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-3907608354711987158?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/CdG5ncsBsrw" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3907608354711987158?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3907608354711987158?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/CdG5ncsBsrw/aspnet-data-meets-ext-js-extnet-store.html" title="ASP.Net Data meets Ext JS: Ext.net – Store and GroupingStore" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/03/aspnet-data-meets-ext-js-extnet-store.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AHQ3Y4eip7ImA9WxBbF0s.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-803235213621729538</id><published>2010-03-16T13:55:00.001-05:00</published><updated>2010-03-16T13:55:32.832-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-16T13:55:32.832-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><title>Bookmarklet: Add URL to Remember the Milk from the iPhone</title><content type="html">I use Google Reader on all my mobile devices (currently an iPhone) and frequently find myself wanting to switch to the desktop to finish a story. &amp;nbsp;Google Reader has great desktop integration with other services to save articles, but is very limited on the iPhone. &amp;nbsp;Google Reader mobile allows you to email a link to yourself, but the whole process is painful and I get enough email.&lt;br /&gt;
&lt;br /&gt;
I am also a heavy user of Remember the Milk as my task management system. &amp;nbsp;Wouldn't it be great to be able to add URL's directly from the iPhone? &amp;nbsp;Enter the RMilk iPhone Bookmarklet.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;javascript:(function(){&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;var a = [&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  '&lt;/span&gt;name=' + document.title,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;'url=' + location.href,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;'due=today',&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;'priority=4',&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;'tags=iPhone'&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;];&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;location.href = "http://m.rememberthemilk.com/add?" + a.join("&amp;amp;");&lt;br /&gt;
})();&lt;br /&gt;
&lt;hr /&gt;The Bookmaklet above adds the URL into the mobile Remember the Milk site. &amp;nbsp;The following values are populated:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;name:&lt;/b&gt; The name of the page you are viewing will be the task name.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;url:&lt;/b&gt;&amp;nbsp;The URL is the page you are viewing.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;due:&lt;/b&gt; The due date can be any legal value that Remember the Milk can validate as a date.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;priority:&lt;/b&gt;&amp;nbsp;Legal priority values are 1, 2, 3, and 4 (none).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;tags:&lt;/b&gt;&amp;nbsp;Any tag (or tags) you would like to use to populate your task.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Additionally, there are two other options worth noting:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;estimate:&lt;/b&gt;&amp;nbsp;Any valid time estimate can be used&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;list:&lt;/b&gt; The integer list id that applies to your list. &amp;nbsp;If you want the URL to go to a specific list, go to&amp;nbsp;&lt;a href="http://m.rememberthemilk.com/add"&gt;http://m.rememberthemilk.com/add&lt;/a&gt;. &amp;nbsp;View the page source and find the list of values that contains your list. &amp;nbsp;Use the value attribute from the option tag as your list value.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;To add this bookmarklet to your iPhone, do the following:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Copy the JavaScript Bookmarklet above into Notepad.&lt;/li&gt;
&lt;li&gt;Edit the values in the array as to how you would like to populate Remember The Milk. &amp;nbsp;Add estimate and list to the array if you would like those values populated.&lt;/li&gt;
&lt;li&gt;Copy the new JavaScript into an email and email it to your iPhone. &amp;nbsp;Copy the JavaScript from the email.&lt;/li&gt;
&lt;li&gt;Bookmark any page in Safari. &amp;nbsp;Edit the bookmark by giving it a new name and pasting the JavaScript into the URL textbox.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;This post is heavily indebted to &lt;a href="http://www.articlesbase.com/blogging-articles/google-reader-how-to-send-to-remember-the-milk-1141903.html"&gt;Steve Ollis, The IT Juggler&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-803235213621729538?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/IfHGINJ07Ac" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/803235213621729538?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/803235213621729538?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/IfHGINJ07Ac/bookmarklet-add-url-to-remember-milk.html" title="Bookmarklet: Add URL to Remember the Milk from the iPhone" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/03/bookmarklet-add-url-to-remember-milk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMDSHg6fyp7ImA9WxBUFEo.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-5540346109827780928</id><published>2010-02-19T11:02:00.003-06:00</published><updated>2010-03-01T15:04:39.617-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-01T15:04:39.617-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="del.icio.us" /><category scheme="http://www.blogger.com/atom/ns#" term="google apps" /><title>Google Chrome Is Now My Default Browser</title><content type="html">Google Chrome has been updated for the Mac, which means I can use it on all platforms now (Mac / Linux / Windows).  It has become my default browser and is now the Swiss Army Knife of my computer.&lt;br /&gt;
&lt;br /&gt;
Following is my list of 'must have' extensions for Chrome:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="https://chrome.google.com/extensions/detail/gclkcflnjahgejhappicbhcpllkpakej?hl=en-us"&gt;Delicious Tools&lt;/a&gt; - Bookmarking for myself, my blog and my friends&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/extensions/detail/gffjhibehnempbkeheiccaincokdjbfe?hl=en-us"&gt;Google Mail Checker Plus&lt;/a&gt; - Alerts me when I get emails from either of my 2 Google Apps accounts&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/extensions/detail/hdokiejnpimakedhajhdlcegeplioahd?hl=en-us"&gt;LastPass&lt;/a&gt; - Secure password management on all devices&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/extensions/detail/kcnhkahnjcbndmmehfkdnkjomaanaooo?hl=en-us"&gt;Google Voice (by Google)&lt;/a&gt; - SMS and voice mail alerts. &amp;nbsp;Plus it converts all phone numbers to dialable links&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/extensions/detail/glcdefibajbglmeelclffdbakgjjjopc"&gt;A Bit Better Remember The Milk&lt;/a&gt; - Rearranges the page to a more logical (for me) layout&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrome.google.com/extensions/detail/nlbjncdgjeocebhnmkbbbdekmmmcbfjd"&gt;RSS Subscription Extension (By Google)&lt;/a&gt; - Enables RSS discovery in Chrome. &amp;nbsp;Why isn't this included right out of the box?&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;One side effect of Google awesomeness is that Fluid (on my Mac) just became much less important. &amp;nbsp;If you haven't tried Google Chrome, or you haven't seen the extensions, I recommend taking a look.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-5540346109827780928?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/UG7YvAAcszo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5540346109827780928?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/5540346109827780928?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/UG7YvAAcszo/google-chrome-is-now-my-default-browser.html" title="Google Chrome Is Now My Default Browser" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/02/google-chrome-is-now-my-default-browser.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUBQH84fyp7ImA9WxBVEEw.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-390899511646866583</id><published>2010-02-12T16:22:00.016-06:00</published><updated>2010-02-12T17:10:51.137-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-12T17:10:51.137-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="ACT" /><title>C#: Add history to an ACT! Group (and contacts)</title><content type="html">My current project requires interaction with ACT!, both retrieving and setting data.&amp;nbsp; &lt;br /&gt;
Working with the ACT! framework is an interesting experience.&amp;nbsp; The code is very verbose and requires some expertise to understand.&amp;nbsp; And it took me a while to realize that the best way to retrieve data is through the database, while using the framework to perform the updates.&lt;br /&gt;
The following method writes an email history to the database.&amp;nbsp; It is useful for when you need to record automated processes to groups in the database.&amp;nbsp; &lt;br /&gt;
The method takes a GUID as an argument, primarily because there are no unique naming constraints in the group list.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Act.Framework;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Act.Framework.Contacts;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Act.Framework.Groups;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Act.Framework.Histories;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Act.Framework.Lookups;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Act.Shared.Collections;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;// simplified connection for multiple methods&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt;ActFramework actFramework() {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;    string&lt;/span&gt; cn = ConfigurationManager.ConnectionStrings[&lt;span class="str"&gt;"actDb"&lt;/span&gt;].ConnectionString;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;    string&lt;/span&gt; login = ConfigurationManager.AppSettings[&lt;span class="str"&gt;"actLogin"&lt;/span&gt;].ToString();&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;    string&lt;/span&gt; pwd = ConfigurationManager.AppSettings[&lt;span class="str"&gt;"actPwd"&lt;/span&gt;].ToString();&lt;/pre&gt;&lt;pre class="alt"&gt;ActFramework f = &lt;span class="kwrd"&gt;new&lt;/span&gt;ActFramework();&lt;/pre&gt;&lt;pre&gt;f.LogOn(cn, login, pwd);&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;    return&lt;/span&gt; f;&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;// adds email history to the database&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AddEmailGroupHistory(&lt;span class="kwrd"&gt;string&lt;/span&gt; GUID, &lt;span class="kwrd"&gt;string&lt;/span&gt; subject, &lt;span class="kwrd"&gt;string&lt;/span&gt; body) {&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;    // create a disposable connection to the database&lt;/span&gt;&lt;/pre&gt;&lt;span class="rem"&gt;    &lt;/span&gt;&lt;br /&gt;
&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;    using&lt;/span&gt;(ActFramework f = actFramework()) {&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // create a new group GUID array with one element&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;Guid[] gGuid = &lt;span class="kwrd"&gt;new&lt;/span&gt; Guid[] { &lt;span class="kwrd"&gt;new&lt;/span&gt; Guid(GUID) };&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // get a group list - the list will contain one group&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;GroupList gList = f.Groups.GetGroupsByID(&lt;span class="kwrd"&gt;null&lt;/span&gt;, gGuid);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // get a contact list from the first group in the list&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;ContactList cList = gList[0].GetContacts(&lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // creates an all-zero GUID&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;Guid activityClearedId = Guid.Empty;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // creates a system type of Email sent&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;HistoryType hType = &lt;span class="kwrd"&gt;new&lt;/span&gt; HistoryType(SystemHistoryType.EmailSent);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // the history is public&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;    bool&lt;/span&gt; isPrivate = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // start and emd (duration) are equal&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;DateTime startEnd = DateTime.Now;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;    // Create a new history object&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;History h = f.Histories.CreateHistory(cList, gList, activityClearedId,&lt;/pre&gt;&lt;pre class="alt"&gt;hType, isPrivate, startEnd, startEnd, subject, body);&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;    // commit the history to the database&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;h.Update();&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-390899511646866583?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/pK8zmI5Vp2w" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/390899511646866583?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/390899511646866583?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/pK8zmI5Vp2w/c-add-history-to-act-group-and-contacts.html" title="C#: Add history to an ACT! Group (and contacts)" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/02/c-add-history-to-act-group-and-contacts.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UAQH04fyp7ImA9WxBWEU8.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-4201900738394716856</id><published>2010-02-02T09:40:00.001-06:00</published><updated>2010-02-02T09:40:41.337-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-02T09:40:41.337-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><title>ExtJS Helper Functions - SelectionModel Modifications</title><content type="html">One of the application patterns I implement in ExtJS is to have ViewPort containing a grid with records for a user to edit. &amp;nbsp;The user double-clicks a record on the grid, which opens a window to edit the information. &amp;nbsp;When complete, the user then closes the window and the grid refreshes.&lt;br /&gt;
&lt;br /&gt;
The issue is that after the grid refreshes, the user loses her place on the grid as the selection goes back to the first record.&lt;br /&gt;
&lt;br /&gt;
Additionally, the RowSelectionModel() only implements selection by index, which means that if there are concurrency checks, you cannot automatically go back to the index you were on or guarantee the new index will be correct.&lt;br /&gt;
&lt;br /&gt;
These methods attempt to correct these shortcomings. &amp;nbsp;The first extension implements a selectById method for the RowSelectionModel object. &lt;br /&gt;
&lt;br /&gt;
The second extension implements a SelectAfterLoad method on the GridPanel (and all of it's descending objects). &amp;nbsp;When closing the form, take the id from the record you are using and pass it into the selectAfterLoad method. &amp;nbsp;The method will kick off a single event to find the id in the current loaded record set. &amp;nbsp;If the id of the record is not found, the default 'selectFirstRow()' method is called.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;// extend the RowSelectionModel&lt;br /&gt;
&lt;b&gt;Ext.override(Ext.grid.RowSelectionModel, {&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
// enables the selection model to select by record id&lt;br /&gt;
&lt;b&gt;selectById: function (id) {&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;var sm = this,&lt;/b&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // hook to the selection model&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;s = sm.grid.store,&lt;/b&gt; &amp;nbsp; // reference to the store&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;f = false,&lt;/b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // found (initialized as false)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;idx = 0;&lt;/b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // record index&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// if store has no records, return control&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (s.getCount() === 0) { &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return; &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; // iterate through each record, looking for the id&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; s.each(function (r) {&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// if the record id matches the passed id&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (r.id.toString() === id.toString()) {&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // found is true&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;f = true;&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // select the row&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;sm.selectRow(idx, false);&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // return false to exit&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;return !f;&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;}&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// iterate the index&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;idx = idx + 1;&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // return true to continue iteration&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return !f;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;});&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // if not false, exit&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;&amp;nbsp;if (!f) {&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// select the first row&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;sm.selectFirstRow();&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;}&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;b&gt;}&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;});&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
// selects by record id after the grid reloads&lt;br /&gt;
&lt;b&gt;Ext.override(Ext.grid.GridPanel, {    &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; // selects row by id after store loads&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;b&gt;selectAfterLoad: function (id) {&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; // get the grid selection model    &lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;b&gt;var sm = this.getSelectionModel();&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; // select record by passed id argument after store loads&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;b&gt;this.store.on({&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;b&gt;'load': {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fn: function (t, recs, opts) {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sm.selectById(id);&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;},&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;single: true&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;});&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-4201900738394716856?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/Xl3tnSzzKEY" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/4201900738394716856?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/4201900738394716856?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/Xl3tnSzzKEY/extjs-helper-functions-selectionmodel.html" title="ExtJS Helper Functions - SelectionModel Modifications" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/02/extjs-helper-functions-selectionmodel.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcNQXs7eSp7ImA9WxBXEEU.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-584854538595344342</id><published>2010-01-20T18:35:00.008-06:00</published><updated>2010-01-21T08:11:30.501-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-21T08:11:30.501-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extjs" /><title>ExtJS Helper Functions - GetValue / SetValue</title><content type="html">This is my first (of several planned) functions to increase the functionality of the ExtJs functionality.&lt;br /&gt;
&lt;br /&gt;
These methods extend the container object and make it easier to set and retrieve values from the controls within the container.&amp;nbsp; A great benefit is that the search will go into all the nested containers as well.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;// Shortcut for adding methods to the prototype&lt;br /&gt;
&lt;b&gt;Function.prototype.method = function (name, func) {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;this.prototype[name] = func;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;return this;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;};&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
// Works on all containers (windows, formformpanels, etc.) and will &lt;br /&gt;
// even search subcontainers.  The control must have an identifiable id &lt;br /&gt;
// and a setValue method.&lt;br /&gt;
// In this method c is the control id and v is the value to be set.&lt;br /&gt;
&lt;b&gt;Ext.Container.method('setValue', function (c, v) {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;this.findById(c).setValue(v);&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;});&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
// Works on all containers as above.  The control must have an identifiable&lt;br /&gt;
// id&amp;nbsp; and a getValue method.&lt;br /&gt;
// In this method, c is the control id of the value to be retrieved. &lt;br /&gt;
&lt;b&gt;Ext.Container.method('getValue', function (c) {&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;return this.findById(c).getValue();&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;});&lt;/b&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
Using these functions on the container saves a tremendous amount of code devoted to looking up and setting values.  Just create a variable for the container and then use the getValue retrieve the value or setValue to set the value.&lt;br /&gt;
&lt;br /&gt;
For instance, if you have a window object named 'win' and a textbox with an id of 'txtName', you can merely use:&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;win.setValue('txtName', 'Michael');&amp;nbsp; &lt;/b&gt;&lt;br /&gt;
&lt;/blockquote&gt;Doing so will set the TextBox value to Michael, even if it is deeply nested in a form panel and several columns.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Links:&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://extjs.com/"&gt;http://extjs.com &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-584854538595344342?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/ipy9P5E0wuY" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/584854538595344342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/584854538595344342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/ipy9P5E0wuY/extjs-helper-functions-getvalue.html" title="ExtJS Helper Functions - GetValue / SetValue" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/01/extjs-helper-functions-getvalue.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cFR34zcSp7ImA9WxBRE0U.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-1215948388091878175</id><published>2010-01-01T15:46:00.001-06:00</published><updated>2010-01-01T16:30:16.089-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-01T16:30:16.089-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sip" /><category scheme="http://www.blogger.com/atom/ns#" term="ipod" /><title>How to Turn Your iPod Touch into a SIP Phone with Nimbuzz and SIPGate</title><content type="html">Many sites on the web that show how to make and receive phone calls on an iPod touch.  But to anyone who has attempted it, you will quickly find that implementation is not fast or easy.  The following shows how to make your iPod Touch into a SIP enabled phone using SIPGate.  Note that these instructions will work with any phone that can load Nimbuzz (such as Nokia, Blackberry and Android) phones.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Get Nimbuzz software and SIPGate account&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
1. Get Nimbuzz.  If you have an iPod touch, get it from the App Store.  Otherwise, go to the &lt;a href="http://www.nimbuzz.com/en/mobile/download"&gt;Nimbuzz site&lt;/a&gt; and follow the download and installation and account setup instructions.&lt;br /&gt;
&lt;br /&gt;
2. Get a SIPGate account at the site of your choice.&amp;nbsp; SIPGate is a German company, so European customers can get European numbers.&amp;nbsp; US phone numbers are available at &lt;a href="http://www.sipgate.us/"&gt;http://www.sipgate.us/&lt;/a&gt;.&amp;nbsp; At this time, only California numbers are available.&amp;nbsp; SIPGate offers free accounts for one person (as of the time of this writing).&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Configure Nimbuzz&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Nimbuzz offers SIPGate as one of the native SIP integration options.&amp;nbsp; In my testing, this native integration does not work.&amp;nbsp; To make matters worse, the required SIP settings are hidden deep within SIPGate.&amp;nbsp; Here's how to configure Nimbuzz with SIPGate to make it work.&amp;nbsp; Please note, the instructions as follow are for the iPod Touch.&amp;nbsp; The UI for other phones may differ slightly or significantly.&lt;br /&gt;
&lt;br /&gt;
1. Open Nimbuzz, choose Call (telephone icon) at the ribbon at the bottom of the screen.&lt;br /&gt;
&lt;br /&gt;
2. &lt;b&gt;Nimbuzz Out&lt;/b&gt; is the default provider.&amp;nbsp; You will see &lt;span style="background-color: black; color: white;"&gt;Nimbuzz Out &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; $0.00 &amp;nbsp;&amp;nbsp; &amp;gt;&lt;/span&gt; in the bar at the top of the screen.&amp;nbsp; Push the &lt;b&gt;&amp;gt;&lt;/b&gt; to see the Nimbuzz call settings screen.&amp;nbsp; You will see NimbuzzOut, SkypeOut and SIP as options.&amp;nbsp; Push SIP to see a list of SIP/VoIP providers.&lt;br /&gt;
&lt;br /&gt;
3. Go to the bottom of the list and select &lt;b&gt;Other VoIP Account&lt;/b&gt;.&amp;nbsp; You will see Sipgate.DE/Sipgate.US as options - do not select either of these as they do not work.&lt;br /&gt;
&lt;br /&gt;
4. Get your SIP username and password from the SIPGate website.&amp;nbsp;&amp;nbsp; &lt;i&gt;Note: Your SIPGate VoIP user name and password are not the same user name and password you use to log into the website.&lt;/i&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Push Settings at the top-right corner of the SIPGate screen.&lt;/li&gt;
&lt;li&gt;Click the left-most phone and choose &lt;b&gt;SIP Credentials&lt;/b&gt; from the menu.&lt;/li&gt;
&lt;li&gt;The SIP-ID is your user name and SIP-Password your password for connecting Nimbuzz to SIPGate.&amp;nbsp; The Domain and Proxy are sipgate.com (unless otherwise noted).&lt;/li&gt;
&lt;/ul&gt;Once you have followed these steps, you should be able to make and receive calls from your Nimbuzz application without any problems. &lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-1215948388091878175?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/P4otpV3KUDs" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/1215948388091878175?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/1215948388091878175?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/P4otpV3KUDs/how-to-turn-your-ipod-touch-into-sip.html" title="How to Turn Your iPod Touch into a SIP Phone with Nimbuzz and SIPGate" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2010/01/how-to-turn-your-ipod-touch-into-sip.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ENR3Y8eSp7ImA9Wx9XGEo.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-8538990234431913404</id><published>2009-10-02T12:12:00.008-05:00</published><updated>2011-01-12T17:41:36.871-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-12T17:41:36.871-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="pgp" /><title>Implementing PGP File Encryption in ASP.Net/C# Using GnuPG</title><content type="html">I was recently asked to implement PGP encryption for a file before sending it to a vendor.&amp;nbsp; In performing my research, I found GnuPG to be the easiest solution to understand as well as posing the least amount of risk for implementation.&amp;nbsp; The great thing about GnuPG is that you can download it and the instructions are easy to follow for encrypting files.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, I also found are some challenges during the implementation.&amp;nbsp; The existing documentation on the web is also confusing and is old.&amp;nbsp; This post is an attempt to update the existing documentation to 2009, provide a working coded example, and give a quick and easy roadmap for implementing PGP in an ASP.Net project.&lt;br /&gt;
&lt;h5&gt;Step 1 – Download and install GnuPG (GPG)&lt;/h5&gt;The main GnuPG page is &lt;a href="http://www.gnupg.org/"&gt;http://www.gnupg.org&lt;/a&gt;.&amp;nbsp; The Windows download can be &lt;a href="http://www.gnupg.org/download/index.en.html#auto-ref-2" rel="enclosure" target="_blank" title="GnuPG Windows Download"&gt;found here&lt;/a&gt;.&amp;nbsp; The version I refer to in this post is GnuPG 1.4.10b.&lt;br /&gt;
&lt;br /&gt;
Installing the GnuPG software is easy as it uses a standard installer.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;Be careful when installing the application on the server.&lt;/em&gt;&amp;nbsp; &lt;i&gt;Choose a Windows account that is generic to installations. &amp;nbsp;&lt;/i&gt;&lt;i&gt;There is a mistake in the installation process where important application data is installed in the Application Data directory of the account performing the installation.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
You can find the files by installing GnuPG on your local machine and then looking in &lt;strong&gt;C:\Documents and Settings\[%Windows User Name%]\Application Data\GnuPG&lt;/strong&gt;.&amp;nbsp; Several key files are installed there and you will need to reference this directory from the ASP.Net code.&amp;nbsp; This is the biggest ‘gotcha’ for the entire process.&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;&lt;b&gt;Update (2011-01-12): For 64-bit servers, the directory is&amp;nbsp;C:\Users\[user name]\AppData\Roaming\gnupg&lt;/b&gt;&lt;hr /&gt;&lt;h5&gt;Step 2 – Learn GPG&lt;/h5&gt;An excellent introduction to GPG has been written by Brendan Kidwell and can be &lt;a href="http://www.glump.net/howto/gpg_intro" rel="enclosure" target="_blank" title="A Practical Introduction to GNU Privacy Guard in Windows"&gt;found here&lt;/a&gt;.&lt;br /&gt;
You will find excellent instructions for installation and use in Windows and Linux.&amp;nbsp; Pay special attention to the GPG Cheat Sheet and make sure you successfully encrypt and decrypt files from the command line before proceeding with coding.&lt;br /&gt;
You will need to install any public keys needed for encryption before running the code, as well as understanding how to retrieve the name of the name of the key (using –list-keys) before running the C# below.&lt;br /&gt;
&lt;h5&gt;Step 3 – Implement the PGP Object&lt;/h5&gt;Following is the code that I use to encrypt files.&amp;nbsp; It is heavily indebted to an article at the Code Project on &lt;a href="http://www.codeproject.com/KB/security/GnuPGAutoDecrypt.aspx" rel="enclosure" target="_blank" title="Automated File Decryption Using GnuPG and C#"&gt;decrypting files&lt;/a&gt; by Kurt Mang.&lt;br /&gt;
&lt;hr /&gt;&lt;div class="csharpcode"&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Diagnostics;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Security;

&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// File encryption wrapper.  Executes GNU PGP as described here:&lt;/span&gt;
&lt;span class="rem"&gt;/// http://www.glump.net/howto/gpg_intro&lt;/span&gt;
&lt;span class="rem"&gt;/// And downloaded from here:&lt;/span&gt;
&lt;span class="rem"&gt;/// http://www.gnupg.org/download/index.en.html#auto-ref-2&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PGP
{
&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// Path to the PGP software&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;string&lt;/span&gt; _pgpPath = &lt;span class="str"&gt;@"C:\Program Files\GNU\GnuPG\gpg.exe"&lt;/span&gt;;

&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// The path to the PGP file can be changed (if needed) &lt;/span&gt;
&lt;span class="rem"&gt;/// or executed&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; PgpPath {
get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _pgpPath; }
set { _pgpPath = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
}
&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// The home directory argument in GnuPG&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;string&lt;/span&gt; _homeDir;
&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// The location of the PubRing and SecRing files&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; HomeDirectory {
get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _homeDir; }
set { _homeDir = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
}
&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// Public constructor stores the home directory argument&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; PGP(&lt;span class="kwrd"&gt;string&lt;/span&gt; homeDirectory) {
HomeDirectory = homeDirectory;
}

&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// Encrypts the file&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;param name="keyName"&amp;gt;Name of the encryption file&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;param name="fileFrom"&amp;gt;Source file to be encrypted&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="rem"&gt;/// &amp;lt;param name="fileTo"&amp;gt;Destination file (after encryption)&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Encrypt(&lt;span class="kwrd"&gt;string&lt;/span&gt; keyName, &lt;span class="kwrd"&gt;string&lt;/span&gt; fileFrom, &lt;span class="kwrd"&gt;string&lt;/span&gt; fileTo) {

&lt;span class="rem"&gt;/// File info&lt;/span&gt;
FileInfo fi = &lt;span class="kwrd"&gt;new&lt;/span&gt; FileInfo(fileFrom);
&lt;span class="kwrd"&gt;if&lt;/span&gt;(!fi.Exists) {
&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Exception(&lt;span class="str"&gt;"Missing file.  Cannot find the file to encrypt."&lt;/span&gt;);
}

&lt;span class="rem"&gt;/// Cannot encrypt a file if it already exists&lt;/span&gt;
&lt;span class="kwrd"&gt;if&lt;/span&gt;(File.Exists(fileTo)) {
&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Exception(&lt;span class="str"&gt;"Cannot encrypt file.  File already exists"&lt;/span&gt;);
}

&lt;span class="rem"&gt;/// Confirm the existence of the PGP software&lt;/span&gt;
&lt;span class="kwrd"&gt;if&lt;/span&gt;(!File.Exists(PgpPath)) {
&lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Exception(&lt;span class="str"&gt;"Cannot find PGP software."&lt;/span&gt;);
}

&lt;span class="rem"&gt;/// Turn off all windows for the process&lt;/span&gt;
ProcessStartInfo s = &lt;span class="kwrd"&gt;new&lt;/span&gt; ProcessStartInfo(&lt;span class="str"&gt;"cmd.exe"&lt;/span&gt;);
s.CreateNoWindow = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
s.UseShellExecute = &lt;span class="kwrd"&gt;false&lt;/span&gt;;
s.RedirectStandardInput = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
s.RedirectStandardOutput = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
s.RedirectStandardError = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
s.WorkingDirectory = fi.DirectoryName;

&lt;span class="rem"&gt;/// Execute the process and wait for it to exit.  &lt;/span&gt;
&lt;span class="rem"&gt;/// NOTE: IF THE PROCESS CRASHES, it will freeze&lt;/span&gt;
&lt;span class="kwrd"&gt;bool&lt;/span&gt; processExited = &lt;span class="kwrd"&gt;false&lt;/span&gt;;

&lt;span class="kwrd"&gt;using&lt;/span&gt;(Process p = Process.Start(s)) {
&lt;span class="rem"&gt;/// Build the encryption arguments&lt;/span&gt;
&lt;span class="kwrd"&gt;string&lt;/span&gt; recipient = &lt;span class="str"&gt;" -r \""&lt;/span&gt; + keyName + &lt;span class="str"&gt;"\""&lt;/span&gt;;
&lt;span class="kwrd"&gt;string&lt;/span&gt; output = &lt;span class="str"&gt;" -o \""&lt;/span&gt; + fileTo + &lt;span class="str"&gt;"\""&lt;/span&gt;;
&lt;span class="kwrd"&gt;string&lt;/span&gt; encrypt = &lt;span class="str"&gt;" -e \""&lt;/span&gt; + fileFrom + &lt;span class="str"&gt;"\""&lt;/span&gt;;
&lt;span class="kwrd"&gt;string&lt;/span&gt; homedir = &lt;span class="str"&gt;" --homedir \""&lt;/span&gt; + HomeDirectory + &lt;span class="str"&gt;"\""&lt;/span&gt;;
&lt;span class="kwrd"&gt;string&lt;/span&gt; cmd = &lt;span class="str"&gt;"\""&lt;/span&gt; + PgpPath + &lt;span class="str"&gt;"\""&lt;/span&gt; + homedir + recipient + output + encrypt;

p.StandardInput.WriteLine(cmd);
p.StandardInput.Flush();
p.StandardInput.Close();
processExited = p.WaitForExit(3500);
p.Close();
}
&lt;span class="kwrd"&gt;return&lt;/span&gt; processExited;
}

}&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;hr /&gt;A couple of things should be noted about this object:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The constructor takes a HomeDirectory argument.&amp;nbsp; This is the Application Settings directory where the GPG application files have been installed.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;Obviously the Windows account that runs the ASP.Net code needs to have access to the executable as well as the ability to run executables and create files. &lt;/li&gt;
&lt;li&gt;The code checks for the existence of the GPG executable, the source file and the destination file.&amp;nbsp; The reason is that the application can hang without throwing an exception if anything goes wrong. &lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-8538990234431913404?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/hxHGZrOLHzI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/8538990234431913404?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/8538990234431913404?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/hxHGZrOLHzI/implementing-pgp-file-encryption-in.html" title="Implementing PGP File Encryption in ASP.Net/C# Using GnuPG" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/10/implementing-pgp-file-encryption-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEESHo4fyp7ImA9WhRWGEU.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-7591605162478575304</id><published>2009-07-08T16:34:00.004-05:00</published><updated>2012-01-06T15:50:09.437-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-06T15:50:09.437-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql server" /><title>Some useful SQL Date functions</title><content type="html">I have been working with dates lately and have come up with a few useful SQL Date functions lately. I find myself recreating these functions on all the projects, so I have saved below in the form of a script.    &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;-- ============================================================================      &lt;br /&gt;
-- Author: Rob Lieving       &lt;br /&gt;
-- Create date: 2009-07-08       &lt;br /&gt;
-- Description: Returns the number of days in a month for the passed date/time       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
CREATE FUNCTION [dbo].[fncDaysInMonth]       &lt;br /&gt;
(       &lt;br /&gt;
@date AS DATETIME       &lt;br /&gt;
)       &lt;br /&gt;
RETURNS INT       &lt;br /&gt;
AS       &lt;br /&gt;
BEGIN       &lt;br /&gt;
RETURN DAY(DATEADD(mm, DATEDIFF(mm, -1, @date), -1))       &lt;br /&gt;
END       &lt;br /&gt;
GO       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
-- Author: Rob Lieving       &lt;br /&gt;
-- Create date: 2009-07-08       &lt;br /&gt;
-- Description: Returns a date from 3 integers       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
CREATE FUNCTION dbo.fncDate       &lt;br /&gt;
(       &lt;br /&gt;
@Year INT,       &lt;br /&gt;
@Month INT,       &lt;br /&gt;
@Day INT       &lt;br /&gt;
)       &lt;br /&gt;
RETURNS DATETIME       &lt;br /&gt;
AS       &lt;br /&gt;
BEGIN       &lt;br /&gt;
RETURN DATEADD(dd, @Day - 1, DATEADD(mm, @Month - 1, DATEADD(yyyy, @Year - 1900, 0)))       &lt;br /&gt;
END       &lt;br /&gt;
GO       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
-- Author: Rob Lieving       &lt;br /&gt;
-- Create date: 2009-06-29       &lt;br /&gt;
-- Description: Calculates the last day of the month       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
CREATE FUNCTION [dbo].[fncLastDayOfMonth]       &lt;br /&gt;
(       &lt;br /&gt;
@dt DATETIME       &lt;br /&gt;
)       &lt;br /&gt;
RETURNS DATETIME       &lt;br /&gt;
AS       &lt;br /&gt;
BEGIN       &lt;br /&gt;
RETURN DATEADD(dd, -DAY(DATEADD(m,1,@dt)), DATEADD(m,1,@dt))       &lt;br /&gt;
END       &lt;br /&gt;
GO       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
-- Author: Rob Lieving       &lt;br /&gt;
-- Create date: 2009-06-29       &lt;br /&gt;
-- Description: Returns the first day of the month for a given date       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
CREATE FUNCTION [dbo].[fncFirstDayOfMonth]       &lt;br /&gt;
(       &lt;br /&gt;
@dt DATETIME       &lt;br /&gt;
)       &lt;br /&gt;
RETURNS DATETIME       &lt;br /&gt;
AS       &lt;br /&gt;
BEGIN       &lt;br /&gt;
RETURN DATEADD(day, -DAY(@dt) + 1, @dt)       &lt;br /&gt;
END       &lt;br /&gt;
GO       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
-- Author: Rob Lieving       &lt;br /&gt;
-- Create date: 2009-02-17       &lt;br /&gt;
-- Description: Returns a smalldatetime with the time removed       &lt;br /&gt;
-- ============================================================================       &lt;br /&gt;
CREATE FUNCTION [dbo].[fncRemoveTime]       &lt;br /&gt;
(       &lt;br /&gt;
@dt AS DATETIME       &lt;br /&gt;
)       &lt;br /&gt;
RETURNS SMALLDATETIME       &lt;br /&gt;
AS       &lt;br /&gt;
BEGIN       &lt;br /&gt;
RETURN CAST(DATEADD(month,((YEAR(@dt)-1900)*12)+MONTH(@dt)-1,DAY(@dt)-1) AS SMALLDATETIME)       &lt;br /&gt;
END       &lt;br /&gt;
GO&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-7591605162478575304?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/ZPuxkOo_o7Q" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/7591605162478575304?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/7591605162478575304?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/ZPuxkOo_o7Q/some-useful-sql-date-functions.html" title="Some useful SQL Date functions" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/07/some-useful-sql-date-functions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cGQ308eyp7ImA9WxJVGUU.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-1444557750432420934</id><published>2009-07-07T11:40:00.002-05:00</published><updated>2009-07-07T11:43:42.373-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-07T11:43:42.373-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql server" /><title>Debugging Print Statement</title><content type="html">I am doing some Stored Procedure testing and trying to push performance as much as possible.  One thing that helps is the ability to time how long individual statements take to execute.  The print statement has to display the time down to the second or millisecond.&lt;br /&gt;&lt;br /&gt;A useful print statement looks like this:&lt;br /&gt;&lt;br /&gt;PRINT '[string value]: ' + CONVERT(varchar,GETDATE(),109)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-1444557750432420934?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/vbVVWM68k8c" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/1444557750432420934?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/1444557750432420934?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/vbVVWM68k8c/debugging-print-statement.html" title="Debugging Print Statement" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/07/debugging-print-statement.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUCRHk4fyp7ImA9WxJWGEs.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-3581657479003191304</id><published>2009-06-24T12:49:00.001-05:00</published><updated>2009-06-24T12:57:45.737-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-24T12:57:45.737-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ssis" /><category scheme="http://www.blogger.com/atom/ns#" term="sql server" /><title>How to Deploy and Test An SSIS Package</title><content type="html">&lt;p&gt;When working with SSIS, it is not immediately obvious how to deploy a package.&amp;#160; Following are my short notes on deploying an SSIS package*.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Deploy the Package&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;While in the Package designer, choose &lt;u&gt;P&lt;/u&gt;roject &amp;gt; [Package Name] &lt;u&gt;P&lt;/u&gt;roperties.&amp;#160; The Configuration manager dialog will appear. &lt;/li&gt;    &lt;li&gt;Choose Deployment Utility from the tree. &lt;/li&gt;    &lt;li&gt;Change the &lt;strong&gt;CreateDeploymentUtility&lt;/strong&gt; option from False to True.&amp;#160; Note the &lt;strong&gt;DeploymentOutputPath&lt;/strong&gt; variable.&amp;#160; Push OK to close the dialog. &lt;/li&gt;    &lt;li&gt;Open the Solution Explorer and right-click on the .dtsx file and choose Properties.&amp;#160; Copy the Full Path variable and use it to find the bin\Deployment folder. &lt;/li&gt;    &lt;li&gt;Locate the [Package Name].SSISDeploymentManifest file.&amp;#160; Double-click on the file and follow the steps outlined by the wizard to deploy the package. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Test the deployed Package&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open MSFT SQL Server Management Studio and choose Co&lt;u&gt;n&lt;/u&gt;nect &amp;gt; &lt;u&gt;I&lt;/u&gt;ntegration Services from the UI.&amp;#160; Choose the Server and connect.&lt;/li&gt;    &lt;li&gt;The packages will be saved under the MSDB folder.&amp;#160; Right-click on the package to run it.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;---&lt;/p&gt;  &lt;p&gt;*&amp;#160; To re-deploy a package, follow steps 1-5 again.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-3581657479003191304?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/PQ6c_Ws_tt0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3581657479003191304?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3581657479003191304?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/PQ6c_Ws_tt0/how-to-deploy-ssis-package.html" title="How to Deploy and Test An SSIS Package" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/06/how-to-deploy-ssis-package.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQDQXg4cSp7ImA9WxJRFkU.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-6310505991272187776</id><published>2009-05-18T17:38:00.001-05:00</published><updated>2009-05-18T17:39:30.639-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-18T17:39:30.639-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="crystal reports" /><category scheme="http://www.blogger.com/atom/ns#" term="web services" /><title>ASP.Net as Crystal Reports data source</title><content type="html">&lt;p&gt;There are not many good articles on using an ASP.Net web source as a data source.&amp;#160; This post attempts to enumerate the settings and make the process straightforward.&lt;/p&gt;  &lt;p&gt;Before starting, I want to make a couple of recommendations:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;In my experience, embedded schemas do not work.&amp;#160; That means that working with native types (such as DataSets) that have embedded schemas won’t work well. &lt;/li&gt;    &lt;li&gt;Since embedded schemas don’t work, use a simple XMLDocument object as your return value. &lt;/li&gt;    &lt;li&gt;You will need to write your own schema for service.&amp;#160; Again – keep the return XML simple. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The instructions for creating an Crystal Reports XML Data Source are as follows*:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Open the database expert.&amp;#160; Choose &lt;strong&gt;Create New Connection / XML&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;XML (data source) type and location:&lt;/strong&gt;&amp;#160; Choose enter in your service in the &lt;strong&gt;URL HTTP(S) XML URL&lt;/strong&gt; textbox.&amp;#160; Check the box for &lt;strong&gt;Specify Schema File&lt;/strong&gt;.&amp;#160; Click ‘Next’.&amp;#160; There are a couple of items to note here.       &lt;ul&gt;       &lt;li&gt;Crystal gives an option for choosing &lt;strong&gt;Use Web Service Data Source&lt;/strong&gt;.&amp;#160; I cannot get this to work – don’t choose it. &lt;/li&gt;        &lt;li&gt;The URL for the service is the .asmx path/service name.&amp;#160; For instance, if your service is getGrid on the web-apps server, the path is &lt;a href="http://web-apps/services.asmx/getGrid"&gt;http://web-apps/services.asmx/getGrid&lt;/a&gt;.&amp;#160; Adjust the path as needed to your .asmx file. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;HTTP Authentication for XML file:&amp;#160; &lt;/strong&gt;This screen deals with security.&amp;#160; I typically work inside a corporate firewall without security, so I leave these fields blank.&amp;#160; If necessary, fill in the User Id and Password. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Schema file type and location:&lt;/strong&gt;&amp;#160; I put my schema files on the server,&amp;#160; but usually test with a local XSD file.&amp;#160; Choose HTTP and the path, if the file is on your server.&amp;#160; Otherwise, if the file is local, choose &lt;strong&gt;Use Local Schema&lt;/strong&gt; and point the path to the local schema. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;HTTP Parameters:&lt;/strong&gt;&amp;#160; Click the &lt;strong&gt;Add Property …&lt;/strong&gt; button to add your parameters.&amp;#160; The &lt;strong&gt;Value&lt;/strong&gt; can be left blank, but the &lt;strong&gt;Property&lt;/strong&gt; must be filled in with the parameter names.&amp;#160; Service parameters are case sensitive, so make sure that the case matches. &lt;/li&gt;    &lt;li&gt;Clicking Finish will take you back to the data screen.&amp;#160; You will be given an options for the XPaths to the data in your source.&amp;#160; If successful, you will then have data from a web service in your report. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;---&lt;/p&gt;  &lt;p&gt;* Tested on CR XI R2/CR 2008&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-6310505991272187776?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/Z3iM5jjZch8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/6310505991272187776?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/6310505991272187776?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/Z3iM5jjZch8/aspnet-as-crystal-reports-data-source.html" title="ASP.Net as Crystal Reports data source" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/05/aspnet-as-crystal-reports-data-source.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYFQXg4eSp7ImA9WxJTE08.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-3157922627448953098</id><published>2009-04-21T08:53:00.004-05:00</published><updated>2009-04-21T09:11:50.631-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-21T09:11:50.631-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="regular expression" /><title>Regular Expression List</title><content type="html">In an &lt;a href="http://rlieving.blogspot.com/search/label/regular%20expression"&gt;earlier post&lt;/a&gt;, I showed some regular expressions I had found for manipulating strings in a PDF project.  &lt;br /&gt;&lt;br /&gt;The following is a list of other expressions I have developed for use on other projects.  I plan to update this list as I create expressions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;h4&gt;Regular Expressions&lt;/h4&gt;&lt;/span&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Expression (C#):&lt;/span&gt; &lt;br /&gt;@"[\(.\d+.\)]+$"&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Purpose:&lt;/span&gt; &lt;br /&gt;I used this expression to rename spreadsheets.  This expression finds ([digits]) at the end of a string.  Further code parses and increments the number inside the parentheses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-3157922627448953098?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/p3fIdv7Lsus" height="1" width="1"/&gt;</content><link rel="related" href="http://regexlib.com/CheatSheet.aspx" title="Regular Expression List" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3157922627448953098?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3157922627448953098?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/p3fIdv7Lsus/regular-expression-list.html" title="Regular Expression List" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/04/regular-expression-list.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYNQXk5fyp7ImA9WxVVGE0.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-8111573001935209659</id><published>2009-03-09T17:40:00.008-05:00</published><updated>2009-03-11T15:26:30.727-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-11T15:26:30.727-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="calcs" /><title>Return equation</title><content type="html">The following equation calculates a return for 1 period:&lt;br /&gt;&lt;br /&gt;((&lt;span style="font-weight:bold;"&gt;Previous Return&lt;/span&gt; + 100) * (&lt;span style="font-weight:bold;"&gt;Current Return&lt;/span&gt; / 100)) + &lt;span style="font-weight:bold;"&gt;Previous Return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Where:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Previous Return&lt;/strong&gt; is the previous period return&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Current Return&lt;/strong&gt; is the current period return&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-8111573001935209659?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/PbdcWZ5lNds" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/8111573001935209659?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/8111573001935209659?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/PbdcWZ5lNds/return-equation.html" title="Return equation" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/03/return-equation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMCRH47eCp7ImA9Wx9SEk4.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-1061919139440162902</id><published>2009-02-24T08:18:00.009-06:00</published><updated>2010-12-01T14:47:45.000-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-01T14:47:45.000-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql server" /><title>Find the row counts for all the tables in a SQL Server 2005 database</title><content type="html">Have you ever needed to investigate an application database and quickly determine where the records are? &lt;br /&gt;
The following script returns a rowset that contains all the table names of a SQL Server 2005 database along with the row counts. &lt;br /&gt;
&lt;hr /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;-- declare the variables&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;DECLARE @i INT, -- integer holder&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;@table_name VARCHAR(50), -- table name&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;@sql NVARCHAR(800) -- dynamic sql&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;-- create the temp table. Initialize count column to -1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;CREATE TABLE #t (&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;[name] NVARCHAR(128),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;rows CHAR(11),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;reserved VARCHAR(18),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;data VARCHAR(18),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;index_size VARCHAR(18),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;unused VARCHAR(18)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;SELECT @table_name = [name]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;FROM sysobjects&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;WHERE xtype = 'U'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;-- Initialize i to run at least once&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;SET @i = 1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;-- loop while rows are still being selected&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;WHILE (@i &amp;gt; 0)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;BEGIN&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;-- create the dynamic sql that updates the row counts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;-- for each table&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;SET @sql = 'INSERT #t ([name], rows, reserved, data, index_size, unused)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;EXEC sp_spaceused ['+ @table_name + ']'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;-- execute the dynamic sql&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;EXEC sp_executesql @sql&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;-- find out the name of the next table&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;SELECT @table_name = [name]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;FROM sysobjects&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;WHERE xtype = 'U'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;AND [name] NOT IN&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; (&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;SELECT [name]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;FROM #t&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; )&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;-- stop looking if no rows are selected&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;SET @i = @@ROWCOUNT&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;END&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;-- return the results&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;SELECT *&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;FROM #t&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;ORDER BY reserved DESC&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;DROP TABLE #t&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-1061919139440162902?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/HoI94x_FLkM" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/1061919139440162902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/1061919139440162902?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/HoI94x_FLkM/find-row-counts-for-all-tables-in-sql.html" title="Find the row counts for all the tables in a SQL Server 2005 database" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/02/find-row-counts-for-all-tables-in-sql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QDQH8yeCp7ImA9WxVaEk8.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-3793829530328638549</id><published>2009-02-17T16:00:00.003-06:00</published><updated>2009-04-08T17:22:51.190-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T17:22:51.190-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql server" /><title>Script to change object owners</title><content type="html">&lt;p&gt;I have recently started working with SQL Server 2005, and the first thing I noticed is that I cannot automatically set the owner of a script at creation time.&amp;#160; SQL Server 2005 automatically adds my user name as the object owner.&lt;/p&gt;  &lt;p&gt;The following script, adapted from &lt;a title="Scott Forsyth" href="http://weblogs.asp.net/owscott/archive/2004/01/30/65229.aspx" target="_blank"&gt;Scott Forsyth's blog&lt;/a&gt;, batches up the changes.&amp;#160; Change the name of the old owner (@old) and the new owner (@new) and it will change the ownership for all the database objects.&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="600" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="598"&gt;&lt;strong&gt;Script to update SQL Server Object Ownership&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="598"&gt;         &lt;p&gt;DECLARE @old nvarchar(30), @new nvarchar(30), @obj nvarchar(50), @x int;&lt;/p&gt;          &lt;p&gt;SET @old = 'domain\user-name';&lt;/p&gt;          &lt;p&gt;SET @new = 'dbo'SELECT @x = count(*);&lt;/p&gt;          &lt;p&gt;FROM INFORMATION_SCHEMA.ROUTINES a &lt;/p&gt;          &lt;p&gt;WHERE &lt;/p&gt;          &lt;p&gt;&amp;#160; a.ROUTINE_TYPE IN('PROCEDURE', 'FUNCTION') &lt;/p&gt;          &lt;p&gt;&amp;#160; AND a.SPECIFIC_SCHEMA = @old;&lt;/p&gt;          &lt;p&gt;while(@x &amp;gt; 0) &lt;/p&gt;          &lt;p&gt;&amp;#160; BEGIN &lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; SELECT @obj = [SPECIFIC_NAME] &lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; FROM INFORMATION_SCHEMA.ROUTINES a &lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; WHERE &lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; a.ROUTINE_TYPE IN('PROCEDURE', 'FUNCTION') &lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AND a.SPECIFIC_SCHEMA = @old;&lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SET @x = @@ROWCOUNT - 1;&lt;/p&gt;          &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; EXEC sp_changeobjectowner @obj, @new;&lt;/p&gt;          &lt;p&gt;END&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-3793829530328638549?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/TXR2oeGyjmI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3793829530328638549?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/3793829530328638549?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/TXR2oeGyjmI/script-to-change-object-owners.html" title="Script to change object owners" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2009/02/script-to-change-object-owners.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQESXk5eCp7ImA9WxRbEk4.&quot;"><id>tag:blogger.com,1999:blog-25912180.post-9187768894671706768</id><published>2008-12-02T09:55:00.009-06:00</published><updated>2008-12-02T10:11:48.720-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-02T10:11:48.720-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="office" /><category scheme="http://www.blogger.com/atom/ns#" term="google apps" /><title>Direct Link to a new Google Spreadsheet</title><content type="html">&lt;div&gt;One of the advantages to having web-based documents is that you can open them from any desktop in multiple browsers.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I use Google Apps for my online office suite, but find that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Zoho&lt;/span&gt; is a strong competitor for many reasons. One thing I like about &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Zoho&lt;/span&gt; is that they &lt;a href="http://sheet.zoho.com/scratch.do"&gt;publish a URL&lt;/a&gt; that allows you to open a 'scratch' worksheet.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Zoho&lt;/span&gt; does not require an account for this spreadsheet.  If you have a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Zoho&lt;/span&gt; account, you have the option of saving it when done. Otherwise, you can quickly do spreadsheet calculations, export it, save it, or close it when you are done.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But what about Google Apps? Do they publish a similar URL?  It turns out they do, but it is hidden.   After trial and error (and watching my browser carefully), I was able to come up with the URL for a new Google Apps spreadsheet. (Note: This URL requires a Google Apps account - which is free.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The URL is as follows:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;http://spreadsheets.google.com/a/&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;[Google Apps &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Url&lt;/span&gt;]&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;ccc&lt;/span&gt;?new&amp;amp;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;hl&lt;/span&gt;=en&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Where [Google Apps URL] is the URL to your Google Apps.  Just post it on your iGoogle &lt;a href="http://www.google.com/ig/directory?url=www.google.com/ig/modules/bookmarks.xml"&gt;bookmarks widget&lt;/a&gt; and you can start launching new spreadsheets right from your homepage.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25912180-9187768894671706768?l=rlieving.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobsSpace/~4/FcVoaMJVPMk" height="1" width="1"/&gt;</content><link rel="related" href="http://www.google.com/a/" title="Direct Link to a new Google Spreadsheet" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/9187768894671706768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/25912180/posts/default/9187768894671706768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/RobsSpace/~3/FcVoaMJVPMk/direct-link-to-new-google-doc.html" title="Direct Link to a new Google Spreadsheet" /><author><name>Rob</name><uri>http://www.blogger.com/profile/06882656311928696692</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://photos1.blogger.com/blogger/2494/2713/1600/3717.jpg" /></author><feedburner:origLink>http://rlieving.blogspot.com/2008/12/direct-link-to-new-google-doc.html</feedburner:origLink></entry></feed>

