Ir para conteúdo
Fórum Script Brasil

Micheus

Veteranos
  • Total de itens

    3.189
  • Registro em

  • Última visita

Tudo que Micheus postou

  1. Micheus

    Unir Tabelas Paradox

    Eder, você usa uma banda de agrupamento (Group) "vazia" onde o campo de agrupamento (expression) deverá ser o código do Pneu. Já os dados a serem mostrados, como correspondem a totais, você coloca na banda Group Footer, onde as colunas a serem somadas você usa TQRExpr. A banda detalhe é necessária, mas também não conterá nada e pode ter tamanho inicializado para zero antes da impressão do relatório (via código). Talvez alguém saiba como fazer isto no Free-Report e lhe ajude. Seria mais interessante do que fazer uma salada no seu projeto. A outra opção que lhe falei, possivelmente resolveria este problema, mas como disse, preciso de uma base de teste para tentar montar corretamente a consulta, já que raramente uso o Paradox. Se interessar, me envie uma pequena fração das tabelas em questão. Abraços
  2. Carissimi, como você grava no formato RTF (Rich Text Format), esta é uma dúvida tem mais chance de ser respondida se for postada na sessão PHP - como ler o conteúdo RTF no banco de dados e convertê-lo para html. Abraços
  3. Micheus

    Unir Tabelas Paradox

    Suporta sim Eder (claro que pode não ser 100%). Apenas você tem que observar que as colunas das duas consultas devem ser iguais (nome e quantidade). Assim, você poderia modificar a consulta para: //CUSTO INICIO SELECT P.Numero, P.Marca, P.Modelo, P.Tipo, P.Serie, P.Tamanho, P.Lona, Sum(R.RCusto) as Total1, 0 as Total2 FROM PNEU P, RECONST R : : Union all //KM RODADO INICIO SELECT P.Numero, P.Marca, P.Modelo, P.Tipo, P.Serie, P.Tamanho, P.Lona, 0 as Total1, Sum(M.KmRodado) as Total2 FROM PNEU P, MOVI M : : Order By Pneu.NumeroSe não me falha a memória, a cláusula Order By aparece apenas uma vez no final (após todos os unions) e não esqueça que na cláusula group by, todas as colunas do select devem ser colocadas - exceto as que usam as funções de agregação. Experimente a consulta e veja se funciona mesmo (99% de certeza). Mas vai ocorrer que você terá linhas onde uma das duas colunas estará com o valor 0 (já que assim o fixamos). Não chega a ser um problema se você usar as bandas de agrupamento no seu relatório, porque os valores serão somados baseado neste agrupamento e então, visualmente você não perceberá este "detalhe". Ainda acredito que haja outra possibilidade, utilizando Joins, mas teria que criar umas tabelas de teste e populá-las para ter certeza de lhe passar o sql correto. Se eu simplesmente postá-lo aqui, poderá estar errado e não irá lhe ajudar muito. Abraços
  4. Não. Eu não disse que seria sempre uma query. Eu sempre uso o termo DataSet, justamente porque esta é a classe ancestral tanto dos componentes table, query ou outro qualquer que você esteja usando para acessar os dados de uma tabela no seu banco de dados. A solução do seu problema deveria ser exatamente a mesma já mencionada, sendo que o datasource que você ligará à propriedade ListSource do LookupComboBox, deverá ter a sua propriedade DataSet com a tabela "departamento". correto! Poderia ainda ser o caso de um dos datasets não estar aberto. Verifique. Abraços
  5. Como sempre digo, idente seu código e use a tag CODE para melho visualização da estrutura dele. De acordo com o que você postou, desde a primeira alteração (post#8) em que você incluiu um "else" no código do botão BitBtn2, há um erro nele que resulta na inicialização de parâmetros que em teoria não deveriam ser inicializados conforme o teste realizado no if. Veja o código do post referenciado, com a identação (e uso da tag CODE): procedure TFrmConFuncionario.BitBtn2Click(Sender: TObject); Begin if datademini.Date = strtoDate ('00/00/0000') then begin dmdados.sqlconfuncionario.close; dmdados.SqlConFuncionario.ParamByName('nome').asstring:='%'+editnome.text+'%'; dmdados.SqlConFuncionario.ParamByName('cidade').AsString:='%'+EditCidade.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cargo').AsString:='%'+ComboBox1.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cpf').AsString:='%'+EditCpf.Text+'%'; dmdados.SqlConFuncionario.ParamByName('dataadmini').AsDate:=dataadmIni.Date; dmdados.SqlConFuncionario.ParamByName('dataadmfin').AsDate:=DataadmFin.Date; dmdados.SqlConFuncionario.Open; end else dmdados.SqlConFuncionario.Close; dmdados.SqlConFuncionario.ParamByName('nome').asstring:='%'+editnome.text+'%'; dmdados.SqlConFuncionario.ParamByName('cidade').AsString:='%'+EditCidade.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cargo').AsString:='%'+ComboBox1.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cpf').AsString:='%'+EditCpf.Text+'%'; dmdados.SqlConFuncionario.ParamByName('dataadmini').AsDate:=dataadmIni.Date; dmdados.SqlConFuncionario.ParamByName('dataadmfin').AsDate:=DataadmFin.Date; dmdados.SqlConFuncionario.ParamByName('datademini').AsDate:=datademini.Date; dmdados.SqlConFuncionario.ParamByName('datademfin').AsDate:=datademfin.Date; dmdados.SqlConFuncionario.Open; end; perceba que não há a delimitação do bloco para o else, o que faz com que todas as linhas abaixo do último Close (no else) sejam processadas. A correção desta esquecimento, ainda passa pela questão da lógica. Os dois blocos fazem praticamente a mesma coisa, logo, não se duplica todo ele, apenas separamos a parte que é diferente e o resto é codificado apenas uma única vez: procedure TFrmConFuncionario.BitBtn2Click(Sender: TObject); Begin dmdados.sqlconfuncionario.close; dmdados.SqlConFuncionario.ParamByName('nome').asstring:='%'+editnome.text+'%'; dmdados.SqlConFuncionario.ParamByName('cidade').AsString:='%'+EditCidade.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cargo').AsString:='%'+ComboBox1.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cpf').AsString:='%'+EditCpf.Text+'%'; dmdados.SqlConFuncionario.ParamByName('dataadmini').AsDate:=dataadmIni.Date; dmdados.SqlConFuncionario.ParamByName('dataadmfin').AsDate:=dataadmFin.Date; if datademini.Date = strtoDate ('00/00/0000') then begin end else begin dmdados.SqlConFuncionario.ParamByName('datademini').AsDate:=datademini.Date; dmdados.SqlConFuncionario.ParamByName('datademfin').AsDate:=datademfin.Date; end; dmdados.SqlConFuncionario.Open; end; e que melhor escrito ficaria com o if diferente: ... if datademini.Date <> StrToDate ('00/00/0000') then begin dmdados.SqlConFuncionario.ParamByName('datademini').AsDate:=datademini.Date; dmdados.SqlConFuncionario.ParamByName('datademfin').AsDate:=datademfin.Date; end; ... De qualquer modo, não será possível manter um parâmetro definido para a consulta sem que um valor lhe seja atibuído - sua consulta não funionará como deve. Há duas possibilidades para isto. Uma é a construção dinâmica do SQL onde, conforme a situação você irá incluir ou não a linha que deseja filtrar, enquanto que a outra seria um teste no parâmetro recebido e se o valor não for nulo você testa ele com o campo desejado (99% de chances de funcionar com todos os bancos). 1ª opção - Se você adiona os fields ao seu dataset, então, na propriedade SQL (ou similar, conforme componente) você constroi a query sem usar os parâmetros na cláusula where. Com isto, você poderá adicionar os fields sem problema e eles estarão disponíveis para a manipulação no código: select * from FUNCIONARIO (depois, no código, você modifica a query dinamicamente para filtrar as informações de acordo com a necessidade) - A manipulação dinâmica da query ficaria como segue: procedure TFrmConFuncionario.BitBtn2Click(Sender: TObject); Begin // vamos abreviar a escrita usando o "with ... do" with dmdados.sqlconfuncionario do begin Close; // fechamos a consuta atual SQL.Clear; // limpamos a query // reconstruimos a query com a parametrização necessária SQL.Add('select * from FUNCIONARIO'); SQL.Add('Where (Func_NOME like :nome'); SQL.Add('and (FUNC_CIDADE like :cidade'); SQL.Add('and (FUNC_CARGO like :cargo'); SQL.Add('and (FUNC_CPF like :cpf'); SQL.Add('and (FUNC_DATAADM >= :dataadmini and FUNC_DATAADM <= :dataadmfin'); // se formos filtrar a data de demissão... if datademini.Date <> strtoDate ('00/00/0000') then SQL.Add('and (FUNC_DATADEM >= :datademini and FUNC_DATADEM <= :datademfin'); // inicializando os parâmetros ParamByName('nome').asstring:='%'+editnome.text+'%'; ParamByName('cidade').AsString:='%'+EditCidade.Text+'%'; ParamByName('cargo').AsString:='%'+ComboBox1.Text+'%'; ParamByName('cpf').AsString:='%'+EditCpf.Text+'%'; ParamByName('dataadmini').AsDate:=dataadmIni.Date; ParamByName('dataadmfin').AsDate:=dataadmFin.Date; // se formos filtrar a data de demissão... if datademini.Date <> strtoDate ('00/00/0000') then begin ParamByName('datademini').AsDate:=datademini.Date; ParamByName('datademfin').AsDate:=datademfin.Date; end; Open; // abrimos a consulta end; end; 2ª opção - Nesta situação, apenas ampliamos a query atualmente em uso: select * from FUNCIONARIO Where (Func_NOME like :nome) and (FUNC_CIDADE like :cidade) and (FUNC_CARGO like :cargo) and (FUNC_CPF like :cpf) and (FUNC_DATAADM >= :dataadmini and FUNC_DATAADM <= :dataadmfin) and ((:datademini is null) or (FUNC_DATADEM >= :datademini and FUNC_DATADEM <= :datademfin)) observe a inclusão de "(:datademini is null) or ". Isto fará com que, sendo o parâmetro datademini nulo, a consulta não considere o filtro para FUNC_DATADEM. A desvantagem, pode ser a degradação do desempenho da consulta caso haja um índice para o campo em questão, uma vez que não será utilizado o índice para a otimização da query (sempre que usamos o OR estamos jujeitos a isto). - no código inicializamos o parâmetro em questão com null ao chamarmos o método Clear: procedure TFrmConFuncionario.BitBtn2Click(Sender: TObject); Begin dmdados.sqlconfuncionario.close; dmdados.SqlConFuncionario.ParamByName('nome').asstring:='%'+editnome.text+'%'; dmdados.SqlConFuncionario.ParamByName('cidade').AsString:='%'+EditCidade.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cargo').AsString:='%'+ComboBox1.Text+'%'; dmdados.SqlConFuncionario.ParamByName('cpf').AsString:='%'+EditCpf.Text+'%'; dmdados.SqlConFuncionario.ParamByName('dataadmini').AsDate:=dataadmIni.Date; dmdados.SqlConFuncionario.ParamByName('dataadmfin').AsDate:=dataadmFin.Date; // neste caso, se a data for "vazia", setamos os parâmetros para nulo com o Clear if datademini.Date = strtoDate ('00/00/0000') then begin dmdados.SqlConFuncionario.ParamByName('datademini').Clear; dmdados.SqlConFuncionario.ParamByName('datademfin').Clear; end; end; Apenas mais uma observação: se você for passar valores completos nos campos como cidade, cargo, cpf,..., não use o LIKE use a igualdade. E, se houver a questão da distinção entre maiúsculas e minúsculas, você deve fazer uso de funções que convertam os campos para um dos dois tipos, já que normalmente os bancos fazem distinção entre um e outro, podendo interferir nos resultados. Espero que possa ter ajudado a compreer algo mais a respeito desta questão. Abraços
  6. Fuzileir0, tente fazer uso do botão Pesquisa (logo ali em cima, à esquerda). Muitas destas questões dos "iniciantes" já foram algum dia abordadas. ;) A dica para a pesquisa é usar palavras chaves bem escolhidas. Neste caso, você poderia usar "MySQL" e "dll", mas inclua um "and" entre eles para indicar que ambos devem aparecer na consulta (se você não colocar ele, não haverá resultados). Assim, ao pesquisar com: MySQL and dll, você encontrará vários tópicos e um deles é: Não funciona em outras maquinas sera q falta dll? que contém a resposta à sua questão. Grande abraço
  7. Fuzileir0, se não me engano, quando a propriedade Active está marcada como True (você pode ter feito isto em design-time), o seu programa ficará minimizado na tray. Veja se você não mexeu nesta propriedade. Abraços
  8. Livio Neiva, de que SEQUEL você está ser referindo?Seria interessante você por um link ou algo que ajude os colegas leitores a localizarem-se sobre o assunto. Se for sobre este Sequel, então o tópico está na sessão errada. Abraços
  9. Livio Neiva, cheguei a fazer uns testes com dbExpress, mas utilizando endereçamento do servidor em Database, não o caminho do DB. Assim, não vou poder opnar muito sobre a forma que você está implementando. Não sei que versão de Delphi você está usando, mas tenho nos meus favoritos dois artigos que podem lhe ser útil: dbExpress para Firebird - Saiba como acessar o FB com o driver dbExpress especifico Delphi 2007: DBX4 (antigo DBExpress) e Firebird. Abraços
  10. Mesfistofeles, considere que cada ADOQuery vem de uma tabela e que há uma relação entre elas (algum campo deve fazer isto), e é através destes campos que você vai conseguir trazer as informações de cada uma das tabelas. Eventualmente, pode ocorrer o banco utilizado não "aceitar" uma update assim e, neste caso, o jeito seria mesmo como você está fazendo. se estiver deste jeito, o erro está no fato de você ter usado o "]" no lugar de ")". Mas, ainda tem um erro de "lógica", pelo fato de você utilizar duas tabelas na cláusula FROM e não fazer o relacionamento entre elas na cláusula WHERE. Abraços
  11. Mesfistofeles, provavelmente porque seu filtro não está "olhando" o dia (data). Basta que você observe como está sua consulta - em algum lugar, você deveria filtrar, além do cliente, a data em questão. Partindo do princípio de que você está atualizando outra tabela com estes valores (é o que parece que você faz com QTotal.Edit, ...), talvez fosse mais apropriado que você contruisse uma query de UPDATE onde você atualizará o campo TotalMov a partir do somatório dos campos somados (SUM) das outras tabelas onde você filtra a data desejada. Abraços p.s. Quando postar código, use a tag ... seu código ... [/ CODE] (sem o espaço depois da "/") ;)
  12. Vinsclay, o artigo Executando Firebird e InterBase no mesmo computador ensina justamente isto. Caso você precise que os dois bancos coexistam simultaneamente, então você terá que configurar portas diferentes para cada servidor. Há artigos a este respeito. Sugiro que você cadastre-se no site http://www.firebase.com.br - tem bons artigos para Firebird lá. Você encontrará o artigo Instalando o FB 2.1 com outras versões do FB que explica como proceder para configuração de portas diferenciadas para o servidor. (caso lhe interesse) E nesta questão de coexistência simultânea, é importante que sua aplicação permita a configuração de a qual porta o seu componente de acesso ao banco deverá se conectar. Abraços
  13. danielrgoes, como o colega maikel comentou, você precisa explicar o que você quer avaliar como "aproximadamente". Mas, apenas acrescentando, na unit Math há outra função chamada CompareValue que possui várias opções de parâmetros (overload) e um deles permite que você informe qual deve ser a máxima diferença entre os números. O resultado indica de é menor, igual ou maior. Pode ser que ela lhe sirva e, neste caso, veja no help mais detalhes. Abraços
  14. Micheus

    Renomear Units

    nsouza, deve ser relativamente simples sim. Eu costumo usar a opção "Save As...". Com isto, o source do projeto será automaticamente atualizado. Depois, uso a opção do menu: Search->Find in files... e procuro pelo texto desejado. Na janela de resultados aparecerão todas as linhas onde o texto aparece, bastando que você dê um duplo click nela para que o respectivo arquivo do projeto seja aberto e posicionado no texto procurado e, então, você pode alterá-lo. Depois é só gravar as alterações e recompilar seu projeto - use a opção Build All para ter certeza que todo o projeto foi realmente recompilado. Ao final, com tudo funcionando corretamente, eu posso excluir o arquivo antigo com o nome antigo. O que pode ser mais complicado e sujeito a erros é a mudança do nome de um componente. Abraços
  15. Esses dois últimos comandos matam o formulário da memória? Fuzileir0, apenas o Free provocaria este efeito, o hide apenas oculta o formulário o que neste caso seria desnecessário já que ele sumirá de qualquer modo. (neste post eu exemplifiquei os eventos que citei antes) Entretanto, a documentação, mesmo eu tendo sugerido anteriormente o uso do FreeAndNil, que nada mais faz do que chamar o método Free do objeto em questão e o setar com nil, a documentação do Delphi é clara em frisar que para eliminar um objeto da classe TForm, o método a ser utilizado deveria ser o Release. Vou postar aqui o que está neste outro post: *Informe se não conseguir ler o texto ;) Sim. O "destroy" que eu citei seria realmente o evento OnDestry. Só melhorando a explicação. O primeiro form criado (adicionado à Application) será sempre o form principal e o seu fechamento implica no encerramento do programa.Há a possibilidade de você executar um form de login e apenas se o login for aceito é que a sua aplicação continua e é iniciada. Veja um exemplo neste post. Eder Moraes, acho que aqui você quis dizer que coloca o DataModule como primeiro na ordem de criação dos formulários do projeto, não é?! Nas opções do projeto, apenas forms podem ser selecionados em MainForm. Ou você usa algum artifício? Abraços
  16. Gabriel Cabral, já que você usa componentes data-aware (os TDB...), há algum motivo especial para você não utilizar um TLookupComboBox no lugar do seu ComboBox? Ele já faria todo o "serviço sujo" para você. Abraços
  17. Micheus

    Erro ao salvar

    Novamente venho lembrar que é muito importante que os componentes em uso sejam corretamente citados. Considerando que o colega Zuera esteja usando o componente TUpdateSQL, constante da paleta BDE, então os outros componentes utilizados podem ter sido: conexão com banco de dados TDataBase e consultas SQL via TQuery. Assim, fugindo um pouco do foco, só para não gerar qualquer confusão para algum leitor distraído, caso os componentes em uso sejam mesmo estes citados... apenas chamando a atenção para o fato de que o método ExecQuery é exclusivo do componente TIBSQL (não descendente da classe TDataSet). Os demais componentes, como TQuery (possivelmente usado pelo colega Zuera), TSQLDataSet, TSQLQuery, TUpdateSQL, TADOQuery, TIBDataSet, TIBQuery, TIBUpdateSQL e tantos outros usam o ExecSQL para execução das instruções SQL. Quando o colega Eder Moraes cita no exemplo CommitRetaining, está referindo-se ao uso de transações. Este é um ponto interessante de ser observado e o importante é procurar entender o conceito (há muitas apostilas que falam a respeito) e este artigo: Programação Cliente/Servidor - parte 4, comenta um pouquinho sobre isso. Mas, voltando ao exemplo, para que este recurso seja utilizado, em algum ponto do código no processo atual (seja de inclusão, alteração, ...), deve ocorrer o início desta transação. Quando uma transação é iniciada, ela pode ser efetivada (Commit) ou desfeita/cancelada (RollBack). O help do Delphi tem um exemplo de como isso ocorreria ao utilizar componentes descendentes da classe TBDEDataSet: procedure TForm1.ApplyButtonClick(Sender: TObject); begin with CustomerQuery do begin Database1.StartTransaction; try ApplyUpdates; {try to write the updates to the database}; Database1.Commit; {on success, commit the changes}; except Database1.Rollback; {on failure, undo the changes}; raise; {raise the exception to prevent a call to CommitUpdates!} end; CommitUpdates; {on success, clear the cache} end; end; Os diversos componentes relacionados a transações tem varições com relação ao nome dos métodos, então é importante buscar na documentação (help ou net), quais os métodos que você poderá utilizar para aplicar este recurso. A título de exemplo: TIBTransaction (IB), TZConnection (Zeos): - StartTransaction - CommitRetaining e Commit - RollbackRetaining e Rollback TADOConnection (ADO) - BeginTrans - CommitTrans - RollbackTrans TDataBase (BDE), TSQLConnection (dbExpress) - StartTransaction - Commit - Rollback Abraços
  18. Com certeza não está bom. Mas, se você não conseguiu compreender mesmo o que tentei explicar no post que pus de referência, então não dá para explicar melhor. O seu caso é exatamente o que está lá, exceto pelo nome dos dataset's. A figura 2 ilustra o que você estaria fazendo. Ao filtrar cada elemento na tabela Pedido que é mostrado no 1º DBGrid (no seu caso seria Saidas), os vários elementos da tabela Parcelas (no seu caso ItensSaidas), para aquele pedido, seriam listados no 2º DBGrid. Boa sorte.
  19. Micheus

    Erro ao salvar

    Zuera, vamos ver se com o que postei abaixo, você consegue resolver seu problema - ficou muito grande, então leia com calma. Espero que esteja correto. :D Quanto a esta sua observação, ela está correta: vai ficar read-only sim. (nada como um pouco mais de informação ;)) Por esta última fração de código, dá para ver que teria que dar algum erro de qualquer jeito - se o dataset QAddObs tem este select composto, e você sabe que não pode modificar seus dados. Aparentemente voce não inicializa mesmo os parâmetros em lugar algum. Isto tem que ser feito, já que você tem 3 opções (SQL) de manipulação da tabela através do componente TUpdateSQL. Conforme a ação que você esteja fazendo, deverá utilizar uma das opções como parâmetro para a ação: - ukModify (quando alterando) - ukInsert (quando adicionando) - ukDelete (quando excluindo) Estive olhando e, em design-time, o componente TUpdateSQL não há uma propriedade DataSet para indicar o dataset de onde virão os dados para os parâmetros (quando eles existem), mas no help há indicação de que a propriedade existe. Talvez ela seja inicializada quando você selecina manipula a propriedade UpdateSQL do dataset "read-only". Se isto estiver correto (e acho que deve estar), para você inicializar os parâmetros e executar a operação desejada basta que você use o método Applay do componente TUpdateSQL: ex.: UpdateSQL1.Applay(ukModify); Qualquer parâmetro que não venha do dataset, pode ser incializado usando o método ParamByName: ex. UpdateSQL1.ModifySQL.ParamByName('DatAtualizacao').Value = Now; Com isto, o problema deveria "sumir". Mas, caso isto não ocorra ou você estivesse fazendo tudo no código, uma alternativa é iniciar a propriedade DataSet em run-time: ex. UpdataSQL1.DataSet := QAddObs; (definindo o dataset de origem dos valores para os parâmetros) Conforme a ação que você esteja fazendo, deverá utilizar uma das opções para inicializar os parâmetros adequados através do método SetParams do componente TUpdateSQL: ex. UpdataSQL1.SetParams(ukModify); Depois para que o comando desejado seja executado, você pode usar o método ExecSQL ou Applay, para que o respectivo comando seja executado usando os parâmetros inicializados com o método já citado: ex.: UpdataSQL1.ExecSQL(ukModify); Observe, ainda, que você deve ter habilitado no seu dataset "read-only" a propriedade CachedUpdates antes de usar este recurso do TUpdateSQL. Como vê, você estará manipulando este componente - não o dataset em si. Um documento interessante, que pode ser usado como referência porque mesmo tratando de componentes da paleta IB, grande parte da funcionalidade diz respeito à classe comum entre estes componentes TDataSet: Interbase Developer Guide (em Inglês - ref. Unicamp) - este assunto é tratado na seção Working with Cached Updates. Abraços
  20. Micheus

    stringgrid

    AllNet, você está usando mesmo um TStringGrid ou é um TDBGrid? É sempre bom ficar bem claro que componente está usando, já que as ações podem ser diferentes. ;) Abraços
  21. Livio Neiva, independente do componente que você esteja usando, o conceito será exatamente o mesmo: faz uma consulta para saber se existe ou não o registro na sua tabela de controle. (conforme o colega Eder Moraes sugeriu) Abraços
  22. Micheus

    Erro ao salvar

    ZueRa, não estou conseguindo pensar em uma forma de lhe ajudar com isso. Eu não costumo usar UpdateSQL - espero que algum outro colega possa lhe dar uma luz. E quanto a questão "Olhando o código, tem algo estranho nesta parte..."? Olhou isto? Abraços
  23. Vivendo&Aprendendo, há algum motivo específico para que naquela sua consulta (que supostamente está no primeiro DBGrid) traga as informações sobre os itens da saída, uma vez que esta informação supostamente deveria aparecer apenas no segundo DBGrid? Se não tiver, use naquela consulta apenas os dados da tabela de saída (a master - no 1º DBGrid) e use o seu código para filtrar os itens (o detalhe - no 2º DBGrid) - faça um teste e confira o resultado (vai cair no que está no post que havia citado). Quando você usa o distinct, que está dizendo para que seja retornado apenas uma ocorrência de toda a linha encontrada, ou seja, todos os campos são levados em conta. Assim, você terá a repetição de todos os dados de uma mesma saída quando os produtos (ou qualquer outro campo) são diferentes. Abraços
  24. Micheus

    Erro ao salvar

    Por acaso, desde que você colocou estes componentes no seu form/datamodule, você fez alguma alteração na estrutura da tabela em questão? Alterou o tipo de dados ou tamanho de algum campo? Os parâmetros estão devidamente configurados quanto ao seu tipo? Olhando o código, tem algo estranho nesta parte: ... Dmdados.Qaddobs.Active := true; Dmdados.Qaddobs.ApplyUpdates; //também já tentei o ApplyUpdates em baixo do Post Dmdados.Qaddobs.Post;como é que você ativa o dataset e sem inicializar seus valores, usa o ApplayUpdates e Post? Quando é que os campos/parâmetros estão sendo inicializados? Abraços
×
×
  • Criar Novo...