Gravar no arquivo

Delphi

10/10/2013

Pessoal. Bom Dia!

Estou com problemas em uma implementação.

Tenho a procedure abaixo:
procedure TfrmPrincipal.PopulaNovoArquivo(var matriz: array of string;  valor, novaLinha, arq: string);
var
  i, j: integer;
  ListaArray, lst: TStringList;
begin
  ListaArray := TStringList.Create;
  lst := TStringList.Create;
  ListaArray.Clear;
  lst.Clear;

  for i := low(matriz) to High(matriz) do
  begin
    ExtractStrings(['|'], [], PChar(matriz[i]), ListaArray);
    if ListaArray[0] = valor then
    begin
      matriz[i] := novaLinha;
    end;
  end;
  ListaArray.Free;

  for j := low(matriz) to High(matriz) do
  begin
    lst.Add(matriz[j]);
  end;
  lst.SaveToFile(arq);
  lst.Free;
end;

O que esta procedure faz é o seguinte: Ele recebe um array e 3 campos string.
A ideia é pegar esse array, fazer una comparação pelo paramento 'valor' e, no índice(que é único), que for encontrado o 'valor', eu irei substitui o conteúdo desse índice pelo parâmetro 'novaLinha' e então, paro o loop for e já gravo todo o array novo em um arquivo txt.

2 erros estão acontecendo.

1) Aqui, deveria alterar o array, não esta alterando
  for i := low(matriz) to High(matriz) do
  begin
    ExtractStrings(['|'], [], PChar(matriz[i]), ListaArray);
    if ListaArray[0] = valor then
    begin
      matriz[i] := novaLinha;
    end;
  end;                        


2) Aqui, deveria salvar o conteúdo do array alterado no arquivo txt: acesso negado ao arquivo
  for j := low(matriz) to High(matriz) do
  begin
    lst.Add(matriz[j]);
  end;
  lst.SaveToFile(arq);
  lst.Free;                                

Como corrigir esses dois erros?
Detalhe o array esta testado e chegando Ok dentro da procedure. o problema é depois de passar pelo for.
Carlos Rocha

Carlos Rocha

Curtidas 0

Respostas

Carlos Rocha

Carlos Rocha

10/10/2013

Corrigido a parte do array:
procedure TfrmPrincipal.PopulaNovoArquivo(var matriz: array of string;
  valor, novaLinha, arq: string);
var
  i, j: integer;
  ListaArray, lst: TStringList;
begin
  for i := low(matriz) to High(matriz) do
  begin
    ListaArray := TStringList.Create;
    ListaArray.Clear;
    ExtractStrings(['|'], [], PChar(matriz[i]), ListaArray);
    if ListaArray[0] = valor then
    begin
      matriz[i] := novaLinha;
    end;
  end;
  ListaArray.Free;

  lst := TStringList.Create;
  for j := low(matriz) to High(matriz) do
  begin
    lst.Add(matriz[j]);
  end;
   ShowMessage(lst.Text);
  //lst.SaveToFile(arq);
  lst.Free;                          
end;  

Falta-me apenas a parte do acesso ao arquivo para altera-lo. Esta dando que não pode criar o arquivo.
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

Pelo que entendi está dando erro na linha --> //lst.SaveToFile(arq); ? Seria isso ? Não identifiquei aonde vc está criando esse Arq.
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

Achei. O erro estava em outro formulário.
Estava abrindo o arquivo mas não chagava a fechar ele. Então, não tinha ´permissão de escrita.
procedure TfrmPesquisa.btnProcurarClick(Sender: TObject);
var
  linha, funcionario: string;
  Parte: TStringList;
  arq: TextFile;
begin
    AssignFile ( arq, Principal.fileName );
    reset ( arq );
    funcionario:=txtNome.text;
    while not Eof ( arq ) do
    begin
      ReadLn ( arq, linha );
      Parte := TStringList.Create;
      Parte.Clear;
      ExtractStrings(['|'],[], PChar(linha), Parte);
      if (Parte[0]=funcionario) or (Parte[1]=funcionario) then
      begin
        nome:=Parte[0];
        CPF:=Parte[1];
        salario:=Parte[2];
        idade:=Parte[3];
         CloseFile (arq);
         frmPesquisa.Hide();
         frmFuncionarios.show();
         Parte.Free;
         abort;
      end;
    end;
    ShowMessage('Nenhum resultado para sua Pesquisa!');
    CloseFile (arq);
end;

eu preciso arranjar uma forma de sair dessa while sem abortar a operaçao de fora a chegar no closeFile (arq) lá embaixo
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

