Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Didiron

Problema ao inserir registros em um record

Recommended Posts

Olá pessoal, me chamo Dionei Cardozo, eu frequento bastante o fórum de ASP aqui do imasters, já aqui no fórum de delphi sou um novato. Bem sou iniciante no Delphi, e estou tendo uns pequenos problemas para inserir, registros dentro de um record e depois dentro de um arquivo com a extensão ".bin". Eu estou fazendo um curso de Delphi, e já fizemos um sistema de cadastro de clientes, utilizando record, etc.. Eu utilizei uma boa parte daquele código, só que estou tendo alguns problemas.

 

Eu tenho uma primeira Unit chamado UPrincipal,e nela eu tenho esse código:

 

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

  type
  alunos = record
    Codigo:Integer;
    Nome:String[200];
    DataNascimento:String[25];
    Sexo: String[50];
    NomeMae:String[200];
    NomePai:String[200];
    Matricula: Integer;
    Serie: String[20];
    CPF:String[20];
    RG: String[20];
    Sala:Integer;
    NotaPortugues: Integer;
    FaltasPortugues: Integer;
    NotaMatematica: Integer;
    FaltasMatematica: Integer;
    NotaHistoria: Integer;
    FaltasHistoria: Integer;
 end;

Claro que tenho ainda mais códigos de botões, etc..

 

 

E tenho ainda um outro form CadastroAlunos, com esse código:

 

procedure TFrmCadastroAlunos.BtnCadastrarAlunoClick(Sender: TObject);
 Var
  ender: alunos;
  Arq: file of alunos;
begin
  AssignFile(Arq, ExtractFilePath(Application.ExeName)+'\alunos.bin');

    rewrite(arq);
    int:= 1;
    seek(arq, filesize(arq)-1);
    read(arq, ender);
    int := ender.Codigo+1;
    ender.Codigo := int;
    ender.Nome := EdNomeAluno.Text;
    ender.DataNascimento = EdDataNasc.Text;
    ender.Sexo := EdSexo.Text;
    ender.NomeMae := EdNomeMae.Text
    ender.NomePai := EdNomePai.Text;
    ender.Matricula := EdMatricula.Text;
    ender.Serie := EdSerie.Text;
    ender.CPF := EdCpf.Text;
    ender.RG := EdRg.Text;
    ender.Sala := EdSala.Text;
    ender.NotaPortugues := EdNotaPortugues.Text;
    ender.FaltasPortugues := EdFaltasPortugues.Text;
    ender.NotaMatematica := EdNotaMatematica.text;
    ender.FaltasMatematica := EdFaltasMatematica.text;
    ender.NotaHistoria := EdNotaHistoria.Text;
    ender.FaltasHistoria := EdFaltasHistoria.Text;
    seek(arq, filesize(arq));
    Write(arq, ender);
    reset(arq);
    seek(arq, filesize(arq)-1);
    read(arq, ender);
    Showmessage('Aluno cadastrado com sucesso!')

end;

 

Só que ele está me dando um erro na linha onde está o seguinte código:

 

ender: alunos;

E o erro é esse:

Undeclared identifier: 'alunos'

 

Alguém poderia pelo menos me dar uma luz de como resolver esse problema?

 

Grato a todos. Abraços.

Compartilhar este post


Link para o post
Compartilhar em outros sites

ele não está reconhecendo a classe alunos ...

 

ela foi declarada na UPrincipal pelo que percebi...

 

na outra unit onde você referencia "ender: alunos", você deve declarar lá em cima em uses, abaixo do implementation: "uses UPrincipal;"

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bem isso já resolveu o problema anterior, muito obrigado.

Só que dai aconteceu um erro no

 

int := 1;

 

Como se essa variável não havia sido declarada, então lá dentro do vars, eu coloquei assim:

 

Var

ender: alunos;

Arq: file of alunos;

int: Integer;

 

Assim ele não me retornou nenhume erro, mas me deixou uma observação lá em baixo assim:

 

Value assigned to 'int' never used.

 

Só que ele deixou rodar o programa.

mas quando eu clico em cadastrar Aluno, ele me dá o seguinte erro:

 

