Baza danych

0

Witam,
Od razu zaznaczam że nie jestem zbyt dobry z programowania.
Otóż mam problem- dostałem pracę zaliczeniową - bazę danych.
Napisałem cały program - tj. tworzę plik, usuwam, dodaje wpis, usuwam wpis, odczytuje zawartosc pliku, ale mam problem - jak podczas dodawania wpisu zamiast liczby wpiszę literę to wyskakuje błąd i program się sypie. poza tym wszystko jest dobrze. Co zrobić?

0

"Napisalem program, ale jak wpisze do niego litere to sie sypie", moze tak troche wiecej, jakis kod .... ?

0

Sorry, oto kod programu:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Baza1: TMenuItem;
    Koniec1: TMenuItem;
    Nowyplik1: TMenuItem;
    Wprowadnowedane1: TMenuItem;
    Czytajdanezpliku1: TMenuItem;
    Kasujdanezpliku1: TMenuItem;
    StringGrid1: TStringGrid;
    Usuplik1: TMenuItem;
    procedure Koniec1Click(Sender: TObject);
    procedure Nowyplik1Click(Sender: TObject);
    procedure Usuplik1Click(Sender: TObject);
    procedure Wprowadnowedane1Click(Sender: TObject);
    procedure Czytajdanezpliku1Click(Sender: TObject);
    procedure Kasujdanezpliku1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 type
 spis=record
 nazwa:String[45];
 powierz:Integer;
 glebok:Integer;
 dno:String[50];
 dostep:Integer;
 brzegi:String[50];
 sprzet:String[50];
 miejscowosc:String[40];
 end;
 spis_2=file of spis;
var
  Form1: TForm1;
  jeziora, jeziora_pomoc:spis_2;
  rek:spis;
  kas_pozycja:string[50];
  znkon:string[1];
  ile,wynik:integer;
implementation

{$R *.dfm}

procedure TForm1.Koniec1Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Nowyplik1Click(Sender: TObject);
begin
  AssignFile(jeziora,'jeziora.dat');
 {$i-}
 Reset(jeziora);
 CloseFile(jeziora);
 {$i+}
  if IORESULT = 0 then
  Showmessage ('Plik juz istnieje')
   else
  Begin
  Showmessage('Tworze plik');
   Rewrite(jeziora);
   CloseFile(jeziora);
  end;
end;


procedure TForm1.Usuplik1Click(Sender: TObject);
begin
AssignFile(jeziora,'jeziora.dat');
{$i-}
erase(jeziora);
{$i+}
 if ioResult=0 then
  Showmessage('Usunięto!')
 else
  Showmessage('Brak pliku do usunięcia!');
end;

procedure TForm1.Wprowadnowedane1Click(Sender: TObject);
begin
AssignFile(jeziora,'jeziora.dat');
{$i-}
Reset(jeziora);
{$i+}
 if IOResult<>0 then
 begin
 wynik:=Application.MessageBox('Czy stworzyc nowy?','Plik nie istnieje',
MB_YesNo+MB_IconStop+MB_DefButton1);
if wynik=6 then
begin
Rewrite(jeziora);
ShowMessage('Nowy plik został utworzony!');
end;
end;
Seek(jeziora, FileSize(jeziora));
repeat
with rek do
begin
 nazwa:=InputBox('Podaj dane','Podaj nazwe jeziora','');
 powierz:=StrToInt(InputBox('Podaj dane','Podaj wielkosc jeziora',''));
 glebok:=StrToInt(InputBox('Podaj dane','Podaj glebokosc',''));
 dno:=InputBox('Podaj dane','Podaj rodzaj dna','');
 dostep:=StrToInt(InputBox('Podaj dane','Ocen dostep do jeziora (1-6)',''));
 brzegi:=InputBox('Podaj dane','Podaj typ brzegów','');
 sprzet:=InputBox('Podaj dane','Podaj rodzaj wypozyczanego sprzetu','');
 miejscowosc:=InputBox('Podaj dane','Podaj nazwe najblizszej miejscowosci','');
 end;
 Write(jeziora,rek);
 wynik:=Application.MessageBox('czy wprowadzac dalej?','Wprowadzanie rekordu zakończono',MB_YesNo+MB_DefButton1);
 if wynik=6 then znkon:='K' else znkon:='N';
 until(znkon='N') or (znkon='n');
 CloseFile(jeziora);
