Erarbeitung eines "POS-Kassenbuchs"

Diskussionen zu Projekten

Moderator: Moderatoren

Forumsregeln
Dieses Unterforum versteht sich als Plattform zur Diskussion/Bearbeitung komplexerer Anfragen bzw. konkret verabredeter Projekte. Das können Dinge sein wie eine komplexere Calc-Datei oder auch die gemeinsame Programmierung eines größeren Makros, wichtig ist immer die Absicht ein Thema über längere Zeit (z.B. 3 Monate) fortlaufend zu besprechen.
Benutzeravatar
balu
********
Beiträge: 3483
Registriert: Do, 23.08.2007 23:28
Wohnort: Warstein

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon balu » Sa, 07.01.2017 19:01

Hallo Julia,

Wie - weder Kopf- noch Bauchschmerzen?! Du brauchst dringend ein Laster! :P

Ich bin ein Laster :lol:


Aufgrund deines Hinweises vor einiger Zeit, besser die SVERWEISE im Makro berechnen zu lassen, fliegen jetzt alle Formeln aus dem Tabellenblatt.

SPIELVERDERBERIN! Nimmst mir einfach die Arbeit ab.;-)
Aber auf deine Lösung bin ich trotzdem mal sehr gespannt, da ich nicht weiß welche Technik Du da angewendet hast.


Ein anderer Hintergrund ist die Tatsache, dass die Berechnungsformeln in der Tabelle das System verlangsamen, zumal wir auf einem Raspberry arbeiten.

Da die Datei ja je nach Monat ca. 30 Blätter enthalten wird, fallen ein oder 2 Formeln nicht so ins Gewicht. Aber je mehr Formeln pro Blatt, und das mal 30, sieht die Sache schon ganz anders aus. Das spürt man selbst auf einem ausgewachsenen PC mit 4*3GHz, so wie meiner.
Ich weiß wovon ich da Rede, nämlich aus Erfahrung mit meinem damaligem Projekt.


Ich fürchte, du wirst das Kassenbuch nicht wiedererkennen.

Egal! Hauptsache ich bekomme auch noch was zu tun :-D



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Benutzeravatar
Julia NuN
**
Beiträge: 33
Registriert: Mo, 07.11.2016 14:57

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon Julia NuN » So, 08.01.2017 01:26

Hallo balu,
Aufgrund deines Hinweises vor einiger Zeit, besser die SVERWEISE im Makro berechnen zu lassen, fliegen jetzt alle Formeln aus dem Tabellenblatt.


SPIELVERDERBERIN! Nimmst mir einfach die Arbeit ab.;-)
Aber auf deine Lösung bin ich trotzdem mal sehr gespannt, da ich nicht weiß welche Technik Du da angewendet hast

Technik?! Öhm...
Keine Bange - ich glaub', du wirst dich über einen Mangel an Arbeit nicht beklagen können. :D

Gute Nacht!
Wilhelm Busch: "Ein jeder Wunsch, wenn er erfüllt, kriegt augenblicklich Junge."
... ich glaub, der wär heutzutage Programmierer und nicht Schriftsteller.

Benutzeravatar
Julia NuN
**
Beiträge: 33
Registriert: Mo, 07.11.2016 14:57

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon Julia NuN » So, 08.01.2017 15:12

Hey balu,

hier mein Upload.
Folgendes ist neu hinzugekommen:

1. Mitarbeiter-Arbeitsstunden
Wir notieren die Mitarbeiter-Arbeitsstunden jetzt auch im POS-Kassenbuch (Blatt „Stunden“).
Daher wurden noch die Namen, der Stundenlohn und eine Liste mit den aktuellen Datumsangaben für den Monat hinterlegt, siehe Punkt 2.

Um die Stunden-Eingaben nach Datum zu sortieren, wurde ein Sortierbutton eingefügt. Das Makro habe ich mit dem Makrorekorder erstellt (neues Modul „Datum_sortieren“).

2. „Preise“ umbenannt in „Stamm“
Die Daten für Punkt 1 (Namen, Stundenlohn, Datum s.o.) befinden sich jetzt alle auch im ehemaligen Blatt „Preise“, das umbenannt wurde zu „Stamm“. Hinzugekommen sind auch die Daten einer Ansprechperson mit Telefonnummer für die MsgBox im Modul "Flaschenverkauf" und die veränderbaren Daten für das Modul „Kiste_Astra“.

Die Referenzierung zu dem Blatt heißt jetzt gemäß deines Vorschlags wie folgt:

Code: Alles auswählen

oBlattStamm = thisComponent.Sheets.GetByName("Stamm")

3. Kopfbereich Blatt „1“
Um sinnvollere Auswertungsdaten zu erhalten, wurde der Kopfbereich geändert.
Insbesondere werden jetzt die Mindereinnahmen einzeln aufgelistet. Mindereinnahmen sind fehlende Einnahmen durch Vergabe von Rabatten (kostenfreie Abgabe/Schwund = Rabatt 100%).

4. Mitarbeiter-Getränke Blatt „1“
Mitarbeiter müssen jetzt nach Eingabe eines Artikels mit Mitarbeiter-Rabatt (50%) ihren Namen auswählen. Dieses Drop-Down-Menü holt seine Daten aus „Stamm“ um immer aktuell zu bleiben.
Sinn der Sache ist, dass die Mitarbeiter sich jetzt ihre persönlichen Getränkekosten rechts im Blatt anzeigen lassen können.

Frage:
Ich habe versucht, so viel wie möglich in der Sub „Dlg_neuer_Artikel“ vorzudefinieren.
Und manchmal erklärt es sich mir nicht, wieso es dann nicht funktioniert.
Z.B. greife ich im Modul „Flaschenverkauf“ in der MsgBox unten auf Daten zu, deren Werte in der Sub „Dlg_neuer_Artikel“ definiert wurden. Das klappt.

