
Micheus
Veteranos-
Total de itens
3.189 -
Registro em
-
Última visita
Tudo que Micheus postou
-
Exibir dados preestabelecidos no BDEdit
pergunta respondeu ao Alex Freitas de Micheus em Delphi, Kylix
Alex Freitas, reforçando e completando o que já disseram... Inicializações deste tipo, devem ocorrer na inclusão de um novo registro, não é mesmo!? Com isto em mente, localize no seu dataset o evento OnNewRecord (novo registro) e na eventual falta dele, algo como AfterInsert (que também ocorre após um Insert ou Append). Nele, faça toda e qualquer inicialização de campos deste dataset. Não aconselho pensar nos TDBEdit's com sendo a mesma coisa que um TEdit, e assim fazer atribuições utilizando a propriedade Text. Isto pode lhe fazer esquecer de que, na verdade, as informações que constam nele são de fato provenientes do campo pertencente ao dataset a ele vinculado. Além do mais, a inicialização utilizando valores strings pode gerar dor de cabeça quando você estiver tratando de datas e numeros com decimais. Feicará muito mais claro e simples a atribuição de valores utilizando diretamente o campo (field) do dataset. Caso você esteja adicionando os campos (fields) do seu dataset em design-time, você pode acessá-lo diretamente, do contrário poderá utilizar métodos como o FieldByName para acessá-lo. Ex. Tendo um dataset chamado TabCliente que possua um campo Nome, caso você tenha adicionado o field em design-time, você poderá acessá-lo deste modo: TabClienteNome.Value := 'Armando Lero'; caso contrário: TabCliente.FieldByName('Nome').Value := 'Armando Lero'; Detalhando cada item questionado: 1) DBEdit1 - Tipo Data, (Neste campo quero exibir a data atual sem permitir alteração). a parte da inicialização já está explicada. Quanto a parte de não permitir alteração, você deverá usar a propriedade ReadOnly ou Enabled do componente; 2) DBEdit2 – Tipo Currency, (Ficará livre pra digitação do valor “Valor do Cheque”). a princípio, não há como você mostrar o texto “Valor do Cheque” em um campo que não é string (se é o que você quer fazer); 3) DBedit3 – Tipo Currency, (Neste campo quero exibir uma taxa fixa de 3,5% para calculo futuro). também a inicialização já está explicada. Caso este campo não possa ser alterado, agora você já sabe como fazer; 4) DBEdit4 – ( Quero realizar o seguinte cálculo DBEdit2 * DBEdit3) Caso a informação que apareça neste DBEdit seja apenas informativa, ou seja, não fica gravada no banco de dados, então você terá um campo calculado (fkCalculated) e deverá fazer a operação no evento OnCalcFields do dataset em questão. Mas, caso seja um campo que fica armazenado em seu banco de dados, e sabendo que o valor do campo que está no DBEdit4 é resultado da operação entre outros dois, parece razoável que ao alterar qualquer um deles, você tenha que refazer os cálculos, não é mesmo?! Com esta idéia em mente, você pode imaginar que o melhor lugar para isto ser feito seja algum evento que indique a alteração de algum deles. A adição dos fields em design-time, trazem mais este benefício, já que você terá acesso ao evento OnChange deles. A título de exemplo, o que você faria é selecionar os dois campos na lista de campos do dataset, acessar a guia Events na janela Object inspector e dar um duplo-click no evento OnChange. A parte do código em que a operação deverá ser feita ficaria algo como: TabItemValorMulta.AsFloat := TabItemValor.AsFloat *(TabItemPercMulta.AsFloat /100); algo equivalente ao seu exemplo Você pode perguntar: por que usar ".AsFloat" e não ".Value"? e a resposta é que ao usar Value, você está tratando de um tipo Variant que pode conter valores nulos (caso você não inicialize os campos). Como resultado, uma exception pode ocorrer. Ao usar AsFloat, a "função" fará a validação internamente e se for o caso de estar nulo, será retornado o valor 0 (zero) que não gerará erro. Abraços -
Luis Ricardo, apenas uma correção. O somatório das horas trabalhadas se fará pela diferença entre a hora de saída e a de entrada, logo, a ordem deve ser invertida: Sum(f.HorSai1-f.HorEnt1) AS SOMAHORA1, Sum(f.HorSai2-f.HorEnt2) AS SOMAHORA2 mas pode ser feito tudo de uma só vez: Sum((f.HorSai1-f.HorEnt1) + (f.HorSai2-f.HorEnt2)) AS HORAS_TRABALHADAS Lembrando que o resultado da operação com o SUM resultará uma valor real (um float, não um time) - esteja atento para este fato. A título de exemplo, 8:00 trabalhadas será listado como 28800. Querendo listar em termos de quantidade de horas, basta que seja dividido este valor por 3600. Neste caso, 28800/3600 => 8; Para usar este valor corretamente no Delphi, como um TTime, ele deverá ser dividido por 60s x 60m x 24h => 3600 x 24 => 86400 Assim, 28800/86400=0,333333.. que aplicado a função TimeToStr, mostrará: 08:00:00 A forma como usar a informação depende da aplicação que será dada a mesma. Abraços p.s. estes comentários são válidos, pelo menos para uso com Firebird - banco que o robinhocne provavelmente ainda usa.
-
use o campo da tabela que você vinculou ao seu DBImage. Vamos supor que se chame "FOTO". Assim, estando a sua tabela em modo edição, você simplesmente faz algo como: Tabela.FieldByName('Foto').Clear ou ser tiver adicionado os fields do seu dataset Tabela, faça TabelaFOTO.Clear; Quando executar o post, seu campo estará limpo. t+
-
fabim, acho que você conseguirá fazer isto facilmente sim. Eu esqueci de mencionar que no componente StockAudioPlayer foi necessário habilitar em Options o item Volume. No dia post eu não tinha acesso ao site de compartilhamento, mas já coloquei o exemplo lá. Baixe-o do link constante em minha assinatura, está na pasta Programacao\Multimidia - Wave Player.zip Abraços
-
(Resolvido) Imagem piscando por causa do timer
pergunta respondeu ao Vivendo&Aprendendo de Micheus em Delphi, Kylix
Vivendo&Aprendendo, se fizer isto que você sugere, no máximo vou lhe responder com o que você postou inicialmente: Digo isto porque já tenho um demo nestas condições. você não conseguiria fazer uma aplicação (inútil) com este "defeito" pra que ser possa avaliar? Este lance do background ainda está meio obscuro. -
fabim, posso estar enganado, mas acho que você não chegou a dar uma olhada, com carinho, nos exemplos. Sugiro que instale-o novamente, e dê uma olhada nos exemplos para fins de estudos - conhecer eventos, métodos e propriedades dos vários componentes (com ênfase aos que tem potencial para sua aplicação). Haverão dois projetos exemplos que apresentarão erro de compilação. Parece que o cara não testou os exemplos ou, mais provavelmente, realizou alterações nos componentes que não atualizou nos demos: 1) no projeto Receiver em Live Audio\ReceiverFile lá pela linha 112 onde aparece: if WaveFile.State = wssNone then // Getting Wave Format trocar por: if WaveFile.State = wssReady then // Getting Wave Format ocorre que wssNone não está declarada e não é utilizada em mais lugar algum. 2) no projeto Receiver em Live Audio\Receiver ao compilar acusará erro nos parâmetros dos métodos referentes aos eventos OnDataPtr e OnFormat do componente LiveAudioPlayer (LiveAudioPlayerDataPtr e LiveAudioPlayerFormat). Este é mais chato de corrigir. Se precisar construir um streamer para uma rede, então avise que passo o arquivo corrigido. Com uma alteração bem simples no exemplo que ele fornece na pasta WavePlayer, você verá que os itens 1 e 2 serão facilmente implementados. Quanto ao item 3, acho interessante você testar por você mesmo. Eu não percebi qualquer demora. Faça assim, copie o projeto que citei para uma nova pasta de teste e faça as seguintes alterações: - Aumente o tamanho do form (na largura e altura); - adicione 2 TrackBar (paleta Win32), lado a lado, e ajuste as propriedades: -> Orientation = trVertical; -> Frequency = 5 -> no 1º TrackBar ajuste Min = -100 e deixe Max = 0; Usar a escala negativa, fará com que o ajuste do track ocorra de baixo para cima e o valor 100 corresponderá a 100% para o volume; -> no 2º TrackBar estes informações serão ajustada no código; - no evento OnChange do TrackBar1 (volume), coloque o seguinte código: procedure TMainForm.TrackBar1Change(Sender: TObject); begin StockAudioPlayer.Volume := -TrackBar1.Position; // revertemos a escala para positivo end; - no evento OnChange do TrackBar2 (ponto de início para "tocar" o som), coloque o seguinte código: procedure TMainForm.TrackBar2Change(Sender: TObject); begin StockAudioPlayer.Position := -TrackBar2.Position; // revertemos a escala para positivo end; - altere o código no evento OnClick do btnPlay para ficar assim: procedure TMainForm.btnPlayClick(Sender: TObject); begin // por Micheus StockAudioPlayer.Volume := 75; // Inicia música com volume sempre neste valor (75%) // ajustar a barra de volume para representar o ajuste TrackBar1.Position := -StockAudioPlayer.Volume; // este "-" é porque usamos escala negativa no TrackBar // fim StockAudioPlayer.PlayFile(WaveFileName.Text); end; - no evento OnClick do btnSelectFile acrescente a parte assinalada com meu nome: ... try AudioFormatLabel.Caption := WaveFile.AudioFormat; Progress.Position := 0; Progress.Max := WaveFile.Length; // por Micheus // ajustar a barra de posição para o início do áudio TrackBar2.Position := 0; // inicializamos sempre no início do áudio // ajustar o maior valor possível para posição do áudio TrackBar2.Min := -WaveFile.Length; // este "-" é porque usamos escala negativa no TrackBar // fim EndPosLabel.Caption := MS2Str(WaveFile.Length, msSh) + ' s'; finally ... end; O ajuste do volume afeta apenas esta sua wave - não interfere nos ajustes do Windows. Abraços
-
fabim, este é o tipo de coisa difícil de encontrar por aí, acho que não vai ser muito fácil não. Mas, dê uma olhada neste componente Wave Audio v1.88. Se ele não recursos lá tão revolucionários, pelo menos você poderá aproveitar muito do código que o autor disponibiliza (veja p.e., WaveUtils). Você provavelmente obterá uma possível ajuda com relação ao item 3. Nas notas da revisão consta: Added two new classes for converting wave audio stored in memory and file on the fly ou Adicionado duas classes novas para converter o áudio da wav armazenado na memória e arquivo em "tempo real" Boa sorte.
-
(Resolvido) Imagem piscando por causa do timer
pergunta respondeu ao Vivendo&Aprendendo de Micheus em Delphi, Kylix
Vivendo&Aprendendo, isso demonstra que o flicker deve estar associado a forma como este seu backgroud é mostrado no form do seu sistema. Como você implementou ele? Já que um panel é opaco, você deve estar fazendo algo para que a imagem apareça no fundo dele também. Abraços -
Simples!Utilize duas consultas, onde em uma você filtra o que é Entrada e na outra o que é Saída. Com isso você terá exatamente os dois datasets (um para entrada e outro para saída). ;) Tenta isto primeiro. Qualquer coisa posta aí que eu continuo dando apoio. Abraços
-
(RESOLVIDO)como colar texto de um RichEdit no Quick Report?
pergunta respondeu ao Greed de Micheus em Delphi, Kylix
este não é mesmo o modo correto. Conforme a documentação, você deveria usar um componente TRichEdit e linka-lo ao TQRRichText. quanto a perda do formato, eu acredito que, ainda você consiga resolver a questão do link, você vá ter problemas. Por isso minha citação anterior: não faço a menor idéia, porque nunca tive este problema. Eu fico em dúvida é se você usando o seu JvRichEdit (que lembro-me tem alguns recursos a mais que o RichEdti) vai conseguir uma impressão correta do que você formatou no seu texto.Teria que ver ser há algum componente que possa ser usado para a impressão neste pacote do Jedi Lib. parece que você não viu as sugestões de posts que eu passei. São as opções que existem com o Quick. O problema, é que no seu código, você não está conseguindo fazer funcionar. Abraços -
(RESOLVIDO)como colar texto de um RichEdit no Quick Report?
pergunta respondeu ao Greed de Micheus em Delphi, Kylix
É este mesmo. Eu errei o nome. :blush: estranho isso. Nem sequer mostra ele? Eu passei por paremetro, mas mesmo assim ele não recebe o texto. Eu coloquei os códigos no evento BeforePrint do QR. É neste evento que eu coloco correto? não faço a menor idéia, porque nunca tive este problema. Eu fico em dúvida é se você usando o seu JvRichEdit (que lembro-me tem alguns recursos a mais que o RichEdti) vai conseguir uma impressão correta do que você formatou no seu texto. eu não lembro qual seria. Dê uma olhada neste outro post: http://scriptbrasil.com.br/forum/index.php...st&p=425646 na parte que ele chama: FrmPreviewRTF.PreviewRTF(RichEdit1); troque por: FrmPreviewRTF.PreviewRTF(JvRichEdit1); Greed, tem problemas como este que são muito difíceis de serem resolvidos quando a gente não o tem na mão, porque é o tipo de coisa simples que normalmente estaria funcionando sem problemas. Então, eu não saberia mais o que lhe sugerir. Grande abraço -
como criar um banco de dados no delphi
pergunta respondeu ao Arrais Júnior de Micheus em Delphi, Kylix
Quero acreditar que você queira fazer apenas um cadastro bem simples (poucos campos, poucos registros, pouco recursos), porque do contrário você estaria querendo reinventar a roda. Supondo que seja isto mesmo, então você poderia trabalhar com arquivos *.csv - que seria a opção mais simples de todas. Aqui no forum tem uns tópicos sobre importação ou exportação de arquivos que "falam" sobre este tipo de arquivo e podem lhe auxiliar em certo ponto do programa. Poderia utilizar também arquivos tipados - veja este exemplo (ref. PCForum) Só que não utilizando qualquer tipo de "banco de dados", você não terá recursos como buscas e ordenação - você terá que implementar tudo isso. Se você estiver certo de que é isto mesmo que quer implementar, dê um pouco mais de detalhes sobre o que você pretende. que sacanagem. :D Abraços -
João Paulo Taraciuk, veja se este tópico lhe ajuda a dar uma idéia: Relatório Diário de Caixa Entrada/Saída, Como fazer este relatório de maneira correta! (leia do início, mas a resposta e ele está no post#10)
-
(RESOLVIDO)como colar texto de um RichEdit no Quick Report?
pergunta respondeu ao Greed de Micheus em Delphi, Kylix
Na paleta do Quick Report. -
(RESOLVIDO)como colar texto de um RichEdit no Quick Report?
pergunta respondeu ao Greed de Micheus em Delphi, Kylix
Greed, você vai pagar por um componente ou tornar seu software pirata (caso use uma versão crackeada) se quiser. você diz que já tem o conteúdo em um RichEdit - não apenas no clipboard. Então, onde está a dificuldade em usar a opção que lhe passei? Olhe este outro post onde um RichEdit no form é passado como parâmetro para o procedimento que mostra o relatório. -
traira007, você não teria instalado um programa de administração do banco, algo como o MySQL Administrator (ou o próprio), para dar uma verificada se neste momento que estoura o limite de usuários não haveriam conexões que não deveriam estar ativas (tipo algum problema que possa estar mantendo conexões ativas) de modo a estourar, na verdade, os 100 usuários? Abraços
-
você pode usar a função CONVERT (ref. msdn) para isto:CONVERT ( data_type [ ( length ) ] , expression [ , style ] ) ex: select Nome, CONVERT (varchar(10), DatNasc ,103) from alunos o 103, conforme você poderá ver no link em referência, diz respeito a formatação dd/mm/yyyy (ano com 4 dígitos). Se for para usar 2 dígitos, style deve ser 3. para este caso, talvez você possa fazer uso da mesma função, se usar a data como um string:CONVERT (date, '25/04/2008' , 103) É experimentar para ver... Abraços
-
lmroot, dê uma olhada na função DateDiff (Ref. msdn)
-
Blackleaf, se você está falando de algo como um live-update para seu programa, dê uma olhada neste tópico (ref. DevMedia) - tem duas opções. Abraços
-
Para este tópico não se alongar mais que o necessário, seguem tópicos já existentes sobre esta questão: Como Inserir Uma Skin Numa Aplicação Delphi? (bem explicado) Este pode responder dúvida futura: Glyph Png Abraços
-
opa... demorei escrevento o post e agora vi que você já encontrou o problema. :blush: No geral, quando uma exceção ocorre e o fluxo do programa é desviado para dentro do editor, você pode usar o F7 para avançar na execução apenas um passo e então, utilizar a janela Call Stack para saber que procedimentos foram executados até o erro (pilha das chamadas) e também fazer uso da janela Watch para visualizar valores das variáveis. Abraços
-
darth_ivan, este método é chamado na destruição de qualquer classe. Na verdade, durante a depuração, seria interessante que você pusesse um break-point no begin inícial desta procedure para que ao chegar a ela, você possa acessar a janela Call Stack e verificar os procedimentos anteriormente chamados. Assim, ao ocorrer o erro, você saberia com mais segurança, que procedimento está tentando utilizar este ponteiro inválido. mas, observando seus posts iniciais e a não solução pela abordagem do form, vamos explorar outras situações, pois podemos ter nos desviado do real causador do problema já que "Invalid pointer operation" se refere a operações com ponteiros e parece que você faz mais uso deles do que apenas no blu.free. Primeiramente seria interessante que você conseguisse apontar em que linha o erro ocorre, já que a execução do programa deve ser interrompida neste ponto ou muito próximo; Depois, temos outras questões a avaliar, como: - a_Arg, pode em algum momento ser um endereço de memória inválido? Quando ele é iniciado e quando é finalizado? - em que momento você insere algo nesta suposta lista (a_Arg) e em que momento você o remove? Como está removendo? Haveria a possibilidade de este item sendo buscado ter ficado na lista após sua eliminação? - uma vez que é verificada sua validade, este v_Form é utilizado em algum momento no TagToForm, FormToTag ou no ShowModalDock? - como está a codificação nestes procedimentos TagToForm e FormToTag? Abraços
-
Apenas acrescentando a título de informação... No caso do Firebird é possível criar um índice com uma expressão. Neste exemplo, teríamos um índice criado com a expressão UPPER(nom_cli): CREATE INDEX IDX_NOME_UPPER ON CLIENTE COMPUTED BY (UPPER(nom_cli)); depois na consulta, usando o UPPER e passando o parâmetro já em maiúsculo (p.e. usando a função UpperCase), o banco faz uso do índice acima (IDX_NOME_UPPER): select cod_cli, nom_cli from cliente where UPPER(nom_cli) like :nom_cli order by nom_cli acredito que outros bancos permitam algo semelhante. Abraços
-
Bem lembrada a questão do uso das funções Denis. Se ele estiver usando mesmo o Paradox, ou ele aplica sua sugestão com relação a forma como guarda as strings ou vai ter que usar a função mesmo. Há ainda de se considerar que, algumas vezes, também pode ser relevante observar a questão da acentuação nestas buscas. É bom buscar informações sobre como o banco que você usa se comporta em relação a estes tópicos para que não deixe seu usuário sem a informação correta. Abraços
-
Vivendo&Aprendendo, em suma, TABLE SCAN é a condição em que o banco de dados terá que varrer todos os registros de sua tabela em busca daqueles que satisfazem a condição desejada.Quando existe algum índice que possa ser aproveitado pelo banco de dados, as consultas são feitas sobre ele para retornar o registros sem que seja necessário varrer toda a tabela. Por exemplo, buscar todos os nomes que começam com a letra "M", em uma tabela (Nomes) onde fisicamente a sequência de inclusão foi a seguinte: Pedro Ubirajara Leandro Moacir Maria Cecília Antônio Juvenal Marcia select nome from Nomes where nome like "M%" não existindo um índice para o campo nome, o banco tem que ler todos os registros (09) para lhe retornar apenas os 03 compatíveis com a busca. Havendo um índice, o mesmo estará organizado de modo a fornecer acesso aos nomes na sequência: Antônio Cecília Juvenal Leandro Marcia Maria Moacir Pedro Ubirajara Assim, a busta será primeiramente realizada no índice de modo buscar apenas os 03 registros na tabela Nomes. Mas, no caso específico do uso de like, esta otimização é feita apenas quando você não usa um "%" antes do substring sendo procurada. Ex. %M% ou %M. Com isto, torna-se conveniente uma boa avaliação das consultas realizadas em campos que não possuem índice e conforme relevância, é conveniente criar índices que acelerem estas consultas. Quanto mais registros existirem na tabela, maior será a perda de performance por conta do TABLE SCAN. Observe, entretanto, que isto é válido para os bancos de dados "de verdade". Para as tabelinhas Paradox (*.db), DBase ou Clipper (*.dbf) eu não estou certo de que os drivers façam uso de tal recurso na instrução LIKE. _____________________________ Greed, este componente tem seu próprio esquema de localização pela digitação. Observe que se você for digitando o nome sem fazer intervalo (+/- 1 caracter por segundo), você notará que ele irá posicionando a seleção na lista de acordo com o que foi digitado. Este componente, diferente do TDBComboBox, não tem a caixa de edição - ele monitora o evento keypressed. Voce está utilizando ele para filtra dados apenas? Não configurou as propriedades DataSource e DataField, então? Se sim, neste caso, não coloque um "*" na cláusula SELECT, mas apenas o campo de referência do cliente (codigo) e o nome do cliente. Daí, apenas ao sair do componente (OnExit) você buscaria todos os dados do cliente (uma única vez). Segue uma sugestão de implementação para atender a solicitação inicial: - você precisará declarar uma variável do tipo string na sessão private do seu form (LkpString); - como estou quase certo de que você está usando Paradox (você não confirmou isto no meu outro post), ajuste sua consulta para algo como: select cod_cli, nom_cli from cliente where UPPER(nom_cli) like UPPER(:nom_cli) order by nom_cli observe o detalhe da função UPPER. Isto forçará a comparação sempre com maiúsculas e garante a localização (coisa das limitações do Paradox); - adapte o código abaixo de acordo com o nome de seus componentes. procedure TForm1.FormShow(Sender: TObject); begin // mostra todos as linhas ao apresentar o form QryClientesLkp.ParamByName('customer').AsString := '%'; QryClientesLkp.Open; end; procedure TForm1.DBLookupComboBox1Enter(Sender: TObject); begin // inicializa a substring quando componente recebe o foco LkpString := ''; end; procedure TForm1.DBLookupComboBox1KeyPress(Sender: TObject; var Key: Char); begin case Key of #27 : // Escape, limpa substring mostrando tudo LkpString := ''; #08 : // BackSpace, apaga último caracter da substring Delete(LkpString, Length(LkpString), 1); #32..#255 : // caracteres aceitos - exclui os especiais, abaixo de 32 // este teste "ignora" caracteres após uma // substring não ser encontrada if QryClientesLkp.RecordCount > 0 then LkpString := LkpString +Key; end; if Key in [#27, #08, #32..#255] then begin QryClientesLkp.Close; QryClientesLkp.ParamByName('nom_cli').AsString := LkpString +'%'; QryClientesLkp.Open; end; end;nesta aplicação, não é necessário "limpar" o parâmetro Key quando nós o processamos. Abraços