end;


procedure TForm1.Czytajdanezpliku1Click(Sender: TObject);
begin
AssignFile(jeziora,'jeziora.dat');
{$I-}
Reset(jeziora);
CloseFile(jeziora);
{$I+}
if IOResult<>0 then
begin
ShowMessage('Plik nie istnieje!');
end
else
begin
Reset(jeziora);
ile:=0;
while not eof(jeziora) do
begin
Read(jeziora,rek);
ile:=ile+1;
end;
Reset(jeziora);
StringGrid1.ColCount:=9;
StringGrid1.RowCount:=ile+1;
StringGrid1.Cells[0,0]:='Nr. rek';
StringGrid1.Cells[1,0]:='Nazwa';
StringGrid1.Cells[2,0]:='Powierzchnia';
StringGrid1.Cells[3,0]:='Głębokosc';
StringGrid1.Cells[4,0]:='Rodzaj dna';
StringGrid1.Cells[5,0]:='Dostępnosc';
StringGrid1.Cells[6,0]:='Brzegi';
StringGrid1.Cells[7,0]:='Wyp. sprzętu';
StringGrid1.Cells[8,0]:='Miejscowosc';
ile:=0;
while not eof(jeziora) do
begin
ile:=ile+1;
Read(jeziora, rek);
with rek do
begin
StringGrid1.Cells[0,ile]:=IntToStr(ile);
StringGrid1.Cells[1,ile]:=nazwa;
StringGrid1.Cells[2,ile]:=IntToStr(powierz);
StringGrid1.Cells[3,ile]:=IntToStr(glebok);
StringGrid1.Cells[4,ile]:=dno;
StringGrid1.Cells[5,ile]:=IntToStr(dostep);
StringGrid1.Cells[6,ile]:=brzegi;
StringGrid1.Cells[7,ile]:=sprzet;
StringGrid1.Cells[8,ile]:=miejscowosc;
end;
end;
CloseFile(jeziora);
end;

end;

procedure TForm1.Kasujdanezpliku1Click(Sender: TObject);
begin
AssignFile(jeziora,'jeziora.dat');
{$I-}
Reset(jeziora);
{$I+}
if IOResult<>0 then
begin
ShowMessage('Plik nie istnieje!');
end
else
begin
Reset(jeziora);
ile:=0;
while not eof(jeziora) do
begin
Read(jeziora,rek);
ile:=ile+1;
end;
Reset(jeziora);
StringGrid1.ColCount:=9;
StringGrid1.RowCount:=ile+1;
StringGrid1.Cells[0,0]:='Nr. rek';
StringGrid1.Cells[1,0]:='Nazwa';
StringGrid1.Cells[2,0]:='Powierzchnia';
StringGrid1.Cells[3,0]:='Głębokosc';
StringGrid1.Cells[4,0]:='Rodzaj dna';
StringGrid1.Cells[5,0]:='Dostępnosc';
StringGrid1.Cells[6,0]:='Brzegi';
StringGrid1.Cells[7,0]:='Wyp. sprzętu';
StringGrid1.Cells[8,0]:='Miejscowosc';
ile:=0;
while not eof(jeziora) do
begin
ile:=ile+1;
Read(jeziora, rek);
with rek do
begin
StringGrid1.Cells[0,ile]:=IntToStr(ile);
StringGrid1.Cells[1,ile]:=nazwa;
StringGrid1.Cells[2,ile]:=IntToStr(powierz);
StringGrid1.Cells[3,ile]:=IntToStr(glebok);
StringGrid1.Cells[4,ile]:=dno;
StringGrid1.Cells[5,ile]:=IntToStr(dostep);
StringGrid1.Cells[6,ile]:=brzegi;
StringGrid1.Cells[7,ile]:=sprzet;
StringGrid1.Cells[8,ile]:=miejscowosc;
end;
end;
AssignFile(jeziora_pomoc,'pomoc.dat');
Reset(jeziora);
Rewrite(jeziora_pomoc);
kas_pozycja:=InputBox('','Podaj nazwe kasowanej pozycji','');
while not eof(jeziora) do
begin
Read(jeziora, rek);
if kas_pozycja<>rek.nazwa then Write(jeziora_pomoc,rek);
end;
CloseFile(jeziora);
CloseFile(jeziora_pomoc);
{$I-}
Erase(jeziora);
{$I+}
RenameFile('pomoc.dat','jeziora.dat');
end;
end;


