Warenkorb

Über die UI Masken kann man auch mit dem Warenkorb interagieren. Die reinen, mechanischen Funktionen können mit der allgemeinen KKP-Python-API abgefragt werden. Für die UI-Masken gibt es aber diverse Funktionen, die die Handhabung deutlich vereinfachen.

Zuerst müssen wir in unserer UI ein Table-Widget einfügen. Zur besseren Übersicht, habe ich ein Tab – Widget eingefügt und dann in den 2. Tab das Table – Widget eingefügt

Dann braucht das TableWidget noch einen Namen, damit wir es in den Skripten verwenden können.

Dann können wir unser In-Skript vorbereiten um die Tabelle mit Leben zu füllen. Für den Umgang mit dem Warenkorb bietet die KKP-API ein eigenes Modul Warenkorb. Dieses übernimmt für uns das Laden und Speichern im richtigen Format. Also brauchen wir uns um diese Form der Konvertierung und Zuordnung nicht mehr kümmern. Also importieren wir das Modul.

import Warenkorb as WK

Dann müssen wir den Warenkorb laden. Der Warenkorb ist immer an eine bestimmte Objektnummer gebunden, also eine eingezeichnete Gruppe im KKP. Wenn man einen allgemeinen Warenkorb wünscht, kann man beispielsweise die Wurzel der Konstruktion verwenden. Diese hat ja immer die Objektnummer 100.

def createXML():
    try: iObjNr = int(XML_PARAM)
    except: iObjNr = 0
    sc = SC.SegmentConfig(iObjNr)
    wk = WK.Warenkorb(100)
    wk.load()

Oder, wenn man einen Warenkorb nur für das angeklickte Segment wünscht: wk = WK.Warenkorb(sc.objnr())

Durch das Laden des Warenkorbs laden bereits alle Artikel, die auf irgendeine Weise bereits in den Warenkorb eingefügt worden sind. Somit können wir diese dann auch bearbeiten.

Dazu wollen wir uns nun eine Funktion schreiben mit der die Tabelle mit Zubehör-Artikeln befüllen können und die Artikel aus unserem geladenen Warenkorb mit einfügen können.

def initZubehoer(sc , wk):
    pass
def createXML():
    try: iObjNr = int(XML_PARAM)
    except: iObjNr = 0
    sc = SC.SegmentConfig(iObjNr)
    wk = WK.Warenkorb(100)
    wk.load()
    initZubehoer(sc , wk) # AUFRUFEN NICHT VERGESSEN!!!
    sXml = sc.toXml()
    return sXml

Für die Tabelle brauchen wir eigentlich nicht viel. Wir brauchen die Spaltenbezeichnungen und eine Liste mit dem Inhalt. Diese Inhaltsliste darf auch leer sein. Und so fangen wir dann auch erst einmal an.

def initZubehoer(sc , wk):
    content = []
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)

In „content“ werden wir gleich den Inhalt der Tabelle füllen. Zuerst schauen wir uns aber die Spalten an. Für die Spalten gibt man nur einen String an. Jedes Semikolon trennt die Spalten. Somit wird auch gleich bekannt gemacht, wie viele Spalten die Tabelle hat, in unserem Beispiel sind es vier.

Dann schauen wir uns das doch mal an:

Um den Inhalt in die Tabelle zu schreiben, müssen wir leider mehr Aufwand betreiben.

Für den Inhalt müssen wir eine Liste für alle Zellen erstellen, die unsere Tabelle haben soll. Jeder dieser Einträge muss ein „Node“ Objekt sein, welches aus dem Modul SegmentConfig stammt. Und wir müssen diverse Eigenschaften vergeben. Daher ist es ratsam sich eine kleine Hilfsunktion zu bauen, mit der wir eine Zelle erstellen können.

def erstelleZelle(sc, sText, bBearbeitbar , zeile , spalte):
    cell = sc.Node(„QTableWidgetItem“)
    cell.setProperty(„row“ , str(zeile))
    cell.setProperty(„col“ , str(spalte))
    return cell

Das sind die Basisdaten, die eigentlich jede Zelle mindestens braucht. Wichtig ist hier zu wissen, dass wir für jede Zelle angeben müssen, in welcher Zeile und in welcher Spalte die Zelle hinkommen soll. Beide Werte Zeile und Spalte beginnen bei 0.