Pelo que vi no seu código, existe um if que dentro dele tá fechando o arquivo.
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

Sim.
só que, aparentemente, não fecha.

A ideia é, se encontrar uma combinação, no form de pesquisa, popular as variáveis e fechar o arquivo pois vou precisar dele aberto e não estou conseguindo fechar.
procedure TfrmPesquisa.btnProcurarClick(Sender: TObject);
var
  linha, funcionario: string;
  Parte: TStringList;
  arq: TextFile;
begin
    AssignFile ( arq, Principal.fileName );
    reset ( arq );
    funcionario:=txtNome.text;
    while not Eof ( arq ) do
    begin
      ReadLn ( arq, linha );
      Parte := TStringList.Create;
      Parte.Clear;
      ExtractStrings(['|'],[], PChar(linha), Parte);
      if (Parte[0]=funcionario) or (Parte[1]=funcionario) then
      begin
        nome:=Parte[0];
        CPF:=Parte[1];
        salario:=Parte[2];
        idade:=Parte[3];
        CloseFile (arq);
        frmPesquisa.Hide();
        frmFuncionarios.show();
      end;
      Parte.Free;
      exit;
    end;
    ShowMessage('Nenhum resultado para sua Pesquisa!');
    CloseFile (arq);
end;    

Testei o SaveToFile co outro arquivo e deu certo.
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

deixa eu ver se eu entedi, quando ele entra dentro do if tem um closearq, e não tá fechando ?
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

Sim. Fiz usando uma boolena mas tambem não deu!
procedure TfrmPesquisa.btnProcurarClick(Sender: TObject);
var
  linha, funcionario: string;
  Parte: TStringList;
  arq: TextFile;
  sair: boolean;
begin
    sair:= false;
    AssignFile ( arq, Principal.fileName );
    reset ( arq );
    funcionario:=txtNome.text;
    while (not Eof ( arq )) and (sair=false) do
    begin
      ReadLn ( arq, linha );
      Parte := TStringList.Create;
      Parte.Clear;
      ExtractStrings(['|'],[], PChar(linha), Parte);
      if (Parte[0]=funcionario) or (Parte[1]=funcionario) then
      begin
        nome:=Parte[0];
        CPF:=Parte[1];
        salario:=Parte[2];
        idade:=Parte[3];
        sair:=true;
        Parte.Free;
        frmPesquisa.Hide();
        frmFuncionarios.show();
      end;
    end;
    if sair=false then
    begin
     ShowMessage('Nenhum resultado para sua Pesquisa!');
    end;
    CloseFile (arq);
end;                       

Sistinha para a Faculdade
http://www.guicapas.com.br/teste.zip
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

tenta usar :


repeat


until sair = true;






GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

O laço esta saindo normal
O problema é com o close(arq)
É um projeto (estudo) para a faculdade.
Pode baixalo aqui
[url]http://www.guicapas.com.br/teste.zip[/url]
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

Tem como manda o projeto pra mim roda o danado aqui
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

[url]http://www.guicapas.com.br/teste.zip[/url]
É Lazarus tá!
Facul só software livre
Taí
Tem u arquivo funcionarios.txt no diretório da aplicaçao
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

Fiz um teste aqui e deu certo, se achar o funciinário e pega os dados, se não dá mensagem e fecha o aquivo, no seu exemplo, notei que vc estava fechando o arquivo enquanto lia o mesmo, ae não dá, segue o exemplo abaixo :


procedure TForm1.Button1Click(Sender: TObject);
var
  Arq   : TextFile;
  Texto : string;
  Txt   : TStringList;
  achou : Boolean;
begin
  Txt := TStringList.Create;
  Txt.Delimiter := '|';
  AssignFile(Arq,'Y:\Ricardo\teste\Ricardo\funcionarios.txt');
  Reset(Arq);
  memo1.clear;

  if not EOF(Arq) then
  repeat
    ReadLn(Arq, Texto);
    Txt.DelimitedText := Texto;
    if Txt[0] = Edit1.Text then begin
      Memo1.lines.Add('Nome    : ' + txt[0]);
      Memo1.lines.Add('Cpf     : ' + txt[1]);
      Memo1.lines.Add('Salario : ' + txt[2]);
      Memo1.lines.Add('Idade   : ' + txt[3]);
      achou := true;
    end;
  until achou = true;
  if not achou then begin
    ShowMessage('Nenhum resultado para sua Pesquisa!');
    CloseFile(arq);
  end;
end;
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

Mas onde eu fecho o arquivo enquanto lei-o?
procedure TfrmPesquisa.btnProcurarClick(Sender: TObject);
var
  linha, funcionario: string;
  Parte: TStringList;
  arq: TextFile;
  sair: boolean;
