Ir para conteúdo
Fórum Script Brasil

Micheus

Veteranos
  • Total de itens

    3.189
  • Registro em

  • Última visita

Tudo que Micheus postou

  1. Alex Freitas, o problema é que você não está usando a sintax correta. Para definir um parâmetro na instrução SQL o ":" tem que estar junto ao nome do parâmetro: ... Where DataCadastro >= :PInicio and DataCadastro <= :PFinal and Clientes.Corretor = ... Abraços
  2. biakeffer, você pode siguir os passos que o colega Jhonas descreve neste post. Abraços
  3. Micheus

    quickreport

    lucy4000, neste caso, aparentemente o mais apropriado seria utilizar uma banda do tipo rbSummary. Este tipo de banda é impresso logo ao final do relatório - Depois de todo ele impresso. Já a banda rbPageFooter é impressa ao final de toda a página. parece-me que você está se referindo a imprimir cada grupo de lançamento em uma nova página. Se for isto, basta que você habilite a propriedade ForceNewPage no seu TQRGroup. Se não for isto, o controle por linhas tem um requisito: você deve saber na banda anterior, quantas vezes a próxima será impressa, ou seja, na banda group, quantos registros serão impressos na detalhe. Isto possibilita calcular a área da página que estará sendo ocupada e conforme o caso, podemos foçar uma quebra. Quanto a questão da impressão do transporte do saldo para a próxima página, acredito que você possa facilmente aproveitar a idéia que propus neste outro tópico:extrato bancario quickreport / clientdataset (ref. DevMedia) Abraços
  4. robinhocne, o problema não tem qualquer relação com o RxMemoryData, bem como você não deve ter muitas dificuldades com ele, porque basicamente é um dataset como o TTable. A única diferença é que ele trabalha com os registros na memória e não no disco. O método EmptyTable, como o nome diz, limpa a tabela e está presente em outros datasets do tipo table. E é por esta sua característica que os registros do seu RXMemoryData estão sendo "zerados". Abraços
  5. Micheus

    Comparar 2 Listbox

    é só se registrar. ;) Visitante Feliz, você pode fazer isto através do método IndexOf da propriedade Items do TListBox (que é um TStrings). Voce "varre" a primeira lista procurando itens na segunda lista: procedure TForm1.BtnCompara(Sender :TObject); var Idx :Integer; begin for Idx := 0 to ListBox1.Items.Count -1 do begin if ListBox2.Items.IndexOf(ListBox1.Items[Idx]) >=0 then begin // achou texto end else begin // não encontrou end; end; end; t+
  6. Erso, dê uma olhada neste artigo "TYPE CURSOR - Retornar um Resultset numa Procedure - Oracle". Não se trata do mesmo componente que você usa, mas pode estar acontecendo algo parecido com os problemas detectados e contornados pelo autor. Talvez fosse conveniente você postar em outros forums esta questão, já que por aqui o uso de Oracle (ainda com packages) não é muito comum. Boa sorte.
  7. Micheus

    quickreport

    luciana, você poderia fazer isto, pelo menos, de duas maneiras. Em ambos você precisará adicionar ao seu QuickRep um TQRBand do tipo rbPageFooter:1) Adiconar um TQRLabel para a footer band e utiliza uma variável global ao form, inicializando-a no evento BeforePrint do QuickRep. A cada impressão da banda que imprime o valor a ser somado, no evento AfterPrint, você soma a esta variável o valor em questão. No evento BeforePrint da footer band, você formata o valor e o atribui ao qrlabel. Caso a totalização em cada página impressa deva ser reiniciada, neste mesmo evento você inicializará a variável global. 2) Adicionar um TQRExpr para a footer band e definir em sua propriedade Expression o SUM do campo desejado. Caso a totalização em cada página impressa deva ser reiniciada, você deverá definir como True a propriedade ResetAfterPrint do qrexpr. Eu diria que isto poderia ser meio complicado de gerenciar. Imagine que em um determinado relatório, um registro possa ocupar mais que uma página... Como é que isso iria funcionar?! Mas é possível sim! Qual a estrutura de bandas de seu relatório e que bandas você quer manter agrupadas? t+
  8. robinhocne, vamos melhorar a identação do seu código e talvez você perceba porque isto ocorre: if ( not tblcheques.Active ) then tblcheques.Open else tblcheques.EmptyTable; with tblcheques do ... Se não sacou, observe o que ocorre no seu código quando a tabela tblcheques está ativa. ;) Abraços
  9. Micheus

    editando um DBGrid

    NAHIM, da forma como você coloca, talvez você pudesse fazer da seguinte forma: - Use um table para pedidos ligado ao DBGrid (dataset principal, onde será feita a edição); - Precisaremos de um dataset do tipo query para consultar cada tabela referenciada (no seu exemplo seria a cliente) onde, em cada uma, deverá ser incluso na cláusula SELECT o campo de referência e o campo de descrição (p.e., Nome, Razao_Social, ...); - Agora, no dataset principal, faremos a referência a estes dataset's de consulta (lookup); Para isso, em design-time, acesse a lista de campos do dataset principal (duplo click no componente); Agora, adicione um novo campo (botão direito -> New field...); Em Name, vamos definir NomeCliente, seguido por Type igual a String e Size conforme definido o referido campo na sua tabela de clientes; A seguir, definimos o tipo deste campo como sendo Lookup; Mais abaixo, fazemos a vinculação à consulta definindo KeyFields com o campo de referência à tabela clientes (codcliente), DataSet apontando para a consulta à clientes (a query), em Lookup Keys selecionamos o campo referenciado (provavelmente, também codcliente) e em Result Field selecionamos o campo a ser apresentado no DBGrid (nome ou razao, ...); - O procedimento anterior deverá ser repetido para todos os campos do pedido que venham a ser obtidos a partir de outras tabelas (lookups); - Ao DBGrid, são então adicionados apenas os campos a serem digitados e os que foram criados como Lookup (não os "nativos"); Como resultado, estes tipos de campos são mostrados no DBGrid na forma de uma caixa de lista. Obs: 1) Antes de o dataset principal ser aberto, as consultas lookup's já devem estar abertas; 2) Se alguma alteração for realizada nas tabelas utilizadas como lookup neste DBGrid, as respectivas consultas tem que ser atualizadas (close e open); 3) Como você mencionou Oracle e uma consulta simples, você poderia sim utilizar o TQuery com a propriedade RequestLive=True. Dou 99% de chances de funcionar nestas condições. :D Tente por este caminho e veja se você chega onde quer. Abraços
  10. robinhocne, no seu código OnDrawCell você ajusta ele como abaixo: ... if odd(DtsCarChe.DataSet.RecNo) then DbgCarChe.Canvas.Brush.Color:= clmenubar else DbgCarChe.Canvas.Brush.Color:= clCream; TDbGrid(Sender).Canvas.font.Color:= clBlack; if gdSelected in State then begin DbgCarChe.Canvas.Brush.Color := clSkyBlue; DbgCarChe.Canvas.Font.Style := DbgCarChe.Canvas.Font.Style + [fsBold]; if clic2 = TRUE then DbgCarChe.Canvas.Brush.Color := clRed; end else DbgCarChe.Canvas.Font.Style := DbgCarChe.Canvas.Font.Style - [fsBold]; TDbGrid(Sender).DefaultDrawDataCell(Rect, TDbGrid(Sender).columns[datacol].field, State); end; repare que removemos o "clic2 := FALSE;" e acrescentamos o else conforme eu sugeri. Coloque um componente TDataSource neste seu form (caso você esteja usando um datamodule - você não informou), defina a propriedade DataSet para apontar para o mesmo dataset que você já ligou ao DBGrid e no eveno OnDataChange coloque a linha que removemos acima: procedure TForm1.DataSourceDataChange(Sender :Tobject.... begin clic2 := FALSE; end; Teste e veja se funciona a contento. braços
  11. eu detesto quando isto acontece... :angry: Mas não é o seu caso. Parece mesmo é que você não entendeu direito o que eu tentei explicar. Preste atenção ao que você postou do seu código: if odd(DtsCarChe.DataSet.RecNo) then DbgCarChe.Canvas.Brush.Color:= clmenubar else DbgCarChe.Canvas.Brush.Color:= clCream; TDbGrid(Sender).Canvas.font.Color:= clBlack; if gdSelected in State then begin DbgCarChe.Canvas.Brush.Color := clSkyBlue; DbgCarChe.Canvas.Font.Style := DbgCarChe.Canvas.Font.Style + [fsBold]; if clic2 = TRUE then begin DbgCarChe.Canvas.Brush.Color := clRed; clic2 := FALSE; end; end; TDbGrid(Sender).DefaultDrawDataCell(Rect, TDbGrid(Sender).columns[datacol].field, State); Quantas vezes você acha que este evento deverá ocorrer? Inúmeras!!! Uma vez para cada coluna e linha que esteja visível no DBGrid - lembre-se que nos parâmetros estão inclusos ARow (linha) e ACol (coluna). ;) Então, quando vai ser desenhada a linha selecionada (e a atualização evidentemente começará pela 1ª coluna) você está mudando as informações conforme desejado - até aí tudo bem. Mas, veja o que você está fazendo com a variável de controle do duplo click (clic2) nesta condição... Será que ao ser executado o evento para a pintura da 2ª coluna, ele vai conseguir passar pelo if que muda o fundo para clRed?! Será que captou porque foi que eu disse "o negócio aperta é como saber em que momento esta variável deverá ser sinalizada como falsa"? Justamente porque não poderia estar onde você colocou!!!! Leia novamente meu post e veja onde você poderá fazer isto e caso seu DataSource esteja em um DataModule, não se preocupe - simplesmente adicione um novinho em folha no form onde está o DBGrid apenas para usar este recurso. É..., você terá dois DataSources ligados ao mesmo dataset - isto não é problema. Outra coisa: observei todas as linha estão destacadas em negrito? Ao menos é como parece na imagem. Você deve lembrar de retirar o negrito quando não for a condição que você está usando para por o negrito: ... if gdSelected in State then begin ... end else DbgCarChe.Canvas.Font.Style := DbgCarChe.Canvas.Font.Style - [fsBold]; Abraços
  12. Micheus

    editando um DBGrid

    nahim, para editar os registros em um DBGrid, o dataset deve permitir isto. Em geral, apenas tendo um dataset do tipo table ligado ao DBGrid é que você conseguirá isto ou, usando um componente tipo query, quando habilitando a propriedade RequestLive=True, sendo que não há garantia de que funcionará - tornando o resultado ReadOnly. Isto pode ocorrer caso a consulta SQL não respeite alguns requerimentos para que possa ser aplicado pelo BDE, com não ter join's, order by, funções de agregação (sum, avg, ...), bem como o banco de dados sendo utilizado (os Server's, diferentemente dos tipos similares ao Paradox, podem resolver as questões relacionadas a join) Como você comentou que tem um select com mais que uma tabela (isto é um join) e não indicou o banco utilizado, já há uma grande chance de você não conseguir fazer o que quer. Na pior das hipóteses, você pode tentar e ver o que acontece. ;) Abraços alguma referência: - TQuery - SQL In Delphi (About.com) - DataBase Application Developper's Guide (ver capítulo 5 - pag. 120, sobre TQuery) - TClientDatasets - Gary's Delphi Client Dataset Based Application (ler: Problems with TClientDatasets and their solutions) Abraços
  13. robinhocne, o procedimento passa por este método mesmo. A questão, é como saber que a linha a ser modificada a fonte é a linha em que foi dado o duplo click. Voce pode partir do princípio de que a linha do duplo click é a linha correntemente selecionada. Isto você pode verificar através se gdSelected está presente no parâmetro State: if gdSelected in State then Entretanto ainda assim, deverá utilizar algum meio (uma variável global, boolean) para saber quando foi dado o duplo click no DBGrid, sinalizando ela quando o evento OnDblClick ocorrer e daí você força um Repaint do DBGrid. Até aí deve estar fácil... O negócio aperta é como saber em que momento esta variável deverá ser sinalizada como falsa - o que deverá ocorrer quando a linha selecionada no DBGrid mudar (é o que penso). Supondo que seja mesmo esta a situação, acredito que você poderá utilizar o evento OnDataChange do componente DataSource ligado ao DBGrid. É testar para ver no que dá. OBS: Outra coisar, passe a utilizar o evento OnDrawColumnCell para a manipulação do visual do DBGrid. Se você olhar no help sobre OnDrawDataCell, você vai encontrar este comentário: Do not write an OnDrawDataCell event handler. OnDrawDataCell is obsolete and included for backward compatibility. Instead, write an OnDrawColumnCell event handler. traduzindo, caso já tenha visto e não entendido: Não escreva um manipulador de eventos OnDrawDataCell. OnDrawDataCell é obsoleto e incluído para compatibilidade. Ao invés disto, escreva um manipulador de eventos OnDrawColumnCell
  14. Joao Paulo, em última instância, lembre-se que você pode tentar utilizar o Suporte ao Desenvolvedor da Bematech. t+
  15. Micheus

    Tabcontrol

    gibagiraia, sê uma olhada neste tópico: Comando Para Criar Componentes. No post#4 tem uma dica referente ao TabSheet que são as "abas" do PageControl. t+
  16. Micheus

    Biblioteca Jedi

    pesquisando mais um pouquinho no Google: "biblioteca jedi" = resultados o primeiro link é um hotlist de links ref. à programação Delphi (muito interessante) e lá pelo meio aparece JEDI Visual Component Library - JVCL (que é o que lhe interessa ;)) Abraços
  17. na possibilidade de algum destes campos ser nulo no banco, é mais prudente utilizar o método AsFloat para forçar o tipo retornado e em caso de nulo, será retornado 0: dmBDPregao.Percentual.AsFloat:= ((dmBDPregao.fltfldPropostaValPropostoFornecedor.AsFloat - Valor_Minimo) / Valor_Minimo)*100; Abraços
  18. Gabriel Cabral, muitíssimo!!! Já estava mais ou menos imaginando que você estivesse movendo os campos na mão, mas vendo como você está implementando, e com a mensagem de erro original, fica mais fácil - dá para sair do campo da suposição. ;) Este método que você está utilizando é pedreira mesmo - tem que estar bastante atento para as características das atribuições e também aos valores passados às funções. No caso citado, os erros estão ocorrendo nas funções de conversão de tipos - nem chegou à execução da query. Quando você usa um TMaskEdit (com alguma máscara setada), ao deixá-lo em brando você estárá lendo em Text a própria máscara como neste caso você deve ter usado a máscara similar a '99/99/99;1;_', a string retornada por Text será mesmo ' / / ' e que não poderá ser convertida pela função StrToDate sem gerar erro. Do mesmo modo, tentar converter uma string nula, retornada pela propriedade Text de um TEdit, utilizando a função StrToFloat irá gerar erro. Uma string inválida, como 2.540,50 também irá gerar erro, porque para executar a função com sucesso, o número deveria ter apenas o ponto decimal como separador de dezenas: 2540.50. Você deverá de algum modo se preocupar com a validação dos campos antes de tentar passar eles para a função. Dê uma olhada em alguns posts relacionados a estes assuntos: Erro de conversão em função, EConvertError with message (veja a função ENumero que o colega robinhocne implementou - pode lhe servir) Como faço para testar se um campo string é decimal? Problema Com Formato De Número, ajuda!!! Verificando conteúdo, Verificando data digitada no maskedit Duvida Em Máscara Para R$ E Tel: tem muitos outros... Dica: Poupe os dedos ao criar suas instruções SQL. Use o recurso de Alias (apelido) ou, quando não for necessário, não informe o nome da tabela junto ao campo. Por ex., neste trecho: dm.Query1.SQL.Add('INSERT INTO ESTAPRO(ESTAPRO.PROCOD,ESTAPRO.PROTIP,'); dm.Query1.SQL.Add('ESTAPRO.PROCAD,ESTAPRO.PRODES,ESTAPRO.PROQTD,'); dm.Query1.SQL.Add('ESTAPRO.PROUND,ESTAPRO.PROICM,ESTAPRO.PROMIN,'); você pode omitir o nome da tabela junto ao campo, porque seu SQL trata exclusivamente de uma única tabela dm.Query1.SQL.Add('INSERT INTO ESTAPRO(PROCOD, PROTIP,'); dm.Query1.SQL.Add('PROCAD, PRODES, PROQTD,'); dm.Query1.SQL.Add('PROUND, PROICM, PROMIN,'); e quando houvessem mais tabelas envolvidas, poderia usar o alias como em: dm.Query1.SQL.Add('INSERT INTO ESTAPRO E (E.PROCOD, E.PROTIP,'); dm.Query1.SQL.Add('E .PROCAD, E.PRODES, E.PROQTD,'); dm.Query1.SQL.Add('E.PROUND, E.PROICM, E.PROMIN,'); Abraços
  19. sllc, você copiou a DLL errada. gds32.dll é o client para Interbase. (acho que você deu uma viajada ;)) Você precisa copiar a dll referente a versão que você utilizou no seu componente de conexão Zeos, que pode ser uma destas que estão na pasta ..Zeosdbo\lib\postgresql libpq73.dll, libpq74.dll, libpq80.dll e libpq81.dll Abraços
  20. Vivendo&Aprendendo, esta questão, você determina usando Order By no seu SQL ou ser estiver usando um dataset tipo table, através de um índice que tenha este campo no início. Correto sllc, e nem seria necessário utilizar um TQRDBText - poderia ser um simples TQRLabel, onde o valor do campo (como você sugeriu) seria movido para este label após testar o campo que indica o tipo de pessoa. Também daria para ser feito usando um TQRExpr, utilizando um if com o campo do tipo de pesso como argumento de validação e para cada opção, o respectivo campo. Algo como: IF(TipoPessoa='F', Nome, Fantasia) Se interessar, use a dica deste post para saber como usar o wizard da propriedade Expression. Abraços
  21. Ferizinha, será necessário fazer uso da função GetPrinter da API do Windows (ver Win32 Programmer's Reference) utilizando o nível 2 para obtermos a estrutura Printer_Info_2 que contém a informação desejada: procedure TForm1.FormCreate(Sender: TObject); begin // adiciona o nome das impressoras em um listbox ListBox1.Items.Assign(Printer.Printers); end; // ex. de botão para obter informações da impressora selecionada na lista procedure TForm1.PrnInfoClick(Sender: TObject); var PrnHandle :THandle; PrnInfo2 :PPRINTERINFO2; PrnInfoSize :DWord; begin // se selecionada uma impressora na lista if ListBox1.ItemIndex >= 0 then begin // precisamos do handle PrnHandle para obter info sobre a impressora if OpenPrinter(PChar(ListBox1.Items[ListBox1.ItemIndex]), PrnHandle, nil) then begin // obtemos a quantidade de memória a alocar para o record a ser retornado GetPrinter(PrnHandle, 2, nil, 0, @PrnInfoSize); PrnInfo2 := AllocMem(PrnInfoSize); if GetPrinter(PrnHandle, 2, PrnInfo2, PrnInfoSize, @PrnInfoSize) then Label1.Caption := PrnInfo2^.pServerName +' | ' + PrnInfo2^.pPrinterName +' | ' + PrnInfo2^.pShareName else Label1.Caption := 'Falhou...'; ClosePrinter(PrnHandle); FreeMem(PrnInfo2, PrnInfoSize) end; end; end;- caso a impressora não seja de rede, pServerName será nulo; - caso a impressora não esteja compartilhada, pShareName será nulo. Veja o help citado para saber que outras propriedades você pode obter desta estrutura (Printer_Info_2) Abraços
  22. Micheus

    calcular campos

    No D7, existe a função DaysBetween que retorna a quantidade de dias entre duas datas, entretanto deve ter decorrido 24horas entre ambas. Caso você armazene a hora junto com a data, ela pode não lhe servir. function DaysBetween(const ANow, AThen: TDateTime): Integer; Já a função DaySpan retorna a quantidade dias entre duas datas, não levando a hora em consideração: function DaySpan(const ANow, AThen: TDateTime): Double; Abraços
  23. Vivendo&Aprendendo, aparentemente você posiciona o registro de algum modo, já que não está posicionado no 1º como mostra o Edit. Onde você faz isto? O evento OnChange do Edit só ocorrerá caso o seu conteúdo seja mudado, não apenas quando se digita algo, mas também quando via código alteramos o conteúdo da propriedade Text. Isto dá a impressão que, por exemplo, no evento OnCreate do form você esteja, por exemplo, limpando seu edit. Assim, se seu dataset está aberto no momento que o Edit.Text é definido para '', ao executar o OnChange, ele será inicializado com o primeiro registro do dataset. Numa etapa seguinte, quando você posiciona seu dataset no registro desejado, vai acontecer justamente o que você descreveu: Edit mostra 1º registro e DBEdits mostrando registro atualmente selecionado. Abraços
  24. Esta mensagem não informa qual o campo em questão está "inválido"? Observe que este tipo de mensagem indica que há a tentativa de gravar um valor inadequado num determinado campo. Isto não tem relação o fato de você tentar gravar um campo vazio. Seria melhor você colocar a mensagem original.
  25. robinhocne, você não deixou claro onde o erro ocorre: se na execução do SQL ou no código mais abaixo? Estou supondo que tenha sido no SQL. Primeiro, parece-me que você não está usando a operação correta dentro do SUM. Voce não deveria estar somando as diferenças, já que quer obter o total de horas. Ou seja, ao invés de: HorarioInicial + HorarioFinal deveria usar: HorarioFinal - HorarioInicial Segundo, por acaso não há algum destes dois campos nulo na sua base? Terceiro, sabendo que o resultado da operação com horas resultará em um tipo float (equivalente a TTime ou TDateTime) e, por consequência, que a parte referente a hora estará na parte fracionária, você acha que obteria o resultado correto utilizando o método AsInteger como no código: Total := QryHoras.FieldByName('HorasMarcadas').AsInteger Já toquei neste assunto várias vezes aqui no forum. Dê uma olha neste post do colega paulobergo e no seguinte. Abraços
×
×
  • Criar Novo...