Wir müssen aber auch noch den Text einfügen, bzw. sollten das machen, denn sonst bleibt die Zelle optisch leer. Ferner kann jede Zelle diverse „Flags“ annehmen. Dadurch wird das Verhalten der Zelle gesteuert. Die Wichtigsten hier sind 1 = Anwählbar, 32 = Aktiv, 2 = Bearbeitbar. In der Regel möchte man immer, dass Zellen Aktiv und Anwählbar sind, aber ob die Zelle bearbeitet werden darf ist doch immer wieder unterschiedlich. So könnten wir beispielsweise definieren, dass die Artikelnummer und die Bezeichnung nicht bearbeitet werden dürfen, die Menge und die Länge hingegen schon.

Diese Flags müssen zu einer Zahl summiert werden, je nachdem was man haben möchte. Wir brauchen nur bearbeitbar = 1 + 32 + 2 = 35 und nicht bearbeitbar = 1 + 32 = 33.

def erstelleZelle(sc, sText, bBearbeitbar , zeile , spalte):
    cell = sc.Node(„QTableWidgetItem“)
    if bBearbeitbar: cell.setProperty(„flags“ , „35“)
    else: cell.setProperty(„flags“ , „33“)
    cell.setProperty(„text“ , sText)
    cell.setProperty(„row“ , str(zeile))
    cell.setProperty(„col“ , str(spalte))
    return cell

Bitte beachte, dass die Properties von einem Node Objekt immer als String übergeben werden und nicht als Zahl.

Um diese Funktion zu testen, können wir sie ja mit einigen Fantasiewerten füllen.

def erstelleZelle(sc, sText, bBearbeitbar , zeile , spalte):
    cell = sc.Node(„QTableWidgetItem“)
    if bBearbeitbar: cell.setProperty(„flags“ , „35“)
    else: cell.setProperty(„flags“ , „33“)
    cell.setProperty(„text“ , sText)
    cell.setProperty(„row“ , str(zeile))
    cell.setProperty(„col“ , str(spalte))
    return cell
def initZubehoer(sc , wk):
    content = []
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
    cell = erstelleZelle(sc , „Artikel – Test“ , False , 0 , 0)
    content.append(cell)
    cell = erstelleZelle(sc , „Die Bezeichnung für meinen TestArtikel“ , False , 0 , 1)
    content.append(cell)
def createXML():
    try: iObjNr = int(XML_PARAM)
    except: iObjNr = 0
    sc = SC.SegmentConfig(iObjNr)
    wk = WK.Warenkorb(100)
    wk.load()
    initZubehoer(sc , wk)
    sc.setWindowTitle(„Hello UI!“)
    sXml = sc.toXml()
    return sXml
if __name__ == ‚__main__‘:
    sXml = createXML()
    print(sXml)

Das sieht doch schon mal super aus. ABER! Da wir die letzten beiden Spalten nicht mit einer Zelle befüllt haben, stürzt das KKP ab, wir in der UI Maske versuchen eine der beiden nicht gesetzten Spalten zu bearbeiten. Also immer ALLE Zellen anlegen!!!

Wir können aus dem 2-Zeiler zum Erstellen einer Zelle auch einen 1-Zeiler machen, das ist aber vollkommen optional.

def initZubehoer(sc , wk):
    content = []
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
    content.append(erstelleZelle(sc , „Artikel – Test“ , False , 0 , 0))
    content.append(erstelleZelle(sc , „Die Bezeichnung für meinen TestArtikel“ , False , 0 , 1))
    content.append(erstelleZelle(sc , „1.5“ , True , 0 , 2))
    content.append(erstelleZelle(sc , „“ , True , 0 , 3))

Da unsere Inhalte eigentlich immer dem gleichen Schema folgen können wir uns nun eine Hilfsfunktion schreiben mit der wir gleich eine ganze Zeile einsetzen können. Das geht natürlich nur wenn die Flags in jeder Zeile gleich bleiben.

def erstelleZeile(sc , content , sArtikelnr, sBezeichnung, sMenge , sLaenge):
    iZeilen = len(content) / 4 # Jede Zeile hat 4 Zellen
    iZeile = iZeilen – 1 # Da der Index bei 0 anfängt müssen wir um 1 reduzieren
    if iZeile < 0: iZeile = 0 # Wenn noch gar kein Inhalt da ist ergibt 0 / 4 => 0 ||| 0 – 1 = -1 ||| Der Index muss aber bei 0 starten
    content.append(erstelleZelle(sc , sArtikelnr , False , iZeile , 0)) # Spalte A
    content.append(erstelleZelle(sc , sBezeichnung , False , iZeile , 1)) # Spalte B
    content.append(erstelleZelle(sc , sMenge , True , iZeile , 2)) # Spalte C
    content.append(erstelleZelle(sc , sLaenge , True , iZeile , 3)) # Spalte D
def initZubehoer(sc , wk):
    content = []
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
    erstelleZeile(sc , content , „Artikel 1“ , „Bezeichnung 1“ , „1.0“ , „0.0“)

Auf diese Weise machen wir es uns dann schon einmal etwas leichter, wenn wir viele Artikel in die Tabelle einfügen wollen.

Und da wir gerade von Artikeln reden, sollten wir als nächstes auch zusehen, dass wir welche laden. Und auch dafür bauen wir uns eine kleine Funktion.

import ole
def leseArtikelAusDatenbankAus():
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    kkp.MsgBox(str(erg) , 0)
def initZubehoer(sc , wk):
    content = []
    leseArtikelAusDatenbankAus()
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
    erstelleZeile(sc , content , „Artikel 1“ , „Bezeichnung 1“ , „1.0“ , „0.0“)

Schaut man genauer hin erkennt man folgenden Aufbau:

[

‚Die Anfrage, die ich gestellt habe‘ ,

<Hier im 2. Feld könnte der Dateiname der Datenbank stehen, wenn wir einen angegeben hätten>

‚Hier steht der Header der Abfrage oder das Ergebnis der Abfrage‘

‚Im letzten Feld steht das Ergebnis meiner Anfrage als XML String‘

]

 

Wie man sieht, habe ich in meiner Datenbank nur sehr wenig an Artikeln zu bieten, daher werde ich die Zubehör-Datenbank mit hinzuziehen.

def leseArtikelAusDatenbankAus():
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])

Da meine Zubhördatenbank sehr viele Artikel bietet kann ich die nicht einfach so ausgeben. Aber an der Systemgeberdatenbank kann ich sehen, dass im letzten Feld vom Ergebnis eine XML Struktur steht. Und genau die beinhaltet unsere Artikel. Also holen wir uns diese jetzt einfach mal heraus. Da wir wir die Ergebnisse von 2 Datenbanken haben, baue ich mir wieder eine Funktion, dann brauche ich den Code nicht zu doppeln.

def queryToArray(queryResult):
    rows = []
    sXml = „“
    anzahlFelder = len(queryResult)
    if anzahlFelder > 0: sXml = queryResult[anzahlFelder-1]
    xml = ET.fromstring(sXml)
def leseArtikelAusDatenbankAus():
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])
    queryToArray(erg)
    queryToArray(ergZub)

 

Nun muss ich aus der xml noch die einzelenen Zeilen herausholen. Ich werde das so anstellen, dass ich mir eine Liste mit Zeilen aufbaue. Jede Zeile selbst ist wieder eine Liste in der die einzelnen Spalten der Zeile stehen.

[

[Artikelnr , Bezeichnung , Menge , Länge],

[Artikelnr, Bezeichnung, Menge, Länge],

….

]

def queryToArray(queryResult):
    rows = []
    sXml = „“
    anzahlFelder = len(queryResult)
    if anzahlFelder > 0: sXml = queryResult[anzahlFelder-1]
    xml = ET.fromstring(sXml)
    for record in xml.findall(‚record‘):
        Artikelnr = record.get(‚NR‘)
        Bezeichnung = „“
        Menge = „“
        Laenge = „“
        row = [Artikelnr , Bezeichnung , Menge , Laenge]
        rows.append(row)
    return rows
def leseArtikelAusDatenbankAus():
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])
    rows = queryToArray(erg)
    # rows += queryToArray(ergZub) #Fuer eine kleine Print Ausgabe lasse ich die Daten der Zubehoer Datenbank einmal kurz weg
    kkp.MsgBox(str(rows) , 0)

