<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Ruminations of a Developer</title>
    <link>http://www.bpsvc.com/devblog/</link>
    <description>Mark Bonafe</description>
    <language>en-us</language>
    <copyright>Mark Bonafe</copyright>
    <lastBuildDate>Fri, 27 Jul 2007 12:09:59 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.8.5223.2</generator>
    <managingEditor>markbonafe@bpsvc.com</managingEditor>
    <webMaster>markbonafe@bpsvc.com</webMaster>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=46eb2d59-8e61-4907-af1a-c687e19c9251</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,46eb2d59-8e61-4907-af1a-c687e19c9251.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,46eb2d59-8e61-4907-af1a-c687e19c9251.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=46eb2d59-8e61-4907-af1a-c687e19c9251</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.dotnet247.com/247reference/msgs/44/221227.aspx">Here is a list</a> of
      all the attributes available for creating an inherited Windows textbox user control.
   </p>
        <p>
      Very useful information!
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=46eb2d59-8e61-4907-af1a-c687e19c9251" />
      </body>
      <title>Trouble Creating a Windows User Control?</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,46eb2d59-8e61-4907-af1a-c687e19c9251.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,46eb2d59-8e61-4907-af1a-c687e19c9251.aspx</link>
      <pubDate>Fri, 27 Jul 2007 12:09:59 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;a href="http://www.dotnet247.com/247reference/msgs/44/221227.aspx"&gt;Here is a list&lt;/a&gt; of
   all the attributes available for creating an inherited Windows textbox user control.
&lt;/p&gt;
&lt;p&gt;
   Very useful information!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=46eb2d59-8e61-4907-af1a-c687e19c9251" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,46eb2d59-8e61-4907-af1a-c687e19c9251.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=960f08b7-42af-42ef-a45b-61fc533ee0cb</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,960f08b7-42af-42ef-a45b-61fc533ee0cb.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,960f08b7-42af-42ef-a45b-61fc533ee0cb.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=960f08b7-42af-42ef-a45b-61fc533ee0cb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I recently read this <a href="http://www.lhotka.net/weblog/PermaLink,guid,2508e05d-4d80-4891-b909-0df6546f7dc9.aspx">post</a> by <a href="http://www.lhotka.net/weblog/">Rocky
      Lhotka</a> about the importance of where to place business rules when designing
      software.  My reply, along with an answer to my own question, is reposted
      here.
   </p>
        <p>
      I must say I agree with you on this topic; I don't know anyone who doesn't. 
      I have developed a few applications in VB 6 (yes, VB version 6) and C# using this
      approach.
   </p>
        <p>
      It IS very, very difficult to implement in any but the most simple of applications,
      however.  Unless you are very careful, it is very easy to have all your layers
      working properly and then still find business rules being placed in screens, forms,
      and services.  In the majority of business applications that I've put together,
      the same business object is used in multiple screens, forms, and services.  The
      problem is that, usually, each one requires that different - conflicting - sets of
      business rules be placed on the same object.  There are many design choices when
      faced with this situation.
   </p>
        <p>
      1.  You can wire each screen, form, or service with the rules.  Obviously,
      some of the rules will be duplicated.  This is exactly what we are trying to
      avoid.  It is, however, the easiest to implement; especially since many UI actions
      occur based on the results of some of the business rules.  It's a trap! 
      Don't fall for it.<br />
      2.  You can clutter the object with "condition" settings and apply rules based
      on the conditions.  I've seen this done many times and I hate it.  Talk
      about a maintenance nightmare...<br />
      3.  If the screen, rule, or service requires a special set of business rules,
      you can create a separate business object for each; inheriting from the business object
      that provides the most complete set of rules for the designed purpose.  This
      sounds good.  Business Objects contain all the business rules.  Screens,
      forms, and services don't have duplicate rules to maintain.  Maintenance can
      still be a pain in some cases, though.  When a new rule must be created, care
      must be taken to position it in the right business object so that it is inherited
      only where required.  It is very easy to find duplicate rules in this setup after
      a few months of maintenance kicks in.
   </p>
        <p>
      Of these options, I like number three the best.  But I find that most people
      first choose option 2, then find themselves wishing for something different.
   </p>
        <p>
      If anyone knows of other options or approaches, I'd love to hear about them.
   </p>
        <p>
      Now all this said, I have to laugh at this statement from your post, Rocky:<br />
      "The resulting applications are very fragile and are impossible to upgrade to the
      next technology (like .NET). Today, as we talk, many thousands of lines of code are
      being written in Windows Forms and Web Forms in exactly the same way. Those poor people
      will have a hell of a time upgrading to WPF, because none of their code is reusable."
   </p>
        <p>
      This strikes me as "funny" because every time I've upgraded an application to the
      next technology, it required a complete rewrite from the ground up!  The rewrites
      aren't necessary because business rules are placed in forms, screens, and services
      - but because the code wasn't transferable to the new technology!  Even upgrading
      from .NET 1.1 to .NET 2, or .NET 2 to .NET 3, how much of the code is going to transfer
      cleanly?  That's just code.  Usually an upgraded database is involved, too. 
      SQL Server 2000 to 2003 or 2005, for example.  Coding technology, databases,
      and even hardware are changing so rapidly that keeping up with it all is practically
      impossible.
   </p>
        <p>
      Really, does ANY of this really matter?
   </p>
        <p>
      My Answer:  Yes!  It does matter.  Some day, hopefully sooner than
      later, there will be a "universal" understanding of how to design and write code for
      these situations.  I thought XML, or some cousin, had a chance of helping in
      this arena.  Perhaps it still does.  For now, though, it seems to have hit
      a wall.
   </p>
        <p>
      All the discussing and swapping of ideas leads us closer to this magical day.
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=960f08b7-42af-42ef-a45b-61fc533ee0cb" />
      </body>
      <title>Objects, Business Rules, and Design - Does it Really Matter?</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,960f08b7-42af-42ef-a45b-61fc533ee0cb.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,960f08b7-42af-42ef-a45b-61fc533ee0cb.aspx</link>
      <pubDate>Mon, 22 Jan 2007 15:35:32 GMT</pubDate>
      <description>&lt;p&gt;
   I recently read this &lt;a href="http://www.lhotka.net/weblog/PermaLink,guid,2508e05d-4d80-4891-b909-0df6546f7dc9.aspx"&gt;post&lt;/a&gt;&amp;nbsp;by &lt;a href="http://www.lhotka.net/weblog/"&gt;Rocky
   Lhotka&lt;/a&gt;&amp;nbsp;about the importance of&amp;nbsp;where to place business rules when designing
   software.&amp;nbsp; My reply, along&amp;nbsp;with an answer to my own question,&amp;nbsp;is reposted
   here.
&lt;/p&gt;
&lt;p&gt;
   I must say I agree with you on this topic; I don't know anyone who doesn't.&amp;nbsp;
   I have developed a few applications in VB 6 (yes, VB version 6) and C# using this
   approach.
&lt;/p&gt;
&lt;p&gt;
   It IS very, very difficult to implement in any but the most simple of applications,
   however.&amp;nbsp; Unless you are very careful, it is very easy to have all your layers
   working properly and then still find business rules being placed in screens, forms,
   and services.&amp;nbsp; In the majority of business applications that I've put together,
   the same business object is used in multiple screens, forms, and services.&amp;nbsp; The
   problem is that, usually, each one requires that different - conflicting - sets of
   business rules be placed on the same object.&amp;nbsp; There are many design choices when
   faced with this situation.
&lt;/p&gt;
&lt;p&gt;
   1.&amp;nbsp; You can wire each screen, form, or service with the rules.&amp;nbsp; Obviously,
   some of the rules will be duplicated.&amp;nbsp; This is exactly what we are trying to
   avoid.&amp;nbsp; It is, however, the easiest to implement; especially since many UI actions
   occur based on the results of some of the business rules.&amp;nbsp; It's a trap!&amp;nbsp;
   Don't fall for it.&lt;br&gt;
   2.&amp;nbsp; You can clutter the object with "condition" settings and apply rules based
   on the conditions.&amp;nbsp; I've seen this done many times and I hate it.&amp;nbsp; Talk
   about a maintenance nightmare...&lt;br&gt;
   3.&amp;nbsp; If the screen, rule, or service requires a special set of business rules,
   you can create a separate business object for each; inheriting from the business object
   that provides the most complete set of rules for the designed purpose.&amp;nbsp; This
   sounds good.&amp;nbsp; Business Objects contain all the business rules.&amp;nbsp; Screens,
   forms, and services don't have duplicate rules to maintain.&amp;nbsp; Maintenance can
   still be a pain in some cases, though.&amp;nbsp; When a new rule must be created, care
   must be taken to position it in the right business object so that it is inherited
   only where required.&amp;nbsp; It is very easy to find duplicate rules in this setup after
   a few months of maintenance kicks in.
&lt;/p&gt;
&lt;p&gt;
   Of these options, I like number three the best.&amp;nbsp; But I find that most people
   first choose option 2, then find themselves wishing for something different.
&lt;/p&gt;
&lt;p&gt;
   If anyone knows of other options or approaches, I'd love to hear about them.
&lt;/p&gt;
&lt;p&gt;
   Now all this said, I have to laugh at this statement from your post, Rocky:&lt;br&gt;
   "The resulting applications are very fragile and are impossible to upgrade to the
   next technology (like .NET). Today, as we talk, many thousands of lines of code are
   being written in Windows Forms and Web Forms in exactly the same way. Those poor people
   will have a hell of a time upgrading to WPF, because none of their code is reusable."
&lt;/p&gt;
&lt;p&gt;
   This strikes me as "funny" because every time I've upgraded an application to the
   next technology, it required a complete rewrite from the ground up!&amp;nbsp; The rewrites
   aren't necessary because business rules are placed in forms, screens, and services
   - but because the code wasn't transferable to the new technology!&amp;nbsp; Even upgrading
   from .NET 1.1 to .NET 2, or .NET 2 to .NET 3, how much of the code is going to transfer
   cleanly?&amp;nbsp; That's just code.&amp;nbsp; Usually an upgraded database is involved, too.&amp;nbsp;
   SQL Server 2000 to 2003 or 2005, for example.&amp;nbsp; Coding technology, databases,
   and even hardware are changing so rapidly that keeping up with it all is practically
   impossible.
&lt;/p&gt;
&lt;p&gt;
   Really, does ANY of this really matter?
