
Micheus
Veteranos-
Total de itens
3.189 -
Registro em
-
Última visita
Tudo que Micheus postou
-
laudir, seu "problema" está relacionado a forma como você está usando o GROUP BY. Com as informações que você postou, se você quiser que não haja repetição do codigo (CODVEIC) você terá que mudar sua consulta. A inclusão do campo DT_CAD da tabela CADVIAJEM, faz com que seja realizado um agrupamento para o mesmo código a cada data de viajem cadastrado. Então, se você quer mesmo apenas agrupar as informações por veículo, remova a coluna v.DT_CAD da cláusula SELECT e GROUP BY: select f.CODVEIC, f.NR_PLACA, f.MOD_VEIC, f.DT_CAD, SUM(v.KM_SAIDA) TKMS, SUM(v.KM_CHEGADA) TKMC, SUM(v.LT_COMBUSTIVEL) LTCOM FROM CADVIAGEM as v, CADFROTA as f where v.DT_CAD between :Data03 and :Data04 GROUP BY f.CODVEIC,f.NR_PLACA,f.MOD_VEIC,f.DT_CAD lembre-se: no uso do GROUP BY, apenas as colunas com valores iguais são agrupadas em uma linha. Qualquer coluna que mude de valor, irá regar uma nova linha no resultado final. Abraços
-
CAIO.EXE, pelo que é possível verificar no Caché SQL Reference, não há. Ainda não tinha ouvido falar neste banco mas, para tentar dar uma luz, acredito que por analogia a outros bancos você possa implementar uma procedure ou function (não saberia dizer qual você utilizaria - mas imagino que você possa saber) que recebesse e devolvesse as informações através de parâmetros. Normalmente a função REPLACE recebe os parâmetros (<expressão>, <procurar por>, <substituir por>) e para implementá-la precisaríamos alguns equivalentes ao que estamos acostumados a ver em programação: Equivale ao SubString: $EXTRACT(StrValue, StartPos, EndPos) Equivale ao Pos: $FIND(StrValue, SubString) Na implementação da procedure, os parâmetros seriam: - entrada => StrExpression, StrToSearch, StrToReplace - saída => Result (testo retornado) Este seria um esqueleto/exemplo baseado nas informações encontradas no guia de referência: CREATE PROCEDURE REPLACE (IN StrExpression VARCHAR(100), IN StrToSearch VARCHAR(50), IN StrToReplace VARCHAR(50), OUT Result VARCHAR(150)) BEGIN LANGUAGE OBJECTSCRIPT { SET StrPos=$FIND(StrExpression, ToFind) If (StrPos > 0) { SET ResultBegin = $EXTRACT(StrExpression, 1, StrPos -1) SET ResultEnd = $EXTRACT(StrExpression, StrPos +$LEN(StrToSearch) +1) SET Result = ResultStart + StrToReplace + ResultEnd } else { SET Result = StrExpression } } END *Não está claro na documentação se as funções utilizadas são case-sensitive. Supondo que algo assim funcione, os parâmetros VARCHAR devem ter seus tamanhos definidos de modo a acomodar as informações que você pretende passar. Pelo que consta em SQL Data type, parece não haver como um tipo string de tamanho indefinido. No Firebird, por ex., usar esta procedure em uma consulta SQL seria feita do seguinte modo: SELECT Nome, REPLACE(Nome, 'MARIO', 'MARIA').Result FROM TabNOME Abraços
-
FormatFloat depois tirar formatação pra salvar
pergunta respondeu ao flavioavilela de Micheus em Delphi, Kylix
flavioavilela, este código ao teclar ENTER, baseado no que já falamos aqui, está em risco de erro não acha? Em que lugar (linha) é acusado o erro? observei que nesta linha: Params[7].AsFloat:= StrtoFloat(EdtDesconto.Text); você ainda não tratou o campo. obs: use a tag CODE não QUOTE para delimitar o código - Se você puder editar seu post, ele ficará mais claro. Abraços -
Rodrigao, por acaso você formatou a propriedade DisplayFormat do campo adequadamente?Em geral, usar o AsString, deveria retornar o resultado já formatado de acordo com esta propriedade. Abraços
-
isso não estava claro no post anterior... isto ocorre porque você desenhando o texto no grid, deverá se preocupar com todas as variantes que estão envolvidas, como por ex.: alinhamento horizontal, se a linha está selecionada ou não e se estando selecionada... Para ganhar o seu tempo, segue uma rotina prontinha para seu uso e, se necessário, adaptação: procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); // procedimento para cálculo e desenho das células procedure DrawAligned(Text :String; Rect :TRect; Alignment :TAlignment); var TxtRect :TRect; TxtHeight, TxtAlign, XOffset, YOffset :Integer; RectWidth :integer; begin with (Sender as TDBGrid) do begin // desenhando o retângulo (célula) Canvas.Brush.Style := bsSolid; Canvas.FillRect(Rect); with Rect do begin Canvas.MoveTo(Right +1, Top -1); Canvas.LineTo(Right +1, Bottom +1); Canvas.LineTo(Left -1, Bottom +1); end; // preparação do alinhamento RectWidth := Rect.Right -Rect.Left +1; case Alignment of taLeftJustify: begin TxtAlign := DT_LEFT; XOffset := Rect.Left +2; end; taCenter : begin TxtAlign := DT_CENTER; XOffset := Rect.Left +(RectWidth -Canvas.TextWidth(Text)) div 2; end; taRightJustify: begin TxtAlign := DT_RIGHT; XOffset := Rect.Left +(RectWidth -Canvas.TextWidth(Text)) -4; end; end; // desenhando o texto na célula Canvas.Brush.Style := bsClear; // na linha abaixo, é testado se o campo é um um campo tipo memorando, para o qual // usamos outro método de desenho que viabiliza o desenho com quebra de linha if Column.Field.FieldType = ftMemo then begin TxtRect := Rect; DrawText(Canvas.Handle, PChar(Text), Length(Text), Rect, TxtAlign or DT_WORDBREAK); end else begin // YOffset provoca a centralização do texto na Vertical // se não quizer este alinhamento, basta suprimí-lo nas // duas próximas linhas YOffset := ((Rect.Bottom -Rect.Top) -Canvas.TextHeight('Mj')) div 2; Canvas.TextRect(Rect, XOffset, Rect.Top +YOffset, Text); end; // desenha retângulo pontilhado se a coluna estiver selecionada // e não estiver habilitada a opção de linha selecionada if (gdSelected in State) and not (dgRowSelect in Options) then Canvas.DrawFocusRect(Rect); end; end; begin DrawAligned(Column.Field.AsString, Rect, Column.Alignment); end; O DBGrid deve ter sua propriedade DefaultDrawing = False, e não deve ser chamado o método DefaultDrawColumnCell do DBGrid1. Abraços
-
Luiz F, para que os colegas possam lhe ajudar de forma objetiva, você também tem que ser objetivo e claro no seu questionamento. ;) Observe seu post inicial: Veja que o colega Jhonas, teria praticamente respondido ao seu questionamento: e você acrescenta, precisar contar os diretórios... já neste último post, você volta a mudar o foco do problema, acrescentando que quer contar os arquivos também: Dê uma olhada na dica Pesquisa em diretório e subdiretórios do colega Thales. Implemente, execute e entenda ele e você vai facilmente conseguir ajustá-lo a sua necessidade. Abraços
-
FormatFloat depois tirar formatação pra salvar
pergunta respondeu ao flavioavilela de Micheus em Delphi, Kylix
flavioavilela, por gentileza poste a parte do código onde você faz a atribuição antes de gravar no banco e a mensagem original (em inglês). -
Recife, fica uma dica: instale um destes drivers de impressão PDF gratuitos (eu gosto muito do doPDF, mas existem vários outros) - eles quebram o maior galho - é o que uso para não gastar tinta e papel quando estou testando resultados deste tipo. Abraços
-
Rodrigao, você deve estar fazendo isto no evento OnDrawColumnCell (ou outro similar), seria interessante que você postasse todo o código como lá está. De qualquer modo, a solução passa por testar se o campo sendo desenhado é o campo memo. Caso não seja, segue com o procedimento default de pintura. Abraços
-
FormatFloat depois tirar formatação pra salvar
pergunta respondeu ao flavioavilela de Micheus em Delphi, Kylix
flavioavilela, voce não pode simplesmente retirar a formatação. Voce tem que ajustá-la! Se você chegou a ler os posts que citei como referência no seu outro tópico, você deveria ter percebido que temos a questão a inversão dos separadores de milhar e decimais e, provavelmente, você teria observado que para fazer a conversão correta - neste seu exemplo - teria que tentar converter o texto no formato 5.0 e não 5,0. Assim, o sensato seria usar as funções para realizar esta substituição não supressão. StringReplace(Edit1.text, ',', '.', [rfReplaceAll]) - isto troca a vírgula por ponto. O que resolve um problema, não outro. Caso você tenha um valor 1.052,50 e use a função como acima, o resultado será: 1.052.50; o que também não poderá ser corretamente convertido, porque há dois separadores de decimais e evidentemente isto é impossível. Então, já sabemos que será necessário remover qualquer outra pontuação que não seja a de decimal - só ela deverá existir antes da conversão. Com isto em mente, começamos por tentar remover qualquer caracter ponto (.) que exista na sua string, já que estará denotando milhares (não decimal): Edit1.text := StringReplace(Edit1.text, '.','', [rfReplaceAll]) - isto resulta em um texto numérico que não tem separador de milhar - o exemplo ficaria: 1052,50 e terminamos por tentar trocar o separador de decimal do formato texto (a vírgula) para delimitador de decimal na notação numérica - padrão americano: Edit1.text := StringReplace(Edit1.text, ',', '.', [rfReplaceAll]) - isto resulta em um texto numérico onde o separador de decimal passa a ser o ponto - o exemplo agora passaria a 1052.50, que será corretamente convertido. Agora é só converter: StrToFloat(Edit1.text); Para ficar 100%, não deveríamos utilizar fixo os caracteres ',' e '.' nas funções, porque os delimitadores são dependentes da linguagem, mas como acredito que a maioria não tem programa exportado para outros países, não vou entrar no mérito da coisa. Abraços -
Recife, isto é relativamente fácil:- declare uma variável booleana para controlar quando zebrar (no preview) e quando não (na impressão); - inicialize ela com com false (antes de chamar o método Preview ou PreviewModal do quick); - no evento BeforePrint você inverte seu conteúdo, utilizando um not; - no evento AfterPrint você atribui a ela o valor True; - no evento BeforePrint da banda detalhe (ou a que desejar), você deve testar se está zebrando antes de executar o teste que irá trocar a cor de fundo para obter este efeito. O porque deste procedimento estranho: O evento BeforePrint ocorre antes da impressão na tela (Preview) e na impressora (Print). Então, quando você chama o Preview, a variável que está falsa é passada para true no evento BeforePrint e o relatório aparecerá zebrado na tela. Concluida a montagem do relatório pelo quick, o evento AfterPrint ocorre e a variável será marcada como true. Assim, quando é acionada a impressão, o evento BeforePrint ocorre e estando a variável com true, passará a ter o valor False, resultando que na impressão no papel não haja zebra. O fato de forçarmos a variável para True (e não not <variavel>) no AfterPrint deve-se ao fato de que o usuário pode resolver imprimir novamente o relatório, sem ter saido do preview e, assim, não term erro - a impressão continua não sendo zebrada. Sugestão, no relatório: type TForm1 = class(...) ... private Zebra :Boolean; ... public Zebrar :Boolean; ... end; .... procedure TForm1.QRBand1BeforePrint(Sender: TQRCustomBand; var PrintBand: Boolean); begin if Zebrar then begin if Zebra then Sender.Color := clRed else Sender.Color := clWhite; Zebra := not Zebra; end; end; procedure TForm1.QuickRep1BeforePrint(Sender: TCustomQuickRep; var PrintReport: Boolean); begin Zebrar := not Zebrar; end; procedure TForm1.QuickRep1AfterPrint(Sender: TObject); begin Zebrar := True; end; preparando para chamada do relatório: ... Form1 := TForm1.Create(Self); try ... Form1.Zebrar := False; Form1.QuickRep1.Preview; finally Form1.Release; end; ... end; Abraços
-
exatamente, mas quanto mais próximo do valor exato melhor.A vantagem a impressão em modo gráfico é a precisão: se você quer imprimir algo a 8,55cm da margem, você consegue! Sendo impressão de texto apenas (nada de imagens), seria possível até um tempo atrás utilizar o esquema do Writeln para LPT1 (que resulta em uma impressão muito rápida), entretanto, quando você se depara com uma impressora plugada na porta USB, vira problema e sinceramente eu não saberia lhe apontar um modo de contornar isto - espero aqui que outro colega possa se pronunciar a respeito para lhe ajudar neste problema. A título de conhecimento, você pode dar uma olhada no final deste artigo para saber como seria este processo. Há também a opção de outros geradores de relatórios em modo gráfico, mas é provável que você caia no mesmo problema do quick. Abraços
-
(Resolvido) campo numeric sqlserver 2005
pergunta respondeu ao flavioavilela de Micheus em Delphi, Kylix
flavioavilela, você está no caminho certo, apenas está esquecendo o principal: atribuir o resultado da função FormatFloat de volta ao edit! Corrigindo... procedure TFrmVendas_Balcao.EdtValor_VendaExit(Sender: TObject); var valor: double; begin valor:= StrToFloat(EdtValor_Venda.Text); EdtValor_Venda.Text := FormatFloat('#,##0.00', valor); end; Se você for usar este tipo de formatação em vários edits, então prefira torná-lo "genérico" para poder apenas atribuir este evento ao evento OnExit dos demais edits: procedure TFrmVendas_Balcao.EdtValor_VendaExit(Sender: TObject); var valor: double; begin valor:= StrToFloat(TEdit(Sender).Text); TEdit(Sender).Text := FormatFloat('#,##0.00', valor); end; mas já lhe advirto que você deverá tratar erros, como text nulo ou com letras... ... e texto contendo o "." como separador de milhar. Deixo como sugestão: procedure TFrmVendas_Balcao.EdtValor_VendaExit(Sender: TObject); var Value :Double; begin TEdit(Sender).Text := Trim(TEdit(Sender).Text); // retira qualquer espaço desnecessário // caso você aceite valor nulo, tire o comentário da linha a seguir: // if TEdit(Sender).Text <> '' then // ou, caso o valor nulo deva ser entendido como zero, retire o comentário da linha a seguir // if TEdit(Sender).Text = '' then // TEdit(Sender).Text := '0'; try Value := StrToFloat(StringReplace(TEdit(Sender).Text, '.', '', [rfReplaceAll])); TEdit(Sender).Text := FormatFloat('#,##0.00', Value); // reformatamos o edit except on E:Exception do begin E.Message := Format('"%s" não é um valor válido!', [TEdit(Sender).Text]); TEdit(Sender).SetFocus; raise; end; end; end; Veja estes tópicos relacionados ao assunto deste tópico: - Formatar Edits - Formatar Variável Real - Dividindo no Delphi - Como faço para testar se um campo string é decimal? Abraços -
maneju, você deve cria seu próprio "protocolo" de envio. Algo como enviar primeiro o nome do arquivo e depois enviar os dados. Abraços
-
Primeiramente, vamos visualizar melhor este amontuado de linhas...: Function Mensagem(Msg,Bt1,Bt2:String):Boolean; var I,K:Integer; F:TForm; begin K:=0; F:= createmessagedialog(Msg,mtconfirmation,[mbyes,mbno]); try for i:=0 to f.componentCount -1 do if f.components[i] is tbutton then with tbutton(f.components[i]) do case modalresult of mryes: Caption := Bt1; mrno: Caption := Bt2; end; f.caption := 'Mensagem do Sistema'; K:=f.showmodal; finally if K = mryes then Result:=True else Result:=False; f.free; end; end; O que esta função faz é usar CreateMessageDialog para criar um form aos moldes das caixas de diálogos padrão, mas que viabiliza alterar o conteúdo dos componentes contidos nele (neste caso, o caption dos botões e o texto da mensagem). Ao ser mostrado o form e clicado em um dos botões o resultado de ShowModal será sempre mrYes ou mrNo. A resposta positiva é correspondente ao texto passado em Bt1, de modo que a função retorna True caso o Bt1 seja pressionado ou False se Bt2. Para usar: if Mensagem('Confirma exclusão do cliente?', 'Confirmo', 'Não tenho certeza') then begin // exclui o cliente.... end else ShowMessage('Voce ficou na dúvida e o cliente não foi excluído!');parece que a finalidade básica desta função é a de evitar que sejam apresentadas as caixas de diálogo com o texto em inglês (é o que penso). Abraços
-
(Resolvido) campo numeric sqlserver 2005
pergunta respondeu ao flavioavilela de Micheus em Delphi, Kylix
flavioavilela, se você está usando DBEdit's para a edição (ou mesmo edição no DBGrid) basta que você formate a propriedade DisplayFormat do field (campo em seu dataset). Para saber como usar a formatação corretamente (as opções), você pode selecionar esta propriedade na janela Object Inspector e teclar F1. Para adiantar, quando você quer manter a quantidade de casas fixas você deve por "0" na posição desejada. Ex.: 5 => 0.0 => 5,0 3 => 0.00 => 3,00 1240 => #,##0.00 => 1.240,00 (o uso dos #, possibilita a formatação de milhar, do contrário o resultado seria 1240,00) Observando que na máscara você usa a pontuação no formato americano (ponto como separador decimal). Se for acrescentar a moeda, basta preceder a máscara com ela: R$ #,##0.00 Abraços -
Programador(Iniciante), este componente é pago e você não vai encontrar ele por aqui (é proibido :mellow:). Se quiser adquirir uma versão quente, no site oficial (Link Rank), você encontra suporte até o Delphi 2009. ;) Abraços
-
(Resolvido) Dúvidas na função Autofit
pergunta respondeu ao Rodrigo Flores de Micheus em Delphi, Kylix
Rodrigo Flores, em um documento no Excel, com esta situação que você postou (celulas mescladas + autofit), o autofit não funciona. Como os recursos que usamos no Delphi, são provenientes do próprio Excel, então não haverá como fazê-lo (pelo menos até o Office 2000) - o jeito será ajustar a altura da célula via código (propriedade RowHeight). Abraços -
flavioavilela, já que isto está ocorrendo, acredito que se você observar bem, deverá notar que da primeira até esta última supostamente correta, deve ter havido pequena mudança de posição. Digamos que isto é "normal", devido ao fato de a impressão via quickreport ser realizada em modo gráfico e não caracter (aquele linha a linha, baseado no espaçamento escolhido). Não tenho detalhes das dimensões da folha de etiqueta em uso, mas o que você vai precisar fazer é tentar ajustar a altura da banda detalhe (imagino que você apenas a use) para conter a altura o mais próxima possível do valor resultante da divisão da altura total das etiquetas pela quantidade das mesmas. Por exemplo, eu tenho etiquetas em formulário contínuo em uma folha de 12" de altura (30,48cm), com 12 etiquetas, sendo que existe um pequeno intervalo entre elas de 2mm. Assim, se for tratar as dimensões em polegadas, a distância do início de uma etiqueta para outra, seria de exatamente 1", logo definiria a altura da minha banda detalhe com 1 polegada. Mas, se estiver desenhando no quickreport usando mm(QuickRep->Units), eu deveria ajustar em 25,4mm e teria que fazer isto informando esta dimensão diretamente na propriedade Size->Height - não via o uso do mouse. Assim, se você não a dimensão exata do "passo", procure calculá-la (caso não possua esta informação) e ajuste diretamente na propriedade, pois a pequena diferença de 0,15mm (imperceptível sozinha), representa uma variação de 2,25mm na décima sexta etiqueta. Confira se este não está sendo seu problema e esteja certo de ter também ajustado o tamanho da folha no quickreport. Abraços
-
fajo, veja como fica melhor a visualização do código utilizando a tag ..[/ CODE]. Para apontar a linha com problema utilize algo como: <<< AQUI Quanto a sua dúvida não dá para dizer se faz sentido ou não, simplesmente porque você não negritou a linha. ;) Abraços
-
pgregoreki, vamos seguir com idéias... ou melhor, perguntas... - Voce quer criar esta tabela no código? (estou tentando fazer uma tabela...) - Voce já sabe que campos terá esta tabela? Sendo você iniciante e não tendo especificado, imagino que você vá criar tabelas Paradox. Neste caso, voce poderia criar a tabela usando o Database Desktop (ferramenta que acompanha o Delphi) - De que forma esta matriz servirá de fonte de dados: Voce inicializará a matriz no código utilizando valores aleatórios ou haverá uma tela de entrada de dados de onde você moverá os valores digitados para o vetor e, depois, deste para a tabela? Abraços
-
eu me referia ao fato da reimportação dos dados da view, o que poderia resultar nos dados alterados em sua tabela serem substituídos pelos existentes na view. Mas, como você diz que já está pensando sobre estas questões de conferência dos dados e tal... Também, convém lembrar que o método que sugeri (select into), irá reescrever a sua tabela, logo, você terá mesmo que criar a estrutura da tabela e fazer algum tipo de verificação antes de importar os dados da view para ela. Xafam, apenas para ficarem claras as coisas. Uma coisa é criar a tabela no Delphi (ferramenta de programação - seria via código) e outra coisa é utilizar uma das ferramentas que acompanham o Delphi - como é o caso SQL Explorer - com a qual você poderia criar a tabela. Meu conhecimento em SQL Server é um pouco limitado (fazem 10anos que mexi com ele), mas vejo uma forma simples de criar a tabela vazia usando justamente o que passei antes. A diferença seria no fato de você adicionar uma condição (na cláusula where) que não retornasse algo. Para exemplificar, vou supor que nesta sua view exista um campo chamado CODIGO que um valor que sabemos não dever existir seria negativo: select * into TAB_FROM_VIEW18 from VIEW18 where CODIGO = -1 Atualmente tenho trabalhado com o FireBird e esta sintaxe acima não funcionaria. Para este caso, eu teria que usar: insert into TAB_FROM_VIEW18 select * from VIEW18 where CODIGO = -1o qual funcionaria perfeitamente. Assim, você teria duas opções a testar na sua ferramenta de acesso ao banco (front-end) - se não me engano, o SQL Explorer permita execução de SQL's. Dúvidas específicas do banco de dados (gerenciamento e SQL), você pode tirar na sessão Banco de Dados -> SQL Server Abraços
-
claudyo, você está dizendo que a query qryCadProd, contém uma instrução "select * ..." em design-time e depois você a reutiliza atribuindo? é isto?Dependendo de que modo e quando você esteja usando a query com este select, pode até não haver problema, porque quando você atribui algo a sql.Text é como se o componente fosse reiniciado com os novos campos, parametros, ... (dependendo o caso) Se for, porque você está usando deste modo então? você não está mesmo usando componentes data-awares (tipo TDBEdit, TDBComboBox,...)?
-
biakeffer, tem também um componente freeware que funciona exatamente como aquelas janelinhas do messenger, inclusive empilhando elas caso ainda haja uma aberta. Chama-se TMSNPopUp. Download neste neste link Após você instalá-lo, ele estará disponível na paleta Custom criada por ele. Eu preferi mudar este local e, antes de instalá-lo, alterei o destino para a paleta Additional (já temos paletas demais). Para mostra uma mensagem, basta utilizar a propriedade Text. A apresentação da janelinha é feita através do método ShowPopUp. Um exemplo: procedure TForm1.BtnMsgClick(Sender :TObject); begin MSNPopUp1.Text := 'Mensagem apresentada na janela tipo lembretes do messenger no canto direito'; MSNPopUp1.ShowPopUp; end; Há várias propriedades que podem ser utilizadas, como largura, altura, timeout (tempo antes que se feche), fundo gradiente e por aí vai. é só explorar. Basta apenas um componente, para que vários lembretes possam ser abertos. Neste exemplo que postei, cada vez que você pressiona o botão, uma nova janela vai aparecendo empilhada na anterior. Abraços
-
Gabriel Cabral, qual o tipo de dados do campo PROCOD nesta sua tabela? é algo bem estranho, já que o código aparentemente é o mesmo em ambos os locais. O código está mesmo sendo gravado com o zeros na tabela, ou você observou isto durante a depuração?