Project PrPrincipal.exe raised exception class EinOutError with message 'I/O error 131'.Process stopped. Use step or Run to cotinue.

 

Voce sabe o que poderia estar acontecendo.

Valeu pela ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

quanto ao primeiro problema que você mencionou é o seguinte:

 

observe esta parte do seu código:

 

    int:= 1;
    seek(arq, filesize(arq)-1);
    read(arq, ender);
    int := ender.Codigo+1;

você colocou "int:= 1" e 3 linhas abaixo "int:= ender.Codigo+1"... o primeiro comando não serve pra nada, pois logo em seguida você

está colocando outro valor na variável int.

 

quanto ao seguindo erro mencionado, aparentemente está relacionado com o arquivo que está trabalhando ... tipo, o arquivo está bloqueado ou com algum erro ...

 

tente localizar qual a linha que contém erro ...

 

tente debugar o programa com F9 para localizar a linha que contém erro ...

Compartilhar este post


Link para o post
Compartilhar em outros sites

é, realmente o problema (como disse o Daniel Sanches) parece se no arquivo.

 

Va la na linha "AssignFile(Arq, ExtractFilePath(Application.ExeName)+'\alunos.bin');" e precione F5, ela ficará marcada em vermelho. Quando rodadr o programa e clicar no botão para salvar o aluno, o delphi ira parar nestea linha. Vá apertando F8 até o erro aparecer. Depois poste ai em qual linha foi o erro.

 

 

:D

Compartilhar este post


Link para o post
Compartilhar em outros sites

um erro que constatei neste código é o seguinte:

 

AssignFile(Arq, ExtractFilePath(Application.ExeName)+'\alunos.bin');

 

a função ExtractFilePath retorna o path já com \ no final... do jeito que tá aí vai retornar algo assim:

 

c:\path da aplicação\\alunos.bin

 

corrija nos demais locais e verifique se o erro persiste ...

Compartilhar este post


Link para o post
Compartilhar em outros sites

pra você que pretende trabalhar com records, dá uma lida nesse tutorial abaixo:

 

Iniciando

Aqui pretendo empregar técnicas para aumentar as possibilidades de criação RAD do Delphi obtendo, desta maneira, a criação simplificada de inúmeros aplicativos.

Importante - Todas as técnicas empregadas aqui funcionam perfeitamente desde o ambiente Turbo Pascal.

Definimos a estrutura deste tipo de Arquivo antes do próprio corpo do objeto principal, dentro do comando Type, segundo o exemplo:

Trecho de Código:

type
cartao = record
posic : integer; // Posição do Cartão
Nome : String[30]; // Nome
Ender : String[30]; // Endereço
Empres : String[30]; // Empresa
Telef : String[30]; // Telefone
Observ : String[30]; // Observações
ExcCar : Boolean; // Cartão Excluído : S ou N
end;
TF_Cartao = class(TForm)
// resto do objeto

tudo em linguagem Object Pascal é definido basicamente como Variáveis. O próprio Formulário, por exemplo é uma, o conceito dos arquivos nativos não escapam desta definição, então vamos criar as variáveis que ajudarão o controle do Arquivo:

Trecho de Código

public
RegCartao:Cartao;// Registro que contém a estrutura 
tpCartao:file of Cartao: // Nome interno do arquivo
NomArq: TfileName; // guarda o nome externo
end;

Para o acesso (ou criação) do Arquivo , pode ser utilizada a seguinte função, que através do comando AssignFile associa o arquivo com o comando Reset e caso o arquivo não exista prepara-o para a Criação do mesmo com o comando ReWrite:

Trecho de Código:

function TF_Cartao.GeraArquivo : Boolean;
begin
AssingFile(tpCartao, NomArq);
{$ I-} 
Reset(tpCartao);
{$ I-}
if IoResult <> 0 then
ReWrite(tpCartao); // para a primeira criação 

Para a abertura do arquivo pode ser usado o objeto TOpenDialog do seguinte modo:

if OpenDialog1.Execute then begin
NomArq := OpenDialog1.FileName;
if not GeraArquivo then
Raise Exception.Create ('Arquivo não encontrado');
// Arquivo Inválido

Importante - Sempre que se Utilizar desta função não se esqueça de fechar o 
arquivo com o comando CloseFile.