Aber wenn ich Ähnliches im Modul „Kiste_Astra“ versuche, geht das nicht. Vielleicht, weil mit den Werten dort gerechnet werden soll?

Modul „Kiste_Astra“
Ich wollte eigentlich die zwei möglichen Preise (30€/35€) für den Verkauf einer Kiste Astra ebenfalls im Stammblatt hinterlegen.
Aber ich hab mir scheinbar durch die Anwendung von .SelectedItemPos selbst ein Bein gestellt. Das müsste man sonst wohl nochmal ganz anders machen.

Modul „Flaschenverkauf“:
Hier ist jetzt doch noch eine Formel drin – ich habe es nicht hinbekommen, die zu ersetzen. Das ist allerdings auch nicht notwendig, das wird nicht so oft benutzt.
Das ist übrigens ein Modul, durch das ich selbst noch nicht recht durchsteige. Ich schätze mal, da geht noch ganz gut was zu verbessern. ;)

Sonstiges:

Code: Alles auswählen

    iArtikelnummer_Art = oArtikelnummer_Artikel.Value()
' Die folgenden 2 Zeilen kannst Du löschen.'
'    sgAnzahl_Art = oAnzahl_Artikel.Value()'
'    sgRabatt_Art = oRabatt_Artikel.Value()'
   
    mySheet.getCellRangeByName("A" & iEnd_Row).Value = iID + 1
    mySheet.getCellRangeByName("B" & iEnd_Row).Formula = oFormulaText_Art
    mySheet.getCellRangeByName("D" & iEnd_Row).Value = iArtikelnummer_Art
    mySheet.getCellRangeByName("E" & iEnd_Row).Value = oAnzahl_Artikel.Value()' jetzt neu'
    mySheet.getCellRangeByName("F" & iEnd_Row).Formula = oFormulaEinnahme_Art
    mySheet.getCellRangeByName("G" & iEnd_Row).Formula = oFormulaEPRabatt_Art
    mySheet.getCellRangeByName("I" & iEnd_Row).Value = oRabatt_Artikel.Value()' jetzt neu'
    mySheet.getCellRangeByName("J" & iEnd_Row).Formula = oFormulaRabattArt_Art
    mySheet.getCellRangeByName("K" & iEnd_Row).Formula = oFormulaMindEinnahme_Art

Ich habe das so gut es ging versucht umzusetzen. Weil ich jetzt aber wegen des Wegfalls der Formeln mit fast allen dieser Feldwerte rechnen musste, um wiederum die anderen Werte zu erhalten, musste ich dann doch wieder so neudefinieren. Hhm... :?
Kann man eigentlich, wenn man "sgRabatt_Art = oRabatt_Artikel.Value()" in Klammern setzt, auch damit rechnen? Fällt mir grad spontan ein - hab's nicht ausprobiert.

Und dann habe ich noch versucht, das hier umzuschreiben:

Code: Alles auswählen

   
   oAktuellesBlatt = thiscomponent.getcurrentcontroller.activesheet
   oCellCursor = oAktuellesBlatt.createCursor()
   oCellCursor.GotoEndOfUsedArea(True)

Mit meiner Kreation

Code: Alles auswählen

   oAktuellesBlatt = thiscomponent.getcurrentcontroller.activesheet.createCursor().GotoEndOfUsedArea(True)
war ich aber nicht erfolgreich.

Liebe Grüße Julia
Dateianhänge
POS_Kassenbuch_Forum_5.ods
(61.43 KiB) 5-mal heruntergeladen
Wilhelm Busch: "Ein jeder Wunsch, wenn er erfüllt, kriegt augenblicklich Junge."
... ich glaub, der wär heutzutage Programmierer und nicht Schriftsteller.

Benutzeravatar
Julia NuN
**
Beiträge: 33
Registriert: Mo, 07.11.2016 14:57

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon Julia NuN » So, 08.01.2017 16:37

Achja (seufz), sobald ich was hochlade, finde ich auch schon wieder Fehler…:

Der String sZelleFonChef ist nicht richtig deklariert, daher wird in der obigen Datei noch nicht die Telefonnumer in der MsgBox im Modul „Flaschenverkauf“ angezeigt.

Wenn das SO ist, kann ich gleich noch was schreiben, was ich vergessen hatte.
In selbiger MsgBox gibt es ja auch den errechneten Rabatt. Diesen wollte ich mit FORMAT auf 2 Nachkommastellen formatieren:

Code: Alles auswählen

sgRabatt_Fl = Format(100 - (EPRabatt_Fl * 100 / sgListenpreis_Fl), "##,##0.00")

Das hat auch geklappt. Dann hat er (ist "es" eigentlich eine "sie" oder ein "er"?) aber in der Tabelle einen auf eine ganze Zahl gerundeten Wert eingetragen --> aus "56,5217399597168" wurde "56". Das hab ich nicht verstanden und wieder herausgenommen, weil ich mir nicht sicher war, ob das so vom Wirt gewünst ist.
Ansonsten ist das mit der FORMAT-Funktion aber klasse. Ich nehm an, wir nehmen das auch wieder mit rein.

nimm mal das hier.

Code: Alles auswählen

sFormulaText_Art = "=SVERWEIS(D" & iEnd_Row & ";Preisliste;2;0)"
[...]
mySheet.getCellRangeByName("B" & iEnd_Row).FormulaLocal = SFormulaText_Art


Das war natürlich ein Super-Tipp! Nachdem ich allerdings die Formeln bis auf eine rausgeworfen hatte, habe ich das bei der dann auch vergessen zu ändern. :oops: :mrgreen:

LG Julia
Wilhelm Busch: "Ein jeder Wunsch, wenn er erfüllt, kriegt augenblicklich Junge."
... ich glaub, der wär heutzutage Programmierer und nicht Schriftsteller.

Benutzeravatar
balu
********
Beiträge: 3483
Registriert: Do, 23.08.2007 23:28
Wohnort: Warstein

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon balu » So, 08.01.2017 18:39

Hallo Julia,

ohne die Datei zu sehen, ich muss gleich raus wegen Winterdienst (Straße räumen und streuen... brrr-nasskalt-brrrr :? ), muss ich sagen das Du wohl recht fleißig warst. Und nicht nur der Fleiß ist anerkennenswert, sondern auch die Überlegungen die Du angestellt und umgesetzt hast. Respekt. :-)

Das natürlich noch einige Stolpersteine zu meistern sind, bleibt nicht aus. Das werden wir aber noch alles irgendwie hinbekommen.


ist "es" eigentlich eine "sie" oder ein "er"?

:lol:
Echt klasse das mal ein "Anfänger" sich darüber Gedanken macht.
Ist aber auch nicht ganz so einfach.
- das Tabellenkalkulationsprogramm (Excel, Calc...)
- das Makro
- der Code (vom Makro)
- der Rechner (PC)
- die Formel
Und je nach Problematik kann man dann sagen
- der Code macht nicht was er soll
- die Formel hat ne macke
- ich schmeiß den Rechensklave ausm Fenster
Also pauschalisieren fällt mir auch schwer, deshalb nehme ich das was zur Problematik passt, denn es ist kein Biologisches Lebewesen. ;-).

Ich meld mich wieder wenn ich Zeit hatte und habe.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Benutzeravatar
balu
********
Beiträge: 3483
Registriert: Do, 23.08.2007 23:28
Wohnort: Warstein

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon balu » So, 08.01.2017 22:44

So, jetzt hatte ich mir etwas Zeit gönnen können.

Dann hat er [...] aber in der Tabelle einen auf eine ganze Zahl gerundeten Wert eingetragen --> aus "56,5217399597168" wurde "56". Das hab ich nicht verstanden und wieder herausgenommen

Tja, da gibt es einige Regeln zu beachten, wenn man per Makro ausgerechnete Werte in ein Tabellenblatt eintragen will.

1.
Im Makro schon eine Art "Vor-Formatierung" vornehmen

2.
Eintragen

3.
Formatieren

Hört sich einfacher an als es in wirklichkeit ist.
Punkt 1 braucht man nicht immer, aber durchaus öfters.
Handelt es sich um eine Ganzzahl, also ohne Nachkommastellen, dann braucht man da eigentlich nicht viel machen. Mal ein theoretische Grundlagenbeispiel.

Code: Alles auswählen


oBlattStamm
.getCellRangeByName("B99").value = sgEP_Korr.value

Und fertig.
Komme gleich nochmal darauf zurück.

Punkt 2 habe ich ja schon grad eben mit dem Grundbeispiel gezeigt.

Punkt 3 kann durchaus seeehr kompliztierter werden.
Will man eine Ganzzahl eintragen, so braucht man eigentlich nix mehr weiter zu machen. Man muss lediglich drauf achten das man sich bei der Zuordnung nicht vertut, also nicht die Zelle als String vorbereiten und dann einen echten Wert eintragen, denn das ergibt dann nämlich einen String. Gemeint ist folgendes Verbot.

Code: Alles auswählen


oBlattStamm
.getCellRangeByName("B99").string = sgEP_Korr.value

Anders sieht es aber aus, wenn man Beispielsweise die aktuelle Uhrzeit eintragen will. Denn dann muss vom Makro nach dem eintragen in die Zelle gleich noch eine weitere Aktion durchgeführt werden. Und diese Aktion heißt:

Die Tabellenzelle mit dem richtigen Zahlenformat formatieren.

Und das ist vom Prinzip her nix anderes, als wenn Du von Hand die Zelle z.B. auf Format Uhrzeit: "HH:MM" formatierst. Im Makro ist das aber etwas komplizierter, da man das Format anders einstellt. Hier ein Beispiel.

Code: Alles auswählen


Sub Main
oBlattNo1 
= ThisComponent.Sheets.GetByName("Tabelle1")
oBlattNo1.getCellRangeByName("A1:D1").clearContents(255)
oBlattNo1.getCellRangeByName("A1").FormulaLocal =  NOW

oBlattNo1
.getCellRangeByName("B1").FormulaLocal =  TimeValue(NOW)

oBlattNo1.getCellRangeByName("C1").FormulaLocal =  NOW
oBlattNo1
.getCellRangeByName("C1").Numberformat = 40

oBlattNo1
.getCellRangeByName("D1").FormulaLocal =  TimeValue(NOW)
oBlattNo1.getCellRangeByName("D1").Numberformat = 40
End Sub

Nimm eine neue und leere Datei, und starte dies Makro.

Und so ganz nebenbei kommt jetzt auch der Punkt 1 zum tragen. Denn es findet eine "Vor-Formatierung" statt, und zwar durch TimeValue. Und die Zellformatierung wird durch Numberformat = 40 vorgenommen.

Nimm dir ruhig einen Moment Zeit dafür, und schau nicht nur was in der Zelle angezeigt wird, sondern auch oben in der Eingabezeile.



Zelle A1 ist fast identisch zur Eingabezeile.
Zelle B1 ist identisch zur Eingabezeile.
Zelle C1 & D1 sind nicht mehr identisch zur Eingabezeile.

