beschriebene Excel-Zelle erkennen und variable Quelldaten finden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rottyger
User
Beiträge: 2
Registriert: Dienstag 10. Juli 2018, 06:33

Guten Tag liebe Community,

dies ist mein erster Beitrag, ich bitte eventuelle Fehler oder undeutliche Beschreibungen zu entschuldigen.

Erstmal die Grundanforderung:

Es soll eine PDF-Datei (später mehrere Datei) in Excel gewandelt werden, bestimmte Daten rausgefiltert werden und in einer Excelsammelliste erfasst werden.

Soweit bin ich bisher auch (fast) mit Hilfe von openpyxl und xlrd gekommen. Die PDF-Dateien werden (noch) von einer bereits vorgandenden Programm (nicht mein Werk) in Exceldateien gewandelt.

Bisher kann ich die Daten an Zellen fest machen, filtern und in die neue Liste entsprechen eintragen.

Ich bin blutigster Anfänger, was die Programmierung angeht (erstes Projekt). Entrechend simpel ist mein Text aufgebaut.

Ich bitte um Nachsicht.

Meine zwei Probleme:

1. wie erkläre ich meinem Programm, dass es zuerst prüfen soll ob die angesteuerte Zelle bereits beschrieben ist und ggfls. eine Zelle weiter geht?

2. aktuell geb ich als Quelle die Grunddatei fest an. Die Finale Anforderung soll aber eigenständig mehre Dateien durchlaufen lassen.
Würde sich ein ORdnersystem hier anbieten? Alle Exceldateien in Order Xyz werden beim start angesteuert?


Vielen Dank vorab

MFG
rottyger

Code: Alles auswählen

import xlrd
import openpyxl


workbook = xlrd.open_workbook("Test.xlsx")

worksheet = workbook.sheet_by_index(0)

a = format(worksheet.cell (6,1).value)
b = a.split(':')
#print (b)
Lieferant = b[1]

c = format(worksheet.cell (7,1).value)
d = c.split(':')
#print (d)
Lieferantennr = d[1]
Bestellnummer = d[3]


e = format(worksheet.cell (8,1).value)
f = e.split(':')
#print (f)
Lieferschein = f[3]

excelDatei = openpyxl.load_workbook('Mappe2.xlsx')
sheetNamen = excelDatei['2018']

sheetNamen.cell(row=2, column=3).value = (Lieferant)
sheetNamen.cell(row=2, column=5).value = (Bestellnummer)
sheetNamen.cell(row=2, column=10).value = (Lieferantennr)
sheetNamen.cell(row=2, column=11).value = (Lieferschein)

excelDatei.save("Mappe2.xlsx")
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rottyger: Erst einmal Anmerkungen zum Quelltext:

Nichtssagende einbuchstabige Namen sollte man nicht verwenden. Am Namen sollte der Leser erkennen können was ein Wert im Programm bedeutet. Das geht bei `a` bis `f` nicht wirklich.

Die Namenskonventionen in Python sehen für alles ausser Konstanten (KOMPLETT_IN_GROSSBUCHSTABEN) und Klassen (MixedCase) eine kleinbuchstaben_mit_unterstrichen Schreibweise vor. Siehe Style Guide for Python Code.

Die `format()`-Aufrufe machen alle keinen Sinn. Was sollten die denn Deiner Meinung nach bewirken?

Dann kann und sollte man schon anfangen das sinnvoll auf Funktionen aufzuteilen.

Zwischenstand, mit teilweise zu generischen Namen, könnte so aussehen:

Code: Alles auswählen

import openpyxl
import xlrd


def get_values(sheet, row, column, indices):
    parts = sheet.cell(row, column).split(':')
    return [parts[i] for i in indices]


def get_value(sheet, row, column, index):
    return get_values(sheet, row, column, [index])[0]


def load_data(filename):
    workbook = xlrd.open_workbook(filename)
    sheet = workbook.sheet_by_index(0)
    lieferanten_nr, bestellnummer = get_values(sheet, 7, 1, [1, 3])
    return {
        'bestellnummer': bestellnummer,
        'lieferant': get_value(sheet, 6, 1, 1),
        'lieferanten_nr': lieferanten_nr,
        'lieferschein': get_value(sheet, 8, 1, 3),
    }


def update_document(filename, sheet_name, data):
    workbook = openpyxl.load_workbook(filename)
    sheet = workbook[sheet_name]

    for column, key in [
        (3, 'lieferant'),
        (5, 'bestellnummer'),
        (10, 'lieferanten_nr'),
        (11, 'lieferschein'),
    ]:
        sheet.cell(row=2, column=column).value = data[key]

    workbook.save(filename)


def main():
    update_document('Mappe2.xlsx', '2018', load_data('test.xlsx'))


if __name__ == '__main__':
    main()
Zu den Fragen:

Ad 1: Ganz allgemein musst Du halt die Koordinaten der Zelle solange entsprechend verändern, bis du eine leere Zelle gefunden hast. Eine ``while``-Schleife wäre da nützlich.

Spezieller kann es einfacher gehen. Wenn es beispielsweise darum geht die erste Zeile am Ende der Daten ohne Werte zu finden, um zum Beispiel eine neue Zeile mit Werten zu füllen, haben `Sheet`-Objekte ein `nrows`-Attribut, welches die Anzahl der Zeilen liefert. Analog gibt es `ncols` für Spalten.

Ad 2: Ordner wäre eine Möglichkeit. Eine andere wäre es die Dateinamen als Argument beim Aufruf an das Programm zu übergeben. Zumindest bei Shells die das nicht unnötig kompliziert machen, ist das genau so einfach wie ein Ordner, aber viel flexibler. Man kann es auch kombinieren, also entweder Dateien vorgeben oder Ordner.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
rottyger
User
Beiträge: 2
Registriert: Dienstag 10. Juli 2018, 06:33

@_blackjack_ vielen Dank für die schnelle und ausführliche Antwort!

Ich werde mich mit dem Style Guide auseinandersetzen.

Die 'format()' - Aufrufe brauche ich um die Date zu bekommen, da in der Excelquelle die Daten hintereinanderweg in einer Zelle stehen.

Könnte die While-Schleife so aussehen?:

Code: Alles auswählen

zeile = 2
while sheetNamen.cell(row=zeile, column=5).value == #mir fehlt der Befehl der pauschal prüft ob hier etwas steht :
    zeile = zeile + 1
else: sheetNamen.cell(row=zeile, column=5).value = (Lieferant)
Vielen Dank vorab.
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rottyger: `format()` bewirkt nichts anderes als den Wert in eine Zeichenkette umzuwandeln. Da Du den dann an Doppelpunkten aufteilst, muss das vorher schon eine Zeichenkette gewesen sein, also bewirkt `format()` gar nichts. Deswegen fragte ich.

Um eine leere Zelle zu finden, musst Du Dir den Wert anschauen. Schau doch einfach mal was Du da so an Werten ausgegeben bekommst.

``else`` bei Schleifen macht nur Sinn wenn in der Schleife ein ``break`` verwendet wird. ``break`` wird in einer Lösung zwar wahrscheinlich vorkommen, weil man `sheetNamen.cell(row=zeile, column=5)` nicht zweimal im Quelltext stehen haben möchte, aber dann ist das ``break`` im Erfolgsfall.

Willst Du da wirklich selber suchen, oder reicht die `append()`-Methode auf `Worksheet`-Objekten aus?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten