<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ixto-Blog &#187; Marcel Ebner</title>
	<atom:link href="http://www.ixto.de/blog/author/mebner/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ixto.de/blog</link>
	<description>Business Intelligence, Database Consulting, Software Development</description>
	<lastBuildDate>Mon, 26 Sep 2011 09:23:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>SSAS 2005 MDX Simple CASE WHEN &#8211; Probleme im ELSE Zweig</title>
		<link>http://www.ixto.de/blog/sql-server-2005/analysis-services-2005/ssas-2005-mdx-simple-case-when-probleme-im-else-zweig/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/analysis-services-2005/ssas-2005-mdx-simple-case-when-probleme-im-else-zweig/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 16:06:26 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Analysis Services 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=275</guid>
		<description><![CDATA[Manchmal, aus welch guten oder schlechten Gründen auch immer, muss man in berechneten Measures eines SSAS 2005 Cubes mehrere Zustände eines Members unterschiedlich behandeln. Dies erreicht man durch die Verwendung von IIF Statements, oder, ein wenig bequemer, durch die Verwendung von CASE WHEN Statements.

Das CASE WHEN Statement  wird in zwei Typen unterteilt:
A) “Simple” CASE:
CASE [MyValue]
  [...]]]></description>
			<content:encoded><![CDATA[<p>Manchmal, aus welch guten oder schlechten Gründen auch immer, muss man in berechneten Measures eines SSAS 2005 Cubes mehrere Zustände eines Members unterschiedlich behandeln. Dies erreicht man durch die Verwendung von IIF Statements, oder, ein wenig bequemer, durch die Verwendung von CASE WHEN Statements.<br />
<span id="more-275"></span></p>
<p>Das CASE WHEN Statement  wird in zwei Typen unterteilt:</p>
<p>A) “Simple” CASE:</p>
<p>CASE [MyValue]<br />
  WHEN 100 THEN „Small“<br />
  WHEN 1000 THEN “Middle”<br />
  WHEN 10000 THEN “Large”<br />
ELSE “Micro” END</p>
<p>B) “Searched” CASE:</p>
<p>CASE<br />
  WHEN [MyValue] = 100 THEN „Small“<br />
  WHEN [MyValue] = 1000 THEN “Middle”<br />
  WHEN [MyValue] = 10000 THEN “Large”<br />
