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

    Data como Parâmetro

    Carlos, se o código está exatamente deste jeito que você postou, então seu problema não deve ser, necessariamente, com a passagem de parâmetros. Observe esta parte do código; sql.Add(' values :XCD_INT_VENDA, :XCD_INT_PLANO_PAG, :XCD_INT_FORMA_REC, :XNUMERO_DOCUMENTO, :XDT_VENCIMENTO )'); está faltando o "(" da cláusula VALUES: sql.Add(' values (:XCD_INT_VENDA, :XCD_INT_PLANO_PAG, :XCD_INT_FORMA_REC, :XNUMERO_DOCUMENTO, :XDT_VENCIMENTO )'); Quanto a passagem do parâmetro, após a correção deverá funcionar, mas não é necessário a conversão como está anteriormente postado, tente assim: Parameters.ParamByName('XDT_VENCIMENTO').AsDateTime := StrToDate(edtDtVencimento.Text); Lembre-se, é sempre importante postar a mensagem de erro que você recebe - quem está do lado de cá não sabe o que você vê aí. ;) Abraços
  2. Johelson, o que ocorre é que você deve fazer esta verificação/adição apenas quando o texto já foi digitado, ou seja, quando o usuário deixa o componente - evento OnExit.Pode até ser conveniente você confirmar com o usuário se deve ou não incluir o novo item. Sim isto é correto, é assim mesmo que este componente funciona.Mas veja bem, se este componente busca a informação de uma tabela, você não acha que faz sentido que você guarde este texto adicionado na respectiva tabela? Sendo assim, além de adicionar a lista como já mostrado, em algum momento você deverá guardar esta informação na tabela para que numa próxima utilização ele esteja lá. Mas, também, você poderia gravá-lo em um arquivo (txt) local - o que não parece conveniente para este tipo de aplicação e informação, visto que é provável que você deseje compartilhar ela com outros usuários e manter um certo padrão em seu banco de dados. Vai que um usuário grava "São Paulo" e outro "S. Paulo"... Voce deverá guardar duas informações, não é (Cidade e UF)? Supondo que sejam dois campos na sua tabela de cidades, como é que você pretende gerenciar isto? Mostrar as duas informações na lista é simples, mas esperar que o usuário digite o nome da cidade seguido da UF (com ou sem delimitador) fica um pouco mais "complicado". É por isto que eu costumo utilizar um DBLookupComboBox, e ao seu lado adiciono um pequeno botão [...] para dar acesso a uma tela de cadastro onde os dados são solicitados e o usuário tem que informá-los corretamente, sem grandes problemas. Após uma inclusão como esta, basta atualizar o ListSource para que o registro apareça na lista e o usuário o selecione, já devolta na tela principal. Abraços Este é um dos motivos
  3. João, no caso de um simples StringGrid (TStringGrid), isto seria mais fácil. Para um DBGrid, eu no momento não teria como verificar uma forma de fazê-lo (se é que seria possível). O que ocorre na forma como você implementou, é que o hint será formado pela linha inicialmente selecionada quando você mostra a tela, e que normalmente é a primeira (esta linha, representa o registro atualmente posicionado no dataset - apesar de o grid mostrar várias linhas dele). Seria possível sim, alterar o conteúdo do hint de modo a refletir qualquer das linhas selecionadas num determinado momento. Mas, o hint diria respeito apenas a linha selecionada. Seria este o caso? Porque se for parta mostar as informações de uma linha que não esteja selecionada, esta cituação, como mencionei antes, eu não saberia lhe informar da possibilidade (por hora). Abraços
  4. José, supondo que este comando que você recebe você o adiciona no memo, não haveria qualquer problema em utilizar o tal método (procurar pela substring). Mas também poderia utilizar (se é que realmente você adiciona um comando por linha, e este memo tenha ReadOnly=true), o método IndexOf da propriedade Lines. Supor o memo com (uma sequencia em cada linha): $01$05$07$03$07 $04$06$09$03$08 $02$05$09$05$01 $07$08$07$01$03 $06$05$03$01$05 Novo comando recebido: ???? $07$06$03$01$03 então, de acordo com a instrução Copy, deveria ser inserido no memos apenas a sequencia: $07$06$03$01$03 O teste para verificar a existência poderia ser feito assim: if Memo2.Lines.IndexOf(Copy(ReceivedCmd, 5, Length(ReceivedCmd))) = -1 then Memo2.Lines.Add(Copy(ReceivedCmd, 5, Length(ReceivedCmd))); Como no conteúdo do memo2 exemplificado a sequencia não existi, ela deverá ser inserida e ficar: $01$05$07$03$07 $04$06$09$03$08 $02$05$09$05$01 $07$08$07$01$03 $06$05$03$01$05 $07$06$03$01$03 A título de reduzir processamento e simplificação, eu sugeriria que você utilizasse uma variável local para processar a sequencia: HexaValue := Copy(ReceivedCmd, 5, Length(ReceivedCmd)); if Memo2.Lines.IndexOf(HexaValue) = -1 then Memo2.Lines.Add(HexaValue); Abraços
  5. José, não ficou-me bem claro o que você estará monitorando no memo2. Mas, se a questão é verificar a existência de um fragmento de texto nas linhas de um memo, acho que você pode utilizar algo como: if AnsiContainsText(Memo2.Lines.Text, <texto a procurar>) then <contém texto> else <não contém> A função que você citou (AnsiSameText) verifica se os textos são iguais, e não se um sub-texto existe em outro. Abraços
  6. João, o componente ListBox não seria o mais indicado para este caso, já que você não vai conseguir colocar os dados no formato colunado (vai ficar uma porcaria mesmo). Voce pode ver este post sobre como utilizá-lo. Teria, ainda, a opção de utilizar um StringGrid (na seqüência do post acima eu exemplifico como). Quanto a utilizar o ListView, você vai precisar definir a propriedade ViewStyle = vsReport, adicionar as colunas (headers) e definir suas larguras através da propriedade Columns. A partir daí, basta popular o ListView. O primeiro post deste tópico tem um exemplo do que você deverá fazer para adicionar cada item/subitem. Mas fica a pergunta: Por que você não utiliza um DBGrid, que automatiza todo o processo? Veja se consegue ir a diante. Abraços
  7. Ok, é realmente assim que ele funciona. Ele é útil, quando você tem o cadastro da informação em outra tela - parece-mse não é seu caso. Com esta opção voltamos a sua questão inicial, e agora falando sobre o componente correto (que foi o que questionei inicialmente). O TDBComboBox permite isto que você quer fazer. No caso deste erro que você está tendo, deve ser porque o texto que é passado como parâmetro não está declarado em lugar algum. Alias, parece-me mesmo que deveria se referir ao texto digitado na caixa de edição do DBComboBox e que não existe na sua lista. Neste caso, este texto digitado é acessado pela propriedade Text do DBComboBox. Logo, seria algo como colocar no seu códigio:if dbcombobox.items.indexof(dbcombobox.text) = -1 then dbcombobox.items.add(dbcombobox.text); Mas tenho a impressão de que ainda assim, ele não será incluso na sua tabela no banco de dados. Teste e verifique. Abraços
  8. Ninguém disse que é fácil, não. Pelo menos quando se está começando. ;) Mas, se você não tiver dificuldades com inglês, vai a dica: utilize o help do Delphi - é muito bom!! Se você procura por Date (tem que "perguntar" em inglês), vai ver na lista um monte de opções relacionadas a datas. Segue rolando até que vai achar DateTime routines, e acessando ela você vai encontrar todo tipo de função para manipular datas. Pelo menos foi assim que aprendi Turbo Pascal (vixe faz tempo), Delphi e tudo o mais que resolvo aprender (usando o help), se bem que é verdade que hoje a net tem tudo que se procura. Quanto a sua dúvida, conseguiu resolver então? Abraços
  9. Denis, acho que está relacionado a Layered Windows (ref. msdn) Abraços
  10. Um bom ano para você também José. Sobre esta parte das suas questões (este tópico) podemos então dizer que está Resolvido? Ficando apenas o outro pendente? Abraços
  11. Micheus

    Ambiente Gráfico

    Seria interessante que você colocasse a mensagem de erro original e o código que é executado na função1. Do contrário, fica difícil alguém dar um palpite. ;) Abraços
  12. Que poste heim?! Se você editou o post, poderia ter alterado no código o item que você disse estar trocado. Neste caso, a linha: vr_totE := vr_totE + strtofloat(q_entrada.SQL[0]); passaria a: vr_totE := vr_totE + strtofloat(q_entrada.fields[0]); Quanto ao erro estar resolvido, seria sempre interessante que você mencionasse a solução do problema, já que esta informação pode vir a ser útil a outro colega. Vou colocar a correção aqui, apenas me corrija se eu estiver errado (deve ser uma destas): vr_totE := vr_totE + strtofloat(q_entrada.fields[0].Value); (caso este campo seja string) ou vr_totE := vr_totE + strtofloat(q_entrada.fields[0].AsString); (caso você o leia com string) ou vr_totE := vr_totE + q_entrada.fields[0].AsFloat; (caso este campo seja numérico) Abraços
  13. Acho que é só uma questão de você descer ao planeta terra... :D Fireboard, você só deu uma bobeada no código. Olha só o que você colocou no if: FormatDateTime('yyyy/mm/dd', date) > formatdatetime('aaaa/mm/dd', 06/02/2008) fora a questão da string de formatação, ainda não é possível você passa a data da forma como fez. Digamos que para compilar e "funcionar", deveria ficar assim: FormatDateTime('yyyy/mm/dd', date) > formatdatetime('yyyy/mm/dd', StrToDate('06/02/2008')) Mas, na verdade não há necessidade de você transformar a data para string de modo a fazer uma correta comparação de data (o que ocorre usando o formato yyyy/mm/dd). Além do mais, utilizar StrToDate, implica em você passar o texto da data na seqüência definida em ShortDateFormat que tem seu formato baseado nas configurações locais, podendo ser m/d/y, d/m/y, e y/m/d. Isto seria ruim, porque seu programa não ficaria "genérico". Uma vez que o campo TDataTime é um float, então você pode comparar os números diretamente. Assim, ficaria mais apropriado você trabalhar com este tipo e seu if ficaria assim: if Date > EncoceDate(2008, 2, 6) then EncodeDate está declarada na unit SysUtils (Delphi 7), assim como Date. Abraços
  14. Pois eu baixei o danado aqui e não deu problemas denovo. :wacko: Parece que você está premiado. Se os edits forem todos do mesmo tamanho e posição, ficaria mais fácil é adicionar eles em run-time. você quiz dizer apenas trocar o número (valor) da constante MaxNumEdits - este é o objetivo dela, facilitar este tipo de alteração. Pensando na possibilidade de adicionar os Edits em run-time, esta constante deveria ficar global à unit (não a procedure), e assim, ao alterá-la automaticamente você estaria modificando a quantidade de edits processados na função de totalização, bem como na de criação dos edits. ;) pois é, tem que servir para alguma coisa. heheheObserve que ela é do tipo Inteiro (longo), assim, va pode armazenar qualquer coisa nestes 4bytes (até um ponteiro, fazendo um type-cast) Abraços
  15. R.: Nesses Edits eu só mostro o total de aulas marcadas da respectiva categoria. R.: Não, a listagem para esse procedimento que estou tentando fazer é para as categorias B,C,D e E.É, então como está não vai rolar. :( Observe o seguinte, vamos supor que a categoria "C" tenha umas 7 aulas, então o seu TxtC.Text terá seu valor igual a "7". Certo?! Nesta condição, quando você testar: (Trim(DtmIza.QryPraticas.FieldByName('pCat').AsString) = 'C') and (StrToInt(TxtC.Text) > 5) o resultado vai ser verdadeiro e, por tanto, para cada linha a ser pintada no grid, a cor será alterada para clRed. Como resultado, você verá todo o seu grid em vermelho e não apenas os itens que ultrapassam a contagem 5. Esta contagem de excedentes é baseada na quantidade de aulas para o dia? Acho que você poderia utilizar aquela procedure que você criou no banco, para retornar estes dados no DBGrid (procedure STPCSLAUL neste post), e além de retornar o seqüencial (Ord), você poderia também retornar o número de ordem por categoria. Deste modo, supondo o nome pOrdCat, ao invés de você testar os Txt?.Text, você testaria este campo. Por ex.: (Trim(DtmIza.QryPraticas.FieldByName('pCat').AsString) = 'C') and (DtmIza.QryPraticas.FieldByName('pOrdCat').AsInteger > 5) acho que é por aí.
  16. As regras sugerem que você não tente tirar dúvidas utilizando o recurso de MP (Mensagens Pessoais) do forum:4.2 Não utilize o sistema de MP's para retirar dúvidas. Prefira postá-las no fórum, para que todos possam ajudar. Mesmo assim, quanto a lhe add no MSN fica por conta de algum outro colega que o deseje, já que você deixou seu e-mail. Eu apenas add alguém do forum apenas em certas circunstâncias (por hora, foram apenas 2). É que o tempo é meio curto e não dá para add cada um que solicitar, senão, vou ter que passar todo o tempo em off-line ;). Voce verá que, na medida do possível, sempre haverá algum colega disposto a ajudar. Com certeza é um componente muito interessante. Basicamente, como os outros data-aware, você configura as propriedades DataSource e DataField referentes a tabela que você está editando. A idéia do "lookup" está associada a busca de uma lista de valores a partir de outro dataset, motivo pelo qual você configura as propriedade ListSource (o datasource ligado ao dataset de onde você obtém a lista de valores), ListField (o campo ou lista de campos separados por ";") e KeyField (o campo chave que será atribuído ao dataset em edição, setado na propriedade DataField, quando o item na lista for selecionado). Uma característica deste componente é que você pode utilizá-lo sem necessitar estar ligado a um DataSource (alterando um determinado dataset a ele ligado). Nesta condição, qualquer item selecionado da lista, poderá ser obtido programaticamente via propriedade KeyValue, bem como uma seleção na lista pode ser feita setando esta propriedade para um valor que exista na lista. Esta propriedade está associada a propriedade KeyField, ou seja, os valores atribuídos ou lidos em KeyValue, corresponde àquele presente no dataset no campo definido por KeyField. É o tipo de aplicação útil em telas de filtro, onde você pode mostrar em uma lista os itens disponíveis e o usuário seleciona um deles a ser utilizado como filtro em um relatório, por exemplo. Ao utilizar mais que um campo na visualização, convém alguns "ajustes visuais" para que ao abrir a caixa de lista, ela tenha largura suficiente para apresentar as colunas. Por padrão, a largura da caixa quando aberta, é a mesma quando fechada (a definida em design-time), mas uma nova largura pode ser definida ao alterar a propriedade DropDownWidth (esta largura é em pixels). Quanto a largura de cada coluna, esta é definida pela propriedade DisplayWidth do(s) campo(s) adicionado(s) à ListField (esta largura é definida em caracteres - mais ou menos isto). Supondo que você mantenha os fontes padrões dos componentes, daria para fazer uma continha que facilita um pouco o cálculo da largura necessária (DropDownWidth) para mostrar as n colunas. Seria mais ou menos isto, para DisplayWidth >= 7: DropDownWidth = Σ [(7 x DisplayWidth) - (DisplayWidth -7 +1)] + 20 Este 20 é só uma aproximação. Ele corresponde a aproximadamente a largura da barra de rolagem vertical. É relevante ter uma idéia aproximada da largura da caixa, pois, quando aberta, ela não apresenta barra de rolagem horizontal. mesmo assim, seria conveniente ler e tentar entender aqueles assuntos listados no tópico que lhe passei (apenas sugestão). Abraços
  17. Johelson, um ComboBox apresenta apenas uma lista de strings, assim este tipo de componente mostra aquilo que foi inserido nele. É importante saber se você fala de um TComboBox ou de um TDBComboBox (data-aware) O recurso que você menciona, existe de forma fácil apenas no TDBLookupComboBox (propriedade ListField). Nos demais, você teria que criar mecanismos para mostrar da forma desejada (tipo, utilizando o desenho customizado). Caixa de listagem todos são, mas as funcionalidades e particularidades são outras. uma coisa puxa outra. Se você tiver uma tabela, você vai ver na lista o que você tem na tabela. Se não aparecer na listaa, vai ter que adicionar na tabela. Se você não tem tabela deve estar gravando em algum lugar. O componente apropriado depende do que você tem ou quer ter (tabela ou arquivo, ou o que você estiver usando).Fazer uma tabela só para os dois campos pode lhe economizar espaço em disco, além do mais é o tipo de informação que normalmente está em tabela específica onde você tem o Código da cidade, nome da cidade e UF, sendo que nos registros que fazem referência a determinada cidade, você estará utilizando o código da cidade para relacionamento. É uma questão de aplicar as regras de modelagem de dados (até 3ª forma normal) - se interessar veja este tópico Abraços
  18. samyr, já que é um arquivo texto, não bastaria que você lesse ele linha-a-linha e, a cada linha, procurasse pelo caracter "," e fosse processando cada palavra (substring)?
  19. robinhcne, primeiramente, indiferente de o código funcionar ou não, você deve observar que a chamada ao método DbgRel.DefaultDrawColumnCell(Rect, DataCol, Column, State); deve ser a última coisa a ser feita. Apesar de comentado todo o seu teste (condições nos if's), já dá para ver que o procedimento não está no lugar certo. Observe que o objetivo de chamar este método é que o grid seja desenhado após todas as configurações do canvas terem sido alteradas. Quanto a questão em si, cabem uns questionamentos: - estes edits (tipo TxtB.Text) são campos que você digita ou que apenas mostram alguma totalização (no caso número de aulas)? - a listagem no DBGrid é feita apenas por uma categoria de cada vez, como você colocou no seu exemplo? Se sim, então você poderia utilizar a propriedade RecNo do dataset e determinar quando ela é > que n aulas. Se não, a coisa complica um pouco. Abraços
  20. Eu diria que apenas parece. Talvez porque você não consiga visualizar exatamente a operação com os edits, se comparado com a forma como você postou seu exemplo.Mas, eu esperava realmente que você fizesse alguns questionamentos. É mais fácil você dizer do que tem dúvida, do que eu sair escrevendo um monte (como agora) e você já saber metade do que estou escrevendo. Diferente em termos: - É também no OnExit que o meu exemplo faz o cálculo, porém não faz só isto - ele reformata o texto, caso o cara digite "15", será atualizado o edit para "15,00". - O somatório que você coloca em um único label, também pode ser assim colocado no meu exemplo, já que ele coloca sub-totais por valor digitado. Basta que utilizemos apenas um label para mostrar o valor, ao invés de uma a cada edit. Como está, no último label, você terá o valor total de qualquer modo - questão de adaptar. Mas, realmente há mais trabalho do que o necessário para o que você queria. É que entendi que você queria visualizar o sub-total ao lado de cada item, como em um extrato bancário. :blush: Vou colocar cada pedaço aqui sem os comentários existentes no fonte para que não pareça mais complicado do que é, bem como vou utilizar apenas um label para o total. A forma como você exemplificou que o seu código está hoje, não é muito viável para a quantidade de Edits que você pretende utilizar (84, se bem que nada que um copiar colar não resolva...). Então, a idéia é a de que tenhamos um procedimento para somar, em um loop, o valor de todos estes edits (procedure CalcValues). Para fazer isto, da forma mais automatizada possível, torna-se importante padronizar o nome dos edits, de modo a acessarmos eles através de seu nome. Foi o que fiz quando dei a eles o nome Valor<n> (onde <n> corresponde a um número sequencial, que no seu caso, seria de 1 a 84). Este procedimento nos viabiliza o uso do método FindComponent(<nome_componente>) (do Form), que nos retorna o componente (neste caso um Edit), do qual podemos converter seu valor textual em valor numérico, em um loop, para que possamos chegar ao resultado final (o valor total digitado nos edits) a ser colocado em um label (ValorTotal): // Procedimento para totalizar Edits procedure TForm1.CalcValues; const MaxNumEdits = 8; // define máximo indexador dos Edits a verificar - no seu caso será 84 var Idx :Byte; Total :Double; edValue :TEdit; begin Total := 0; for Idx := 1 to MaxNumEdits do begin edValue := FindComponent(Format('Valor%d', [Idx])) as TEdit; if Assigned(edValue) and (edValue.Text <> '') then Total := Total +StrToFloat(StringReplace(edValue.Text, '.', '', [rfReplaceAll])); end; ValorTotal.Caption := FormatFloat('#,##0.00', Total); end; Bom, este procedimento para totalização deverá atualizar o label ValorTotal, a cada valor informado. Para isso, como você já havia instruído, teremos que fazê-lo no evento OnExit de cada Edit. Mas não vamos escrever o mesmo código para o evento de cada um dos edits do form, já que todos farão a mesma coisa. Assim, já que sabemos que o parâmetro Sender neste evento, diz respeito ao edit que o chamou, escreveremos o procedimento genérico para um e depois atribuímos ao evento dos outros Edits. Neste procedimento faremos a validação do valor digitado para, só depois, chamar o procedimento de totalização, já com um valor válido: // procedimento do evento OnExit do 1º edit, posteriormente atribuído ao evento dos demais procedure TForm2.Valor1Exit(Sender: TObject); var Value :Double; begin try Value := StrToFloat(StringReplace(TEdit(Sender).Text, '.', '', [rfReplaceAll])); TEdit(Sender).Text := FormatFloat('#,##0.00', Value); // reformatamos o edit CalcValues; // atualiza label com valor total except on E:Exception do begin E.Message := Format('"%s" não é um valor válido!', [TEdit(Sender).Text]); TEdit(Sender).SetFocus; raise; end; end; end; E por último, tem a questão de que ao teclar ENTER, estando o edit nulo, deve ser verificado o valor do edit anterior e atribuído a este último. Ainda incrementando esta questão, automaticamente passamos o foco para o próximo edit, agilizando a digitação. Para isto, de modo similar ao feito com evento OnExit, criamos o procedimento para o evento OnKeyDown do 1º edit e o atribuímos ao respectivo evento dos demais: // procedimento do evento OnExit do 1º edit, posteriormente atribuído ao evento dos demais procedure TForm2.Valor1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var Edit :TEdit; begin if (Key = VK_RETURN) and (Shift = []) then begin if (TEdit(Sender).Tag > 1) and (Trim(TEdit(Sender).Text) = '') then begin Edit := FindComponent(Format('Valor%d', [TEdit(Sender).Tag -1])) as TEdit; TEdit(Sender).Text := Edit.Text; end; FindNextControl(TEdit(Sender), True, True, True).SetFocus; end; end;Como é possível observar, também fiz uso da propriedade TAG. Para cada edit, também atribuí a esta propriedade o respectivo número seqüencial. Este procedimento, otimiza bastante a obtenção da posição (número) do edit (atual, anterior e posterior). Este processo de atribuir o evento do 1º componente para os demais, não tem nada de tedioso. Basta que selecione todos os componentes edit e na propriedade OnExit e OnKeyDown (via janela Object inspector) selecione o respectivo procedimento que aparecerá na lista. Alguém poderia ainda questionar o porque de eu não ter utilizado o evento OnKeyDown do Form (tendo sua propriedade KeyPreview habilitada), ao invés de utilizar o de cada edit. Na verdade, poderia ser feito deste modo sim. Apenas optei por esta abordagem, porque caso hajam outros edits no form o código teria que ser um pouco mais truncado. Isto porque, monitorando todos os evento OnKeyDown que o form recebe, deveríamos testar a classe do sender, para saber se trata-se de um TEdit e, sendo um, teríamos de verificar se por acaso seria um dos que desejamos processar e não outro. Bom, segue anexo esta nova versão (os comentários do código estão nela). Espero que seja de maior utilidade agora e que tenham diminuídas as suas dúvidas (aguardo as próximas ;)). Abraços ProjEder2.zip
  21. Acredito que a resposta seja sim às duas perguntas. Não sei exatamente o que você pretende passar via conexão, mas se for apenas coisa simples como mensagem de texto (como aparentemente você mencionou), acredito que seja apenas uma questão de você definir seu próprio protocolo, baseado no que eu exemplifiquei. Deve funcionar perfeitamente. Abraços
  22. brugall, acho que não está muito claro.Voce quer criar um programa em delphi para atualizar uma pagina no navegador aberto? Ou quer criar um programa em que para atualizar seus dados (que estão na tela), o usuário pressiona F5?
  23. João, acesse este link, baixe a última versão (1.2.3).Acompanha um exemplo neste arquivo zipado (pasta examples) - o mesmo que você vê na página indicada. ou seja:- Depois de descompactar o arquivo na pasta do delphi, você deve entrar na opção Environment Options e acrescentar o caminho em Library Path. - Para utilizar no seu programa, acrescente os arquivos zlibex e zlibexgz na cláusula uses. Abraços
  24. Eder, lembrei de que você utiliza o Delphi 4 (se não me engano), então, caso você ocorra um erro de compilação informando de que a função StringReplace não está definida, é porque ela realmente não existe na sua versão (no Delphi 7, ela está na unit SysUtil). Bom, se for o seu caso, segue minha versão da função que fiz no Delphi 3 (deve ficar compatível com o 4): function StringReplace(S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string; var Idx, Offset :Integer; S_Case, OldPattern_Case: string; begin if rfIgnoreCase in Flags then begin S_Case := UpperCase(S); OldPattern_Case := UpperCase(OldPattern); end else begin S_Case := S; OldPattern_Case := OldPattern; end; Idx := Pos(OldPattern_Case, S_Case); Offset := Idx; if Idx > 0 then repeat Delete(S, Offset, Length(OldPattern)); Insert(NewPattern, S, Offset); Delete(S_Case, 1, Idx); Idx := Pos(OldPattern_Case, S_Case); Offset := Offset +Length(NewPattern)+ Idx -1; until not(rfReplaceAll in Flags) or ((Idx = 0) and (rfReplaceAll in Flags)); Result := S; end; Depois de tê-la feito, é que lembrei de recortá-la do fonte disponível no Delphi 7 :blush: : function StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string; var SearchStr, Patt, NewStr: string; Offset: Integer; begin if rfIgnoreCase in Flags then begin SearchStr := AnsiUpperCase(S); Patt := AnsiUpperCase(OldPattern); end else begin SearchStr := S; Patt := OldPattern; end; NewStr := S; Result := ''; while SearchStr <> '' do begin Offset := AnsiPos(Patt, SearchStr); if Offset = 0 then begin Result := Result + NewStr; Break; end; Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern; NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); if not (rfReplaceAll in Flags) then begin Result := Result + NewStr; Break; end; SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); end; end; Para ambas as opções, você deverá declarar na cláusula TYPE o conjunto (SET) de flags TReplaceFlags: type TReplaceFlags = set of (rfReplaceAll, rfIgnoreCase); Observe, ainda, que no Delphi 3 não é conveniente o uso da cláusula CONST no cabeçalho da função (como está definida na do Delphi 7), pois haverá erro de compilação do código. Pode ser que também ocorra isto no Delphi 4, no caso de você optar pela codificação da Borland. Abraços
  25. Esta mensagem aparece porque a sua versão do WinZip é de avaliação (Tryout) - então, não tem como. Talvez seja conveniente você utilizar um componente para isto. Veja este tópico: Backup Abraços
×
×
  • Criar Novo...