&lt;/p&gt;
&lt;p&gt;
   My Answer:&amp;nbsp; Yes!&amp;nbsp; It does matter.&amp;nbsp; Some day, hopefully sooner than
   later, there will be a "universal" understanding of how to design and write code for
   these situations.&amp;nbsp; I thought XML, or some cousin, had a chance of helping in
   this arena.&amp;nbsp; Perhaps it still does.&amp;nbsp; For now, though, it seems to have hit
   a wall.
&lt;/p&gt;
&lt;p&gt;
   All the discussing and swapping of ideas leads us closer to this magical day.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=960f08b7-42af-42ef-a45b-61fc533ee0cb" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,960f08b7-42af-42ef-a45b-61fc533ee0cb.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=1f4d51ae-510d-4a9f-a85e-d1720c3258e7</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,1f4d51ae-510d-4a9f-a85e-d1720c3258e7.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,1f4d51ae-510d-4a9f-a85e-d1720c3258e7.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=1f4d51ae-510d-4a9f-a85e-d1720c3258e7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I've seen many posts and articles on how to create a modal dialog for a web application. 
      They all describe different ways to acheive this goal.  Some articles even offer
      controls that you can drag onto the page.  I tried these with varying levels
      of success.  That is to say, the more complex the page, the less reliable these
      controls.  So...
   </p>
        <p>
      I'm going to describe, step by step, how I accomplish modal dialogs for my web applications
      written using .NET v1.1, C#, and Inernet Explorer v6.0.  I see no reason why
      this wouldn't work for VB as well.  If anyone can add to this or explain why
      this wouldn't work for other browsers, I'd love to hear from you.
   </p>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
          <strong>
            <u>Step 1:</u>
          </strong>
          <br />
      Create the dialog page.  I should be setup just like any other web page with
      the following exceptions:
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p dir="ltr" style="MARGIN-RIGHT: 0px">
      Normally, we don't want a dialog to be cached because it is customized for certain
      situations.  In the directive section of the page (HTML view, top of the page),
      enter a directive to disable the caching for the page. 
   </p>
          <ul>
            <li dir="ltr" style="MARGIN-RIGHT: 0px">
              <font face="Courier New">&lt;%@ OutputCache Location="None" VaryByParam="None" %&gt;</font>
            </li>
            <font color="#000000">
            </font>
          </ul>
   In the &lt;HEAD&gt; tag, set the target for the page to itself.  This prevents
   a blank page from displaying when the page is closed. 
   <ul><li style="MARGIN-RIGHT: 0px"><font face="Courier New">&lt;base target="_self"&gt;</font></li></ul><p></p></blockquote>
        <p>
          <strong>
            <u>Step 2:</u>
          </strong>
          <br />
      We need a way to close the dialog reliably.  Response.Redirect() won't work for
      obvious reasons.  Inside the event that will close the dialog, normally a "cancel"
      button click, register script that will close the window.  If you have multiple
      ways to exit the dialog, you might want to create a seperate method and call it from
      each event.
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#0000ff">string</font> strScript = "&lt;script
      language='javascript'&gt;self.close(); &lt;/script&gt;";<br /><font color="#0000ff">if</font> (! <font color="#0000ff">this</font>.IsClientScriptBlockRegistered("CloseScript"))<br />
         <font color="#0000ff">this</font>.RegisterStartupScript("CloseScript",strScript);</font>
          </p>
        </blockquote>
        <p>
          <strong>
            <u>Step 3:</u>
          </strong>
          <br />
      Create the page that opens the dialog.  In the button or link that requires the
      modal dialog, setup the script that will open it for you.  I use the syntax "script
      defer" to allow the page to finish painting before opening the dialog.  "Defer"
      is not necessary and might not work in your situation, but it doesn't hurt to include
      it.  Make sure to include code that submits the form to allow processing of the
      dialog results.  By default, the form name is Form1, so the script is document.Form1.submit(). 
      If you are creating a dialog the only displays information, then the document.Form1.submit();
      script is not necessary.
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#0000ff">string</font> strScript = "&lt;script
      defer&gt;"+<br />
         "var strReturn = window.showModalDialog('MyModalDialog.aspx?Parameter1="
      + </font>
            <font face="Courier New">parameterVariable + "','','dialogWidth:520px;dialogHeight=600px');"+<br />
         "document.Form1.submit();   &lt;/script&gt;";</font>
          </p>
          <p>
            <font face="Courier New">
              <font color="#0000ff">if</font> (! <font color="#0000ff">this</font>.IsClientScriptBlockRegistered("OpenMyDialog"))<br />
        <font color="#0000ff">this</font>.RegisterStartupScript("OpenMyDialog",strScript);</font>
          </p>
        </blockquote>
        <p>
      Of course, if the dialog doesn't required parameters then you don't need to set them
      up.  Set the dialogWidth and dialogHeight properties appropriately.
   </p>
        <p>
          <strong>
            <u>Step 4:</u>
          </strong>
          <br />
      All that's left is to setup a way to determine what the user did inside the dialog. 
      Dialogs have many different uses, so this is where you can get creative.  Some
      dialogs may enter information into a database, some may be as simple as answering
      a yes or no question.  Still others may only be displaying information. 
      If I have a dialog that gathers data for entry into a database, I usually let the
      dialog handle the actual entry instead of passing the data back to the calling form. 
      This allows me to display any rule breaks or errors to the user without loosing track
      of what they were entering.  That way, they don't have to start all over with
      a blank form.  If the application is more complex, then you might need the main
      form to process the information before saving it to the database.
   </p>
        <p>
      In almost all cases, the main form needs to know what the dialog has done.  So
      the approach I use works for nearly every situation.  I create a simple serializable
      object, DataTable, or DataSet (depending on the complexity of the dialog) to put into
      Session.  The main form normally seeds the variable with information.  The
      dialog can use the variable however is necessary.  In nearly every case, in the
      event that closes the dialog, the Session variable is modified and saved back into
      Session.  The calling form then uses it's Page_Load() event to check the variable
      and take appropriate action.
   </p>
        <p>
      The dialog "accept" event code:
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">MyDialogObject DialogReturn = new MyDialogObject();<br />
       ... save to database, fill DialogReturn properties, etc.<br />
       <br />
       Session[MYDIALOG] = DialogReturn;</font>
          </p>
          <p>
            <font face="Courier New"> CloseWindow();  <font color="#006400">// Step
      2 above</font></font>
          </p>
        </blockquote>
        <p>
          <br />
      The main (calling) form code:
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New" color="#000000">
              <font color="#0000ff">private</font>
              <font color="#0000ff">void</font> Page_Load(<font color="#0000ff">object</font> sender,
      System.EventArgs e)<br />
      {<br /><font color="#0000ff">   if</font> (! IsPostBack)<br />
         {<br />
            ... whatever ...<br />
         }</font>
          </p>
          <p>
            <font face="Courier New" color="#000000">
              <font color="#006400">   //
      If a dialog just closed, do whatever is necessary;<br /></font>
              <font color="#0000ff">   if</font> (Session[MYDIALOG] != null)<br />
         {<br />
            ProcessDialogInfo();<br />
         }<br />
      }</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <strong>
            <u>All Done!</u>
          </strong>
          <br />
      Creating modal dialogs with C# and .NET is not as complex as it might seem at first
      glance.  Well, ok - aquiring all this knowledge and information and putting it
      to use was harder than it should've been.  But now it's all in one place. 
      Comments and suggestions are welcome.
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=1f4d51ae-510d-4a9f-a85e-d1720c3258e7" />
      </body>
      <title>Step by Step:  Create a Web Modal Dialog</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,1f4d51ae-510d-4a9f-a85e-d1720c3258e7.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,1f4d51ae-510d-4a9f-a85e-d1720c3258e7.aspx</link>
      <pubDate>Fri, 13 Oct 2006 16:37:54 GMT</pubDate>
      <description>&lt;p&gt;
   I've seen many posts and articles on how to create a modal dialog for a web application.&amp;nbsp;
   They all describe different ways to acheive this goal.&amp;nbsp; Some articles even offer
   controls that you can drag onto the page.&amp;nbsp; I tried these with varying levels
   of success.&amp;nbsp; That is to say, the more complex the page, the less reliable these
   controls.&amp;nbsp; So...
&lt;/p&gt;
&lt;p&gt;
   I'm going to describe, step by step, how I accomplish modal dialogs for my web applications
   written using .NET v1.1, C#, and Inernet Explorer v6.0.&amp;nbsp; I see no reason why
   this wouldn't work for VB as well.&amp;nbsp; If anyone can add to this or explain why
   this wouldn't work for other browsers, I'd love to hear from you.
&lt;/p&gt;
&lt;p dir=ltr style="MARGIN-RIGHT: 0px"&gt;
   &lt;strong&gt;&lt;u&gt;Step 1:&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   Create the dialog page.&amp;nbsp; I should be setup just like any other web page with
   the following exceptions:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p dir=ltr style="MARGIN-RIGHT: 0px"&gt;
   Normally, we don't want a dialog to be cached because it is customized for certain
   situations.&amp;nbsp; In the directive section of the page (HTML view, top of the page),
   enter a directive to disable the caching for the page. 
&lt;ul&gt;
   &lt;li dir=ltr style="MARGIN-RIGHT: 0px"&gt;
      &lt;font face="Courier New"&gt;&amp;lt;%@ OutputCache Location="None" VaryByParam="None" %&amp;gt;&lt;/font&gt;&gt;
   &lt;/li&gt;&lt;font color=#000000&gt;
