AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Joblist - Aufgabenplaner

Joblist - Aufgabenplaner

Ein Thema von AlexII · begonnen am 18. Sep 2014 · letzter Beitrag vom 19. Nov 2014
Antwort Antwort
Seite 1 von 3  1 23   
AlexII
Registriert seit: 28. Apr 2008
Hallo,

ich habe eine kleine Anwendung zum Aufgabenplanung geschrieben. Man kann eine Aufgabe mit bestimmten Eigenschaften (Beginn, Priorität, Status, Beschreibung, Ort, usw.) anlegen und verwalten, aber am besten siehe Screenshot.

Die Anwendung hat bis jetzt nur die nötigsten Funktionen, da ich erst das "Fundament" stabil schreiben möchte. Daher werde ich mich als Hobbyprogrammierer sehr freuen wenn sie mir dabei helfen, vor allem mein Umgang mit der DB bewerten und gute Tipps gibt. Der Quellcode liegt bei. ))

Danke!

19.09.2014 Version 0.4 alpha
- Bug Post #2 beseitigt!

22.09.2014 Version 0.5 beta
- Vorschlag aus Post #3 umgesetzt
- Fehlerausgabe in MessageDlg() erweitert



P.S. falls jemand Lust und Laune hat, kann mir bei der Entwicklung helfen. ))
Miniaturansicht angehängter Grafiken
screenshot.png   db-modell.png  
Angehängte Dateien
Dateityp: zip Joblist-05.zip (2,35 MB, 56x aufgerufen)
Bin Hobbyprogrammierer! Meine Fragen beziehen sich meistens auf Lazarus!

Geändert von AlexII (22. Sep 2014 um 15:11 Uhr)
 
Benutzerbild von freak4fun
freak4fun

 
Delphi 10.2 Tokyo Starter
 
#2
  Alt 18. Sep 2014, 23:49
Wenn ich die über FK eingebundene Werte in den Tabellen lösche, sind alle anderen Einträge auch betroffen. Das sollte nicht passieren.
Zumindest eine Warnung sollte erscheinen.
  Mit Zitat antworten Zitat
-=ZGD=-

 
Delphi 10.1 Berlin Professional
 
#3
  Alt 19. Sep 2014, 08:11
Guten Morgen.

Find´s gut.
Funktioniert.

Ich habe mir natürlich auch mal den Quelltext angeschaut.

Es gibt einige Dinge, die ich anders machen würde, da diese redundant sind.

Du hast zwei Funktionen, die bis auf die Reihenfolge der Selektierung die gleichen Felder abfragen. Einzige Unterschiede sind das Flag zum Einen und die Listview zum Anderen.

Delphi-Quellcode:
// Geschlossene Aufgaben
procedure TForm1.LoadCloseJobslistByStart();
var
  MyItem: TListItem;
begin
  try

    ListView2.Clear;
    ListView2.Items.BeginUpdate;

    SQLQuery1.Close;
    SQLQuery1.SQL.Text := 'SELECT tbmain.id_tbmain, '
    + 'tbmain.title, '
    + 'tbmain.start, '
    + 'tbmain.ende, '
    + 'tbcategory.category, '
    + 'tbprocessowner.processowner, '
    + 'tbpriority.priority, '
    + 'tbstatus.status, '
    + 'tbplace.place '
    + 'FROM tbmain '
    + 'LEFT JOIN tbcategory ON tbmain.fk_category_id=tbcategory.id_tbcategory '
    + 'LEFT JOIN tbprocessowner ON tbmain.fk_processowner_id=tbprocessowner.id_tbprocessowner '
    + 'LEFT JOIN tbpriority ON tbmain.fk_priority_id=tbpriority.id_tbpriority '
    + 'LEFT JOIN tbstatus ON tbmain.fk_status_id=tbstatus.id_tbstatus '
    + 'LEFT JOIN tbplace ON tbmain.fk_place_id=tbplace.id_tbplace WHERE flag = 1';
    SQLQuery1.Open;
    while not SQLQuery1.Eof do
    begin
      MyItem := ListView2.Items.Add;
      MyItem.Data := Pointer(SQLQuery1.FieldByName('id_tbmain').AsInteger); //data mit ids fuellen. Mit dieser ID werden weitere Operationen gemacht, z.B. Bearbeiten, Löschen
      MyItem.Caption := SQLQuery1.FieldByName('title').AsString;
      MyItem.SubItems.Add(SQLQuery1.FieldByName('priority').AsString);
      MyItem.SubItems.Add(DateToStr(SQLQuery1.FieldByName('start').AsDateTime)); // DateTimeToStr zeigt auch die Uhrzeit an

      // Prüfen, ob Datenfeld belegt
      if not SQLQuery1.FieldByName('ende').IsNull then
        MyItem.SubItems.Add(DateToStr(SQLQuery1.FieldByName('ende').AsDateTime))
      else MyItem.SubItems.Add('');

      MyItem.SubItems.Add(SQLQuery1.FieldByName('place').AsString);
      MyItem.SubItems.Add(SQLQuery1.FieldByName('category').AsString);
      MyItem.SubItems.Add(SQLQuery1.FieldByName('processowner').AsString);
      MyItem.SubItems.Add(SQLQuery1.FieldByName('status').AsString);
      SQLQuery1.Next;
    end;

    ListView2.Items.EndUpdate;

  except
    MessageDlg('Die Aufgaben konnten nicht gelesen werden!', mtError, [mbOk], 0);
  end;
end;

// Offene Aufgaben
procedure TForm1.LoadJobslistByStart();
var
  MyItem: TListItem;
begin
  try

    ListView1.Items.BeginUpdate;
    ListView1.Clear;

    SQLQuery1.Close;
    SQLQuery1.SQL.Text := 'SELECT tbmain.id_tbmain, '
    + 'tbmain.title, '
    + 'tbmain.start, '
    + 'tbmain.ende, '
    + 'tbcategory.category, '
    + 'tbprocessowner.processowner, '
    + 'tbpriority.priority, '
    + 'tbstatus.status, '
    + 'tbplace.place '
    + 'FROM tbmain '
    + 'LEFT JOIN tbcategory ON tbmain.fk_category_id=tbcategory.id_tbcategory '
    + 'LEFT JOIN tbprocessowner ON tbmain.fk_processowner_id=tbprocessowner.id_tbprocessowner '
    + 'LEFT JOIN tbpriority ON tbmain.fk_priority_id=tbpriority.id_tbpriority '
    + 'LEFT JOIN tbstatus ON tbmain.fk_status_id=tbstatus.id_tbstatus '
    + 'LEFT JOIN tbplace ON tbmain.fk_place_id=tbplace.id_tbplace WHERE flag = 0';
    SQLQuery1.Open;
    while not SQLQuery1.Eof do
    begin
      MyItem := ListView1.Items.Add;
      MyItem.Data := Pointer(SQLQuery1.FieldByName('id_tbmain').AsInteger); //data mit ids fuellen. Mit dieser ID werden weitere Operationen gemacht, z.B. Bearbeiten, Löschen
      MyItem.Caption := SQLQuery1.FieldByName('title').AsString;
      MyItem.SubItems.Add(SQLQuery1.FieldByName('priority').AsString);
      MyItem.SubItems.Add(DateToStr(SQLQuery1.FieldByName('start').AsDateTime)); // DateTimeToStr zeigt auch die Uhrzeit an

      // Prüfen, ob Datenfeld belegt
      if not SQLQuery1.FieldByName('ende').IsNull then
        MyItem.SubItems.Add(DateToStr(SQLQuery1.FieldByName('ende').AsDateTime))
      else MyItem.SubItems.Add('');

      MyItem.SubItems.Add(SQLQuery1.FieldByName('place').AsString);
      MyItem.SubItems.Add(SQLQuery1.FieldByName('category').AsString);
      MyItem.SubItems.Add(SQLQuery1.FieldByName('processowner').AsString);
      MyItem.SubItems.Add(SQLQuery1.FieldByName('status').AsString);
      SQLQuery1.Next;
    end;

    ListView1.Items.EndUpdate;

  except
    MessageDlg('Die Aufgaben konnten nicht gelesen werden!', mtError, [mbOk], 0);
  end;
end;
Besser wäre es, du würdest einfach einen Boolean übergeben und die ListView.

Delphi-Quellcode:
procedure LoadJobslistByStart(aClosedOnes: Boolean; aListView: TListView);
begin
  //Irgendwo unterscheidest du dann.
  ...
  + 'LEFT JOIN tbplace ON tbmain.fk_place_id=tbplace.id_tbplace WHERE flag = :flag';

  if aClosedOnes then
  begin
   SQLiteQuery1.ParamByName('flag').value:= 0;
  end
  else
  begin
   SQLiteQuery1.ParamByName('flag').value:= 1;
  end;

  //Weitere Verarbeitung
end;
Gruß,
Stefan
Stefan Michalk
  Mit Zitat antworten Zitat
AlexII

 
FreePascal / Lazarus
 
#4
  Alt 19. Sep 2014, 09:44
Wenn ich die über FK eingebundene Werte in den Tabellen lösche, sind alle anderen Einträge auch betroffen. Das sollte nicht passieren.
Zumindest eine Warnung sollte erscheinen.
Stimmt, habe es noch nicht bemerkt. Danke Dir werde es ändern!
  Mit Zitat antworten Zitat
AlexII

 
FreePascal / Lazarus
 
#5
  Alt 19. Sep 2014, 09:46
@-=ZGD=-

Ok, danke für den Tipp. Und sonst alles gut, oder hast Du dir nicht alles angeschaut?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

 
Delphi 10.2 Tokyo Professional
 
#6
  Alt 19. Sep 2014, 10:16
Apropos doppelter Code.
Zitat:
Delphi-Quellcode:
if aClosedOnes then
begin
  SQLiteQuery1.ParamByName('flag').value := 0;
end
else
begin
  SQLiteQuery1.ParamByName('flag').value := 1;
end;
Das ist ja wie ein
Delphi-Quellcode:
if MyBoolean then
  Result := True
else
  Result := False;
In Delphi ist True als 1 definisert und False ist sowieso immer 0, darum ginge das hier.
SQLiteQuery1.ParamByName('flag').value := Ord(aClosedOnes);

Aber aus selbem Grund, warum ich ständig drarauf hinweise, daß man if MyBool = True then nicht machen sollte, da zwar die Konstante "True" = 1, aber der Zustand "True" <> 0 ist, wäre es so bestimmt sicherer,
SQLiteQuery1.ParamByName('flag').value := IfThen(aClosedOnes, 1, 0);
wenn man nicht sichestellen kann, was in der Variable drin steckt.


bzw.
WHERE flag = :flag; / SQLiteQuery1.ParamByName('flag').AsInteger := IfThen(aClosedOnes, 1, 0);
WHERE (flag <> 0) = :flag; / SQLiteQuery1.ParamByName('flag').AsBoolean := aClosedOnes;

Geändert von himitsu (19. Sep 2014 um 10:23 Uhr)
  Mit Zitat antworten Zitat
AlexII

 
FreePascal / Lazarus
 
#7
  Alt 19. Sep 2014, 10:21
Gut, ich komme noch dazu... bin noch am Post #2

Habe das Problem so gelöst, aber die FK werden trotzdem gelöscht. Ich verstehe nicht wieso, ist doch alles richtig gemacht, zumindest beim DB Erstellen.

Delphi-Quellcode:
PRAGMA foreign_keys = ON;

CREATE TABLE [tbmain] (
  [id_tbmain] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  [title] TEXT NOT NULL,
  [start] DATETIME NOT NULL,
  [ende] DATETIME,
  [memo] TEXT,
  [flag] INTEGER NOT NULL,
  [fk_category_id] INTEGER,
  [fk_processowner_id] INTEGER,
  [fk_priority_id] INTEGER,
  [fk_status_id] INTEGER NOT NULL,
  [fk_place_id] INTEGER,
  FOREIGN KEY ([fk_category_id]) REFERENCES [tbcategory]([id_tbcategory]) ON DELETE RESTRICT,
  FOREIGN KEY ([fk_processowner_id]) REFERENCES [tbprocessowner]([id_tbprocessowner]) ON DELETE RESTRICT,
  FOREIGN KEY ([fk_priority_id]) REFERENCES [tbpriority]([id_tbpriority]) ON DELETE RESTRICT,
  FOREIGN KEY ([fk_status_id]) REFERENCES [tbstatus]([id_tbstatus]) ON DELETE RESTRICT,
  FOREIGN KEY ([fk_place_id]) REFERENCES [tbplace]([id_tbplace]) ON DELETE RESTRICT)
  Mit Zitat antworten Zitat
-=ZGD=-

 
Delphi 10.1 Berlin Professional
 
#8
  Alt 19. Sep 2014, 10:26
Apropos doppelter Code.
Zitat:
Delphi-Quellcode:
if aClosedOnes then
begin
  SQLiteQuery1.ParamByName('flag').value := 0;
end
else
begin
  SQLiteQuery1.ParamByName('flag').value := 1;
end;
Das ist ja wie ein
Delphi-Quellcode:
if MyBoolean then
  Result := True
else
  Result := False;
In Delphi ist True als 1 definisert und False ist sowieso immer 0, darum ginge das hier.
SQLiteQuery1.ParamByName('flag').value := Ord(aClosedOnes);

Aber aus selbem Grund, warum ich ständig drarauf hinweise, daß man if MyBool = True then nicht machen sollte, da zwar die Konstante "True" = 1, aber der Zustand "True" <> 0 ist, wäre es so bestimmt sicherer,
SQLiteQuery1.ParamByName('flag').value := IfThen(aClosedOnes, 1, 0);
wenn man nicht sichestellen kann, was in der Variable drin steckt.


bzw.
WHERE flag = :flag; / SQLiteQuery1.ParamByName('flag').AsInteger := IfThen(aClosedOnes, 1, 0);
WHERE (flag <> 0) = :flag; / SQLiteQuery1.ParamByName('flag').AsBoolean := aClosedOnes;
Da hast du schon recht.

Ich persönlich mach das immer so wie von mir beschrieben, da oft bei der Entscheidung neuer/aktualister Datensatz noch einige andere Anweisungen/Callbacks/etc. folgten.
Stefan Michalk
  Mit Zitat antworten Zitat
-=ZGD=-

 
Delphi 10.1 Berlin Professional
 
#9
  Alt 19. Sep 2014, 10:29
Da fällt mir ein...war True in Delphi nicht -1 - irgendwann mal?
Stefan Michalk
  Mit Zitat antworten Zitat
AlexII

 
FreePascal / Lazarus
 
#10
  Alt 19. Sep 2014, 15:52
Habe den Fehler aus Post #2 beseitigt... man war das eine Quälerei... Aber es läuft jetzt. Jetzt sind die nächsten Tipps dran.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:24 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf