[Delphi6Ent/Interbase]Formularz Master-Detail

Odpowiedz Nowy wątek
2006-08-25 10:00
0

Witam!!!
Mam taki problem, otóż stworzyłem sobie formularz(master-detail) do wprowadzania danych(coś takiego jak faktura z pozycjami), formularz skałda sie z DbNavigatora i paru DBEditów polączonych z jedną tabelą i DBGrig polączony z drugą tabela. Wszystko pięknie działa jak wpisze dane i zatwierdzam przyciskiem Post z DBNawigatora, ale ja chcąc sobie troche utrudnić sprawę postanowiłem zrobić własny przycisk do zatwierdzania wprowadzonych danych, tylko że ładnie wprowadza mi to co wpisze w DbEdity(czyli to co jest połączone z pierwsza tabelą) ,a problem tkwi w tym że chcąc zatwierdzić drugą tabele np. IBTable2.Post potrzebuje do wszystkich zatwierdzanych/wpisywanych rekordów do DBGrida numer aktualnego rekordu z pierwszej tabeli.

procedure TTest.BitBtn1Click(Sender: TObject);
Begin
if not DataModule.IBTransaction1.InTransaction then
 DataModule.IBTransaction1.StartTransaction;
proceduraInsert('INSERT INTO Tabela (a,b,c) VALUES('a','''+Edit1.text+''',....,...);'); //procedura wprowadzająca dane do pierwszej tabeli.
 DataModule.IBTransaction1.Commit;
 DataModule.IBTable1.Open;
Test.Close;
End;
 

Dodam tylko że "a" jest to pole(klucz główny) zwiększane o jeden podczas dodawania nowego rekordu.
Mam nadzieję że wystarczająco opisałem mój problem;
Z góry dziekuje za pomoc i Pozdrawiam:)

Pozostało 580 znaków

2006-08-26 11:56
0

Spróbuje troche przybliżyć problem na podstawie prób jakie wykonałem:

Mam min. dwie tabele w mojej bazie z takimi polami:
table1:
a integer not null;
b char;
c char;
primary key(a);

table 2
d integer not null;
a integer;
e char;
f char;
primary key(d)

i taka referencja miedzy tymi tabelami:
ALTER TABLE "table2" ADD FOREIGN KEY ("a") REFERENCES table1 ("a");

Na podstawie tych dwóch tabel zrobiłem sobie formularz master_detail tak jak opisałem powyżej;
Oprogramowałem tez dwa zdaczenia NewRekord w ten sposób(może nie najlepszy ale powinno zadziałać)
Zdarzenie OnNewRekord tabeli1;

   try
      a:=StrToInt(proceduraSelect('SELECT MAX(a) AS ID FROM table1......'));//procedura liczaca max z   pola "a"//
      a:=a+1;
    except
      on EConvertError do a:=1;
    end;

Zdarzenie OnNewRekord tabeli2;

procedure TDataModule.IBTable2NewRecord(DataSet: TDataSet);
begin
 IBTable2.FieldByName('a').AsInteger:=a;
end;

I jak próbuje podczas wpisywania w DBGrig dodać 1 rekord to nie ma problemu wszystko ładnie liczy i przydziela polu "a" tabeli2 odpowiedni numer według procedurki OnNewRekord tabeli2; ,a jak już chcĘ dodać kolejny rekord to pojawia sie błąd:
Violation of Foreign Key constraint integer 77 on table "Table2"

I kompletnie nie mam pojęcia jak temu sprostać.
Jak usunę relacje z tabeli to wszystko pięknie hula. Czyżbym źle zrobił relacje???
Z góry dziękuje za podpowiedź
Pozdrawiam:)

Pozostało 580 znaków

2006-08-28 16:27
0

zostawić TIBTable w spokoju, zamiast nich TIBQuery (i zamiast TDBEdit TEdit), dodawanie nagłówka procedurą, która zwraca ID dodanego nagłówka, parametry w SQLu a nie dziwne konstrukcje


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-08-28 19:28
0

Dziękuje Misiekd za odpowiedź, ale wydaje mi sie że właśnie tak robię jak Ty piszesz. Dane do IBTable1 wpisywane sa z Editów/DBEditów i zatwierdzane przyciskiem/procedurą:

procedure TTest.BitBtn1Click(Sender: TObject);

dodawanie nagłówka procedurą, która zwraca ID dodanego nagłówka

Dodawanie nagłówka nie wiem czy dobrze rozumiem ale chyba chodzi tu o klucz główny tabeli odbywa sie w procedurze dodawania nowego rekordu do tabeli za pomocą procedurki opartej właśnie na zapytaniach SQL:

a:=StrToInt(proceduraSelect('SELECT MAX(a) AS ID FROM table1......'));//procedura liczaca max z   pola "a"//

A ta procedurka wyglada tak:

procedure Select(zapytanie:String; IBQuery:TIBQuery; IBDataBase:TIBDataBase);
begin
    IBQuery.Close;               
    IBQuery.SQL.Clear;           
    IBQuery.SQL.Add(zapytanie);  
    IBQuery.Open;                 
end;

Także wpisywanie do pierwszej tabeli jest ok-chyba że sie mylę.
Wpisywanie do drugiej odbywa sie za pomocą zatwierdzenia IBTable2.Post ponieważ jest połączony z DBgridem, no chyba tak najłatwiej, tylko jedno pole(własnie to nieszczęsne a(klucz główny IBTable1)) wstawiane do każdego rekordu IBTable2 stwarza mi problem podczas próby wpisania 2 rekordu do DbGrida.
Bardzo chetnie dowiedziałbym sie jak to prosciej zrobić bez tych

dziwne konstrukcje

.
Z góry dziękuje za odpowiedź.
Pozdrawiam:)

Pozostało 580 znaków

2006-08-28 19:57
0

chodziło mi o procedurę wbudowaną na serwerze, coś na kształt

CREATE PROCEDURE DODAJ_NAGLOWEK (
    POLE_1 Typ,
    POLE_2 Typ,
    ...)
RETURNS (
    NAGLOWEK_ID INTEGER)
AS
DECLARE VARIABLE ID INTEGER;
BEGIN
  id = gen_id(nazwa_generatora_id_dla_tabeli_naglowki, 1);
  INSERT INTO tabela (pole_id, pole1, pole2, ...) VALUES (:id, pole_1, pole_2, ...);
END

i potem

with IBQuery, SQL do
begin
  Clear;
  Add('SELECT * FROM DODAJ_NAGLOWEK(:a, :b, ...)');
  ParamByName('a').AsTyp := edit1.text;
  ParamByName('b').AsTyp := edit2.text;
  ParamByName('...').AsTyp := editx.text;
  Open;
end;

a co do pozbycia się TIBTabel to miałem na myśli pozbycie się całkowicie także przy dodawaniu pozycji


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-08-30 16:21
0

Ok, przestudiowałem troche zagadnienie procedur/wyzwalaczy, i zastosowałem w swoim programiku, ale nadal nie moge rozgryźć tego problemu "z nadawaniem klucza obcego IBtable2". Jak mając 2 tabele i jeden formularz(taki master/detail czyli dane o fakturze(IBTable1) z kilkoma pozycjami wpisywanymi w DBGrid(IBTable2)), dodawać kolejne rekordy w DBGridzie, tak aby każdy rekord wpisany w DBGrida dostał automatycznie numer ID faktury(czyli klucz głowny IBTable1) do której będą należały te pozycje i wszystko zatwierdzić jednym przyciskiem np BitBtn.
Wiem, że da sie to zrobic bo przeciez na tej zasadzie są wystawiane wszystkie dokumenty(faktury, dokumenty magazynowe, przesunięcia magazynowe itp.)
Pozdrawiam:)

Pozostało 580 znaków

2006-08-30 16:25
0

piszę to po raz ostatni zostaw IBTable i dodawaj pozycje "ręcznie" SQLem!


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-08-30 21:11
0

Rozumiem, tylko jak dodać np. 2 wiersze wpisane do DBGrida, do tabeli za pomocą SQLa.
Dziękuję za pomoc!!!
Pozdrawiam:)

Pozostało 580 znaków

2006-08-30 21:26
0

masz dwa wyjścia
1) przed dodaniem jakiejkolwiek pozycji MUSISZ dodać nagłówek - wtedy masz ID nagłówka
2) zamiast wpisywać pozycje do bazy zapisujesz je sobie na jakiejś liście (tablica rekordów czy cuś), wyświetlasz np. w StringGridzie i dopiero przy zatwierdzeniu faktury (bo mowa była o fakturach, ale dotyczy wszystkiego co jest tak skonstruowane) dodajesz nagłówek i potem pozycje

wniosek jest jeden - jak byś nie robił najpierw musisz dodać NAGŁÓWEK dlatego wg mnie pomysł z dodatkową listą pozycji jest najlepszy


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-09-04 23:03
0

Wielkie DDDzięki Misiekd, troche pokombinowałem z tym StringGridem i coś już pomalutku zaczyna pasować!!!
Pozdrawiam:)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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