Ir para conteúdo
Fórum Script Brasil

Micheus

Veteranos
  • Total de itens

    3.189
  • Registro em

  • Última visita

Tudo que Micheus postou

  1. José, referente aos dois últimos posts seus, experimente colocar este código na sua procedure. Basicamente, o que fiz foi desmenbrar sua string de comando para variáveis locais, as quais facilitarão muito o processo. Apesar de não saber qual a composição da sua string de comando eu tentei fazer uso do que você já deixa meio claro nos exemplos. Assim, assumo que os 9 caracteres iniciais correspondem a identificação do client e o restante como comando. Da itendificação do client, eu assumo que você padronizou o nome como "Cliente" + Índice. Assim, desta identificação, extraimos o índice do client que nos dá acesso direto a posição em qualquer tipo de lista que você utilize para corresponder às informações do mesmo - como é o caso da linha no memo2. Observe que o uso de Memo2.Lines.IndexOf retorna a existência de uma string (no caso a de comando) em qualquer uma das linhas, logo não é necessário loop para esta verificação - ou existe, ou não existe. procedure .... var ClientSource, ClientCommand :String; ClientIndex :Integer; begin ClientSource := Trim(Copy(ReceivedCmd, 1, 9)); // copia o "nome" (identificação) do cliente ClientIndex := StrToInt(Copy(ClientSource, 8, Length(ClientSource))); // copia o "número" (índice) do cliente ClientCommand := Copy(ReceivedCmd, 10, Length(ReceivedCmd)); // copia apenas o comando enviado pelo cliente if Memo2.Lines.IndexOf(ClientCommand) = -1 then // comando não repetido begin Memo2.Lines.Delete(ClientIndex); Memo2.Lines.Insert(ClientIndex, ClientCommand); end; ... // outros procedimentos end; Quanto a questão do hexadecimal, acredito que a questão estaria relacionada a string de comando. Acredito que ela já esteja sendo enviada no formato a ser enviado para a porta, ou seja, com os caracteres de configuração. Se for isto, então, para que você mostre o comando no formato hexa legível (vamos dizer assim), você teria que implementar uma rotina que faça o inverso, ou seja, converta cada caracter da string de comando (apenas a parte do comando) em seu código decimal que formatado em hexa resultará no formato legível. Seria fazendo uso da função CharsToHexa (deste post). Abraços
  2. Micheus

    Ajuda Delphi

    devil69, quanto ao uso de IdSMTP1.Authenticate, é porque no meu caso se faz necessário o uso de autenticação no servidor (isso varia de servidor para servidor - é o caso do meu). Quanto a se fazer entender, eu até já tinha entendido. O exemplo, eu lhe passei após ter me desconectado da internet (só não fiz a desconexão física), e como disse, a mensagem ocorre apenas quando executado o programa no ambiente de desenvolvimento, ou seja, a partir do Delphi. Se executo o programa gerado (executável - .exe), não há qualquer mensagem de erro (exceto, no exemplo que postei, pois está programado para mostrar uma mensagem informando a falha na conexão). Assim, fica a pergunta sobre algo que até agora você não mencionou: Quando você executa o programa diretamente (o .exe), ocorre o erro? Fora isto, não teria mais nada a acrescentar. Sinto muito. Abraços
  3. Micheus

    Ajuda Delphi

    devil69 você tem dois componentes idsmtp ou foi apenas erro de digitação (tem um idsmtp e idsmtp1 no seu exemplo) Eu fiz o teste com um form de email que eu tenho e ocorre o erro #11004, mas da forma como disse antes - apenas no ambiente de programação (executando por fora não aparece nada). Então adaptei e coloquei um ShowMessage, para conferir, e daí ao executar por fora apresenta a mensagem de problema com a conexão. Logo, a abordagem deveria funcionar. Veja como está meu código (eu trato mais informações, inclusive): procedure TFrmEMail.BitBtn3Click(Sender: TObject); begin //Configuração do IdMessage (dados da mensagem) IdMessage1.From.Address := edMailUserName.Text; //e-mail do remetente IdMessage1.Recipients.EMailAddresses := mmMailTo.Text; //e-mail do destinatário IdMessage1.Subject := edMailAssunto.Text; IdMessage1.Body.Assign(RichEdit1.Lines); //Configuração do IdSMTP (dados do protocolo) IdSMTP1.Host := RecAPOUS.SMTP_Server; IdSMTP1.Port := StrToIntDef(RecAPOUS.SMTP_Port, 25); IdSMTP1.Username := RecAPOUS.SMTP_User_Name; IdSMTP1.Password := medMailUserPassword.Text; try IdSMTP1.Connect; //Estabelece a conexão try IdSMTP1.Authenticate; //Faz a autenticação try IdSMTP1.Send(IdMessage1); except on E:Exception do E.Message := 'Houve um erro ao tentando enviar a mensagem:'#10 +E.Message; end; except ShowMessage('Houve um erro na autenticação'); end; except ShowMessage('Houve um erro na conexão'); end; end; A única alteração que faço nas propriedades do idSMTP, após adicioná-lo ao form, é na propriedade AuthenticationType=atLogin; No componente idMessage, não faço qualquer alteração de propriedades. Abraços
  4. Micheus

    Ajuda Delphi

    seria mais conveniente se você pudesse colocar a parte do código (procedure) onde você está fazendo este tratamento, assim ficaria mais fácil de verificar o que você está fazendo e dar alguma sugestão.
  5. Vou por alguns tópicos sobre o assunto, mas para ver outros, use o botão Pesquisar e coloque como palavra chave: LIKE (tem muitos tópicos a respeito)- Fazer Uma Busca Em Sql E Usar Like Ao Invés De = - Duvida Com Pesquisa - Consulta Usando Query Vai olhando eles que você consegue tirar muitas dúvidas (que outros já tiveram) sobre este comando. Abraços
  6. Micheus

    Ajuda Delphi

    Então. O que quiz sugerir é que você tente tratar o erro na tentativa de conexão com o servidor. Em algum lugar do programa você tem um IdSMTP1.Connect, então o exemplo ficaria assim: procedure TForm1.Button2Click(Sender: TObject); begin try IdSMTP1.Connect; // tenta estabelecer a conexão ... // segue com seu código aqui, quando a conexão for estabelecida except // aqui fica sem comando algum, já que você não quer que algo ocorra nesta condição end; end; Catpou?! Testa aí e vê como fica. É importante lembrar, que mesmo fazendo o tratamento das exceções, enquanto você está no ambiente de desenvolvimento (ou seja, executando via IDE do Delphi) e com a opção Integratting debuging habilitada no Delphi (o que é o ideal para desenvolvimento), ao ocorrer um erro, o programa será interrompido e desviado para o código do mesmo na IDE do Delphi e daí ao teclar F9 o mesmo continua. Então, se isto ocorrer, você pode então testar o programa, já compilado, por fora do delphi (o seu executável final) para tirar a dúvida. Abraços
  7. Fabiano, é quase certo que seja devido a linha:Aluno := strtoint(Edit1.Text); O evento OnChange ocorre a cada alteração do Edit. Seja pela digitação de um caracter ou por sua definição como nulo (''). E é justo nesta condição que a linha citada gera erro. Ao tentar coverter qualquer coisa que não seja número para um (isto inclui a string nula - vazia), você terá o erro. Para contorná-la você deverá validar seu conteúdo, tipo: if Edit1.Text <> '' then begin Aluno := strtoint(Edit1.Text); Zquery.Active := false; ... Zquery.Open; end; ou, pelo menos, talvez o mais apropriado: try Aluno := strtoint(Edit1.Text); Zquery.Active := false; ... Zquery.Open; except ShowMessage('Digite um núbero válido.'); end; Entretanto, por não tratar-se de uma busca incremental (onde a cada caracter digitado você vai filtrando a consulta - como se faz em uma pesquisa usando LIKE), minha sugestão é que este tratamento seja feito no evento OnExit, ou seja, apenas quando o texto (mesmo que numérico) esteja completo. Abraços
  8. Micheus

    Ajuda Delphi

    devil69, foi só um exemplo, ou seja, a idéia principal é a de que você "cerque" a abertura da conexão com o host (servidor) como exemplificado. Eu nem sei se era este componente da paleta que você estava utilizando... Se você colocar a parte do código onde você conecta com o servidor fica mais fácil alguém exemplificar. Convém também que você informe sempre o erro. Este não "tá dando erro" sugere que não seja o mesmo que você tinha antes, então, fica muito vago. Abraços
  9. Micheus

    Ajuda Delphi

    devil69, fora este nick "demoníaco", utilizar um timer para enviar e-mails periódicos e sem que uma mensagem de erro seja apresentada ao usuário.... meio suspeita esta aplicação <_< (esteja atento ao item 3.2 das regras do forum) de qualquer modo, tente tratar a abertura da conexão utilizando um try...except...end, como: procedure TForm1.Button2Click(Sender: TObject); begin try IdFTP1.Connect(True, -1); ShowMessage('Conexão ok'); except ShowMessage('Conexão falhou'); end; end; Abraços
  10. Cedricovale esta observação que já fiz em outro tópico: Ocorre que utilizando ShowModal, a execução das instruções após sua chamada ficam "suspensas" até que o form seja fechado. Assim, chame o Hide antes do ShowModal. A sequência funcionaria apenas se fosse utilizado o método Show, mas talvez esta opção não lhe enteresse. E outra coisa, após fechado o form, ele (a variável que você faz referência) torna-se inválido. Neste caso, você cria deverá recriá-lo para poder mostrá-lo, ou então, você não deve fechá-lo (close) mas sim esconder (hide). Vai da sua aplicação. Veja este post Um outro post onde é utilizado Show. Voce deve observar também se estará ou não criando os forms em run-time ou design-time. Conforme o caso, especifique melhor como você pretende manipular estes forms. Abraços
  11. José, uma vez que os LBoxn são limpos a cada comando recebido, ou seja, mantém apenas o último comando recebido, porque que é que você não utiliza apenas um TEdit? Isto supostamente poderia simplificar o processo de comparações, já que pelo que entendi, você deverá comparar um valor com o outro para que não existam iguais. E no ListBox1 estarão os comandos a serem enviados para a porta. Certo?!Eu só não entendi, direito a função do Comparador, uma vez que não existindo o texto nele no LBox2, você o limpa e adiciona um novo valor. Mas a comparação não deveria ser feita com os demais LBoxn? :unsure: É, realmente parece que temos um bug com a função, inclusive a função AnsiContainsStr (que é uma versão case-sensitive) apresenta o mesmo problema.Mas podemos contornar de outros modos. Se você está armazenando os valores em caixa alta, por ex., não há maiores preocupações e podemos substituir pela função AnsiPos: if AnsiPos(Edit1.Text, Memo1.Lines.Text) > 0 then caso contrário, devemos garantir que os textos comparados tenham o mesmo "case" if AnsiPos(AnsiUpperCase(Edit1.Text), AnsiUpperCase(Memo1.Lines.Text)) > 0 then Bom, isto está ocorrendo porque você está convertendo o valor hexa para char. Por ex., $AA é o valor decimal do caracter ª. Então, este comando tem que ir no formato string para o listbox. A sua conversão para código ascii, na seqüência de caracteres, só terá que ser enviada para a porta de comunicação. Não seria isto? Abraços
  12. Jhonas, permita-me uma parte nesta discussão. vms, ao identar seu código lá no post#5, observei que algum problema com a soma realmente você pode ter. Observe que você não está posicionando o dataset no primeiro registro antes de percorrer todos os existentes. Assim, na primeira vez o dataset está posicionado no registro inicial e, ao ler os próximos (via Next), voce vai movendo o dataset até seu último registro. Mas, em uma segunda vez, o dataset está no último registro e você vai somando o valor atual (o último, onde ficou na operação anterior) "n" vezes (n=RecordCount) - logo não está correto. Outra coisa, observada, é que você não seguiu exatamente a idéia que o colega Jhonas colocou no post#4. Lá ele lhe exemplificou colocando a atribuição do somatório aos edits, apenas após a conclusão do loop - o correto. Assim, segue aquele código corrigido nestes termos: procedure TForm1.ToolButton4Click(Sender: TObject); var i : integer; valComp0, valComp1 : real; begin valComp0 := 0; valComp1 := 0; // A cada click do botão, você tem que realizar a soma // a partir do registro inicial, então, você deve posicionar // o dataset no registro inicial DM.Q1.First; for i := 1 to DM.Q1.recordcount do begin if DM.Q1Departamento.Value = Edit3.Text then valComp0 := valComp0 + DM.Q1Valor.Value; if DM.Q1Departamento.Value = 'ZELADORIA' then valComp1 := valComp1 + DM.Q1Valor.Value; DM.Q1.Next; end; // Estes edits recebem o total após a conclusão da soma, portanto // esta atribuição TEM que ficar fora do loop!!! Edit1.Text := 'Total Dep. Projetos ) : R$ ' + floattostr(valComp0); Edit2.Text := 'Total Dep. Zeladoria) : R$ ' + floattostr(valComp1); end; Abraços
  13. e quanto aos datamodules? Quando são criados? Nestes procedimentos, procure colocá-los dentro do padrão que você já utiliza e que são mais adequados ex. da correção sugerida: procedure TFrmPrincipal.acClienteExecute(Sender: TObject); begin frm_cliente := TFrm_Cliente.Create(self); // < FICA NESTA POSIÇÃO try frm_cliente.ShowModal; finally FreeAndNil(frm_cliente); end; end; procedure TFrmPrincipal.acVendasExecute(Sender: TObject); begin if not assigned(Frm_Vendas) then application.CreateForm(TFrm_Vendas,Frm_Vendas); Frm_Vendas.ShowModal; FreeAndNil(Frm_Vendas); end; Sendo que se você utilizar os forms neste formato (após o showmodal liberá-los, não haveria porque fazer o teste para sua criação já que você o cria e o destroy. Então, seria mais apropriado utilizar o formato que você utiliza em alguns pontos do programa, como o formato apresentado no 1º exemplo da correção Outra pergunta: Nos form's onde você está utilizando este método de criação (abaixo), por acaso você está manipulando o evento OnClose e definindo Action com csFree? procedure TFrmPrincipal.MapaDirio1Click(Sender: TObject); begin if not assigned(Frm_RelMapaDiario) then application.CreateForm(TFrm_RelMapaDiario,Frm_RelMapaDiario); Frm_RelMapaDiario.ShowModal; end; Abraços
  14. etspaz, eu acho pouco provável ser com o Delphi.você executa algum procedimento no evento OnCreate dos forms? Você está criando os forms em run-time?
  15. Vera, a resposta do post do colega Paulobergo não lhe serviu? Qual a dúvida?
  16. Micheus

    Linha do Dbgrid

    colega.. mesmo que voce tenha limitado a visualização do dbgrid em 13 linhas, ao usar a barra de rolagem, a posição do registro muda... então voce não vai ter sempre a linha 1 como sendo o registro 1, mas na linha 1 visualizada no dbgrid pode estar o registro 2 ou 3 ou 5, ou 10.... etc... a linha do dbgrid reflete a linha do registro na tabela Rodrigo, isto que o Jhonas está colocando é real.Você deve ter isto em mente quando pensa no posicionamento linha/coluna em um TDBGrid. Jhonas, na verdade tem um meio sim (mesmo que a informação não seja a esperada, como você já citou ao colega Rogerio). A idéia básica é que você define na sua unit, uma classe descendente de TDBGrid e nela exporta as propriedades Col e Row que estão protegidas (sessão protected da classe) na classe ancestral TCustomGrid. (não lembro se isto já foi mostrado por aqui antes :unsure:) Rodrigo, Implementando a codificação abaixo, você observará a diferença entre uma abordagem e outra. Talvez você compreenda melhor a que o Jhonas se referiu em sua observação. Coloque dois labels no form e experimente ele com um grid que mostre menos linhas do que a que há no dataset e você entenderá (ex. dataset com 8 registros e grid mostra 5 linhas). unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Controls, Forms, DB, Grids, DBGrids, StdCtrls, ExtCtrls, DBCtrls; type // declaração da nossa classe para exportação de propriedades protegidas TDBGridExtended = class(TDBGrid) published property Col; property Row; end; TForm1 = class(TForm) DBGrid1: TDBGrid; ... end; implementation ... procedure TForm1.DBGrid1CellClick(Column: TColumn); begin // utilizando o número do registro como linha e o índice de Column como coluna Label1.Caption := Format('Linha: %d Coluna: %d', [DBGrid1.DataSource.DataSet.RecNo, Column.Index +1]); // utilizando a posição no grid visível. Row como linha e Col como coluna Label2.Caption := Format('Linha: %d Coluna: %d', [TDBGridExtended(DBGrid1).Row, TDBGridExtended(DBGrid1).Col]); end; procedure TForm1.DBGrid1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key in [VK_LEFT, VK_RIGHT, VK_HOME, VK_END] then DBGrid1CellClick(DBGrid1.Columns[DBGrid1.SelectedIndex]); end; procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField); begin DBGrid1CellClick(DBGrid1.Columns[DBGrid1.SelectedIndex]); end; end. Uma observação, quanto a questão do posicionamento, é que não dá para considerar apenas o evento OnCellClick, já que o usuário pode movimentar-se utilizando o teclado, por isto a implementação do evento OnKeyUp. Inclusive deve ser no UP e não do DOWN da tecla, pois o índice da coluna ainda não estaria atualizado. Mas, utilizar os dois métodos ainda não seria suficiente, porque o usuário poderia utilizar a barra de rolagem vertical, motivo pelo qual utilizei o evento OnDataChange do DataSource associado ao DBGrid. Devido ao uso deste evento, que gerará a atualização pela movimentação entre as linhas, é que o código no evento do teclado foi otimizado de modo a verificar apenas a movimentação vertical. Bom, ficou de fora a movimentação pela barra vertical, mas como sua utilização não resulta na mudança de coluna, acho que não temos que nos preocupar com ela. Qualquer dúvida... Abraços
  17. Você viu o seu post que eu mencionei?Lá tem o código da Stored Procedure STPCSLAUL em seu banco. Não é dela que você obtém os dados para serem mostrados no DBGrid? Se for, o que eu queria dizer é que você poderia acrescentar mais um campo a ser retornado por ela, como você fez quando criou o campo pOrd apenas para retornar um número sequencial. A diferença é que este sequencial seria por categoria. Será que captou agora? Se não for, ignore o que eu disse até agora. Abraços
  18. José, para facilitar na compreensão de seu problema, eu pediria que você colocasse aqui um exemplo de um destes cenários por você apontado. Ou seja, uma condição inicial (onde já existem alguns itens nas listas), uma condição em que um item será adicionado (o texto a ser processado) e o resultado esperado. Seria ainda conveniente que você colocasse as procedures envolvidas nesta questão (não precisa ser completa, mas a parte que envolve estas listas, memos e edits que você citou).Com isto, ficaria mais fácil simular o que você tem aí, e tentar achar uma sugestão por aqui. ;) Dica O código abaixo pode ser simplificado uma vez que o método Add retorna a posição em que o texto foi adicionado. Logo, ele passaria de: ListBox1.Items.Add(Copy(ReceivedCmd, 10, Length(ReceivedCmd))); ListBox1.ItemIndex := ListBox1.Count -0; para: ListBox1.ItemIndex := ListBox1.Items.Add(Copy(ReceivedCmd, 10, Length(ReceivedCmd))); Abraços
  19. fajo, não dá para opnar exatamente. Mas, quanto a desempenho, há itens a serem observados, tais como existência ou não de índices, número de registros armazenados, complexidade das consultas SQL, ... Visto que você fez a migração de Access para Firebird, por acaso você teria mantido os mesmos componentes de acesso e utilizou o driver ODBC para acessar o Firebird? Uma dica, aparentemente seu campo doc_data_operacao é do tipo DATE (ou seja, armazena apenas a data). Se for, seria mais apropriado que você o camparace com CURRENT_DATE e não com CURRENT_TIMESTAMP (ambos guardam informações diferentes - timestamp armazena a hora também). Abraços
  20. AllNet, dependendo de como está definida sua tabela, o fato de gravar um mesmo registro pode gerar uma exceção do tipo "Key Violation". Mas, há cituações em que isso pode não ocorrer. Neste caso, e mesmo no primeiro, a saída é utilizar uma querie auxiliar para verificar a existência da informação na tabela, antes de você gravar as informações. Como você utiliza o DBNavigator (e também por conta do DBGrid), a ação de gravação (via método Post) pode ocorrer sem que você o efetue explicitamente (via código). Nesta situação, você pode utilizar o evento BeforePost do dataset sendo editado e nele você faz a validação via querie auxiliar. Caso a informação já exista, então você aborta o processo de inclusão (via procedure Abort). Veja este post para ter uma idéia. Abraços
  21. Filipe, então como deve ser este seu relatório?Como você imagina que deva ser o lay-out final dele? Se você postar a estrutura da tabela (nome e campos) e lay-out, talvez fique mais fácil de auxiliá-lo. Abraços
  22. Jhonas, sem querer interferir na linha de raciocínio tomada, eu sugeriria ao colega etspaz que verificasse em algum dos procedimentos chamados a partir da procedure FollowUp, ou forms que lá ele cria, em que ponto ele está fazendo uso da função Format. Esta mensagem de erro é típica da chamada desta função como: Label1.Caption := Format('Cliente: %d %s', [Codigo]); onde foi informado apenas um parâmetro, sendo esperado outro que é justamente o string (%s) Abraços
  23. Eder, se a idéia é eliminar o texto com é inserido, experimente: procedure TFormRelCidades.ComboLayOutChange(Sender: TObject); begin IF COMBOLAYOUT.TEXT = 'LAYOUT-1' THEN ComboOrdem.Items.Append('CIDADES/PRAÇAS/ESTADOS'); else ComboOrdem.Items.Delete(ComboOrdem.Items.IndexOf('CIDADES/PRAÇAS/ESTADOS')); end; IndexOf, retorna o índice na lista onde está o texto. Caso ele não exista, será retornado -1. Se não me engano, quando é passado um índice meno que zero, não qualquer erro relacionado a "ranger", tipo: "Index out of ranger" Assim, o exemplo deve funcionar sem problemas... Teste. Abraços
  24. Este tipo de informação normalmente é guardado em um arquivo de configuração ou registro do Windows. OBS: Um exe não pode alterar a si mesmo equanto está rodando (no Windows não é possível - pelo menos até estes dias). Ou seja, você deveria utilizar um exe para alterar outro. Abraços
  25. Por outro lado, se a função não for parte de um form, como exemplificou o colega João Paulo, então você deve declarar seu cabeçalho na seção Interface da unit para que possa ser referenciada pela outra. Ex. Program Unit1; Interface Type TForm1 = Class(TForm) ... end; function ProcessaInfo :Boolean; // < DECLARAÇÃO DO HEADER Implementation function ProcessaInfo :Boolean; // < Códificação da unit, na sessão implementation begin ... Result := True; end; procedure TForm1.FormCreate(Sender :TObject); begin ... end; end. Program Unit2; Interface Type TForm2 = Class(TForm) ... end; Implementation Uses Unit1; // < REFERÊNCIA a Unit1 para poder utilizar a função lá contida procedure TForm1.ButtonClick(Sender :TObject); begin if ProcessaInfo then // < USO da função na outra unit ShowMessage('Processou função e dados ok'); ... end; end. Abraços
×
×
  • Criar Novo...