Mit den Zellen C1 & D1 würde ich jetzt so nicht weiterrechnen wollen, wenn man sich nur auf das Aussehen der Zelle beschränkt. Denn es wird etwas anderes angezeigt, als das was wirklich in der Zelle steht. Und das kann sehr schnell zu bösen Problemen führen. Also muss eine andere Lösung daher. Und die kommt jetzt.

Code: Alles auswählen


Sub Mimi
CompatibilityMode
(True)
oBlattNo1 = ThisComponent.Sheets.GetByName("Tabelle1")
oBlattNo1.getCellRangeByName("C4:D4").clearContents(255)
oBlattNo1.getCellRangeByName("C4").FormulaLocal =  FormatDateTime(TimeValue(NOW), 4)

oBlattNo1.getCellRangeByName("D4").FormulaLocal =  FormatDateTime(TimeValue(NOW), 4)
oBlattNo1.getCellRangeByName("D4").Numberformat = 40
CompatibilityMode
(FALSE)
End Sub

Führe dieses Makro ruhig in der gleichen Datei aus. Ich habe dafür extra andere Zellen genommen damit Du dir die Unterschiede zum ersten Code in Ruhe anschauen und vergleichen kannst.

Es sind jetzt wohl "nur" 2 Dinge dazu gekommen, aber die haben es in sich.
Als erstes wird ein "Kompatibilitäts Modus" aktiviert -{CompatibilityMode}- - (und später wieder deaktiviert), und zweitens können wir dadurch, und zwar nur dadurch, auf eine zusätzliche Funktion drauf zugreifen. Und diese Funktion lautet: FormatDateTime.

Jetzt schlägt die "Vor-Formatierung" aber auch so richtig zu. Denn durch die 4 in FormatDateTime wird gesagt, stelle auf "Stunden und Minuten(hh:mm, Stunden im 24-Stunden-Format)" ein. Nachzulesen in "Andrew Pitonyak", das Buch findest Du hier: http://www.uni-due.de/~abi070/ooo.html
Das ist wirklich eine sehr wichtige Lektüre.

Es gibt aber auch noch eine sehr gute und emfehlenswerte Seite, und das ist Dannenhöfer. Bei dem ist auch dieses Thema vom grundsätzlichen eigentlich schon ganz gut beschrieben. Schau dir mal folgende Links an.
7.1.22 Wie kann man das Zahlenformat auf Standardformate einstellen?
7.1.26 Wie kann man das Zellenformat einstellen?

Besonders der Punkt (7.1.26) ist dir dabei behiflich ein "Zellenformat-Kode" auszulesen, da dort ein kleines aber effektives Hilfsmakro vorhanden ist. Dazu musst Du erstmal eine Zelle selber von Hand Formatieren, also über ->rechtsklick ->Zellen formatieren ..., na den Weg kennst Du ja wohl ;-). Anschließend führst Du das Hilfsmakro von dort aus, und schon bekommst Du die Formatnummer die Du dann weiter verwenden kannst.

Klar hätte ich sofort auf die beiden genannten (Pitonyak, Dannenhöfer) verweisen können, aber so hast Du schon mal etwas womit Du das von mir gesagte ausprobieren kannst, und außerdem gleichzeitig einen sehr schweren Broken von den Füßen. Ich habe jetzt hier wohl nur von der Uhrzeit gesprochen, aber beim Thema Datum verhält es sich nicht wesentlich anders, bis auf folgende kleinigkeiten.

Code: Alles auswählen


FormatDateTime
(DateValue(NOW), 2)

Und Numberformat kann entfallen, wenn das Datum beispielsweise so aussehen soll 06.01.17. Damit müsstest Du jetzt eigentlich gut gerüstet sein um Zellen selber per Makro zu formatieren.


Anderes Thema.

Ich glaube das ich jetzt verstanden habe wie Du die SVERWEIS im Makro ersetzt hast. Einfach dadurch das Du durch die Zeilen suchst, und bei einem Treffer dann dementsprechend reagierst. Das ganze mit einer einfachen For...Next.

Ist wohl soweit in Ordnung. Jedoch in deiner jetzigen Testdatei mit mal grad eben 11 Testzeilen spürst Du noch nicht was passiert wenn wirklich 500 Zeilen durchsucht werden müssen. Denn dann macht die Uhr *tick-tack-tick-tack-tick-tack-tick-tack-*

Ich hatte mich schon mal so zwischendurch mit diesem Thema selber befasst, da ich in dieser Art noch keine richtige Erfahrung gesammelt habe, und ich habe da auch eine Lösung für mich gefunden. Ich sage nur eins: Array. Und das ist eine ganz andere Hausnummer. Aber heute gehe ich nicht weiter darauf ein, das kommt später.


Ich sehe Du hast hier im Forum etwas gefunden, was sehr nützlich ist.

Code: Alles auswählen

   aSourceDataArray() = oZellenMitarbeiter.getDataArray()
   Dim aSource(UBound(aSourceDataArray())) as String 
   For j = LBound(aSource()) To UBound(aSource())
      aDataArrayRow() = aSourceDataArray(j)
   aSource(j) = aDataArrayRow(0)

Find ich echt klasse wie Du doch so aktiv bist. :mrgreen:
Jedoch
Aber ich hab mir scheinbar durch die Anwendung von .SelectedItemPos selbst ein Bein gestellt.

wird das auch erst später besprochen.


Keine Bange - ich glaub', du wirst dich über einen Mangel an Arbeit nicht beklagen können. :D

Oh jeh! Wie recht Du hast. Da gibts noch so einiges an Arbeit ;-)

