none
Gerador de Relatório RRS feed

  • Pergunta

  • Bom dia,

    estou fazendo uma pequena aplicação (que gerencia o tempo de tarefas e processos, gastos pelos funcionários, para assim saber onde preciso melhor o desempenho da equipe e por ai vai), cheguei em um determinado momento em que estou emitindo relatórios, esses relatórios de acordo com os filtros são exibidos em um DataGridView, até aqui tudo ok!
    Tenho a opção de o usuário escolher entre 7 filtros diferentes, como por exemplo Funcionário, Tarefa, Data de inicio, Data de Termino, Status (em execução, finalizada com atraso...) e por ai vai!

    Porém não tive uma boa ideia de como fazer o select buscando no banco de maneira fácil, digo utilizando um único select e uma única função para tal. Então fiz varios If Else if, verificando quais campos estão preenchidos, se é apenas um filtro, dois... E chamar a função por exemplo RelatórioUmFiltro, RelatórioDoisFiltros, passando por parâmetro a coluna do banco de dados e o texto no quais deve-se pesquisa no banco! Porém como tenho 7 opções de filtros serão muitas combinações possíveis, com tantas verificações para If e Else if a aplicação ficará lenta!

    Poderiam me dar uma dica de como economizar codigo fonte e com isso ganhar desempenho, um amigo falou sobre union, mais não consegui aplicar em meu select pois o relatório busca dados em apenas uma tabela, segue a tabela do BD:

    create table TempoTarefa(
    id_tempo int not null identity (1,1) primary key,
    descricao varchar(150) not null,
    tarefa int not null foreign key references Tarefa (id_tarefa),
    funcionario int not null foreign key references Funcionario (id_funcionario),
    quantidade int not null,
    data_inicial datetime not null,
    data_final datetime,
    tempo_gasto int,
    obs text,
    situacao varchar(50) not null,
    usuario varchar(50) not null
    );

    tempo_gasto estou usando int pois foi solicitado para trabalharmos apenas com minutos, então achei mais fácil converter esse tempo em minutos para gravar! O usuário eu gravo o nome dele pois apenas quem iniciou um gerenciamento de tempo (adm ou Chefe de setor ou o proprio usuario) pode finalizar ou alterar a mesma!

    Segue um trecho dos else if e também do select que estou usando

    else if (cbTarefa.Text != "" && cbFuncionario.Text == "" && cbDepartamento.Text == "" && txtDescricao.Text == "" &&
                    mtxtDataInicial.Text == "  /  /" && mtxtDataFinal.Text == "  /  /" && cbSituacao.Text != "")
                {
                    tipopesquisa1 = "ta.descricao";
                    tipopesquisa2 = "t.situacao";
                    pesquisa1 = cbTarefa.Text.ToString();
                    pesquisa2 = cbSituacao.Text.ToString();
                    com.PesquisaRelatorioDuasCondicoes(dtTempo, tipopesquisa1, tipopesquisa2, pesquisa1, pesquisa2);
                    DefinirCoresGrid(dtTempo);
                    AtualizarLegenda(dtTempo);
                }

    aqui ele é com duas condições, segue o select:

    try
                {
                    if (tipopesquisa2 == "t.data_inicial")
                    {
                        comando = "select t.cod_tempo, t.descricao, ta.descricao as tarefa, f.nome as funcionario, t.quantidade, t.data_inicial,\n" +
                            "t.data_final,t.quantidade/ta.quantidade as estimativa, t.tempo_gasto, t.obs, t.situacao, ta.cod_tarefa as cod_tarefa from TempoTarefa as t\n" +
                            "inner join Tarefa as ta on t.tarefa = ta.cod_tarefa\n" +
                            "inner join Funcionario as f on t.funcionario = f.cod_funcionario\n" +
                            "left join Cargo as c on f.cod_cargo = c.cod_cargo\n" +
                            "left join Departamento as d on c.cod_departamento = d.cod_departamento\n" +
                            "where " + tipopesquisa1 + " like '" + pesquisa1 + "%' and " + tipopesquisa2 + ">= '" + pesquisa2 + "'\n" +
                            "order by t.descricao";
                    }
                    else if (tipopesquisa2 == "t.data_final" && tipopesquisa1 != "t.data_inicial")
                    {
                        comando = "select t.cod_tempo, t.descricao, ta.descricao as tarefa, f.nome as funcionario, t.quantidade, t.data_inicial,\n" +
                            "t.data_final,t.quantidade/ta.quantidade as estimativa, t.tempo_gasto, t.obs, t.situacao, ta.cod_tarefa as cod_tarefa from TempoTarefa as t\n" +
                            "inner join Tarefa as ta on t.tarefa = ta.cod_tarefa\n" +
                            "inner join Funcionario as f on t.funcionario = f.cod_funcionario\n" +
                            "left join Cargo as c on f.cod_cargo = c.cod_cargo\n" +
                            "left join Departamento as d on c.cod_departamento = d.cod_departamento\n" +
                             "where " + tipopesquisa1 + " like '" + pesquisa1 + "%' and " + tipopesquisa2 + "<= '" + pesquisa2 + " 23:59:59'\n" +
                            "order by t.descricao";
                    }
                    else if (tipopesquisa1 == "t.data_inicial" && tipopesquisa2 == "t.data_final")
                    {
                        comando = "select t.cod_tempo, t.descricao, ta.descricao as tarefa, f.nome as funcionario, t.quantidade, t.data_inicial,\n" +
                            "t.data_final,t.quantidade/ta.quantidade as estimativa, t.tempo_gasto, t.obs, t.situacao, ta.cod_tarefa as cod_tarefa from TempoTarefa as t\n" +
                            "inner join Tarefa as ta on t.tarefa = ta.cod_tarefa\n" +
                            "inner join Funcionario as f on t.funcionario = f.cod_funcionario\n" +
                            "left join Cargo as c on f.cod_cargo = c.cod_cargo\n" +
                            "left join Departamento as d on c.cod_departamento = d.cod_departamento\n" +
                             "where " + tipopesquisa1 + " >= '" + pesquisa1 + "' and " + tipopesquisa2 + " <= '" + pesquisa2 + " 23:59:59'\n" +
                            "order by t.descricao";
                    }
    
                    else
                    {
                        comando = "select t.cod_tempo, t.descricao, ta.descricao as tarefa, f.nome as funcionario, t.quantidade, t.data_inicial,\n" +
                        "t.data_final,t.quantidade/ta.quantidade as estimativa, t.tempo_gasto, t.obs, t.situacao, ta.cod_tarefa as cod_tarefa from TempoTarefa as t\n" +
                        "inner join Tarefa as ta on t.tarefa = ta.cod_tarefa\n" +
                        "inner join Funcionario as f on t.funcionario = f.cod_funcionario\n" +
                        "left join Cargo as c on f.cod_cargo = c.cod_cargo\n" +
                        "left join Departamento as d on c.cod_departamento = d.cod_departamento\n" +
                        "where " + tipopesquisa1 + " like '" + pesquisa1 + "%' and " + tipopesquisa2 + " like '" + pesquisa2 + "%'\n" +
                        "order by t.descricao";
                    }
                    SqlCommand Cnd = new SqlCommand(comando, AbriConexao());
                    SqlDataReader dados = Cnd.ExecuteReader();
                    tempo.Rows.Clear();
                    while (dados.Read())
                    {
    
                        tempo.Rows.Add(dados["cod_tempo"].ToString(), dados["descricao"], dados["tarefa"], dados["funcionario"],
                                       quanttotal, dados["data_inicial"], dados["data_final"], estimativa, tempogasto, dados["obs"], dados["situacao"]);
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("ERRO AO PREENCHER O GRID: " + e.Message);
                }
                finally
                {
                    FechaConexao();
                }

    terça-feira, 26 de novembro de 2019 12:28

Respostas

Todas as Respostas

  • Deleted
    terça-feira, 26 de novembro de 2019 13:07
  • estou começando a entender!

    A minha dúvida é referente ao SQL, pois eu apenas mando o comando do C# para o SQL, da forma que estou fazendo tenho uma função para um, duas, três filtros, e na hora que clica no botão pesquisar ele verifica quais campos estão preenchidos para mandar por parametro nessa função e preencher a coluna no comando sql na parte do where, pode ver que no meu comando tem lá tipopesquisa1, 2, ai eu atribuo o valor da coluna nessa variável string, e o comando é executado de forma correta!

    Mais como são várias condições, o programa começa a ficar um lento para carregar o grid, pois faz varias condições comparações entre if, else if e else(se nada tiver preenchido ele preenche por completo), assim fica muito grande, gostaria de um comando em sql apenas para ser executado independente de quais filtro o usuario faça, vou pesquisar mais sobre a forma que você comentou acima, acredito que ela iria me atender, assim eu teria apenas uma função o que me ajudaria e muito.
    terça-feira, 26 de novembro de 2019 14:01
  • José, após sua dica e dar uma olhada no artigo, fiz o seguinte código:

    CREATE PROCEDURE emite_relatorio 
       @tarefa varchar(50),
       @funcionario varchar(50),
       @departamento int,
       @Descricao varchar(50),
       @data_inicial datetime,
       @data_final datetime,
       @situcao varchar(20)
    as
    begin
    
    select t.cod_tempo, t.descricao, ta.descricao as tarefa, f.nome as funcionario, t.quantidade, t.data_inicial,
    t.data_final,t.quantidade/ta.quantidade as estimativa, t.tempo_gasto, t.obs, t.situacao, ta.cod_tarefa as cod_tarefa from TempoTarefa as t
    inner join Tarefa as ta on t.tarefa = ta.cod_tarefa
    inner join Funcionario as f on t.funcionario = f.cod_funcionario
    left join Cargo as c on f.cod_cargo = c.cod_cargo
    left join Departamento as d on c.cod_departamento = d.cod_departamento
      where (@tarefa is null or ta.descricao = @tarefa)
            and (@funcionario is null or f.nome = @funcionario )
            and (@departamento is null or d.descricao = @departamento )
    		and (@Descricao is null or t.descricao like @Descricao + '%')
    		and (@data_inicial is null or t.data_inicial >= @data_inicial )
    		and (@data_final is null or t.data_final <= @data_final + ' 23;59:59' )
    		and (@situcao is null or t.situacao = @situcao ); 
    end;	
    
    EXEC emite_relatorio null, null, null, 'teste', null, null, null --esse será o comando que o C# vai mandar!


    • Editado Lucas Lott terça-feira, 26 de novembro de 2019 14:50 alteração no código fonte
    terça-feira, 26 de novembro de 2019 14:42
  • Deleted
    • Sugerido como Resposta IgorFKModerator quinta-feira, 28 de novembro de 2019 14:24
    • Marcado como Resposta IgorFKModerator quinta-feira, 26 de dezembro de 2019 16:51
    terça-feira, 26 de novembro de 2019 15:12
  • Sobre os dois left join, daria para usar o inner join normalmente, pois todo funcionário tem um cargo e todo cargo tem um departamento, então o inner funcionaria normalmente, alterei para inner join agora!
    Sobre a substituição que você sugeriu, também fiz essa alteração ficou muito melhor, pois não preciso me preocupar com o horário, a principio quando fiz os comando, ele não puxava a data de hoje (como data final) ela não aparecia no relatório, então vi que era por conta disso, um campo datetime, onde pega o horario também, e o como o dia se inicia as 00 e não estava mandando a hora apenas a data ele por padrão ficava com a 00, fiz essa concatenação para pegar o dia todo! Sua sugestão de alteração ajudou a deixar com um código muito mais elabora!

    Obrigado
    terça-feira, 26 de novembro de 2019 15:32