0

Inventarnummer suchen oder anlegen

Hallo zusammen,

wir testen gerade, ob wir Ninox nutzen, um unser Büroinventar zu dokumentieren (keine Warenwirtschaft, sondern nur Dokumentation für technische Prüfung und Versicherung).

Eigentlich geht es um eine einfache Tabelle. Jedes Gerät kriegt eine Inventarnummer (0001, 0002, usw.). Dann sind dort Bezeichnung, Lieferant, Kaufdatum, Kaufpreis, etc. hinterlegt.

Im Moment sieht das so aus:

 

Jetzt verzweifle ich ein bisschen bei folgender Aufgabe:

Das Feld Inventarnummer ist nicht mehr zu bearbeiten, wenn schon eine Nummer darin steht – das hab' ich hinbekommen.

Ich würde mir jetzt aber wünschen, dass man bei einem leeren/neuen Datensatz die Inventarnummer eingibt und dann geprüft wird, ob sie schon vorhanden ist. Wenn sie noch nicht vorhanden ist, wird das Feld einfach ausgefüllt. Soweit funktioniert das natürlich.

Wenn die Inventarnummer aber schon vorhanden ist, soll sich der entsprechende Datensatz öffnen. Damit dient das Feld sozusagen als Suche. Auch das klappt mit folgendem Code, der nach Änderung ausgeführt wird:

let myART := 'Inventar-Nr.';
if cnt((select Inventarliste)['Inventar-Nr.' = myART]) > 1 then
'Inventar-Nr.' := null;
let myR := last(select Inventarliste where 'Inventar-Nr.' = myART);
openRecord(myR)
end

Problem dabei: Zwar wird das Feld Inventar-Nr. wieder leer gemacht, damit keine Nummer doppelt existiert, aber die leere Zeile existiert weiterhin in der Tabelle. Ich gehe also ans Ende der Tabelle, gebe eine Nummer ein, die schon existiert, komme zum richtigen Datensatz, habe aber eine leere Zeile in der Tabelle.

Wenn ich diesen Vorgang ein paar mal wiederhole, ist das ein ganz schönes Chaos.

Gibt es dafür eine besser Lösung?

Vielleicht muss man auch ein gesondertes Feld machen zur Suche, dass – falls nichts gefunden wird – einen neuen Datensatz erzeugt? Das scheint mir aber erst einmal recht umständlich.

Oder kann man den gerade geöffneten Datensatz löschen, bevor der andere geöffnet wird? Problem dabei: Manchmal gibt es schon einen Datensatz, der nachträglich eine Inventarnummer bekommt. Also müsste beim Löschen (falls das der richtige Weg ist) vorab geprüft werden, ob der Datensatz komplett leer ist...

Vermutlich ist mein Problem einfach zu lösen – ich komme aber als Neuling nicht darauf.

Herzlichen Dank schonmal!

Grüße, Roland

15 Antworten

