Copiar string de forma peculiar
17/06/2008
0
preciso fazer o seguinte. Uma determinada string, não tem um valor
exato. Ela pode vir assim: WWWWWW 1 x 63,00 ou WWWWWW10 x 63,00
O que eu preciso é copiar todos os W´s, depois o 1 ou 10 e depois o
valor. Um copy length(sting) não dá, senão ele copia toda a linha.
Se a quantidade ou valor fossem fixos, tipo 001 ou 010, aí seria
fácil, mas não é. Essa é a minha dificuldade no momento. Como faço
uma rotina que me traga o que eu quero.
Os W´s são minha descrição, que terá até 26 caracteres, depois o
1 ou 10 é minha quantidade e depois o valor. Como faço então?
Espero ter sido claro.
Paulo
Posts
17/06/2008
Emerson Nascimento
de qualquer forma - pela sua explicação - sugiro a você fazer a varredura na linha, de trás pra frente.
procedure TForm1.BitBtn2Click(Sender: TObject); var texto: tstringlist; i, j: integer; descricao, valor: string; vlrUnit, Qtd: double; begin texto := tstringlist.create; texto.Add(´WWWWWW 1 x 63,00´); texto.Add(´WWWWWWDDRR DDDDDD10 x 63,03´); texto.Add(´WWWWWW XXXXXX ZZZZZZZZZ012x64,67´); // varre o arquivo-texto for i := 0 to texto.Count-1 do begin descricao := texto[i]; valor := ´´; // varre a linha de trás pra frente for j := length(descricao) downto 1 do if UpperCase(descricao[j])[1] in [´X´, ´,´, ´ ´, ´0´..´9´] then valor := descricao[j] + valor else break; descricao := copy(descricao, 1, length(descricao)-length(valor)); j := pos(´X´, UpperCase(valor)); Qtd := StrToFloatDef(trim(copy(valor,1,j-1)),0); vlrUnit := StrToFloatDef(trim(copy(valor,j+1,length(valor))),0); ShowMessage(´Descricao:´+descricao+#13´Quantidade:´+ FormatFloat(´0´,Qtd)+13´Valor unitário:´+FormatFloat(´,0.00´,vlrUnit)); end; end;
17/06/2008
Paulo
17/06/2008
Brunodsr
Funcao para separar a string em tres partes e retornar um StringList com elas
function TForm1.f_divideStrings(sWord: String): TStringList; var i, nTam:integer; sAux, sAux2, sAux3 : String; bControl:Boolean; begin //Inicializando as variaveis result := TStringlist.Create; sAux := ´´; sAux2 := ´´; bControl := true; sAux3 := Trim(sWord); //Varrendo a string original e retirando a primeira parte dela (WWWW) nTam := length(sAux3); for i:= 1 to nTam do begin if (UpCase(sAux3[i]) in [´A´,´B´,´C´,´W´,´Z´]) and bControl then sAux := sAux + sAux3[i] else begin sAux2 := sAux2 + sAux3[i]; bControl := False; end; end; //Alimentando a primeira string Result.Add(sAux); //Limpando as variáveis bControl := True; sAux3 := Trim(sAux2); sAux := ´´; sAux2 := ´´; //Varrendo o restante da string e retirando a segunda string dela (1, 2..10) nTam := length(sAux3); for i:= 1 to nTam do begin if (sAux3[i] in [´0´,´1´,´2´,´3´,´4´,´5´,´6´,´7´,´8´,´9´]) and bControl then sAux := sAux + sAux3[i] else begin sAux2 := sAux2 + sAux3[i]; bControl := False; end; end; //Alimentando a segunda string Result.Add(sAux); //Limpando as variáveis sAux3 := Trim(sAux2); sAux := ´´; sAux2 := ´´; //Varrendo o restante da string e retirando a ultima string dela (4.5, 4.00, ...) nTam := length(sAux3); for i:= 1 to nTam do begin if sAux3[i] in [´0´,´1´,´2´,´3´,´4´,´5´,´6´,´7´,´8´,´9´,´.´,´,´] then sAux := sAux + sAux3[i]; end; //Alimentando a segunda string Result.Add(sAux); end;
Usando a funcao lendo de um edit
procedure TForm1.Button1Click(Sender: TObject); var StringList: TStrings; begin StringList := f_divideStrings(Edit1.Text); Showmessage(´1ª Parte: ´+StringList[0]+1310+ ´2ª Parte: ´+StringList[1]+1310+ ´3ª Parte: ´+StringList[2]+1310); end;
Espero ter ajudado
17/06/2008
Carlosrm
se eu entendi, toda linha do arquivo texto começa com ´wwwwww´, seguida por um fator (1 .. 10), mais um ´ x ´ e também um número com duas casas decimais, cujo separador de decimais é uma vírgula (,).
Nesse caso, se você localizar a posição da vírgula, será possível copiar a substring da linha, que começara em 1 e vai até a posição da vírgula mais 2 (supondo que são sempre duas casas decimais). A substring não terá um tamanho único, mas você sempre saberá o tamanho exato a copiar.
No caso de poder aparecer uma outra vírgula, por exemplo, no meio dos ´ww..w´, você poderá considerar apenas a vírgula que vier depois do x...).
Vai precisar obter a posição do ´x´ em cada linha... (função pos()...)
Um outro caminho ( me parece mais trabalhoso), seria verificar a cada linha do txt lida, se o fator (1..10) tem uma ou dois (ou mais) dígitos. Se tiver menos que o necessário, poderia completar com espaços, zeros, o que for apropriado.
Espero que a idéia possa ser útil...
17/06/2008
Emerson Nascimento
você testou o código que eu te passei? ele não fixa nada. você pode passar o que quiser.
porque você achou que o código está esperando ´1´ depois da string???
note no preenchimento da stringlist:
texto := tstringlist.create;
texto.Add(´WWWWWW 1 x 63,00´);
texto.Add(´WWWWWWDDRR DDDDDD10 x 63,03´);
texto.Add(´WWWWWW XXXXXX ZZZZZZZZZ012x64,67´);
veja que na terceira linha, depois da string, vem um zero.
17/06/2008
Lauro.balceiro
procedure TForm1.Button1Click(Sender: TObject); var suaString : String; parte1 : String; parte2 : String; parte3 : String; aux : String; begin suaString := ´WWWWWW 1 x 63,00 ´; aux := StrPos(PChar(suaString), ´x´); parte3 := trim(copy(aux,2,length(aux))); aux := trim(StringReplace(suaString,aux,´´,[rfReplaceAll])); parte1 := copy(aux,0,6); parte2 := trim(StringReplace(aux,parte1,´´,[rfReplaceAll])); ShowMessage(parte1 + ´ - ´ + parte2 + ´ - ´ + parte3); end;
17/06/2008
Luciano.lirio
procedure TForm1.Button1Click(Sender: TObject); var I: Integer; J: Integer; H: Integer; Linha: String; Descricao: String; Qtde: String; Valor: String; begin Linha := ´WWWWWWDDRR DDDDDD10 x 63,03´; for I := 1 to Length(Linha) do if (Linha[I] in [´0´..´9´]) then Break; Descricao := Copy(Linha,1,I-1); for J := I to Length(Linha) do if not (Linha[J] in [´0´..´9´]) then Break; Qtde := Copy(Linha,I,J-I); for H := J to Length(Linha) do if (Linha[H] in [´0´..´9´]) then Break; Valor := Copy(Linha,H,Length(Linha)-H+1); ShowMessage(Descricao+´;´+Qtde+´;´+Valor); end;
Clique aqui para fazer login e interagir na Comunidade :)