Aber, nach einem "Smal-Talk" und einem ausgewachsenen Beitrag von mir, mach ich hier jetzt schluß, und stelle gleich meinen teilweise vorbereiteten Beitrag hier rein. Das wäre dann der dritte in Folge. Dadurch habe ich dann wieder etwas Zeit mich deiner jetzigen unbehandelten Probleme zu befassen, während Du meine Beiträge Abarbeitest.
Och-Mennoooo! Ich brauch doch mal wieder einen kleinen Vorsprung :-)


Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Benutzeravatar
balu
********
Beiträge: 3483
Registriert: Do, 23.08.2007 23:28
Wohnort: Warstein

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon balu » So, 08.01.2017 23:07

So, und nun zum letzten Beitrag für heute.

Auch wenn es dir jetzt vielleicht ein wenig unsinnig, verwirrend oder blöde vorkommt, so verfolge ich doch durchaus ganz bestimmte Ziele mit dem was jetzt kommt.

Ein Ziel ist es, dir so nebenbei Step-by-Step einiges beizubringen was Du noch öfters anwenden kannst. Mir geht es hier dabei auch nicht darum das ich dir jetzt schon Fix und Fertig zeige wie die Dialoge und der dazugehörige Makro-Code komplett überarbeitet aussehen könnten, denn dann könnten wir das Projekt innerhalb weniger Tage abschließen, sondern vielmehr darum zu zeigen wie man aus dem schon vorhandenen etwas ausbauen und verändern kann. Und deshalb sage ich jetzt auch nichts zu den anderen Zielen die ich verfolge. ;-)


Wir nehmen uns jetzt etwas vor, was auf den ersten Blick als "nicht so wichtig" eingestuft werden kann, aber ein gewisser Grundstein für was anderes dient was noch kommen wird, und ferner als ein Lernziel dient.

Als erstes legst Du ein neues Basic Modul an, mit dem Namen:

Text_Mitteilungen

In diesem Modul benennst Du die

Code: Alles auswählen

Sub Main

In das hier um.

Code: Alles auswählen


Sub PoaFaw

Nicht wegen den Namen wundern, Erklärung folgt gleich noch.
Doch nun ein wechsel zum:

Modul: Flaschenverkauf

Du arbeitest ja generell mit der MsgBox, wenn die Datei auf etwas reagieren soll. Das kenne ich selber, und das habe ich früher auch mal so gemacht. Habe das aber mittlerweile aufgegeben und ein anderes System dafür genommen. Doch so weit wollen wir jetzt bei dir noch nicht gehen, aber dennoch uns der MsgBox annehmen.

In diesem besagten Modul hast Du mehrere MessageBoxen.
Fangen wir mit der 1. an, und zwar diese.

Code: Alles auswählen

' Prüfen, ob alle Felder ausgefüllt wurden      
    If iArtikelnummer_Fl = 0 Or iAnzahl_Fl = 0 Or sgFuellmenge_Fl = 0 Or sgPreis_Fl = 0 Then
   antwort = MsgBox("Du hast nicht alle Felder ausgefüllt.",0," ;-)")
   If antwort = 1 Then exit sub
   Endif

Der Sub Name PoaFaw in dem vorhin angelegten neuen Modul beruht auf die Anfangsbuchstaben in deinem Kommentar, aber ohne Satzzeichen.

PoaFaw = Prüfen ob alle Felder ausgefüllt wurden

Er hat so gesehen momentan einen Wiedererkennungswert wegen Orientierungsmöglichkeit.

Benenne jetzt antwort in iPoaFaw_Antwort um.
Der geänderte Code-Ausschnitt müsste jetzt wie folgt aussehen.

Code: Alles auswählen

' Prüfen, ob alle Felder ausgefüllt wurden'
    If iArtikelnummer_Fl = 0 Or iAnzahl_Fl = 0 Or sgFuellmenge_Fl = 0 Or sgPreis_Fl = 0 Then
    iPoaFaw_Antwort 
= MsgBox("Du hast nicht alle Felder ausgefüllt.",0," ;-)")
    If iPoaFaw_Antwort = 1 Then exit sub
    Endif

Und aus diesem Ausschnitt kopierst Du folgende Zeile in die Zwischenablage.

Code: Alles auswählen


    iPoaFaw_Antwort 
= MsgBox("Du hast nicht alle Felder ausgefüllt.",0," ;-)")
 

Und diese Zeile fügst Du nun, - na wohin wohl? - ....... in das Modul Text_Mitteilungen in die

Code: Alles auswählen


Sub PoaFaw

ein.
Dadurch müsste jetzt die dortige Sub wie folgt aussehen.

Code: Alles auswählen


Sub PoaFaw
    iPoaFaw_Antwort 
= MsgBox("Du hast nicht alle Felder ausgefüllt.",0," ;-)")
end Sub


Okay, noch mal zurück in das Modul Flaschenverkauf.
Dort wird die eben kopierte Zeile wie folgt geändert.

Code: Alles auswählen

' Prüfen, ob alle Felder ausgefüllt wurden'
    If iArtikelnummer_Fl = 0 Or iAnzahl_Fl = 0 Or sgFuellmenge_Fl = 0 Or sgPreis_Fl = 0 Then
        PoaFaw
    If iPoaFaw_Antwort 
= 1 Then exit sub
    Endif


Wie Du jetzt siehst, hat sich die Anzahl der Zeilen nicht geändert, aber eine Zeile sieht jetzt doch ganz anders aus. Vorher stand da ein etwas längerer "Text", und jetzt nur noch ein "Wort".

Nun, dir ist sicherlich aufgefallen, das das einzelne "Wort" der Name der einen Sub entspricht. Und das soll auch so sein, und das ist auch richtig so.
Denn wenn der Sub-Name so alleine in einer Zeile steht, wird dadurch diese Sub automatisch vom Programm aufgerufen und ausgeführt.