Localizando e Carregando

A localização dos registros dentro do arquivo é feita através do comando Seek os registros dentro deste tipo de arquivo são localizados através da posição física do registro, para localizar um determinado registro do Arquivo construiremos a seguinte função:

Trecho de Código:

function TF_Cartao.Carrega (PosReg: Interger) : boolean;
begin
result := False;
Seek(tpCartao, PosReg);
If not EOF (tpCartao) then begin
// Não é Fim de Arquivo
Read (tpCartao, RegCartao);
if RegCartao.ExcCar then // Cartão Excluído 
MessageDlg('Este Cartão foi excluído, utilize a recuperação', 
mtInformatio, [mbOK], 0);
else
result := True;
end;
end;

Importante - Podemos construir arquivos de índices contendo apenas dois campos, a Posição física dentro do arquivo e o campo ao qual queremos que sirva como chave. Realizando periodicamente a organização deste arquivo paralelo por este campo chave definido, então toda a pesquisa é realizada neste arquivo por localização seqüencial e depois localiza-se o registro no arquivo principal através do comando Seek.

Podemos mostrar determinado registro do Arquivo depois de Localizado atrav;es de objetos do tipo Edit colocados num formulário, mas lembre-se que eles não estão vinculados como os objetos DBEdit então devemos controlar o que deverá ser mostrado bem como o tamanho do que pode será inserido. Em alguns casos podemos nos utilizar do objeto MaskEdit:

Trecho de Código:

procedure TF_Cartao.Mostra;
begin
with RegCartao do begin
EdtNome.Text := Nome;
EdtEnder.Text :=Ender;
EdtEmpres.Text := Empres;
EdtTelef.Text := Telef;
EdtObserv.Text := Observ;
end;
end;

Para carregar os dados dos objetos do tipo Edit para o registro do Arquivo podemos criar um procedimento único para a utilização da Inclusão (Tipo=1), Alteração(Tipo=2), Exclusão Lógica (Tipo = 3) e Recuperação Lógica (Tipo = 4):

Trecho de Código:

procedure TF_Cartao.CarrArq(Tipo, PosReg : Interger);
begin
with F_Cartao do begin
case tipo of
3 : ExcCar := True;
4 : ExcCar := False;
else
with RegCartao do begin
Posic := PosReg;
Nome := EdtNome.Text;
Ender := EdtEnder1.Text;
Empres := EdtEmpres.Text;
Telef := EdtTelef.Text;
Observ := EdtObserv.Text;
ExcCar := False;
end;
end;
Seek (tpCartao, PosReg); // Relocaliza
Write (tpCartao, RegCartao); // Gravar
end;
end;

Para limitar o tamanho dos campos pode ser criado um procedimento Global que não deixa o Edit ultrapassar o número de casas pre-determinada:

Trecho de Código:

procedure TF_Cartao.DevMaior(var Campo: Tedit; Tam : Interger);
begin
if Length (campo.Text) >Tam then begin
Campo.Text := Copy (Campo.Text,1,Tam);
MessageBeep (0);
end;
end;

Coloque no evento OnChange de cada Edit a limitar a chamada ao procedimento, por exemplo, no edit do Nome:

Trecho de Código

procedure TF_Cartao.EdtNomeChange (Sender: Tobject);
begin
DevMaior(EdtNome, 30);
end;

Manipulação dos Dados

Aproveitando os procedimentos realizados vamos criar o proce3dimento para inserir um novo registro:

Trecho de Código:

procedure TF_Cartao.InseriClick(Sender: Tobject);
begin
GeraArquivo;
CarrArquivo(1, FileSize(tpCartao));
CloseFile(tpCartao);
end;

Importante - Não esqueça de limpar os Edits comText := "antes de incluir

O procedimento para atualizar o registro N (sendo Na posição - em Inteiro -- do registro a alterar):

Trecho de Código


procedure TF_Cartao.AtualizaClick(Sender : TObject);
begin 
GeraArquivo;
if Carrega (N) then CarrArq(2, N);
CloseFile(tpCartao);
end;

O procedimento para Excluir, é realizado apenas logicamente, marcando determinado registro N (sendo N a posição - em Inteiro - do registro a excluir):