&lt;/ul&gt;
In the &amp;lt;HEAD&amp;gt; tag, set the target for the page to itself.&amp;nbsp; This prevents
a blank page from displaying when the page is closed. 
&lt;ul&gt;
   &lt;li style="MARGIN-RIGHT: 0px"&gt;
      &lt;font face="Courier New"&gt;&amp;lt;base target="_self"&amp;gt;&lt;/font&gt;
   &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   &lt;strong&gt;&lt;u&gt;Step 2:&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   We need a way to close the dialog reliably.&amp;nbsp; Response.Redirect() won't work for
   obvious reasons.&amp;nbsp; Inside the event that will close the dialog, normally a "cancel"
   button click, register script that will close the window.&amp;nbsp; If you have multiple
   ways to exit the dialog, you might want to create a seperate method and call it from
   each event.
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
   &lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;string&lt;/font&gt; strScript = "&amp;lt;script
   language='javascript'&amp;gt;self.close(); &amp;lt;/script&amp;gt;";&lt;br&gt;
   &lt;font color=#0000ff&gt;if&lt;/font&gt; (! &lt;font color=#0000ff&gt;this&lt;/font&gt;.IsClientScriptBlockRegistered("CloseScript"))&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;this&lt;/font&gt;.RegisterStartupScript("CloseScript",strScript);&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   &lt;strong&gt;&lt;u&gt;Step 3:&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   Create the page that opens the dialog.&amp;nbsp; In the button or link that requires the
   modal dialog, setup the script that will open it for you.&amp;nbsp; I use the syntax "script
   defer" to allow the page to finish painting before opening the dialog.&amp;nbsp; "Defer"
   is not necessary and might not work in your situation, but it doesn't hurt to include
   it.&amp;nbsp; Make sure to include code that submits the form to allow processing of the
   dialog results.&amp;nbsp; By default, the form name is Form1, so the script is document.Form1.submit().&amp;nbsp;
   If you are creating a dialog the only displays information, then the document.Form1.submit();
   script is not necessary.
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
   &lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;string&lt;/font&gt; strScript = "&amp;lt;script
   defer&amp;gt;"+&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;"var strReturn = window.showModalDialog('MyModalDialog.aspx?Parameter1="
   + &lt;/font&gt;&lt;font face="Courier New"&gt;parameterVariable + "','','dialogWidth:520px;dialogHeight=600px');"+&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;"document.Form1.submit();&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;";&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;if&lt;/font&gt; (! &lt;font color=#0000ff&gt;this&lt;/font&gt;.IsClientScriptBlockRegistered("OpenMyDialog"))&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;this&lt;/font&gt;.RegisterStartupScript("OpenMyDialog",strScript);&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Of course, if the dialog doesn't required parameters then you don't need to set them
   up.&amp;nbsp; Set the dialogWidth and dialogHeight properties appropriately.
&lt;/p&gt;
&lt;p&gt;
   &lt;strong&gt;&lt;u&gt;Step 4:&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   All that's left is to setup a way to determine what the user did inside the dialog.&amp;nbsp;
   Dialogs have many different uses, so this is where you can get creative.&amp;nbsp; Some
   dialogs may enter information into a database, some may be as simple as answering
   a yes or no question.&amp;nbsp; Still others may only be displaying information.&amp;nbsp;
   If I have a dialog that gathers data for entry into a database, I usually let the
   dialog handle the actual entry instead of passing the data back to the calling form.&amp;nbsp;
   This allows me to display any rule breaks or errors to the user without loosing track
   of what they were entering.&amp;nbsp; That way, they don't have to start all over with
   a blank form.&amp;nbsp; If the application is more complex, then you might need the main
   form to process the information before saving it to the database.
&lt;/p&gt;
&lt;p&gt;
   In almost all cases, the main form needs to know what the dialog has done.&amp;nbsp; So
   the approach I use works for nearly every situation.&amp;nbsp; I create a simple serializable
   object, DataTable, or DataSet (depending on the complexity of the dialog) to put into
   Session.&amp;nbsp; The main form normally seeds the variable with information.&amp;nbsp; The
   dialog can use the variable however is necessary.&amp;nbsp; In nearly every case, in the
   event that closes the dialog, the Session variable is modified and saved back into
   Session.&amp;nbsp; The calling form then uses it's Page_Load() event to check the variable
   and take appropriate action.
&lt;/p&gt;
&lt;p&gt;
   The dialog "accept" event code:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
   &lt;font face="Courier New"&gt;MyDialogObject DialogReturn = new MyDialogObject();&lt;br&gt;
   &amp;nbsp;... save to database, fill DialogReturn properties, etc.&lt;br&gt;
   &amp;nbsp;&lt;br&gt;
   &amp;nbsp;Session[MYDIALOG] = DialogReturn;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New"&gt;&amp;nbsp;CloseWindow();&amp;nbsp; &lt;font color=#006400&gt;// Step 2
   above&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   &lt;br&gt;
   The main (calling) form code:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
   &lt;font face="Courier New" color=#000000&gt;&lt;font color=#0000ff&gt;private&lt;/font&gt; &lt;font color=#0000ff&gt;void&lt;/font&gt; Page_Load(&lt;font color=#0000ff&gt;object&lt;/font&gt; sender,
   System.EventArgs e)&lt;br&gt;
   {&lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/font&gt; (! IsPostBack)&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;... whatever ...&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" color=#000000&gt;&lt;font color=#006400&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// If
   a dialog just closed, do whatever is necessary;&lt;br&gt;
   &lt;/font&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/font&gt; (Session[MYDIALOG] != null)&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProcessDialogInfo();&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
   }&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
   &lt;strong&gt;&lt;u&gt;All Done!&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   Creating modal dialogs with C# and .NET is not as complex as it might seem at first
   glance.&amp;nbsp; Well, ok - aquiring all this knowledge and information and putting it
   to use was harder than it should've been.&amp;nbsp; But now it's all in one place.&amp;nbsp;
   Comments and suggestions are welcome.&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=1f4d51ae-510d-4a9f-a85e-d1720c3258e7" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,1f4d51ae-510d-4a9f-a85e-d1720c3258e7.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=434bd3b1-f442-4707-94c5-b812ab194d2b</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,434bd3b1-f442-4707-94c5-b812ab194d2b.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,434bd3b1-f442-4707-94c5-b812ab194d2b.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=434bd3b1-f442-4707-94c5-b812ab194d2b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.lhotka.net">Rockford Lhotka </a>has posted a very nice article
      on some <a href="http://www.lhotka.net/weblog/SemanticCouplingTheElephantInTheSOARoom.aspx">tough
      issues with SOA</a>.  Please read the post and then check my thoughts
      below:
   </p>
        <p>
      Very well written.  I have a question, though.  If we need to perform the
      follwing actions - trigger invoicing, contact the customer, print pick lists, and
      update the customer's sales history - why would we call a service that *might* do
      these actions.
   </p>
        <p>
      Wait, I think I can answer this one myself.  You are talking about systems that
      are already in place, have been for quite some time, and have evolved to do these
      things.  Then people start using the service and either need something else done
      or don't need all the "services" the object provides.  
   </p>
        <p>
      This is a very common problem and is certainly not limited to SOA.  All developers
      have had to fix "established" code that has these problems.  What you end up
      with is code that resembles a ball of twine and you're darned lucky if it doesn't
      have more than a few knots inside.
   </p>
        <p>
      How do you solve the problem?  Some would say to force the service objects to
      perform one and only one service.  This is all well and good.  But then
      you hit the overhead problem you so very well described.
   </p>
        <p>
      What I have determined is this.  Each application has a purpose and needs "services"
      performed.  Other applications may need similar services.  But the second
      you decide to combine the services provided to both applications into one object,
      you open the door to unexpected behavior.  Heck, sometimes (usually) even the
      same application needs a service to behave differently for various situations.<br /></p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=434bd3b1-f442-4707-94c5-b812ab194d2b" />
      </body>
      <title>SOA Semanting Coupling</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,434bd3b1-f442-4707-94c5-b812ab194d2b.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,434bd3b1-f442-4707-94c5-b812ab194d2b.aspx</link>
      <pubDate>Tue, 10 Oct 2006 15:59:16 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;a href="http://www.lhotka.net"&gt;Rockford Lhotka &lt;/a&gt;has posted a very nice article
   on&amp;nbsp;some&amp;nbsp;&lt;a href="http://www.lhotka.net/weblog/SemanticCouplingTheElephantInTheSOARoom.aspx"&gt;tough
   issues with&amp;nbsp;SOA&lt;/a&gt;.&amp;nbsp; Please read the post&amp;nbsp;and then check&amp;nbsp;my thoughts
   below:
&lt;/p&gt;
&lt;p&gt;
   Very well written.&amp;nbsp; I have a question, though.&amp;nbsp; If we need to perform the
   follwing actions - trigger invoicing, contact the customer, print pick lists, and
   update the customer's sales history - why would we call a service that *might* do
   these actions.
&lt;/p&gt;
&lt;p&gt;
   Wait, I think I can answer this one myself.&amp;nbsp; You are talking about systems that
   are already in place, have been for quite some time, and have evolved to do these
   things.&amp;nbsp; Then people start using the service and either need something else done
   or don't need all the "services" the object provides.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
   This is a very common problem and is certainly not limited to SOA.&amp;nbsp; All developers
   have had to fix "established" code that has these problems.&amp;nbsp; What you end up
   with is code that resembles a ball of twine and you're darned lucky if it doesn't
   have more than a few knots inside.
&lt;/p&gt;
&lt;p&gt;
   How do you solve the problem?&amp;nbsp; Some would say to force the service objects to
   perform one and only one service.&amp;nbsp; This is all well and good.&amp;nbsp; But then
   you hit the overhead problem you so very well described.
&lt;/p&gt;
&lt;p&gt;
   What I have determined is this.&amp;nbsp; Each application has a purpose and needs "services"
   performed.&amp;nbsp; Other applications may need similar services.&amp;nbsp; But the second
   you decide to combine the services provided to both applications into one object,
   you open the door to unexpected behavior.&amp;nbsp; Heck, sometimes (usually) even the
   same application needs a service to behave differently for various situations.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=434bd3b1-f442-4707-94c5-b812ab194d2b" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,434bd3b1-f442-4707-94c5-b812ab194d2b.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=c46a70de-b49d-4995-b00a-1c4d2785f0fd</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,c46a70de-b49d-4995-b00a-1c4d2785f0fd.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,c46a70de-b49d-4995-b00a-1c4d2785f0fd.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=c46a70de-b49d-4995-b00a-1c4d2785f0fd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Ever need to open a modal dialog in a web application?  Unless you've only written
      the simplest of applications, then the answer is a resounding "YES!"  There is
      certainly more than one way to accomplish this.  But this particular answer suited
      my needs perfectly.
   </p>
        <p>
      What I needed:  Display a list of items for the user to choose in a modal window. 
      If the item they require is not available, then allow them to add the item, with extra
      details.  In this case the item represents a company, and the extra details are
      the company address, phone numbers, fax, notes, etc.  Sounds easy enough.  
   </p>
        <p>
      There were two problems, though.    
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <strong>
              <u>Modal Form Opens a Blank Window</u>
            </strong>
            <br />
      Closing the window causes another - blank - window to open in it's place.  Weird
      but easily solvable.  Simply place this code in the &lt;HEAD&gt; section of the
      modal form:<br />
      &lt;base <font color="#ff0000">target</font>="<font color="#0000ff">_self</font>"&gt;<br />
      Now the the blank window is no longer opened.  
   </p>
          <p>
            <strong>
              <u>The Modal Window is Cached!</u>
            </strong>
            <br />
      The content of the window is cached on the server.  So when it is opened for
      the second time, the Page_Load event is not fired.  The problem for me was that
      the contents of the combo box were not refilled, so any new companies that were added
      manually weren't reflected in the list!  I saw a multitude of answers while searching,
      but this one seemed to make more sense to me than the others.  In the declarations
      section of the form (very top of the HTML code) enter the following line:<br /><span style="BACKGROUND-COLOR: yellow">&lt;%@ OutputCache Location="None" VaryByParam="None"
      %&gt;</span></p>
          <p>
      I should mention that I <em>did</em> find numerous other answers to the caching problem
      that I did not try.  If the above answer doesn't fit your situation, you might
      try some of these:
   </p>
          <p>
      add this to the modal window's page_load: 
      <br />
      Response.Expires = 0; 
      <br />
      Response.Cache.SetNoStore(); 
      <br />
      Response.AppendHeader("Pragma", "no-cache"); 
   </p>
          <p>
      Or this:<br />
      Response.Cache.SetNoStore(); 
      <br />
      Response.Cache.SetExpires(DateTime.Now.AddMilliseconds(-500)); 
      <br />
      Response.Cache.SetCacheability(HttpCacheability.NoCache); 
      <br />
      Response.AppendHeader("Pragma", "no-cache"); 
   </p>
          <p>
      Or any combination of the above.  I did not require any code in the page_load
      method.
   </p>
        </blockquote>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=c46a70de-b49d-4995-b00a-1c4d2785f0fd" />
      </body>
      <title>Modal Dialogs in ASP.NET 1.1</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,c46a70de-b49d-4995-b00a-1c4d2785f0fd.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,c46a70de-b49d-4995-b00a-1c4d2785f0fd.aspx</link>
      <pubDate>Mon, 18 Sep 2006 13:46:38 GMT</pubDate>
      <description>&lt;p&gt;
   Ever need to open a modal dialog in a web application?&amp;nbsp; Unless you've only written
   the simplest of applications, then the answer is a resounding "YES!"&amp;nbsp; There is
   certainly more than one way to accomplish this.&amp;nbsp; But this particular answer suited
   my needs perfectly.
&lt;/p&gt;
&lt;p&gt;
   What I needed:&amp;nbsp; Display a list of items for the user to choose in a modal window.&amp;nbsp;
   If the item they require is not available, then allow them to add the item, with extra
   details.&amp;nbsp; In this case the item represents a company, and the extra details are
   the company address, phone numbers, fax, notes, etc.&amp;nbsp; Sounds easy enough.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
   There were two problems, though.&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
   &lt;strong&gt;&lt;u&gt;Modal Form Opens a Blank Window&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   Closing the window causes another - blank - window to open in it's place.&amp;nbsp; Weird
   but easily solvable.&amp;nbsp; Simply place this code in the &amp;lt;HEAD&amp;gt; section of the
   modal form:&lt;br&gt;
   &amp;lt;base &lt;font color=#ff0000&gt;target&lt;/font&gt;="&lt;font color=#0000ff&gt;_self&lt;/font&gt;"&amp;gt;&lt;br&gt;
   Now the the blank window is no longer opened.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
   &lt;strong&gt;&lt;u&gt;The Modal Window is Cached!&lt;/u&gt;&lt;/strong&gt;
   &lt;br&gt;
   The content of the window is cached on the server.&amp;nbsp; So when it is opened for
   the second time, the Page_Load event is not fired.&amp;nbsp; The problem for me was that
   the contents of the combo box were not refilled, so any new companies that were added
   manually weren't reflected in the list!&amp;nbsp; I saw a multitude of answers while searching,
   but this one seemed to make more sense to me than the others.&amp;nbsp; In the declarations
   section of the form (very top of the&amp;nbsp;HTML code)&amp;nbsp;enter the following line:&lt;br&gt;
   &lt;span style="BACKGROUND-COLOR: yellow"&gt;&amp;lt;%@ OutputCache Location="None" VaryByParam="None"
   %&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   I should mention that I &lt;em&gt;did&lt;/em&gt; find numerous other answers to the caching problem
   that I did not try.&amp;nbsp; If the above answer doesn't fit your situation, you might
   try some of these:
&lt;/p&gt;
&lt;p&gt;
   add this to the modal window's page_load: 
   &lt;br&gt;
   Response.Expires = 0; 
   &lt;br&gt;
   Response.Cache.SetNoStore(); 
   &lt;br&gt;
   Response.AppendHeader("Pragma", "no-cache"); 
&lt;/p&gt;
&lt;p&gt;
   Or this:&lt;br&gt;
   Response.Cache.SetNoStore(); 
   &lt;br&gt;
   Response.Cache.SetExpires(DateTime.Now.AddMilliseconds(-500)); 
   &lt;br&gt;
   Response.Cache.SetCacheability(HttpCacheability.NoCache); 
   &lt;br&gt;
   Response.AppendHeader("Pragma", "no-cache"); 
&lt;/p&gt;
&lt;p&gt;
   Or any combination of the above.&amp;nbsp; I did not require any code in the page_load
   method.
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=c46a70de-b49d-4995-b00a-1c4d2785f0fd" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,c46a70de-b49d-4995-b00a-1c4d2785f0fd.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=d87d73b1-4875-48ed-b10e-cc5347a31780</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,d87d73b1-4875-48ed-b10e-cc5347a31780.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,d87d73b1-4875-48ed-b10e-cc5347a31780.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=d87d73b1-4875-48ed-b10e-cc5347a31780</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">In my last <a href="http://www.bpsvc.com/devblog/PermaLink,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx">post</a>,
   I showed you how to navigate a self-joined table to create a list of primary keys. 
   Now I will show you how to put the code into a UDF to return the list.<br /><br />
   It is quite easy to create a User Defined Function that will return table variable. 
   Using the information from the last post, here is the setup.  Note that the table
   is defined right in the RETURN definition:<br /><br /><font color="#0000ff">CREATE FUNCTION </font>dbo.udf_BookingCommodityList<br />
   (<br />
       @BookingId <font color="#0000ff">int</font><br />
   ) 
   <br /><font color="#0000ff">RETURNS </font>@CommodityIdList <font color="#0000ff">TABLE </font>(<br />
       BookingCommodityId <font color="#0000ff">int </font>) 
   <br /><font color="#0000ff">AS  
   <br />
   BEGIN </font><br />
   &lt;... Rest of function &gt;<br /><br />
   The cool thing about this is that, with the table defined in the RETURN definition,
   we can use it throughout the UDF as though we created it with a normal DECLARE statement.<br /><br />
   So now that a table of primary keys is being returned, how can it be used.  Well
   it turns out that the UDF acts almost just like any other table in SQL Server. 
   For example, this statement works just fine:  <font color="#0000ff">SELECT </font>* <font color="#0000ff">FROM </font>dbo.udf_BookingCommodityList(12345). 
   This will return all the commodity ids for booking number 12345.<br /><br />
   Using the UDF in a statement is pretty straight forward:<br /><br /><font color="#808080">-- @BookingId is passed in as a parameter</font><br /><font color="#0000ff">SELECT </font>commodity.Description<br /><font color="#0000ff">FROM </font>dbo.udf_BookingCommodityList(@BookingId) bc 
   <br /><font color="#0000ff"> INNER JOIN</font> Commodity <font color="#0000ff">ON </font>(Commodity.BookingCommodityId
   = bc.BookingCommodityId)<br /><br />
   This returns the commodity descriptions used on the booking.  This is great as
   long as the BookingId is known in advance (i.e. passed in as a parameter or derived
   in some other fashion; cursors, etc.).<br /><br />
   This statement <i><b>does not</b></i> work to my dismay.  I haven't figured out
   why just yet.<br /><br /><font color="#0000ff">SELECT </font>commodity.Description<br /><font color="#0000ff">FROM <font color="#000000">Booking</font><br /></font><font color="#0000ff"> INNER JOIN </font>dbo.udf_BookingCommodityList(Booking.BookingId)
   bc 
   <br /><font color="#0000ff"> INNER JOIN</font> Commodity <font color="#0000ff">ON </font>(Commodity.BookingCommodityId
   = bc.BookingCommodityId)<br /><font color="#0000ff">WHERE </font>Booking.BookingId = 12345<br /><img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=d87d73b1-4875-48ed-b10e-cc5347a31780" /></body>
      <title>UDF Returns Table Variables - Cool!</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,d87d73b1-4875-48ed-b10e-cc5347a31780.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,d87d73b1-4875-48ed-b10e-cc5347a31780.aspx</link>
      <pubDate>Mon, 13 Mar 2006 18:51:28 GMT</pubDate>
      <description>In my last &lt;a href="http://www.bpsvc.com/devblog/PermaLink,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx"&gt;post&lt;/a&gt;,
I showed you how to navigate a self-joined table to create a list of primary keys.&amp;nbsp;
Now I will show you how to put the code into a UDF to return the list.&lt;br&gt;
&lt;br&gt;
It is quite easy to create a User Defined Function that will return table variable.&amp;nbsp;
Using the information from the last post, here is the setup.&amp;nbsp; Note that the table
is defined right in the RETURN definition:&lt;br&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;CREATE FUNCTION &lt;/font&gt;dbo.udf_BookingCommodityList&lt;br&gt;
(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; @BookingId &lt;font color="#0000ff"&gt;int&lt;/font&gt;
&lt;br&gt;
) 
&lt;br&gt;
&lt;font color="#0000ff"&gt;RETURNS &lt;/font&gt;@CommodityIdList &lt;font color="#0000ff"&gt;TABLE &lt;/font&gt;(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; BookingCommodityId &lt;font color="#0000ff"&gt;int &lt;/font&gt;) 
&lt;br&gt;
&lt;font color="#0000ff"&gt;AS&amp;nbsp; 
&lt;br&gt;
BEGIN &lt;/font&gt;
&lt;br&gt;
&amp;lt;... Rest of function &amp;gt;&lt;br&gt;
&lt;br&gt;
The cool thing about this is that, with the table defined in the RETURN definition,
we can use it throughout the UDF as though we created it with a normal DECLARE statement.&lt;br&gt;
&lt;br&gt;
So now that a table of primary keys is being returned, how can it be used.&amp;nbsp; Well
it turns out that the UDF acts almost just like any other table in SQL Server.&amp;nbsp;
For example, this statement works just fine:&amp;nbsp; &lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;* &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;dbo.udf_BookingCommodityList(12345).&amp;nbsp;
This will return all the commodity ids for booking number 12345.&lt;br&gt;
&lt;br&gt;
Using the UDF in a statement is pretty straight forward:&lt;br&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;-- @BookingId is passed in as a parameter&lt;/font&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;commodity.Description&lt;br&gt;
&lt;font color="#0000ff"&gt;FROM &lt;/font&gt;dbo.udf_BookingCommodityList(@BookingId) bc 
&lt;br&gt;
&lt;font color="#0000ff"&gt; INNER JOIN&lt;/font&gt; Commodity &lt;font color="#0000ff"&gt;ON &lt;/font&gt;(Commodity.BookingCommodityId
= bc.BookingCommodityId)&lt;br&gt;
&lt;br&gt;
This returns the commodity descriptions used on the booking.&amp;nbsp; This is great as
long as the BookingId is known in advance (i.e. passed in as a parameter or derived
in some other fashion; cursors, etc.).&lt;br&gt;
&lt;br&gt;
This statement &lt;i&gt;&lt;b&gt;does not&lt;/b&gt;&lt;/i&gt; work to my dismay.&amp;nbsp; I haven't figured out
why just yet.&lt;br&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;commodity.Description&lt;br&gt;
&lt;font color="#0000ff"&gt;FROM &lt;font color="#000000"&gt;Booking&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt; INNER JOIN &lt;/font&gt;dbo.udf_BookingCommodityList(Booking.BookingId)
bc 
&lt;br&gt;
&lt;font color="#0000ff"&gt; INNER JOIN&lt;/font&gt; Commodity &lt;font color="#0000ff"&gt;ON &lt;/font&gt;(Commodity.BookingCommodityId
= bc.BookingCommodityId)&lt;br&gt;
&lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;Booking.BookingId = 12345&lt;br&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=d87d73b1-4875-48ed-b10e-cc5347a31780" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,d87d73b1-4875-48ed-b10e-cc5347a31780.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=aac53303-5006-4d69-8740-b96a30ea8c7e</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=aac53303-5006-4d69-8740-b96a30ea8c7e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <b>Situation:</b>
        <br />
   I have a SQL Table that is self linking.  Records act as parent and child. 
   In this case, it is for a packaging system where it is possible to have multiple packages
   containing a commodity (product).  For example, a pallet containing 50 boxes,
   each box contains 24 bags of potato chips.  The application allows for an unlimited
   number of package to package relationships.<br /><br />
   Here's a sample diagram from SQL Server.<br /><br /><p></p><img src="content/binary/SelfJoin.JPG" border="0" /><br /><b><br />
   Problem:</b><br />
   The customer requires a report where only the commodity is displayed.  The commodity
   may be burried very deep in the chain of packages.  And because the commodity
   is only aware of the immediate package above it (using the example above, the boxes),
   getting to the commodity can be difficult.  To help illustrate, here's a perfectly
   valid example from the application.<br /><br /><br /><img src="http://www.bpsvc.com/devblog/content/binary/SelfJoinApp.JPG" border="0" /><br /><br />
   This is a very complex pallet to say the least.  Probably one that would never
   happen, but it is still "valid" as far as the application is concerned. 
   <br /><br />
   The report requirements state that, given the CargoLineId (represented by the green
   ball, pallet), list the commodities.  The report is not interested in displaying
   any details about the packaging.<br /><br /><b>Solution:</b><br />
   Using the self-join of table BookingPackage we can determine the immediate children
   of each record.  The child package will have a ParentBookingPackageId that matches
   the parent BookingPackageId.  Each package may or may not contain a commodity. 
   What we must do is walk our way down the tree of packages to get to the commodities.<br /><br />
   The solution presented here could be used differently depending on the solution required. 
   Use the example as a guide and change it to suit your particular needs.<br /><br />
   Here is the code in T-SQL:<br /><font color="#808080">/* 
   <br />
   Create a temporary table to hold all PackageIds.<br />
   */<br /></font><font color="#0000ff">DECLARE </font>@PackageIdList <font color="#0000ff">TABLE </font>(<br />
       PackageId <font color="#0000ff">int </font>)<br /><br /><font color="#808080">/*<br />
   Create a temporary table to hold the CommodityLineIds.<br />
   This table eventually contains every Commodity attached<br />
   to the booking and is used as the result set.<br />
   */<br /></font><font color="#0000ff">DECLARE </font>@CommodityIdList <font color="#0000ff">TABLE </font>(<br />
       CommodityLineId <font color="#0000ff">int </font>)<br /><br /><font color="#808080">/*<br />
   Insert the top level packages<br />
   @BookingId is passed in as a parameter<br />
   */<br /><font color="#0000ff">I</font></font><font color="#0000ff">NSERT INTO</font> @PackageIdList<br /><font color="#0000ff">SELECT </font>BookingPackageId<br /><font color="#0000ff">FROM </font>BookingPackage pkg<br />
       <font color="#0000ff">INNER JOIN</font> BookingCargoLine cargo <font color="#0000ff">on</font> (cargo.BookingCargoLineId
   = pkg.BookingCargoLineId)<br /><font color="#0000ff">WHERE</font><br />
       cargo.BookingId = @BookingId<br /><br /><font color="#808080">/*<br />
   Get a count of second level packages<br />
   */<br /></font><font color="#0000ff">DECLARE </font>@pkgCount <font color="#0000ff">int</font><br /><font color="#0000ff">SET </font>@pkgCount = (<br />
       <font color="#0000ff">SELECT COUNT</font>(BookingPackage.BookingPackageId)<br /><font color="#0000ff">    FROM </font>BookingPackage<br />
       <font color="#0000ff">INNER JOIN</font> @PackageIdList list <font color="#0000ff">on</font> (list.PackageId
   = BookingPackage.ParentBookingPackageId)<br />
       <font color="#0000ff">WHERE </font>BookingPackage.BookingPackageId <font color="#0000ff">NOT
   IN</font> (<font color="#0000ff">SELECT </font>PackageId <font color="#0000ff">FROM </font>@PackageIdList)<br />
       )<br /><br /><font color="#0000ff">WHILE </font>@pkgCount &gt; 0<br /><font color="#0000ff">BEGIN</font><br /><font color="#808080">    /*<br />
       Insert the package list into the temporary Package table<br />
       If the PackageId is already collected into the temporary table,<br />
       do not add it.<br />
       With each pass, sub-packages are added to the list.<br />
       */<br /></font>    <font color="#0000ff">INSERT INTO </font>@PackageIdList<br />
       <font color="#0000ff">SELECT </font>BookingPackage.BookingPackageId<br />
       <font color="#0000ff">FROM </font>BookingPackage<br />
       <font color="#0000ff">INNER JOIN </font>@PackageIdList list <font color="#0000ff">on </font>(list.PackageId
   = BookingPackage.ParentBookingPackageId)<br />
       <font color="#0000ff">WHERE </font>BookingPackage.BookingPackageId <font color="#0000ff">NOT
   IN</font> (<font color="#0000ff">SELECT </font>PackageId <font color="#0000ff">FROM </font>@PackageIdList)<br /><br /><font color="#808080">    /*<br />
       We just added packages to the list, check to see if there are more
   to add.<br />
       Eventually, we will get to the lowest level of sub-packages and<br />
       the count will be zero; ending the WHILE loop.<br />
       */<br /></font>    <font color="#0000ff">SET </font>@pkgCount = (<br />
           <font color="#0000ff">SELECT COUNT</font>(BookingPackage.BookingPackageId)<br />
           <font color="#0000ff">FROM </font>BookingPackage<br />
           <font color="#0000ff">INNER JOIN </font>@PackageIdList
   list <font color="#0000ff">on </font>(list.PackageId = BookingPackage.ParentBookingPackageId)<br />
           <font color="#0000ff">WHERE </font>BookingPackage.BookingPackageId <font color="#0000ff">NOT
   IN </font>(<font color="#0000ff">SELECT </font>PackageId <font color="#0000ff">FROM </font>@PackageIdList)<br />
           )<br /><font color="#0000ff">END</font><br /><br /><font color="#808080">/*<br />
   Now that we have a list packages, we can derive the 
   <br />
   Commodities that belong to each one.<br />
   */<br /></font><font color="#0000ff">INSERT INTO</font> @CommodityIdList<br /><font color="#0000ff">SELECT </font>BookingCommodityId<br /><font color="#0000ff">FROM </font>BookingCommodity<br /><font color="#0000ff">WHERE </font>BookingPackageId <font color="#0000ff">IN </font>(<font color="#0000ff">SELECT </font>PackageId <font color="#0000ff">FROM </font>@PackageIdList)<br /><font color="#808080">/*<br />
   Now we have a table of commodities that we can use in the rest of 
   <br />
   the procedure as a joining table to retrieve the commodity details<br />
   for the report.<br />
   */<br /></font>*** END OF T-SQL<br /><br />
   The secret to this working is the WHILE loop and the table @PackageIdList being used
   as a filter to determine the depth of the package tree.  We are inserting into
   the @PackageIdList table and, at the same time, using it as an inner join for parent
   packages.  The where clause is used to make sure we don't pump duplicate values
   into the table.<br /><br />
       <font color="#0000ff">INSERT INTO </font>@PackageIdList<br />
       <font color="#0000ff">SELECT </font>BookingPackage.BookingPackageId<br />
       <font color="#0000ff">FROM </font>BookingPackage<br />
       <font color="#0000ff">INNER JOIN </font>@PackageIdList list <font color="#0000ff">on </font>(list.PackageId
   = BookingPackage.ParentBookingPackageId)<br />
       <font color="#0000ff">WHERE </font>BookingPackage.BookingPackageId <font color="#0000ff">NOT
   IN</font> (<font color="#0000ff">SELECT </font>PackageId <font color="#0000ff">FROM </font>@PackageIdList)<br /><br />
   The final step is to fill a table variable, @CommodityIdList, with the list of commodity
   ids belonging to the main cargo line, or package.<br /><br /><font color="#0000ff">     INSERT INTO</font> @CommodityIdList<br />
        <font color="#0000ff">SELECT </font>BookingCommodityId<br />
        <font color="#0000ff">FROM </font>BookingCommodity<br />
        <font color="#0000ff">WHERE </font>BookingPackageId <font color="#0000ff">IN </font>(<font color="#0000ff">SELECT </font>PackageId <font color="#0000ff">FROM </font>@PackageIdList)<br /><br />
   If we wanted, we could have put a lot more information into this table.  I decided
   to use it as a joining table to get the details I need later on in the procedure.<br /><br /><b>Conclusion:</b><br />
   We end up with a result that mirrors recursion in T-SQL.  We didn't have to use
   cursors or extra procedures to make it work.  Now, if we were only using SQL
   Server 2005, we could achieve the same result with one statement using the WITH clause. 
   I'll find a good example and post on that next.<br /><img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=aac53303-5006-4d69-8740-b96a30ea8c7e" /></body>
      <title>Recursive Join in SQL 2000</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx</link>
      <pubDate>Wed, 08 Mar 2006 21:34:11 GMT</pubDate>
      <description>&lt;b&gt;Situation:&lt;/b&gt;
&lt;br&gt;
I have a SQL Table that is self linking.&amp;nbsp; Records act as parent and child.&amp;nbsp;
In this case, it is for a packaging system where it is possible to have multiple packages
containing a commodity (product).&amp;nbsp; For example, a pallet containing 50 boxes,
each box contains 24 bags of potato chips.&amp;nbsp; The application allows for an unlimited
number of package to package relationships.&lt;br&gt;
&lt;br&gt;
Here's a sample diagram from SQL Server.&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img src="content/binary/SelfJoin.JPG" border="0"&gt;
&lt;br&gt;
&lt;b&gt;
&lt;br&gt;
Problem:&lt;/b&gt;
&lt;br&gt;
The customer requires a report where only the commodity is displayed.&amp;nbsp; The commodity
may be burried very deep in the chain of packages.&amp;nbsp; And because the commodity
is only aware of the immediate package above it (using the example above, the boxes),
getting to the commodity can be difficult.&amp;nbsp; To help illustrate, here's a perfectly
valid example from the application.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;img src="http://www.bpsvc.com/devblog/content/binary/SelfJoinApp.JPG" border="0"&gt;
&lt;br&gt;
&lt;br&gt;
This is a very complex pallet to say the least.&amp;nbsp; Probably one that would never
happen, but it is still "valid" as far as the application is concerned. 
&lt;br&gt;
&lt;br&gt;
The report requirements state that, given the CargoLineId (represented by the green
ball, pallet), list the commodities.&amp;nbsp; The report is not interested in displaying
any details about the packaging.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Solution:&lt;/b&gt;
&lt;br&gt;
Using the self-join of table BookingPackage we can determine the immediate children
of each record.&amp;nbsp; The child package will have a ParentBookingPackageId that matches
the parent BookingPackageId.&amp;nbsp; Each package may or may not contain a commodity.&amp;nbsp;
What we must do is walk our way down the tree of packages to get to the commodities.&lt;br&gt;
&lt;br&gt;
The solution presented here could be used differently depending on the solution required.&amp;nbsp;
Use the example as a guide and change it to suit your particular needs.&lt;br&gt;
&lt;br&gt;
Here is the code in T-SQL:&lt;br&gt;
&lt;font color="#808080"&gt;/* 
&lt;br&gt;
Create a temporary table to hold all PackageIds.&lt;br&gt;
*/&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;DECLARE &lt;/font&gt;@PackageIdList &lt;font color="#0000ff"&gt;TABLE &lt;/font&gt;(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; PackageId &lt;font color="#0000ff"&gt;int &lt;/font&gt;)&lt;br&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;/*&lt;br&gt;
Create a temporary table to hold the CommodityLineIds.&lt;br&gt;
This table eventually contains every Commodity attached&lt;br&gt;
to the booking and is used as the result set.&lt;br&gt;
*/&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;DECLARE &lt;/font&gt;@CommodityIdList &lt;font color="#0000ff"&gt;TABLE &lt;/font&gt;(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; CommodityLineId &lt;font color="#0000ff"&gt;int &lt;/font&gt;)&lt;br&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;/*&lt;br&gt;
Insert the top level packages&lt;br&gt;
@BookingId is passed in as a parameter&lt;br&gt;
*/&lt;br&gt;
&lt;font color="#0000ff"&gt;I&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;NSERT INTO&lt;/font&gt; @PackageIdList&lt;br&gt;
&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;BookingPackageId&lt;br&gt;
&lt;font color="#0000ff"&gt;FROM &lt;/font&gt;BookingPackage pkg&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INNER JOIN&lt;/font&gt; BookingCargoLine cargo &lt;font color="#0000ff"&gt;on&lt;/font&gt; (cargo.BookingCargoLineId
= pkg.BookingCargoLineId)&lt;br&gt;
&lt;font color="#0000ff"&gt;WHERE&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cargo.BookingId = @BookingId&lt;br&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;/*&lt;br&gt;
Get a count of second level packages&lt;br&gt;
*/&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;DECLARE &lt;/font&gt;@pkgCount &lt;font color="#0000ff"&gt;int&lt;/font&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;SET &lt;/font&gt;@pkgCount = (&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;SELECT COUNT&lt;/font&gt;(BookingPackage.BookingPackageId)&lt;br&gt;
&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM &lt;/font&gt;BookingPackage&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INNER JOIN&lt;/font&gt; @PackageIdList list &lt;font color="#0000ff"&gt;on&lt;/font&gt; (list.PackageId
= BookingPackage.ParentBookingPackageId)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;BookingPackage.BookingPackageId &lt;font color="#0000ff"&gt;NOT
IN&lt;/font&gt; (&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;PackageId &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;@PackageIdList)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;WHILE &lt;/font&gt;@pkgCount &amp;gt; 0&lt;br&gt;
&lt;font color="#0000ff"&gt;BEGIN&lt;/font&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Insert the package list into the temporary Package table&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; If the PackageId is already collected into the temporary table,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; do not add it.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; With each pass, sub-packages are added to the list.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INSERT INTO &lt;/font&gt;@PackageIdList&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;BookingPackage.BookingPackageId&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;BookingPackage&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INNER JOIN &lt;/font&gt;@PackageIdList list &lt;font color="#0000ff"&gt;on &lt;/font&gt;(list.PackageId
= BookingPackage.ParentBookingPackageId)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;BookingPackage.BookingPackageId &lt;font color="#0000ff"&gt;NOT
IN&lt;/font&gt; (&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;PackageId &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;@PackageIdList)&lt;br&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; We just added packages to the list, check to see if there are more
to add.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Eventually, we will get to the lowest level of sub-packages and&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; the count will be zero; ending the WHILE loop.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;SET &lt;/font&gt;@pkgCount = (&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;SELECT COUNT&lt;/font&gt;(BookingPackage.BookingPackageId)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;BookingPackage&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INNER JOIN &lt;/font&gt;@PackageIdList
list &lt;font color="#0000ff"&gt;on &lt;/font&gt;(list.PackageId = BookingPackage.ParentBookingPackageId)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;BookingPackage.BookingPackageId &lt;font color="#0000ff"&gt;NOT
IN &lt;/font&gt;(&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;PackageId &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;@PackageIdList)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;
&lt;font color="#0000ff"&gt;END&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
&lt;font color="#808080"&gt;/*&lt;br&gt;
Now that we have a list packages, we can derive the 
&lt;br&gt;
Commodities that belong to each one.&lt;br&gt;
*/&lt;br&gt;
&lt;/font&gt;&lt;font color="#0000ff"&gt;INSERT INTO&lt;/font&gt; @CommodityIdList&lt;br&gt;
&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;BookingCommodityId&lt;br&gt;
&lt;font color="#0000ff"&gt;FROM &lt;/font&gt;BookingCommodity&lt;br&gt;
&lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;BookingPackageId &lt;font color="#0000ff"&gt;IN &lt;/font&gt;(&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;PackageId &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;@PackageIdList)&lt;br&gt;
&lt;font color="#808080"&gt;/*&lt;br&gt;
Now we have a table of commodities that we can use in the rest of 
&lt;br&gt;
the procedure as a joining table to retrieve the commodity details&lt;br&gt;
for the report.&lt;br&gt;
*/&lt;br&gt;
&lt;/font&gt;*** END OF T-SQL&lt;br&gt;
&lt;br&gt;
The secret to this working is the WHILE loop and the table @PackageIdList being used
as a filter to determine the depth of the package tree.&amp;nbsp; We are inserting into
the @PackageIdList table and, at the same time, using it as an inner join for parent
packages.&amp;nbsp; The where clause is used to make sure we don't pump duplicate values
into the table.&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INSERT INTO &lt;/font&gt;@PackageIdList&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;BookingPackage.BookingPackageId&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;BookingPackage&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;INNER JOIN &lt;/font&gt;@PackageIdList list &lt;font color="#0000ff"&gt;on &lt;/font&gt;(list.PackageId
= BookingPackage.ParentBookingPackageId)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;BookingPackage.BookingPackageId &lt;font color="#0000ff"&gt;NOT
IN&lt;/font&gt; (&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;PackageId &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;@PackageIdList)&lt;br&gt;
&lt;br&gt;
The final step is to fill a table variable, @CommodityIdList, with the list of commodity
ids belonging to the main cargo line, or package.&lt;br&gt;
&lt;br&gt;
&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT INTO&lt;/font&gt; @CommodityIdList&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;BookingCommodityId&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;BookingCommodity&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;font color="#0000ff"&gt;WHERE &lt;/font&gt;BookingPackageId &lt;font color="#0000ff"&gt;IN &lt;/font&gt;(&lt;font color="#0000ff"&gt;SELECT &lt;/font&gt;PackageId &lt;font color="#0000ff"&gt;FROM &lt;/font&gt;@PackageIdList)&lt;br&gt;
&lt;br&gt;
If we wanted, we could have put a lot more information into this table.&amp;nbsp; I decided
to use it as a joining table to get the details I need later on in the procedure.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Conclusion:&lt;/b&gt;
&lt;br&gt;
We end up with a result that mirrors recursion in T-SQL.&amp;nbsp; We didn't have to use
cursors or extra procedures to make it work.&amp;nbsp; Now, if we were only using SQL
Server 2005, we could achieve the same result with one statement using the WITH clause.&amp;nbsp;
I'll find a good example and post on that next.&lt;br&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=aac53303-5006-4d69-8740-b96a30ea8c7e" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,aac53303-5006-4d69-8740-b96a30ea8c7e.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=5bdab8fc-9a61-4d94-8af6-e322ea9dfb86</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,5bdab8fc-9a61-4d94-8af6-e322ea9dfb86.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,5bdab8fc-9a61-4d94-8af6-e322ea9dfb86.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=5bdab8fc-9a61-4d94-8af6-e322ea9dfb86</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I just read a very nice <a href="http://www.codeproject.com/useritems/ASPNET_Best_Practices.asp">article</a> on
      ASP.NET Best practices by Ali Khan.  It covers some items that most .NET developers
      should know by heart and others that we <em>do</em> know but sometimes forget.
   </p>
        <p>
      The only thing I can find to disagree with is tip number 15.  It talks about
      using stored procedures instead of "ad-hoc" queries.  The speed benefit of this
      approach has met skepticism lately by numerous developers.  I definitely fall
      into this category.  I prefer keeping the maintenance of queries outside of the
      database.
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=5bdab8fc-9a61-4d94-8af6-e322ea9dfb86" />
      </body>
      <title>ASP.NET General Info</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,5bdab8fc-9a61-4d94-8af6-e322ea9dfb86.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,5bdab8fc-9a61-4d94-8af6-e322ea9dfb86.aspx</link>
      <pubDate>Tue, 21 Feb 2006 14:28:07 GMT</pubDate>
      <description>&lt;p&gt;
   I just read a very nice &lt;a href="http://www.codeproject.com/useritems/ASPNET_Best_Practices.asp"&gt;article&lt;/a&gt;&amp;nbsp;on
   ASP.NET Best practices by Ali Khan.&amp;nbsp; It covers some items that most .NET developers
   should know by heart and others that we &lt;em&gt;do&lt;/em&gt; know but sometimes forget.
&lt;/p&gt;
&lt;p&gt;
   The only thing I can find to disagree with is tip number 15.&amp;nbsp; It talks about
   using stored procedures instead of "ad-hoc" queries.&amp;nbsp; The speed benefit of this
   approach has met skepticism lately by numerous developers.&amp;nbsp; I definitely fall
   into this category.&amp;nbsp; I prefer keeping the maintenance of queries outside of the
   database.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=5bdab8fc-9a61-4d94-8af6-e322ea9dfb86" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,5bdab8fc-9a61-4d94-8af6-e322ea9dfb86.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=05ad00e9-8742-43f9-867f-092b9f988a79</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,05ad00e9-8742-43f9-867f-092b9f988a79.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,05ad00e9-8742-43f9-867f-092b9f988a79.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=05ad00e9-8742-43f9-867f-092b9f988a79</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      So now you have a nice report written to an HTML file.  How do you open it for
      the user to view it using IE?  You could try this:
   </p>
        <p>
          <font face="Courier New" size="2">System.Diagnostics.Process.Start("iexplore.exe","MyReport.htm");</font>
        </p>
        <p>
      But this hasn't always worked for me.  Here is a sure fire way to put it all
      together. 
   </p>
        <p>
      Add a project reference to the COM library, Microsoft Internet Controls.  Add
      these two using statements:
   </p>
        <p>
          <font face="Courier New" size="2">
            <font color="#0000ff">using</font> SHDocVw;<br /><font color="#0000ff">using</font> System.Runtime.InteropServices;</font>
        </p>
        <p>
          <font face="Courier New" size="2">Where you need to open the browser, add the following
      code:</font>
        </p>
        <p>
          <font face="Courier New" size="2">explorer = <font color="#0000ff">new</font> InternetExplorer(); <br /><font color="#0000ff">if</font> (explorer != <font color="#0000ff">null</font>) <br />
      { <br />
           explorer.Visible = <font color="#0000ff">true</font>; <br />
           <font color="#0000ff">object</font> x = <font color="#0000ff">null</font>; 
      <br />
           explorer.Navigate(@"MyReport.htm</font>
          <font face="Courier New" size="2">", <font color="#0000ff">ref</font> x, <font color="#0000ff">ref</font> x, <font color="#0000ff">ref</font> x, <font color="#0000ff">ref</font> x); <br />
      } 
      <br /></font>
          <font face="Courier New" size="2">
          </font>
        </p>
        <p>
      Thanks to a good friend of mine, Micheal Beall of <a href="http://overdrivetech.com/">Overdrive
      Technologies</a>, for helping me with this.
   </p>
        <p>
      ***Originally posted on DotNetJunkies on February 16, 2005
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=05ad00e9-8742-43f9-867f-092b9f988a79" />
      </body>
      <title>Opening Internet Explorer Using C# Windows</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,05ad00e9-8742-43f9-867f-092b9f988a79.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,05ad00e9-8742-43f9-867f-092b9f988a79.aspx</link>
      <pubDate>Mon, 20 Feb 2006 19:10:49 GMT</pubDate>
      <description>&lt;p&gt;
   So now you have a nice report written to an HTML file.&amp;nbsp; How do you open it for
   the user to view it using IE?&amp;nbsp; You could try this:
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" size=2&gt;System.Diagnostics.Process.Start("iexplore.exe","MyReport.htm");&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   But this hasn't always worked for me.&amp;nbsp; Here is a sure fire way to put it all
   together. 
&lt;/p&gt;
&lt;p&gt;
   Add a project reference to the COM library, Microsoft Internet Controls.&amp;nbsp; Add
   these two using statements:
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" size=2&gt;&lt;font color=#0000ff&gt;using&lt;/font&gt; SHDocVw;&lt;br&gt;
   &lt;font color=#0000ff&gt;using&lt;/font&gt; System.Runtime.InteropServices;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" size=2&gt;Where you need to open the browser, add the following
   code:&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" size=2&gt;explorer = &lt;font color=#0000ff&gt;new&lt;/font&gt; InternetExplorer();&amp;nbsp;&lt;br&gt;
   &lt;font color=#0000ff&gt;if&lt;/font&gt; (explorer != &lt;font color=#0000ff&gt;null&lt;/font&gt;)&amp;nbsp;&lt;br&gt;
   {&amp;nbsp;&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; explorer.Visible = &lt;font color=#0000ff&gt;true&lt;/font&gt;;&amp;nbsp;&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;object&lt;/font&gt; x = &lt;font color=#0000ff&gt;null&lt;/font&gt;; 
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; explorer.Navigate(@"MyReport.htm&lt;/font&gt;&lt;font face="Courier New" size=2&gt;", &lt;font color=#0000ff&gt;ref&lt;/font&gt; x, &lt;font color=#0000ff&gt;ref&lt;/font&gt; x, &lt;font color=#0000ff&gt;ref&lt;/font&gt; x, &lt;font color=#0000ff&gt;ref&lt;/font&gt; x);&amp;nbsp;&lt;br&gt;
   } 
   &lt;br&gt;
   &lt;/font&gt;&lt;font face="Courier New" size=2&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   Thanks to a good friend of mine, Micheal Beall of &lt;a href="http://overdrivetech.com/"&gt;Overdrive
   Technologies&lt;/a&gt;, for helping me with this.
&lt;/p&gt;
&lt;p&gt;
   ***Originally posted on DotNetJunkies on February 16, 2005
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=05ad00e9-8742-43f9-867f-092b9f988a79" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,05ad00e9-8742-43f9-867f-092b9f988a79.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=846996b5-a1da-4da0-a874-603076177392</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,846996b5-a1da-4da0-a874-603076177392.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,846996b5-a1da-4da0-a874-603076177392.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=846996b5-a1da-4da0-a874-603076177392</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Printing a web page that represents a report has been difficult for me in the past. 
      I want to print a header and/or a footer that repeats on every printed page. 
      The screen version certainly isn't paginated, so how can you print a good looking
      report?  Style (or CSS) to the rescue.  
   </p>
        <p>
      Put the following Style tag, or something similar, in the header of the page.
   </p>
        <p>
          <font face="Courier New" size="2">
            <font color="#0000ff">&lt;</font>STYLE <font color="#ff0000">TYPE</font>=”<font color="#0000ff">text/css</font>” <font color="#ff0000">MEDIA</font>=”<font color="#0000ff">screen,
      print</font>”<font color="#0000ff">&gt;</font><br /><font color="#0000ff">&lt;!--<br /></font>TABLE {<br /><font color="#0000ff">  table-layout: fixed;<br />
        border: 0;<br />
        cellspacing: 1;<br />
        cellpadding: 1;<br />
        font-family: Arial;<br />
        font-size: 8pt;<br /></font>  }<br />
      TH {<br /><font color="#0000ff">  font-family: Arial;<br />
        color: black;<br />
        background-color: lightgrey;<br />
        text-decoration: underline;<br /></font>  }<br />
      THEAD {<br /><font color="#0000ff">  display: table-header-group;<br /></font>  }<br />
      TFOOT {<br /><font color="#0000ff">  display: table-footer-group;<br /></font>  }<br /><font color="#0000ff">--&gt;</font><br /><font color="#0000ff">&lt;/</font>STYLE<font color="#0000ff">&gt;</font></font>
        </p>
        <p>
      Since nearly every report uses an HTML Table, this works very well.  The THEAD
      and TFOOT styles is what makes the table a report.  If you don't want to setup
      a style tag, you can enter the style right into the table.
   </p>
        <p>
          <font face="Courier New" size="2">
            <font color="#0000ff">&lt;</font>table <font color="#ff0000">style</font>="<font color="#0000ff">table-layout:fixed</font>"<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;</font>colgroup<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;</font>col <font color="#ff0000">width</font>="<font color="#0000ff">150</font>"<font color="#0000ff">/&gt;</font><br />
              <font color="#0000ff">&lt;</font>col <font color="#ff0000">width</font>="<font color="#0000ff">100</font>"<font color="#0000ff">/&gt;</font><br />
              <font color="#0000ff">&lt;</font>col <font color="#ff0000">width</font>="<font color="#0000ff">150</font>"<font color="#0000ff">/&gt;</font><br />
          <font color="#0000ff">&lt;/</font>colgroup<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;</font>thead <font color="#ff0000">style</font>="<font color="#0000ff">display:table-header-group</font>"<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;</font>tr<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Header
      column 1<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Header
      column 2<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Header
      column 3<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;/</font>tr<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;/</font>thead<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;</font>tbody<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;</font>tr<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Body
      column 1<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Body
      column 2<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Body
      column 3<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;/</font>tr<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;/</font>tbody<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;</font>tfoot <font color="#ff0000">style</font>="<font color="#0000ff">display:table-footer-group</font>"<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;</font>tr<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Footer
      column 1<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Footer
      column 2<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
                  <font color="#0000ff">&lt;</font>td<font color="#0000ff">&gt;</font>Footer
      column 3<font color="#0000ff">&lt;/</font>td<font color="#0000ff">&gt;</font><br />
              <font color="#0000ff">&lt;/</font>tr<font color="#0000ff">&gt;</font><br />
          <font color="#0000ff">&lt;/</font>tfoot<font color="#0000ff">&gt;</font><br /><font color="#0000ff">&lt;/</font>table<font color="#0000ff">&gt;</font><br /></font> <br />
      Sounds too easy to be true but it works very nicely.  Of course, adding more
      style (bolding, underlining, background and foreground colors, etc.) makes this a
      very nice reporting option.
   </p>
        <p>
      ***Originally posted on DotNetJunkies on February 16, 2005
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=846996b5-a1da-4da0-a874-603076177392" />
      </body>
      <title>Reporting with HTML.  Who Needs Expensive Reporting Tools</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,846996b5-a1da-4da0-a874-603076177392.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,846996b5-a1da-4da0-a874-603076177392.aspx</link>
      <pubDate>Mon, 20 Feb 2006 19:08:19 GMT</pubDate>
      <description>&lt;p&gt;
   Printing a web page that represents a report has been difficult for me in the past.&amp;nbsp;
   I want to print a header and/or a footer that repeats on every printed page.&amp;nbsp;
   The screen version certainly isn't paginated, so how can you print a good looking
   report?&amp;nbsp; Style (or CSS) to the rescue.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
   Put the following Style tag, or something similar, in the header of the page.
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" size=2&gt;&lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;STYLE &lt;font color=#ff0000&gt;TYPE&lt;/font&gt;=”&lt;font color=#0000ff&gt;text/css&lt;/font&gt;” &lt;font color=#ff0000&gt;MEDIA&lt;/font&gt;=”&lt;font color=#0000ff&gt;screen,
   print&lt;/font&gt;”&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;lt;!--&lt;br&gt;
   &lt;/font&gt;TABLE {&lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;nbsp; table-layout: fixed;&lt;br&gt;
   &amp;nbsp; border: 0;&lt;br&gt;
   &amp;nbsp; cellspacing: 1;&lt;br&gt;
   &amp;nbsp; cellpadding: 1;&lt;br&gt;
   &amp;nbsp; font-family: Arial;&lt;br&gt;
   &amp;nbsp; font-size: 8pt;&lt;br&gt;
   &lt;/font&gt;&amp;nbsp; }&lt;br&gt;
   TH {&lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;nbsp; font-family: Arial;&lt;br&gt;
   &amp;nbsp; color: black;&lt;br&gt;
   &amp;nbsp; background-color: lightgrey;&lt;br&gt;
   &amp;nbsp; text-decoration: underline;&lt;br&gt;
   &lt;/font&gt;&amp;nbsp; }&lt;br&gt;
   THEAD {&lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;display: table-header-group;&lt;br&gt;
   &lt;/font&gt;&amp;nbsp; }&lt;br&gt;
   TFOOT {&lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;nbsp; display: table-footer-group;&lt;br&gt;
   &lt;/font&gt;&amp;nbsp; }&lt;br&gt;
   &lt;font color=#0000ff&gt;--&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;STYLE&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   Since nearly every report uses an HTML Table, this works very well.&amp;nbsp; The THEAD
   and TFOOT styles is what makes the table a report.&amp;nbsp; If you don't want to setup
   a style tag, you can enter the style right into the table.
&lt;/p&gt;
&lt;p&gt;
   &lt;font face="Courier New" size=2&gt;&lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;table &lt;font color=#ff0000&gt;style&lt;/font&gt;="&lt;font color=#0000ff&gt;table-layout:fixed&lt;/font&gt;"&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;colgroup&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;col &lt;font color=#ff0000&gt;width&lt;/font&gt;="&lt;font color=#0000ff&gt;150&lt;/font&gt;"&lt;font color=#0000ff&gt;/&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;col &lt;font color=#ff0000&gt;width&lt;/font&gt;="&lt;font color=#0000ff&gt;100&lt;/font&gt;"&lt;font color=#0000ff&gt;/&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;col &lt;font color=#ff0000&gt;width&lt;/font&gt;="&lt;font color=#0000ff&gt;150&lt;/font&gt;"&lt;font color=#0000ff&gt;/&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;colgroup&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;thead &lt;font color=#ff0000&gt;style&lt;/font&gt;="&lt;font color=#0000ff&gt;display:table-header-group&lt;/font&gt;"&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;tr&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Header
   column 1&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Header
   column 2&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Header
   column 3&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;tr&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;thead&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;tbody&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;tr&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Body
   column 1&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Body
   column 2&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Body
   column 3&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;tr&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;tbody&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;tfoot &lt;font color=#ff0000&gt;style&lt;/font&gt;="&lt;font color=#0000ff&gt;display:table-footer-group&lt;/font&gt;"&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;tr&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Footer
   column 1&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Footer
   column 2&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &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; &lt;font color=#0000ff&gt;&amp;lt;&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;Footer
   column 3&lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;td&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;tr&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;tfoot&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &lt;font color=#0000ff&gt;&amp;lt;/&lt;/font&gt;table&lt;font color=#0000ff&gt;&amp;gt;&lt;/font&gt;
   &lt;br&gt;
   &lt;/font&gt;&amp;nbsp;&lt;br&gt;
   Sounds too easy to be true but it works very nicely.&amp;nbsp; Of course, adding more
   style (bolding, underlining, background and foreground colors, etc.) makes this a
   very nice reporting option.
&lt;/p&gt;
&lt;p&gt;
   ***Originally posted on DotNetJunkies on February 16, 2005
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=846996b5-a1da-4da0-a874-603076177392" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,846996b5-a1da-4da0-a874-603076177392.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=203f400f-5310-4663-b992-4994f18b642f</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,203f400f-5310-4663-b992-4994f18b642f.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,203f400f-5310-4663-b992-4994f18b642f.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=203f400f-5310-4663-b992-4994f18b642f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      After examining numerous articles on printing with C#, I was about ready to toss in
      the towel and just copy &amp; paste to Word (yuck).  Then I found <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;812425">How
      To Print the Content of a RichTextBox Control By Using Visual C# .NET</a> on
      Microsoft's support site.
   </p>
        <p>
      I was sure that printing a RichTextbox should be pretty easy.  All the articles
      made it very difficult, though.  This article shows the “correct” way to print. 
      The entire contents are printed; pictures, other graphics, colors, etc.
   </p>
        <p>
      ***Originally posted on DotNetJunkies on January 11, 2005
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=203f400f-5310-4663-b992-4994f18b642f" />
      </body>
      <title>Print a RichTextBox</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,203f400f-5310-4663-b992-4994f18b642f.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,203f400f-5310-4663-b992-4994f18b642f.aspx</link>
      <pubDate>Mon, 20 Feb 2006 19:05:53 GMT</pubDate>
      <description>&lt;p&gt;
   After examining numerous articles on printing with C#, I was about ready to toss in
   the towel and just copy &amp;amp; paste to Word (yuck).&amp;nbsp; Then I found &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;812425"&gt;How
   To Print the Content of a RichTextBox Control By Using Visual C# .NET&lt;/a&gt;&amp;nbsp;on
   Microsoft's support site.
&lt;/p&gt;
&lt;p&gt;
   I was sure that printing a RichTextbox should be pretty easy.&amp;nbsp; All the articles
   made it very difficult, though.&amp;nbsp; This article shows the “correct” way to print.&amp;nbsp;
   The entire contents are printed; pictures, other graphics, colors, etc.
&lt;/p&gt;
&lt;p&gt;
   ***Originally posted on DotNetJunkies on January 11, 2005
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=203f400f-5310-4663-b992-4994f18b642f" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,203f400f-5310-4663-b992-4994f18b642f.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.bpsvc.com/devblog/Trackback.aspx?guid=34d1c42e-6e87-4c44-b71e-9abdc80711d0</trackback:ping>
      <pingback:server>http://www.bpsvc.com/devblog/pingback.aspx</pingback:server>
      <pingback:target>http://www.bpsvc.com/devblog/PermaLink,guid,34d1c42e-6e87-4c44-b71e-9abdc80711d0.aspx</pingback:target>
      <dc:creator>myemail@myemail.com (Your DisplayName here!)</dc:creator>
      <wfw:comment>http://www.bpsvc.com/devblog/CommentView,guid,34d1c42e-6e87-4c44-b71e-9abdc80711d0.aspx</wfw:comment>
      <wfw:commentRss>http://www.bpsvc.com/devblog/SyndicationService.asmx/GetEntryCommentsRss?guid=34d1c42e-6e87-4c44-b71e-9abdc80711d0</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Welcome to my developer blog!  The entries here will focus on my experiences
      and thoughts as a software professional.  The first entries will be transferred
      from my first blog on <a href="http://www.dotnetjunkies.com/">dotnetjunkies</a>. 
      I haven't posted there for quite a while.  I will post on a variety of topics;
      coding tips, interesting articles, cool products, project methodologies, etc. 
      If it has anything to do with software development, I'll be talking about it here.
   </p>
        <p>
      My writing style is to be straight forward, sometimes from the hip.  I can be
      hard on others at times.  But I can also be very gratious when I find or read
      something with which I like or agree.  I can dish it out and I can take it. 
      If you read anything here that you agree, or disagree, with, please let me know. 
      I don't take things personally.  
   </p>
        <p>
      Conversation, including an occasional heated disagreement, is great for the mind. 
      It solidifies your character.  So let's get started...
   </p>
        <img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=34d1c42e-6e87-4c44-b71e-9abdc80711d0" />
      </body>
      <title>Welcome</title>
      <guid>http://www.bpsvc.com/devblog/PermaLink,guid,34d1c42e-6e87-4c44-b71e-9abdc80711d0.aspx</guid>
      <link>http://www.bpsvc.com/devblog/PermaLink,guid,34d1c42e-6e87-4c44-b71e-9abdc80711d0.aspx</link>
      <pubDate>Sun, 19 Feb 2006 17:05:13 GMT</pubDate>
      <description>&lt;p&gt;
   Welcome to my developer blog!&amp;nbsp; The entries here will focus on my experiences
   and thoughts as a software professional.&amp;nbsp; The first entries will be transferred
   from my first blog on &lt;a href="http://www.dotnetjunkies.com/"&gt;dotnetjunkies&lt;/a&gt;.&amp;nbsp;
   I haven't posted there for quite a while.&amp;nbsp; I will post on a variety of topics;
   coding tips, interesting articles, cool products, project methodologies, etc.&amp;nbsp;
   If it has anything to do with software development, I'll be talking about it here.
&lt;/p&gt;
&lt;p&gt;
   My writing style is to be straight forward, sometimes from the hip.&amp;nbsp; I can be
   hard on others at times.&amp;nbsp; But I can also be very gratious when I find or read
   something with which I like or agree.&amp;nbsp; I can dish it out and I can take it.&amp;nbsp;
   If you read anything here that you agree, or disagree, with, please let me know.&amp;nbsp;
   I don't take things personally.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
   Conversation, including an occasional heated disagreement, is great for the mind.&amp;nbsp;
   It solidifies your character.&amp;nbsp; So let's get started...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bpsvc.com/devblog/aggbug.ashx?id=34d1c42e-6e87-4c44-b71e-9abdc80711d0" /&gt;</description>
      <comments>http://www.bpsvc.com/devblog/CommentView,guid,34d1c42e-6e87-4c44-b71e-9abdc80711d0.aspx</comments>
    </item>
  </channel>
</rss>