Im Moment holen wir nur die Artikelnummer aus der Datenbank heraus. Menge und Länge stehen eh nicht in der Datenbank drin. Die müssen wir später über den Warenkorb holen. Aber erst einmal können wir das ja schon nutzen, um unsere Tabelle zu füllen. Und weil wir in der Zwischenzeit schon so viel umbauen mussten, gibt’s mal das ganze Skript.

# -*- coding: utf-8 -*-
import kkp
import SegmentConfig as SC
import Warenkorb as WK
import ole
import xml.etree.ElementTree as ET
import sys
sys.path.append(kkp.Get_Systemgeberdir() + „/ui“)
XML_PARAM = „“““““
def erstelleZelle(sc, sText, bBearbeitbar , zeile , spalte):
    cell = sc.Node(„QTableWidgetItem“)
    if bBearbeitbar: cell.setProperty(„flags“ , „35“)
    else: cell.setProperty(„flags“ , „33“)
    cell.setProperty(„text“ , sText)
    cell.setProperty(„row“ , str(zeile))
    cell.setProperty(„col“ , str(spalte))
    return cell
def erstelleZeile(sc , content , sArtikelnr, sBezeichnung, sMenge , sLaenge):
    iZeilen = int(len(content) / 4)
    iZeile=iZeilen-1
    ifiZeile<0: iZeile=0
    content.append(erstelleZelle(sc , sArtikelnr , False , iZeile , 0)) # Spalte A
    content.append(erstelleZelle(sc , sBezeichnung , False , iZeile , 1)) # Spalte B
    content.append(erstelleZelle(sc , sMenge , True , iZeile , 2)) # Spalte C
    content.append(erstelleZelle(sc , sLaenge , True , iZeile , 3)) # Spalte D
def queryToArray(queryResult):
    rows = []
    sXml = „“
    anzahlFelder = len(queryResult)
    if anzahlFelder > 0: sXml = queryResult[anzahlFelder-1]
    xml = ET.fromstring(sXml)
    for record in xml.findall(‚record‘):
        Artikelnr = record.get(‚NR‘)
        Bezeichnung = „“
        Menge = „“
        Laenge = „“
        row = [Artikelnr , Bezeichnung , Menge , Laenge]
        rows.append(row)
    return rows
def leseArtikelAusDatenbankAus(sc , content):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])
    rows = queryToArray(erg)
    rows += queryToArray(ergZub)
    for row in rows:
        Artikelnr = row[0]
        Bezeichnung = row[1]
        Menge = row[2]
        Laenge = row[3]
        erstelleZeile(sc , content, Artikelnr , Bezeichnung , Menge , Laenge)
def initZubehoer(sc , wk):
    content = []
    leseArtikelAusDatenbankAus(sc , content)
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
def createXML():
    try: iObjNr = int(XML_PARAM)
    except: iObjNr = 0
    sc = SC.SegmentConfig(iObjNr)
    wk = WK.Warenkorb(100)
    wk.load()
    initZubehoer(sc , wk)
    sXml = sc.toXml()
    return sXml
if __name__ == ‚__main__‘:
    sXml = createXML()
    print(sXml)

Ich weiß, das war bislang schon ne Menge Stoff, und es kommt auch noch einiges, aber dafür kann ich versprechen, dass Abspeichern der Tabelle in der Warenkorb wird dafür sehr klein ausfallen. Das ganze Datenbank-Auslesen braucht einfach viel. Dann wollen wir mal schauen, ob wir die Bezeichnung aus der Datenbank bekommen. Hier ergibt sich (zumindest für mich) folgendes Problem. Meine Zubehör-Datenbank ist internationalisiert. Also die hat eine Tabelle Bezeichnung wo die Bezeichnungen mit einer Sprach-ID hinterlegt sind. Meine KKP-System-Datenbank ist aber noch älter und hat keine internationalen Bezeichnungen. Dort befinden sich die Bezeichnungen in der Tabelle Artikel in der Spalte Bezeichnung. Also brauche ich eine Funktion um die Funktion der Artikel auslesen zu können und das je nach Datenbank. Und das mache ich wie folgt. Zuerst frage ich in der Tabelle Bezeichnung nach der Bezeichnung für den Artikel. Wenn ich dort nichts finde, dann nehme ich die Bezeichnung aus der Tabelle Artikel.

