Mostrando postagens com marcador 5 dicas. Mostrar todas as postagens
Mostrando postagens com marcador 5 dicas. Mostrar todas as postagens

segunda-feira, 13 de outubro de 2014

Criando um Relatório Personalizado no Preactor em 5 passos

Um demanda correte para qualquer software são os relatórios, eles podem ser para simples visualização, gerenciais, estratégicos etc. 

Os relatórios são responsáveis por mostrar os resultados do uso de um software, que podem representar a verdade sobre a empresa ou se o uso do sistema não for o mais adequado, ele também pode mascarar resultados.

Enfim, os relatórios sempre são muito importantes para qualquer software, e para o Preactor não é diferente.

Por esse motivo resolvi escrever um simples tutorial de como implementar um novo relatório para o Preactor.


Relatório: 


Em nosso exemplo vamos criar um relatório de ordens programadas, onde devemos mostrar, o identificador da ordem, nome do recurso, data de início da ordem e data de fim. Terremos um filtro por "Programação salva" e outro "por período", ok?

Pré-Requisitos:

  • Preactor 11.2 ou superior;
  • SQL Server 2008;
  • MSQL Manager Studio;
  • Ter um modelo Preactor devidamente instalado em sua máquina;
  • Visual Studio 2005 Report Server ou SQL Server 2005 ADV


Eu indico o uso do SQL Server 2005 Business Intelligence, pois ele já instala o Visual Studio 2005 Report Server, por isso segue o link do mesmo para download: clique aqui para download;
Outro link: http://www.microsoft.com/en-us/download/details.aspx?id=5897


Bem, caso você não tenha conhecimentos de SQL server, esse vídeo irá te ajudar a entender um pouco da linguagem t-SQL https://www.youtube.com/playlist?list=PLucm8g_ezqNqI5cW3alteV5olcMCcHYRK


1º Passo


 - Escrever as querys no Microsoft SQL SERVER Manager Studio


Query:
SELECT O.Cdigo AS PARTNO, R.Nome AS RECURSO, O.IncioDaOrdem, O.FimDaOperao
FROM UserData.Ordens O
JOIN UserData.Recursos R on O.Recurso = r.Nmero
WHERE O.DatasetId = 145
AND O.IncioDaOrdem BETWEEN '2014-10-10' AND '2014-10-15'

OBS: todas as tabelas utilizadas para cadastro no Preactor estão dentro do schema "UserData";


2º Passo

Vamos criar nosso projeto no Visual Studio 2005:














3º Passo

Vamos criar os parâmetros do relatório e testar.

Vá na aba Data de seu relatório e vamos primeiramente adicionar um novo Dataset que irá conter as programações salvas do Preactor, para isso vejas as imagens logo abaixo:





query: SELECT DatasetId, name FROM UserData.Ordens_Dataset

Ordens_Dataset: tabela que contém as programações salvas do Preactor, por exemplo, caso você queria comparar duas programações salvas basta utilizar essa tabela;


Criando os parâmetros na query principal:

Para criar um parametro no Report Server basta na query principal, substituir os valor que DataSetId e da Data inicial da Operação por uma variavel, que é definida pelo caracter @:

SELECT O.Cdigo AS PARTNO, R.Nome AS RECURSO, O.IncioDaOrdem, O.FimDaOperao
FROM UserData.Ordens O
JOIN UserData.Recursos R on O.Recurso = r.Nmero
WHERE O.DatasetId = @PROGRAMACAO

AND O.IncioDaOrdem BETWEEN @INICIO AND @FIM

Logo em seguida vá no menú "Report", "Report Parameters"








4º Passo


Para finalizar vamos acertar o layout do nosso relatório.

Para adicionar o Número da Página: =Globals!PageNumber

Para colocar o relatório Zebrado: Clique sobre as linhas da tabela, aperta a tecla F4 (Propriedades), vá no item Backgroud: =iif(RowNumber(Nothing) mod 2=1,"LightBlue","White")






Para Concluir vamos ver como ficou nosso relatório aqui:



5º Passo

Agora com o relatório desenvolvido vamos coloca-lo em uso no Preactor, para isso vá no explorer, na pasta onde você salvou seu projeto e copie o arquivo "Lista de Ordens Sequenciadas.rdl", 