end.
0

W którym miejscu jak wpiszesz literę?

0

np.

glebok:=StrToInt(InputBox('Podaj dane','Podaj glebokosc',''));

to ci spowoduje, jezeli chcesz przeprowadzic konwersje ze stringa na integera (StrToInt), a w stringu nie bedzie liczby to doataniesz taki rezultat.

A zeby tego uniknac to zmodyfikuj twoj rekord

 spis=record
  nazwa:String[45];
  powierz:Integer;
  glebok:Integer;
  dno:String[50];
  dostep:Integer;
  brzegi:String[50];
  sprzet:String[50];
  miejscowosc:String[40];
 end;

Czyli zamiast Integer zadeklaruj cos innego, np String;

0

Do LUDOMIRA:
Jak skompiluję program i zacznę dodawać wpis, wtedy jak np. mam podać głębokość jeziora (w liczbach) zamiast tego powiedzmy pomylę się i wpiszę literę to wyskakuje błąd i program się wiesza.

Do WOLVERINE:
Ale jak zadeklaruję zamiast integer stringa to będą to musiały być litery a nie liczby prawda? A ja jednak muszę mieć liczby:-/

0

Zrób własnego "InputBox" tak aby dało się wpisywać tylko liczby.
Albo
http://4programmers.net/Forum/viewtopic.php?id=51258

0

a może by tak użyć zmiennej variantowej? później dopiero sprawdzać czy jest liczba czy literka.

0

Ale jak zadeklaruję zamiast integer stringa to będą to musiały być litery a nie liczby prawda? A ja jednak muszę mieć liczby

Ale String to liczby + znaki... Wiec mozesz wpisac liczbe, tylko po prostu trudniej zrobin na tym jakies operacje np dodawanie.

0

trudniej nie trudniej. wystarczy zutowanie i zmiana typów i elegancko wychodzi, tyle, że trzeba w tedy uważać na wyjątki, które mogą przyspożyć kłopotu.

0

Ok, używam Stringa, i działa, ale jak wpiszę zamiast liczby literę to ta litera potem jest wpisana w tabeli. Próbowałem wpisać warunek że jeżeli wpiszę literę zamiast liczby to wyskoczy Showmessage "to nie jest liczba" tylko że mi nie wyszło, nie za bardzo wiem jak zmodyfikować kod. Moglibyście pomóc?

0

Ok, używam Stringa, i działa, ale jak wpiszę zamiast liczby literę to ta litera potem jest wpisana w tabeli. Próbowałem wpisać warunek że jeżeli wpiszę literę zamiast liczby to wyskoczy Showmessage "to nie jest liczba" tylko że mi nie wyszło, nie za bardzo wiem jak zmodyfikować kod. Moglibyście pomóc?

Nie uzywaj zadnych stringow zamiast int

po prostu zrob

[code]var Liczba, Blad :Integer; Str :String;
Begin
Str:=InputBox(...);
Val(Str,Liczba,Blad);
If Blad=0 then
Begin
{wszystko ok}
End
else
Begin
MessageBox(0,'Nie wiem co to jest liczba ???????','',0);
End;
End;[/code]

Albo gdybys np zakladal ze te liczby musza byc wieksze lub rowne 0 to mozesz zrobic

Liczba:=StrToIntDef( InputBox(..) , -1);
if Liczba<>-1 then {OK}

Albo jeszcze pewnie kilka innych rzeczy mozna zrobic...

0

Dzięki skorzystałem z Twojej rady, teraz perocedura na dodanie wpisu wygląda tak:

procedure TForm1.Wprowadnowedane1Click(Sender: TObject);
var
str:string;
blad:integer;
begin
AssignFile(jeziora,'jeziora.dat');
{$i-}
Reset(jeziora);
{$i+}
 if IOResult<>0 then
 begin
 wynik:=Application.MessageBox('Czy stworzyc nowy?','Plik nie istnieje',
MB_YesNo+MB_IconStop+MB_DefButton1);
if wynik=6 then
begin
Rewrite(jeziora);
ShowMessage('Nowy plik został utworzony!');
end;
end;
Seek(jeziora, FileSize(jeziora));
repeat
with rek do

begin
 nazwa:=InputBox('Podaj dane','Podaj nazwe jeziora','');
 str:=InputBox('Podaj dane','Podaj wielkosc jeziora [ha]','');
val(str,powierz,blad);
if blad=0 then
begin
{wszystko ok}
end
else
Begin
   showmessage('Musisz wpisac liczbę - spróbuj jeszcze raz!');
   
  End;
 str:=InputBox('Podaj dane','Podaj glebokosc [m]','');
 val(str,glebok,blad);
if blad=0 then
begin
{wszystko ok}
end
else
Begin
   showmessage('Musisz wpisac liczbę - spróbuj jeszcze raz!');

  End;
 dno:=InputBox('Podaj dane','Podaj rodzaj dna','');
 str:=InputBox('Podaj dane','Ocen dostep do jeziora (1-6)','');
 val(str,dostep,blad);
if blad=0 then
begin
{wszystko ok}
end
else
Begin
   showmessage('Musisz wpisac liczbę - spróbuj jeszcze raz!');

  End;
 brzegi:=InputBox('Podaj dane','Podaj typ brzegów','');
 sprzet:=InputBox('Podaj dane','Podaj rodzaj wypozyczanego sprzetu','');
 miejscowosc:=InputBox('Podaj dane','Podaj nazwe najblizszej miejscowosci','');
 end;
 Write(jeziora,rek);
 wynik:=Application.MessageBox('czy wprowadzac dalej?','Wprowadzanie rekordu zakończono',MB_YesNo+MB_DefButton1);
 if wynik=6 then znkon:='K' else znkon:='N';
 until(znkon='N') or (znkon='n');
 CloseFile(jeziora);
end;

A co zrobić żeby po wpisaniu literki i wyświetleniu komunikatu 'Musisz wpisac liczbę - spróbuj jeszcze raz!' program się zamykał (jak wpiszę close; to nie działa jak powinno) i wpis nie dodawał się do bazy. Albo żebym miał możliwość poprawienia błędu?

<font size="12"><font color="red">UZYWAJ TAGÓW DELPHI !</span></span>

0

A co zrobić żeby po wpisaniu literki i wyświetleniu komunikatu 'Musisz wpisac liczbę - spróbuj jeszcze raz!' program się zamykał

Użyj zamiast ShowMessage uzyj MessageBox-a lub MessageDlg abyś mógł jakoś reagować na kliknięcie jakiegoś buttona a potem wywołaj Application.Terminate

i wpis nie dodawał się do bazy. Albo żebym miał możliwość poprawienia błędu?

Po prostu omiń resztę procedury exit-em lub jakimś goto-em.

A tak w ogóle to powinieneś użyć do tego grupy typu try except end i wtedy sam przed wpisaniem danych sprawdzałbyś poprawność danych. Prosta konstrukcja i podstawowa jeśli chodzi o obsługę błedów.

0

A czy mógłbyś mi wyjaśnić co to jest ta grupa try except end? Nie za bardzo wiem o co chodzi.

0

Ale w helpie masz wszystko

Chodzi o to że pomiędzy słowami kluczowymi try except piszesz cały kod. Ten kod jest wykonywany aż coś się "wywali" czy będzie wywołany jakiś Exception. Wtedy program skacze do części pomiędzy except end i według twoich ustawień obsługuje wywołany wyjącek. Jeżeli obsługi tego wyjątku nie znajdzie wyświetli własny komunikat o błędzie.
Można też użyć try finally end ale w jakich wypadkach to sobie sam poczytaj.
Można również zagnieżdżać te elementy np:
try
.....
try
....
except
...
end;
...
finally
....
end;

A to z helpa

Try...except statements

Exceptions are handled within try...except statements. For example,

try

X := Y/Z;
except
on EZeroDivide do HandleZeroDivide;
end;

