Friday 6 October 2017

Moving Average In Tm1


Acer Aspire S 13 S5-371 Notebook-Testbericht Für die deutsche deutsche Version finden Sie hier. Nach der Aspire S7 und dem günstigen Aspire S3. Acer startet den nächsten Vertreter der dünnen und leichten Klasse. Der Aspire S13 könnte ein glückliches Medium zwischen seinen beiden Vorgängern sein. Während es High-End-Komponenten, zum Beispiel eine Intel i7-6500U CPU verwendet. Es ähnelt der Aspire S7 im Display (Full HD, matt) und Speichergerät (bis zu 512 GB SATA3 SSD). Dies schafft einen attraktiven, schnellen und mobilen Computer für einen Preis von etwa 1000 Euro (1140). Kommt Ihnen das bekannt vor? Zum Beispiel die unzähligen UX300 ZenBook-Modelle von Asus sind in der gleichen Preisklasse. Updates Changelog 05-10-2016 16:00 Zusätzliche Informationen über die Webcam und ein Video über das Lüftergeräusch 05-04-2016 14:30 Farbraum, Bewertung, Gaming Benchmarks 05-03-2016 18:00 Wartungs-und Upgrade-Möglichkeiten erklärt Und veranschaulicht 05-03-2016 09:15 Bildanalyse im Freiengebrauch, Audioanalyse, Sd-Kartenprüfung, Betrachtungswinkel 05-02-2016 17:00 Drosselungsanalyse (Leistung, Taktraten und Temperaturen unter CB15 und das Witcher 3 gt1h) 05 -01-2016 12:45 Systemgeräusche und Lautsprecher Die Witcher 3-Benchmarks 05-01-2016 09:00 Battery Life unter Last, AS SSD und 3DMark 11 Benchmarks 04-30-2016 23:44 PCMark 8 mit Analyse 04-30- 2016 21:30 first publication Upgrades amp Maintenance Um Lüfter, Batterie und M.2 SSD zu erhalten, müssen Sie zunächst 10 Kreuzschlitzschrauben entfernen und die Kante mit einem Plastikschäkel lösen (um Schäden zu vermeiden). Leider ist dies eine umständliche Aufgabe, während der wir unser Werkzeug ruiniert haben. Sobald Sie die Plastikclips gelöst haben, können Sie die Unterseite entfernen und zu den internen Bestandteilen erhalten. Es ist lobenswert, dass die Batterie nicht geklebt, sondern nur mit einem Stecker verbunden und mit zwei Schrauben befestigt ist. Selbst der Lüfter kann direkt zum Reinigen erreicht werden und die M.2 SSD kann nach Entfernen einer weiteren Schraube ersetzt werden. Das Qualcomm Wi-Fi-Modul befindet sich in der oberen rechten Ecke. Es ist mit zwei Antennen verbunden und kann auch leicht ersetzt werden. Kommunikation Eine Besonderheit ist der 802.11 n-Chip von Qualcomm, der zu MU-MIMO fähig ist. Zu Beginn der Tests war die WLAN-Verbindung stabil und die Download-Raten wurden nicht verlangsamt. Eine 2 GB-Datei wurde von unserem langsamen WD MyCloud NAS bei 60-70 MBs übertragen (entsprechend dem Task-Manager bei über 600 MBits empfangenem Traffic). Allerdings haben wir in einem Standardtest mit iperf (mit unserem MU-MIMO-fähigen Linksys EA8500 Referenzrouter) nur 250 Mbits (Senden) und 320 Mbits (Empfangen) erreicht. Die gleiche Datei von NAS auch nur 160-200 MBits nach dem Task-Manager danach erreicht. Die hinterleuchtete Tastatur erfreut mit einem angenehmen, gedämpften Hub und erlaubt uns eine reibungslose und schnelle Eingabe mit wenigen Fehlern von Anfang an. Wir mochten das Layout, den Schlüsselabstand und den Strich. Nur die Cursortasten sind etwas klein. Hinweis: Wir hatten eine Variante der Aspire S 13 mit QWERTY-Layout im Bericht. QWERTZ Tastaturen werden in den Modellen von deutschen Händlern verkauft werden. Im WPM-Test (Words per Minute) erreichte der Autor 84 WPM ohne lange Anpassung. Der Test, der direkt mit einer Cherry-Desktop-Tastatur (mechanisch) durchgeführt wurde, führte zu 90 WPM. Schreibfehler wurden gleichmäßig verteilt. Insgesamt ist dies ein sehr gutes Ergebnis. Das Touchpad ist komfortabel groß und verfügt über gute Gleiteigenschaften. Seine untere 90 ist anklickbar, wenn auch nicht unbedingt sogar prinzipiell. Aber es funktioniert ganz gut für ein quotWindows Touchpadquot. Während es nicht mit dem aktuellen MacBook Trackpad Schritt halten kann, gehört es definitiv zu den besseren in der Windows-Welt. Unser Testmodell verwendet einen Intel Core i7-6500U. In den ersten Benchmarks zeigt es eine durchschnittliche bis sehr gute Performance im Vergleich zu anderen Notebooks mit i7-6500U. Das gleiche gilt für die Grafikeinheit. Offensichtlich reicht die Kühlung für gute Leistungsergebnisse aus der Dual-Core CPU mit integrierter GPU aus. Wir überprüfen die Leistung der Prozessorkerne in Cinebench R15. Der eingebaute Core i7-6500U erzielt im Einzelkerntest ein durchschnittliches Ergebnis. Die schnellste i7-6500U ist nur 8 schneller, während die langsamste erreicht nur 69 der Leistung. Im Gegenzug ist es nur 1 unter dem Vorsprung in der Multi-Core-Test. Alles in allem gibt es eine sehr gute Leistung. Nach vielen Cinebench R15 Multi läuft, ist die Punktzahl des Aspire S 13 etwa 10 niedriger (292 versus 326 Punkte). Die Taktrate bleibt stabil zwischen 2,6 und 2,7 GHz und die Prozessorkerne steigen bei 84 C aus. Systemleistung Im System-Benchmark PCMark8 Home (3.0 beschleunigt) liegt die S 13 auf dem Niveau der besten Notebooks mit Core i7-6500Us. Das Zenbook UX303UA (5), das Aspire R14 R5-471T (3) und das ThinkPad X1 Carbon (3) sind nur etwas schneller. Allerdings sind die Yoga 900. der XPS 13. und der Envy 13 etwa 15 langsamer. Die Full-HD-Auflösung kann tatsächlich zu einer Leistungssteigerung im Vergleich zu z. B. 4K Notizbücher. Im Vergleich zu allen bewerteten Subnotebooks ist der Aspire S13 hervorragend. Das schnellste Gerät ist das alte EliteBook 820 G1. Die jedoch nur 10 schneller ist. Der Durchschnitt ist deutlich niedriger bei 82. PCMark 8 Home Score Accelerated v2 PCMark 8 Work Score Accelerated v2 Speichergerät Unser Testmodell verwendet eine 512 GB SSD von LiteOn als Speichergerät. Der LITEON CV1-8B512 ist ein M.2 2280 SATA SSD und spezifiziert mit einem Maximum von 520450 MBs (readwrite). Mit 502418 MBs erzielt es gute Ergebnisse für eine SATA SSD in CrystalDiskMark 3.0 und die AS-SSD-Benchmark-Ergebnisse sind auch nichts zu niesen. Trotzdem ist es ein wenig bedauerlich, dass das System keine schnellere NVMe SSD verwendet. Es ist jedoch fraglich, ob dies bei alltäglichen Aufgaben ohnehin spürbar wäre. Systemgeräusche Nach unseren ersten Beobachtungen ist das Kühlsystem ein Mischbeutel. Das gemessene Systemrauschen ist überhaupt nicht übertrieben. Der Lüfter bleibt ohne Last ausgeschaltet und das Gerät ist leise. Leider läuft der kleine Lüfter schnell bei minimaler Belastung. Bei unserem Test geschah dies bereits beim Öffnen von Webseiten oder beim Installieren von Programmen. Obwohl das gemessene Systemrauschen bei 31,3 dB (selten 33 dB) gering bleibt, ist die Rauschcharakteristik aufgrund einer hohen Frequenz relativ unangenehm und in ruhigen Umgebungen sehr hörbar. Darüber hinaus ändert sich die Lüfterdrehzahl dauerhaft, was es noch deutlicher macht. Unter Last beläuft sich der Lüfter meist auf 36,9 dB. Allerdings gibt es auch höhere Spitzen. So erhielt das Gerät während des ersten 3DMark06-Laufs auf einem kalten Gerät kurzzeitig eine Lautstärke von 42 dB. Darüber hinaus beschleunigt er häufig, nachdem Programme bereits geschlossen worden sind, als ob es den Rest der Wärme aus dem Kühlsystem heraus blasen wolle. Da die Frequenz bei höheren Drehzahlen ebenfalls unangenehm hoch ist, können sich empfindliche Benutzer in ruhigen Umgebungen gestört fühlen. Wenn Sie den Laptop in einem normalerweise lauten Büro verwenden, wird das Umgebungsgeräusch sicherlich ertrinken den Lüfter. Angesichts der beobachteten unkritischen Temperaturen im Inneren könnte es möglich sein, den zu aktiven Lüfter unter geringer Last mit einem Software-Update zu moderieren. Acer arbeitet derzeit an einem solchen BIOS-Upgrade. Wenn möglich, werden wir den Aspire danach überprüfen. Das Kühlsystem bleibt relativ ruhig, aber die wechselnde Drehzahl und hohe Frequenzen waren für uns ziemlich unangenehm. Während des ersten 3DMark06-Laufs steigt das Systemrauschen zu Beginn an, endet aber bei etwa 37 dB. In einem ersten Eindruck spielen die Lautsprecher laut und deutlich. Jedoch fehlen dem Sound Bässe. Im direkten Vergleich mit dem Frequenzdiagramm des neuen Apple MacBook 12, das aufgrund seiner Größe einen hervorragenden Klang erzeugt, zeigt der Aspire S 13 vor allem Schwachstellen bei tiefen Frequenzen und hohen Frequenzen. Der MB 12 ist in beiden Bereichen lauter und zeigt insgesamt eine linearere Frequenzkurve. Mit 80 dB und einer Frequenzkurve weit von linear, sind die Lautsprecher nicht bemerkenswert. Batterielebensdauer Mit 7,5 Stunden (ca. 452 Minuten) in unserem WiFi-Batterietest (öffnet Webseiten per Skript bei 150 cdm Helligkeit) ist der Acer Aspire S 13 nur überdurchschnittlich gut (die überprüften Subnotebooks der letzten 24 Monate erreichten 422 Minuten durchschnittlich). Der Toshiba Satellite Z30-B-100 führt mit einer beeindruckenden 12 Stunden. Das Zenbook UX305UA-FC040T mit der gleichen CPUGPU-Kombination erreichte 561 Minuten (über 9 Stunden) und ist das beste 6500U Gerät. Allerdings ist die minimale gemessene Akkulaufzeit (Battery Eater Classic Gaming Last bei maximaler Helligkeit), ist definitiv unter dem Durchschnitt. Die relativ kurze Akkulaufzeit von 1,5 Stunden ist sicherlich auf die hohe maximale Helligkeit zurückzuführen. Zum Beispiel lief der anspruchsvolle The Witcher 3 für zwei Stunden und fünf Minuten bei 150 cdm leider nur bei 14-16 fps, jedoch ohne Leistungsverlust im Vergleich zum Netzbetrieb. Leerlauf (ohne WLAN, minimale Helligkeit) Der erste Eindruck des Acer Aspire S 13 war sehr positiv und wurde vor allem durch den Rest des Tests bestätigt. Wir mochten den Fall, die Eingabegeräte und das Display. Obgleich die Farbtreue besser out-of-the-box (sehr gute Ergebnisse nach der Kalibrierung) sein sollte, ist die matte Oberfläche kombiniert mit einer hohen maximalen Helligkeit ein großer Profi. Wir haben das Ventilatorverhalten unseres frühen Testmodells nicht so sehr gemocht, was eine unangenehme Frequenz zeigt. Wir müssen hier auf ein BIOS-Update warten, da bei niedrigen Belastungen angesichts der Temperaturen kein aktiver Lüfter notwendig ist. Nach Acer, sie sind bereits an einem Update, um dieses Problem zu beheben. Dies könnte unsere Systemlärm-Bewertung erheblich verbessern und die Notebook-Gesamtbewertung könnte um einen Prozentpunkt zunehmen. Schnelles System, helles und mattes IPS-Display sowie eine gute Akkulaufzeit in realistischen Szenarien: Acer hat mit dem Aspire S 13 ein wohlverdientes Bündel für mobile Anwender geschaffen. Weitere Vorteile des Aspire S 13 sind seine gute Leistung und Akkulaufzeit 7 Stunden in realen Szenarien. Darüber hinaus überzeugten die Eingabegeräte in unserem Test. Die Asus Zenbooks, einschließlich der UX305CA mit passiver Kühlung oder der ähnlich ausgerüsteten UX303UA. Sind ähnlich wie der Acer Aspire S13 positioniert. Acers Aspire R13 R7-372T ist eine interessante Alternative aus dem 2-in-1-Bereich. Derzeit ist der Dell XPS 13 sehr erfolgreich im 13-Zoll-Bereich und Varianten mit i5 CPU und FHD-Display sind ähnlich preislich. PriceCompare Erstellen dynamischer Subsets in Applix TM1 mit MDX - Ein Primer zu diesem Dokument Dieser MDX-Primer dient als einfache Einführung in die Erstellung von dynamischen Dimensions-Subsets mit MDX in TM1. Es konzentriert sich auf die Bereitstellung von Arbeitsbeispielen anstatt zu versuchen, die vollständige Theorie der MDX zu erklären und stellt sicher, dass die Funktionen, die für TM1-Nutzer am nützlichsten sind zu decken. TM1 derzeit (ab 9.0 SP3) erlaubt es Benutzern, MDX zu verwenden, um Dimensionsuntermengen zu erstellen und keine Cubeansichten zu definieren. Dies bedeutet, dass die Verwendung von MDX in TM1 in Bezug auf die Syntax und die Intention von Beispielen, die in Büchern und im Internet gefunden werden, oft ganz unterschiedlich ist. Da MDX (Multi-Dimensional eXpressions) eine Industriestandard-Abfragesprache für OLAP-Datenbanken von Microsoft ist, gibt es viele Referenzen und Beispiele, die im Internet zu finden sind, obwohl man bedenkt, dass TM1 nicht jeden Aspekt der Sprache unterstützt und einige hinzufügt Einzigartige Eigenschaften seiner eigenen. Dies kann die Verwendung von im Web gefundenen Beispielen erschweren, während alle Beispiele in diesem Dokument einfach in TM1 kopiert und eingefügt werden können und ohne Modifikation ausgeführt werden, vorausgesetzt, Sie haben das Beispiel-Mini-Modell erstellt, wie es später dokumentiert wurde. Vollständige Dokument als nur eine HTML-Seite hier. Was ist eine MDX-basierte dynamische Teilmenge in TM1 Eine dynamische Teilmenge ist eine, die keine feste, statische Liste ist, sondern sie basiert auf einer Abfrage, die jedes Mal neu bewertet wird, wenn die Teilmenge verwendet wird. In der Tat könnte MDX verwendet werden, um eine statische Teilmenge zu erstellen und ein Beispiel ist unten gezeigt, aber dies unwahrscheinlich, nützlich zu sein oder häufig. Einige Beispiele für nützliche dynamische Teilmengen könnten eine Liste aller Basisebenen eine Liste unserer Top-10-Kunden durch Bruttomarge eine Liste der überfälligen Lieferungen alle Kostenstellen, die noch nicht ihr Budget vorgelegt haben. Der Punkt ist, dass diese Listen (Teilmengen) von Sekunde zu Sekunde auf der Grundlage der Struktur oder der Daten in TM1 variieren können. Sobald beispielsweise ein neuer Zweig nach Europa hinzugefügt wird, wird die Teilbranche Europäische Zweige diese neue Zweigstelle ohne jeglichen manuellen Eingriff sofort enthalten. MDX ist die Abfragesprache, die verwendet wird, um diese Untermengen zu definieren. MDX ist eine branchenübergreifende Abfragesprache für mehrdimensionale Datenbanken wie TM1, obwohl TM1 nur eine bestimmte Teilmenge (Entschuldigung für das Wortspiel) der gesamten Sprache unterstützt und in ein paar einzigartigen Eigenschaften seiner eigenen hinzufügt. Wenn Sie eine Teilmenge mit MDX anstelle einer Standard-Teilmenge definieren, speichert TM1 diese Definition und nicht die resultierende Menge. Dies bedeutet, dass die Definition oder Abfrage erneut ausgeführt wird, wenn Sie es betrachten, ohne dass der Benutzer oder Administrator etwas tun muss. Wenn sich die Datenbank in gewisser Weise geändert hat, können Sie beim letzten Mal unterschiedliche Ergebnisse erzielen. Zum Beispiel, wenn eine Teilmenge definiert als die Kinder der Westküste Niederlassungen und dies zunächst wieder Oakland, San Francisco, San Diego, wenn es zuerst definiert ist, kann es später wieder Oakland, San Francisco, San Diego, Los Angeles einmal LA hat Wurde in die Dimension als ein Kind der Westküste Niederlassungen hinzugefügt. Das ist es, was wir unter Dynamik verstehen. Ein anderer Grund, der dazu führen kann, dass sich die Untermenge ändert, ist, wenn sie auf den Werten innerhalb eines Cubes oder Attributs basiert. Jeden Tag in der Zeitung sind die größten Börsenmärkte gelistet, wie z. B. eine Top 10 in Bezug auf die Aktienkurssteigerung. In einem TM1-Modell wäre dies eine Teilmenge, die ein Aktienkursänderungsmaß ansieht, und würde wahrscheinlich einen anderen Satz von 10 Mitgliedern jeden Tag zurückgeben. Das Beste daran ist, dass die Teilmenge ihre Ergebnisse automatisch aktualisiert, ohne dass die Arbeit eines Benutzers erforderlich ist. So erstellen Sie eine MDX-basierte Untermenge in TM1 Die gleichen grundlegenden Schritte können mit allen Beispielen in diesem Dokument verfolgt werden. Generell können die Beispiele in das Expression-Fenster des Subset-Editors kopiert und eingefügt werden. Beachten Sie, dass es irrelevant ist, welchen Würfel die Dimension verwendet wird, indem Sie dieselben Ergebnisse erhalten, unabhängig davon, ob Sie die Dimension Subset Editor innerhalb einer Cube-Ansicht, der Cube-Struktur im Server-Explorer oder der Dimensionsstruktur im Server-Explorer öffnen. Um eine MDX-Abfrage anzeigen und bearbeiten zu können, müssen Sie das Expression-Fenster im Subset-Editor sehen können. Um dieses Fenster ein - und auszuschalten, wählen Sie das Ansichtsfenster. Sie können jetzt einfach (oder fügen Sie) Ihre Abfrage in diesem Ausdruck Windows und drücken Sie die Schaltfläche Aktualisieren, um die Ergebnisse zu sehen. So erstellen Sie eine statische Teilmenge mit MDX Eine statische Teilmenge ist eine, die nie in ihrem Inhalt variiert. Diese Abfrage wird die gleichen 3 Mitglieder (Discount Loan, Term Loan und Retail) jedes Mal zurück. Mach dir keine Sorgen, es wird noch spannender von hier. So erstellen Sie eine dynamische Teilmenge mit MDX TM1 unterstützt nur eine bestimmte Anzahl von Funktionen aus der vollständigen MDX-Spezifikation. Verschiedene Versionen von TM1 unterstützen verschiedene Funktionen (und können die verschiedenen Möglichkeiten unterstützen). Die gültigen Funktionen für die verwendete TM1-Version finden Sie in der Haupt-Hilfedatei unter Referenzmaterial MDX-Funktionsunterstützung. Bevor Sie versuchen, eine neue Abfrage zu schreiben, stellen Sie sicher, dass es unterstützt wird, und obwohl einige nicht aufgeführte Funktionen sicher funktionieren, müssen sie auf eigenes Risiko verwendet werden. Die Standardfehlermeldung, die bedeutet, dass die Funktion tatsächlich von Ihrer TM1-Version nicht unterstützt wird, ist fehlgeschlagen, den Ausdruck zu kompilieren. Ein Wort der Warnung: Die Ergebnisse einer dynamischen Teilmenge können sich ihrer Natur nach ändern. Wenn Sie dynamische Teilmengen in Ansichten, Prozessen, SUBNM-Funktionen und so weiter berücksichtigen, sollten Sie sorgfältig darüber nachdenken, was die potenziellen zukünftigen Ergebnisse sein könnten, besonders wenn die Teilmenge eines Tages leer sein könnte. Die beiden gängigsten Methoden, um über die tatsächliche Schaffung eines dynamischen Teilmenge gehen, um sie von Hand oder mit TurboIntegrator erstellen. Von Hand . Sie können entweder eine Abfrage in das Expression-Fenster eingeben (oder einfügen), wie zuvor beschrieben, oder Sie können Tools Records Ausdruck (und dann Stop Recording, wenn fertig) wählen, um eine Art von Videorecorder einzuschalten. Sie können dann die normalen Funktionen des Subset-Editors verwenden (z. B. nach Ebene auswählen, absteigend sortieren usw.), und dieser Rekorder wird Ihre Aktionen in einen gültigen MDX-Ausdruck umwandeln. Dies ist eine gute Möglichkeit, einige Beispiele für gültige Syntax, vor allem für komplexere Abfragen zu sehen. Wenn Sie einen Ausdruck aufgenommen haben, wählen Sie Stopp Recording TM1 wird Sie bitten, zu bestätigen, ob Sie den Ausdruck mit der Teilmenge anhängen möchten - vergewissern Sie sich, dass Sie Ja sagen und das Kontrollkästchen Save Expression beim Speichern der resultierenden Teilmenge anklicken, ansonsten nur eine statische Liste Des Ergebnisses gespeichert wird, nicht die dynamische Abfrage selbst. Verwenden von TurboIntegrator. Es wird nur eine Zeile mit SubsetCreateByMDX benötigt, um die Teilmenge zu erstellen und zu definieren. Sie müssen wissen, welche Abfrage Sie wollen, wie die Definition bereits. Beachten Sie, dass die Abfrage im TI-Skript unter Verwendung von Textverknüpfungen aufgebaut werden kann, so dass Variablen aus Ihrem Skript übernommen werden können und lange Abfragen in Stufen aufgebaut werden können, die einfacher zu lesen und zu pflegen sind. SubsetCreatebyMDX (Base Products,, 0)) Alle von TI erstellten MDX-Subsets werden als dynamische MDX-Abfragen automatisch und nicht als statische Liste gespeichert. Beachten Sie, dass mindestens bis TM1 v9.0 SP3 MDX-basierte Untermengen nicht zerstört werden können (SubsetDestroy), wenn sie von einer öffentlichen Ansicht verwendet werden, und sie können nicht mit einem zweiten SubsetCreateByMDX-Befehl neu erstellt werden. Daher ist es schwierig, MDX-basierte Teilmengen mit TI zu ändern. Während die dynamische Natur der Teilmenge Definition kann es etwas unwahrscheinlich, dass Sie tatsächlich wollen, dies zu tun, ist es wichtig zu bedenken. Wenn Sie einen Aspekt der Abfrage ändern müssen (zB ein TM1FilterByPattern von 2006-12 bis 2007-01), müssen Sie die Abfrage definieren, um externe Parameter zu verwenden, wie in diesem Dokument dokumentiert Hartcodierte Version. Weiterhin filtern Sie gegen Werte eines Cubes mit SubsetCreateByMDX auf der Registerkarte Epilog, zB 0), Test. (Posting Measures. Amount) gt 0) funktioniert nicht, wenn die Werte auf der Registerkarte Data geladen wurden. Sie müssen den SubsetCreateByMDX-Befehl in einem nachfolgenden TI-Prozess ausführen. Beachten Sie, dass TI ein Limit von 256 Zeichen für die Definition MDX Teilmengen, mindestens bis zu v9.1 SP3, die sehr begrenzt sein kann. Syntax und Layout Eine Abfrage kann über mehrere Zeilen gebrochen werden, um sie lesbarer zu machen. Zum Beispiel: FILTER (, 0), Test2 (Rate Measures. Rate) 19) ist besser lesbar als die gesamte Abfrage in einer Zeile. Der eigentliche Filterabschnitt ist leichter zu lesen und zu modifizieren, indem er ihn auf einer Linie von selbst hat. Beachten Sie, dass Verweise auf Mitglieder in der Regel den Dimensionsnamen als Präfix haben. Beispielsweise ist der Dimensionsname optional, aber nur, wenn der Mitgliedsname (Retail in diesem Fall) vollständig innerhalb des gesamten Servers ist - d. h. es gibt keine Cubes, Dimensionen oder Member mit dem genauen Namen. Dies ist zum Beispiel dieselbe Abfrage, bei der der Dimensionsname weggelassen wurde: Dies würde im Kontext der von diesem Dokument verwendeten Beispielanwendung funktionieren, wäre aber in einer realen Anwendung riskant. Die Fehlermeldung, die beim Vergessen eingegeben wurde, um das Präfix anzugeben, wäre etwa so: Level oder Mitgliedsname Retail doppeldeutig: in Dimensionen gefunden und dann geht es weiter, um die verschiedenen Dimensionen aufzulisten, in denen der nicht eindeutige Membername gefunden werden kann hilfreich. Es ist daher sicher am sichersten und am performantesten, das Dimensionspräfix immer zu verwenden. Die Verwendung von eckigen Klammern kann manchmal etwas willkürlich beim Lesen von Beispielen für MDX-Abfragen erscheinen. Tatsache ist, dass ein OLAP-Objektname (z. B. Würfelname, Dimensionsname, Mitgliedsname) in eckigen Klammern eingeschlossen werden muss, wenn er ein Leerzeichen enthält, mit einer Zahl beginnt oder ein MDX-reserviertes Wort ist (z. Allerdings kann es manchmal einfacher sein zu entscheiden, immer Klammern verwenden, so dass ähnliche Abfragen können Seite an Seite leichter verglichen werden. Die genaue Definition eines Mitglieds in TM1 wird fast immer als Dimension Name. Member-Name und nicht mehr ausgedrückt. In anderen Produkten, die auch MDX als Abfragesprache (z. B. Microsoft Analysis Services) verwenden, können Sie feststellen, dass Abfragen den vollständigen Pfad vom Dimensionsnamen über die Hierarchie bis zum Mitgliedsnamen spezifisch angeben, zum Beispiel: Date.2009.Q1.Feb. Week 06 Dies kann auch geschrieben werden als Date.2009Q1FebWeek 06 Der Grund dafür ist, dass andere Produkte nicht erforderlich, dass jeder Mitgliedsname eindeutig sein muss, da jedes Mitglied einen Kontext (seine Familie) hat, damit er eindeutig identifiziert werden kann Müssen sie genau wissen, welche Woche 06 benötigt wird, da es andere (im Jahr 2008 zum Beispiel im obigen Beispiel) geben kann. TM1 erfordert, dass alle Mitgliedsnamen auf jeder Ebene (und innerhalb von Aliases) innerhalb dieser Dimension vollständig eindeutig sind. TM1 würde Sie brauchen, um Q1, Feb und Woche 06 expliziter in erster Linie (dh Q1 2009, Feb 2009, Woche 06 2009) zu machen, aber Sie können dann nur beziehen sich auf Date. Week 06 2009. Schließlich Fall (dh Großbuchstaben Versus Kleinbuchstaben) ist bei MDX-Befehlen (zB Filter oder FILTER, TOPCOUNT oder TopCount sind alle in Ordnung) nicht wichtig. Vielleicht möchten Sie aber lieber nur einen Style als Standard verwenden, um es leichter zu lesen. Das verwendete Beispielmodell In diesem Dokument werden viele Beispiele für dynamische Abfragen angegeben. Sie alle arbeiten (genau wie geschrieben, nur kopieren und fügen Sie sie in das Expression-Fenster in der Subset-Editor der entsprechenden Dimension, um sie zu verwenden) auf den einfachen Satz von Würfeln und Dimensionen unten gezeigt. Das Modell ist bewusst einfach, ohne besondere Eigenschaften, so sollten Sie es einfach finden, die Arbeit auf Ihr eigenes Modell zu übertragen. Das Modell verwendet 1 Hauptdimension, Produkt, auf dem die überwiegende Mehrheit der Abfragen funktioniert plus 3 Cubes: Test, Test2 und Test3. Die Datenwerte in den Cubes variieren während des Testens (youll möchten die Werte anpassen und die Abfrage erneut ausführen, um sicherzustellen, dass die Ergebnisse sich ändern und korrekt sind), aber die Screenshots unten zeigen die Cube - und Dimensionsstrukturen, die für eine schnelle Wiederherstellung ausreichend sind Oder wie Sie Ihr eigenes Modell verwenden. Um die Verteilung dieses Dokuments zu vereinfachen, besteht nicht die Absicht, auch die tatsächlichen TM1-Modelldateien zu verteilen. Beachten Sie, dass die wichtigsten Dimension verwendet, Produkt, featured ragged, und mehrere, Hierarchien. TM1SubsetAll, Members, member range Die Basis für viele Abfragen ist die Rückgabe der gesamten Dimension (fast, siehe unten), die das Äquivalent zum Klicken auf die Schaltfläche Alle im Subset-Editor ist. TM1SUBSETALL (Product) Beachten Sie, dass nur die letzte Instanz in der ersten Hierarchie von Mitgliedern zurückgegeben wird, die mehrfach konsolidiert werden. Die Member-Funktion liefert auf der anderen Seite die volle Dimension, Duplikate enthalten: Product. Members Eine Reihe von aneinander grenzenden Mitgliedern aus derselben Ebene kann ausgewählt werden, indem das erste und letzte Element des gewünschten Satzes mit einem Doppelpunkt angegeben wird. Dieses Beispiel gibt den 1. Januar bis zum 12. Januar 1972 zurück. Selektieren Sie nach Level, Regular Expression (Pattern) und Ordinal Die Auswahl von Mitgliedern auf Basis ihrer Ebene in der Dimensionshierarchie (TM1FilterByLevel) oder durch ein Stringmuster (TM1FilterByPattern) Indem Sie die Record Expression-Funktion im Subset-Editor verwenden. Die klassische alle Blatt-Mitglieder Abfrage mit TM1s Ebene Filterung Befehl TM1FilterByLevel:, 0) Wählen Sie alle Blatt-Mitglieder, die die Wildcard HC, die H und C als das dritte und vierte Zeichen vom Ende ihres Namens haben entsprechen. , 0), HC) Grund dafür, dass diese Funktionen mit TM1 beginnen, ist, dass sie keine Standard-MDX-Befehle sind und für TM1 eindeutig sind. Es gibt zwei Hauptgründe, warum Applix solche einzigartigen Funktionen implementiert: um eine Funktion hinzuzufügen, die im Standard TM1 vorhanden ist und die Benutzer vermissen werden, wenn sie nicht da ist oder weil Standard TM1 die gleiche Funktion wie MDX hat, aber historisch etwas anders implementiert hat MDX und würde daher wieder zu Problemen führen, wenn es nur in der Standard-MDX-Weise implementiert wurde. In diesen beiden Fällen bringt TM1FilterByPattern eine Funktion, die häufig von TM1 - Anwendern verwendet wird, die in MDX fehlt, während TM1FilterByLevel existiert, da TM1 seit ihrer Markteinführung im Jahr 1984 Konsolidierungsstufen nummeriert hat, beginnend bei Null für die Blätterebene, die die Ebenen ansteigt Insgesamt, während Microsoft beschlossen, es zu tun, die genaue entgegengesetzte Weise. In bestimmten Situationen ist es sinnvoll, die Standard-MDX-Stufen-Methode zu verwenden, und dies ist auch mit der Levels-Funktion verfügbar. Es erlaubt Ihnen, die Mitglieder einer Dimension zurückzugeben, die sich auf derselben Ebene wie ein benanntes Mitglied befinden, nur bedenken, dass Standard-MDX die Ebenen in Bezug auf ihre Entfernung von der Oberseite der Hierarchie und nicht die Unterseite als TM1 ordnet. In diesem Beispiel werden alle Mitglieder auf derselben Ebene wie das Einzelhandelsmitglied zurückgegeben: Obwohl Retail eine Konsolidierung auf hohem Niveau ist, wird ein N: - Produkt (Produkt nicht anwendbar) in der Dimension zurückgegeben, da es direkt auf All Products zugreift Sie gelten als auf dem gleichen Niveau. Um die Dimension auf Basis einer Level-Nummer zu filtern, müssen Sie die. Ordinal-Funktion verwenden. Dies ist nicht dokumentiert als in der Hilfedatei unterstützt und funktionierte nicht in 8.2.7, scheint aber in 9.0 SP3 und 9.1.1.36 mindestens zu funktionieren. In diesem Beispiel werden alle Member auf Stufe 1 zurückgegeben: Product. CurrentMember. Level. Ordinal 1) Dieses Beispiel würde alle Member zurückgeben, die nicht auf demselben Niveau wie Discount Loan sind. , Product. CurrentMember. Level. Ordinal TM1Sort, TM1SortByIndex und Auftrag TM1Sort ist das Äquivalent des Drückens einer der beiden Sortieren aufsteigenden oder Sortieren absteigenden Schaltflächen im Teilmengeneditor, d. H. Alphabetisch sortieren. TM1SortIndex ist das Äquivalent zum Drücken einer der beiden Sortiert nach Index, aufsteigend oder Sortieren nach Index, absteigende Schaltflächen im Teilmengen-Editor, d. H. Nach dem Dimensionsindex (dimix) sortieren. Order ist eine Standard-MDX-Funktion, die einen Datenwert aus einem Cube verwendet, um die Sortierung durchzuführen. Zum Beispiel, sortieren Sie die Liste der Kunden nach dem Verkauf oder eine Liste der Mitarbeiter nach ihrer Länge der Dienstleistung. Sortieren Sie die gesamte Produktdimension in alphabetisch aufsteigender Reihenfolge. , ASC) Sortieren Sie die Blattelemente der Dimension nach ihren Betragswerten im Testwürfel von höchsten abwärts. BESTELLEN (, 0). Test (Posting Measures. Amount), BDESC) Beachten Sie, dass die Verwendung von BDESC anstelle von DESC radikal verschiedene Ergebnisse liefert. Das ist so, weil BDESC alle Mitglieder über das eingesetzte Set (in diesem Fall die gesamte Dimension) als gleichberechtigte Geschwister behandelt und sie entsprechend klassifiziert, während DESC die Mitglieder als noch in ihren Familiengruppen behandelt und sie nur gegen ihre eigenen direkten Geschwister platziert . Wenn Sie nicht sicher sind, was das bedeutet und kann nicht sehen, den Unterschied, wenn Sie es ausprobieren, dann verwenden Sie einfach BDESC Bestellung kann auch ein Attribut anstelle eines Würfels Wert. In diesem Beispiel wird das AlternateSort-Attribut des Produkts verwendet, um die Kinder von Demand Loan in absteigender Reihenfolge zu sortieren. Es ist ein numerisches Attribut, das ganze Zahlen (zB 1, 2, 3, 4 usw.) enthält, um die Definition einer vollständig dynamischen Sortierreihenfolge zu ermöglichen:, Product. AlternateSort, DESC) TopCount und BottomCount Ein klassischer Top-10-Befehl: 10, Test (Posting Measures. Amount)) Durch das Weglassen einer Sortierreihenfolge sortiert es sich in der Standardreihenfolge (die die Werte im Wert absteigt und alle vorhandenen Hierarchien bricht). Eine Top-10-Abfrage mit einer expliziten Sortierreihenfolge für die Ergebnisse. , 0), 10, Test (Posting Measures. Amount), Test (Posting Measures. Amount), BDESC) BDESC bedeutet, die Hierarchie zu brechen. Beachten Sie, wie das gewählte Maß für die Sortierreihenfolge wiederholt wird. Obwohl die gleiche Maßnahme in der Stichprobe oben verwendet wird, könnten Sie tatsächlich die Top-10-Produkte durch den Verkauf finden, aber dann zeigen sie in der Reihenfolge, sagen, Einheiten verkauft oder ein Attribut der strategischen Bedeutung. Dies sind die Top 10 Produkte basierend auf Test2s Rate Werte, nicht bestellt, so wird nach den Werten in Test2 sortiert werden. , 0), 10, Test2 (Rate Measures. Rate)) Dies ist die Top 10 Produkte auf der Grundlage von test2s Daten in der Rate Maßnahme, bestellt von 10 bis 1., 0), 10, test2 (Rate Measures. Rate) ), Test2 (Rate Measures. Rate), ASC) TopCount automatisch eine absteigende Sortierung nach Wert, um die TOP-Mitglieder zu bekommen. Wenn dies nicht erwünscht ist, können Sie stattdessen die Head-Funktion verwenden (siehe unten). BottomCount ist das Gegenteil von TopCount und wird verwendet, um die Mitglieder mit den niedrigsten Werten in einem Cube zu finden. Achten Sie darauf, dass der niedrigste Wert oft Null ist und wenn dieser Wert von der Abfrage ausgeschlossen werden muss, müssen Sie sich auf den Abschnitt über die Filterfunktion später in diesem Dokument beziehen. Eine Bottom-10-Abfrage mit einer expliziten Sortierreihenfolge für die Ergebnisse. (Posting Measures. Amount), BASC) Weiterführende Literatur: TopSum, TopPercent und ihre unteren Äquivalente sind nützliche verwandte Funktionen. Filtern nach Werten, Strings und Attributen Mit der Funktion FILTER können Sie die Dimension auf der Grundlage von Datenwerten filtern und nicht nur die Mitglieder und deren Hierarchie. Diese Daten können Cube-Daten (numerisch oder Zeichenfolge) oder Attributdaten sein. Dies erfordert eine Veränderung des Denkens von einfachen Dimensionen (Listen mit einer Hierarchie und gelegentlich einigen Attributen) zu einem mehrdimensionalen Raum, wo jede Dimension in diesen Würfeln berücksichtigt und behandelt werden muss. In diesem Beispiel werden die Blattmitglieder von Product zurückgegeben, die einen Betragswert im Testcube über Null haben. , 0), Test (Posting Measures. Amount) gt 0) Da der Testcube nur 2 Dimensionen Produkt - und Buchungsmaße hat, ist dies ein vereinfachtes Beispiel. Die meisten Cubes haben mehr als nur die Dimension gefiltert und die Dimension mit dem Filterwert in. Jedoch ist es einfach, das erste Beispiel zu erweitern, um in einem größeren Cube zu arbeiten. Dieses Beispiel gibt die Blattmitglieder von Product zurück, die einen Wert für alle Entitäten im Test3-Cube über Null haben. , 0), Test3 (Entity. All Entities, Posting Measures. Amount) gt 0) Wie Sie von oben sehen können, fügen Sie einfach alle erforderlichen Dimension Referenzen innerhalb der runden Klammern. Normalerweise benötigen Sie nur ein bestimmtes benanntes Mitglied (z. B. alle Entitäten). Wenn die Dimension weggelassen wird, wird stattdessen das CurrentMember verwendet, das der Verwendung der Dimension (d. h. für jedes) in einer TM1-Regel ähnlich ist, und könnte unterschiedliche Ergebnisse mit einer unterschiedlichen Geschwindigkeit zurückgeben. Anstatt nur einen hartcodierten Wert zum Filtern (Nullen in den obigen Beispielen) zu verwenden, gibt dieses Beispiel alle Produkte mit einem Betrag im Testcube zurück, der größer oder gleich dem Wert in der Zelle MidasJCFI, Betrag ist. , 0), Test (Posting Measures. Amount) gt Test (Product. MidasJCFI, Posting Measures. Amount)) Diese Abfrage gibt die Produkte mit einem Rate-Wert in Test2 größer als MidasJXCOs Rate in Test2. Nun gibt diese Abfrage nur eine Reihe von Produkten seine bis zu Ihnen, die Würfel Sie diese Produkte in, dh Sie können dies beim Durchstöbern Test und daher zurückgeben, was aussieht wie eine fast zufällige Reihe von Produkten, aber die Tatsache ist, dass die Abfrage filtert Die Liste der Produkte, die auf den Daten von Test2 basieren. This may not immediately appear to be useful but actually it is, and can be extremely useful for example display the current years sales for products that were last years worst performers. If the data for two years was held in different cubes then this would be exact same situation as this example. There are often many potential uses for displaying a filteredfocused set of data in Cube B that is actually filtered based on data in Cube A. , 0), Test.(Posting Measures. Amount) gt Test2.(Product. MidasJXCO, Rate Measures. Rate) ) As detailed elsewhere, Tail returns the final member(s) of a set. An example of when it is handy when used with Filter would be for finding the last day in a month where a certain product was sold. The simple example below initially filters Product to return only those with an All Entity Amount gt 0, and then uses tail to return the final Product in that list. , 0), Test3.( Entity. All Entities, Posting Measures. Amount) gt 0 )) Note: with the other cubes having more dimensions than does Test the current member is used (each), not All so whether you want each or All you should write this explicitly to be clearer. You can even filter a list in Cube1 where the filter is a value in one measure compared to another measure in Cube1. This example returns the Products with an amount in the Test cube above zero where this Amount is less than the value in Count. , 0), (Test. Posting Measures. Amount 0 ) This example returns all the leaf products that have an Amount in Entity Not Applicable 10 greater than the Amount in Entity Not Found, in the Test3 cube. Not very useful but this was the only example cube we had to work with, but it would be very useful when comparing, say, Actual Q1 Sales with Budget, or finding out which cost centres Q2 Costs were 10 higher than Q1. Later in this document we will see how to take that 10 bit and make it a value from another cube, thus allowing administrators, or even end users, to set their own thresholds. , 0), test3.(Entity. Entity Not Applicable, Posting Measures. Amount) 1.1 gt test3.(Entity. Entity Not Found, Posting Measures. Amount)) Filtering for strings uses the same method but you need to use double quotes to surround the string. For example, this query returns products that have a value of bob in the Test2 cube against the String1 member from the StringTest dimension. Note that TM1 is case-insensitive. , 0), Test2.(StringTest. String1) bob ) Filter functions can be nested if required, although the AND or INTERSECT functions may be useful alternatives. The limit to the number of characters that an MDX subset definition can sometimes be, 256, is too restricting for many data-based queries. When trying to shoehorn a longer query into less characters there are a few emergency techniques that might help: consider whether you need things like TM1FILTERBYLEVEL, 0 (it might well be that the filter would only return members at the leaf level by definition anyway) whether the dimension name prefix can be removed if the member is guaranteed to be unique remove all spaces lookup cubes are not for end users so maybe you could shorten some names (cubes, dimension, members) drastically whether there are alternative functions with shorter syntaxes that return the same result - e. g. an INTERSECT or AND versus a triple FILTER. Finally, if it really is vital to get a long query working then you can build up the final result in stages i. e. put some of the filtering into Subset1, then use Subset1 as the subject of Subset2 which continues the filtering, etc. Parent, Children, FirstChild, LastChild, Ancestors, Descendants, DrillDownLevel and TM1DrilldownMember Children returns the set of members one level below a named parent. FirstChild returns the first child one level below a named parent. Returns Call Participation Purchased. LastChild returns the last child one level below a named parent. This is excellent for finding the last day in a month, since they can vary from 28 to 31. Another example is when a consolidation is set up to track a changing set of members (e. g. Easter, or Strategic Customers). Returns Term Participation Purchased. Parent returns the first parent of a given member. If a member has more than one parent, and the full unique path to the member is not specified then the first parent according to the dimension order is returned. Returns Bonds. Would force TM1 to return the second parent, External Bonds. Descendants returns the named parent and all of its descendant children i. e. the hierarchy down to the leaf level: TM1DrilldownMember returns the same thing as descendants: , ALL, RECURSIVE ) DrillDownLevel just returns the parent and its immediate children: ) DrillDownLevel can be extended with a parameter to say which level to return the members from, rather than the level immediately below, but this doesnt appear to work in TM1 v9.0 SP2 through to 9.1.1.36. The common requirement to return a list of just leaf-level descendants of a given consolidated member just needs a level filter applied to the TM1DrillDownMember example above:,ALL, RECURSIVE), 0) Or: , 0) Ancestors is like a more powerful version of Parent it returns a set of all the parents of a member, recursively up though the hierarchy including any multiple parents, grandparents, etc. Returns 2006 October, 2006 Q4, 2006 H2, 2006, All Dates. Lag, Lead, NextMember, PrevMember, FirstSibling, LastSibling, Siblings and LastPeriods Lags and Leads are the equivalent of DnextDprev. will return 2006-10-04. Lead(n) is the same as Lag(-n) so either function can be used in place of the other by using a negative value, but if only one direction will ever be needed in a given situation then you should use the correct one for understandabilitys sake. Note that they only return a single member so to return the set of members between two members you can use the lastperiods function. Equally you can use NextMember and PrevMember when you only need to move along by 1 element. Or: To return the 6 months preceding, and including, a specific date: Or: LastPeriods(6, Date.2006-10-03) Both of which work because LastPeriods is a function that returns a set, and TM1 always requires a set. Curly braces convert a result into a set which is why many TM1 subset definitions are wrapped in a pair of curly braces, but in this case they are not required. This will return the rest (or the ones before) of a dimensions members at the same level, from a specified member. Despite its name LastPeriods works on any kind of dimension: Siblings are members who share a common parent. For example, a date of 14th March 2008 will have siblings of all the other dates in March the first of which is the 1st March and the last of which is 31st March. A cost centre under West Coast Branches would have a set of siblings of the other west coast branches. The FirstSibling function returns the first member that shares a parent with the named member. For example: Returns MidasHCBK. While: Returns MidasHSFI. The siblings function should return the whole set of siblings for a given member. TM1 9.0 SP2 through to 9.1.2.49 appear to give you the entire set of members at the same level (counting from the top down) rather than the set of siblings from FirstSibling through to LastSibling only. Filtering by CurrentMember, NextMember, PrevMember, Ancestor and FirstSibling This example returns the members that have an Amount value in the Test cube above 18. The Product. CurrentMember part is optional here but it makes the next example clearer. , 0), Test.(Product. CurrentMember, Posting Measures. Amount) gt 18 ) This query then modifies the previous query slightly to return members where the NEXT member in the dimension has a value above 18. In practice this is probably more useful in time dimensions. , 0), Test.(Product. CurrentMember. NextMember, Posting Measures. Amount) gt 18 ) This can then be improved to returning members where the next member is greater than their amount. , 0), Test.(Product. CurrentMember. NextMember, Posting Measures. Amount) gt Test.(Product. CurrentMember, Posting Measures. Amount) ) In addition to NextMember, PrevMember can also be used as could lags and leads. The simple, but unsupported as of 9.1.1.89, Name function allows you to filter according to the name of the member. As well as exact matches you could find exceptions, less-thans and greater-thans, bearing in mind these are alphanumeric comparisons not data values. This example returns all base members before and including the last day in January 1972. ,0), Date. CurrentMember. Name For example, this could be a useful query even a dimension not as obviously sorted as dates are: ,0), Product. CurrentMember. Name which returns all base members before MidasJ in terms of their name rather than their dimension index. Parent returns the first parent of a given member: Used with Filter you can come up with another way of doing a children of query: ,0), Date. CurrentMember. Parent. Name 1972 - January) Ancestor() can be used instead of Parent if desired. This example returns base-level product members whose first parents have a value above zero, in other words a kind of family-based suppress zeroes: a particular product might have a value of zero but if one if its siblings has a value then it will still be returned. , 0), Test.(Ancestor(Product. CurrentMember,0), Posting Measures. Amount) gt 0 ) This example filters the products based on whether they match the Amount value of MidasHCBK. , Test.(Ancestor(Product. CurrentMember,0), Posting Measures. Amount) Test.(Product. MidasHCBK, Posting Measures. Amount) ) This example uses FirstSibling to filter the list based on whether a products value does not match that products First Sibling (useful for reporting changing stock levels or employee counts over time, for example, things that are usually consistent). , 0), Test.(Ancestor(Product. CurrentMember,0), Posting Measures. Amount) Filtering by Attributes and logical operators This returns members that match a certain attribute value using the Filter function. , Product. Category Customer Lending) This example looks at multiple attribute values to return a filtered list: FILTER( , ( (Product. CategoryCustomer Lending OR Product. TypeDebit) AND (Product. Internal Deal Filtering by level, attribute and pattern are combined in the following example: ,0), Product. Internal Deal Yes), ID) Head, Tail and Subset Where TopCount and BottomCount sort the values automatically and chop the list to leave only the most extreme values, Head combined with Filter works in a similar manner but Head then returns the FIRST members of the filtered set in their original dimension order. These queries simply return the first and last members of the Product dimension as listed when you hit the All button: This returns the actual last member of the whole Product dimension according to its dimix: , ALL, RECURSIVE ), ASC)) An example of Tail returning the last member of the Customer Lending hierarchy: , ALL, RECURSIVE )) An example of Head returning the first 10 members (according to the dimension order) in the product dimension that have an Amount in the Test cube above zero. , 0), Test.(Posting Measures. Amount) gt 0 ), 10) With both Head and Tail the ,10 part can actually be omitted (or just use ,0) which will then return the first or last member. This returns the last (in terms of dimension order, not sorted values) product that had an amount gt 0 in the Test cube. , 0), Test.(Posting Measures. Amount) gt 0 )) One example of when this is useful over TopCount or BottomCount i. e. when sorting the results would be detrimental - would be to return the last day the year when a certain product was sold. Subset is closely related to Head and Tail, and can actually replicate their results, but is additionally capable of specifying a start point and a range, similar in concept to substring functions (e. g. SUBST) found in other languages, though working on a tuple of objects not strings. The equivalent of Head, 10 would be: , 1, 10) But Subset would also allow us to start partitioning the list at a point other than the start. So for example to bring in the 11th 20th member: , 11, 10) Note that asking for more members than exist in the original set will just return as many members as it can rather than an error message. Union joins two sets together, returning the members of each set, optionally retaining or dropping duplicates (default is to drop). To create a list of products that sold something both in this cube and in another (e. g. last year and this): FILTER( , 0), Test.(Posting Measures. Amount) gt 0 ) , FILTER( , 0), Test3.(Posting Measures. Amount, Entity. All Entities) gt 0 ) ) Intersect returns only members that appear in both of two sets. One example might be to show products that performed well both last year and this year, or customers that are both high volume and high margin. The default is to drop duplicates although , ALL can be added if these are required. This example returns leaf Product members that have an Amount gt 5 as well as a Count gt 5. INTERSECT( FILTER( , 0), Test.(Posting Measures. Amount) gt 5 ) , FILTER( , 0), Test.(Posting Measures. Count) gt 5 ) ) Except and Validating Dimension Hierarchies The function takes two sets as its mandatory parameters and removes those members in the first set that also exist in the second . In other words it returns only those members that are not in common between the two sets, but note that members that are unique to the second set are not included in the result set. Except is a useful function in a variety of situations, for example when selecting all the top selling products except for 1 or 2 you already know are uninteresting or irrelevant, or selecting all the cost centres with high IT costs except for the IT department. The simplest example is to have a first set of 2 members and a second set of 1 of those members: EXCEPT ( , ) Which returns MidasJCFI, the only member not in common between the two sets. For the purposes of maximum clarity in the rest of this section only, we will drop the Product reference and trust that these product names are uniquely in the Product dimension on our server. The optional extra ALL parameter allows duplicates to remain prior to the determination of the difference i. e. matching duplicates within the first set are discarded, while non-matching duplicates are retained. A simple example where there are duplicate members in the first set: EXCEPT ( , ) Returns MidasJCCO (because duplicates are discarded without ALL), while: EXCEPT ( , . ALL) Returns MidasJCCO, MidasJCCO (as ALL allows the duplicate MidasJCCO members to be retained). Note that ALL has no effect on the following query as MidasJCFI is the only member not in common between the two sets and so this is the only result either way: EXCEPT ( , ) Returns MidasJCFI. Remember, the members in the first set that also exist in the second are eliminated, hence (both instances of) MidasJCCO is eliminated So if you were to ask for EXCEPT( , ) then the final set would be without ALL and with ALL. Because matching duplicates in the first set are eliminated first (that is, duplicates in the first set that match a member in the second set), Apples (the only member in the second set that matches a pair of duplicates in the first set, is eliminated. To put the fruit down and return to our demo model we can write the equivalent query against products: EXCEPT ( , ) Returns just one MidasJCFI (the equivalent of Oranges above) while: EXCEPT ( , . ALL) Returns two instances of MidasJCFI. These results are due to the fact that, in the example with ALL, MidasJCCO is eliminated due to a matching member in set 2, while MidasJCFI is reduced to 1 instance due to the lack of ALL. MidasHDBK has no impact because it could not be subtracted from set 1 as it was not in set 1. When ALL was used in the second example, the two MidasJCCO members were still eliminated due to a match in set 2, and MidasHDBK was still irrelevant, but this time the two MidasJCFI members were left alone due to the ALL allowing duplicates. Note: the following section does not work in v9.1 SP2, but does work in v9.0. Your mileage may vary. A particularly clever use of Except is to check a TM1 dimension for a valid structure. A simple query can return a list of members that do not eventually roll up into a particular consolidated member. This could be included in a TI process to automate the consistency checking of dimensions after an update. This example returns all the members in the dimension that do not roll up into All Products: EXCEPT ( TM1SUBSETALL( Product ), TM1DRILLDOWNMEMBER( , ALL, RECURSIVE )) Modifying this slightly makes it return base-level members that do not roll up into All Products: EXCEPT ( TM1FILTERBYLEVEL(TM1SUBSETALL( Product ), 0), TM1FILTERBYLEVEL(TM1DRILLDOWNMEMBER( , ALL, RECURSIVE ), 0)) This query returns members that have been consolidated twice or more at some point under the given consolidated member this will often mean there has been an accidental double-count. EXCEPT ( TM1DRILLDOWNMEMBER( , ALL, RECURSIVE ), TM1SUBSETALL( Product ), ALL) It will return one instance of the multi-consolidated member for each time it is consolidated greater than once i. e. if it has been consolidated 4 times then it will return 3 instances. This is due to the fact that TM1SUBSETALL( Product ) will only return one instance of a member that has been consolidated multiple times while the TM1DrilldownMember function will return all the instances. You are reminded that Dimension. Member is actually a shortcut that usually works in TM1 but because the MDX specification allows for member names to be non-unique within a dimension the full address of a member is actually Dimension. Parent1.Parent2Member. Therefore more specific references to duplicate members may be needed, for example Product. Demand Loan. MidasHCBK will address a different instance of MidasHCBK than would Product. Discount Loan. MidasHCBK. In this case, with the Except function, they are treated as if they are different member names altogether. ToggleDrillState ToggleDrillState changes the default drill state from a returned set so if the first query returns a member in a hierarchy rolled up then it will drill it down, or vice versa. Using TM1 Subsets, TM1Member and TM1SubsetToSet One of the special features of using MDX with TM1 dimensions is that existing subsets can be used within the query for defining a new subset. This can be useful in allowing a simpler building block approach and for not having to repeat the same code over and over again and having to maintain it. Used throughout this section, Report Date is an existing subset in the Date dimension containing one leaf date member and test2 is an existing 20-member subset. Note that private subsets are used in preference to public subsets when there is one of each with the same name. This can allow a public subset to return different results based on the contents of different users private subsets, though inevitably with some issues with reliability of results. To simply return the member(s) of pre-existing Date subsets: Date. Report Date Or TM1SubsetToSet(Date, Report Date) The first syntax may be shorter and more convenient but bear in mind, as per the TM1 help file, Since the same syntax (.IDENTIFIER ) is used for members and levels, a subset with the same name of a member or a level will never be instantiated. The second syntax on the other hand will happily work with any subset names even if they are named the same as a cube or dimension. To return the first member of the test2 subset: To return a valid cube reference within a more complex query: TM1Member(Date. Current Date. Item(0), 0) For example: , 1), Reconciliation.(Entity. All Entities, TM1Member(Date. Current Date. Item(0),0),Reconciliation Measures. Transaction Balance) To start with the fourth item (.Item counts from zero) in the test2 subset and then return the preceding 14 members from the whole dimension, including the fourth item: This example returns the one date in Report Date and the next 13 periods, sorted with the earliest date first a moving 2-week reporting window which just needs the Report Date subset to be maintained. This query uses another subset, Strategic Products, as a building block and finds the Top 5 members within it, even though this ranking may well have been based on different values than the original subset was built on. For example, a subset that is already defined may list the 10 highest spending customer segments in terms of year to date actuals, and you then build a new subset that works with these 10 only to find the top 5 in terms of planned marketing spend next quarter. , 5, Test.(Posting Measures. Count)), Test.(Posting Measures. Count), BDESC) Heres a bigger example using TM1member and TM1SubsetToSet functions, in addition to various others. It takes the single period in the Current Date subset and returns the last day of the two preceding months. There would be several different ways of achieving the same result. union( tm1member(tm1subsettoset(Date, Current Date).item(0),0),1) )))), tm1member(tm1subsettoset(Date, Current Date).item(0),0),1) )))) ) Username and StrToMember It returns the TM1 username (or Windows domain username depending on the security system being used for example, GERJEREMY) of the user who runs the query. Note that you may need to give all users Read access to the Clients dimension and all its elements. It is not documented in the help file as being officially supported by TM1 but it is a standard MDX feature that appears to work in v8.3. However, since 8.4.3 until 9.1.2.49 it is reported as failing to automatically update when a new user uses the subset. This can be circumvented by running a frequent TI process that uses the subset as its datasource and the following line in Prolog (Workaround reported by Steve Vincent on the Applix Forum, 2nd August 2006): DIMENSIONSORTORDER(CLIENTS, BYNAME, ASCENDING,,) With this micro-process workaround set to run every few minutes a pseudo-dynamic result is possible. An actual solution to the problem should be tested for in your version if it is 9.1 or later. To save a dynamic subset it needs to be set up on the Clients dimension choose View Control Objects in Server Explorer to see this dimension. Once you have saved the public subset (e. g. as Current User) you can turn this option off again. Clients ), USERNAME ) As an alternative to the above method, and as a way of including the current username directly in queries use the StrToMember function which converts a plain string into a valid MDX member reference. Clients. USERNAME) Either way the subset can then be referred to on Excel spreadsheets, VBA processes and, as it is simply a standard TM1 subset, in TM1 Websheets. As a non-MDX alternative v9.1.2.49 introduced a TM1User(servername) worksheet function which could be used in some circumstances. Data-based queries, Filter, Sum, Avg and Stdev Sometimes it is not adequate to simply use a single value in a query you need to consider a combination of values. It might be that this combination is only needed for one or two queries, though, so it is not desirable to calculate and store the result in the cube for all to see. Therefore it is more logical to quickly calculate the result on the fly and although this is then repeated every time the subset is used, it is still the preferred choice. The function Sum, Avg and Stdev are therefore useful for things that are only needed occasionally or by a limited number of users and means that the actual cube is thus smaller and more efficient. SUM, as it might appear, sums up a set of numbers. This allow the aggregation of members not already consolidated in the model. This example checks the Test3 cube for products whose Amounts in the on-the-fly-consolidation of 2 entities are greater than 50. , 0), SUM( , Test3.(Posting Measures. Amount) ) gt 50 ) AVG calculates the average value of a set. Note how empty (zero) cells are not included by the AVG function so the resulting average value might be higher than you expected. This example returns a list of leaf products that have an Amount value in the Test cube higher than the average Amount value of all leaf products (or rather all non-zero leaf products). , 0), (Test. Posting Measures. Amount gt AVG( , 0), Test.(Posting Measures. Amount)) ) ) The set of members that AVG works on here (AVG , 0)) can be changed to something that doesnt match the list of members being filtered earlier in the query. For example, return a list of all leaf products that are higher than the average of the leaf descendants of the Customer Lending consolidation only. , 0), (Test. Posting Measures. Amount gt AVG(,Test.(Posting Measures. Amount))) ) STDEV is the standard deviation function. It returns the average distance from each value in a set to the average of the set as a whole. In this way you can calculate how consistent or unpredictable a set of data is if all the values lie tightly around the average, or if the values vary to be extremely high and low. This example returns the outlying products whose Amount value in the Test cube is greater than the average value plus the standard deviation i. e. those products who have values that are above averagely above the average. , 0), ( Test. Posting Measures. Amount gt ( AVG( , 0), Test.(Posting Measures. Amount)) STDEV( , 0), Test.(Posting Measures. Amount) gt 0 ) ) ) ) ) Note that the AVG function automatically drops empty cells from the filtering set but STDEV does not so we have to apply our own filter. The above queries could be INTERSECTed for both sets of outliers in one subset, if required. Further reading: The MEDIAN function is also supported by TM1 and might be more appropriate than AVG (mean) in some circumstances. Using parameters in queries TM1Member will allow you to use parameterized references by using cube values as part of the query itself. For example if a UserParams cube was created with the Clients dimension (thus allowing concurrent usage by all users) which would hold various choices made by users as they used your application, then dynamic subsets could use those choices as part of their syntax, thus altering not just the thresholds for comparisons (we can see elsewhere in this document how to check if something is, say, above a certain threshold which is actually a value in another cube) but the actual thing that is queried in the first place. For example, this shows the descendants of a parent member, the name of which is held in the 2D UserParams cube at the intersection of the current username and SelectedParentDimix. TM1SUBSETALL( Product ).Item(UserParams.(StrToMember(Clients. USERNAME), UserParamMeasures. SelectedParentDimix)-1) . 0)) Below are screenshots showing the parameter cube which can be extended to hold various user-specific selections and then link them into dynamic subsets plus the other relevant screens. The Generate function applies a second set to each member of a first set, performing a union of the results. Duplicates are dropped by default but can be retained with, ALL. Although Generate doesnt really do anything unique in itself it is a very useful way of shortening what would otherwise be long, laborious and error-prone queries. In the following example the top performing child product is returned for each member of Level 1 of the hierarchy: GENERATE( , 1), TopCount(Descendants(Product. CurrentMember, 1),1,Test.(Posting Measures. Amount))),Test.(Posting Measures. Amount) gt 0 ) Count and IIF Caveat: Note that IIF is not listed in the TM1 v9.0 SP2 help file as being supported so use at your own risk. Count returns the number of items in a set but this set can be a set of members or a set of data values. The result is, obviously, a number and is often returned in reports when used in MDX queries outside of TM1. When trying to use it do define a TM1 subset it can only be used as part of the query logic and not as a result itself. Count can be wrapped around a lot of the other MDX functions and so can be used in many different scenarios. One example is to count how many children a month has and, if there are 28, doing something that is unique to February. Although dimension subsets are usually a list of meaningful items in a business model and are included within application cubes, it is actually possible to have dimensions for administrator purposes only (that are never used to build cubes) which might indicate the state of something e. g. All Passwords Set, or Reconciliation Failed and the Count function could be used to define a subset that contains one of these members, which is information for the administrator only. IIF allows you to introduce some branching logic in your queries i. e. do one thing if this is true, otherwise do something else. You could use it to apply different statistical functions to members that have certain attributes. It works quite commonly with Count to allow one thing to happen if the count of something falls below a threshold, or do something else if not. This example performs either a Top 5 or a Top 10 on all base products Amounts in the Test cube, depending on whether the number of base level Products is 10 or less at the time the query is run. , 0), IIF(Count( , 0)) lt 10, 5, 10), Test.(Posting Measures. Amount) ) This example does a TopCount of the base products based on their Amount value in the Test cube where the number of items displayed is equal to the number of cells in the Test cube whose Amount value is anything other than zero. , 0), Count( Filter( , 0), Test.(Posting Measures. Amount) These are fairly pointless examples, practically speaking, but they show the syntax. Comments allow you to explain, to yourself andor to your users, what the query is trying to achieve, how it works, who wrote it or amended, etc. Use or (without the double quotes) to end a line with a comment or to have the comment on its own line. You can also use COMMENT (again without the quotes) to insert a comment in the middle of a line. You are also able to type anything after the command. This heavily-commented example returns all the products beginning MidasJ: Comment number 1 this is another comment -- and another comment , this is yet another comment MidasJ) You seem to be able to type what you like here, but treat with caution This does not work in version 8.2.7 but does in at least 9.0 and 9.1.1.

No comments:

Post a Comment