Ir para conteúdo
Fórum Script Brasil

Micheus

Veteranos
  • Total de itens

    3.189
  • Registro em

  • Última visita

Tudo que Micheus postou

  1. Ramon Bedin, quanto a atualizar a barra de progresso você deverá incluir no evento OnWork do componente IdHTTP, uma chamada ao método ProcessMessages do objeto Application. Veja exemplo: procedure TFrmUpdate.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); begin // Atualiza barra de progresso ProgressBar1.Position := AWorkCount; ProgressBar1.Repaint; // dá oportunidade de processamento de mensagens pendentes (como atualização visual) Application.ProcessMessages; end; Quanto a questão de executar o processo de atualização sem intervenção do usuário, inicialmente lembro que você não poderá neste momento estar atualizando o seu programa que encontra-se em execução (isto não é possível). Mas, se for atualização de outros arquivos que não estejam em uso - sem problema. A solução em si, passa pelo uso do procedimento PostMessage que irá colocar uma mensagem na lista de mensagens a serem tratadas pela sua aplicação. O Post, indica que a mensagem vai para a lista e não é aguardada uma resposta para que o seu programa continue executando as linhas seguintes - diferente do uso de SendMessage (ver Win32 Reference para detalhes). Você precisará definir um tratador para a mensagem em seu form, e a sua chamada pode ocorrer no evento OnCreate, OnActivate ou OnShow - veja onde lhe traz melhor resultado (embora, seja mais apropriado que ocorra no último momento antes de a tela ser apresentada - OnShow). Exemplificando: ... const WM_STARTUPD = WM_USER +1; type TForm1 = class(TForm) ... private ... procedure WMStartUpdate(var Message :TMessage); message WM_STARTUPD; end; implementation ... procedure TForm1.WMStartUpdate(var Message :TMessage); begin // aqui iria o procedimento que atualmente está no evento // OnClick do botão, ou seja, o procedimento para a atualização end; procedure TForm1.Form1Create(Sender :TObject); begin ... PostMessage(Handle, WM_STARTUPD, 0, 0); end; ... end. Abraços
  2. valdmir, este assunto deveria estar em um novo tópico - já está fugindo ao assunto deste aqui. Continuando assim, vai virar bagunça e você pode inclusive ficar se auxílio. Por hora, dê uma olhada no final deste tópico. t+
  3. Sem dúvidas este não é o local - é um forum de programação e não hardware ou SO. Voce pode tentar adicionar este questionamento a este outro: Como Imprimir No Msdos Pelo Sistema Operacional Xp, já que é só uma variante dele. Mas fica este link como referência para que você possa experimentar uma possível solução: Connecting an MS-Dos Application to a Printer on a USB Port on Windows 2000 (deve funcionar no XP também) Abraços
  4. alexandre_prog, não é apropriado usar Firebird//Interbase porque, apesar de o Firebird ter surgido do Interbase v6, cada um segue seu próprio rumo e não são necessariamente compatíveis em tudo. O "erro" citado é um exemplo. select first skip firebird, retornam isto no Google.e no primeiro link você encontra: Migrando de Interbase 6 para FireBird 1.5 "(...) No INTERBASE não há o Select First Usa-se a clausula ROWS que por sua vez podem usar expressões e outras cláusuals como TO, TIED, PERCENT etc... eles implementam de forma um pouco diferente um exemplo simples é assim: SELECT PK_COD, CAMPO1, CAMPO2, CAMPO3 FROM nome_tabela ORDER BY PK_COD DESC ROWS 1 TO 2 ; (...)"
  5. Ainda pode ser útil a alguém... Se são máquinas separadas, como menciona, não devem haver. A única preocupação que deve haver é que a aplicação aponte para o servidor correto, porque ambos estariam aptos a responder a uma requisição pela porta 3050. Já quanto a rodar ambos em um mesmo computador - a princípio, apenas um ativo a cada vez: Running Firebird and InterBase together Executando Firebird e InterBase no mesmo computador t+
  6. Ferizinha, para funcionar o WriteLn para a LPT1 é necessário que a impressora na rede esteja "capturada" para a porta LPT1 do computador onde o programa está rodando. Voce pode dar uma olhada nesta alternativa postada pelo nosso colega paulobergo, onde há uma parte comentada que explica como acessar a impressora diretamente na rede (leia ele, e teste) Boa sorte
  7. Foi o que suspeitei. De novo, você deixou informação faltando. Então segue a sugestão que evitei de passar lá no início, por não ter certeza do que você realmente queria: select CFOP, sum(VRTOTAL) as VRTOTAL from T1 group by CFOP isto resulta em todos os CFOP somados de acordo com seu código, podendo ser inseridas as linhas resultantes na tabela T2 diretamente. Talvez você possa ainda, fazer de uma só vez (eu nunca testei usando group by): select CFOP, sum(VRTOTAL) as VRTOTAL INTO T2 from T1 group by CFOPtalvez seja necessário executar o DROP table T2, no lugar do seu DELETE from Tenho certeza que o colega Denis Courcy, já lhe teria sugerido algo parecido se você não tivesse omitido tantos detalhes. <_< Abraços
  8. acho que não consegui deixar claro o comentário. Vamos supor que você faça este processo através do click de um botão. Então, usando o exemplo que você mesmo deu, e partindo desta premissa de que se houver a informação, você soma o valor: T1 PK | CFOP | VRTOTAL 01 | 5929 | 280,88 02 | 5102 | 420,00 03 | 5102 | 32,90 04 | 5929 | 336,50 05 | 1102 | 150,00 06 | 2303 | 867,37 07 | 1102 | 213,00 08 | 2102 | 690,00 Então na tabela T2 eu teria como resultado (onde CFOP é a chave primária): CFOP | VRTOTAL 1102 | 363,00 2102 | 690,00 2303 | 867,37 5102 | 452,90 5929 | 617,38 Daí, o procedimento é executado uma outra vez (é clicado no botão de novo) Então na tabela T2 o resultado passaria a ser: CFOP | VRTOTAL 1102 | 726,00 2102 | 1.380,00 2303 | 1.734,74 5102 | 905,80 5929 | 1.234,76 É a este tipo de possibilidade a que me referia. Abraços
  9. Acesse minha pasta compartilhada no 4Shared e baixe Change TAB Key.zip Veja se lhe ajuda. Abraços
  10. Realmente é sempre bom postar a dúvida com seus detalhes relevantes - evita que fiquemos "falando" de algo que não é correto, podendo até confundir a quem pergunta. Duduh_Capixaba, só uma ressalva quanto a este tipo de procedimento: Voce tem algum meio de prevenir que a informação seja processada mais que uma vez? Do contrário, poderá gerar resultados indesejados, já que sempre é adicionado o valor da tabela T1 para a T2. Abraços
  11. não sou a melhor pessoa para opinar, já que não programo profissionalmente.Acredito que outros colegas possam falar a respeito. Apenas o mínimo necessário.Do ponto de vista visual, sou conservador e acho melhor manter a aparência que o usuário escolher para seu Windows. pode ser sim, caso você não tenha os códigos fonte e o proprietário não portá-lo para a versão que você espera usar. Se tiver os códigos isto pode ser mais facilmente contornável. Outros forums onde você poderia fazer estes questionamentos (precisa ser registrado), já que não dá para ter uma noção muito realista com a quantidade de colegas que lhe responderam este tópico e opnaram sobre o banco (apenas 6): DevMedia ActiveDelphi Abraços
  12. rclaudio7, releia esta parte: quanto às questões... primeiramente, já que você diz-se iniciante, dbedit não é um campo e sim um componente. Ele está sim associado a um campo da sua tabela (via dataset).O correto uso dos termos ajuda a não criar confusões quando você faz os questionamentos. ;) se o que você quiz perguntar é como fazer a inicialização do campo que está ligado ao DBEdit, então você deverá fazer uso da sugestão que fiz no post anterior: "Com isto em mente, localize no seu dataset o evento OnNewRecord (novo registro) e na eventual falta dele, algo como AfterInsert (que também ocorre após um Insert ou Append)." assim, supondo que o nome do campo seja DatSaida e do dataset TabVendas, neste evento você escreveria algo como: procedure TForm1.TabVendasNewRecord(Sender ...); begin TabVendasDatSaida.Value := Date; // Date é uma função que retorna a data atual // ou // TabVendas.FieldByName('DatSaida').Value := Date; // ou ... end; a forma de fazer isto pode variar um pouco de acordo com o tipo de componente de acesso (dataset) que você utiliza. você deverá usar a propriedade DisplayFormat do campo (Field) desejado. Se você adicionar os campos ao componente dataset em design-time, basta selecioná-lo e na janela Object Inspector localizar a propriedade citada. Se for fazer isto em tempo de execução, você pode fazer isto no evento OnCreate do form, como por ex.:TabVendasTotalVenda.DisplayFormat := '#.##0,00'; note que na máscara, é usado invertido em relação ao que você quer, porque ela é definida utilizando a notação americana (ponto no lugar de vírgula e vice-versa) Esta questionamento, eu já tentei explicar no item 4 do outro post. Talvez algum colega possa tornar isto mais claro a você. Leia alguma apostila, execute algum tutorial passo-a-passo e tente conhecer os componentes que você usará. Tem muito material na net (e aqui no forum). Use muito a tecla F1 em um componente, propriedade ou linha do código - o help tem quase tudo que você precisará saber. Se tiver dificuldades com inglês, use um tradutor on-line, como o Altavista BabelFish. Abraços
  13. schaukoski, com relação a versão, voce pode ler esta que citei como sendo 2.0 (versão principal) release 4 (a cada correção/otimização este último número aumenta) Esta é a "casa" do Firebird: http://www.firebirdsql.org (inglês) Nela você pode acessar a sessão de documentação, com algum material em português (pt-br) Application Tools: Front-end IBExpert (versão free - idioma selecionável) demonstração em flash, neste endereço: http://www.ibexpert.com/download/Demos/ (são 4 arquivos .htm - sem áudio) Firebird PHP Generator (freeware - tem para MySQL) SpeedCASE Personal Edition (gera aplicação com D7. Ver versão Personal - freeware) Access Component: MDO no SourceForge.net IB distribuído com Delphi ZeosLib no SourceForge.net Useful links: Suporte MDO no Yahoo Groups (português) Forum Firebird Experts (inglês) Firebase (português) Comunidade Firebird de lingua portuguesa Conheça o Firebird em 2 minutos (português) Ivan Prenosil's Firebird/InterBase site (inglês) IBExpert Database Training e Firebird - Google Video (inglês) Estes links responderão muitas das perguntas que irão aparecer. Ler é preciso. ;) 1) A forma de uso de ambos é praticamente a mesma. 2) D7 Curiosidade: Sabiam que há um hino para o Firebird? Pois é! A letra pode ser encontrada aqui, mas infelizmente o link para o mp3 está quebrado. :( Abraços
  14. warlockplus, como o lay-out são exatamente iguais, seu relatório é bem simples. Basicamente você vai precisar usar duas bandas GroupHeader (que agrupa os dados por Empresa e Fornecedor - uma para cada), uma detalhe (que mostrará as linhas com valores) e uma GroupFooter (que apresentará o somatório dos valores para o grupo). sabendo qual o layout a usar, basta que você habilite apenas a GroupBand que lhe é conveniente. é importante que você lembre-se de que os dados (dataset de origem) deve estar ordenado de acordo com o tipo de layout, ou seja, ordenado por Empresa ou Fornecedor. Com os links que você já tem para pesquisa, você deverá conseguir montar o relatório. Qualquer dúvida, avise. Abraços
  15. Jesc, não tem o que não entender nesta explicação, mas vamos tentar acrescentar algo... O cara sugere que você tem 5 botões no seu form: BtInserir, BtAlterar, BtExcluir, BtGravar e BtCancelar. Ele diz: - que inicialmente (pode ser em design-time - durante o desenho da tela), os botões BtInserir, BtAlterar, BtExcluir devem ter sua propriedade Enabled setadas para True ("iniciar habilitados"). E que os botões BtGravar e BtCancelar devem ter esta propriedade Enabled setadas para False ("iniciar desabilitados"); - e que o procedimento TrataBotoes deve ser chamado no evento OnClick dos botões BtInserir, BtAlterar, BtGravar e BtCancelar; Onde encontrar o tal evento? Selecione o botão (ou componente desejado) e localize na janela Object Inspector (normalmente à esquerda) a guia Events. Dê um duplo click no evento OnClick. Será lhe mostrado o editor do código e lá você faz a chamada ao procedimento. Deve ficar algo como: procedure TForm1.BtInserir(Sender :TObject); begin tratabotoes; end; o que a procedure faz é inverter o valor da propriedade Enabled, ou seja, se o botão está habilitado, ele será desabilitado. Já se estiver desabilitado, será habilitado. Bom, se ainda houver dúvida, informe qual, porque realmente não dá para saber que parte você não entendeu, já que o que o exemplo proposto não é realmente tão sofisticado assim. Abraços
  16. Me corrijam se eu estiver errado (e posso estar) :unsure: Mas, baseado no comentário: "(...) Sendo que na tabela T1 eu possuo vários dados duplicados, e na tabela T2 esses dados são a chave primária, portanto, não podem se repetir." não seria o caso de usar uma query com uma instrução SQL parecida com isto: select distinct Campo from T1 que retorna apenas uma ocorrência de Campo na tabela T1 e assim, minimiza a pesquisa na tabela T2. Ou ainda: select distinct Campo from T1 where not exists(select Campo from T2 where T1.Campo = T2.Campo)que deve retornar exatamente os campos da tabela T1 que ainda não existem na tabela T2. Duduh_Capixaba, com este outro comentário: Exemplo de estrutura da tabela T1 (cada "|" significa um campo diferente): você sugere estar falando dos campos (colunas) na estrutura da sua tabela T1. Mas, se o objetivo era falar de um determinado campo da estrutura da tabela (coluna), que se repete em várias linhas (registros), talvez ficasse melhor deixar claro de que: "|" significa um registro diferente, assim não fica dúvidas sobre o que você está falando. Abraços
  17. Vivendo&Aprendendo, o motivo é porque a alteração que sugeri resultou no mesmo efeito que o seu código. No processo de manipulação da mensagem enviada pelo sistema para a aplicação, chega até o procedimento a mensagem (Msg) que nós processamos ou mesmo os métodos antecessores (em inherited). Quando para a tecla VK_TAB o seu (e o "meu") código atribui a Msg.Result o valor 0, e não fazemos nada mais, ao retornar ao procedimento que chamou este nosso procedimento entende que a mensagem foi tratada e não faz mais nada, ou seja, não executa seu procedimento padrão. Foi isso que tentei explicar quando falei dos valores para Result no post anterior. Eu acabei por me precipitar ao citar a alteração, e não me dei conta que ficaria na mesma. Desculpe. :blush: Mas, vamos tentar sanar este problema... A proposta do colega Denis Courcy de usar o evento OnMessage do objeto Application tem como vantagem, aplicar-se a todos os forms - você não tem que duplicar o código em cada form. Entretanto, para este caso, haverão alguns efeitos colaterais, sendo um deles baseado no que citei acima: Ao "processarmos" a tecla ENTER, mas não informando ao método antecessor que fizemos isto (quando atribuirmos True ao parâmetro Handled), o foco será movido para o próximo controle pela chamada ao método Perform, mas será executado pelo procedimento padrão para a tecla pressionada e serão, gerados eventos como OnKeyPress, OnKeyDown e OnKeyUp. Só terá um porém: Será processada o evento pelo componente que está com o foco, ou seja, o componente seguinte ao que teve teclado o ENTER. Assim, no exemplo em que testei, após o edit havia um botão que teve seu procedimento executado como se eu tivesse pressionado ele (OnClick). Quando o próximo componente era um TEdit, resultava em um Beep - que é o padrão quando se tecla ENTER em um TEdit. Por outro lado, se atribuirmos True ao parâmetro Handled, informando que processamos a tecla, votaremos a estaca zero, pois os evento como OnKeyPress, OnKeyDown e OnKeyUp, não ocorrerão ao pressionar ENTER. É só testar estas situações, para entender o que tentei explicar. Mesmo assim, a sugestão é que você use esta última situação porque, além de ser mais genérica, o tipo de validação que você está fazendo é tem como lugar mais apropriado o evento OnExit do que o OnKeyDown. Sabe por quê? Porque usuário nem sempre usa só o teclado e ao usar o mouse para mover o foco, o seu processo de validação fica furado ao tratar apenas a tecla!!! Voce só tem que cuidar, ao usar o evento OnExit, quando houver algo como um botão de cancelamento, pois ao clicar nele será gerado o evento OnExit e neste caso, você deverá testar se o tal botão é o controle ativo (ActiveControl). Se optar por esta saída, segue procedimento para o evento OnMessage ajustado para ignorar a tecla TAB (que ficou faltando). Quanto a testar a classe do componente deve ser processado, fica o critério do que você acha que vai simplificar seu trabalho: - se as que não devem (exemplo do colega Denis Courcy): procedure TFrmP000000.prvMudarComEnter(var Msg: TMsg; var Handled: Boolean); begin if not((Screen.ActiveControl is TCustomMemo) or (Screen.ActiveControl is TCustomGrid) or (Screen.ActiveControl is TButton)) then if Msg.message = WM_KEYDOWN then case Msg.wParam of VK_RETURN, VK_DOWN: begin Screen.ActiveForm.Perform(WM_NextDlgCtl, 0, 0); Handled := True; end; VK_UP: Screen.ActiveForm.Perform(WM_NextDlgCtl, 1, 0); VK_TAB: Handled := True; end; end; - ou, se verificar as que devem ser processadas (exemplo abaixo): procedure TForm1.CustomOnMessage(var Msg: TMsg; var Handled: Boolean); begin if Msg.message = WM_KEYDOWN then if (Screen.ActiveControl is TCustomEdit) then case Msg.wParam of VK_RETURN : begin Screen.ActiveForm.Perform(WM_NEXTDLGCTL, 0, 0); Handled := True; end; VK_TAB : Handled := True; end; end; neste exemplo, usei a classe antecessora mais acima das classes TEdit, TMaskEdit, TDBEdit, TMemo e TDBMemo, que é TCustomEdit - antecessora de todas elas. Você descobre isto através do help, clicando em Hierarchy e achando as que são comuns aos componentes que lhe interessam verificar. o evento OnExit, ficaria assim: procedure TForm1.Edit1Exit(Sender: TObject); begin if ActiveControl <> btnSair then if Trim(TEdit(Sender).Text) = '' then begin Application.MessageBox('Campo não pode ser em branco!', 'Aviso', MB_ICONHAND+MB_OK); TEdit(Sender).SetFocus; end; end;e ele está construído de modo genérico, para que seja atribuído ao evento de outros TEdits que tenham esta validação. Abraços
  18. Vivendo&Aprendendo, você pode experimentar esta modificação: Procedure TForm1.CMDialogKey(Var Msg: TWMKEY); begin Msg.Result := -1; if ((ActiveControl is TDBEdit) or (ActiveControl is TEdit) or (ActiveControl is TDBComboBox) or (ActiveControl is TComboBox) or (ActiveControl is TDBLookupComboBox) or (ActiveControl is TDBMemo)) and (TEdit(ActiveControl).Focused) then begin if (Msg.Charcode = VK_TAB) then Msg.Result := 0 else if (Msg.Charcode = VK_RETURN) then SelectNext(ActiveControl, True , True); end; end; Observe que está sendo feito alguma coisa com o ENTER porque é o único momento em que você atribuia o valor -1 a Result. Se você souber porque deve fazer este tipo de atribuição, saberia que é a forma de você "dizer" para o sistema que você não processou o evento. Já quando você atribui o 0 (zero), você está dizendo que processou, e então, o sistema após a chamada ao seu procedimento não fará mais nada com ele. Para todos os efeitos, apenas quando for pressionado VK_TAB, você deveria enganar o sistema informando que processou a tecla. Abraços
  19. Greed, não que eu tenha conhecimento. A princípio, voce está usando um recurso que deve estar disponível no computador do cliente. Se não houver office instalado, seu programa falhará! Supondo que o recurso seja uma solicitação do cliente, acho que faz sentido que ele é quem se preocupe com a instalação de uma licença válida do Office. Agora, se você é quem está empurrando o recurso para o cara, e ele não estava ciente disto, acho melhor você falar a respeito com ele. Abraços
  20. Voce só poderá fazer, no seu programa, aquilo que consegue fazer no próprio Excel. Assim, ao proteger as células, não será possível alterar nada - inclusive apagar algumas colunas. Na verdade, você até pode permitir que alguma(s) coluna(s)/linha(s)/área(s) seja(m) modificada(s), desde que as células desta tenham sua propriedade de travamento desmarcada (todas estão marcadas, por padrão). Como já mencionei em outro tópico, tudo que você precisar saber sobre VBA do MSOffice, você encontrará nos arquivos de ajuda do Office (especificamente em C:\Arquivos de programas\Microsoft Office\Office\1046). Mas, facilitando um pouco as coisas segue a informação: - o método do objeto Sheet para bloquear a planilha chama-se Protect(<senha>) (Proteje); - para referenciar uma coluna inteira, usa-se a propriedade Columns[<nº coluna>] (Colunas) do objeto Sheet; - para referenciar uma linha inteira, usa-se a propriedade Rows[<nº linha>] (Linhas) do objeto Sheet; - para referenciar/selecionar uma área, usa-se a propriedade Range (escala, faixa - de valores); - o bloqueio é habilitado/desabilitado através da propriedade Locked (bloqueado); Exemplos; 1) bloquear planilha ativa, mas deixar a coluna 1 (A) liberada para alteração: ... MSExcel.ActiveSheet.Columns[1].Locked := False; MSExcel.ActiveSheet.Protect(''); MSExcel.ActiveSheet.SaveAs('C:\Teste.xls'); 2) bloquear planilha ativa, mas deixar a linha 5 liberada para alteração: ... MSExcel.ActiveSheet.Rows[5].Locked := False; MSExcel.ActiveSheet.Protect(''); MSExcel.ActiveSheet.SaveAs('C:\Teste.xls'); 3) bloquear planilha ativa, mas deixar a seleção A1 a B4, liberada para alteração: ... MSExcel.ActiveSheet.Range['A1:B4'].Locked := False; MSExcel.ActiveSheet.Protect(''); MSExcel.ActiveSheet.SaveAs('C:\Teste.xls'); Deixar a senha nula (como nos exemplos), resulta em qualquer pessoa poder desbloquear a planilha. O método Protect, aceita mais parâmetros - passar a senha é o mínimo que você precisará fazer. Veja mais detalhes no arquivo de ajuda. Abraços
  21. valdmir, você está brincando comigo. Não é?! <_< Leia denovo o post #17, bem no meio dele, onde eu começo dizendo: "Isto exposto, no caso de você precisar copiar todas as linhas ..." t+
  22. José Luiz, selecione o seu DBGrid e na janela Object Inpector, acesse o evento OnKeyPress e escreva este código: procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (Key = VK_LEFT) or (Key = VK_RIGHT) then Key := 0; // descarta a tecla end; caso este seu DBGrid opere hora com dgRowSelect = True e hora com dgRowSelect = False, você precisará incluir este teste no if..then: if (dgRowSelect in TDBGrid(Sender).Options) and ((Key = VK_LEFT) or (Key = VK_RIGHT)) then Abraços
  23. tudo bem, mas vejo que você não leu muito a respeito do assunto ou não entendeu.Você nunca vai colocar esta sequência para um mesmo dataset: tablepedidos.edit; Tablepedidos.Insert; tablepedidos.append; Edit => coloca o dataset em modo edição. Se o dataset estiver vazio(na primeira vez), equivale ao append; Insert => insere uma nova linha "em branco" no dataset, na posição atual (baseado em que registro está posicionado); Append => insere uma nova linha "em branco" no dataset, no final do mesmo. Acho que você entendeu minha afirmação. ;) Vamos lá... O motivo da mensagem "dataset not in editor or insert mode" (dataset não está em modo edição - ou mesmo inserção) deve-se ao fato de que voce primeiro o colocou em modo edição/inserção (usando os 3 métodos :huh: ) e depois utilizou o método Locate para verificar se o registro já existia. Sempre que você mover o "ponteiro" do registro no dataset, automaticamente ele sairá do modo edição/inserção (caso esteja) e em algumas situações, será automaticamente tentado realizar um Post (gravação dos dados). Mas o que seria mais lógico? O mais lógico, é que você primeiro faça a verificação e caso seja necessário, aí sim, execute todo aquele procedimento para inclusão da nova informação. (esta lógica, é uma regra para tudo que você deva fazer uma verificação antes de executar uma ação). Já vou antecipar, que para executar várias ações dependentes de um if .. then, você precisará utilizar o delimitador de blocos begin..end;. Outra observação que estava por fazer, é que supondo que este procedimento seja feito através do pressionar de um botão (como você citou inicialmente) e que os dados de origem já estão sendo visualizados em um DBGrid (tabela insumos), não faz sentido que você utilize a linha "tableinsumos.open" porque esta tabela já se encontra aberta e sendo visualizada em um DBGrid (e assim deverá permanecer). A tabela pedidos (tablepedidos), também já deverá estar aberta visto que você deverá estar visualizando os itens do pedido no terceiro DBGrid. Aplicando o que foi comentado, seu código ficará mais ou menos assim: tableinsumos.First; while not tableinsumos.EOF do begin if not Tablepedidos.Locate('Cod_insumo', tableinsumos.FieldByName('cod_insumo').value,[]) then begin tablepedidos.append; tablepedidos.FieldByName('cod_insumo').value := tableinsumos.FieldByName('cod_insumo').value; // outras atribuições vão aqui... tablepedidos.post; end; tableinsumos.Next; end; Dica: o uso de identação (estas tabulações que organizam a visualização do fluxo do programa) ajudam muito, então, tente usá-las e aqui no forum, faça uso das TAGs CODE e /CODE (devem estar entre couchetes [...] e o seu código entre as duas tags) - ajuda muito na visualização e auxílio. Abraços
  24. veja este tópico lhe ajuda ou este post do colega Jhonas que sugere o uso de outro componente. Abraços
  25. Usando a opção de busca do forum, procurando por "serial", você encontra estes tópicos: Serial Communication Interface Comunicação Via Porta Serial, Enviar informações para uma matriz-display Comunicação Rs232, Projeto em Delphi Acho que lhe ajudarão. Abraços
×
×
  • Criar Novo...