Trecho de Código

procedure TF_Cartao.ExcluiClick(Sender : TObject);
begin 
GeraArquivo;
if Carrega (N) then CarrArq(3, N);
CloseFile(tpCartao);
end;

Importante - Não esqueça de Proteger os Edits com ReadOnly com True antes de excluir

O procedimento que servirá para Recuperar o registro N (sendo N a posição - em Inteiro - do registro a recuperar) do arquivo excluído logicamente:

Trecho de Código:

procedure TF_Cartao.RecuperaClick(Sender : Tobject);
begin 
GeraArquivo;
if Carrega (N) then CarrArq(4, N);
CloseFile(tpCartao);
end;

Importante - Não esqueça de proteger os Edits com ReadOnly com True antes de recuperar.

Para eliminar do arquivo os registros marcados como excluídos (ou Excluídos logicamente), pode ser utilizado um arquivo temporário idêntico e feito um Balance-Line, varrendo o arquivo principal e copiando os registros determinados, seguindo os seguintes passos:

1. Crie as variáveis para um arquivo temporário:

Trecho de Código:
private 
RegCartaoB : Cartao; // Registro que contém a estrutura
tpCartaoB : file of Cartao; // Nome interno do arquivo

2. disponibilize a unidade que contém variáveis do Arquivo principal:

Trecho de Código:

uses fCartao;

3. Crie o procedimento:

Trecho de Código:

procedure TF_Cartao.ButEliminaClick(Sender: TObject);
var 
IndReg, Corre: Integer;
NomArqB: TfileName;
begin
// Cria o arquivo temporário
NomArqB := Copy (F_Cartao.NomArq,1, Legth
(F_Cartao.NomArq) -4) + '.TMP';
AssignFile(tpCartaoB, NomArqB);
{$I-}
Reset(tpCartaoB);
{$I-}
if IoResult <> 0 then ReWrite(tpCartaoB);
// Carrega os Registros
IndReg := 0;
Corre := 0;
Repeat
Seek(F_Cartao.tpCartao,Corre);
if not EOF(F_Cartao.tpCartao) then begin
Read(F_Cartao.tpCartao, F_Cartao.RegCartao);
With F_Cartao.RegCartao do begin
if not ExcCar then begin // se o registro não 
tiver excluído transfere os Registros.
RegCartaoB.Posic := IndReg;
RegCartaoB.Nome := Nome;
RegCartaoB.Ender := Ender;
RegCartaoB.Empres := Empres;
RegCartaoB.Telef := Telef;
RegCartaoB.Observ := Observ;
RegCartaoB.ExcCar := ExcCar;
Seek (tpCartaoB, FileSize (tpCartaoB));
Write (tpCartaoB, RegCartaoB); // grava
Inc(indReg);
end;
end;
end;
Inc(Corre);
until EOF(F_Cartao,tpCartao);
CloseFile(F_Cartao.tpCartao); // Elimina o arquivo
Erase(F_Cartao.tpCartao);
CloseFile(tpCartaoB);
Rename(tpCartaoB, F_Cartao.NomArq); // Renomeia o arquivo
end;

A mesma técnica pode ser utilizada para a organizar o arquivo por qualquer campo. Repita os passos 1, 2 e 3 e recrie o procedimento principal da seguinte maneira:

Trecho de Código:

procedure TF_Cartao.ButOrganizaClick(Sneder: TObject); 
var
IndReg, Numero: Interger;
Campo, Monta: String;
Achei: Boolean;
NomArqB : TfileName;
begin
// acertar a lista
Lista.Items.Clear;
IndReg := -1;
with F_Cartao do 
repeat
Inc(IndReg);
Seek (tpCartao, IndReg);
if not EOF(tpCartao) then begin
Read (tpCartao, RegCartao);
with RegCartao do begin
if RadNome.Checked then Campo := Nome;
if RadEnder.Checked then Campo := Ender;
if RadEmpres.Checked then Campo := Empres;
if RadTelef.Checked then Campo := Telef;
if RadObserv.Checked Then Campo := Observ;
Campo := Campo + ' {' + IntToStr(Posic) +'}';
end;
E_Organiz.Lista.Items.Add(Campo);
end;
Util EOF(F_Cartao.tpCartao); // cria arq. Temporário
NomArqB := copy(F_Cartao.NomArq, 1, Length
(F_Cartao.NomArq)-4) + '.TMP';
AssingFile(tpCartaoB, NomArqB);
{$ I-} 
Reset (tpCartaoB);
{$ I-}
if IoResult <> 0 then ReWrite(tpCartaoB);
for IndReg := 0 to (F_Organiz.Lista.Items.Count 
-1) do begin // Carrega os Registros
Campo := Lista.Items[IndReg];
Achei := False;
Monta := '';
for numero := 1 to Legth (Campo) do begin
// Localiza o Registro Correto.
if Achei then begin
if Campo[Numero] = ']' then Break;
Monta := Monta + Campo[Numero];
end;
if Campo[Numero] = '{' then Achei := True;
end;
Seek(F_Cartao.tpCartao, StrToInt(Monta));
Read(F_Cartao.tpCartao, F_Cartao.RegCartao);
With F_Cartao.RegCartao do begin
// Acerta Registro
RegCartaoB.Posic := IndReg;
RegCartaoB.Nome := Nome;
RegCartaoB.Ender := Ender;
RegCartaoB.Empres := Empres;
RegCartaoB.Telef := Telef;
RegCartaoB.Observ := Observ;
RegCartaoB.ExcCar := ExcCar;

end;
Seek(tpCartaoB, FileSize (tpCartaoB)); // grava
Write(tpCartaoB, RegCartaoB);
end;
CloseFile (F_Cartao.tpCartao);
Erase(F_Cartao.tpCartao); // Elimina o Arquivo
CloseFile(tpCartaoB);
Rename(tpCartaoB, F_Cartao.NomArq); // Renomeia 
end;

Terminando tudo

Nota-se, com tudo o que foi explanado, que o conjunto Delphi com a estrutura do Record pode ampliar drasticamente o número de aplicativos construídos, e evitar a construção de sistemas que se utilizam de partes de estruturas de dados sejam desenvolvidas com bancos complexos e acessos via BDE gastando tempo bem para os seguintes aplicativos:

>> Coletores de informações;
>> Importação e Exportação de arquivos em mídia rápida;
>> Em aplicativos de Jogos, criação de Scorescontendo os melhores resultados;
>> Criação de arquivo de configuração para sistemas coorporativos

mas também não precisa exagerar tentando reinventar a roda e recriando inúmeras funções para criar um complexo sistema de Bancos de Dados quando as opções de mercado nesta área são vastas, recomendo a utilização visando o seguinte propósito:
>> Sistemas de Pequenos / Médio Porte: dBase, Access e Paradox
>> Sistemas de grande porte: MS-SQL e Interbase
>> Sistemas Coorporativos e Integrados: ORACLE

Todos estes bancos acima citados se comportam excelentemente bem nestes espaços pré-determinados.

texto retirado do site www.ramosdainformatica.com.br

Autor: Raphael Rissato

Compartilhar este post


Link para o post
Compartilhar em outros sites

olha ... quanto ao erro neste comando seek, como não tenho muita experiência trabalhando com record, deixo aos amigos do fórum tentar te ajudar .... do mais, estarei acompanhando o tópico para tentar ajudar ...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então pessoal, depois de muito tempo quebrando a cabeça, eu consegui resolver o problema.

Eu comecei a refazer todo os sistema do 0. :mellow:

E dai funcionou logo na primeira vez.

huahuahuahuahuahuahuahhauahahauhaua

Aquele ero eu até agora ainda não solucionei, mas foi bom que funcionou agora, espero nunca mais passar por este erro. Agora só estou tendo alguns pequenos problemas em trabalhar com Strnggrid, mas vou ver se consigo resolver se não eu volto aqui ao fórum. :D :D

 

Agradeço a quem ajudou. ;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então seguindo o que o Raficcha disse, o erro apareceu nesta linha:

 

seek(arq, filesize(arq)-1);

 

Hum... qual é o tamanho do arquivo? Se este arquivo estiver vazio, vai dar erro sim! Ele vai tentar dar seek na posiçõ "-1".

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.