{"id":150,"date":"2007-11-17T10:32:00","date_gmt":"2007-11-17T10:32:00","guid":{"rendered":"\/lisa\/post\/2007\/11\/17\/One-more-for-the-road-Labels-Times-N-for-SQL-Server-and-VFP.aspx"},"modified":"2007-11-17T10:32:00","modified_gmt":"2007-11-17T10:32:00","slug":"one-more-for-the-road-labels-times-n-for-sql-server-and-vfp","status":"publish","type":"post","link":"https:\/\/spacefold.com\/lisa\/2007\/11\/17\/one-more-for-the-road-labels-times-n-for-sql-server-and-vfp\/","title":{"rendered":"One more for the road: Labels-Times-N for SQL Server and VFP"},"content":{"rendered":"<p>\nThis will be a quick Reporting Convergences chapter, as C and I get ready for a week+ of fun, travel, and the madcap thrills of completely Life Re-arranging.\n<\/p>\n<p>\nI&#39;ll be working on TMM while I&#39;m away, slowly, but I&#39;m not sure if I will have any opportunities to post.\n<\/p>\n<h3>What is it about mailing labels?<\/h3>\n<p>\nIt always amuses me that Microsoft and other vendors are off in their flow-page, screen-only, and web-centric&nbsp;universe while most of the people I know who have to slam out reports for real business applications are still worried about delivering&nbsp;fixed page layouts for printed output.&nbsp; As a primary problem, not as an afterthought.\n<\/p>\n<p>\nI don&#39;t know&#8230; how goes it, in your world?\n<\/p>\n<p>\nMailing labels represent the epitome of the fixed page layout, in some ways, because label sheets are made up of fixed-layout&nbsp;sections, each of which is minutely specified and each of which must be exactly placed.&nbsp; As you know.&nbsp; That makes them a real PITA from the POV of report layout design. As&nbsp;we all&nbsp;know.\n<\/p>\n<p>\nWhat I can&#39;t really figure out is why&nbsp;people tend to ask questions about this type of thing in bunches.&nbsp;\n<\/p>\n<p>\nIt just happened AGAIN. Just like I got two Sideways report questions in a row, in the past two weeks, two people asked how to print a variable number of label copies, one in SQL Server and one in VFP.\n<\/p>\n<h3>The labels-times-N problem<\/h3>\n<p>\nApparently more than one of you are writing an application for UPS or whomtever to handle the holiday rush and they want multiple copies of each recipient&#39;s label.&nbsp; Of course you don&#39;t want to hard-code the number of label copies.&nbsp;\n<\/p>\n<p>\nThis is a classic problem. You can do it in both VFP and SQL Server RS report layouts &#8212; but it&#39;s a real mess. Just like the Sideways problem you should solve&nbsp;this one&nbsp;at the data level whenever possible,&nbsp;rather than&nbsp;kludging around in the report layout.\n<\/p>\n<p>\nYou can solve this classic problem using the equally-classic Cartesian join.\n<\/p>\n<h5>The SQL Server resolution&nbsp;<\/h5>\n<p>\nThere have always been a bunch&nbsp;of ways to do this in SQL Server, but (thank goodness) SQL Server 2005 has&nbsp;Top N-variable syntax.\n<\/p>\n<p>\nSo, now, all you have to do is what you see in the quick sketch below.&nbsp;\n<\/p>\n<p>\nNotice that I&#39;ve used a <strong>Master<\/strong> database table known to have a decent size record set here; you can use any table you like in the nested <strong>SELECT<\/strong> as long as it has &gt;= the max number of label copies you might want to produce.&nbsp;&nbsp; Also notice the parens around the <strong>TOP<\/strong> clause, without which it might not work:\n<\/p>\n<p class=\"code\">\n<font color=\"#0000ff\">DECLARE<\/font> @LabelCount <font color=\"#0000ff\">AS<\/font> <font color=\"#0000ff\">integer<br \/>\nSET<\/font> @LabelCount <font color=\"#808080\">=<\/font> 4<br \/>\n<font color=\"#0000ff\">SELECT<\/font> <font color=\"#808080\">*<\/font> <font color=\"#0000ff\">FROM<\/font> Recipient<br \/>\n<font color=\"#808080\">&nbsp;&nbsp; RIGHT<\/font> <font color=\"#808080\">OUTER<\/font> <font color=\"#808080\">JOIN<\/font> <br \/>\n<font color=\"#808080\">&nbsp;&nbsp; (<\/font><font color=\"#0000ff\">SELECT<\/font> <font color=\"#0000ff\">TOP<\/font> <font color=\"#808080\">(<\/font>@LabelCount<font color=\"#808080\">)<\/font> <font color=\"#0000ff\">Name<\/font> <br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color=\"#0000ff\">FROM<\/font> Master<font color=\"#808080\">.<\/font>dbo<font color=\"#808080\">.<\/font>spt_values <font color=\"#808080\">)<\/font> X <font color=\"#0000ff\">ON<\/font> 1 <font color=\"#808080\">=<\/font> 1<br \/>\n<font color=\"#0000ff\">ORDER<\/font> <font color=\"#0000ff\">BY<\/font> Recipient_ID\n<\/p>\n<p>\nWhat&nbsp;you&#39;re looking at here (the Cartesian join part) is &quot;join every record in one table with every record in the other table&quot;.&nbsp; Not usually recommended, but perfect when you want multiple copies of your data.&nbsp; You just join it with some set of records, any set at all, containing the proper number of rows.\n<\/p>\n<h5>Morph this to VFP SQL <\/h5>\n<p>\n&#8230;&nbsp;&nbsp;Here&#39;s the VFP version. The<strong>&nbsp;SELECT<\/strong> statement in it&nbsp;is almost exactly the same as the SQL Server version, but this sample code is fully-worked to be runnable with any tables you happen to have handy.\n<\/p>\n<p>\nYou can pick a table to use in place of the Master table you see in the SQL Server sketch above, and you also pick a table to serve as your &quot;recipient&quot; table, as part of this demo:\n<\/p>\n<div class=\"code\">\n<p>\n#<font color=\"#0000ff\">DEFINE <\/font>DEFAULT_COUNT 4<br \/>\n<font color=\"#0000ff\">LPARAMETERS <\/font>iLabelCount<br \/>\n<font color=\"#0000ff\">LOCAL <\/font>iSelect<br \/>\n<font color=\"#0000ff\">IF EMPTY<\/font>(iLabelCount) OR <font color=\"#0000ff\">VAL<\/font>(<font color=\"#0000ff\">TRANSFORM<\/font>(iLabelCount)) &lt; 2<br \/>\n&nbsp;&nbsp; iLabelCount = DEFAULT_COUNT<br \/>\n<font color=\"#0000ff\">ELSE<br \/>\n<\/font>&nbsp;&nbsp; iLabelCount = <font color=\"#0000ff\">INT<\/font>(<font color=\"#0000ff\">VAL<\/font>(<font color=\"#0000ff\">TRANSFORM<\/font>(iLabelCount)))<br \/>\n<font color=\"#0000ff\">ENDIF<\/font>\n<\/p>\n<p>\niSelect = <font color=\"#0000ff\">SELECT<\/font>(0)\n<\/p>\n<p>\n<font color=\"#0000ff\">DO WHILE RECCOUNT() &lt; iLabelCount<br \/>\n&nbsp;&nbsp; SELECT 0<br \/>\n&nbsp;&nbsp; WAIT WINDOW NOWAIT &quot;Pick a table with&nbsp;at least&nbsp;&quot; ;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + TRANSFORM(iLabelCount) + &quot; recs&#8230; &quot;<br \/>\n&nbsp;&nbsp; USE ? ALIAS YourLargeEnoughTable SHARED AGAIN<br \/>\n&nbsp;&nbsp; WAIT CLEAR<br \/>\n&nbsp;&nbsp; IF EMPTY(ALIAS())<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EXIT<br \/>\n&nbsp;&nbsp; ENDIF<br \/>\nENDDO <\/font>\n<\/p>\n<p>\n<font color=\"#0000ff\">IF RECCOUNT() &gt; 0<br \/>\n&nbsp;&nbsp; SELECT 0<br \/>\n&nbsp;&nbsp; WAIT WINDOW NOWAIT &quot;Pick the table with your label recipients&#8230; &quot; <br \/>\n&nbsp;&nbsp; USE ? ALIAS YourRecipients SHARED AGAIN<br \/>\n&nbsp;&nbsp; WAIT CLEAR<br \/>\nENDIF <\/p>\n<p>IF USED(&quot;YourRecipients&quot;)<br \/>\n&nbsp;&nbsp; SELECT * FROM YourRecipients ;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; RIGHT OUTER JOIN&nbsp;;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp; (SELECT TOP (iLabelCount) .T. ;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM YourLargeEnoughTable ;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORDER BY .T.) X ON 1 = 1 ; <font color=\"#008000\">&amp;&amp;&nbsp;doesn&#39;t matter what fields or order<br \/>\n<\/font>&nbsp;&nbsp; ORDER BY 1 <font color=\"#008000\">&amp;&amp; or whatever is appropriate <br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; for your recipient table <br \/>\n<\/font>&nbsp;&nbsp; USE IN YourRecipients<br \/>\nENDIF <\/font>\n<\/p>\n<p>\n<font color=\"#0000ff\">IF USED(&quot;YourLargeEnoughTable&quot;)<br \/>\n&nbsp;&nbsp; USE IN YourLargeEnoughTable<br \/>\nENDIF <\/font>\n<\/p>\n<p>\n<font color=\"#0000ff\">SELECT (iSelect) <\/font>\n<\/p>\n<p>\n<font color=\"#0000ff\">RETURN <\/font>\n<\/p>\n<\/div>\n<p class=\"NB\">\nJust&nbsp;so you know: I am aware of the hash that VFP&#39;s p*ss-poor attempt at rich text copy and paste sometimes makes in these posts.&nbsp; I hope the code comes out runnable, and some days that&#39;s the best I can do.\n<\/p>\n<h4>Put X-Up and Times-N together and they spell label heaven <\/h4>\n<p>\nYou can put Sideways reports for SQL Server or for VFP, from my recent posts, together with what you have here.&nbsp; You&nbsp;get a variable number of label copies, with each set of copies on its own horizontal line.\n<\/p>\n<p>\nWhat more could a label-meister ask?&nbsp;\n<\/p>\n<p>\nHow about rational label sizes? Doubt that will ever happen, because odd sizes of labels,&nbsp;precisely placed on a sheet,&nbsp;are a business requirement in the real world. Gotta respect that.&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This will be a quick Reporting Convergences chapter, as C and I get ready for a week+ of fun, travel, and the madcap thrills of completely Life Re-arranging. I&#39;ll be working on TMM while I&#39;m away, slowly, but I&#39;m not sure if I will have any opportunities to post. What is it about mailing labels?<a class=\"more-link\" href=\"https:\/\/spacefold.com\/lisa\/2007\/11\/17\/one-more-for-the-road-labels-times-n-for-sql-server-and-vfp\/\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6,9],"tags":[],"class_list":["post-150","post","type-post","status-publish","format-standard","hentry","category-reporting","category-sql-server","category-visual-foxpro"],"_links":{"self":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/comments?post=150"}],"version-history":[{"count":0,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/posts\/150\/revisions"}],"wp:attachment":[{"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/media?parent=150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/categories?post=150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spacefold.com\/lisa\/wp-json\/wp\/v2\/tags?post=150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}