# -*- coding: utf-8 -*-
import kkp
import SegmentConfig as SC
import Warenkorb as WK
import ole
import xml.etree.ElementTree as ET
import sys
sys.path.append(kkp.Get_Systemgeberdir() + „/ui“)
XML_PARAM = „“““““
def erstelleZelle(sc, sText, bBearbeitbar , zeile , spalte):
    cell = sc.Node(„QTableWidgetItem“)
    if bBearbeitbar: cell.setProperty(„flags“ , „35“)
    else: cell.setProperty(„flags“ , „33“)
    cell.setProperty(„text“ , sText)
    cell.setProperty(„row“ , str(zeile))
    cell.setProperty(„col“ , str(spalte))
    return cell
def erstelleZeile(sc , content , sArtikelnr, sBezeichnung, sMenge , sLaenge):
    iZeilen = int(len(content) / 4)
    iZeile=iZeilen-1
    ifiZeile<0: iZeile=0
    content.append(erstelleZelle(sc , sArtikelnr , False , iZeile , 0)) # Spalte A
    content.append(erstelleZelle(sc , sBezeichnung , False , iZeile , 1)) # Spalte B
    content.append(erstelleZelle(sc , sMenge , True , iZeile , 2)) # Spalte C
    content.append(erstelleZelle(sc , sLaenge , True , iZeile , 3)) # Spalte D
def queryBezeichnung(ID_Artikel , filenameDB):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select Bezeichnung from Bezeichnung where ID_Artikel = “ + ID_Artikel , filenameDB])
    sXml = erg[len(erg)-1]
    xml = ET.fromstring(sXml)
    record = xml.find(‚record‘)
    if record is not None:
        return record.get(‚Bezeichnung‘)
    return „“
def queryToArray(queryResult):
    rows = []
    sXml = „“
    anzahlFelder = len(queryResult)
    if anzahlFelder > 0: sXml = queryResult[anzahlFelder-1]
    filenameDB = „“
    if anzahlFelder == 4: filenameDB = queryResult[1]
    xml = ET.fromstring(sXml)
    for record in xml.findall(‚record‘):
        Artikelnr = record.get(‚NR‘)
        ID_Artikel = record.get(‚ID‘)
        Bezeichnung = queryBezeichnung(ID_Artikel , filenameDB) #Versuchen Bezeichnung aus Tabelle Bezeichnung zu holen
        if Bezeichnung == „“: Bezeichnung = xml.get(‚Bezeichnung‘) #Wenn leer, dann aus Tabelle Artikel
        Menge = „“
        Laenge = „“
        row = [Artikelnr , Bezeichnung , Menge , Laenge]
        rows.append(row)
    return rows
def leseArtikelAusDatenbankAus(sc , content):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])
    rows = queryToArray(erg)
    rows += queryToArray(ergZub)
    for row in rows:
        Artikelnr = row[0]
        Bezeichnung = row[1]
        Menge = row[2]
        Laenge = row[3]
        erstelleZeile(sc , content, Artikelnr , Bezeichnung , Menge , Laenge)
def initZubehoer(sc , wk):
    content = []
    leseArtikelAusDatenbankAus(sc , content)
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
def createXML():
    try: iObjNr = int(XML_PARAM)
    except: iObjNr = 0
    sc = SC.SegmentConfig(iObjNr)
    wk = WK.Warenkorb(100)
    wk.load()
    initZubehoer(sc , wk)
    sXml = sc.toXml()
    return sXml
if __name__ == ‚__main__‘:
    sXml = createXML()
    print(sXml)

Okay, damit haben wir es endlich geschafft, Daten aus der Datenbank in die Tabelle hineinzulesen. Und jetzt brauchen wir ein bisschen Vorstellungskraft. Wir stellen uns vor, wir öffnen die Maske und sehen die Artikel. Dann geben wir bei den gewünschten Artikeln die Mengen ein und speichern das Ganze. Nun wollen wir das wieder aufrufen. Dann müssen wir also die eingegebenen Daten wieder laden und mit in der Tabelle anzeigen. Und da kommt nun endlich unser Warenkorb ins Spiel. Da unser Warenkorb aber schon ziemlich viele, coole Funktionen liefert, ist das ganz wenig, was wir machen müssen. Das fällt in dem Ganzen Skript drum herum gar nicht auf …