Prinzipiell könntest du jetzt einwänden:

"Wegen einer einzigen Code-Zeile so einen Aufwand?"

Theoretisch hättest Du ja auch recht. Aber das ist ja jetzt nur eine MsgBox mit nur einer Zeile, während ja noch mehrere MsgBoxen mit mehreren Code-Zeilen folgen. Und außerdem ist das jetzt das erste Lernziel:

Wie ruft man auf einfache Art eine andere Sub auf?

Aber damit diese Änderungen und Ergänzungen auch funktionieren, muss noch eine Kleinigkeit gemacht werden. Und dazu gehts ab ins Modul Artikel.
Dort ergänzt Du jetzt die Variablen deklarationen, und zwar um folgendes.

Code: Alles auswählen

' Temporäres'
Dim iPoaFaw_Antwort as Integer


Jetzt speicherst du die geänderte Datei ausm Basic-Editor heraus, nicht aus Calc heraus. Schließt sie, und öffnest sie erneut. Und nur zur Sicherheit kontrollierst Du ob auch die Änderungen gespeichert wurden. Ich empfehle diese Vorgehensweise, weil dadurch sichergestellt werden kann das nicht irgendwelche Variablen sich noch im Arbeitsspeicher befinden, die das Makro durcheinander bringen können.

Danach startest Du den Dialog wie gehabt, gehst auf "Verkauf ganzer Flaschen" und dort klickst Du auf "Übernehmen", ohne irgendein Feld auszufüllen. Daraufhin müsste die dir wohl bekannte MsgBox mitsamt ihrem Text erscheinen.

Und das ist der Beweis das durch den Aufruf des Sub-Namen die dementsprechende Sub nicht nur aufgerufen, sondern auch ausgeführt wird. Es wird jetzt so gesehen wohl nur eine einzige ausgelagerte Zeile abgearbeitet, aber das ist der erste kleine Schritt in Richtung Umfangreichere Sub aufrufe, was sehr viel später noch kommen wird.

In den Dialogen rufst Du ja auch per "Knopfdruck" die eine oder andere Sub auf. Das ist hier im wesentlichen nix anderes, blos das der Auslöser für den Sub-Aufruf etwas anders ist, im Dialog per Knopf, hier per Code.


Und jetzt drückst Du den *großen-imaginären-geistigen-Pause-Button*, und gönnst dir erstmal eine solche.


Wenn Du dich wieder erholt hast, dann gehst Du daher und lagerst ALLE MsgBoxen wie eben gezeigt in das Modul Text_Mitteilungen aus. Achte aber darauf das jede MsgBox ihr eigene Sub bekommt. Und überprüfe auch ob jede MsgBox nach der Auslagerung noch genau so funktioniert wie von dir gedacht und geplant ist.

So! Das wars für heute.
Viel spaß beim "Abarbeiten" :lol:



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Benutzeravatar
Julia NuN
**
Beiträge: 33
Registriert: Mo, 07.11.2016 14:57

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon Julia NuN » Mo, 09.01.2017 01:01

Wow! Cool! :D
Daaankee!

Das mit dem Auslagern hat's mir besonders angetan.
Ich hab so'n Gefühl, dass man da noch viel mehr auslagern kann.
Aber ich werde mich beherrschen und auf deine Eingaben warten, sonst kommen wir hier noch völlig durcheinander.

Jetzt kann ich mir auch Zeit lassen, die Alpha-Version läuft ja schon. :)

Mit der Verschnaufpause hast du Recht - bei mir ist so einiges anderes liegen geblieben.
Da muss ich morgen auch ran, sonst fliegt mir das um die Ohren... :roll:

CU und Guts Nächte
Julia
Wilhelm Busch: "Ein jeder Wunsch, wenn er erfüllt, kriegt augenblicklich Junge."
... ich glaub, der wär heutzutage Programmierer und nicht Schriftsteller.

Benutzeravatar
balu
********
Beiträge: 3483
Registriert: Do, 23.08.2007 23:28
Wohnort: Warstein

Re: Erarbeitung eines "POS-Kassenbuchs"

Beitragvon balu » Mo, 09.01.2017 22:22

Hallo Julia,

Wow! Cool!
Daaankee!

Gern geschehen :D


Das mit dem Auslagern hat's mir besonders angetan.
Ich hab so'n Gefühl, dass man da noch viel mehr auslagern kann.

Och jo! Da gibt es noch das eine oder andere ;-)

Also denn! Es gibt viel zu tun. Packen wir es an.


Bitte gewöhne dir bei "For ... next" (Kurz: Schleife) folgendes an.

Code: Alles auswählen


For i 
= 1 to 10
    
[tu irgendetwas]
next i

Denn Du schreibst das next bisher immer ohne den "Zähler". Und das kann unter Umständen durchaus mal zu Problemen führen, wenn mehrere Schleifen ineinander verschachtelt sind. Und beim durchlesen eines Codes kannst Du dann selber ins Stolpern geraten, wenn Du nicht wirklich nachvolziehen kannst welche Schleife abgearbeitet wurde und welche nicht.

Ferner empfehle ich dir auch aus Sicherheitsgründen dabei nicht immer den gleichen Zähler zu benutzen. Also nicht immer nur next i, sondern auch andere Buchstaben, Buchstabenkombinationen oder auch Wörter.

Code: Alles auswählen


For r2d2 
= 0 to 5
    
[tu irgendetwas]
next r2d2

Code: Alles auswählen


For KistenIndex 
= 0 to 5
    
[tu irgendetwas]
next KistenIndex 

Das sind Erfahrungswerte die sich wirklich lohnen zu merken.


Thema: Fehleranalyse