This statement attempts to divide Y by Z, but calls a routine named HandleZeroDivide if an EZeroDivide exception is raised.
The syntax of a try...except statement is

try statements except exceptionBlock end

where statements is a sequence of statements (delimited by semicolons) and exceptionBlock is either

another sequence of statements or
a sequence of exception handlers, optionally followed by

else statements

An exception handler has the form

on identifier: type do statement

where identifier: is optional (if included, identifier can be any valid identifier), type is a type used to represent exceptions, and statement is any statement.
A try...except statement executes the statements in the initial statements list. If no exceptions are raised, the exception block (
exceptionBlock) is ignored and control passes to the next part of the program.
If an exception is raised during execution of the initial statements list, either by a raise statement in the statements list or by a procedure or function called from the statements list, an attempt is made to “handle” the exception:

If any of the handlers in the exception block matches the exception, control passes to the first such handler. An exception handler “matches” an exception just in case the type in the handler is the class of the exception or an ancestor of that class.
If no such handler is found, control passes to the statement in the else clause, if there is one.
If the exception block is just a sequence of statements without any exception handlers, control passes to the first statement in the list.

If none of the conditions above is satisfied, the search continues in the exception block of the next-most-recently entered try...except statement that has not yet exited. If no appropriate handler, else clause, or statement list is found there, the search propagates to the next-most-recently entered try...except statement, and so forth. If the outermost try...except statement is reached and the exception is still not handled, the program terminates.

When an exception is handled, the stack is traced back to the procedure or function containing the try...except statement where the handling occurs, and control is transferred to the executed exception handler, else clause, or statement list. This process discards all procedure and function calls that occurred after entering the try...except statement where the exception is handled. The exception object is then automatically destroyed through a call to its Destroy destructor and control is passed to the statement following the try...except statement. (If a call to the Exit, Break, or Continue standard procedure causes control to leave the exception handler, the exception object is still automatically destroyed.)

In the example below, the first exception handler handles division-by-zero exceptions, the second one handles overflow exceptions, and the final one handles all other math exceptions. EMathError appears last in the exception block because it is the ancestor of the other two exception classes; if it appeared first, the other two handlers would never be invoked.

try

...
except
on EZeroDivide do HandleZeroDivide;
on EOverflow do HandleOverflow;
on EMathError do HandleMathError;
end;

An exception handler can specify an identifier before the name of the exception class. This declares the identifier to represent the exception object during execution of the statement that follows on...do. The scope of the identifier is limited to that statement. For example,

try

...
except
on E: Exception do ErrorDialog(E.Message, E.HelpContext);
end;

If the exception block specifies an else clause, the else clause handles any exceptions that aren’t handled by the block’s exception handlers. For example,

try

...
except
on EZeroDivide do HandleZeroDivide;
on EOverflow do HandleOverflow;
on EMathError do HandleMathError;
else
HandleAllOthers;
end;

Here, the else clause handles any exception that isn’t an EMathError.
An exception block that contains no exception handlers, but instead consists only of a list of statements, handles all exceptions. For example,

try

...
except
HandleException;
end;

Here, the HandleException routine handles any exception that occurs as a result of executing the statements between try and except.

0

Zrob np cos w stylu:

Repeat
Tekst:=InputBox(..);
Val(Tekst,Liczba,Blad);
Until Blad=0;

To spowoduje, ze okienko do wpisania tej liczby bedzie sie pojawialo az wpiszesz liczbe a nie jakies literki czy cos

a poza tym w tym moim poprzednim kodzie to miales kilka rzeczy zmienic, np jak pisze {jesli ok} to znaczy, ze tam masz wpisac to co sie bedzie dzialo jak podasz prawidlowa liczbe a nie ze masz taki komentarz zostawic bo on do niczego nie jest potrzebny..

0

Ok dzięki wszystkim za pomoc!

0

Dobra, mam jeszcze jedno pytanie - co zrobić aby zabezpieczyć program przed następującą rzeczą - uruchamiam program z dyskietki i ktoś mi ją wyciąga, żeby np. pojawił się komunikat "Brak dyskietki"?

1 użytkowników online, w tym zalogowanych: 0, gości: 1