Add Styles to Your Reporting Services Reports

  • e.j.egan (2/26/2009)


    One other drawback however is that you can't visibly see the colors from the layout view...which when you have a lot going on in a layout can be confusing (you always have to preview to ensure you have everything.

    I began using the styling-stored-in-database approach about a year ago, but for the reason mentioned here I dropped it shortly after. While you're designing a report, if you've got font names, sizes, colours, etc. being pulled from a dataset using expressions, all you have on screen in Layout mode is a generic-looking template, which doesn't give you a true sense of the way a page full of content will be laid out when viewed.

    However I still like to have company logos stored in a database and rendered in my report headers from a dataset.

    Anyway, I like where you're going with this, Adam, and will look forward to reading more.

    David

  • Excellent article Adam! Looking forward to the other installments.

    On a side note though I am amazed that you actually like working with Reporting Services. Before using RS, I was developing reports using Crystal Reports XI and I still feel that tool is way better and more user-friendly. Or maybe I haven't exploited Reporting Services enough yet ...

  • Instead of writing function/s in multiple reports (code window). We can make an external dll file (assembly) using one of the .NET language and can use that assembly in the report.

    Start adding attributes method whenever required. Which makes this assembly a utility having almost frequently used attributes covered in it.

  • Have anybody tried out to modify the templates from the wizard?

    C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\Business Intelligence Wizards\Reports\Styles\en\StyleTemplates.xml

    C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies\ProjectItems\ReportProject\Report.rdl

    If found this here

    http://beacspeak.spaces.live.com/blog/cns!69043F34B6D40843!125.entry

    I've been trying to create a new template with the "company colours and styles" or just modify one of the existing, but all i got when i select the template modified in the wizard is an exception error of the xml

  • I discuss templates in the third article in this series, which should be published in a couple of weeks.

    I had no trouble getting templates to work, though - and never saw this error!

  • It would be nice to have some dot net assembly that can translate a real CSS style sheet into class functions to be used by Reporting Services. Because many application developers have to make CSS Styel sheets for the web project anyway. So simply by copying the same stylesheet to the SSRS report folder, and then we can cover both side, the application side and the reporting side.

  • I'm using Visual Studio 2005 and trying to follow your example; however, once I've created the function and I go to reference it (i.e., =code.StyleColor), it is not being found by the Intellisense engine and consequently the color provided to the function is not returned. What gives?

  • I'm using Visual Studio 2005 and trying to follow your example; however, once I've created the function and I go to reference it (i.e., =code.StyleColor), it is not being found by the Intellisense engine and consequently the color provided to the function is not returned. What gives?

  • Function ChangeColor(ByVal sTeam As String) As String

    Dim sColor As String

    Select Case sTeam

    Case Is = "A"

    sColor = "Red"

    Case Is = "B"

    sColor = "Aqua"

    Case Is = "C"

    sColor = "ForestGreen"

    Case Is = "D"

    sColor = "MediumPurple"

    Case Is = "E"

    sColor = "Yellow"

    Case Else

    sColor = "White"

    End Select

    Return sColor

    End Function

    with this one you pass a value from your report that comes from the database in my case a team

    and then in some part of your report you add the formula

    =code.ChangeColor(Fields!R_TEAM.Value)

    bear in mind that this must be a section related to color eg. background or font color elsewhere the formula would be wasted

  • I do much the same thing in defining standardized colors for different sections of reports, except I use parameters to hold color definitions instead of custom code. For instance, I have a custom report template that contains a parameter 'GrayBarColor' with visibility set to Internal and a default value of '#dbe5f1'. Changing the default value of the parameter changes the color everywhere it's applied.

    To apply this color to a cell, I simply set the BackgroundColor Expression to '=Parameters!GrayBarColor.Value'. Of course, if I'm setting up alternating graybar rows, it would be something more like '=IIf(RowNumber(Nothing) Mod 2, Parameters!GrayBarColor.Value, 'Transparent")

    To get the color values (like '#dbe5f1'), I just pick a cell, select the drop-down for the BackgroundColor property in the properties window, select More colors, then tweak the three RGB color values until I get the color I want. When I click OK, the BackgroundColor property value is returned in the above hex format.

    Sometimes I am given a report mock-up in Excel (complete with colors) and asked to match it in SSRS. It's easy to match the colors - in Excel, I select a colored cell, select the drop-down arrow on the Fill menu icon, select More Colors, and then the Custom tab. This displays the three RGB values of the color, which can be directly applied in SSRS to get the exact same color.

    I'm really glad to see this series of articles. Like many working with SSRS, I'm a programmer and not a graphics artist. Unfortunately, reports are often judged by there appearance rather than by accuracy of the data.

  • Very useful article and forum. Thanks.

  • Good information.

    However, imagine there are ~30 odd reports. Single change will trigger modification in ~30 reports. Suggest to use custom DLL, which can be accessed easily using custom code. Check @ http://www.sqlservercentral.com/articles/Development/2803/

  • I've used this methodology as well and it works great except for one thing; the color palette that Dynamics AX 2009 uses does not seem to match up well with the color palette used by BIDS or SSRS (Report Manager). My AX form, for example, calls the winAPI::chooseColor color picker and changes the form control background to reflect the newly chosen color. When the report renders, though, the colors are interpreted very differently. Hex value #0000FF, for example, shows as red on my AX form, but when the report renders, it is a blue. Some colors look correct, some are way off, and some others will actually display differently in AX, BIDS, AND SSRS (the Report Manager). How do you get around this? I cannot figure out how to designate a particular color palette from my report programmatically to ensure the same palettes are being used.

    John

    :blush: Updated 10/8/2010: I found a bug in my code that was causing this anomoly... we're better now.

  • Hi John,

    SSRS always renders the colors specified with #000000 HEX RGB notation properly. What I mean by "properly" is that if you use a tool like MS Paint or Adobe Photoshop and you specify the same HEX/DEC numbers there, you'll get the same colour that SSRS renders. I have no idea how Dynamics does this, but I have never seen SSRS rendering the wrong colours. Please test your colours in Paint and if Dynamics shows a wrong one, you will have to investigate why that is happening.

  • Thanks for the post. I think I've located the issue (sort of) in the WinAPI::RGB2int(r,g,b) function call. (BTW, this is all inside Dynamics AX written in X++.) If I pass in red (255,0,0) the returned integer should be 16711680, but it returns 255. The contents of that function are:

    static client server int rgb2int(RGBint r, RGBint g, RGBint b)

    {

    return r + g<<#offset8 + b<<#offset16;

    }

    ... it looks like something in the #offset8 and/or #offset16 calls that swaps the red and blue channels, so it really evaluates (0,0,255) and returns the integer 255, which is really blue and not red. Vice versa if I pass in blue. If I pass in green, (or any color) with the same red and blue channels, it will work fine because green is (0,255,0) and the swap doesn't affect the returned integer value.

    Here's the snippet that refreshes my form control (this is on a data source method):

    public void refresh()

    {

    Container c;

    int64 r, g, b, y;

    int64 bgColor;

    str rgbValue;

    str hexValue;

    str pureBlack = "000000"; // pure black expressed in hex

    str midLevelGray = "808080"; // flat gray expressed in hex

    str pureWhite = "FFFFFF"; // pure white expressed in hex

    int pureBlackInt = hex2Int(pureBlack);

    int pureWhiteInt = hex2Int(pureWhite);

    real realR, realG, realB;

    real realRconst = 0.241;

    real realGconst = 0.691;

    real realBconst = 0.068;

    int64 luminanceThreshold = 128; // middle gray (#808080) luminance

    ;

    // Refresh Report Header Font Color

    c = WinAPI::RGBint2Con(hex2Int(strRem(mbsbdSSRSTextTagReplacement.RptHdrFontColor, "#")));

    r = conpeek(c,1);

    g = conpeek(c,2);

    b = conpeek(c,3);

    realR = any2Real(r);

    realG = any2Real(g);

    realB = any2Real(b);

    // calculate relative luminance

    y = any2Int64(sqrt(realR * realR * realRconst +

    realG * realG * realGconst +

    realB * realB * realBconst));

    if (!mbsbdSSRSTextTagReplacement.RptHdrFontColor)

    {

    RptHdrFontColorControl.backgroundColor(pureWhiteInt);

    }

    else

    {

    bgColor = WinAPI::RGB2int(r, g, b);

    hexValue = int2Hex(r, 2) + int2Hex(g, 2) + int2Hex(b, 2);

    // info(strfmt("_refresh r,g,b: %1,%2,%3 bgColor: %4 hexValue: %5",r,g,b,bgcolor,hexvalue));

    RptHdrFontColorControl.backgroundColor(bgColor);

    // reset foreground color to contrast background color

    if (y <= luminanceThreshold)

    {

    RptHdrFontColorControl.foregroundColor(pureWhiteInt);

    }

    else

    {

    RptHdrFontColorControl.foregroundColor(pureBlackInt);

    }

    }

    ... and here is the form control method that actually updates my table...

    public void lookup()

    {

    Common common;

    Container c;

    int64 r, g, b;

    int64 bgColor;

    str hexValue;

    ;

    c = WinAPI::RGBint2Con(hex2Int(strRem(mbsbdSSRSTextTagReplacement.RptHdrFontColor, "#")));

    // set current r,g,b value for color picker

    r = conpeek(c,1);

    g = conpeek(c,2);

    b = conpeek(c,3);

    c = WinAPI::chooseColor(this.hWnd(), r, g, b, NULL, true);

    // set new r,g,b value to repaint

    r = conpeek(c,1);

    g = conpeek(c,2);

    b = conpeek(c,3);

    if (conlen(c))

    {

    bgColor = WinAPI::RGB2int(r, g, b);

    hexValue = int2Hex(r,2) + int2Hex(g,2) + int2Hex(b,2);

    mbsbdSSRSTextTagReplacement.RptHdrFontColor = strFmt("#%1", hexValue);

    }

    // info(strfmt("_lookup r,g,b: %1,%2,%3 bgColor: %4 hexValue: %5",r,g,b,bgcolor,hexvalue));

    }

    So, basically, my red and blue channels are being swapped. I just need to figure out how to deal with it! :crazy:

Viewing 15 posts - 16 through 30 (of 45 total)

You must be logged in to reply to this topic. Login to reply