Entwickler-Ecke
Datenbanken - Anfänger braucht Vorschläge für Programmrealisation
crashboy - Mo 07.07.03 08:33
Titel: Anfänger braucht Vorschläge für Programmrealisation
Moin Moin erstmal,
als Anfänger will ich mich mal mit einem kleinen Datenbank-Proggi beschäftigen. Dafür benötige ich von Profis einige Infos zur effektivsten Umsetzung.
Ziel: Mittels eines Barcode-Scanners wird ein Artikel eingescannt, der dazugehörige EAN-Code in einer Tabelle gesucht, vollständig mit Bezeichnung angezeigt und durch Eingabe einer Stückzahl vervollständigt. Anschließend soll dieser Artikel ein einer weiteren Tabelle abgespeichert werden.
Die zu scannenden Artikel liegen vollständig in der ersten Tabelle vor (manuell eingetragen).
System: normaler PC, Handscanner- der in Tastatur eingeschliffen ist und die EAN-Codes in Form von Strings ausgiebt.
Frage: Welches DB-System sollte ich nehmen und wie gehe ich am besten vor.
Habe schonmal angefangen mit dBase. Scheint mir aber zu unflexibel und der Locate-Befehl will sich nicht so richtig mit mir anfreunden. Zumindest sollte doch nach dem Locate der Satzzeiger auf den gescannten Wert zutreffen, wa er jedoch nicht macht.
Danke für jede Hilfe
crashboy
BeniSchindler - Mo 07.07.03 13:04
Was man am besten nehmen sollte, kann man glaube ich nicht so einfach beantworten. Ich selber benutze jedoch eigentlich immer die Opensource-Interbase-Datenbank : Firebird.
Vorteile von Firebird: schnell, sehr klein, Linux und Windows fähig.
Das ist jedoch blos meine Persönliche erste wahl. Das kommt ganz auf einen selber an. Ich würde jedoch immer eine SQL-Datenbank nehmen.
Interbase/Firebird/MySQL/MSSQL/Oracel/etc.
Das einzige von dem ich abrate ist eine Access-Datenbank. Die sind mir einfach zu oft und zu schnell um die Ohren geflogen.
mfg Karr.
hwb - Mo 07.07.03 13:55
Schau erst mal hier nach:
http://www.delphi-forum.de/viewtopic.php?t=160
Und daß dein Programm mit DBase nicht funktioniert liegt aber am Programmierer. Wobei allerdings die große Zeit von DBase vorbei ist.
Auf jeden Fall wurde ich auf die BDE verzichten.
HWB
grayfox - Mo 07.07.03 15:47
halo crashboy!
| Zitat: |
...als Anfänger will ich mich mal mit einem kleinen Datenbank-Proggi beschäftigen...
|
dann würd ich dir paradox 7.0 & die BDE empfehlen. das ganze ist bei delphi dabei, ist einfach handzuhaben und hier im forum gibts schon jede menge tipps zum
nachlesen wenn du mal nicht weiterweisst.
locate stellt den satzzeiger
immer auf den gefundenen datensatz, lookup liefert nur den inhalt zurück
wenn du nach 'ausgibst' suchst, aber 'ausgiebst' in der tabelle erfasst hast, dann kanns vorkommen, dass du nicht das gewünschte ergebnis erhältst ;)
mfg, stefan
Klabautermann - Mo 07.07.03 16:53
Hallo,
vonn der BDE würde ich abraten, sie ist veraltet und wird nciht mehr weiterentwickelt. Außerdem macht sie sobald die Anforderungen etwas höher sind Probleme. Besonders im Netzwerk.
Gruß
Klabautermann
crashboy - Mo 07.07.03 17:19
Titel: Danke
erstmal für Eure Tips.
Nun sieht es so aus, dass das Programm zur simplen Vereinfachung meines Jobs dienen soll.
Ich scanne für ein Marktforschungsinstitut vorgegebene Waren in Supermärkten und vervollständige die Daten manuell mit der vorhandenen Verkaufszahl.
Mehr nicht! Hört sich so simpel an wie es ist und genauso soll das Proggi werden.
Aus diesem Grund will ich mich nicht weiter in die Tiefe der Materie reinsteigern. Letztendlich soll noch ein Ausdruck mit QR der gescannten Daten erfolgen.
Muss ich hierfür extra SQL oder dergleichen lernen?
Ich denke das ich für diese Aufgabe mit Kanonen nach Spatzen schiessen würde.
Wenn möglich, würde ich mal meinen bisherigen Source hier uppen und jemand verrät mir, wie das dann genau mit Locate funktioniert.
Gruss
crashboy
grayfox - Mo 07.07.03 17:28
hallo crashboy!
| Zitat: |
Muss ich hierfür extra SQL oder dergleichen lernen?
|
ja und nein. es kommt drauf an, für welches system du dich entscheidest.
bei paradox7 & BDE brauchst du es nicht umbedingt zu lernen. und für die erstellung eines berichtes mit QuickReport ist es auch nicht zwingend notwendig.
das locate bereitet dir noch kopfzerbrechen, gell? ;)
schlag die suchfunktion auf, tipp 'locate' ein und du findest jede menge tipps zu diesem thema.
mfg, stefan
Klabautermann - Mo 07.07.03 17:32
Hallo,
du kannst unter Delphi recht gut mit Datenbanken Arbeiten ohne SQL zu können. Erst wenn die aufgabe komplexer wird solltest du SQL lernen (ist sehr einfach und daber unheinmlich flexibel).
Auf
dieser Seite [
http://downloads.oitmann.de/samples] findest du ein NoCodeExcampel. Das ist eine kleine datenbankanwendung, die ohne eine Zeile (getippten) Quelltext erstellt wurde. Nur mit der Maus. Wenn du dieses verstanden hast, dann solltest du noch
das hier [
http://www.delphi-forum.de/viewtopic.php?t=363] lesen und kannst alles was du kennen musst. Nur würde ich dir wie gesagt zu einer anderen DB (z.B. Advantage) raten. Die funktionieren in aller regel genau so, sind aber zuverlässiger.
Gruß
Klabautermann
crashboy - Mo 07.07.03 18:11
Titel: @Klabautermann
Wiederum Danke für die schnelle Antwort.
Soweit habe ich die Problematik mit DB's verstanden. Habe ja auch selber schon rumexperimentiert und gelesen.
Ich komme halt "nur" mit dem Locate-Befehl nicht zurecht.
Die EAN wird gescannt und im DBEdit eingetragen, dann folgt Locate und er sollte dann den richtigen Datensatz finden. Macht er aber nicht. Habe mir ein DBGrid zu Hilfe genommen, um verfolgen zu können, wo der Satzzeiger steht.
Desweiteren kommt die Fehlermeldung " Ungültige Variant-Typumwandlung".
Ich hänge mal die eine Zeile an:
Quelltext
1:
| Table1.Locate('Artnummner', VarArrayOf([DBEdit1.Text]), []); |
Diese Zeile folgt auf ein OnExit-Ereignis im DBEdit.
Gruss
Mario
grayfox - Mo 07.07.03 21:28
hallo crashboy!
genau. wieso einfach, wenns umständlich auch irgendwie vielleicht doch geht? ;)
wie wärs mit:
Delphi-Quelltext
1: 2: 3: 4:
| if Table1.Locate('Artnummner', Edit1.Text, []) then ..... else ..... ; |
- bist du sicher, dass dein feld 'Artnumm
ner' heisst?
- in welches DBEditFeld welchen Datensatzes liest ihn denn ein?
einfacher gehts mit einem TEdit.Feld. diesen eintrag suchst dann in der tabelle und du hast schon den richtigen datensatz gefunden, falls es ihn gibt.
mfg, stefan
Klabautermann - Di 08.07.03 09:53
Hallo,
ansonsten kannst du es auch mit der Filter funktion versuchen, die ist glaube ich einfacher zu verstehen (aber nicht umbedingt so schnell).
Gruß
Klabautermann
crashboy - Di 08.07.03 11:05
Titel: @grayfox
Danke erstmal.
Ja das Feld heisst artnumm
ner. Hab die Tabelle jetzt aber nochmal neu erstellt. Werds gleich mal ausprobieren.
Gruss
crashboy
So, entweder bin ich zu blöd oder es ist einfacher wie ich denke:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.DBEdit1Change(Sender: TObject); begin
if Table1.Locate('Artikelnr', DBEdit1.Text, []) then begin end else end; |
Soweit ich die Locate-Anweisung verstanden habe, wird der Datensatz, falls gefunden, als aktiv markiert. Habe mir ja ein DBGrid dafür draufgesetzt um das verfolgen zu können. Der Datensatzzeiger springt aber immer auf den ersten Satz, egal ob gefunden oder nicht.
Gruss
crashboy
grayfox - Di 08.07.03 14:56
hallo crashboy!
hast deine lesebrille verlegt? vergleich mal die beiden zeilen:
deine version:
Delphi-Quelltext
1:
| if Table1.Locate('Artikelnr', DBEdit1.Text, []) then |
meine version
Delphi-Quelltext
1:
| if Table1.Locate('Artikelnr', Edit1.Text, []) then |
| Zitat: |
| Der Datensatzzeiger springt aber immer auf den ersten Satz, egal ob gefunden oder nicht. |
na no na logisch! :D überleg mal. der datensatzzeiger steht nach dem öffnen der tabelle auf dem ersten datensatz. jetzt beauftragst du locate nach dem inhalt des feldes DBEdit1 zu suchen. in diesem müsste ein eintrag es ersten datensatzes zu finden sein. richtig? daher lies den code des scanners in ein editfeld ein und dann such danach in der tabelle. das ist viel einfacher...
mfg, stefan
crashboy - Di 08.07.03 17:11
Titel: Hurra
Funzt :D :D :D
Letzte Frage: Wie bekomme ich die gescannten Datensätze, also die, die er gefunden hat, in eine 2. existierende Tabelle.
Soll heissen, die Daten in der 1. Tabelle bleiben unverändert und die Felder Artikelnummer und -name sowie ein DBEdit namens Stück sollen in die 2. rein.
Unter Clipper kannte ich den Befehl Replace. Laut Onlinehilfe hat der aber wenig damit zu tun.
Und zweite Frage, in der else anweisung soll ein Sprung auf einen Button erfolgen, wenn der EAN nicht gefunden wurde.
Danke Danke
für Eure Hilfe
Gruss
crashboy
CenBells - Di 08.07.03 19:15
hallo,
ich habe mal ne ganz andere frage, was für einen handscanner verwendest du? Und wie steuerst du den an?
Gruß
Ken
crashboy - Di 08.07.03 22:52
Titel: @cenbells
Das ist so ein Billigteil von aus dem akt. Conrad Katalog. 69 €, Made in TW und frisst jeden Barcode. Programmierbar über beiliegende Barcodes. Anschluss mittels Y-Kabel an Tastatur.
Funzt tadellos.
Gruss
crashboy
hwb - Mi 09.07.03 07:53
Nochmal zurück zu deinem ersten Posting:
Warum arbeitest du mit LOCATE ? Ich geh mal davon aus, daß dei Tabelle in der gesucht wird auch von dir ist. Also was hindert dich daran auf das Feld mit dem EAN-Code einen Index zu setzen und mit FINDKEY zu arbeiten ? Da doch jeder Code einmalig ist, sollte das die bessere Möglichkeit sein.
HWB
grayfox - Mi 09.07.03 08:08
hallo crashboy!
na siehst, so schlecht war mein vorschlag gar nicht ;)
| Zitat: |
Soll heissen, die Daten in der 1. Tabelle bleiben unverändert und die Felder Artikelnummer und -name sowie ein DBEdit namens Stück sollen in die 2. rein.
|
mal ein ganz einfaches beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| {$UNTESTED} if quelltable.locate('Artikelnr', ScanCode.Text, []) then begin with zieltable do begin append; FieldByName('Artikelnr').asString:= ScanCode.Text; FieldByName('Bezeichnung').asString:= quelltable.FieldByName('Bezeichnung').asString; FieldByName('Anzahl').asInteger:= StrToInt(Anzahl.Edit); post end; end else ShowMessage('EAN-Code noch nicht angelegt'); end; |
das wäre das grundprinzip des datensatzanlegens, unter der voraussetzung, dass beide tabellen vorhanden und offen sind.
mit dem anzahlfeld als DBEdit könnte sich ein problem ergeben, sobald der EAN-Code nicht gefunden wird. daher würde ich ein normales Edit-Feld verwenden und im OnExitEvent den feldinhalt auf gültigkeit überprüfen. dafür findest hier im forum beispiele zur genüge.
was meinst denn damit?
| Zitat: |
in der else anweisung soll ein Sprung auf einen Button erfolgen
|
auf einen button bin ich noch nie gesprungen ;)
mfg, stefan
crashboy - Mi 09.07.03 10:18
Titel: @grayfox
Danke erstmal für Deinen Tip. Learning by doing macht richtig Spass.
Habe Deinen Vorschlag mal folgendermaßen umgesetzt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TForm1.Edit1Exit(Sender: TObject); begin
if table1.locate('Artikelnr', Edit1.Text, []) then begin with Table2 do begin Append; FieldByName('Artikelnr').asInteger:= Table1.FieldByName('Artikelnr').AsInteger; FieldByName('Artikelnam').asString:= Table1.FieldByName('Artikelnam').asString; FieldByName('Anzahl').asInteger:= StrToInt(DBEdit2.Text); post end; end else ShowMessage('EAN-Code noch nicht angelegt'); end; |
Wie nicht anders zu erwarten funzt es net. :( Noch zur Erläuterung: Der gescannte Code ist vom Typ numerisch, in der 2. Tabelle soll er praktischerweise auch numerisch abgelegt werden. Wenn ich nun aber das Edit1.Exit auslöse, d.h. Artikel wurde gescannt und gefunden, kommt die Fehlermeldung:
| Zitat: |
| "" ist kein Integerwert. |
Logisch, Nichts kann nicht Integer sein. Warum ist da aber nichts? Ausserdem darf doch ne Integer nicht mehr als 10 Stellen haben. Da denke ich nur an der EAN13. Hier müsste doch dann ein Int64 rein. Nur wie? :(
In der
else-Anweisung soll nicht extra ne ShowMessage erscheinen, sondern der Tab gleich auf den "NEU"-Button erfolgen.
Danke für Deine Hilfe
Gruss
crashboy
CenBells - Mi 09.07.03 11:01
Titel: Re: @grayfox
| crashboy hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure TForm1.Edit1Exit(Sender: TObject); begin
if table1.locate('Artikelnr', Edit1.Text, []) then begin ... end; |
| Zitat: | | "" ist kein Integerwert. |
Logisch, Nichts kann nicht Integer sein. Warum ist da aber nichts?
|
hallo,
ich habe den gesamten thread nicht mit vollem fleiß gelesen, aber wann füllst du denn Edit1? Ich meine, wenn du bsp bei programmstart nichts drin hast und dann das edit verlässt, dann steht doch noch immer nichts drin, oder?
Du könntest vorher noch eine überprüfung einbauuen, ob edit1.text <> '' wenn der text nicht leer ist, kannst du mit deinem locat weiter machen.
Gruß
Ken
crashboy - Mi 09.07.03 11:54
Titel: @cenbells
Der locate-Befehl wird doch erst ausgeführt, wenn ich das Edit verlasse und in dem Moment stehen doch die gescannten Daten drin, sprich der EAN als Zahlenfolge.
Probeweise habe ich einen nichtvorhandenen Artikel gescannt und dann wird ordnungsgemäß else ausgeführt.
Gruss
crashboy
CenBells - Mi 09.07.03 12:01
hast du schon mal mit einem breakpoint die genaue zeile bestimmt, in der der fehler auftritt? das könnte ungemein helfen.
Gruß
Ken
crashboy - Mi 09.07.03 12:18
Titel: @cenbells
Hab das ganze als String umprogrammiert und die Tabellen neu typisiert.
Funzt jetzt.
Jetzt nur noch die Datensätze ohne QR auf Papier bringen und fertig.
Gruss
crashboy
grayfox - Mi 09.07.03 12:49
hallo crashboy!
Delphi-Quelltext
1:
| StrToInt(DBEdit2.Text) |
das hab ich dir aber so sicherlich nicht gesagt. nimm lieber ein Edit-feld zum erfassen der menge, das ist einfacher.
den EAN-code würde ich auch als string und nicht als integer ablegen - du willst ja nicht damit rechnen.
mach deinen bericht lieber mit QR, das geht einfacher und schneller als 'zu fuss'. vor rund 2 wochen hat kiwicht hier im forum ein tolles tutorial über die anwendung von QR erstellt.
mfg, stefan
crashboy - Mi 09.07.03 14:47
Titel: @all
Ich habe das jetzt alles als String gemacht. Problem war nur den Scanner dazu zu kriegen, die Daten nicht numerisch zu schicken. Hätte ich auch erst wieder umwandeln müssen. Nu funzt es erstmal ganz gut und ich hab viel gelernt.
Gruss
crashboy
Hab jetzt 2 allerletzte Fragen:
Soweit haut alles hin. Will aber noch eine 2. Abhängigkeit einbauen.
Die Daten sollen erst dann in die zweite Tabelle eingetragen werden, wenn beide Edit-Felder ausgefüllt sind. Das funzt aber mit dem .AND. nicht ganz.
Wie kann ich das realisieren?
Und 2. wie kann ich am einfachsten einen Tabelleninhalt löschen?
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.Edit1Exit(Sender: TObject);
begin Table2.Append; if Edit1.Text <>'' .AND. Edit2.Text <> '' then begin if table1.locate('Artikelnr', Edit1.Text, []) then begin with Table2 do begin FieldByName('Artikelnr').AsString:= Table1.FieldByName('Artikelnr').asString; FieldByName('Artikelnam').asString:= Table1.FieldByName('Artikelnam').asString; FieldByName('Anzahl').asString:= Edit2.Text; Table2.Post end;
end else ShowMessage('EAN-Code noch nicht angelegt'); end else ShowMessage('EAN-Feld darf nicht leer sein'); end; |
Gruss
crashboy
grayfox - Mi 09.07.03 14:57
diesen satz hier versteh ich nicht:
| Zitat: |
die Daten nicht numerisch zu schicken...
|
mal langsam zum mitschreiben:
du stellst dich auf das eingabefeld es EAN-codes und liest mit dem scanner den code ein - dieser füllt das einabefeld genauso, als wenn du über die tastatur ziffer für ziffer eintippen würdest. richtig?
den inhalt des edit-feldes hast dann als string vorliegen. stimmts?
was hättest denn da hin- und herwandeln müssen?
mfg, stefan
crashboy - Mi 09.07.03 18:24
Titel: @grayfox
Als ich die gescannten EAN's als Typ Character in meiner Tabelle Speichern wollte ging es nicht. Nur Numerisch. Sorry, war aber so.
Bin immernoch dabei die 2.
If-Anweisung einzubinden. Ich platziere das dazugehörige
Endfalsch. Könnte verrückt werden.
Und dann stören auch immernoch die lästigen Nachbarn weil meine LAG heute ihre Fahrprüfung bestanden hat.
Hier nochmal der derzeit funzende Code:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TForm1.Edit1Exit(Sender: TObject);
begin if Edit1.Text <>'' then begin if table1.locate('Artikelnr', Edit1.Text, []) then begin if Edit2.Text<> '' then begin with Table2 do begin Table2.Append; FieldByName('Artikelnr').AsString:= Table1.FieldByName('Artikelnr').asString; FieldByName('Artikelnam').asString:= Table1.FieldByName('Artikelnam').asString; FieldByName('Anzahl').asString:= Edit2.Text; Table2.Post end end; end else ShowMessage('EAN-Code noch nicht angelegt'); end else ShowMessage('EAN-Feld darf nicht leer sein'); end; |
Problem: jeder Artikel wird 2x in der 2. Tabelle abgespeichert. Einmal mit der Bezeichung des Edit2-Feldes und einmal mit der tatsächlich eingegebenen Anzahl.
Und wie gesagt, wie bekomme ich die Tabelle ohne SQL am schnellsten leer? Records zählen und ne Zählschleife bauen?
Gruss
crashboy
grayfox - Mi 09.07.03 18:48
versuchs mal so - vorsicht: untested ;)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Edit1Exit(Sender: TObject); begin if Edit1.Text ='' then begin ShowMessage('EAN-Feld darf nicht leer sein'); Exit end; Table2.Append; if table1.locate('Artikelnr', Edit1.Text, []) then begin with Table2 do begin FieldByName('Artikelnr').AsString:= Table1.FieldByName('Artikelnr').asString; FieldByName('Artikelnam').asString:= Table1.FieldByName('Artikelnam').asString; FieldByName('Anzahl').asString:= Edit2.Text; Table2.Post end else ShowMessage('EAN-Code noch nicht angelegt');
end; |
.AND. gehört zu DBase & Clipper und wird von delphi nicht unterstützt *g*
vergleiche mit mehreren parametern schrteibt man in klammern:
Delphi-Quelltext
1:
| if (Edit1.Text <>'') and (Edit2.Text <> '') then ... |
sieht dir mal das format des EAN-codes in der tabelle an. ist das ein ziffernfeld?
mfg, stefan
ps: gratulation unbekannterweise an deine freundin. dann feiert mal schön ;)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!