Frage:
Ich habe versucht, so viel wie möglich in der Sub „Dlg_neuer_Artikel“ vorzudefinieren.
Und manchmal erklärt es sich mir nicht, wieso es dann nicht funktioniert.
Z.B. greife ich im Modul „Flaschenverkauf“ in der MsgBox unten auf Daten zu, deren Werte in der Sub „Dlg_neuer_Artikel“ definiert wurden. Das klappt.

Aber wenn ich Ähnliches im Modul „Kiste_Astra“ versuche, geht das nicht. Vielleicht, weil mit den Werten dort gerechnet werden soll?

Und so was auf nüchteren Magen :-)

Also ich musste auch erstmal nach sofort auffälligen Fehlern suchen, hatte aber auf den ersten Blick nix gefunden.

Dann bin ich daher gegangen und habe den von dir markierten Code-Abschnitt in die "Sub Dlg_neuer_Artikel" kopiert, und in der Problem Sub alles geREMt. Dann den dementsprechenden Dialog gestartet, Testwerte eingegeben und ausgewählt. Es erschien eine Fehlermeldung. Diese konnte ich aber nicht wirkklich nachvollziehen. Also eine Händische Fehlersuche durchgeführt.

Und bei der Fehlersuche ist mir aufgefallen, das Du eine kleinigkeit vergessen hast. Kann vorkommen, kenne das selber. Der Fehler ist nämlich, das Du wohl richtig definiert hast

Code: Alles auswählen


iNrAstra_Ki 
= oBlattStamm.getCellRangeByName("F27").value

ABER iNrAstra_Ki nicht DEKLARIERT hast. Also füge das zu deiner deklaration noch hinzu.

Code: Alles auswählen


Dim iNrAstra_Ki as Integer


Danach kannst Du den kommentierten Block aus der "Sub Kiste_Astra" komplett in die "Sub Dlg_neuer_Artikel" verschieben.

Das folgende baut nicht der Reihe nach auf dessen auf was Du gesagt hast, sondern es wird Thematisch vorgegangen da das eine auf das andere aufbaut. Arbeite jedes Thema der Reihe nach ab.

Thema. Verbesserung Teil 1

Modul „Kiste_Astra“
Ich wollte eigentlich die zwei möglichen Preise (30€/35€) für den Verkauf einer Kiste Astra ebenfalls im Stammblatt hinterlegen.

Das geht, und das machen wir jetzt auch.

Auch wenn es eine andere Methode gibt, so zeige ich dir eine relativ einfache Methode.
Fangen wir mit der deklaration an.

Code: Alles auswählen


Dim aKistenPreise
(1) as Integer

Kommt dir bekannt vor, oder?
Okay, es gibt einen Unterschied. Durch die Klammer mit Inhalt signalisiert man das es sich um ein Array handelt.

"Array? Array? Array? War da nicht etwas?"

Wirst Du dich zu Recht fragen, und JA das hatte ich vor kurzem schon angesprochen. Und außerdem hast Du ja selber schon etwas mit Array eingebaut. Du erinnerst dich an das hier?
balu hat geschrieben:Ich sehe Du hast hier im Forum etwas gefunden, was sehr nützlich ist.

Code: Alles auswählen

   aSourceDataArray() = oZellenMitarbeiter.getDataArray()
   Dim aSource(UBound(aSourceDataArray())) as String 
   For j = LBound(aSource()) To UBound(aSource())
      aDataArrayRow() = aSourceDataArray(j)
   aSource(j) = aDataArrayRow(0)

Find ich echt klasse wie Du doch so aktiv bist.

Ja, dieser Code arbeitet auch mit Array. Ist ja auch gar nicht so schwer zu identifizieren, gelle!
Da dieser Code aber auf ein Tabellenblatt zugreift, und nur mit String arbeitet, können wir vorläufig nicht sehr viel damit anfangen. Also nehmen wir eine andere Methode, ist vom Prinzip eigentlich nicht anders.

Und so nebenbei gibts jetzt einen sehr kleinen Mini Crash-Kurs zum Thema ARRAY.

Das Array aKistenPreise (1) wurde ja jetzt so deklariert. Und die 1 in den Klammern sagt, es handelt sich um 2 Elemente die das Array aufnehmen soll.

"Und warum 2, und nicht 1?"

Ganz einfach, weil es sich automatisch dabei um eine Null-Basierte Zählung handelt. Und damit hast Du ja wohl schon öfters im Makro zu tun gehabt, mit der Null-Basierten Zählung. Also brauche ich wohl nix mehr dazu zu sagen. Es gibt wohl auch noch Ausnahmen davon, aber das passt jetzt nicht zum *Mini Crash-Kurs*, kommt vielleicht später.

Und jetzt muss noch das Array mit Leben befüllt werden.

Code: Alles auswählen


aKistenPreise
(0) = 35
aKistenPreise
(1) = 30

Im groben kannst Du das jetzt mit einer Spalte in einem Tabellenblatt vergleichen. Und die Zahlen in Klammern wären dann jetzt die Zeilennummern. Und auf ein Tabellenblatt angepasst hätten wir jetzt also folgende Situation.
A1 hat den Wert 35
A2 hat den Wert 30

Nun könnte man folgendes im Makro machen.

Code: Alles auswählen


Print aKistenPreise
(1)

Das Ergebnis wäre 30. Tauscht man die 1 gegen die 0, würde beim erneuten ausführen die 35 ausgegeben.
Also vom Prinzip her nix anderes, als wenn man im Tabellenblatt in der Zelle H1 einfach =A2, oder =A1 eingeben würde. Ist doch für den Anfang gar nicht so extrem schwer, oder ;-)

Okay, jetzt muss aber damit die Listbox befüllt werden, und das machen wir hiermit.

