Moving Average In Tm1
Acer Aspire S 13 S5-371 Análise do notebook Para a revisão original em alemão, veja aqui. Após o Aspire S7 e o Aspire S3 barato. Acer lança o próximo representante da classe fina e leve. O Aspire S13 pode ser um meio feliz entre os dois antecessores. Embora use componentes de ponta, por exemplo, uma CPU Intel i7-6500U. Assemelha-se ao Aspire S7 em exibição (Full HD, mat) e dispositivo de armazenamento (até 512 GB SATA3 SSD). Isso cria um computador atraente, rápido e móvel por um preço aproximado de cerca de 1000 Euros (1140). Isso parece familiar para você Por exemplo, os inúmeros modelos UX300 ZenBook da Asus estão exatamente na mesma faixa de preço. Atualizações Changelog 05-10-2016 16:00 informações adicionadas na webcam e um vídeo sobre o ruído do ventilador 05-04-2016 14:30 espaço de cores, classificação, benchmarks de jogos 05-03-2016 18:00 possibilidades de manutenção e atualização explicadas E ilustrado 05-03-2016 09:15 imagens analise de uso externo, análise de áudio, teste de cartão SD, ângulos de visão 05-02-2016 17:00 Análise de bloqueio (desempenho, taxas de clock e temperaturas abaixo de CB15 e The Witcher 3 gt1h) 05 -01-2016 12:45 Ruído do sistema e alto-falantes Benchmarks do Witcher 3 05-01-2016 09:00 Duração da bateria sob carga, AS SSD e 3DMark 11 benchmarks 04-30-2016 23:44 PCMark 8 com análise 04-30- 2016 21:30 primeira publicação Atualizações de manutenção do amplificador Para chegar ao ventilador, bateria e M.2 SSD, primeiro você deve remover 10 parafusos Phillips e afrouxar a borda com um espelho de plástico (para evitar danos) depois. Infelizmente, esta é uma tarefa pesada, durante a qual arruinamos nossa ferramenta. Depois de afrouxar os clipes de plástico, você pode remover o lado de baixo e chegar aos componentes internos. É digno de louvor que a bateria não seja colada, mas apenas ligada a uma ficha e fixada com dois parafusos. Até mesmo o ventilador pode ser alcançado diretamente para limpeza e o M.2 SSD pode ser substituído depois de remover outro parafuso. O módulo Qualcomm Wi-Fi pode ser encontrado no canto superior direito. Ele está conectado a duas antenas e também pode ser substituído facilmente. Comunicação Uma característica especial é o chip 802.11 n da Qualcomm, que é capaz de MU-MIMO. No início dos testes, a conexão WLAN era estável e as taxas de download não diminuíram. Um arquivo de 2 GB foi transferido do nosso WD MyCloud NAS lento em 60-70 MBs (de acordo com o Gerenciador de Tarefas em um tráfego recebido acima de 600 MBits). No entanto, nós só conseguimos 250 Mbits (enviando) e 320 Mbits (recebendo) em um teste padrão com iperf (com nosso roteador de referência Linksys EA8500 com MU-MIMO). O mesmo arquivo do NAS também atingiu apenas 160-200 MBs de acordo com o gerenciador de tarefas depois disso. O teclado retro-iluminado se delicia com um golpe confortável e úmido e nos permitiu uma digitação suave e rápida com poucos erros desde o início. Nós gostamos do layout, da distância da chave e do golpe. Somente as teclas do cursor são um pouco pequenas. Nota: Tivemos uma variante do Aspire S 13 com layout QWERTY sob revisão. Os teclados QWERTZ serão incorporados em modelos vendidos por revendedores alemães. No teste WPM (Words per Minute), o autor alcançou 84 WPM sem adaptação longa. O teste executado diretamente depois com um teclado de mesa Cherry (mecânico) resultou em 90 WPM. Os erros de digitação foram uniformemente distribuídos. No geral, este é um resultado muito bom. O Touchpad é confortavelmente grande e apresenta bons traços de deslizamento. Seu 90 inferior é clicável, embora não seja absolutamente mesmo como uma questão de princípio. Mas, funciona bastante bem para um quetWindows touchpadquot. Embora não consiga acompanhar o atual MacBook Trackpad, definitivamente pertence aos melhores no mundo do Windows. Nosso modelo de teste usa um Intel Core i7-6500U. Nos primeiros benchmarks, mostra um desempenho médio a muito bom em comparação com outros notebooks com i7-6500U. O mesmo é verdadeiro para a unidade gráfica. Aparentemente, o resfriamento é suficiente para bons resultados de desempenho da CPU dual-core com GPU integrada. Verificamos o desempenho dos núcleos do processador no Cinebench R15. O Core i7-6500U incorporado atinge um resultado médio nos testes de um único núcleo. O i7-6500U mais rápido é apenas 8 mais rápido, enquanto o mais lento só atinge 69 do desempenho. Em troca, é apenas 1 abaixo da liderança no teste multi-core. Tudo considerado, isso dá uma ótima performance. Depois de várias corridas do Cinebench R15 Multi, a pontuação do Aspire S 13 é aproximadamente 10 inferior (292 versus 326 pontos). A taxa de clock permanece estável entre 2,6 e 2,7 GHz e os núcleos do processador nivelam-se a 84 C. Desempenho do sistema No benchmark do sistema PCMark8 Home (3.0 acelerado), o S 13 está em par com os melhores notebooks com Core i7-6500Us. O Zenbook UX303UA (5), o Aspire R14 R5-471T (3) eo ThinkPad X1 Carbon (3) são apenas um pouco mais rápidos. No entanto, o Yoga 900. o XPS 13. e o Envy 13 são cerca de 15 mais lentos. A resolução Full HD pode, de fato, levar a um ganho de desempenho em comparação com, por exemplo, Cadernos 4K. Comparado a todos os subnotebooks revisados, o Aspire S13 funciona de forma excelente. O dispositivo mais rápido é o antigo EliteBook 820 G1. Que, no entanto, é apenas 10 mais rápido. A média é significativamente menor em 82. PCMark 8 Home Score Accelerated v2 PCMark 8 Work Score Dispositivo de armazenamento v2 acelerado Nosso modelo de teste usa um SSD de 512 GB de LiteOn como dispositivo de armazenamento. O LITEON CV1-8B512 é um M2 2280 SATA SSD e especificado com um máximo de 520450 MBs (readwrite). Com 502418 MBs, ele obtém bons resultados para um SSD SATA no CrystalDiskMark 3.0 e os resultados do benchmark AS SSD também não são para espirrar. No entanto, é um pouco lamentável que o sistema não use um SSD NVMe mais rápido. No entanto, é questionável se isso seria notável nas tarefas diárias de qualquer maneira. Ruído do sistema De acordo com nossas primeiras observações, o sistema de resfriamento é um saco misto. O ruído do sistema medido não é excessivo. O ventilador geralmente permanece desligado sem carga e o dispositivo está em silêncio. Infelizmente, o pequeno ventilador rapidamente começa a correr com carga mínima. Durante o nosso teste, isso já ocorreu ao abrir sites ou instalar programas. Embora o ruído do sistema medido permaneça baixo, na maior parte, 31,3 dB (raramente 33 dB), a característica de ruído é relativamente desagradável devido a uma alta freqüência e é muito audível em ambientes silenciosos. Além disso, a velocidade do ventilador muda permanentemente, o que torna ainda mais discernível. Sob carga, o ventilador em grande parte desce em 36,9 dB. No entanto, também há picos mais altos. Por exemplo, o dispositivo ficou tão alto quanto 42 dB por um curto período de tempo durante o primeiro 3DMark06 executado em um dispositivo frio. Além disso, ele acelera frequentemente depois que os programas já foram fechados como se desejassem que o resto do calor fosse removido do sistema de refrigeração. Uma vez que a frequência também é desagradavelmente elevada a velocidades de rotação mais elevadas, os usuários sensíveis podem se sentir perturbados em ambientes silenciosos. Se você vai usar o laptop em um escritório normalmente alto, o ruído ambiente certamente irá afogar o ventilador. Em vista das temperaturas acríticas observadas no interior, pode ser possível moderar o ventilador muito ativo com baixa carga com uma atualização de software. Atualmente, a Acer está trabalhando em uma atualização desse tipo de BIOS. Se possível, verificamos novamente o Aspire. O sistema de resfriamento permanece relativamente silencioso, mas a mudança da velocidade de rotação e altas freqüências foi bastante desagradável para nós. Durante a primeira execução do 3DMark06, o ruído do sistema aumenta no início, mas, finalmente, diminui em cerca de 37 dB. Em uma primeira impressão, os alto-falantes tocam alto e claro. No entanto, o som não possui baixos. Torna-se aparente na comparação direta com o diagrama de freqüência do novo Apple MacBook 12. que gera um som excelente em vista de seu tamanho, que o Aspire S 13 mostra especialmente fraquezas em baixas freqüências e altas freqüências. O MB 12 é mais alto em ambos os intervalos e mostra uma curva de freqüência mais linear em geral. Com 80 dB e uma curva de freqüência longe de linear, os alto-falantes não são notáveis. Duração da bateria Com 7,5 horas (452 minutos) em nosso teste de bateria de Wi-Fi (abre páginas da web por meio de script com um brilho de 150 cdm), o Acer Aspire S 13 está acima da média (os subnotebooks revisados nos últimos 24 meses alcançaram 422 minutos em média). O Toshiba Satellite Z30-B-100 lidera com impressionantes 12 horas. O Zenbook UX305UA-FC040T com a mesma combinação CPUGPU realizou 561 minutos (acima de 9 horas) e é o melhor dispositivo 6500U. No entanto, a duração mínima da bateria medida (Battery Eater Classic game load com o brilho máximo), está definitivamente abaixo da média. A duração relativamente baixa da bateria de 1,5 horas é certamente devido ao alto brilho máximo. Por exemplo, o exigente The Witcher 3 correu por duas horas e cinco minutos a 150 cdm, infelizmente, apenas em 14 a 16 fps, mas sem perda de desempenho em relação à operação da rede. Ocioso (sem WLAN, brilho mínimo) Nossa primeira impressão do Acer Aspire S 13 foi muito positiva e isso foi confirmado principalmente pelo resto do teste. Nós gostamos do caso, dos dispositivos de entrada e da tela. Embora a fidelidade de cores seja melhor fora da caixa (muito bons resultados após a calibração), a superfície mate combinada com um brilho máximo elevado é um grande profissional. Nós não gostamos muito do comportamento do nosso modelo de teste inicial, o que mostra uma frequência desagradável. Temos que esperar por uma atualização do BIOS aqui, uma vez que um ventilador ativo não é necessário sob baixa carga em vista das temperaturas. De acordo com a Acer, eles já estão trabalhando em uma atualização para solucionar esse problema. Isso poderia melhorar significativamente a classificação do ruído do sistema e a classificação total dos notebooks pode aumentar em um ponto percentual. Sistema rápido, display IPS brilhante e mate, bem como boa vida útil da bateria em cenários realistas: a Acer criou um pacote bem feito para usuários móveis com o Aspire S 13. Outros prós do Aspire S 13 são o seu bom desempenho e duração da bateria acima 7 horas em cenários do mundo real. Além disso, os dispositivos de entrada foram convincentes em nosso teste. O Asus Zenbooks, incluindo o UX305CA com resfriamento passivo ou o UX303UA equipado de forma semelhante. Estão bastante posicionados como o Acer Aspire S13. Acers Aspire R13 R7-372T é uma alternativa interessante da gama 2 em 1. Atualmente, o Dell XPS 13 é muito bem sucedido no alcance de 13 polegadas e as variantes com CPU i5 e FHD apresentam preços semelhantes. PricecompareCreating Subsistemas Dinâmicos no Applix TM1 com MDX - Um Primer Sobre este Documento Este MDX Primer destina-se a servir como uma introdução simples para criar subconjuntos de dimensão dinâmica usando o MDX no TM1. Ele se concentra em dar exemplos funcionais ao invés de tentar explicar a teoria completa do MDX e garante a cobertura dos recursos mais úteis para os usuários TM1. TM1 atualmente (a partir de 9.0 SP3) só permite aos usuários usar MDX para criar subconjuntos de dimensão e não para definir visualizações de cubo. Isso significa que o uso do MDX no TM1 é muitas vezes bastante diferente em termos de sintaxe e intenção dos exemplos encontrados nos livros e na internet. Como MDX (Multi-Dimensional eXpressions) é uma linguagem de consulta padrão do setor para bancos de dados OLAP da Microsoft, existem muitas referências e exemplos encontrados na Internet, embora tenha em mente que TM1 não suporta todos os aspectos do idioma e adiciona alguns Características únicas próprias. Isso pode dificultar a utilização de exemplos encontrados na web, enquanto que todos os exemplos neste documento podem ser copiados e colados na TM1 e serão executados sem modificação, assumindo que você tenha o exemplo mini modelo criado como documentado posteriormente. Documento completo como apenas uma página HTML aqui. O que é um subconjunto dinâmico baseado em MDX no TM1 Um subconjunto dinâmico é aquele que não é uma lista fixa, estática, mas sim é baseado em uma consulta que é reavaliada sempre que o subconjunto é usado. Na verdade, o MDX pode ser usado para criar um subconjunto estático e um exemplo é mostrado abaixo, mas é improvável que seja útil ou comum. Alguns exemplos de subconjuntos dinâmicos úteis podem ser uma lista de todos os produtos de nível básico, uma lista de nossos clientes Top 10 por margem bruta, uma lista de embarques de fornecimento vencidos, todos os centros de custo que ainda não enviaram seu orçamento. O ponto é que essas listas (subconjuntos) podem variar de segundo a segundo com base na estrutura ou dados no TM1. Por exemplo, assim que um novo ramo é adicionado à Europa, o subconjunto de Brinquedos Europeus irá conter imediatamente esse novo ramo, sem necessidade de qualquer intervenção manual. MDX é o idioma de consulta usado para definir esses subconjuntos. O MDX é uma linguagem de consulta padrão do setor para bancos de dados multidimensionais como o TM1, embora o TM1 suporte apenas um determinado subconjunto (desculpe o trocadilho) de todo o idioma e adicione algumas características únicas próprias. Quando você define um subconjunto usando MDX em vez de um subconjunto padrão, o TM1 armazena essa definição em vez do conjunto resultante. Isso significa que a definição ou consulta é re-executada sempre que você olha para ele sem que o usuário ou o administrador precisem fazer nada. Se o banco de dados mudou de alguma forma, você pode obter resultados diferentes da última vez que você o usou. Por exemplo, se um subconjunto for definido como sendo filhos de West Coast Branches e este retorna inicialmente Oakland, San Francisco, San Diego, quando é definido pela primeira vez, pode retornar Oakland, San Francisco, San Diego, Los Angeles, uma vez que LA tenha Foi adicionado à dimensão como filho de West Coast Branches. Isto é o que queremos dizer com as mudanças dinâmicas do resultado. Outro motivo que pode fazer com que o subconjunto seja alterado é quando é baseado nos valores dentro de um cubo ou atributo. Todos os dias no jornal, os maiores motores do mercado de ações estão listados, como um dos 10 melhores em termos de aumento de preço da ação. Em um modelo TM1, este seria um subconjunto olhando para uma medida de mudança de preço da ação e claramente seria provável que retornasse um conjunto diferente de 10 membros todos os dias. A melhor parte é que o subconjunto atualizará seus resultados automaticamente sem qualquer trabalho necessário por parte de um usuário. Como criar um subconjunto baseado em MDX no TM1 Os mesmos passos básicos podem ser seguidos com todos os exemplos neste documento. Geralmente, os exemplos podem ser copiados e colados na Janela de Expressão do Editor de Subconjunto da dimensão em questão, muitas vezes, Product. Observe que é irrelevante qual cubo a dimensão está sendo usada por você obterá os mesmos resultados, se você abrirá o Editor de subconjunto de dimensão dentro de uma exibição de cubo, a árvore de cubos no Server Explorer ou a árvore de cota no Server Explorer. Para visualizar e editar uma consulta MDX, você pode ver a Janela de Expressão no Editor de Subconjuntos. Para ativar e desativar esta janela, escolha Exibir janela de expressões. Agora, basta digitar (ou colar) sua consulta neste Expression Windows e pressionar o botão Atualizar para ver os resultados. Como criar um subconjunto estático com MDX Um subconjunto estático é aquele que nunca varia em seu conteúdo. Esta consulta irá devolver os mesmos 3 membros (Empréstimo de Desconto, Empréstimo de Termo e Varejo) toda vez. Não se preocupe, fica mais excitante daqui. Como criar um subconjunto dinâmico com MDX TM1 só suporta um certo número de funções a partir da especificação MDX completa. Diferentes versões do TM1 suportarão diferentes funções (e potencialmente suportarão de maneiras diferentes). O conjunto válido de funções para a versão do TM1 que você está usando pode ser encontrado no arquivo de ajuda principal, em Material de Referência, Suporte a Função MDX. Antes de tentar escrever uma nova consulta, certifique-se de que ela é suportada e, embora algumas funções não cotadas certamente funcionem, devem ser usadas por sua conta e risco. A mensagem de erro padrão, que significa que a função é genuinamente não suportada pela sua versão do TM1 é, Falha ao compilar a expressão. Uma palavra de advertência: pela sua própria natureza, os resultados de um subconjunto dinâmico podem mudar. Ao incluir subconjuntos dinâmicos em visualizações, processos, funções SUBNM, e assim por diante, considere cuidadosamente quais os resultados futuros potenciais, especialmente se o subconjunto pudesse um dia estar vazio. Os dois métodos mais comuns para criar realmente um subconjunto dinâmico são criá-los manualmente ou usar o TurboIntegrator. À mão . Você pode digitar (ou colar) uma consulta na Janela de Expressão como explicado anteriormente, ou você pode escolher a Expressão de Registro de Ferramentas (e, em seguida, Parar Gravação quando terminar) para ativar um tipo de gravador de vídeo. Você pode usar os recursos normais do editor do subconjunto (por exemplo, selecionar por nível, classificar, etc.) e este gravador transformará suas ações em uma expressão MDX válida. Esta é uma ótima maneira de ver alguns exemplos de sintaxe válida, especialmente para consultas mais complexas. Quando você está gravando uma expressão e escolha Parar Gravação, a TM1 solicitará que você confirme se deseja anexar a expressão com o subconjunto - certifique-se de dizer Sim e marque a caixa de seleção Salvar Expressão ao salvar o subconjunto resultante, caso contrário, apenas uma lista estática Do resultado é salvo, não a própria consulta dinâmica. Usando o TurboIntegrator. Apenas uma linha, usando SubsetCreateByMDX, é necessária para criar e definir o subconjunto. Você precisará saber qual consulta você deseja como a definição já. Observe que a consulta pode ser compilada no script TI usando a concatenação de texto, portanto, pode incorporar variáveis do seu script e permitir que consultas longas sejam compiladas em estágios mais fáceis de ler e manter. SubsetCreatebyMDX (Produtos base,, 0)) Todos os subconjuntos MDX criados pela TI são salvos como consultas MDX dinâmicas automaticamente e não como uma lista estática. Observe que, pelo menos até o TM1 v9.0 SP3, os subconjuntos baseados em MDX não podem ser destruídos (SubsetDestroy) se eles estiverem sendo usados por uma exibição pública e não podem ser recriados usando um segundo comando SubsetCreateByMDX. Portanto, é difícil alterar subconjuntos baseados em MDX usando TI. Embora a natureza dinâmica da definição do subconjunto possa torná-lo um pouco improvável, você realmente quer fazer isso, é importante ter em mente. Se você precisar alterar algum aspecto da consulta (por exemplo, um TM1FilterByPattern de 2006-12 a 2007-01, talvez você precise definir a consulta para usar parâmetros externos, conforme documentado neste documento. Isso terá um impacto de desempenho pequeno sobre o mais simples Versão codificada. Além disso, filtre contra valores de um cubo com SubsetCreateByMDX na guia Epilog, por exemplo, 0), Test. (Posting Measures. Amount) gt 0) não funcionará se os valores tiverem sido carregados na guia Dados. Você precisa executar o comando SubsetCreateByMDX em um processo posterior da TI. Observe que a TI possui um limite de 256 caracteres para definir subconjuntos MDX, pelo menos até o v9.1 SP3, que pode ser bastante limitante. Sintaxe e Layout Uma consulta pode ser quebrada em várias linhas para torná-la mais legível. Por exemplo: FILTER (, 0), Test2. (Rate Measures. Rate) 19) é mais legível do que ter toda a consulta em uma linha. A seção de filtro atual é mais facilmente lida e modificada agora por ter ela em uma linha por si só. Observe que as referências aos membros normalmente têm o nome da cota como um prefixo. Por exemplo, de fato, o nome da dimensão é opcional, mas somente se o nome do membro (Retail neste caso) é completamente exclusivo em todo o servidor - isto é, não há cubos, dimensões ou membros com esse nome exato. Por exemplo, esta é a mesma consulta com o nome da dimensão omitido: o que funcionaria no contexto do aplicativo de exemplo usado por este documento, mas seria arriscado em uma aplicação do mundo real. A mensagem de erro recebida ao esquecer de especificar o prefixo seria algo parecido com o nome Nível ou membro Vizinhança ambígua: encontrada nas dimensões e depois continua a listar as várias dimensões em que o nome do membro não exclusivo pode ser encontrado, o que é muito útil. Portanto, certamente é mais seguro e mais performante para usar sempre o prefixo de dimensão. O uso de colchetes pode às vezes parecer um pouco arbitrário ao ler exemplos de consultas MDX. O fato é que um nome de objeto OLAP (por exemplo, nome do cubo, nome da cota, nome do membro) deve estar entre colchetes apenas se contiver um espaço, começa com um número ou é uma palavra reservada MDX (por exemplo, Selecionar). No entanto, às vezes pode ser mais simples decidir sempre usar colchetes, de modo que as consultas semelhantes podem ser comparadas lado a lado com mais facilidade. A definição exata de um membro no TM1 é quase sempre expressa como Nome da Dimensão. Nome do Membro e não mais. Em outros produtos que também usam o MDX como linguagem de consulta (como o Microsoft Analysis Services), você pode notar que as consultas especificam o caminho completo do nome da cota até a hierarquia até o nome do membro, por exemplo: Data.2009.Q1.Feb. Week 06 Isso também pode ser escrito como Date.2009Q1FebWeek 06 O motivo para isso é que outros produtos podem não exigir que cada nome de membro seja único, pois cada membro tem um contexto (sua família) para permitir que seja identificado de forma exclusiva, e é por isso que Eles precisam saber exatamente qual semana 06 é necessária, pois pode haver outros (em 2008, por exemplo, no exemplo acima). O TM1 exige que todos os nomes de membros, em qualquer nível (e dentro de Alias), sejam completamente únicos dentro dessa dimensão. A TM1 precisaria que você fizesse o primeiro trimestre, fevereiro e semana 06 mais explícito em primeiro lugar (ou seja, Q1 2009, fevereiro de 2009, semana 06 de 2009), mas você pode simplesmente se referir a Date. Week 06 2009. Finalmente, caso (ou seja, letras maiúsculas Versus minúsculas) não é importante com os comandos MDX (por exemplo, Filtro ou FILTRO, TOPCOUNT ou TopCount estão todos bem), mas novamente você pode preferir adotar apenas um estilo como padrão para facilitar a leitura. O modelo de exemplo utilizado Neste documento, serão apresentados muitos exemplos de consultas dinâmicas. Todos eles funcionam (exatamente como escrito, basta copiá-los e cole-os na Janela de Expressão no Editor do Subconjunto da dimensão apropriada para usá-los) no conjunto simples de cubos e dimensões mostrados abaixo. O modelo é deliberadamente simples sem características especiais, então você deve achar fácil transferir o trabalho para o seu próprio modelo. O modelo utilizado incluiu 1 dimensão principal, Produto, na qual a grande maioria das consultas funciona mais 3 cubos: Test, Test2 e Test3. Os valores de dados nos cubos variam durante o teste (você quer ajustar os valores e re-executar a consulta para se certificar de que os resultados mudam e estão corretos), mas as capturas de tela abaixo mostram as estruturas de cubos e dimensões bem o suficiente para você recriar rapidamente Eles ou como usar seu próprio modelo em vez disso. Para simplificar a distribuição deste documento, não há intenção de também distribuir os arquivos do modelo TM1 atual. Observe que a principal dimensão utilizada, o Produto, apresentou irregularidades e múltiplas hierarquias. TM1SubsetAll, Membros, intervalo de membros A base para muitas consultas, isso retorna (quase, veja abaixo) a dimensão inteira, que é o equivalente a clicar no botão Todo no Editor do subconjunto. TM1SUBSETALL (Produto) Observe que apenas a instância final na primeira hierarquia de membros que são consolidadas várias vezes é retornada. A função Membros, por outro lado, oferece a dimensão completa, as duplicatas incluídas: Product. Members Um grupo de membros contíguos do mesmo nível pode ser selecionado especificando o primeiro e último membro do conjunto que você precisa com um dois pontos entre eles. Este exemplo retorna de 1 de janeiro a 12 de janeiro de 1972. Selecione por Nível, Expressão Regular (Padrão) e Ordinal Selecionar membros com base em seu nível na hierarquia de dimensão (TM1FilterByLevel) ou por um padrão de strings em seu nome (TM1FilterByPattern) pode ser visto Facilmente usando o recurso Gravar Expressão no editor de subconjuntos. O clássico todos os membros da folha consulta usando o comando de filtragem de nível TM1s TM1FilterByLevel:, 0) Selecione todos os membros da folha que combinam o curinga HC, isto é, que têm H e C como o terceiro e quarto caracteres a partir do final do seu nome. , 0), HC) O motivo pelo qual essas funções começam com TM1 é que eles não são comandos MDX padrão e são exclusivos do TM1. Existem dois motivos principais pelos quais a Applix implementará tais funções únicas: adicionar um recurso presente no padrão TM1 e os usuários perderão se não estiver lá ou porque o TM1 padrão possui o mesmo recurso que o MDX, mas o implementou historicamente de maneira ligeiramente diferente MDX e, portanto, novamente, causaria problemas nos usuários se fosse implementado apenas na maneira MDX padrão. Nestes dois casos, TM1FilterByPattern traz uma função comumente usada pelos usuários de TM1 que faltam no MDX, enquanto o TM1FilterByLevel existe porque o TM1, desde o seu lançamento em 1984, numerou os níveis de consolidação a partir de zero para o nível da folha aumentando os níveis para o nível Membros totais, enquanto a Microsoft decidiu fazê-lo exatamente o contrário. Em determinadas situações, é útil usar o método de níveis MDX padrão e isso também está disponível com a função Levels. Ele permite que você retorna os membros de uma dimensão que residem no mesmo nível que um membro nomeado, basta ter em mente que o MDX padrão ordena os níveis em termos de distância do topo da hierarquia e não o fundo como TM1. Este exemplo retorna todos os membros no mesmo nível que o membro Varejista: o qual, embora o varejo seja uma consolidação de alto nível, retorna um item N: (Produto não aplicável) na dimensão, porque isso rola diretamente em todos os produtos, assim como o varejo, para que Eles são considerados no mesmo nível. Para filtrar a dimensão com base em um número de nível, você precisa usar a função. Ordinal. Isso não está documentado como sendo suportado no arquivo de Ajuda e não funcionou no 8.2.7, mas parece funcionar em 9.0 SP3 e 9.1.1.36 pelo menos. Este exemplo retorna todos os membros no Nível 1: Product. CurrentMember. Level. Ordinal 1) Este exemplo retornaria todos os membros não ao mesmo nível do empréstimo de desconto. , Product. CurrentMember. Level. Ordinal TM1Sort, TM1SortByIndex e Order TM1Sort é o equivalente a pressionar um dos dois botões Ordenar Ascending ou Sort Descending no editor de subconjuntos, ou seja, classificar alfabeticamente. TM1SortIndex é o equivalente a pressionar um dos dois botões Classificar por índice, ascendente ou Classificar por índice, descendente no editor de subconjuntos, ou seja, classificar pelo índice de dimensão (dimix). O pedido é uma função MDX padrão que usa um valor de dados de um cubo para executar o ordenamento. Por exemplo, classifique a lista de clientes de acordo com as vendas ou uma lista de funcionários de acordo com a duração do serviço. Classifique toda a dimensão do Produto em ordem crescente alfabeticamente. , ASC) Classifique os membros da folha da dimensão de acordo com seus valores de Quantidade no Cubo de teste do mais alto para baixo. ORDEM (, 0). Test. (Posting Measures. Amount), BDESC) Observe que usar BDESC em vez de DESC dá resultados radicalmente diferentes. Isso ocorre porque o BDESC trata todos os membros do conjunto usado (neste caso toda a dimensão) como irmãos iguais e classifica-os de acordo, enquanto o DESC trata os membros como ainda em seus grupos familiares e os classifica apenas contra seus próprios irmãos diretos . Se você não tem certeza do que isso significa e não pode ver a diferença quando você tenta, então use o BDESC Order também pode usar um atributo em vez de um valor de cubo. Neste exemplo, o atributo AlternateSort do Produto é usado para classificar os filhos do Demand Loan em ordem decrescente. É um atributo numérico que contém inteiros (ou seja, 1, 2, 3, 4, etc.) para permitir que uma ordem de classificação completamente dinâmica seja definida: Product. AlternateSort, DESC) TopCount e BottomCount Um comando clássico Top 10:, 0), 10, Test. (Posting Measures. Amount)) Ao omitir uma ordem de classificação, ele classifica na ordem padrão (que tem os valores decrescendo em valor e quebra as hierarquias presentes). Uma consulta Top 10 com uma ordem de classificação explícita para os resultados. , 0), 10, teste. (Postando medidas. Amount)), teste. (Postando medidas. Amount), BDESC) BDESC significa quebrar a hierarquia. Observe como a medida escolhida é repetida para a ordem de classificação. Embora a mesma medida seja usada na amostra acima, você pode realmente encontrar os 10 melhores produtos por vendas, mas depois exibi-los na ordem, por exemplo, unidades vendidas ou um atributo de Importância Estratégica. Estes são os 10 melhores produtos com base nos valores da Taxa Test2s, não encomendados, então serão ordenados de acordo com os valores em Test2. 0), 10, Test2. (Rate Measures. Rate)) Estes são os 10 melhores produtos com base nos dados test2s na medida Rate, ordenada de 10 a 1., 0), 10, test2. (Rate Measures. Rate) ), Test2. (Rate Measures. Rate), ASC) O TopCount faz automaticamente uma classificação descendente por valor para obter os membros TOP. Se isso não for desejado, você pode querer usar a função Cabeça (detalhada abaixo) em vez disso. BottomCount é o oposto do TopCount e, portanto, é usado para encontrar os membros com os valores mais baixos em um cubo. Tenha em atenção que o valor mais baixo geralmente é zero e se esse valor precisa ser excluído da consulta, você precisará consultar a seção sobre a função Filtro posteriormente neste documento. Uma consulta Bottom 10 com uma ordem de classificação explícita para os resultados. , 0), 10, teste (Measing Measures. Amount)), teste. (Posting Measures. Amount), BASC) Leitura adicional: TopSum, TopPercent e seus equivalentes inferiores são funções relacionadas úteis. Filtro, por valores, strings e atributos A função FILTER é usada para filtrar a dimensão com base em algum tipo de valores de dados em vez de apenas os membros e sua hierarquia por conta própria. Estes dados podem ser dados de cubos (numéricos ou de cadeia) ou dados de atributos. Isso requer uma mudança de pensamento a partir de dimensões simples diretas (listas com uma hierarquia e ocasionalmente alguns atributos) para um espaço multidimensional, onde cada dimensão nesses cubos deve ser considerada e tratada. Este exemplo retorna os membros da folha do Produto que possuem um Valor Valor no Cubo de teste acima de zero. , 0), Teste (Medidas de lançamento). Gt 0) Uma vez que o cubo de teste possui apenas 2 dimensões, produto e medidas de lançamento, este é um exemplo simplista. A maioria dos cubos terá mais do que apenas a dimensão sendo filtrada e a dimensão com o valor do filtro. No entanto, é simples expandir o primeiro exemplo para trabalhar em um cubo maior. Este exemplo retorna os membros da folha do Produto que possuem um Valor Valor para Todas as Entidades no Cubo Test3 acima de zero. , 0), Test3. (Entidade. Todas as Entidades, Medidas de Postagem. Montante) gt 0) Como você pode ver do acima, simplesmente inclua todas as referências de dimensão necessárias dentro dos suportes redondos. Normalmente, você precisará apenas de um membro nomeado específico (por exemplo, All Entities). Se a dimensão for omitida, então o CurrentMember é usado em vez disso, o que é semelhante ao uso de dimensão (ou seja, para cada) em uma regra TM1 e pode retornar resultados diferentes a uma velocidade diferente. Em vez de apenas usar um valor codificado para filtrar contra (zero nos exemplos acima), este exemplo retorna todos os produtos com uma quantidade no cubo Test maior ou igual ao valor na célula MidasJCFI, Montante. , 0), Test. (Posting Measures. Amount) gt Test. (Product. MidasJCFI, Posting Measures. Amount)) Esta consulta retorna os produtos que possuem um valor de Taxa em Test2 maior do que MidasJXCOs Rate em Test2. Agora, essa consulta apenas retorna um conjunto de produtos até você, cujo cubo você exibe esses produtos, ou seja, você pode executar isso enquanto navega no Teste e, portanto, retorna o que parece um conjunto de produtos quase aleatório, mas o fato é que a consulta está sendo filtrada A lista de produtos com base em dados mantidos em Test2. 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 allow ing 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.
Comments
Post a Comment