null
    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hallo Roland, woher kommen die Inventar-Nummern? Existieren die bereits und werden nur in Ninox übertragen? Oder werden sie beim Erfassen des Inventargegenstandes manuell vergeben? In letzterem Fall würde ich mir überlegen, die Nummer automatisch beim Anlegen eines neuen Datensatzes generieren zu lassen. Dann wäre von vornherein ausgeschlossen, dass die Nummer schon existiert. Das setzt allerdings eine Systematik voraus, und sei es nur eine bei 1 startende fortlaufende Nummer.

    Mir ist allerdings unklar, wieso es noch Datensätze (mit Inhalt) ohne Inventar-Nr. gibt. Diese Lücken sollte man natürlich schließen, entweder script-gesteuert oder manuell.

    Eine wie auch immer geartete Suchfunktion würde ich aber auf jeden Fall von der Nummernvergabe und vom Feld 'Inventar-Nr.' trennen. Wenn man ans Ende der Tabelle geht und dort in die freie Zeile klickt, dann erzeugt man halt jedesmal einen neuen, leeren Datensatz. Und zum Durchsuchen einer Tabelle gibt es ohnehin viel effektivere Möglichkeiten: Entweder in der Tabellenansicht über das darüber stehende Suchfeld oder im Datenformular über die Kombination eines oder auch mehrerer eigener Suchfelder mit dem Gestaltungselement "Ansicht".

    Konkretere Hinweise auf bestimmte Formeln, Funktionen oder Scripte lassen sich zu diesem Zeitpunkt schlecht geben, weil der Kontext unklar ist. Ich sehe aber zwei unterschiedliche Aufgabenstellungen, die erst mal gar nichts miteinander zu tun haben, und deshalb auch getrennt voneinander angegangen werden sollten:

    1.) Neuanlage eines Datensatzes mit Vergabe einer Inventar-Nr. (manuell oder automatisch).
    2.) Auffinden bestimmer Inventargegenstände anhand der Nr. (oder anderer Kriterien).

    Zum Löschen von Datensätzen lässt sich noch sagen: Wenn man das über den "Papierkorb" in der Symbolleiste über dem Formular macht, dann löscht Ninox diesen Datensatz, wenn man die Sicherheitsabfrage bestätigt. Eine Prüfung auf Inhalte ist dabei nicht möglich.

    Man kann das Löschen von Datensätzen aber auch über eine Schaltfläche realisieren und dort natürlich vorher bspw. auch prüfen, ob der betreffende Datensatz leer ist, entsprechende Meldungen generieren etc. pp. Auch da gibt es viele Möglichkeiten.

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Vielen Dank für die ausführliche Antwort!

     

    Stimmt, vermutlich sind es zwei getrennte Aufgaben…

     

    Wieso gibt es Einträge ohne Inventarnummer?

    Es gibt einen Datenbestand – eine Liste mit Gegenständen mit Kaufbetrag, Bezeichnung, etc. Jedes Gerät erhält eine eindeutige Nummer (einen Barcode), um es später leichter zu haben. Elektrogeräte brauchen diese Nummer ohnehin für die Prüfung.

    Aktuell sind die meisten Gegenstände erfasst, aber erhalten jetzt nach und nach eine Nummer – so, wie sie eben auftauchen bzw. über den Schreibtisch wandern.

    D.h. beim nachträglichen Erfassen der Inventernummer muss eigentlich nur geprüft werden, ob sie schon (aus irgendwelchen Gründen) vorhanden ist. Das kann ich ja mit einem Alert lösen – kein Problem eigentlich.

     

    Suche

    Jetzt wäre es natürlich toll, wenn es eine super einfache Suche gäbe. Die eingebaute Suche ist etwas "unkomfortabel" in der Handhabung. Der beste Weg für uns wäre ja, man gibt die Inventarnummer ein und drückt Enter (das macht der Barcode-Scanner von selbst).

    Jetzt müsste nur einfach nur direkt der Eintrag geöffnet werden.

     

    Leider fehlt mir als absoluter Neuling die Idee, wie ich das umsetzen könnte...

    Mit einer Ansicht, sagst Du? Aber wie? Es bräuchte ja ein Formular, das ein Skript mit openRecord ausführt. Kannst Du oder könnt ihr mir da eine Hilfestellung geben, an welcher Stelle oder wie das am einfachsten wäre?

    Braucht es dazu ein neues Feld (das geht ja immer mit einer neuen Spalte einher, oder?), das ich dann ins Formular einbinde? Aber dann wäre ja im Formular ein Feld Inventarnr. und eins namens Inventar-Suche oder wie? Das wäre natürlich irgendwie auch "unkomfortabel" – daher hatte ich ursprünglich die Idee, alles in eins zu packen. Aber das ist vielleicht auch ein Denkfehler.

     

    Hier käme natürlich jetzt noch der "Sonderfall" ins Spiel… Man scannt eine Nummer bzw. gibt sie ein und drückt Enter. Wenn sie jetzt nicht auffindbar wäre, könnte direkt eine neue Zeile angelegt werden. Denn dann hat der Gegenstand offensichtlich eine Inventarnummer (einen Barcode-Aufkleber), aber ist noch nicht erfasst.

     

    Ich hoffe, das ist verständlich :) Toll wäre, wie gesagt. Wenn immer eine Inventarnummer eingegeben wird, dass immer das richtige passiert ;)

     

    Lieben Dank und Grüße,

    Roland

    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hallo Roland, zum Suchen und Filtern: Mit dem Gestaltungselement "Ansicht" lassen sich die Daten einer Tabelle innerhalb eines Datenformulars anzeigen und auch filtern. Das lässt sich ganz einfach in wenigen Minuten ausprobieren:

    Neue Tabelle namens "Inventarsuche" (o. ä.) erstellen.
    Datenfeld vom Typ Text -> "Suche nach Nr" erstellen.
    Gestaltungslement hinzufügen: Ansicht.
    Button rechts unten "Änderungen am Datenmodell sichern".
    In die erste Zeile der neuen Tabelle klicken, so dass sich das Formular öffnet.
    Die Ansicht markieren und auf das Schraubenschlüsselsymbol klicken, so dass sich das Optionen-Fenster öffnet und bei "Funktion" folgenden Code eingeben:

    if 'Suche nach Nr' then
        let myNr := 'Suche nach Nr';
        select Inventarliste where 'Inventar-Nr.' = myNr
    else
        select Inventarliste
    end

    Das bedeutet: Wenn in das Feld "Suche nach Nr" etwas eingegeben wurde (manuell oder per Barcodescanner), dann zeige nur die Datensätze der Tabelle 'Inventarliste' (select ... where), welche dieser Inventar-Nummer entsprechen, ansonsten zeige alle Datensätze an (select ohne "where"). Auf dieselbe Weise ließe sich die Ansicht natürlichauch nach anderen Kriterien filtern, etwa nach dem Hersteller, Kaufdatum, Preis oder was auch immer man für sinnvoll erachtet.

    Außerdem könnte man bspw. eine Befehlsschaltfläche einbauen, mit der sich direkt von dort aus ein neuer Datensatz anlegen ließe. Der Code:

    let newId := create Inventarliste;
    openRecord(newId)

    Man könnte es auch so steuern, dass die Schaltfläche nur angezeigt wird, wenn eine nicht vorhandene Inventar-Nummer eingegeben wurde. Damit hätte man so eine Art Steuerzentrale zur Verwaltung der Inventargegenstände. Die man auch automatisch beim Öffnen der Datenbank anzeigen lassen könnte. Das aber nur als Beispiel. Der Möglichkeiten sind da viele.

    Auch in der Inventarliste selbst wäre noch vieles möglich. So könnten bspw. die Hersteller und Lieferanten in eigenen Tabellen gespeichert und mit dem Inventar verknüpft werden. Damit ließen sich Tipparbeit sowie Tippfehler reduzieren und spätere Auswertungen erleichtern. Für all solche Dinge ist Ninox perfekt geeignet.

    Das aber erst mal nur so als Anregungen. Es ist natürlich unmöglich, alle denkbaren Eventualitäten durchzuspielen. Bei weiteren, konkreten Fragen gerne wieder melden.

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Vielen Dank! Das hilft sehr, um auch mal die grundsätzliche Idee zu verstehen. Ich probiere das später mal aus :)

     

    Eine konkrete Frage gerade wegen dem letzten Punkt, den Du genannt hast, hatte ich hier noch gestellt: https://ninoxdb.de/de/forum/technische-hilfe-5ab8fe445fe2b42b7dd39ee8/auswahliste-untertabelle-5e21741d45dcf70528699980

    Da geht es um Untertabellen mit Lieferanten oder Herstellern. Kannst Du dazu noch einen Tipp geben?

     

    Viele Grüße,

    Roland

    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Siehe verlinkter Thread.

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Auch vielen Dank für die Antwort dort.

     

    Eine Nachfrage:

    Ich hab' die Tabelle zum Suchen angelegt und dann den Code nach Änderung im Suchfeld ausführen lassen.

    Leider passiert aber nichts nach Eingabe. Was sollte denn "select" machen?

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Also könnte man auch openRecord dazu nutzen? In der anderen Tabelle?

    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Ähm, jetzt bin ich etwas irritiert ... Der obige Codeblock mit "if 'Suche nach Nr' then ..." gehört in nicht in das Suchfeld, sondern in die Ansicht.

     

    Ein openRecord() könnte man prinzipiell nutzen, aber man kann den betreffenden Datensatz ja auch einfach in der Ansichts-Tabelle anklicken, was einem popupRecord() entspräche. Sofern ich die Frage richtig verstehe.

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Ohje... Zu schnell gelesen – sorry! Klar, so klappt es! :) Danke!

     

    Eine Nachfrage noch:

    Ich hab eine Schaltfläche erstellt, mit dem genannten Code oben. Unterschied nur, dass ich popupRecord(newId) genommen hab. Dann springt nichts hin und her.

    Wenn ich das Popup öffne (über die Schaltfläche) und nichts eintrage und per "X" wieder schließe wird natürlich trotzdem ein Datensatz erstellt. Kann man das noch verhindern? Natürlich kann man ja auch mal versehentlich auf den Button klicken.

    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Na ja, zunächst sollte man die Schaltfläche natürlich sinnvoll benennen, "Neuer Datensatz" oder so, damit klar ist, was passiert, wenn man darauf klickt. Um auf Nummer Sicher zu gehen, kann man mit dialog() aber noch eine Sicherheitsabfrage einbauen:

    let myAnswer := dialog("Bitte bestätigen", "Wollen Sie tatsächlich einen neuen, leeren Datensatz in der Inventarliste erzeugen?", ["Ja", "Nee, doch nicht"]);
    if myAnswer = "Ja"
        let newId := create Inventarliste;
        popupRecord(newId)
    end

    Für den Fall, dass dann auch die Sicherheitsabfrage versehentlich mit "Ja" bestätigt und unerwünscht ein neuer Datensatz angelegt wird, kann man diesen mit Klick auf den "Papierkorb" in der Symbolleiste löschen. Oder man baut auch dafür in das Formular der Tabelle 'Inventarliste' eine Schaltfläche namens "Datensatz löschen" oder so ein, natürlich mit Sicherheitsabfrage:

    let myAnswer := dialog("Bitte bestätigen", "Wollen Sie diesen Datensatz tatsächlich endgültig löschen?", ["Ja", "Nee, doch nicht"]);
    if myAnswer = "Ja"
        delete this
    end

    Grundsätzlich ist es auch nicht schlimm, wenn man in der Probierphase immer wieder mal neue, leere Datensätze erzeugt und sofort oder später wieder löscht. Man hat dann halt Lücken bei der internen, von Ninox automatisch vergebenen Datensatz-Nr, weil die Nummern gelöschter Datensätze nicht wieder belegt werden. Das ist aber völlig egal und hat keinerlei negative Auswirkungen auf die Performance oder so.

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Vielen, vielen Dank für die Hilfe!

     

    Noch eine Nachfrage:

    Wäre es möglich, beim Start von Ninox ein Script laufen zu lassen, das einfach alle Zeilen in Inventarliste löschen, die keinen Inhalt haben? Also bei denen in keinem einzigen Feld/keiner einzigen Spalte etwas eingetragen ist?

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Und gleich noch eine Frage:

     

    Kann ich in meiner Suchmaske auch eine "Freitextsuche" machen?

    Also neben der direkten Eingabe der Inventarnummer als Suche auch ein Feld, in das ich einen Begriff eingebe, nach dem dann in der Tabelle Inventarliste gesucht wird? Dabei müssten mehrere Spalten berücksichtigt werden: Beschreibung, Hersteller und Art z.B.

     

    Dann könnte die Such-Ansicht die Hauptansicht sein, das wäre sehr praktisch.

    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Hallo Roland, ich will dir nicht reinreden, aber das mit dem Löschen würde ich anders machen. Zum Beispiel über einen weiteren Button namens "Leere löschen" o. ä. im Suchformular. Mit dem könnte man zunächst die Anzahl betreffender Datensätze ermitteln und dann auch noch maleine Sicherheitsabfrage einblenden, bevor der Löschbefehl ausgeführt wird:

    let myCnt := cnt(select Inventarliste where 'Inventar-Nr.' = null and Bezeichnung = null);
    if myCnt > 0 then
        let myAnswer := dialog("Bitte bestätigen!", text(myCnt) + " leere Datensätze gefunden. Löschen?", ["Ja", "Nein"]);
        if myAnswer = "Ja" then
            delete (select Inventarliste where 'Inventar-Nr.' = null and Bezeichnung = null)
        end
    else
        alert("Keine leeren Datensätze gefunden!")
    end

    Wobei noch festzulegen wäre, wann ein Datensatz als "leer" gilt. Im Beispielcode oben frage ich dazu in der ersten Zeile die Felder 'Inventar-Nr' und 'Bezeichnung' ab, ob sie leer (= null) sind, aber das können natürlich auch mehr oder weniger bzw. andere Felder sein.

    Wenn man das Suchfeld leer lässt bzw. macht, dann werden in der Ansicht ja alle Inventargegenstände angezeigt. Mit einer entsprechende Sortierung über den jeweiligen Spaltentitel könnte man alle "leeren" Datensätze oben anzeigen lassen und ggf. auch noch mal überprüfen.

    • Ninox-Professional
    • planoxpro
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Ein weiteres "Freitext"-Suchfeld geht natürlich auch, klar. Dazu würde man ein weiteres Textfeld anlegen (bspw. 'Stichwortsuche'), in das der Suchbegriff eingegeben werden kann. Dann müsste man allerdings auch den Code der Ansicht anpassen, weil die ja von alleine nicht weiß, ob sie nach Nummer oder Stichwort suchen soll:

    if 'Suche nach Nr' then
        let myNr := 'Suche nach Nr';
        select Inventarliste where 'Inventar-Nr.' = myNr
    else
        if Stichwortsuche then
            let myTxt := lower(Stichwortsuche);
            select Inventarliste where contains(lower(Bezeichnung), myTxt) or contains(lower(Hersteller), myTxt) or contains(lower(Art), myTxt)
        else
            select Inventarliste
        end
    end

    In diesem Beispiel durchsuche ich die Felder 'Bezeichnung', 'Hersteller' und 'Art' nach dem eingegeben Suchbegrff. Die lower()-Funktion bewirkt lediglich, dass auf beiden Seiten alle Groß- in Kleinbuchstaben umgewandelt werden, damit es nicht an einem Tippfehler oder so scheitert. Das contains() bedeutet soviel wie "beinhaltet". Man durchsucht also das angegebene Feld komplett nach diesem String, so dass bspw. bei Eingabe von "corder" auch "Camcorder" gefunden würde.

    Zusätzlich würde ich über einen Trigger "Nach Änderung" auch noch das jeweils andere Suchfeld leeren. Also im Feld 'Suche nach Nr':

    if 'Suche nach Nr' != null then
        Stichwortsuche := null
    end

    Und im Feld 'Stichwortsuche' halt umgekehrt:

    if Stichwortsuche != null then
        'Suche nach Nr' := null
    end

     

    Ich hoffe, dass sich kein Fehler in die Code-Zeilen geschlichen hat, garantieren kann ich das aber nicht. Insofern: Alle Angaben ohne Gewähr, Betreten auf eigene Gefahr, Eltern haften für ihre Kinder usw. ;)

    • blickgerecht GbR
    • Roland_Stichler
    • vor 4 Jahren
    • Gemeldet - anzeigen

    Vielen Dank für die Top-Hilfe! Funktioniert alles wunderbar!

     

    Grüße,

    Roland

Content aside

  • vor 4 JahrenZuletzt aktiv
  • 15Antworten
  • 3834Ansichten