Code: Alles auswählen


    For iKP 
= 0 To UBound(aKistenPreise())
        aKistenPreise(iKP ) = aKistenPreise(iKP )
    Next iKP
        Dlg_Astrakiste
.Model.getByName("Preis").StringItemList = aKistenPreise()

Aber Achtung!
Es gibt einen sehr wichtigen Punkt den man berücksichtigen muss.

Du hast wohl korrekt die Listbox wie folgt deklariert,

Code: Alles auswählen


oListBox_Preis 
= Dlg_Astrakiste.GetControl("Preis")

jedoch das befüllen geschieht nicht über GetControl, sondern mit Model.getByName. Das darf auf gar keinen Fall durcheinander geworfen werden. Denn sonst erlebt man böse Überraschungen.


Das ist kurz, einfach und für den Anfang reicht das für die 2 einzutragenden Werte.
Und hier jetzt noch mal alles zusammen.

Code: Alles auswählen


Dim aKistenPreise
(1) as Integer

' Ab hier in die Sub Dlg_neuer_Artikel eintragen'

aKistenPreise(0) = 30
aKistenPreise
(1) = 35

    For iKP 
= 0 To UBound(aKistenPreise())
        aKistenPreise(iKP ) = aKistenPreise(iKP ) 
    Next iKP
        Dlg_Astrakiste
.Model.getByName("Preis").StringItemList = aKistenPreise()
 



Thema: Verbesserung Teil 2:

Aber ich hab mir scheinbar durch die Anwendung von .SelectedItemPos selbst ein Bein gestellt. Das müsste man sonst wohl nochmal ganz anders machen.

Stimmt!
Du musst nicht für alles eine zwischenvariable heranziehen, besonders dann, wenn sie nur einmal gebraucht wird. Dadurch wirst Du noch den Überblick verlierern.
Hier ein Beispiel.

Code: Alles auswählen

   LBox_AstraPreis_Ki = oListBox_Preis.selecteditempos()
[...]
If  LBox_AstraPreis_Ki = 0 Then
   LBoxWert_AstraPreis_Ki = 35
Else
 LBoxWert_AstraPreis_Ki = 30
Endif

Das muss nicht wirklich sein.

Das kommende baut auf Verbesserung Teil 1 auf, und ohne dies würde es nicht richtig funktionieren

Mit selecteditempos wird nur die Position ermittelt, also beispielsweise die 2 für die 3. Zeile (Null-Basierte Zählung).

Jedoch mit selecteditem wird der gewählte Eintrag (Text) übernommen.

Und das ganze machen wir uns jetzt zu Nutze. Und zwar kurz und schmerzlos.

Code: Alles auswählen


    LBoxWert_AstraPreis_Ki 
= VAL(oListBox_Preis.selecteditem)

Da selecteditem einen Text zurückgibt, muss dieser "Text" in einen Wert umgewandelt werden. Und das geschieht mittels VAL.
Mehr brauchts nicht. Also nix mit irgendeiner Schleife drunherum. Anstatt 5, jetzt nur noch 1 Zeile.
Hier ein weiterer Link zu Dannenhöfer. 4.3.9 Welches sind die Besonderheiten von Listboxen?


Thema: Zur kentniss genommen:

Modul „Flaschenverkauf“:
[...]
Das ist übrigens ein Modul, durch das ich selbst noch nicht recht durchsteige. Ich schätze mal, da geht noch ganz gut was zu verbessern.

Wenn du all die MsgBoxen ausgelagert hast, wie ja schon von mir schon erklärt, dann lässt sich das doch schon bestimmt besser lesen. Ni war? ;)


Modul „Flaschenverkauf“:
Hier ist jetzt doch noch eine Formel drin – ich habe es nicht hinbekommen, die zu ersetzen. Das ist allerdings auch nicht notwendig, das wird nicht so oft benutzt.

Ach Du meinst z.B. das hier!

Code: Alles auswählen

"=IF(K" & iEnd_Row & "=0;"""";IF(K" & iEnd_Row & "=50;""Mitarbeiter"";IF(AND(K" & iEnd_Row & ">50;K" & iEnd_Row & "<100);""Sachentnahme"";IF(K" & iEnd_Row & "=100;""Kostenfreie Abgabe"";""Sonstige""))))"

Nun, da hätte ich wohl eine alternative, aber nicht mehr heute.


Thema: Das letzte für heute

Kann man eigentlich, wenn man "sgRabatt_Art = oRabatt_Artikel.Value()" in Klammern setzt, auch damit rechnen? Fällt mir grad spontan ein - hab's nicht ausprobiert.

Das solltest Du noch mal genauer erklären.


Und dann habe ich noch versucht, das hier umzuschreiben:

Code: Alles auswählen

   oAktuellesBlatt = thiscomponent.getcurrentcontroller.activesheet
   oCellCursor = oAktuellesBlatt.createCursor()
   oCellCursor.GotoEndOfUsedArea(True)


Mit meiner Kreation

Code: Alles auswählen

   oAktuellesBlatt = thiscomponent.getcurrentcontroller.activesheet.createCursor().GotoEndOfUsedArea(True)

war ich aber nicht erfolgreich.

Ganz Kurz: Nicht alles kann man als Einzeiler schreiben.


Und nun hoffe ich das die letzten Aktuellen "Weh-Wehchen" erstmal abgehakt sind. Wenn Du auch dieses erledigt hast, dann hänge die aktuellste Version - {inklusive der gestrigen Aktionen} - hier beim nächten mal an. Und dann schaun ma mal wie es weiter geht, falls Du dann nicht noch aktuellere Probleme hast.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D


Zurück zu „Projekte“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste