por Justin Joyce, LANtek
Nota
Este artigo faz parte de uma coleção de mensagens de quatro anos do blogue Get the Point para utilizadores finais do SharePoint.
Descrição geral: Relatórios personalizados de envelhecimento sem código
Uma das peças funcionais mais solicitadas de um site do SharePoint é um relatório de envelhecimento para tarefas ou itens de lista. Por outras palavras, quantos dias/meses passaram desde que este item de lista foi modificado pela última vez?
À primeira vista, este parece ser um pedido muito simples. Afinal, temos datas para itens que estão sendo criados e modificados, temos a capacidade de armazenar datas personalizadas quando certas alterações nos itens ocorrem através de receptores de eventos. Temos colunas calculadas onde podemos incluir fórmulas semelhantes ao Excel para trabalhar com as nossas informações. Esta parece ser uma proposta bastante simples. Escolhemos um campo de data, criamos uma coluna calculada e, em seguida, escrevemos uma fórmula nos moldes de [DateField] – [Today]. Ah, não tão rápido assim! Como qualquer pessoa que tenha tentado esta tarefa "simples" sabe, tentar usar algo como [Hoje] em uma coluna calculada causa problemas. Tentar inserir [Hoje] na caixa de fórmula da coluna calculada irá obter uma mensagem de erro semelhante à seguinte:
Porquê? Bem, tem a ver com a forma como as colunas calculadas são calculadas.
Tomemos uma fórmula simples como exemplo:
= SE( [Coluna1]<=[Coluna2], "OK", "Não OK")
Tudo isto diz que se a Coluna1 for menor ou igual à Coluna2, então apresentar OK, caso contrário, apresentar Não OK. Esta é uma fórmula básica bastante típica para uma coluna calculada e faz uma suposição básica sobre o item de lista que contém estas colunas: os valores para a Coluna1 e Coluna2 nunca poderão ser alterados sem um evento Update no item de lista.
Isto mesmo, as colunas calculadas só serão recalculadas quando a lista for atualizada (ou criada), uma vez que assumem que as informações que está a calcular estão contidas no item. Isto cria um problema quando está a tentar utilizar algo que muda independentemente dos campos do item, como a data de hoje.
Agora eu não estava na reunião onde eles decidiram que esta é a maneira que as colunas calculadas funcionariam, no entanto, se eu tivesse que fazer um palpite educado, eu assumiria que eles funcionam dessa maneira para o desempenho. Imagine se você tivesse uma lista de milhares de itens, cada um contendo uma coluna calculada que precisava de uma atualização "ao vivo". Isso significaria que algum mecanismo, talvez um trabalho de temporizador, teria que iterar através de cada item que contivesse aquela coluna calculada de vez em quando e atualizar seu valor. Isso pode ser extremamente desgastante em termos de desempenho, porque com implantações maiores, esse trabalho pode estar constantemente em execução e mudando as coisas. Esse é apenas o meu palpite, mas faz bastante sentido se você pensar sobre isso.
Existem algumas sugestões de soluções semelhantes que circulam por aí que envolvem induzir o SharePoint a aceitar um valor Hoje ao criar primeiro uma coluna com o nome Hoje, adicioná-lo à sua fórmula e eliminá-lo. Tudo isto é bom, mas lembre-se do que disse quando as colunas calculadas são atualizadas. Este valor só será alterado quando o item for atualizado, o que significa que os seus valores estarão incorretos em breve, especialmente no caso de um cálculo diário.
Já vi outros usando JavaScript inteligente para escrever os valores na página. Isso também funcionaria, mas sou categoricamente contra o script do cliente quando ele pode ser evitado.
Execução:
Então, o que fazer? As colunas calculadas estão fora de questão para as chamadas funções "voláteis" como Hoje. É possível que possamos desenvolver algum código personalizado para cuidar disso para nós, como uma Coluna Computada, trabalho de temporizador ou processo agendado para vir e atualizar cada item que precisa desse cálculo feito. Isso nos leva de volta ao problema de desempenho que mencionei no último parágrafo e, além disso, é uma solução frágil que seria altamente específica para o site/lista/coluna em questão. Além dessas duas preocupações, você também teria que encontrar um cara nerd, como eu, que saiba codificar e persuadi-lo a desenvolver essa solução para você. Mas há uma maneira mais fácil!
Se tiver direitos para criar campos e editar páginas no seu site e tiver um pouco de conhecimento sobre XSLT e criação de vistas, pode criar um modelo XSL que pode ser incluído numa vista de lista e calculará fielmente o seu valor sempre que a página for pedida. Este cenário elimina a nossa preocupação com o desempenho e não necessita que o código personalizado seja desenvolvido e implementado através de uma solução.
Perfeito. Então, como o fazemos?
- Crie ou selecione o campo que funcionará como nossa fonte. Tem de ser um tipo de data.
- Crie o nosso campo que irá agir como um marcador de posição para o valor a ser calculado.
- Adicione ambos os campos a um tipo de conteúdo e adicione esse tipo de conteúdo a uma lista.
- Crie uma vista dessa lista que contenha as colunas de origem e de marcador de posição.
- Carregue o modelo XSL para a Biblioteca de Estilos.
- Defina a propriedade "Ligação XSL" para a Peça Web Vista de Lista através da IU.
- Êxito!
Vamos explorar um exemplo de caso de uso e acompanhar a implementação. O nosso cliente queria uma vista da sua lista principal que lhe dissesse há quanto tempo um determinado item da lista estava parado no seu estado. Esta lista continha um tipo de conteúdo de site personalizado derivado do tipo de Item e adicionado à lista. Já existia um recetor de eventos que regista sempre que o campo de estado no item de lista foi alterado e guarda essa data numa coluna denominada "Date Status Changed". Toda essa fiação não é necessária, e pode ser feita com QUALQUER campo de data (acontece que esta é a nossa implementação, mas sinta-se à vontade para experimentar). O mínimo que você precisará é do campo de data de origem e do campo de espaço reservado para manter seu cálculo (mais sobre isso no próximo parágrafo) adicionado à sua lista, embora eu sugira que você use colunas de site e tipos de conteúdo de site caso deseje reutilizar essa solução em outros lugares em seu site.
Assim, temos a nossa data de origem que podemos utilizar no cálculo em relação à data de hoje. Agora podemos criar uma coluna de site personalizada para utilizar como contentor para o nosso valor calculado. Neste caso, optei por utilizar uma coluna calculada, uma vez que não poderá ser alterada nos formulários de itens novos ou de edição, mas pode ser selecionada para apresentação nas vistas, uma vez que não queremos que os utilizadores introduzam valores arbitrários nesta coluna. Pode ser confuso por que ele não está sendo exibido nas vistas, etc.
Agora que temos nossa coluna do site, podemos adicioná-la aos nossos tipos de conteúdo que serão usados em nossa lista. Em seguida, precisamos criar nossa visão que mais tarde será personalizada com nosso XSLT. Certifique-se de que cria uma vista padrão que contém a coluna Data de Origem e a nova coluna calculada que funcionará como um marcador de posição do valor calculado.
Agora temos tudo no lugar que precisaremos para dar suporte ao nosso relatório personalizado de envelhecimento. Tudo o que resta é criar nosso modelo XSL, carregá-lo para a Biblioteca de Estilos do site e vinculá-lo à nossa visualização de lista. O modelo XSL que iremos utilizar irá conter algumas marcações normais geradas pelo SharePoint para gerar a vista, bem como a nossa própria marcação personalizada utilizada para substituir determinadas partes e calcular o valor desejado para nós.
Dando crédito onde o crédito é devido, os modelos XSL para fazer os cálculos reais que estou usando para esta solução foram graciosamente fornecidos por "swirch" nos fóruns MSDN:
http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/aeda905b-9bc6-40c4-bd22-21306c5cb0d2/
Baixe a folha de estilo XSL (aging.zip) que montei localizada aqui:
https://OneDrive.live.com/?cid=c262e8e2d59a86d9&permissionsChanged=1&id=C262E8E2D59A86D9!104
Abrindo isso em seu editor de texto favorito você verá uma abundância de marcação XSL normal do SharePoint para renderizar as visualizações, se você continuar rolando para baixo até a linha 357 você verá o início dos modelos personalizados que eu adicionei à marcação, sendo o primeiro o modelo "DateDiff" seguido por "calculate-julian-day" e "FieldRef_printTableCell_EcbAllowed.Days_x0020_At_x0020_Status". Estes são os nossos três modelos que farão e apresentarão os nossos cálculos nas nossas vistas. Se pretender utilizar nomes de campos diferentes dos especificados anteriormente neste artigo, terá de percorrer estes modelos e substituir as referências aos outros nomes. Lembre-se, para isso você vai querer usar o nome INTERNO do campo e não o nome de exibição.
Quando estiver satisfeito com a conclusão do modelo, navegue até a Biblioteca de Estilos e carregue-o na pasta "Folhas de Estilos XSL" e, em seguida, copie o link para o arquivo. Isso nos permitirá facilmente fazer alterações a ele mais tarde, ou adicioná-lo a diferentes partes do site como quisermos.
Em seguida, aceda à sua lista e selecione a vista que criou anteriormente neste artigo. No menu "Ações do Site", clique em "Editar Página".
Localize a Peça Web Vista de Lista na página e abra o menu Peça Web clicando na pequena seta a apontar para baixo no canto superior direito. A partir deste menu, selecione "Editar Peça Web".
Esta ação irá abrir o menu da Peça Web no lado direito da janela do browser.
Clique no + para a seção "Diversos" e localize a propriedade "Link XSL".
Cole a ligação para o seu ficheiro XSL na Biblioteca de Estilos que copiou anteriormente (pode ser uma ligação relativa ou absoluta).
Clique em "OK" para salvar suas alterações e, em seguida, clique no botão "Parar edição" na faixa de opções "Página" na parte superior da página.
Se tudo tiver sido configurado corretamente, agora deverá ver números na coluna "Dias no Estado".
E, finalmente, aqui está como seria com alguns dados de teste de várias datas:
Resumo:
Aqui está: uma forma bem formatada, robusta e com melhor desempenho para criar um relatório antigo no SharePoint., completo com uma implementação simples sem código. Isso tem algumas aplicações potenciais, além do único caso de uso que exploramos aqui. Outro cenário comum para este tipo de relatório é anexá-lo a uma lista de tarefas para que possa ver rapidamente quanto tempo passou desde que uma tarefa foi criada.
Esperamos que goste!
--Justino
Justin Joyce, LANtek
Comentários
Passos em falta
08/10/2012 03:51
ok eu segui as etapas, mas deve haver algo faltando - como o XSL saberá qual data usar, ou qual campo para adicionar os dias desde em? odeio quando passos são perdidos.
Não-Código, concordo!
30/8/2012 12:12
Eu concordo - eu não acho que isso realmente conta como "sem código".
Curiosamente, através de algum erro do SharePoint, eu tenho uma coluna calculada de trabalho usando Hoje ... não sei como ou porquê porque não consigo fazê-lo novamente, mas o que ainda está lá e trabalhando.
Fórmula para a Coluna Calculada "Dias no Estado"?
02/05/2012 07:39
Justin – Qual é a fórmula que utilizou para a sua coluna de site calculada "Dias no Estado" (coluna de marcador de posição)? Foi "=hoje"?
SharePoint 2007
02/12/2011 11:29
Atualmente eu não tentei aplicar essa solução para o SharePoint 2007, no entanto, estou olhando para ele. Infelizmente, não existe nenhuma propriedade XslLink apresentada na peça Web através da IU.
Ótimo Post
30/11/2011 09:53
Olá,
Ótimo post.
Estou usando o SharePoint 2007.
Eu não tenho uma seção Misc como observado acima.
Tem passos para uma configuração do SP2007?
Obrigado.
Re: Solução sem código: Apresentar o número de dias desde a última alteração de um item de lista do SharePoint
11/10/2011 08:24
Oi Chris.
ótimo achado!
Vou dar uma olhada no que você postou espero que mais tarde hoje e ver se eu posso tornar esta solução um pouco mais robusta.
Estou feliz que você gostou do post, e estou muito feliz que você foi capaz de encontrar uma solução para o formato de data europeu. :)
-Justino
Solução para formatos de data europeus
11/10/2011 06:45
Olá novamente Justin,
FYI, encontrei uma solução para o problema que mencionei anteriormente nesta página;
https://sharepointbydummies.wordpress.com/2011/07/13/possible-work-around-to-date-format-issue-sharepoint-2010/
Formatos de data europeus
07/10/2011 03:59
Olá Justin,
Esta é uma solução muito boa, obrigado, e apenas o tipo de coisa que passei os últimos dois dias procurando! No entanto, estou tendo um pouco de problema com isso e eu estava esperando que você pudesse me ajudar.
Eu alterei seu código ligeiramente para calcular o número de dias até que algo aconteça, em vez de desde então, trocando as variáveis na última linha da função "DateDiff";
<xsl:value-of select="$JulianToday - $JulianStartDate"></xsl:value-of>
No entanto, eu só sou capaz de fazê-lo para reduzir a diferença corretamente metade do tempo. Assim, por exemplo, com esta data (formato dd/MM/aaaa);
30/12/2011
Calcula corretamente, mas com esta data (mesmo formato)
12/10/2011
Ele calcula como se 10-dez-2011 em vez de 12-out-2011.
Eu tentei simplesmente mudar as posições dos valores de dia e mês na variável "JulianStartDate", assim;
<xsl:with-param name="Month" select="substring(ddwrt:FormatDateTime(string($StartDate), 1033, 'yyyyMMdd'),7,2)"/>
<xsl:with-param name="Day" select="substring(ddwrt:FormatDateTime(string($StartDate), 1033, 'yyyyMMdd'),5,2)"/>
E isso corrigiu o problema com a segunda data, no entanto, estava incorreto para a primeira data!
Também tentei alterar as chamadas FormatDateTime para usar LCIDs europeias e várias alterações no último parâmetro de FormatDateTime (por exemplo, ddMMyyyy, MMddyyyy) com os ajustes apropriados para os parâmetros posicionais da substring sem sucesso.
Eu apreciaria muito qualquer conselho que você possa oferecer.
Obrigado,
Fábio
No-Code
21/09/2011 04:27
Eu não acho que XSL se qualifica como uma solução "no-code", como entender a linguagem XSL não é para todos - no entanto, não envolve programação. Além disso: Boa solução, obrigado!