def leseArtikelAusDatenbankAus(sc , wk , content):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])
    rows = queryToArray(erg)
    rows += queryToArray(ergZub)
    for row in rows:
        Artikelnr = row[0]
        Bezeichnung = row[1]
        a = wk.findArtikel(Artikelnr)
        dMenge = 0
        dLaenge = 0
        if a is not None:
            dMenge = round(a[‚m_dMenge‘] , 1)
            dLaenge = round(a[‚m_dLaenge‘] , 3)
        Menge = „%.1f“ % dMenge
        Laenge = „%.3f“ % dLaenge
        erstelleZeile(sc , content, Artikelnr , Bezeichnung , Menge , Laenge)
def initZubehoer(sc , wk):
    content = []
    leseArtikelAusDatenbankAus(sc , wk , content)
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)

Und damit haben wir es endlich geschafft unser IN-Skript zu schreiben. Hier noch einmal das Skript im Ganzen:

# -*- coding: utf-8 -*-
import kkp
import SegmentConfig as SC
import Warenkorb as WK
import ole
import xml.etree.ElementTree as ET
import sys
sys.path.append(kkp.Get_Systemgeberdir() + „/ui“)
XML_PARAM = „“““““
def erstelleZelle(sc, sText, bBearbeitbar , zeile , spalte):
    cell = sc.Node(„QTableWidgetItem“)
    if bBearbeitbar: cell.setProperty(„flags“ , „35“)
    else: cell.setProperty(„flags“ , „33“)
    cell.setProperty(„text“ , sText)
    cell.setProperty(„row“ , str(zeile))
    cell.setProperty(„col“ , str(spalte))
    return cell
def erstelleZeile(sc , content , sArtikelnr, sBezeichnung, sMenge , sLaenge):
    iZeilen = int(len(content) / 4)
    iZeile=iZeilen-1
    ifiZeile<0: iZeile=0
    content.append(erstelleZelle(sc , sArtikelnr , False , iZeile , 0)) # Spalte A
    content.append(erstelleZelle(sc , sBezeichnung , False , iZeile , 1)) # Spalte B
    content.append(erstelleZelle(sc , sMenge , True , iZeile , 2)) # Spalte C
    content.append(erstelleZelle(sc , sLaenge , True , iZeile , 3)) # Spalte D
def queryBezeichnung(ID_Artikel , filenameDB):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select Bezeichnung from Bezeichnung where ID_Artikel = “ + ID_Artikel , filenameDB])
    sXml = erg[len(erg)-1]
    xml = ET.fromstring(sXml)
    record = xml.find(‚record‘)
    if record is not None:
        return record.get(‚Bezeichnung‘)
    return „“
def queryToArray(queryResult):
    rows = []
    sXml = „“
    anzahlFelder = len(queryResult)
    if anzahlFelder > 0: sXml = queryResult[anzahlFelder-1]
    filenameDB = „“
    if anzahlFelder == 4: filenameDB = queryResult[1]
    xml = ET.fromstring(sXml)
    for record in xml.findall(‚record‘):
        Artikelnr = record.get(‚NR‘)
        ID_Artikel = record.get(‚ID‘)
        Bezeichnung = queryBezeichnung(ID_Artikel , filenameDB) #Versuchen Bezeichnung aus Tabelle Bezeichnung zu holen
        if Bezeichnung == „“: Bezeichnung = xml.get(‚Bezeichnung‘) #Wenn leer, dann aus Tabelle Artikel
        Menge = „“
        Laenge = „“
        row = [Artikelnr , Bezeichnung , Menge , Laenge]
        rows.append(row)
    return rows
