<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Chris Hays's Reporting Services Sleazy Hacks Weblog : Sleazy Hacks</title><link>http://blogs.msdn.com/chrishays/archive/tags/Sleazy+Hacks/default.aspx</link><description>Tags: Sleazy Hacks</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>"Continued" Header on Subsequent Pages</title><link>http://blogs.msdn.com/chrishays/archive/2006/09/27/ContinuedHeader.aspx</link><pubDate>Thu, 28 Sep 2006 01:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:774544</guid><dc:creator>ChrisHays</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chrishays/comments/774544.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrishays/commentrss.aspx?PostID=774544</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;BR&gt;How can I repeat a group header on each page, but have it say "MyGroup (continued)" on all but the first page?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Answer:&lt;/STRONG&gt;&lt;BR&gt;Since pagination is determined long after the report has been fully processed, there's no way for the body of the report to reference any page information.&amp;nbsp; As a result, we're going to have to resort to a trick wherein something in the page header can be made to look as if it is the group header.&lt;/P&gt;
&lt;P&gt;The following assumes you are using a table and have no table header but can be readily adapted to other situations.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1:&lt;/STRONG&gt;&amp;nbsp; Turn off RepeatOnNewPage on your group header&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2:&lt;/STRONG&gt;&amp;nbsp; Duplicate the group header information in a hidden column&lt;BR&gt;You're going to need the group header text to always be present on the page, even when the group header itself isn't present. The easiest way is to add a hidden column to the table and then copy the group header textbox into the detail row in that column. Make careful note of the names of both the group header textbox (which I'll call GroupHeader) and the copy (which I'll call GroupCopy)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3:&lt;/STRONG&gt;&amp;nbsp; Copy the first GroupHeader and first GroupCopy to the page header&lt;BR&gt;In the page header, add two textboxes with the following expressions:&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;=First(ReportItems!GroupHeader.Value)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;=First(ReportItems!GroupCopy.Value)&lt;/FONT&gt;&lt;BR&gt;Make careful note of the names of both these textboxes (which I'll call FirstGroupHeader and FirstGroupCopy).&amp;nbsp; Run the report and notice the behavior:&amp;nbsp; FirstGroupHeader is the same as FirstGroupCopy only if it appears at the top of the page.&amp;nbsp; Mark both textboxes as Hidden=True&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4:&lt;/STRONG&gt;&amp;nbsp; Copy the GroupCopy textbox into the page header and add "continued"&lt;BR&gt;In the page header, add a textbox with the following expression:&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;=First(ReportItems!GroupCopy.Value) + " (continued)"&lt;/FONT&gt;&lt;BR&gt;Align and size the textbox to match the GroupHeader textbox exactly.&amp;nbsp; Now when you run the report, you'll see both the normal group header and the Continued group header&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 5:&lt;/STRONG&gt;&amp;nbsp; Conditionally hide the Continued header textbox&lt;BR&gt;Ideally, the next step would be to set the Hidden expression on the Continued header textbox to this:&lt;BR&gt;&lt;FONT face="Courier New" color=#000000 size=2&gt;=ReportItems!FirstGroupHeader.Value=ReportItems!FirstGroupCopy.Value&lt;BR&gt;&lt;/FONT&gt;Unfortunately, this won't work due to a slightly overzealous publishing restriction against using multiple report item references within a single expression in a page header item [which was intended to prevent potentially bad things like Sum(textbox1/textbox2)].&lt;BR&gt;However, we can bypass this publishing restriction by passing in the report items collection to a custom function.&lt;BR&gt;Add the following to the report's Code block:&lt;BR&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;public function HideHeader(Items as ReportItems) as Boolean&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Items("FirstGroupHeader").Value = Items("FirstGroupCopy").Value&lt;BR&gt;end function&lt;/FONT&gt;&lt;BR&gt;&lt;/FONT&gt;Now set the Hidden property of the Continued header to:&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;=Code.HideHeader(ReportItems)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Note: In the event you will always page break at the end of a group, there is a much simpler approach.&amp;nbsp;You can skip steps 3 and 5 and instead set the Hidden property of the Continued header to:&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;=Not(ReportItems!GroupHeader.Value Is Nothing)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;A full working sample of continued headers on subsequent pages is attached.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=774544" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/chrishays/attachment/774544.ashx" length="12507" type="application/octet-stream" /><category domain="http://blogs.msdn.com/chrishays/archive/tags/Sleazy+Hacks/default.aspx">Sleazy Hacks</category></item><item><title>Reset Page Number On Group</title><link>http://blogs.msdn.com/chrishays/archive/2006/01/05/ResetPageNumberOnGroup.aspx</link><pubDate>Fri, 06 Jan 2006 05:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:509925</guid><dc:creator>ChrisHays</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chrishays/comments/509925.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrishays/commentrss.aspx?PostID=509925</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;BR&gt;How can I reset my page number back to 1 every time I get a group break?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Answer:&lt;/STRONG&gt;&lt;BR&gt;Resetting the page number on group breaks isn't natively supported, but it can be achieved by tracking group breaks in a shared variable and subtracting off the page offset of the first page of the group from the current page number.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1:&lt;/STRONG&gt;&amp;nbsp; Make sure there's a textbox in the report which contains the group expression&lt;/P&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;STRONG&gt;Step 2:&lt;/STRONG&gt;&amp;nbsp; Add shared variables to track the current group and page offset&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;Shared offset as Integer&lt;BR&gt;&amp;nbsp;Shared currentgroup as Object&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3:&lt;/STRONG&gt;&amp;nbsp; Add a custom function to set the shared variables and retrieve the group page number&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;Public Function GetGroupPageNumber(group as Object, pagenumber as Integer) as Object&lt;BR&gt;&amp;nbsp;&amp;nbsp;If Not (group = currentgroup)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;offset = pagenumber - 1&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentgroup = group&lt;BR&gt;&amp;nbsp;&amp;nbsp;End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;Return pagenumber - offset&lt;BR&gt;&amp;nbsp;End Function&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4:&lt;/STRONG&gt; Use the function in the page header or footer&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;=Code.GetGroupPageNumber(ReportItems!Category.Value,Globals!PageNumber)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Note:&amp;nbsp; Because this uses static variables, if two people run the report at the exact same moment, there's a slim chance one will smash the other's variable state&amp;nbsp; (In SQL 2000, this could occasionally happen due to two users paginating through the same report at the same time, not just due to exactly simultaneous executions)&amp;nbsp; If you need to be 100% certain to avoid this, you can make each of the shared variables a hash table based on user ID (&lt;FONT face="Courier New" size=2&gt;Globals!UserID&lt;/FONT&gt;).&lt;/P&gt;
&lt;P&gt;A full working sample of page number reset on group is attached.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=509925" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/chrishays/attachment/509925.ashx" length="22178" type="application/octet-stream" /><category domain="http://blogs.msdn.com/chrishays/archive/tags/Sleazy+Hacks/default.aspx">Sleazy Hacks</category></item><item><title>Centered Images</title><link>http://blogs.msdn.com/chrishays/archive/2004/10/27/CenteredImages.aspx</link><pubDate>Wed, 27 Oct 2004 22:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:248683</guid><dc:creator>ChrisHays</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chrishays/comments/248683.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrishays/commentrss.aspx?PostID=248683</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;BR&gt;I have variable sized images I want to display in a table column.&amp;nbsp; How can I center these images without stretching them to fill the table cell?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Answer:&lt;BR&gt;&lt;/STRONG&gt;While there is no automatic centering behavior for the Image control, you can simulate this by writing an expression for PaddingLeft and PaddingTop to result in a centered image.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1:&lt;/STRONG&gt;&amp;nbsp; Clip, don't Fit&lt;/P&gt;
&lt;P&gt;Set the Sizing property of the Image control to Clip.&amp;nbsp; In a table cell, this is the only setting that won't resize your image.&amp;nbsp; (If your image gets automatically resized, the calculations below won't work.)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2:&lt;/STRONG&gt;&amp;nbsp; Give yourself room to grow&lt;/P&gt;
&lt;P&gt;Make your column and row large enough to accomodate your largest image so that the image won't clip.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3:&lt;/STRONG&gt;&amp;nbsp; Turn off CanGrow&lt;/P&gt;
&lt;P&gt;For all other cells in the row, turn off CanGrow, so ensure long textual contents won't cause the row to increase in size (thereby invalidating the calculations below).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4:&lt;/STRONG&gt;&amp;nbsp; Reference System.Drawing&lt;/P&gt;
&lt;P&gt;To determine the size of the image, you'll need to add a reference to the System.Drawing assembly in your report.&amp;nbsp; This is in the Report Properties dialog on the References Tab.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 5:&lt;/STRONG&gt;&amp;nbsp; Calculate padding&lt;/P&gt;
&lt;P&gt;To determine the size of the image, you'll need to load the image from your field into a memory stream and from there load it into a .Net Image object.&amp;nbsp; Since fields are of type Object, you'll need to cast it to a byte array before loading it into a memory stream.&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;ImageWidthInPixels = System.Drawing.Image.FromStream(new System.IO.MemoryStream(CType(Fields!Photo.Value,Byte()))).Width&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;From there, you can calculate the half of the difference between the width of the image and the width of the column.&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;Padding = (ColumnWidthInInches-ImageWidthInPixels/DPI)/2&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;DPI is typically 96&lt;/P&gt;
&lt;P&gt;The padding property takes a size, which is a string including the size and the units.&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;PaddingLeft = CStr(Round(Padding,2)) &amp;amp; "in"&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;Here's the expression fully expanded:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr&gt;&lt;FONT face="Courier New" size=2&gt;=CStr(Round((3-System.Drawing.Image.FromStream(new System.IO.MemoryStream(CType(Fields!Photo.Value,Byte()))).Height/96)/2,2))&amp;amp;"in"&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now just do the same thing for PaddingTop and you've got a fully centered image.&lt;/P&gt;
&lt;P&gt;A full working sample of centered images is attached.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=248683" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/chrishays/attachment/248683.ashx" length="8683" type="application/octet-stream" /><category domain="http://blogs.msdn.com/chrishays/archive/tags/Sleazy+Hacks/default.aspx">Sleazy Hacks</category></item><item><title>Green-Bar Matrix</title><link>http://blogs.msdn.com/chrishays/archive/2004/08/30/GreenBarMatrix.aspx</link><pubDate>Tue, 31 Aug 2004 04:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:223068</guid><dc:creator>ChrisHays</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chrishays/comments/223068.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrishays/commentrss.aspx?PostID=223068</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;Question:&lt;/STRONG&gt;&lt;BR&gt;How can I get a green-bar effect (alternating colors) in a matrix?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Answer:&lt;/STRONG&gt;&lt;BR&gt;For a green-bar table, you can simply use a background color expression like this: &lt;FONT face="Courier New" size=2&gt;=iif(RowNumber(Nothing) Mod 2,"Green","White")&lt;/FONT&gt;&lt;BR&gt;However, there is currently no GroupNumber() function on which to base a green-bar calculation in a matrix.&lt;BR&gt;GroupNumber can be (mostly) simulated by using the RunningValue function to get a running distinct count of group expression values.&lt;BR&gt;However, the trickiest part of green-bar in a matrix is the fact that some matrix cells may contain no data at all.&amp;nbsp; This makes the group number calculation incorrect for empty cells.&lt;BR&gt;To work around this, you need to effectively calculate the group number in the row header and then use that value inside the data cells.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1:&lt;/STRONG&gt;&amp;nbsp; Add a (fake) inner row grouping&lt;BR&gt;Select the innermost row grouping in your matrix.&amp;nbsp; Right-click and select Insert Group.&lt;BR&gt;For the group expression, group on a constant, such as &lt;FONT face="Courier New" size=2&gt;=1&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2:&lt;/STRONG&gt;&amp;nbsp; Calculate the name of the color in the inner row grouping header&lt;BR&gt;In the Value property of the newly created grouping header, add a calculation for the desired color based on a running value of a count distinct of the containing group expression.&lt;BR&gt;For example: &lt;FONT face="Courier New" size=2&gt;=iif(RunningValue(Fields!Country.Value,CountDistinct,Nothing) Mod 2, "AliceBlue", "White")&lt;/FONT&gt;&lt;BR&gt;Note:&amp;nbsp; If you have more than one row grouping, you may need to do the count distinct on the combination of all group expressions, like this:&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;=iif(RunningValue(Fields!Country.Value &amp;amp; CStr(Fields!Year.Value),CountDistinct,Nothing) Mod 2, "AliceBlue", "White")&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3:&lt;/STRONG&gt;&amp;nbsp; Set the background color of the inner row grouping header to =Value&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4:&lt;/STRONG&gt;&amp;nbsp; Set the background color of the matrix data cell to the value of the inner row grouping header&lt;BR&gt;For example:&amp;nbsp; &lt;FONT face="Courier New" size=2&gt;=ReportItems!ColorNameTextbox.Value&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 5:&lt;/STRONG&gt;&amp;nbsp; Set the background color of the outer row grouping header&lt;BR&gt;You'll need to use the same expression here that you used for the Value of the inner row grouping header.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 6:&lt;/STRONG&gt;&amp;nbsp; "Cloak" the inner row grouping header (so it looks like part of of the outer grouping header)&lt;BR&gt;Set the right border style of the outer grouping header to None.&lt;BR&gt;Set the left border style of the inner grouping header to None.&lt;BR&gt;Set the font weight of the inner grouping header to 1 pt.&lt;BR&gt;Set the font color of the inner grouping header to =Value.&lt;BR&gt;Set the CanGrow property of the inner grouping header to False.&lt;BR&gt;Drag the inner grouping header to be as narrow as possible.&lt;BR&gt;Optional:&amp;nbsp; Hand-edit the RDL to set the width of the inner grouping header to 0in.&lt;/P&gt;
&lt;P&gt;A full working sample of green-bar matrix is attached.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=223068" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/chrishays/attachment/223068.ashx" length="8329" type="application/octet-stream" /><category domain="http://blogs.msdn.com/chrishays/archive/tags/Sleazy+Hacks/default.aspx">Sleazy Hacks</category><category domain="http://blogs.msdn.com/chrishays/archive/tags/FAQ/default.aspx">FAQ</category></item></channel></rss>