Gerar um alerta em C#

39 respostas
C

Olá pessoal, sou novo no forum e por este motivo se estiver fora do padrão, favor me orientar que irei refazer o tópico. Galera, é o seguinte: preciso criar uma aplicação de “vencimentos de boleto”.
O método de inserir, listar e tudo mais, eu consigo desenvolver, o que eu não estou conseguindo é: eu tenho um boleto que vence no dia 28/05/2016 mas eu quero que gere um alerta 10 dias antes que ele vença. Preciso ter um controle de boletos aqui na minha empresa, vocês poderiam me ajudar?

Vou começar a desenvolver isso em C# e com banco de dados SQL.

Pessoal, agradeço a boa vontade de vocês! Agradeço desde já.

39 Respostas

P

Você pode criar um Windows Service pra ficar monitorando os boletos. Quando o boleto estiver pra vencer, ele envia
um e-mail automático informando…

W

Boa tarde, eu tenho alguns sistemas de monitoramento em C# onde jogo o sistema no system tray. Se estiver utilizando Windows Forms, coloque um timer e coloque algumas condições de ativação por exemplo a cada duas horas, jogue seu sistema no system tray SystemTray e dispare os avisos via email.

C

Galera, obrigado pelas dicas e vou sim ler elas pois achei bem interessante.
A minha maior dúvida é, como traduzo essa lógica para o C#?

Exemplo: Tenho um boleto que vence no dia 30/05/2016.
Eu quero que 10 dias antes me gera um alerta (pode ser pelo System Tray por exemplo).
Essa é minha maior dúvida.

Poderiam me ajudar neste sentido?
Agradeço mais uma vez esses links, vão me ajudar demais pessoal.

C

Alguém pra me ajudar? :confused:

L

Bom Dia Cristal_Glass!

Crie um formulário em branco e remova a borda do mesmo e coloque para iniciar minimizado.
Feito isto, adicione os seguintes componentes:
1 timer
1 notifyIcon e
1 contextMenuStrip

após adicionar os componentes acima, crie quatro variáveis globais com o seguinte nomes e tipo de prefência:
três variáveis do tipo Int
Int32 segundos, minutos, milisegundos;
e uma do tipo DateTime
DateTime dataHora;

Ainda no formulário, no evento Resize

private void Form1_Resize(object sender, EventArgs e) { //verifica se o formulario esta minimizado if (this.WindowState == FormWindowState.Minimized) { //esconde o formulário this.Hide(); //deixa o aviso visivel notifyIcon1.Visible = true; } }

agora no componente contextMenuStrip

adicione um menu no mesmo com o nome desejado e dê duplo clique no menu para ativar um evento, no meu caso, ficou assim:
private void abrirToolStripMenuItem_Click(object sender, EventArgs e) { //para abrir o formulário form1 mesmo, no seu caso, para você seria a tela de login ou o principal, ou outra tela mesmo new Form1().Show(); }

agora no componente notifyIcon

no notifyIcon, vá na propriedade ContextMenuStript e selecione o contextMenuStrip criado anteriormente.

vá na propriedade BallonTipIcon e selecione a que melhor se adequar (Info,Warning ou Error).
e na propriedade Icone do notify, coloque um icone desejado.
vá em Eventos do notifyIcon e dê duplo click sobre o evento MouseDoubleClick

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) { //irá exibir o formulário (neste caso o form1) em seu caso, pode ser a tela de login ou o principal, não sei como está a aplicação ai... this.Show(); //o formulario irá iniciar maximizado this.WindowState = FormWindowState.Maximized; //oculta o aviso notifyIcon1.Visible = false; }

Agora no componente timer, vá na propriedade enable e altere para true e depois em evento, dê duplo click sobre o evento Tick ou se preferir, dê duplo click sobre o timer.

No evento Tick do timer, ficou assim:

`private void timer1_Tick(object sender, EventArgs e)

{

//data e a hora do sistema. é possivel pegar a data do servidor para evitar possiveis conflitos,

//pois a data da maquina local, pode estar alterada e tals

//para buscar a data do sistema, faça uma consulta do tipo:

//select GETDATE() mais detalhes no tópico da msdn, link abaixo

dataHora = DateTime.Now;

//variavel recebe o minuto do sistema

minutos = dataHora.Minute;

//variavel recebe o segundo do sistema

segundos = dataHora.Second;

//variavel recebe o milisegundo do sistema

milisegundos = dataHora.Millisecond;
//Para ficar melhor ainda, e mostrar para o usuário, quantos boletos tem para vencer, faça uma consulta 
        //do tipo Count para contar quantos boletos tem para vencer dentro de 10 dias e é claro, para não ficar mostrando a mensagem 
        //toda vez que atender o critério mesmo não tendo boleto a vencer!.
        //a consulta abaixo, utilizei o BETWEEN, entre datas, para comparar datas... neste caso a atual e a daqui a dez dias...
        //Select COUNT(*) fROM BoletoVencer Where DataVencimento BETWEEN @DataAtual AND @DataDezMais
        int qtdVencer = Convert.ToInt32(this.boletoVencerTableAdapter.ContarBoletoVencer(dataHora.Date,dataHora.AddDays(+10)));
        //verifica se tem boletos a vencer
        if (qtdVencer > 0)
        {
            if (minutos == 57 && segundos == 10 && milisegundos >= 600)
            {
                //exibe o icone
                notifyIcon1.Visible = true;
                //texto a ser exibido da notificação
                notifyIcon1.Text = "ATENÇÃO";
                //titulo da mensagem
                notifyIcon1.BalloonTipTitle = "Boletos a Vencer!";
                //texto da mensagem
                if (qtdVencer > 1)
                {
                    notifyIcon1.BalloonTipText = "Possui " + qtdVencer.ToString() + "  boletos à vencer dentro de Dez Dias";
                }
                else
                {
                    notifyIcon1.BalloonTipText = "Possui " + qtdVencer.ToString() + " boleto à vencer dentro de Dez Dias";
                }
                
                //o tempo em que ficara sendo exibido
                notifyIcon1.ShowBalloonTip(1000);
            }
        }
    }`

GetDate

:slight_smile:

C

Bem complicado a parte do select ali, mas vou chegar em casa e tentar fazer.

Obrigado pela ajuda!

L

Qual parte do select é complicado ?
que tipo de DataSet você utiliza ? DataSet Tipado ?

C

Eu crio o banco de dados no SQL SERVER.
Migro ele pro Visual Studio por meio do SQLCLIENT, coloco a instância, meu usuário do do SQL SERVER e busco o meu banco de dados e dou OK.
Ele fica visivel pra mim pelo Server Explorer logo após esse processo.

Eu quero que 10 dias antes de qualquer boleto, me gera um alerta e que seja sinalizado de tal forma no sistema, seja por meio de DataGridView, por meio de algo… Depois eu com mais tempo, implemento coisas mais complexas.

L

Foi alterado apenas o código do evento do timer, portanto os outros eventos permanecem do mesmo modo que citei anteriormente…
e agora a consulta apenas irá contar os boletos que vencerão dez dias a partir da data atual pois no código anterior, contaria tudo dentro do intervalo de dez dias…

Fiz adaptando ao método de conexão que você utiliza e ficou assim segundo oque entendi sobre oque você quer:

`

private void timer1_Tick(object sender, EventArgs e)

{

//string de conexão com o banco

SqlConnection conn = new SqlConnection(@“Data Source=.\sqlexpress;Initial Catalog=Boleto;User ID=sa; Password=SuaSenha”);

//abre a conexão com o banco

conn.Open();
//consulta para buscar a data do servidor, pois a do sistema pode estar adiantada ou atrasada...
        SqlCommand cmdDataServ = new SqlCommand("Select GETDATE()",conn);
        //variavel do tipo data, recebe a data do servidor...
        DateTime DataServidor = Convert.ToDateTime(cmdDataServ.ExecuteScalar());            
        // a data é convertida para 'String' para pegar apenas a data, senão ele trárá com a hora e na pesquisa e
        //não atendera o criterio e sempre trará 0 no resultado da contagem mesmo se tiver boletos a vencer na data...
        string novadata = DataServidor.AddDays(+10).ToShortDateString();

        //variaveis recebem os respectivos valores do servidor
        dataHora = DataServidor;
        //variavel recebe o minuto do sistema
        minutos = dataHora.Minute;
        //variavel recebe o segundo do sistema
        segundos = dataHora.Second;
        //variavel recebe o milisegundo do sistema
        milisegundos = dataHora.Millisecond;

        //Para ficar melhor ainda, e mostrar para o usuário, quantos boletos tem para vencer, faça uma consulta 
        //do tipo Count para contar quantos boletos tem para vencer dentro de 10 dias e é claro, para não ficar mostrando a mensagem 
        //toda vez que atender o critério mesmo não tendo boleto a vencer!.
        SqlCommand cmd = new SqlCommand("Select COUNT(*) fROM BoletoVencer Where DataVencimento  =  @DataFuturo",conn);
        cmd.Parameters.Add(new SqlParameter("@DataFuturo", novadata));
        //executa a consulta
        cmd.ExecuteNonQuery();
        //variavel recebe o resultado da consulta
        int qtdVencer = Convert.ToInt32(cmd.ExecuteScalar());

        //fecha a conexão com o banco
        conn.Close();
        
        //verifica se tem boletos a vencer
        if (qtdVencer > 0)
        {
            if (minutos == 57 && segundos == 10 && milisegundos >= 600)
            {
                //exibe o icone
                notifyIcon1.Visible = true;
                //texto a ser exibido da notificação
                notifyIcon1.Text = "ATENÇÃO";
                //titulo da mensagem
                notifyIcon1.BalloonTipTitle = "Boletos a Vencer!";
                //texto da mensagem
                if (qtdVencer > 1)
                {
                    notifyIcon1.BalloonTipText = "Possui " + qtdVencer.ToString() + "  boletos à vencer dentro de Dez Dias";
                }
                else
                {
                    notifyIcon1.BalloonTipText = "Possui " + qtdVencer.ToString() + " boleto à vencer dentro de Dez Dias";
                }
                
                //o tempo em que ficara sendo exibido
                notifyIcon1.ShowBalloonTip(1000);
            }
        }
    }`
C

Simplesmente você é DEMAIS! hahahaha
Lucas, consegui gerar o alerta de quando eu clicar no botão “Verificar Boletos” ele me alerta “Você tem um boleto para pagar”.
OK! Mas eu gerei um DataGridView para listar todos boletos cadastrados.
Eu precisaria que me mostrasse em label ou em cores vermelhas quais são esses boletos, poderia me ajudar?

O foda que ficou meio bagunçado meu sistema kkkk, pois eu tava fazendo em orientação a objetos e agora com seu ultimo post, eu inclui isso tudo no meu botão de “Verificar Boletos” mas isso eu dou uma quebrada de cabeça e tento organizar…

C
private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=CristalGlass;Persist Security Info=True;User ID=sa;Password=123456");
            con.Open();
            SqlCommand cmd = new SqlCommand("SELECT GETDATE()", con);
            DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar());
            string novadata = DataServidor.AddDays(+10).ToShortDateString();



            dataHora = DataServidor;
            minutos = dataHora.Minute;
            segundos = dataHora.Second;
            milisegundos = dataHora.Millisecond;

            label4.Text = novadata;

            SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data  =  @dataFuturo", con);
            command.Parameters.AddWithValue("@dataFuturo", novadata);
            command.ExecuteNonQuery();

            int qtdVencer = Convert.ToInt32(command.ExecuteScalar());
            con.Close();

            if (qtdVencer > 0)
            {
                MessageBox.Show("Tem "+qtdVencer+" boletos pra vencer!");
                Form1_Load(e,e);
            }
            else
            {
                MessageBox.Show("Não tem boletos para vencer!");
            }
        }
        catch (Exception ex)
        {
            throw new Exception (ex.Message);
        }
    }

Galera, até então tá assim… Consigo ver que tem “x” boletos que está pra vencer mas encontrei um “erro”. Ele me mostra quantos boletos tem pra vencer SOMENTE na condição: data + 10 dias.
Eu queria que ele me mostrasse o número x de boletos que estão pra vencer em 10 dias, seria tipo uma “varredura” e me mostrar quantos estão pra vencer. Poderiam me ajudar?

L

Aah, você quer que ele te diga quantos boletos tem para vencer de hoje até a data daqui há dez dias.
é simples, é só colocar a consulta com o BETWEEN que ficará assim:
Select COUNT(*) fROM BoletoVencer Where DataVencimento BETWEEN @dataServidor AND @dataFuturo
no lugar do "Select COUNT(*) fROM BoletoVencer Where DataVencimento = @DataFuturo"

enquanto a questão de pintar, tentarei fazer aqui e te informarei…

em questão ao botão, fica meio desproporcional o usuário ficar clicando rsrs
não deu certo fazer pelo passo a passo que te disse, criando um formulário adicionando os componentes e etc… ?

C

Lucas, vou implementar do jeito que você me mandou… Eu fiz esse botão porque veio na cabeça só pra ver se tá dando certo e deu.
Cara, você tá sendo demais kkk. Preciso voltar a estudar, porque tá foda a lógica viu, puts :s.

Eu vou fazer os testes aqui e te falo amigão. Tô no trabalho agora mas vou acessar meu pc daqui e vou puxar os arquivos e fazer essas alterações e te falo.
Obrigadão Lucas!

C

Lucas, nessa linha:

Select COUNT(*) fROM BoletoVencer Where DataVencimento BETWEEN @dataServidor AND @dataFuturo

O dataServidor eu declaro por qual variável?

a DataFuturo é a novadata.
Mas e a DataServidor?

C
private void button1_Click(object sender, EventArgs e)