ELSE “Micro”<br />
END</p>
<p>Wie Chris Webb in seinem <a href="http://cwebbbi.wordpress.com/2009/12/09/simple-vs-searched-case-statements/">BI-Blog</a> mitteilt, ist die Verwendung von Simple CASE performanter als Searched CASE, allerdings kann in der SQL Server Version 2005 die Verwendung von Simple CASE unter gewissen Umständen fehlerhafte Ergebnisse im ELSE Zweig erzeugen.</p>
<p>Voraussetzung dafür ist, dass in irgendeinem der Zweige ein anderes, berechnetes Measure benutzt wird, welches wiederum aus einem Tupel mit mindestens einer Dimensionsreferenz bestehen muss. Bsp:</p>
<p><span style="color: #0000ff;">CREATE MEMBER CURRENTCUBE</span>.[Measures].TestCalc <span style="color: #0000ff;">AS</span></p>
<p>([Date].[Calendar Year].&amp;[2003],[Measures].[Sales Amount]),</p>
<p><span style="color: #0000ff;">Visible</span>=1,<span style="color: #0000ff;">FORMAT_STRING</span>=<span style="color: #a30000;">&#8220;#,###0.00&#8243;</span>;</p>
<p>Folgend die Definition eines berechneten Elements mit einer SIMPLE CASE Entscheidung auf Basis der AdventureWorks DW 2005 OLAP Datenbank:<br />
<em>(Ich bitte den Sinn der angeführten Berechnungen in den Hintergrund zu stellen … <img src='http://www.ixto.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </em></p>
<p><span style="color: #0000ff;">CREATE MEMBER CURRENTCUBE</span>.[Measures].SimpleCase <span style="color: #0000ff;">AS</span></p>
<p><span style="color: #0000ff;">CASE</span> [Date].[Calendar Year].<span style="color: #a30000;">CURRENTMEMBER</span></p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].&amp;[2002] <span style="color: #0000ff;">THEN</span></p>
<p>      ([Product].[Product Line].&amp;[S],[Measures].TestCalc)</p>
<p>    + ([Product].[Product Line].&amp;[],[Measures].TestCalc)</p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].&amp;[2003] <span style="color: #0000ff;">THEN</span></p>
<p>      ([Product].[Product Line].&amp;[],[Measures].[Sales Amount])</p>
<p>    + ([Product].[Product Line].&amp;[S],[Measures].[Sales Amount])</p>
<p>    <span style="color: #0000ff;">ELSE</span>   <span style="color: #008000;">&#8211; &#8220;Any other year – Product line MOUNTAIN</span></p>
<p>      ([Product].[Product Line].&amp;[M],[Measures].[Sales Amount])</p>
<p><span style="color: #0000ff;">END</span>,</p>
<p><span style="color: #0000ff;">Visible</span>=1,<span style="color: #0000ff;">FORMAT_STRING</span>=<span style="color: #a30000;">&#8220;#,###0.00&#8243;</span>;</p>
<p>Das Measure summiert die Produktlinien „Accessorys“ und „Components“ in den Pfaden 2002 und 2003, benutzt im Pfad für das Jahr 2002 das Measure „TestCalc“ und zeigt im ELSE Zweig den Sales Amount der Produktinie „Mountain“ an.<em> </em></p>
<p>Ein berechnetes Element mit Verwendung der Searched CASE Variante würde dann wie folgt definiert werden müssen:</p>
<p><span style="color: #0000ff;">CREATE MEMBER CURRENTCUBE</span>.[Measures].SearchedCase <span style="color: #0000ff;">AS</span></p>
<p><span style="color: #0000ff;">CASE</span></p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].<span style="color: #a30000;">CURRENTMEMBER</span></p>
<p>     <span style="color: #0000ff;">IS</span> [Date].[Calendar Year].&amp;[2002] <span style="color: #0000ff;">THEN</span></p>
<p>     ([Product].[Product Line].&amp;[S],[Measures].TestCalc)</p>
<p>   + ([Product].[Product Line].&amp;[],[Measures].TestCalc)</p>
<p>    <span style="color: #0000ff;">WHEN</span> [Date].[Calendar Year].<span style="color: #a30000;">CURRENTMEMBER</span></p>
<p>      <span style="color: #0000ff;">IS</span> [Date].[Calendar Year].&amp;[2003] <span style="color: #0000ff;">THEN</span></p>
<p>      ([Product].[Product Line].&amp;[S],[Measures].[Sales Amount])</p>
<p>    + ([Product].[Product Line].&amp;[],[Measures].[Sales Amount])</p>
<p>    <span style="color: #0000ff;">ELSE</span>   <span style="color: #008000;">&#8211; &#8220;Any other year – Product line MOUNTAIN</span></p>
<p>     ([Product].[Product Line].&amp;[M],[Measures].[Sales Amount])</p>
<p>    <span style="color: #0000ff;">END</span>,</p>
<p><span style="color: #0000ff;">Visible</span>=1,<span style="color: #0000ff;">FORMAT_STRING</span>=<span style="color: #a30000;">&#8220;#,###0.00&#8243;</span>;</p>
<p>Das Ergebnis ist verblüffend, zieht man beide berechneten Member in die Abfrage eines Cubebrowsers:</p>
<p>Zeilen   : Dimension Promotion, Attribut Promotion<br />
Filter    : Date.Calendar Year = 2004; Product.Product Line = Mountain</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/me_ssas_05.jpg" alt="" /></p>
<p>Wie man sieht, wird die Gesamtsumme in beiden Membern korrekt angezeigt, im Simple CASE Measure werden jedoch die Ergebnisse für die unteren beiden Zeilen NICHT angezeigt. Das Phänomen / Bug tritt NUR im SQL Server 2005 auf und NUR bei Verwendung eines berechneten Measures mit o.g. Bedingungen in irgendeinem der CASE Zweige.</p>
<p>Gefährlich bleibt es trotzdem, kontrolliert man nämlich nur die Gesamtsummen (was der eine oder andere Developer aus Zeitgründen sicher schon mal getan hat), fällt der Fehler eben NICHT auf.</p>
<p>Deswegen:</p>
<p>Checkt Eure CASE WHEN Member! Vor allem darauf ob Ihr Euch die Verwendung nicht ganz sparen wollt/könnt <img src='http://www.ixto.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/analysis-services-2005/ssas-2005-mdx-simple-case-when-probleme-im-else-zweig/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spaltenreihenfolge in Drillthrough Actions</title>
		<link>http://www.ixto.de/blog/sql-server-2008/spaltenreihenfolge-in-drillthrough-actions/</link>
		<comments>http://www.ixto.de/blog/sql-server-2008/spaltenreihenfolge-in-drillthrough-actions/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 14:05:44 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Analysis Services 2008]]></category>
		<category><![CDATA[MDX im SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/?p=142</guid>
		<description><![CDATA[Wer schon einmal Excel Drillthrough-Actions in einem Cube erstellt hat, wird sich mit Sicherheit mindestens zweimal durch das Fenster &#8220;Drillthroughspalten&#8221; geklickt haben, schließlich kann es kaum vorkommen, dass man schon beim ersten Mal exakt die Informationen trifft, die der Kunde nach der Präsentation des Drillthrough-Features für beachtenswert hält. Entweder hat man die falschen Dimensionen und [...]]]></description>
			<content:encoded><![CDATA[<p>Wer schon einmal Excel Drillthrough-Actions in einem Cube erstellt hat, wird sich mit Sicherheit mindestens zweimal durch das Fenster &#8220;Drillthroughspalten&#8221; geklickt haben, schließlich kann es kaum vorkommen, dass man schon beim ersten Mal exakt die Informationen trifft, die der Kunde nach der Präsentation des Drillthrough-Features für beachtenswert hält. Entweder hat man die falschen Dimensionen und Attribute gewählt oder die Reihenfolge ist unglücklich.<br />
 <span id="more-142"></span><br />
<br\><br />
Wer dann, mit Hoffnung im Herzen und einem Mausklick rechts, versucht, im Kontextmenü den Eintrag &#8220;Reihenfolge ändern&#8221; oder &#8220;Dimension auswählen&#8221; zu finden, wird bitter enttäuscht. Zu sehen gibt&#8217;s nur &#8220;Löschen&#8221;.</p>
<p><img src="http://reborn-resistance.com/user/ric/ixto/blog/me/01_Kontextmenue.jpg" alt="" /><br />
<br\><br />
So bleibt der Versuch, <strong><em>zwischen</em></strong> zwei vorhandenen Dimensionen noch eine dritte hinzuzufügen oder allein einen Eintrag zu ändern, von Misserfolg gekrönt und man darf sich die Aktionsspalten nochmal ganz von vorn zusammenklicken. Will man darüber hinaus gar <strong><em>die Reihenfolge der Attribute</em></strong> einer Dimension ändern, ist man (fast) hilflos der von Visual Studio angebotenen Reihenfolge ausgeliefert, deren Sortierungsgrundlage wohl immer ein Geheimnis bleiben wird.<br />
<br\><br />
Zum Glück gibt es noch die Möglichkeit im XMLA Script des Cubes selbst einzugreifen.<br />
<br\><br />
Hierzu sollte man im Reiter &#8220;Aktionen&#8221; im Fenster &#8220;Aktionsplaner&#8221; die eben erstellte Drillthrough-Aktion auswählen, in der Eigenschaft [ID] den entsprechenden Wert auslesen und im Projektmappenexplorer mit Rechtsklick auf den entsprechenden Cube &#8220;Code anzeigen&#8221; wählen. VisualStudio öffnet eine neue Reiterkarte mit der Cubedefinition im XMLA Format, mit Strg+F kann man den Abschnitt mit der Drillthrough-Aktion schnell finden. (Die XML-Elemente &lt;ID&gt;,&lt;Name&gt; und die &lt;Columns&gt; Sequenz müssen vorhanden sein, das Actions-Element ist unterhalb der KPIs zu finden)</p>
<p><img src="http://reborn-resistance.com/user/ric/ixto/blog/me/02_XMLA.jpg" alt="" /><br />
<br\><br />
Nun kann man die Elemente &lt;Column&gt; innerhalb des &lt;Columns&gt;-Element per Cut&amp;Paste verschieben. Leider gibt es (bisher) keine Möglichkeit den Anzeigenamen der Spalten in Excel festzulegen, aber, immerhin, die Reihenfolge der Attribute (Column) ist nun frei wählbar. Speichert man dann die Änderungen ab, verändert sich auch die Anzeige der Dimensionsreihenfolge im Fenster &#8220;Drillthroughspalten&#8221;, zwar erkennt der Designer nur, dass eine <strong><em>Dimension</em></strong> vor den Measures steht und zeigt dementsprechend <strong><em>alle</em></strong> Attribute der Dimension vor dem Measure an, die Reihenfolge der Spalten aber, wie sie im XMLA Script festgelegt ist, bleibt beim Exceldrillthrough erhalten.</p>
<p><img src="http://reborn-resistance.com/user/ric/ixto/blog/me/03_Sorted.jpg" alt="" /><br />
<br\><br />
<span style="font-size: 9pt;">(<em>nur Promotion Name vor SalesSummary, nicht auch End Date und Start Date)</em></span><br />
<br\><br />
<img src="http://reborn-resistance.com/user/ric/ixto/blog/me/04_Excel.jpg" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2008/spaltenreihenfolge-in-drillthrough-actions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSAS 2005 MDX Tuning – unnötige MEMBER und fast noch schlimmer: STRTOMEMBER</title>
		<link>http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 16:29:55 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Analysis Services 2005]]></category>
		<category><![CDATA[SQL Server 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/</guid>
		<description><![CDATA[&#8220;Das beste MDX ist das, das man nicht schreibt&#8221; (über den Buschfunk: Mosha Pasumansky)
Aber wer kommt denn auf die Idee, dass dieses Zitat wortwörtlich zu nehmen ist?
Ich sah mich mit einer Kundendimension von 172.000 Kunden konfrontiert, die etwa 200 Vertretern zugeordnet waren. Ergebnis der Abfrage sollten die Kunden sein, die in einem gewissen Monat keine [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Das beste MDX ist das, das man nicht schreibt&#8221; (über den Buschfunk: Mosha Pasumansky)</p>
<p>Aber wer kommt denn auf die Idee, dass dieses Zitat wortwörtlich zu nehmen ist?</p>
<p>Ich sah mich mit einer Kundendimension von 172.000 Kunden konfrontiert, die etwa 200 Vertretern zugeordnet waren. Ergebnis der Abfrage sollten die Kunden sein, die in einem gewissen Monat keine Umsätze, dafür aber im Rest des Jahres Umsätze erzielt hatten.</p>
<p><span id="more-77"></span><br />
<br />
 Übersetzt in den AdventureWorks Cube, wobei der Vertreter hier durch die Dimension &#8220;Produkt&#8221; ersetzt wird, sah die Abfrage zuerst so aus:</p>
<p><span style="font-family: Courier New; color: blue; font-size: 10pt;">WITH<br />
</span></p>
<p><span style="font-family: Courier New;"><span style="font-size: 10pt;"><span style="color: blue;">MEMBER</span><br />
</span><span style="color: #c00000; font-size: 12pt; text-decoration: underline;"><strong><em>UmsatzDezember03</em></strong></span><span style="font-size: 10pt;"><br />
<span style="color: blue;">AS</span><br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">(<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    ,<span style="color: maroon;">STRTOMEMBER</span>(&#8216;[Date].[Calendar].[Month].&amp;[2003]&amp;[12]&#8216;, <span style="color: blue;">CONSTRAINED</span>)<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">)<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SET</span> Kunden <span style="color: blue;">AS</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">EXCEPT</span>(<span style="color: maroon;">EXISTS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">(<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">        ,[Measures].[Internet Sales Amount])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">        ,[Product].[Product Categories].[Category].&amp;[1])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">,<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New;"><span style="font-size: 10pt;">    ,</span><span style="color: #c00000; font-size: 12pt; text-decoration: underline;"><strong><em>UmsatzDezember03</em></strong></span><span style="font-size: 10pt;">))<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">SELECT</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 0,<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    Kunden<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 1 <span style="color: blue;">FROM</span> [Adventure Works]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">WHERE</span> [Date].[Calendar].[Calendar Year].&amp;[2003]<br />
</span><br />
<br\><br />
Um der besseren Lesbarkeit willen erstellte ich das berechnete MEMBER UmsatzDezember03 um das &#8211; zugegeben etwas komplizierte – Kundenset zu filtern.<br />
<br\><br />
Die ursprüngliche Abfrage (nicht das Beispiel hier) benötigte 45 Sekunden, was bei einer so kleinen Dimension von 172.000 Membern nicht akzeptabel war. Query-Tuning war also unumgänglich.<br />
<br\><br />
Nehmen wir uns des Beispiels oben an: Diese Abfrage &#8211; mit <a href="http://cid-74f04d1ea28ece4e.skydrive.live.com/self.aspx/MDXStudio/v0.4.12/MDXStudio2005.zip">&#8220;MDX Studio&#8221;</a> auf dem AdventureWorks Cube ausgeführt &#8211; berechnete 44.240 Zellen und benötigte 2,6 Sekunden für die Ausführung.<br />
<br\><br />
Mosha&#8217;s Befehl zur Sparsamkeit gehorchend, verzichtete ich auf das Hilfsmember und brachte den Ausdruck für UmsatzDezember03 direkt in das Kundenset.</p>
<p><span style="font-family: Courier New; color: blue; font-size: 10pt;">WITH<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SET</span> Customers <span style="color: blue;">AS</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">EXCEPT</span>(<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    <span style="color: maroon;">EXISTS</span>(<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">                ,[Measures].[Internet Sales Amount])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">        ,[Product].[Product Categories].[Category].&amp;[1])<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">,<span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS<br />
</span></span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    ,(<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    ,<span style="color: maroon;">STRTOMEMBER</span>(&#8216;[Date].[Calendar].[Month].&amp;[2003]&amp;[12]&#8216;,<span style="color: blue;"> CONSTRAINED</span>)<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">)))<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">SELECT</span><br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    [Measures].[Internet Sales Amount]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 0,<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">{<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">    Customers<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 1 <span style="color: blue;">FROM</span> [Adventure Works]<br />
</span></p>
<p><span style="font-family: Courier New; font-size: 10pt;"><br />
<span style="color: blue;">WHERE</span> [Date].[Calendar].[Calendar Year].&amp;[2003]</span><br />
<br\><br />
Dies führte zu einer Berechnung von nur 7.272 Zellen, benötigte aber immer noch 2,6 Sekunden für die Ausführung. Nachdem ich mir auch das <span style="font-family: Courier New; color: blue; font-size: 10pt;">CONSTRAINED</span> Flag in der <span style="color: maroon;">STRTOMEMBER </span>Funktion erspart hatte, lag die Ausführungszeit bei 0,6 Sekunden.<br />
<br\><br />
Was war passiert? Offensichtlich führte das Einfügen des berechneten Members UmsatzDezember03 dazu, das die Berechnung für den Term <span style="font-family: Courier New;"><span style="font-size: 10pt;"><span style="color: maroon;">NONEMPTY</span>([Customer].[Customer].[Customer].<span style="color: blue;">MEMBERS</span>,</span><span style="color: #c00000; font-size: 12pt; text-decoration: underline;"><strong><em>UmsatzDezember03</em></strong></span><span style="font-size: 10pt;">)</span></span> für <strong>jedes</strong> einzelne Member der Kundendimension ausgeführt wurde – d.h. je mehr Member in der Dimension enthalten sind, desto langsamer wird die Abfrage.<br />
<br\><br />
Darüber hinaus ist festzustellen, dass das CONSTRAINED Flag die Query ebenfalls verlangsamt – was uns zu dem Schluss führt, das Mosha&#8217;s Zitat tatsächlich wortwörtlich zu nehmen ist. Allein das Einsparen der Worte &#8220;MEMBER, AS, STRTOMEMBER und CONSTRAINED&#8221; führt in obigem Beispiel zu einer Beschleunigung der Abfrage von 500% und zu einer 86%-igen Reduktion der berechneten Zellen.<span style="font-family: Courier New; color: blue; font-size: 10pt;"><br />
</span><br />
<br\><br />
In den Analysis Services 2008 tritt dieses Problem nicht mehr auf. &#8220;Hilfsmember&#8221; können hier ohne Scham verwendet werden. Beide auf einem SQL Server 2008 ausgeführten Abfragen berechneten nur die nötigen 7.272 Zellen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/ssas-2005-mdx-tuning-%e2%80%93-unnotige-member-und-fast-noch-schlimmer-strtomember/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MDX ParallelPeriod – bleib auf Deinem Level (Andere gibt’s vielleicht nicht)</title>
		<link>http://www.ixto.de/blog/sql-server-2005/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 14:05:31 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[MDX im SQL Server 2005]]></category>
		<category><![CDATA[MDX im SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/allgemein/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/</guid>
		<description><![CDATA[Um innerhalb einer Zeitdimension zurückliegende Member zu erreichen braucht es kein Voodoo, MDX stellt eine bequeme Funktion namens &#8220;PARALLELPERIOD&#8221; zur Verfügung, welche zu einem angegebenen Element (Bsp. August 2003) über eine Ebene der Zeitdimension (Monat, Quartal, Jahr …) eine bestimmte Anzahl von Schritten (12 Monate, 2 Jahre o. ä.) zurück oder vorwärts geht.


Zum Beispiel folgende [...]]]></description>
			<content:encoded><![CDATA[<p>Um innerhalb einer Zeitdimension zurückliegende Member zu erreichen braucht es kein Voodoo, MDX stellt eine bequeme Funktion namens &#8220;PARALLELPERIOD&#8221; zur Verfügung, welche zu einem angegebenen Element (Bsp. August 2003) über eine Ebene der Zeitdimension (Monat, Quartal, Jahr …) eine bestimmte Anzahl von Schritten (12 Monate, 2 Jahre o. ä.) zurück oder vorwärts geht.</p>
<p><span id="more-71"></span><br />
<br\><br />
Zum Beispiel folgende Abfrage:</p>
<p style="margin-left: 35pt;"><span style="color: blue; font-family: Courier New; font-size: 10pt;">WITH</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">MEMBER</span> LevelMonth_OneYearAgo <span style="color: blue;">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">PARALLELPERIOD</span>([Date].[Calendar].[Month],12,</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].<span style="color: maroon;">CURRENTMEMBER</span>).<span style="color: blue;">MEMBER_CAPTION</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">MEMBER</span> LevelYear_OneYearAgo <span style="color: blue;">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">PARALLELPERIOD</span>([Date].[Calendar].[Calendar Year],1,</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].<span style="color: maroon;">CURRENTMEMBER</span>).<span style="color: blue;">MEMBER_CAPTION</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">SELECT</span> {</span><br />
<span style="font-family: Courier New; font-size: 10pt;">LevelMonth_OneYearAgo</span><br />
<span style="font-family: Courier New; font-size: 10pt;">,LevelYear_OneYearAgo</span><br />
<span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 0 ,</span><br />
<span style="font-family: Courier New; font-size: 10pt;">{</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].[Month].&amp;[2003]&amp;[8]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">}<span style="color: blue;">ON</span> 1 <span style="color: blue;">FROM</span> [Adventure Works]</span></p>
<p>liefert zurück:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel1.png" alt="" /><br />
<br\><br />
Obwohl das Hierarchielevel &#8220;[Date].[Calendar].[Calendar Year]&#8221; auf keiner Achse angegeben ist, kann es durch seine bestehende Attributrelation zur Ebene &#8220;[Date].[Calendar].[Month]&#8221; angesprochen werden .<br />
<br\><br />
Sind also Attributbeziehungen innerhalb der verschiedenen Zeitebenen definiert, können auch andere als in der Abfrage verwendete Ebenen der Zeitdimension mit PARALLELPERIOD verwendet werden.<br />
<br\><br />
Was aber passiert, wenn es im angegebenen zurückliegenden Zeitraum keinen Member gibt? Im AdventureWorks Cube 2008 ist der erste Member der Zeitdimension der erste Juli 2001. Ersetzt man den oben abgefragten Monat auf der Achse mit &#8220;[Date].[Calendar].[Month].&amp;[2002]&amp;[6]&#8221; liefert die Abfrage folgendes zurück:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel2.png" alt="" /><br />
<br\><br />
Das Ergebnis für PARALLELPERIOD mit Level &#8220;Month&#8221; ist korrekt, aber was ist mit dem Ergebnis für Level &#8220;Year&#8221; los? Angezeigt wird der Dezember 2001, der nun definitiv kein Jahr hinter dem Juni 2002 liegt. In diesem Fall wird nun der letzte Monat des Vorjahres angezeigt, also das letzte Member der darunterliegenden Ebene. Auch darauf sollte man sich nun nicht verlassen, beachten Sie das folgende Beispiel (und, wenn möglich, führen Sie das Statement auch mal auf Ihrem eigenen Adventure Works Cube aus)<br />
<br\><br />
Ziel der Abfrage ist den allseits beliebten &#8220;Sales Amount&#8221; der Monate 2001 bis Ende 2002 zu ermitteln. Beim Cubebrowsen stellt sich folgendes heraus:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel3.png" alt="" /><br />
<br\><br />
Zwischen Januar 2001 und Juni 2001 sind keine Werte für &#8220;Sales Amount&#8221; vorhanden, eine ähnliche MDX-Abfrage wie folgende:</p>
<p style="margin-left: 35pt;"><span style="color: blue; font-family: Courier New; font-size: 10pt;">WITH</span><br />
<span style="color: green; font-family: Courier New; font-size: 10pt;">//LAG: </span><br />
<span style="color: green; font-family: Courier New; font-size: 10pt;">Gibt das Element zurück, das eine angegebene Anzahl von Positionen (hier 12) vor einem angegebenen Element entlang der Dimension des Elements liegt.</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">MEMBER</span> [Measures].[Lag_Month] <span style="color: blue;">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;">([Measures].[Sales Amount],</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].<span style="color: maroon;">CURRENTMEMBER</span>.<span style="color: blue;">LAG</span>(12))</span><br />
<span style="color: green; font-family: Courier New; font-size: 10pt;"><br />
//PARALLELPERIOD: Gibt ein Element aus einer früheren Periode in derselben relativen Position wie ein angegebenes Element zurück</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;">MEMBER</span> [Measures].[PP_LevelMonth] <span style="color: blue;">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;">([Measures].[Sales Amount],</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">PARALLELPERIOD</span>([Date].[Calendar].[Month],12,</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].<span style="color: maroon;">CURRENTMEMBER</span>))</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;"><br />
MEMBER</span> [Measures].[PP_LevelYear] <span style="color: blue;">AS</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;">([Measures].[Sales Amount],</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: maroon;">PARALLELPERIOD</span>([Date].[Calendar].[Calendar Year],1,</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].<span style="color: maroon;">CURRENTMEMBER</span>))</span><br />
<span style="font-family: Courier New; font-size: 10pt;"><span style="color: blue;"><br />
SELECT</span> {</span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Measures].[Sales Amount]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">,[Measures].[Lag_Month]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">,[Measures].[PP_LevelMonth]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">,[Measures].[PP_LevelYear]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 0,</span><br />
<span style="font-family: Courier New; font-size: 10pt;">{ <span style="color: green;">//Level month on axis 1</span></span><br />
<span style="font-family: Courier New; font-size: 10pt;">[Date].[Calendar].[Month].&amp;[2001]&amp;[7]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">    : [Date].[Calendar].[Month].&amp;[2002]&amp;[12]</span><br />
<span style="font-family: Courier New; font-size: 10pt;">} <span style="color: blue;">ON</span> 1 <span style="color: blue;">FROM</span> [Adventure Works]</span></p>
<p>ergibt:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/101209_0001_Parallel4.png" alt="" /><br />
<br\><br />
Die &#8220;Sales Amount&#8221; Werte für das mit PARALLELPERIOD Level &#8220;Year&#8221; erstellte Member sind in Unordnung geraten. Schon ab Januar 2002 werden die rückliegenden Werte angezeigt, obwohl erst der Juli 2002 Werte für das aktuelle und das zurückliegende Jahr aufweist.<br />
<br\><br />
Die Werte der Member welche mit der MDX Funktion &#8220;Lag&#8221; oder mit dem in der Achse verwendeten Level, nämlich &#8220;Month&#8221; erstellt wurden sind korrekt.</p>
<p>Deshalb, &#8220;Schuster &#8211; bleib bei Deinem Leisten&#8221; und bei PARALLELPERIOD im abgefragten Level.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/mdx-parallelperiod-%e2%80%93-bleib-auf-deinem-level-andere-gibt%e2%80%99s-vielleicht-nicht/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kaskadierende Parameter – Easy as can be</title>
		<link>http://www.ixto.de/blog/sql-server-2005/reportingservices/kaskadierende-parameter-%e2%80%93-easy-as-can-be/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/reportingservices/kaskadierende-parameter-%e2%80%93-easy-as-can-be/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 09:41:57 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Reporting Services 2005]]></category>
		<category><![CDATA[Reporting Services 2008]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/sql-server-2005/reportingservices/kaskadierende-parameter-%e2%80%93-easy-as-can-be/</guid>
		<description><![CDATA[Herr G. Ordnet, Controller der Firma Adventure Works, möchte sich für ausgewählte Produkte seines Unternehmens die Internetverkäufe und die Frachtkosten ansehen. Er beauftragt den Reportbauer Z. Schnell mit dem Erstellen eines Berichts. Selbiger überdenkt die Anforderung und stellt einen Bericht mit einer Parameterliste aller Produkte zur Verfügung.

Nachdem Herr G. Ordnet mehrere Male alle 606 Produkte [...]]]></description>
			<content:encoded><![CDATA[<p>Herr G. Ordnet, Controller der Firma Adventure Works, möchte sich für ausgewählte Produkte seines Unternehmens die Internetverkäufe und die Frachtkosten ansehen. Er beauftragt den Reportbauer Z. Schnell mit dem Erstellen eines Berichts. Selbiger überdenkt die Anforderung und stellt einen Bericht mit einer Parameterliste aller Produkte zur Verfügung.<br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren1.jpg" alt="" width="306" height="186" /><br />
Nachdem Herr G. Ordnet mehrere Male alle 606 Produkte seiner Firma in der Auswahlkombobox des Berichtes durchforstet hat, platzt ihm der Kragen und er bittet um eine &#8220;vernünftige Einschränkung der Produkte nach Kategorien.&#8221;</p>
<p><span id="more-59"></span><br />
<br\><br />
Ein Glück, dass in der Datenbank diese Produktkategorien vorhanden sind, denkt sich Herr Schnell und entwickelt die sog. &#8220;cascading parameters&#8221; &#8211; also voneinander abhängige, hierarchisch angeordnete Parameter, deren Auswahl die Wertanzahl folgender Parameter einschränkt.<br />
<br\><br />
Zuerst werden im Report drei statt einem Parameter erzeugt. Alle Parameter sind mehrwertig und haben keinen Standardwert.</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren2.jpg" alt="" width="256" height="144" /><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren3.jpg" alt="" width="144" height="156" /><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren4.jpg" alt="" width="387" height="87" /><br />
<br\><br />
Dann werden drei Datasets für die Parameter mit folgenden Statements angelegt:</p>
<p><strong>Produktkategorie:<br />
</strong></p>
<p>SELECT      ProductCategoryKey, EnglishProductCategoryName FROM  DimProductCategory</p>
<p><strong>Produktunterkategorie:<br />
</strong></p>
<p>SELECT        ProductSubcategoryKey, EnglishProductSubcategoryName FROM         DimProductSubcategory</p>
<p><span style="color: #4f81bd;"><strong>WHERE        (ProductCategoryKey IN (@ProductCategory))</strong><br />
</span></p>
<p><strong>Produkte selbst</strong>:</p>
<p>SELECT        EnglishProductName, ProductKey FROM  DimProduct</p>
<p><span style="color: #4f81bd;"><strong>WHERE        (ProductSubcategoryKey IN (@ProdSubCategory))</strong><br />
</span><br />
<br\><br />
Schlussendlich erzeugt Herr Schnell ein Dataset für die Werteabfrage:<br />
<strong></strong><br />
SELECT   DimProduct.EnglishProductName, FactInternetSales.OrderQuantity * FactInternetSales.UnitPrice AS OrderVolume, FactInternetSales.Freight FROM DimProduct INNER JOIN FactInternetSales ON DimProduct.ProductKey = FactInternetSales.ProductKey</p>
<p><span style="color: #4f81bd;"><strong>WHERE  (FactInternetSales.ProductKey IN (@Products))</strong><br />
</span><br />
<strong></strong><br />
<br\><br />
Weil Herr Schnell auf Standardwerte verzichtet hat, und alle vom vorhergehenden Parameter abhängigen Parameterabfragen ohne eine Auswahl des vorhergehenden Parameters nicht getätigt werden können, sind die Auswahlboxen der nachfolgenden Parameter solange deaktiviert, bis die nötige Vorauswahl von Kategorien oder Unterkategorien abgeschlossen ist.</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren5.jpg" alt="" width="609" height="62" /><br />
<strong> </strong><br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren6.jpg" alt="" width="609" height="103" /></p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/071009_0941_Kaskadieren7.jpg" alt="" width="609" height="190" /><br />
<br\><br />
Nun hat Herr G. Ordnet nur die Produkte zur Auswahl, deren Anzahl er vorher durch die Auswahl an Kategorien eingeschränkt hat – und Herr Schnell noch seinen Job.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/reportingservices/kaskadierende-parameter-%e2%80%93-easy-as-can-be/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamische Rahmen innerhalb einer Matrix und/oder die Knechtschaft des Layouts durch das Dataset</title>
		<link>http://www.ixto.de/blog/sql-server-2005/reportingservices/dynamische-rahmen-innerhalb-einer-matrix-undoder-die-knechtschaft-des-layouts-durch-das-dataset/</link>
		<comments>http://www.ixto.de/blog/sql-server-2005/reportingservices/dynamische-rahmen-innerhalb-einer-matrix-undoder-die-knechtschaft-des-layouts-durch-das-dataset/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 17:29:19 +0000</pubDate>
		<dc:creator>Marcel Ebner</dc:creator>
				<category><![CDATA[Reporting Services 2005]]></category>

		<guid isPermaLink="false">http://www.ixto.de/blog/sql-server-2005/reportingservices/dynamische-rahmen-innerhalb-einer-matrix-undoder-die-knechtschaft-des-layouts-durch-das-dataset/</guid>
		<description><![CDATA[1. Die Anforderung ist simpel:

&#8220;Die Linien innerhalb der Matrix sollen Grau und die untere Zeile soll bitte schwarz sein.&#8221;

Die meisten Reportdesigner schreiben sich solch ein Anliegen gar nicht auf, sondern setzen schlicht die Rahmenfarbe der Zeilen auf Grau und die des Subtotals auf Schwarz und reichen den Report zufrieden weiter.


Ergebnis:


2. Die Anforderung erweitert sich &#8220;gering&#8221;:

&#8220;Sehr [...]]]></description>
			<content:encoded><![CDATA[<p>1. Die Anforderung ist simpel:<br />
<br\><br />
&#8220;Die Linien innerhalb der Matrix sollen Grau und die untere Zeile soll bitte schwarz sein.&#8221;<br />
<br\><br />
Die meisten Reportdesigner schreiben sich solch ein Anliegen gar nicht auf, sondern setzen schlicht die Rahmenfarbe der Zeilen auf Grau und die des Subtotals auf Schwarz und reichen den Report zufrieden weiter.</p>
<p><span id="more-41"></span><br />
<br\><br />
Ergebnis:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR1.jpg" alt="" /><br />
<br\><br />
2. Die Anforderung erweitert sich &#8220;gering&#8221;:<br />
<br\><br />
&#8220;Sehr geehrter Reportdesigner, die senkrechten Linien gefallen uns nicht, könnten Sie stattdessen einen Abstand zwischen die Länderspalten einbauen?&#8221;<br />
<br\><br />
Noch kommt keine Unruhe auf, flugs wird folgendes Design umgesetzt:<br />
Auf den Zeilen wird eine neue Gruppe mit derselben Gruppierung wie die vorhergehende und im Detailfeld der Matrix einfach eine weitere Spalte eingefügt.<br />
Die Rahmen der eingefügten Abstandsspalten bleiben unsichtbar, die Rahmenfarbe des Subtotals bleibt weiterhin schwarz.</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR2.jpg" alt="" /><br />
<br\><br />
Ergebnis:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR3.jpg" alt="" /><br />
<br\><br />
Die Linie des Subtotals zieht sich leider über alle Spalten hinweg. Dies mag dem einen oder anderen nicht der Rede wert erscheinen, ärgerlich und unschön bleibt es trotzdem.<br />
<br\><br />
Konsequenz des pfiffigen Reportdesigners:<br />
<br\><br />
<strong>Ausblenden der Rahmen des Subtotals und Formatierung der Rahmenfarbe der Zeilengruppen und des Detailfeldes!<br />
</strong><br />
<br\><br />
Dies kann durch folgende Ausdrücke erreicht werden <span style="font-size: 9pt;"><em>(bei BorderStyle, Bottom=Solid)</em></span><br />
<br\><br />
Für die Zeilengruppen (Textbox Product) gilt:<br />
<span style="color: #0070c0;">BorderColor=IIF(RowNumber(&#8220;MyDataSetName&#8221;)=CountRows(&#8220;MyDataSetName&#8221;), &#8220;Black&#8221;,&#8221;Silver&#8221;)</span><span style="color: #548dd4;"><br />
</span>d.h.:<span style="color: #1f497d;"><br />
</span>Wenn die letzte Zeile des Datasets erreicht ist, färbe die Rahmen bitte Schwarz ein, sonst Silber.<br />
<br\><br />
Für die Zeile funktioniert das prima, für das Detailfeld muss aber auf die letzte Zeile der <strong>Spaltengruppe</strong> verwiesen werden, da das Scope <span style="color: #1f497d;">(&#8220;MyDataSetName&#8221;) </span>auf Detailebene nicht gültig ist.<br />
<br\><br />
Für das Detailfeld (Textbox mit Wertfeld) muss also gelten:<br />
<span style="color: #0070c0;">BorderColor=IIF(RowNumber(&#8220;<strong>MyColumnGroupName</strong>&#8220;)=CountRows(&#8220;<strong>MyColumnGroupName</strong> &#8220;),&#8221;Black&#8221;,&#8221;Silver&#8221;)<br />
</span><br />
<br\><br />
Und genau an dieser Stelle fängt der Ärger an.<br />
<br\><br />
Nehmen wir an, der Reportdesigner ist ein sparsamer Mensch und möchte sich im Dataset die leeren Zeilen für den OrderCount in Australien und Frankreich sparen und filtert diese Zeilen heraus.</p>
<p><span style="font-size: 8pt;"><em>MDX:<br />
</em></span></p>
<p><span style="font-size: 10pt; font-family: Courier New;"><span style="color: blue;">SELECT</span><br />
<span style="color: blue;">NON</span><br />
<span style="color: blue;">EMPTY</span><br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">{<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">[Measures].[Reseller Order Count]<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">} <span style="color: blue;">ON</span><br />
<span style="color: blue;">COLUMNS</span>,<br />
</span></p>
<p><span style="font-family: Courier New;"><strong><span style="font-size: 12pt; color: blue;">NON</span><span style="font-size: 12pt;"><br />
<span style="color: blue;">EMPTY </span></span><span style="font-size: 10pt;">&#8212; &gt; !! FILTERT LEERZEILEN<span style="color: blue;"><br />
</span></span></strong></span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">{ (<span style="color: maroon;">STRTOSET</span>(@countryCountry,<span style="color: blue;">CONSTRAINED</span>) ,<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;"><br />
<span style="color: maroon;">STRTOSET</span>(@productProduct,<span style="color: blue;">CONSTRAINED</span>))} <span style="color: blue;">ON</span><br />
<span style="color: blue;">ROWS</span><br />
<span style="color: blue;">FROM</span> [Adventure Works]</span><br />
<br\><br />
Das Dataset sieht dann wie folgt aus:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR4.jpg" alt="" /><br />
<br\><br />
Ergebnis im <strong>bereitgestellten</strong> Report<span style="font-size: 9pt;">: (Die Vorschau im VisualStudio zählt natürlich NICHT!)<br />
</span></p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR5.jpg" alt="" /><br />
<br\><br />
Das Problem wird schnell klar, natürlich ist die letzte Zeile in der Ländergruppe für Australien auch die einzige,<br />
der o.g. Ausdruck sorgt für eine schwarze Färbung und <strong>alle</strong><br />
<strong>nachfolgenden</strong>, vom Report zu rendernden Elemente <strong>übernehmen die Formatierung des letzten Elementes</strong>, welches noch einen direkten Bezug zur Datasetzeile bzw. den Zeilen der angegebenen Gruppe besitzt<strong>. </strong>Das Phänomen kann sowohl auf Zeilen wie auch auf Spaltengruppen beobachtet werden.<br />
<br\><br />
Ein weiterer Versuch, die Ausdrücke für die Rahmenfarbe anders zu formulieren:<br />
<span style="color: #0070c0;">BorderColor=IIF(InScope(&#8220;matrix1_RowGroup1&#8243;),&#8221;Silver&#8221;,&#8221;Black&#8221;)</span><span style="color: #1f497d;"></span>zeigte gar kein Ergebnis für die Spalten:<br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR6.jpg" alt="" /><span style="color: #1f497d;"><br />
</span><br />
<br\><br />
Damit bleibt leider kein anderer Schluss, als die Leerzeilen für die Ländergruppierung mit ins Dataset aufzunehmen:</p>
<p><span style="font-size: 10pt; font-family: Courier New;"><span style="color: blue;">SELECT</span><br />
<span style="color: blue;">NON</span><br />
<span style="color: blue;">EMPTY</span><br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">{<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">[Measures].[Reseller Order Count]<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">} <span style="color: blue;">ON</span><br />
<span style="color: blue;">COLUMNS</span>,<br />
</span></p>
<p><span style="font-size: 10pt; color: green; font-family: Courier New;">&#8211;non empty auskommentiert<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;">{ (<span style="color: maroon;">STRTOSET</span>(@countryCountry,<span style="color: blue;">CONSTRAINED</span>) ,<br />
</span></p>
<p><span style="font-size: 10pt; font-family: Courier New;"><br />
<span style="color: maroon;">STRTOSET</span>(@productProduct,<span style="color: blue;">CONSTRAINED</span>))} <span style="color: blue;">ON</span><br />
<span style="color: blue;">ROWS</span><br />
<span style="color: blue;">FROM</span> [Adventure Works]</span><br />
<br\><br />
Dataset:<br />
<img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR7.jpg" alt="" /><br />
<br\><br />
Gewünschtes Ergebnis im Report:</p>
<p><img src="http://blog.ixtoprod.s15244651.onlinehome-server.info/blogbilder/121508_1728_DynamischeR8.jpg" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ixto.de/blog/sql-server-2005/reportingservices/dynamische-rahmen-innerhalb-einer-matrix-undoder-die-knechtschaft-des-layouts-durch-das-dataset/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