begin
    sair:= false;
    AssignFile ( arq, Principal.fileName );
    reset ( arq );
    funcionario:=txtNome.text;
    while (not Eof ( arq )) and (sair=false) do
    begin
      ReadLn ( arq, linha );
      Parte := TStringList.Create;
      Parte.Clear;
      ExtractStrings(['|'],[], PChar(linha), Parte);
      if (Parte[0]=funcionario) or (Parte[1]=funcionario) then
      begin
        nome:=Parte[0];
        CPF:=Parte[1];
        salario:=Parte[2];
        idade:=Parte[3];
        sair:=true;
        Parte.Free;
        frmPesquisa.Hide();
        frmFuncionarios.show();
      end;
    end;
    if sair=false then
    begin
     ShowMessage('Nenhum resultado para sua Pesquisa!');
    end;
    CloseFile (arq);
end;  
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

Não tem como vc fechar o arquivo enquanto lê, faz igual eu fiz, manda ler o arquivo até encontrar o conteúdo, ae ele não vai percorrer todas as linhas do arquivo sem necessidade, ae se ele achar ou não, ae vc fecha o arquivo, faz o que for necessário.
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

Pois é.
]Mas como você não corrigiu o meu código, antes criou outro similar, tentei adaptar teu codigo mas não esta dando nada ao clikar no botão enviar.
procedure TfrmPesquisa.btnProcurarClick(Sender: TObject);
var
  arq   : TextFile;
  texto, nome, CPF, salario, idade, funcionario : string;
  txt   : TStringList;
  achou : Boolean;
begin
  txt := TStringList.Create;
  txt.Delimiter := '|';
  AssignFile(arq,Principal.fileName);
  Reset(arq);
  funcionario:=txtNome.text;

  if not EOF(arq) then
  repeat
    ReadLn(arq, texto);
    txt.DelimitedText := texto;
    if txt[0] = funcionario then begin
      nome    := txt[0];
      CPF     := txt[1];
      salario := txt[2];
      idade   := txt[3];
      achou := true;
      frmPesquisa.Hide();
      frmFuncionarios.show();
    end;
  until achou = true;

  if not achou then begin
    ShowMessage('Nenhum resultado para sua Pesquisa!');
  end;

  CloseFile(arq);
end;   

Mas, onde eu estou fechando o arquivo no codigo anterior?
GOSTEI 0
Ricardo Rodrigues

Ricardo Rodrigues

10/10/2013

no meu fiz assim : ae vc ve, se quer ou não ou onde fcha

if not achou then begin
ShowMessage('Nenhum resultado para sua Pesquisa!');
CloseFile(arq);
end;
GOSTEI 0
Carlos Rocha

Carlos Rocha

10/10/2013

Achei.
O problema era na procedure que chama esta procedure

ela este fechando o arquivo depois da chamada da procedure e a procedure tem abertura e fechamento também.
Resultado: o arquivo já estava aberto quando
procedure TfrmPrincipal.btnSalvarClick(Sender: TObject);
var
  linha, funcionario: string;
  novaLinha: string;
  arquivoDivide: array of string;
  contador: integer;
  arq: TextFile;
begin
  funcionario := frmFuncionarios.txtNome.Text;

  if (novoNome <> '') or (novoSalario <> '') or (novaIdade <> '') then
  begin
    if novoNome <> '' then
      novaLinha := novoNome + '|' + frmFuncionarios.txtCPF.Text + '|' +
        frmFuncionarios.txtSalario.Text + '|' + frmFuncionarios.txtIdade.Text;
    if novoSalario <> '' then
      novaLinha := frmFuncionarios.txtNome.Text + '|' + frmFuncionarios.txtCPF.Text +
        '|' + novoSalario + '|' + frmFuncionarios.txtIdade.Text;
    if novaIdade <> '' then
      novaLinha := frmFuncionarios.txtNome.Text + '|' + frmFuncionarios.txtCPF.Text +
        '|' + frmFuncionarios.txtSalario.Text + '|' + novaIdade;

    AssignFile ( arq, fileName );
    reset ( arq );
    contador := 1;
    while not EOF(arq) do
    begin
      ReadLn(arq, linha);
      SetLength(arquivoDivide, contador);
      arquivoDivide[contador - 1] := linha;
      contador := contador + 1;
    end;

    CloseFile(arq);
    populaNovoArquivo(arquivoDivide, funcionario, novaLinha);

  end;
  btnSalvar.Enabled := False;
end;     

Veja quando
a procedure é chamada.
GOSTEI 0
POSTAR