{

try

{

SqlConnection con = new SqlConnection(@“Data Source=.\SQLEXPRESS;Initial Catalog=CristalGlass;Persist Security Info=True;User ID=sa;Password=123456”);

con.Open();

SqlCommand cmd = new SqlCommand(“SELECT GETDATE()”, con);

DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar());

string novadata = DataServidor.AddDays(+10).ToShortDateString();
dataHora = DataServidor;
            minutos = dataHora.Minute;
            segundos = dataHora.Second;
            milisegundos = dataHora.Millisecond;

            //TESTE PRA VER QUAIS DATAS  PEGANDO.
            //label4.Text = novadata;
            //label5.Text = Convert.ToString(dataHora);

            // sql anterior - SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data  =  @dataFuturo", con);
            SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data BETWEEN @DataServidor AND @dataFuturo", con);

            command.Parameters.AddWithValue("@dataFuturo", novadata);
            command.Parameters.AddWithValue("@DataServidor", dataHora);
            command.ExecuteNonQuery();

            int qtdVencer = Convert.ToInt32(command.ExecuteScalar());
            con.Close();

            if (qtdVencer > 0)
            {
                MessageBox.Show("Tem "+qtdVencer+" boletos pra vencer!");
                Form1_Load(e,e);
            }
            else
            {
                MessageBox.Show("Não tem boletos para vencer!");
            }
        }

Ele tá pegando agora, tudo que tem entre a data cadastrada no sistema e o prazo de 10 dias.
Tá correto no código?

L

Blz hehe!
A Data do Servidor é a variavel que é declarada lá em cima no código, lembra ?
que traz a data do servidor onde está instalado o banco…
SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=CristalGlass;Persist Security Info=True;User ID=sa;Password=123456"); con.Open(); DateTime DataServidor = Convert.ToDateTime(cmdDataServ.ExecuteScalar()); // a data é convertida para 'String' para pegar apenas a data, senão ele trárá com a hora e na pesquisa e //não atendera o criterio e sempre trará 0 no resultado da contagem mesmo se tiver boletos a vencer na data... string novadata = DataServidor.AddDays(+10).ToShortDateString();
que no caso, você informa a variável DataServidor convertendo a mesma para ToShortDateString();
ou se preferir, crie uma nova variável do tipo ‘String’ recebendo a data do servidor.
Exemplo:
string DataServ = DataServidor.ToShortDateString();
e você informa a DataServ como parâmetro da data do servidor…

C

Entendi Lucas! Verifica se está OK:

private void button1_Click(object sender, EventArgs e)

{

try

{

SqlConnection con = new SqlConnection(@“Data Source=.\SQLEXPRESS;Initial Catalog=CristalGlass;Persist Security Info=True;User ID=sa;Password=123456”);

con.Open();

SqlCommand cmd = new SqlCommand(“SELECT GETDATE()”, con);

DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar());

string novadata = DataServidor.AddDays(+10).ToShortDateString();
dataHora = DataServidor;
            minutos = dataHora.Minute;
            segundos = dataHora.Second;
            milisegundos = dataHora.Millisecond;

            //TESTE PRA VER QUAIS DATAS  PEGANDO.
            //label4.Text = novadata;
            //label5.Text = Convert.ToString(dataHora);

            // sql anterior - SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data  =  @dataFuturo", con);
            SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data BETWEEN @DataServidor AND @dataFuturo", con);

            command.Parameters.AddWithValue("@dataFuturo", novadata);
            command.Parameters.AddWithValue("@DataServidor", dataHora);
            command.ExecuteNonQuery();

            int qtdVencer = Convert.ToInt32(command.ExecuteScalar());
            con.Close();

            if (qtdVencer > 0)
            {
                MessageBox.Show("Tem "+qtdVencer+" boletos pra vencer!");
                Form1_Load(e,e);
            }
            else
            {
                MessageBox.Show("Não tem boletos para vencer!");
            }
        }
        catch (Exception ex)
        {
            throw new Exception (ex.Message);
        }
    }
L

Funcionando Blz, só tem um porém
quando você passa o parâmetro da data do servidor, converta para ToShortDateString()
pois se houver algum boleto com a data de vencimento atual (que é a do servidor) ele não irá
contar porque está indo com a data com hora do jeito atual…
ficará assim convertendo ele para ToShortDateString() :
command.Parameters.AddWithValue("@DataServidor", dataHora.ToShortDateString());
assim, irá apenas a data e te trará boletos com a data atual caso tenha…

:confused: Uma dúvida … você remove desta tabela quando o boleto é “pago” ou altera algum Status ?
porque se alterar o status, deve alterar a sua consulta para buscar apenas quando o status não for pago…
exemplo:
SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data BETWEEN @DataServidor AND @dataFuturo AND Status = 'Pago' ", con);
que dai trará apenas os não pagos

C