def leseArtikelAusDatenbankAus(sc , wk , content):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, „Select * from Artikel“)
    filenameDb = kkp.Get_Instdir() + „\\Systeme\\KKP-Zubehoer\\Kalkulation\\KKP-Zubehoer.mdb“
    ergZub = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK, [„Select * from Artikel“ , filenameDb])
    rows = queryToArray(erg)
    rows += queryToArray(ergZub)
    for row in rows:
        Artikelnr = row[0]
        Bezeichnung = row[1]
        a = wk.findArtikel(Artikelnr)
        dMenge = 0
        dLaenge = 0
        if a is not None:
            dMenge = round(a[‚m_dMenge‘] , 1)
            dLaenge = round(a[‚m_dLaenge‘] , 3)
        Menge = „%.1f“ % dMenge
        Laenge = „%.3f“ % dLaenge
        erstelleZeile(sc , content, Artikelnr , Bezeichnung , Menge , Laenge)
def initZubehoer(sc , wk):
    content = []
    leseArtikelAusDatenbankAus(sc , wk , content)
    sc.initTable(„tblAccessory“ , „Artikelnr;Bezeichnung;Menge;Länge (in Meter)“ , content)
def createXML():
    try: iObjNr = int(XML_PARAM)
    except: iObjNr = 0
    sc = SC.SegmentConfig(iObjNr)
    wk = WK.Warenkorb(100)
    wk.load()
    initZubehoer(sc , wk)
    sXml = sc.toXml()
    return sXml
if __name__ == ‚__main__‘:
    sXml = createXML()
    print(sXml)

 

Dann können wir uns jetzt ja dem Out-Skript widmen. Hier haben wir eigentlich nicht viel zu tun. Wir müssen nur die Daten aus der Tabelle auslesen und in den Warenkorb einfügen. Auch hier müssen wir zuerst den Warenkorb laden, damit wir unsere Daten dort hinein speichern können.

# -*- coding: utf-8 -*-
import kkp
import SegmentConfig as SC
import Warenkorb as WK
if __name__ == ‚__main__‘:
    sc = SC.SegmentConfig()
    sc.fromfile(kkp.Get_Projektdir() + „\\segmentConfig_ui.xml“)
    wk = WK.Warenkorb(100)
    #TODO Daten aus Tabelle in Warenkorb schreiben
    wk.save()

Und nun brauchen wir noch eine Funktion, um die Daten aus der Tabelle auszulesen und diese dem Warenkorb hinzuzufügen. Dabei brauchen wir nicht alle Daten. Die Bezeichnung, ist uns egal, denn wir schauen nur nach, ob der Artikel, identifiziert über die Artikelnummer, im Warenkorb steckt. Und wir brauchen auch nur solche Artikel bei denen die Menge nicht 0 ist.

# -*- coding: utf-8 -*-
import kkp
import SegmentConfig as SC
import Warenkorb as WK
def stelleZubehoerEin(sc , wk , tblName):
    wk.m_artikel = []
    node = sc.findByName(tblName)
    if node is None: return
    rows = {}
    for c in node.m_children:
        txt = c.findProperty(„text“)[‚value‘]
        row = c.findProperty(„row“)[‚value‘]
        col = c.findProperty(‚col‘)[‚value‘]
        if row in rows: l = rows[row]
        else: l = {}
        l[col] = txt
        rows[row] = l
    for i in rows:
        row = rows[i]
        sArtikelnr = row[‚0‘]
        #sBezeichnung = row[‚1‘] #wird nicht gebraucht
        row[‚2‘] = row[‚2‘].replace(„,“ , „.“)
        row[‚3‘] = row[‚3‘].replace(„,“ , „.“)
        try: dMenge = float(row[‚2‘])
        except: dMenge = 0
        try: dLaenge = float(row[‚3‘])
        except: dMenge = 0
        if dMenge == 0: continue
        wk.addArtikel(sArtikelnr , dMenge , dLaenge)
if __name__ == ‚__main__‘:
    sc = SC.SegmentConfig()
    sc.fromfile(kkp.Get_Projektdir() + „\\segmentConfig_ui.xml“)
    wk = WK.Warenkorb(100)
    stelleZubehoerEin(sc , wk , „tblAccessory“)
    wk.save()

Und das ist schon das gesamte Out-Skript. Easy oder? Das Auslesen der Daten und das Befüllen der UI Maske waren viel Arbeit und auch kompliziert, aber das Speichern ging dafür wie versprochen schnell von der Hand.

Also, ich wünsche dir viel Spaß beim Nach-Programmieren.