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

    Erro ao salvar

    Zuera, o código aparentemente não mostra nada que possa ajudar na compreensão do seu problema. O erro deve ser proveniente de alguma das instruções SQL que você usa no UpdateSQL2. Acredito que seria interessante você postar estes SQL para avaliação. Abraços
  2. Você usa uma query sobre as vendas (ou suas Saídas) para os dados deste DBGrid, onde filtra o cliente... ... e usa outra query para mostrar neste DBGrid os itens da venda, selecionada no 1º DBGrid, usando como parâmetro no filtro o campo de relação entre eles. O conceito é o mesmo que este outro que já expliquei em outro tópico - dê uma olhada nele. Abraços
  3. E esta outra parte, pode ser simplificada: If F_Dados.Q_Funcionario.FieldByName('actotal').AsString = 'X' then CheckboxAcTotal.Checked := True else CheckboxAcTotal.Checked := False; ficando apenas: CheckboxAcTotal.Checked := F_Dados.Q_Funcionario.FieldByName('actotal').AsString = 'X';
  4. DELPHITOTS, sua idéia está correta, apenas a forma de executá-la não. Vamos avaliar apenas a primeira parte, aquela que você disse que já estava funcionando (post#4): SUM(IF(IBQuery1.tipoest='e',(pesobruto*numpecas*qtdemat*valorunitcompcad),0)) Observe que a função SUM, fará o somatório dos valores retornados pela função IF, não é mesmo. Agora olhe para a função IF. O primeiro argumento (IBQuery1.tipoest='e') é a condição a ser avaliada. O segundo argumento (then), você corretamente colocou a cálculo a ser feito quando o resultado desta avaliação é verdadeira. Mas, no terceiro argumento (else), quando a condição é falsa, você instrui ela a retornar o valor zero. Caso o campo tipoest apenas possa possuir um destes dois valores, não tem erro: no lugar do zero, você faz o cálculo para a opção diferente de "e". Entretanto, se houver a possibilidade de outros valores para o campo, então, o que diria a lógica? se tipoest = 'e' então (pesobruto*numpecas*qtdemat*valorunitcompcad) senão (se tipoest = 'i' então (pesobruto*numpecas*qtdemat) senão (0)) ou seja, SUM(IF(IBQuery1.tipoest='e', (pesobruto*numpecas*qtdemat*valorunitcompcad), IF(IBQuery1.tipoest='i',(pesobruto*numpecas*qtdemat), 0))) Experimente isto - deveria funcionar. Abraços
  5. Antonio44, lembro que você usa uma versão antiga do Delphi (acho que é a 3). Qual é a versão do QuickReport que você está usando com ele? (você vê isso, utilizando o menu de contexto do componente TQuickRep). Supondo que seja o D3, a última versão do quick para ele seria a 2.0K (download da versão Standard - outras versões de Delphi, procurar aqui). Como o erro está no Create e não no Preview, fica descartada um dos problemas relacionados a variável de ambiente (se não me engano, inclusive, você já tratou desta questão em outro tópico). Então, lembrei que havia uma outra condição em que já ocorreu erro similar. Trata-se de quando não há uma impressora configurada no computador (nas versões mais recentes do quick, parece-me que isto não ocorre mais). Supondo que funciona no seu computador porque haja uma impressora instalada. E que nos outros computadores da rede, que você testou, possa não haver uma impressora configurada ou, se havia, poderiam não estar mais presentes após a instalação do SP3 do XP. Comento isto porque há um update (KB953979) para corrigir problemas relacionados às conexões de rede: After you install Windows XP Service Pack 3 (SP3), Device Manager may not show any devices, and Network Connections may not show any network connections. Dê uma conferida nesta questão do compartilhamento da impressora (acredito que seja utilizado) Abraços
  6. Nesta fração de exemplo, não há uma linha que não comece com letras (utilizadas para o identificador): :huh: ITP0041500000090327000000000... AE1011306U 0903260030000000... AE2001 A3273530350 ... AE41800 AE70000000000005.10100000000... AE2002 A6533530050 ... AE41800 AE70000000000005.10100000000... AE2003 A3553320148 ... AE41800 AE70000000000005.10100000000... AE8000000 000 TE1 AE1011307U 0903260020000000... AE2001 T53215 ... AE40000 AE70000000000005.92100000000... AE2002 T54315 ... AE40000 AE70000000000005.92100000000... AE8000000 000 TE1 FTP00002000000023 Acrescentando o que você me enviou por e-mail, para ajudar no entendimento dos colegas... (e meu :)) Apesar de a adaptação do código não estar muito apropriada para a abordagem que você utilizou (trabalhar com TextFile ao invés do TStringList), isto pode ser melhorado posteriormente. Mas, a primeira vista, não parece haver algo errado no processamento realizado dentro do loop. Que tipo de registro deveria aparecer apenas uma vez e aparece quatro? Pelo que consta do manual, há tipos de registros que podem ter N ocorrências: ### Modelo Descritivo ### IDENTIF. INDICADOR REG DE USO OCORR. SUBORD. NOME DO REGISTRO --- ------ ------ ------- ------------------------------ ITP M 1 INICIO DA TRANSMISSAO PROCESSO PE1 M N ITP Dados do Item PE2 M 1 PE1 Inform. de Entregas/Embarque PE3 M N PE1 CRONOGRAMA DE ENTREGA/EMBARQUE PE5 O N PE3 COMPL CRONOGR ENTREGA/EMBARQUE PE6 O N PE1 DADOS COMPLEMENTARES DO ITEM PE7 O 1 PE1 DADOS DA EMB. PRIM. DO CLIENTE PE8 O 1 PE1 DADOS DA EMB. SEC. DO CLIENTE PE4 O 1 PE1 DADOS DA EMBALAGEM TE1 O 1 PE1 TEXTO LIVRE FTP M 1 TE1 TERMINO TRANSMISSAO PROCESSO Sugestões: 1) quando postar código no forum, cerque ele com as tag's [ code] <código> [ /code] (sem o espaço depois do couchete); se puder, edite o seu post anterior e inclua elas porque facilita muito a visualização dele. 2) facilitará muito a organização/manutenção, se você criar um procedimento para cada tipo de identificador a ser processado; você passa a linha como parâmetro e, eventualmente, se for tratar a versão do arquivo, também passa a versão. Ex.: procedure LeRegITP(Linha :string); begin ... end; procedure LeRegPE1(Linha :string); begin ... end; : : procedure LeRegPE8(Linha :string); begin ... end; procedure LeRegFTP(Linha :string); begin ... end; procedure TFormProgramacao.BtnImportarClick(Sender: TObject); Var Txt:TextFile; : begin : if RegId = 'ITP' then LeRegITP(Linha); : while .... begin if RegId = 'PE1' then LeRegPE1(Linha) else if RegId = 'PE2' then LeRegPE2(Linha) : end; : end;
  7. micheli_martins, espero que alguém que já tenha feito este tipo de importação antes, possa apresentar uma solução já pronta, ou aproximada, para o seu caso. Mas, enquanto isso... eu acredito que você precisará processar linha por linha, obtendo o identificador do registro. Voce armazena o último registro lido em uma variável, para compará-la com a próxima linha lida, assim você saberá como processar cada um dele. Voce já sabe de ante-mão que alguns registros ocorrem apenas uma vez, bem como, a sequência em que devem ocorrer, que alguns são obrigatórios e que alguns são subtipos. É com estas informações que você terá que trabalhar. Não sei se ajuda muito, mas é apenas um rabisco aproximado de como me parece que deveria funcionar: var Idx :Integer; Linha, RegId, // identificador do registro RegIdOld :string; // identificador do registro anterior EDIFile :TStringList; begin EDIFile := TStringList.Create; try EDIFile.LoadFromFile('arquivo_edi.txt'); Idx := 0; RegIdOld := ''; Linha := EDIFile[Idx]; RegId := Copy(Linha, 1, 3); if RegId = 'ITP' then begin // processa aqui os dados do registro ITP // .... // processa as linhas exceto a última que deverá ser do tipo 'FTP' while (Idx < EDIFile.Count -1) do begin Inc(Idx); Linha := EDIFile[Idx]; RegId := Copy(Linha, 1, 3); if RegIdOld <> RegId then begin // quando há mudança do identificador, faz // algum processamento/validação. Por ex, o // tipo PE3 só pode aparecer depois de um tipo PE5 // ... RegIdOld := RegId; // atualiza variável end; // processa aqui os dados do registro conforme identificador if RegId = 'PE1' then // .... else if RegId = 'PE2' then // .... else if RegId = 'PE3' then end; Inc(Idx); Linha := EDIFile[Idx]; RegId := Copy(Linha, 1, 3); if RegId = 'FTP' then begin // processa dados do identificador FTP end else ShowMessage('Identificador FTP não encontrado'); end else ShowMessage('Identificador ITP não encontrado'); finally EDIFile.Free; end; end; Na verdade, pode ser conveniente fazer uma espécie de parser antes de usar efetivamente os dados, observando todas as questões de sequência, precedência e obrigatoriedade dos identificadores, conforme previsto no manual operacional. Abraços
  8. Este SQL a que você se refere seria uso de datasets (seja table ou query)? Se for, acho que voce mesmo já respondeu a pergunta - parece claro que seja algo relacionado ao QuickReport apenas. António44, olhando seu exemplo, parece-me que para criar seus relatórios você usa a opção do menu File->New->Other->New->Report. Seria isto mesmo? Este exemplo que você citou por último, você saberia dizer se o erro ocorreu no momento em que você chama o Create ou o Preview? Se não souber, tente verificar colocando break-points nestas linhas e observe em que ponto a exceção ocorrerá. Dois comentário sobre o fragmento do código que você postou: 1) não é muito lógico que você use o with <variável dinâmica> do antes que você tenha alocado memória para ela (mesmo que isto não cause erro - pelo menos no seu exemplo). O correto seria a sequência: Report1 := TReport1.create(self); with Report1 do begin : end; 2) a lógica no uso do try..except..end não está muito adequada. Digamos que colocando o Create do relatório dentro do Try e usando o Finally para liberar a memória do objeto não é o correto. Uma coisa é você tratar a instanciação da classe outra é tratar algum erro que possa ocorrem enquanto você usa o objeto. Se for tratar apenas erros na execução do relatório, o objeto tem que ter sido criado antes do "tratador": procedure TForm1.Button1Click(Sender: TObject); begin Report1:=TReport1.create(self); with Report1 do try : : Report1.preview finally free end; end; observe que criamos o objeto Report1, e depois tentamos (try) usar seu(s) metodo(s) e, havendo erro ou não, finalmente (finally) liberamos a memória alocada para ele. Já se fossemos tratar a criação do objeto também (o que é pouco usual), teríamos que ampliar o código: procedure TForm1.Button1Click(Sender: TObject); begin try Report1:=TReport1.create(self); with Report1 do try : : Report1.preview finally free end; except ShowMessage('Não foi possível criar o relatório!'); end; end;agora, estamos tentando (try-1) criar o relatório, se houver um erro neste processo (except), mostraremos a mensagem (a variável não foi alocada nesta condição). Caso não haja erro (a variável foi alocada), passaremos a diante e tentaremos (try-2) mostrar o relatório. Ocorra um erro ou não (finally), liberaremos a memória alocada para o objeto. Lembre-se que qualquer linha de comando que esteja entre o bloco try...finally ou try...except, que possa causar uma exceção resultará no desvio para o bloco finally...end ou except...end. Assim, quanto mais comandos você quizer tratar, mais blocos try terá que aninhar. Abraços
  9. Livio Neiva, você quer dizer: quando não houver nada no DBGrid - é isto? Para a "automação" tem um jeito simples: use o evento OnDataChange do TDataSource. Se o componente TDataSource ligado ao seu TDBGrid estiver neste form, beleza. Já se estiver em um datamodulo, acione um ao form e lique ele ao mesmo dataset que está sendo usado no seu DBGrid. No evento OnDataChange coloque: procedure TForm1.DataSource1DataChange(Sender :TObject); begin if Assigend(DataSource1.DataSet) then BtnExcluir.Enabled := (DataSource1.State = dsBrowse) and (DataSource1.DataSet.RecordCount > 0); else BtnExcluir.Enabled := False; end;O que vai acontecer é que qualquer alteração que seja feita no seu dataset, irá disparar este evento, mas não vai tornar sua aplicação mais lenta por conta disto. Então, logo que você abrir seu dataset este evento ocorrerá (também) e conforme avaliação, o botão de exclusão ficará inibido - só vai liberar se seu dbgrid tiver alguma linha e se ele não estiver em edição ou inserção. O código no seu botão de exclusão não muda nada. Abraços
  10. Rodrigo Bizz, faz todo o sentido que isto funcione.Observe que o destino tem apenas o tamanho da área que você selecionou (largura e altura) - o que é correto. Realmente passou-nos batido no seu - post#7 o fato de você não ter usado a proporção que o colega paulobergo havia mantido no seu exemplo: ... // RectOrigem := Rect(243, 182, 452, 388); // RectDestino := Rect(0, 0, 351, 287); onde RectDestino deveria ser Rect(0, 0, 209, 206) Use deste modo que não terá mais problemas: ... RectOrigem := Rect(243, 182, 452, 388); RectDestino := Rect(0, 0, RectOrigem.Right -RectOrigem.Left, RectOrigem.Boittom -RectOrigem.Top); Bitmapdst.Width := RectDestino.Right +1; Bitmapdst.Height := RectDestino.Bottom +1; Abraços
  11. Ela funciona na condição em que apenas tenhamos que levar em conta o fornecedor. Se houvesse a possibilidade de, na tabela fornecedor2, haver dois registros para o mesmo produto e produtor, então o resultado não seria correto. select A.id, A.nome from fornecedor2 B left join fornecedor A on (B.id_fornecedor = A.id) where B.codigo in (7, 11) group by A.id, A.nome having count(A.id) = 2 Um teste de mesa, para exemplificar... fornecedor2: codigo|id_fornecedor|descricao 5|2|produto cod 5 5|11|produto cod 5 5|18|produto cod 5 7|5|produto cod 7 7|8|produto cod 7 7|11|produto cod 7 8|5|produto cod 8 8|12|produto cod 8 11|5|produto cod 11 11|6|produto cod 11 11|11|produto cod 11 11|12|produto cod 11 12|1|produto cod 12 12|3|produto cod 12 dos candidatos, B.codigo in (7, 11) resulta em: 7|5|produto cod 7 7|8|produto cod 7 7|11|produto cod 7 11|5|produto cod 11 11|6|produto cod 11 11|11|produto cod 11 11|12|produto cod 11 B.id_fornecedor corresponde à A.id assim, o resulta será agrupado na sequência: 7|5|produto cod 7 11|5|produto cod 11 11|6|produto cod 11 7|8|produto cod 7 7|11|produto cod 7 11|11|produto cod 11 11|12|produto cod 11 o resultado será agrupado pelos campos id e nome do fornecedor e o agrupamento por A.id resulta em: 5|fornecedor 5 5|fornecedor 5 6|fornecedor 6 8|fornecedor 8 11|fornecedor 11 11|fornecedor 11 12|fornecedor 12 e apenas os códigos filtrados que aparecem 2 vezes serão retornados ao ser considerado count = 2. Para fins de melhor performance nas consultas, é conveniente que você tenha um índice, na tabela fornecedor2, cujo primeiro campo seja codigo, bem como para tabela fornecedor exista um com o campo id na mesma posição. Abraços
  12. laine, a primeira opção com os exits, com certeza funciona. Mas a segunda opção que postei (aquela que usa o haging count), refletindo um pouco melhor, acho que ela está errada. Peço a gentileza de que você teste com sua base e confirme se está funcionando como deveria. Infelizmente minha base para o teste não era muito grande e eu acho que o resultado que tive foi apenas coincidência. Vou tentar montar uma base maior e avaliar melhor esta sugestão. Abraços
  13. Tentando explicar o que eu havia citado antes... select distinct B.id_fornecedor, A.* from fornecedor2 B left join fornecedor A on (B.id_fornecedor = A.id) where B.codigo in (7, 11) Será procurado na tabela fornecedor2 os registros que contém codigo = 7 ou 11. Para cada um que for encontrado, será buscado o registro em fornecedor. Uma sugestão seria a seguinte: select A.* from fornecedor A where exists(select first 1 B.codigo from fornecedor2 B where B.id_fornecedor = A.id and B.codigo = 7) and exists(select first 1 B.codigo from fornecedor2 B where B.id_fornecedor = A.id and B.codigo = 11) Será procurado na tabela fornecedor os registros onde existam resultados para as sub-consultas realizadas na tabela fornecedor2. Apenas os registros de forncedor em que o campo id for encontrado nas sub-consultas em fornecedor2 juntamente com seu campo codigo igual ao valor passado serão retornados. (as duas sub-consulta devem retornar verdadeiro). Quantos códigos você tiver que procurar, mais sub-selects tem que ser incluídos. O uso do first, ao invés do distinct, otimiza a consulta no banco. Se você usa o IBExpert, poderá observar isto. No exemplo que usei, estes foram os planos adaptados e enviados ao banco: First: PLAN (EP INDEX (INTEG_39)) PLAN (EP INDEX (INTEG_39)) PLAN (P NATURAL) Distinct: PLAN SORT ((EP INDEX (INTEG_39))) PLAN SORT ((EP INDEX (INTEG_39))) PLAN (P NATURAL) Outra opção que pode lhe servir, já que trará dados distintos, seria usar a cláusula group by com having count, mas precisamos declarar na cláusula select as colunas a serem usadas: select A.id, A.nome from fornecedor2 B left join fornecedor A on (B.id_fornecedor = A.id) where B.codigo in (7, 11) group by A.id, A.nome having count(A.id) = 2onde, este 2 corresponde a quantidade de elementos na lista - só assim, você garante que estará trazendo a informação desejada. Funcionou com meu exemplo. Verifique se vale para você. Espero que uma destas sugestões lhe ajude. Abraços
  14. paulobergo, sobre esta questão, vou acrescentar ao seu exemplo a propriedade CompressionQuality que corresponde a um valor percentual (valores de 0..100). Quanto menor este número, pior e o tamanho do arquivo cresce proporcionalmente a este valor. Abraços
  15. laine, como sua consulta procura pelo produto específico para chegar nos fornecedores, eu penso que sua consulta ficaria mais clara se o select principal ocorrer sobre a tabela dos produtos fornecedor2: select distinct B.id_fornecedor, A.* from fornecedor2 B, fornecedor A where B.id_fornecedor = A.id and B.codigo in (7, 11) Quanto a filtrar os dois códigos ao mesmo tempo, vou fazer uns testes antes de dar uma sugestão. :blush: Abraços
  16. Com certeza não dá - é para o MySQL. O front-end que é mais mencionado para o Firebird é o IBExpert. Ele possui uma versão gratuita (Personal) e outra paga. Dê uma olhada neste tópico, tem referência para apostilhas e artigos lá. Abraços
  17. Reisah, este "Start code" corresponde ao StartByte e o "End code" corresponde ao StopByte ou não há necessariamente a relação? Conforme o caso, seria possível utilizar o componente TComDataPacket associado ao TComPort e usar o evento OnRxBuf. O componente TComDataPacket permite que você identifique strings de início e fim de pacote, facilitando a leitura dos mesmos. Supondo que existam vários pacotes possíveis, bastaria configurar um componente deste para cada pacote, ligá-lo ao único TComPort e usar o evento OnPacket de cada um deles para processar o pacote quando este está completo e pronto para ser processado. Dois comentários a respeito a leitura do buffer: 1) Vejo que você fixou o tamanho em 13, mas isto pode não ser correto. Será que você sempre receberá pacotes com 13 caracteres? (está praticamente associada a pergunta inicial) Observe que o correto seria você verificar e/ou usar a quantidade de bytes que está lhe sendo entregue e isto consta no parâmetro Count. Voce não deve correr o risco de ler coisa de menos ou tentar ler coisa de mais. 2) Não estou certo quanto ao funcionamento correto deste processo, uma vez que supostamente a porta poderia retornar algum byte com valor zero no meio da string e, como sabemos, as strings são tratadas normalmente com o zero terminador. Isto resulta que se de 13 bytes o 6º for um zero, sua string a ser concatenada estará incluindo apenas 5 caracteres ao memo e o resto dos bytes recebidos estariam sendo desprezados. Como diga, sugiro que trabalhe com constantes para a identificação dos comandos e status, como por exemplo: Const cmStartCode = $40; cmEndCode = $0D; cmCheckFinger = $4B; ...ajuda bastante na leitura do código como um todo, já que você os usa no lugar do número. São coisas para você avaliar. Eu não tenho como fazer qualquer teste com porta serial e os comentários que faço são baseados em experiência passada. Apenas tenha eles em conta quando estiver fazendo seus testes. Abraços
  18. Especificamente sobre esta questão, você pode dar uma olhada neste tópico da sessão Tutoriais & Dicas: Justificação E Entre-linhas Em Richedit
  19. nsouza, eu não entendi exatamente como esta sua tela está funcionando, já que no formulário estão o campo ligados à tblMaterialGasto e no grid você quer mostrar o resultado da query qryMaterialGasto. Mas, em todos os casos, esta sua query teria que filtrar o campo IDOS da tabela MaterialGasto baseado no valor que você digitou no campo edtOrdemServico - seria uma consulta parametrizada. Então no evento OnExit do edtOrdemServico, voce poderia fechar a consulta, inicializar o parâmetro da query com o valor digitado e depois abrir a consulta. Se a consulta estiver vazia é sinal de que não há informações e você pode mostrar a mensagem do contrário, os itens estarão no grid. É basicamente a mesma "lenga-lenga" que tratamos no seu outro tópico: Impedir número já registrado, especificamente neste post Abraços
  20. nsouza, vamos em etapas porque acho que tem coisa demais aqui para o que você quer fazer. No DBGrid você vai mostrar o resultado da tal query, certo? Então, esta query deve ter uma parâmetro onde você o iniciliza com o valor digitato no seu edtOrdemServico e depois abre a query. Isto feito, duas coisas podem ocorrer: os dados aparecerem no grid ou não aparecer nada nele. Se aparece alguma coisa, então se "olharmos" a propriedade RecordCount obteremos um valor maior que 0 (zero); caso não apareça nada, este valor será 0. Assim, este seria o teste que você deveria fazer para mostrar a mensagem. Logo após abrir a consulta você testa esta propriedade e se for zero mostra a mensagem. Esta tal tblOrdemServico seria a sua query? É o que parece pelo que você "fala" no post, mas não é o que parece pela nomenclatura - tbl, sugere que seja uma tabela (table). Abraços
  21. Você fala em datagrid - estamos falando de programação .NET? Se for um programa Win32, o componente seria um DBGrid. Faz diferença saber isto. O sentido de ligação é do detalhe para o mestre, ou seja, o seu dataset tblOrdemServico deve apontar para o MasterSource do dataset tblMaterialGasto (se não entendi errado quem é mestre e detalhe). Vocês está usando um DBGrid para a edição dos dados? Se for, você quer digitar o número da OS em uma coluna e visualizar os dados dela em outras duas colunas? Abraços
  22. Gabriel Cabral, "Access violation ..." é erro típico (para não dizer exclusivo) de acesso a área de memória não alocada para uma variável. Jhonas, com todas estas informações as vezes "passamos batidos", mas no caso de tentar passar um valor diferente do tipo esperado o comum é ocorrer um erro informando de que a conversão não é válida, algo como "xxx is not a valid date" ou coisa parecida. Posso estar enganado, mas pelo nome que o colega Grabriel Cabral deu aos componentes: - frmLocalControleCaixa => o form - GridLocalControleCaixa => o dbgrid no form eu acreditaria que a query de nome QueryLocalControleCaixa seria aquela ligada ao componente DBGrid de nome GridLocalControleCaixa. Sendo assim, podemos observar que a query foi aberta no seguimento abaixo, onde a primeira coluna do DBGrid receberá o foco e, por consequência, o próprio DBGrid: ... else begin With QueryLocalControleCaixa Do begin Close; SQL.Clear; SQL.Add('SELECT * FROM ESTACAI.dbf'); SQL.Add('WHERE CAIDAT = :pData'); SQL.Add('ORDER BY CAIDAT DESC, CAIHOR DESC'); ParamByName('pData').AsDateTime := StrToDate(txtLocalControleCaixa_Data.Text); Open; //GridLocalControleCaixa.SetFocus; GridLocalControleCaixa.SelectedIndex := 0; end; end; end; ... Assim, no próximo fragmento de código (onde está ocorrendo o erro), o if..then passará e a query é fechada: ... if GridLocalControleCaixa.Focused = True then begin With QueryLocalControleCaixa Do begin Close; SQL.Clear; SQL.Add('SELECT * FROM ESTACAI.dbf'); SQL.Add('WHERE CAIDAT = :pData'); ////////////////////// LINHA QUE O ERRO ACUSA/////////////////////// ParamByName('pData').AsDateTime := StrToDate(GridLocalControleCaixa.SelectedField.AsString); ////////////////////// LINHA QUE O ERRO ACUSA/////////////////////// Open; ...e aqui, é que penso estar o problema. Com a query fechada, não há SelectedField a ser utilizado para o parâmetro (o DBGrid não estará mostrando nada neste momento), pois não há fields que possam ter seu valor recuperado. A sugestão é que seja criada uma variável local para receber o valor deste campo, naquela primeira fração de código, e depois utilizar ela para ser atribuida ao parâmetro. Experimente fazer isto e dê um retorno. Abraços
  23. Jhonas, não estou certo de que o Count ajudaria, porque apenas diria quantos itens há na tabela mas não seria necessariamente o maior valor armazenado no banco (Max) - supondo que normalmente há registros excluídos. prod, conversei com minha esposa (que trabalhou com Oracle há algum tempo) e ela disse que talvez você pudesse fazer uso de uma variável local a sua transação para inicializar e obter o valor em questão. A idéia seria criar uma trigger do tipo pós-insert onde você obteria o valor do registro recém incluído via NEW.<nome campo> e atribuindo seu valor para uma variável com escopo de visualização para a sua conexão (não global). Assim, após você postar o registro no seu código, você poderia fazer um select sobre esta variável para obter o valor do campo. Não sei se consegui explicar direito, mas pareceu-me uma possibilidade, porém você precisaria dar uma pesquisada na documentação de como fazer isto. Abraços
  24. António44, por acaso no seu computador sua conta de usuário pertence a categoria Administrador e a dos outros computadores os usuários não pertencem a ela? Em teoria, se houver alguma nova atualização sobre o pacote SP3, basta que você use o recurso Windows Update para baixar qualquer atualização que esteja pendente. No site da Microsoft tem uma atualização pós SP3: Actualização de Segurança para o Windows XP Service Pack 3 (KB952069) Abraços
  25. danielrgoes, esta parece uma pergunta específica para a sessão Banco de Dados - Demais Bancos. Neste caso, não poderia ser utilizado o recurso de backup da tabela deseja e restauração da mesma no outro banco? Se uma questão para programação, então não há meios de fazer isto em um único SQL, e você teria que utilizar uma conexão para cada banco e mover os dados de um dataset para para outro. Pelo que sei, ainda não dá não. Na documentação de migração do MSSQL para Firebird ainda consta: Using Database Basics MS SQL allows clients to use many databases from a single connection. To do this, you can use the dbname.user.syntax, or execute an explicit USE statement. Firebird does not allow you to use different databases in the same SQL statement, but it does allow you to perform transactions spanning multiple databases. O Roadmap 2009, fala sobre um recurso que deve estar entrando na versão 2.5, que possivelmente implemente isto: * Queries against external databases apesar de que no Roadmap 2008, além deste, era citado um recurso para a versão 3.0 que não está mais presente na 2009, mas que parece expressar melhor esta funcionalidade: * Cross-database queries Abraços
×
×
  • Criar Novo...