Então Lucas, implementei mais uma coluna no meu banco de dados com o nome de Status e agora eu alimento o boleto que está pendente e boleto que já foi pago. Depois vou criar um menu e nesse novo form, vou fazer um select somente dos que já foi pago, aí fica mais organizado.

Valeu pelo toque do .ToShortDateString(); vou fazer isso sim…

Cara, me ajuda num negócio agora (tô te enchendo demais) kkk.

Todo esse código que agente fez:

private void button1_Click(object sender, EventArgs e)

{

try

{

SqlConnection con = new SqlConnection(@“Data Source=.\SQLEXPRESS;Initial Catalog=CristalGlass;Persist Security Info=True;User ID=sa;Password=123456”);

con.Open();

SqlCommand cmd = new SqlCommand(“SELECT GETDATE()”, con);

DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar());

string novadata = DataServidor.AddDays(+10).ToShortDateString();
dataHora = DataServidor;
        minutos = dataHora.Minute;
        segundos = dataHora.Second;
        milisegundos = dataHora.Millisecond;

        //TESTE PRA VER QUAIS DATAS  PEGANDO.
        //label4.Text = novadata;
        //label5.Text = Convert.ToString(dataHora);

        // sql anterior - SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data  =  @dataFuturo", con);
        SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data BETWEEN @DataServidor AND @dataFuturo", con);

        command.Parameters.AddWithValue("@dataFuturo", novadata);
        command.Parameters.AddWithValue("@DataServidor", dataHora);
        command.ExecuteNonQuery();

        int qtdVencer = Convert.ToInt32(command.ExecuteScalar());
        con.Close();

        if (qtdVencer > 0)
        {
            MessageBox.Show("Tem "+qtdVencer+" boletos pra vencer!");
            Form1_Load(e,e);
        }
        else
        {
            MessageBox.Show("Não tem boletos para vencer!");
        }
    }
    catch (Exception ex)
    {
        throw new Exception (ex.Message);
    }
}

Eu gostaria de implementar ele na classe que tenho só de Cadastro, Atualizar, Deletar e etc…
Como eu me organizo nesse sentido? Poderia dar uma “clareada na minha cabeça”?

L

É bem simples, você já tem uma classe criada correto ?:slight_smile:
então, na classe criada, crie as seguintes variáveis globais:

public int qtdVencer;//será utilizada também na tela em que chamar o método da classe... Int32 segundos, minutos, milisegundos; DateTime dataHora;

não se esqueça de utilizar a refência using System.Data.SqlClient; na classe para poder utilizar os comandos de conexão…

agora, crie um método dentro da classe com um nome desejado.
criei um aqui com o nome VerificarBoletosVencer
e ficou assim:

public void VerificarBoletosVencer() { try { SqlConnection con = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=CristalGlass;Persist Security Info=True;User ID=sa;Password=123456"); con.Open(); SqlCommand cmd = new SqlCommand("SELECT GETDATE()", con); DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar()); string novadata = DataServidor.AddDays(+10).ToShortDateString();

dataHora = DataServidor; minutos = dataHora.Minute; segundos = dataHora.Second; milisegundos = dataHora.Millisecond;
//TESTE PRA VER QUAIS DATAS TÁ PEGANDO. //label4.Text = novadata; //label5.Text = Convert.ToString(dataHora);
// sql anterior - SqlCommand command = new SqlCommand("Select COUNT(*) fROM Boletos Where data = @dataFuturo", con); SqlCommand command = new SqlCommand("Select COUNT(*) fROM BoletoVencer Where DataVencimento BETWEEN @DataServidor AND @dataFuturo", con);

command.Parameters.AddWithValue("@dataFuturo", novadata); command.Parameters.AddWithValue("@DataServidor", dataHora.ToShortDateString()); command.ExecuteNonQuery();

qtdVencer = Convert.ToInt32(command.ExecuteScalar()); con.Close(); } catch (Exception ex) { throw new Exception(ex.Message); } }

agora, na tela ( no evento Click de um botão por exemplo) em que você for querer executar o código para saber se tem ou não boletos vencidos, instancie a classe criada e chame o método
Class1 classe = new Class1(); classe.VerificarBoletosVencer();
e logo após, chame a variável qtdVencer da classe em um if, ficando assim:
if (classe.qtdVencer > 0) { MessageBox.Show("Tem " + classe.qtdVencer + " boletos pra vencer!"); Form1_Load(e, e); } else { MessageBox.Show("Não tem boletos para vencer!"); }

C

Eu tinha migrado até o int qtdVencer … na minha classe de Dados, no evento do Click que fiquei perdido…
Vou implementar dessa forma agora.
Lucas, você tá sendo demais cara! Eu pensei no sistema pra me ajudar aqui na empresa e você criou ele pra mim kk :confused: desculpa aí pelas burrices… Realmente preciso estudar MUITO e MUITO C#, não posso parar… :confused:

Obrigado demais, viu cara? Um grande abraço pra você.

C

Lucas, fiz todas as mudanças, mas olha essa imagem, tem algo errado:

Ação do <strong>Botão Verifica Boletos</strong>:

private void button1_Click(object sender, EventArgs e)

{

try

{

Dados dds = new Dados();

dds.VerificaBoleto();

label4.Text = Convert.ToString(dds.dataHora);

label5.Text = Convert.ToString(dds.novadata);

if (dds.qtdVencer > 0)

{

MessageBox.Show(“Tem " + dds.qtdVencer + " boletos para vencer!”);

}

else

{

MessageBox.Show(“Não  boletos que está pra vencer no prazo de 10 dias!”);

}

}

catch (Exception ex)

{

throw new Exception (ex.Message);

}

}
<strong>Ação da minha classe que contém o método VerificaBoleto:</strong>

public void VerificaBoleto()

{

try

{

AbrirConexao();

cmd = new SqlCommand(SELECT GETDATE(), con);

DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar());

novadata = DataServidor.AddDays(+10).ToShortDateString();
dataHora = DataServidor;
            minutos = dataHora.Minute;
            segundos = dataHora.Second;
            milisegundos = dataHora.Millisecond;

            cmd = new SqlCommand("Select COUNT(*) fROM Boletos Where data BETWEEN @DataServidor AND @dataFuturo", con);

            cmd.Parameters.AddWithValue("@dataFuturo", novadata);
            cmd.Parameters.AddWithValue("@DataServidor", dataHora);
            cmd.ExecuteNonQuery();

            qtdVencer = Convert.ToInt32(cmd.ExecuteScalar());
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
        finally
        {
            FecharConexao();
        }

O que tem de errado? ‘-’

C

E se eu coloco esta linha:

cmd.Parameters.AddWithValue("@DataServidor",dataHora.ToShortDateString());

Me dá o retorno: Não há boletos que está pra vencer no prazo de 10 dias!

C

Lucão e galera,

olha que coisa doida.

O primeiro label pega a data atual (variável dataServidor)
O segundo label faz label atual + 10 dias, que gera a novaData.
O terceiro label é uma linha de código que implementei pra ver se o que realmente quero tá acontecendo, no mais, tá sim, pois ele tá pegando a diferença da data atual e a dataFuturo que me dá 9 dias (o correto seria 10, me ajudem também).

Só que quando eu clico em verificar boletos, ele encontra somente 4 boletos.

que é o que tem a data 01/06/2016, 02/06/2016, 03/06/2016 e 04/06/2016, o resto também era pra ele contar pra mim…

Tem algo errado mas não tô conseguindo descobrir…

C

UP! Alguém? :frowning:

C

Ahá! Encontrei o problema.
No meu banco de dados, a minha coluna de data estava com o tipo de dados STRING. Alterei para Date e funcionou.
Agora pega desde a data atual até a dataFuturo.

Sensacional! :slight_smile:

C

Galera ou Lucas,

preciso de fazer um teste pra vê se vai me aparecer o balãozinho ao lado do relógio me avisando que tem boletos pendentes invés de clicar no botão verificar.
Mas quero fazer um teste de 10 segundos. Na propriedade Timer, preciso alterar o Interval?

No meu código, deve ficar assim?

if (dds.minutos == 00 && dds.segundos == 10 && dds.milisegundos == 00)

Me ajudem aí, por favor.

C

Resolvido os problemas! Só está confuso o meu evento de Timer.
Não sei qual valor colocar no Interval da propriedade Timer.
E não sei como faço a linha de código referente aos segundos que quero que esse alerta seja emitido (segundos por ser teste).

C

UP UP. Alguém?

L

Opa…
Então, a questão do tempo de disparo do alerta, é você quem decide, se quiser que ele fique de segundos em segundos, apenas deixe assim:

if (segundos == 10 && milisegundos >= 800)
então a cada 1 minuto ele irá disparar o alerta.

ou se for de hora em hora, deixe como estava antes…

mas de minuto em minuto o sistema notificando o usuário, você não acha que ficaria frustante para o usuário não ?

obs: não deixe o milissegundo igual a zero, se não ele não irá te alertar, pois por o milissegundo
ser rápido demais, é provável que quando ele for verificar, já tenha passado do valor 0 e
nunca vai te alertar por sempre ter passado do valor especificado…
a melhor maneira que encontrei, foi deixando ele para comparar se é maior ou igual a 800

para teste, altere apenas o valor do segundo ou do minuto se for deixar, para testar mesmo…
por exemplo, se for do minuto, sempre coloque 1 a mais do atual e mande rodar a aplicação…

então, em relação ao valor do intervalo do timer, ele por padrão vem 100, mas é bem simples a
lógica, quando maior for o valor do intervalo, maior ficará o tempo que ele irá disparar o evento e menor, irá disparar mais rápido…

Você usa o Interval propriedade para determinar a freqüência com que o Elapsed evento é disparado.Porque o Timer classe depende do relógio do sistema, ele tem a mesma resolução do relógio do sistema.Isso significa que o Elapsed evento será acionado em um intervalo definido pela resolução do relógio do sistema se o Interval propriedade for menor que a resolução do relógio do sistema.
Timer.Interval Propriedade

C

Opa Lucas!

O motivo de ser em 1 em 1 minuto é só para teste mesmo, pra ver se está sendo feito o que foi pedido.
Caso for em 1 em 1 hora posso colocar o Interval da propriedade Timer em 100 e substituir por este trecho: if (minutos == 57 && segundos == 10 && milisegundos >= 600)

Correto?

L

Correto, para disparar de hora em hora, é esta linha de código ai mesmo.
o Interval do timer é apenas para dizer o tempo em que ele irá demorar para disparar o evento…
por exemplo, com o interval com o valor de 100 segundos, ele demora aproximadamente 15 milissegundos para disparar o evento segundo o conteúdo do link postado anteriormente.
Deixe o intervalo com 100 mesmo, já que vem por padrão…

C

OK OK Lucas!
Vou fazer o teste e logo mais retorno aqui. Obrigadão cara!

Me explica uma coisa, porque não é simples assim? Se eu quero que a cada 15 segundos, então: if(dds.segundos == 15){

//lógica

}

?

Não consigo entender esses números de milisegundos e segundos…
Por exemplo, pra emitir o alerta a cada 1 hora: if (minutos == 57 && segundos == 10 && milisegundos >= 600)

No meu ponto de vista, ele iria disparar a cada 57 minutos, 10 segundos e 6 milisegundos.
Mas estou errado, né? Porque?

L

Sim, o seu ponto de vista de acordo com a condição da linha de código está correto, disparando de hora em hora…
if (minutos == 57 && segundos == 10 && milissegundos >= 600)

Então, se você tirar o milissegundos, ele irá ficar disparando o alerta, durante o segundo inteiro ou seja, durante os 1000 milissegundos do segundo vai ficar exibindo a mensagem :joy:
que é assim a linha de código, causando repetição:
if(Segundos == 10) { //ação a ser executada }
ele vai exibir o alerta durante 1 segundo inteiro…

por isso, o porque de colocar o milissegundos, para que ele não fique disparando o alerta n vezes dentro daquele intervalo atendido pelo critério, sendo assim, dispara uma única vez o alerta.:grin:

então para evitar a repetição, coloque os milissegundos, ficando assim:
if(Segundos == 57 && milissegundos >= 600) { //ação a ser executada }

C

Entendi Lucas, foi numas trocas que eu fiz que gerou loop então…

Vou fazer o teste e informo aqui se deu tudo certo. Obrigado mais uma vez!

C

Lucas, nada cara :confused:

Segue os códigos:

Evento Tick:

private void timer1_Tick(object sender, EventArgs e)

{

try

{

Dados dds = new Dados();
dds.VerificaBoleto();

            if (dds.qtdVencer > 0)
            {
                if (dds.segundos == 10 && dds.milisegundos >= 800)
                {
                    notifyIcon1.Visible = true;
                    //texto a ser exibido da notificação
                    notifyIcon1.Text = "ATENÇÃO";   
                    //titulo da mensagem
                    notifyIcon1.BalloonTipTitle = "Boletos a Vencer!";
                    //texto da mensagem
                    if (dds.qtdVencer > 1)
                    {
                        notifyIcon1.BalloonTipText = "Daqui dez dias vence " + dds.qtdVencer.ToString() + " boletos!";
                    }
                    //o tempo em que ficara sendo exibido
                    notifyIcon1.ShowBalloonTip(6000);
                }
            }
            else
            {
                MessageBox.Show("Não há boletos que está pra vencer no prazo de 10 dias!");
            }
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
    }

e

Função que verificaboletos:

public void VerificaBoleto()

{

try

{

AbrirConexao();

cmd = new SqlCommand(SELECT GETDATE(), con);

DateTime DataServidor = Convert.ToDateTime(cmd.ExecuteScalar());

novadata = DataServidor.AddDays(+11).ToShortDateString();
//ME MOSTRA QUANTOS DIAS TEM DE INTERVALO ENTRE A DATA ATUAL E A DATA FUTURO.
            //TimeSpan dt = Convert.ToDateTime(novadata) - Convert.ToDateTime(DataServidor);
            //totalDias = dt.Days;

            dataHora = Convert.ToDateTime(DataServidor.ToShortDateString());
            minutos = dataHora.Minute;
            segundos = dataHora.Second;
            milisegundos = dataHora.Millisecond;

            cmd = new SqlCommand("SELECT COUNT(*) FROM Boletos WHERE data BETWEEN @DataServidor AND @dataFuturo", con);
            cmd.Parameters.AddWithValue("@DataServidor", dataHora);
            cmd.Parameters.AddWithValue("@dataFuturo", novadata);
            cmd.ExecuteNonQuery();

            qtdVencer = Convert.ToInt32(cmd.ExecuteScalar());

        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
        finally
        {
            FecharConexao();
        }

    }

A função de verificar boletos está funcionando, pois tenho um botão manual que faz essa verificação e ele me retorna os boletos que está pra vencer.
Agora não entendo o porque que não está emitindo o System Tray :confused: me ajuda aí :confused:

C

Achei um erro.

Fiz um break point no evento Timer.

private void timer1_Tick(object sender, EventArgs e)

{

try

{

Dados dds = new Dados();

dds.VerificaBoleto();
if (dds.qtdVencer > 0)
            {
<strong>Ele para logo aqui.</strong>

if(dds.segundos == 10 && dds.milisegundos >= 800)

{

//não executa nada aqui e cai pro else logo abaixo.

{
}else{

<strong>E cai aqui.</strong>

MessageBox.Show(“Não  boletos pendentes!”);

}

Erro nos segundos, minutos, milisegundos?

C

Pessoal, achei um erro e resolvi de uma forma que não sei se está correta.
Como eu tenho as variáveis globais e publicas de milisegundos, segundos e minutos eu resolvi criar um MessageBox assim que dou um debug no meu sistema, ao clicar na ação do botão de verificar (adicionei esse MessageBox neste botão com a declaração das variáveis milisegundos, segundos e minutos da forma: sec = DataHora.Second e etc…)
E quando clicava no botão ele pegava a hora atual, os segundos e os milisegundos ATUAL, por um lado está correto mas ele não atualiza, pois se eu clicasse novamente no botão ele continuava com as mesmas marcações de segundos, milisegundos e minutos. Então resolvi fazer dessa forma:

private void timer1_Tick(object sender, EventArgs e)

{

try

{

Dados dds = new Dados();

dds.VerificaBoleto();
if (dds.qtdVencer > 0)
            {
<strong>adicionei essa linha abaixo</strong>

int i = 0;

i++;

if (i > 0 && i <= 9)

<strong>fim</strong>

{

notifyIcon1.Visible = true;

notifyIcon1.Text = “ATENCAO!”;

notifyIcon1.BalloonTipTitle = “Boletos a vencer.”;
if (dds.qtdVencer > 1)
                    {
                        notifyIcon1.BalloonTipText = "Possui " + dds.qtdVencer.ToString() + " boletos a vencer no prazo de dez dias!";

                    }
                    else
                    {
                        notifyIcon1.BalloonTipText = "Possui " + dds.qtdVencer.ToString() + " boletos a vencer no prazo de dez dias!";
                    }

                    notifyIcon1.ShowBalloonTip(1000);
                }
                else
                {
                    notifyIcon1.BalloonTipText = "Não há boletos pra vencer!";
                }
            }

        }
        catch (Exception ex)
        {
            throw new Exception (ex.Message);
        }
    }

E coloquei no meu Timer o valor: 10000.

A cada 10 segundos ele emite pra mim o alerta do SystemTray.
Tentei fazer com 1 minuto não consegui…

A ideia é do sistema alertar a cada 30min ou 1 hora mas pra mim ver se realmente está funcionando precisaria fazer com os segundos, que é no caso que eu fiz agora e funcionou.

Dessa forma que fiz está correto?
Eu precisaria agora é colocar pra funcionar em 30 em 30 minutos ou 1 em 1 hora. Podem me ajudar?

C

Meus amigos, consegui! :slight_smile:

Fiz essa lógica aqui e deu certo.

sec++;
                if (sec == 60)
                {
                    min++;
                    sec = 0;
                }
                else if (min == 29)
                {
                    min = 0;
                    sec = 0;
                }

//label pra verificar
                label8.Text = min.ToString();
                label4.Text = sec.ToString();

                if (dds.qtdVencer > 0)
                {
                    
                    if(min == 28 && sec == 59)
                    {

//faz o que eu quero.

Perfeitamente rapaziada! Ihá… Agora é os ultimos detalhes e colocar pra rodar essa budanga na empresa. Hahah. Valeu Lucas e galera!

Criado 23 de maio de 2016
Ultima resposta 1 de jun. de 2016
Respostas 39
Participantes 4