e cole esse arquivo na pasta de relatórios de seu modelo Preactor.



Agora vamos chamar nosso relatório de dentro do Preactor.



Espero que tenha ajudado, o grande segredo para escreve ótimos relatórios para o Preactor é você estudar bem suas tabelas, pois toda informação está disponível, as vezes não de forma muito clara. Por isso com um pouquinho de empenho você conseguirá montar qualquer relatório que te pedirem.

Se precisar de ajuda basta comentar aqui, ou me escrever besaleel@msn.com

quinta-feira, 2 de outubro de 2014

workShop 02 - Treinamento Preactor API

Conforme o primeiro workshop a solução do problema será exposta em tópicos, num formato de passo-a-passo, ok?


1º - Criar uma nova classe workshop02;




2º - Copiar e colar o método de ler o arquivo CSV, e altera-lo para atender o layout do novo arquivo CSV ( AtualizaOrdens.csv);

private IList getApontamentosByFileCSV(string pathFile)
        {
            try
            {
                IList apos = new List();

                if (!File.Exists(pathFile))
                {
                    MessageBox.Show("O arquivo de Apontamento não foi encontrado.");
                    return new List();
                }
                StreamReader rd = new StreamReader(pathFile, Encoding.Default);
                try
                {
                    var count = 0;
                    while (!rd.EndOfStream)
                    {
                        count++;
                        var linha = rd.ReadLine();
                        if (count == 1) continue;
                        if (string.IsNullOrEmpty(linha)) continue;

                        var colunas = linha.Split(';');
                        Apontamento iten = new Apontamento();
                        iten.Ordem = colunas[0];
                        iten.Recurso = colunas[1];
                        iten.Status = colunas[2];

                        apos.Add(iten);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    rd.Close();
                }


                return apos;
            }
            catch (Exception ex)
            {
                throw new Exception("Falha ao recuperar os dados do arquivo CSV:"
+ Environment.NewLine + ex.Message);

            }

        }

3º - Criar o método de interface com o Preactor, e fazer a função que atualize os dados da tabela de "Apontamento";


public int AtualizaApontamento(ref PreactorObj preactorComObject, ref object pespComObject, ref string arquivo)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);

            try
            {
                preactor.DisplayStatus("Atualizar Apontamentos", "Lendo arquivo CSV...");
                IList itens = getApontamentosByFileCSV(arquivo);
                preactor.DestroyStatus();
                if (itens.Count == 0)
                {
                    MessageBox.Show("O arquivo está em branco.");
                    return 0;
                }
                preactor.DisplayStatus("Atualizar Apontamentos", "Aplicando Atualizações");
                var total = itens.Count;
                var count = 0;
                preactor.UpdateStatus(count, total);
                foreach (var iten in itens)
                {
                    count++;
                    preactor.UpdateStatus(count, total);
                    //BUSCAR A ORDEM NA TABELA DE APONTAMENTOS
                    var record = preactor.FindMatchingRecord("Apontamento", "Ordem", 0, iten.Ordem);
                    if(record < 0)
                        continue;

                    //SÓ AS ORDENS QUE RECEBERAM UM STATUS CONHECIDO
                    switch (iten.Status)
                    {
                        case "Iniciada":
                            preactor.WriteField("Apontamento", "Recurso", record, iten.Recurso);
                            preactor.WriteField("Apontamento", "Status", record, iten.Status);
                            break;
                        case "Liberada":
                            preactor.WriteField("Apontamento", "Recurso", record, iten.Recurso);
                            preactor.WriteField("Apontamento", "Status", record, iten.Status);
                            break;
                        case "Cancelada":
                            preactor.DeleteRecord("Apontamento", record);
                            break;
                        case "Finalizada":
                            preactor.DeleteRecord("Apontamento", record);
                            break;
                    }
                }
                MessageBox.Show("Seus registros foram atualizados com sucesso!");
                preactor.DestroyStatus();
            }
            catch (Exception ex)
            {
                preactor.DestroyStatus();
                MessageBox.Show("Falha ao atualizar os registros de Apontamento: " + Environment.NewLine + ex.Message);
            }
            return 0;

        }



4º - Criar um Botão para chamar a ação do workshop 02;


segue a codificação do Botão:
; ---------------------------------------------------------------------------
; Edit Apontamentos
; ---------------------------------------------------------------------------
;
EDIT_Apontamentos : PREDIT.EXE,
   "/FMT:Apontamento"   /NDS
   "/ActiveX:Atualizar Dados da Tabela:PESP.EventHandler:RunScriptByName:AtualizaApontamento",
   Edit Apontamento,
   Preactor Database Editor,
   Foreground,
   ALWAYS:{RETURN};

;

5º - Criar a Ação Personalizada, dentro do Preactor;





6º - Testar nossa função;

Nesse workshop eu alterei o local de execução da função, não está dentro do quadro de Gantt conforme o workshop 01, isso para que você posso ver a flexibilidade do Preactor quanto a customizações.

A ação será chamada diretamente da tela e edição da tabela de "Apontamentos", em um menu de nome "Ferramentas".


Alguns comandos utilizados

preactor.DisplayStatus("Atualizar Apontamentos", "Aplicando Atualizações");
Exibe uma janela de Status sendo seu primeiro parâmetro o Título da Janela e o segundo o descritivo do Status;

preactor.UpdateStatus(count, total);
Atualiza o Status Bar que está contido na janela, sendo seu primeiro parâmetro andamento do status (inteiro), e o segundo numero que equivale a 100% do Status Bar, pode ser o número total de elementos de uma lista, ou Array, ou mesmo número de elementos de um tabela de banco de dados que estamos lendo;

preactor.DestroyStatus();
Fecha a janela de Status aberta pelo comando DisplaySTatus. Caso você abra um DisplayStatus e se esqueça de fechar, ao chamar sua ação ela irá manter a janela aberta causando um problema para o Preactor, deixado ele inoperante, e para restaurar o Preactor você precisará matar o processo (ctrl + alt + del) e restartar o Preactor.

Dica, por essa razão sempre que você utilizar o DisplayStatus se lembre de colocar dentro do Catch de sua função um DestroyStatus.


Arquivos do work02 para download.

Dúvidas besaleel@msn.com ou comente aqui.

quarta-feira, 1 de outubro de 2014

WorkShop 01 - Preactor API

Resolução workshop 01:

Irei mostrar a resolução do workshop em tópicos, seguindo uma sequencia lógica de trabalho, ok?

1º - Dentro de meu projeto Olá Mundo, eu criei uma classe contendo exatamente as mesmas propriedades do arquivo CSV:
 public class Apontamento
    {
        private string _ordem;
        private string _recurso;
        private string _status;
        private DateTime _dataDeInicio;
        private DateTime _dataDeFim;

        public string Ordem
        {
            get { return _ordem; }
            set { _ordem = value; }
        }

        public string Recurso
        {
            get { return _recurso; }
            set { _recurso = value; }
        }

        public string Status
        {
            get { return _status; }
            set { _status = value; }
        }

        public DateTime DataDeInicio
        {
            get { return _dataDeInicio; }
            set { _dataDeInicio = value; }
        }

        public DateTime DataDeFim
        {
            get { return _dataDeFim; }
            set { _dataDeFim = value; }
        }

        public override bool Equals(object obj)
        {
            if (obj is DBNull) return false;
            if (obj == null) return false;
            var m = (Apontamento) obj;
            return m.Ordem == _ordem;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
2º Criei uma função para ler os dados do arquivo CSV e passar os valores para uma lista de Apontamentos:
 private IList getApontamentosByFileCSV(string pathFile)
        {
            try
            {
                IList apos = new List();

                if (!File.Exists(pathFile))
                {
                    MessageBox.Show("O arquivo de Apontamento não foi encontrado.");
                    return new List();
                }
                StreamReader rd = new StreamReader(pathFile, Encoding.Default);
                try
                {
                    var count = 0;
                    while (!rd.EndOfStream)
                    {
                        count++;
                        var linha = rd.ReadLine();
                        if (count == 1) continue;
                        if (string.IsNullOrEmpty(linha)) continue;

                        var colunas = linha.Split(';');
                        Apontamento iten = new Apontamento();
                        iten.Ordem = colunas[0];
                        iten.Recurso = colunas[1];
                        iten.Status = colunas[2];
                        iten.DataDeInicio = parseDate(colunas[3]);
                        iten.DataDeFim = parseDate(colunas[4]);

                        apos.Add(iten);
                    }
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                  rd.Close();  
                }


                return apos;
            }
            catch (Exception ex)
            {
                throw new Exception("Falha ao recuperar os dados do arquivo CSV:" + Environment.NewLine + ex.Message);
            }
        }
3º Criei um método que faz a comunicação com o Preactor, recebe a lista de apontamentos baseado no arquivo CSV e grava na tabela do Preactor:
OBS: a diferença entre este novo método e o OláMundo (Run) é um novo parâmetro que foi adicionado a função, "ref string arquivo". Eu achei essa forma mais simples configurar o nome e local onde o arquivo csv se encontra, mas você poderia também ter deixa o caminho e nome do arquivo fixos em seu projeto, ok?


 public int ImportApontamento(ref PreactorObj preactorComObject, ref object pespComObject, ref string arquivo)
        {
            IPreactor preactor = PreactorFactory.CreatePreactorObject(preactorComObject);
            try
            {
                //RECUPERAR OS DADOS DO ARQUIVO CSV
                IList itens = getApontamentosByFileCSV(arquivo);
                if (itens.Count == 0) return 0;

                //LIMPAR TABELA DE APONTAMENTOS
                preactor.Clear("Apontamento");

                preactor.DisplayStatus("Apontamentos","Importando arquivos de apontamentos.");
                var count = itens.Count;
                var i = 0;
                preactor.UpdateStatus(i, count);
                //INSERIR O GRUPO DE REGISTROS
                foreach (var iten in itens)
                {
                    i++;
                    preactor.UpdateStatus(i, count);
                    //CRIAR UM NOVO REGISTRO NA TABELA DE APONTAMENTOS
                    int record = preactor.CreateRecord("Apontamento");

                    //ESCREVER NA TABELA APONTAMENTOS
                    preactor.WriteField("Apontamento", "Ordem", record, iten.Ordem);
                    if (!string.IsNullOrEmpty(iten.Recurso))
                        preactor.WriteField("Apontamento", "Recurso", record, iten.Recurso);
                    if (!string.IsNullOrEmpty(iten.Status))
                        preactor.WriteField("Apontamento", "Status", record, iten.Status);
                    if (iten.DataDeInicio != DateTime.MinValue)
                        preactor.WriteField("Apontamento", "Data de Início", record, iten.DataDeInicio);
                    if (iten.DataDeFim != DateTime.MinValue)
                        preactor.WriteField("Apontamento", "Data de Fim", record, iten.DataDeFim);
                }
                preactor.DestroyStatus();
                //VAMOS SALVAR OS DADOS NA TABELA DO PREACTOR
                preactor.Commit("Apontamento");
                MessageBox.Show("Seus dados foram importados com sucesso!");
            }
            catch (Exception ex)
            {
                preactor.DestroyStatus();
                MessageBox.Show("Falha ao importar os Apontamentos:" + Environment.NewLine + ex.Message);
            }

            return 0;

        }
4º Criei um botão no arquivo de configuração prmdf, já fizemos isso no olá mundo.


5º Cadastrei a ação dentro do Preactor conforme a ação Olá Mundo, acompanhe o passo a passo:

clique em Editar
Clique em "Novo Registro" em seguida "Adicionar->", digite o nome "arquivo" E clique Ok


Vá para o Menu Script de Eventos => Script de Eventos


Clique em "Parameters.."

Clique Sobre o nome "arquivo"


No campo "File Name", adicione o caminho e o nome do arquivo que iremos importar

6º Vamos Testar nossa ação, vá no Visual Studio e aparte a tecla de atalho "F5", e vamos debugar nosso código:



Com isso encerramos nosso primeiro WorkShop, não detalhei as ações pois elas são bem simples, igual uma receita de bolo, basta seguir o passo-a-passo que não tem erro.

Se houver algum dúvida sobre esse workshop me escreva besaleel@msn.com ou faça um comentário aqui no blog que responderei o mais breve possível.

Se preferir faça o download da solução completa do WorkShop 01.