per openpyxl sheet leeren

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
stefanxfg
User
Beiträge: 85
Registriert: Sonntag 2. April 2017, 14:11

Hallo, ich schreibe per GUI etwaige Daten in ein Sheet. Diese Daten sind Daten von einer dynamisch erzeugten Tabelle. Diese Daten nehme ich beim nächsten Programmstart, um die Tabelle wiederherzustellen. Gewissermaßen der letzte Stand soll wieder angezeigt werden.
So, nun habe ich ein paar Zeilen generiert und lösche sie aus der Tabelle der GUI raus, aber eben nicht im Sheet. Wenn ich nun neue Zeilen in der GUI erzeuge, dann werden die Excel-Zeilen überschrieben. Bisher alles logisch.
Wenn ich jetzt eine Zeile in der GUI erzeuge, die GUI schließe und dann wieder öffne, wird die überschriebene Zeile und die weiteren Zeilen angezeigt.

Achso, was ich vergesse habe, ich fülle damit ein Dictionary. Ich möchte, ganz schlicht, das Excel-Sheet leeren bevor ich gespeichert wird.

Ich finde einfach nicht so eine einfache Funktion wie in VBA. workbook.worksheet.clear()

Wenn ich ein " " rausschreibe und dass wieder einlese, wird ein None angezeigt. Die Excel-Zeilen sind leer, aber so kann ich es nicht gebrauchen.

Hat jemand eine Idee?
Benutzeravatar
pixewakb
User
Beiträge: 1405
Registriert: Sonntag 24. April 2011, 19:43

Hilft das: http://www.pythonexcel.com/delete-sheet.php

Tabelle auswählen, löschen und (!) dann neu erzeugen, so würde ich das wahrscheinlich versuchen (und vorher mal ein backup anlegen in einem Ordner, den ich regelmäßig leere).
stefanxfg
User
Beiträge: 85
Registriert: Sonntag 2. April 2017, 14:11

Das finde ich Bockmist. Wenn man öfters ändert, oder bei jeder Zeile, die man hinzufügt, wird dann das Sheet gelöscht und neu eingefügt.

Also ehrlich gesagt, dann schieße ich das openpyxl ab. Auch der Mist mit COM ist meines Erachtens nur so ein zusammengefummle. Dann sollte man auf andere Module gehen, die das eben unterstützen. Ich habe jetzt xlwings gefunden. Das weißt in den docs auf Matplotlibanbindung und möglicher Einbindung von VBA-Code hin. Mal sehen, ob das zu gebrauchen ist.
Benutzeravatar
pixewakb
User
Beiträge: 1405
Registriert: Sonntag 24. April 2011, 19:43

Ich nutze openpyxl selbst und bin damit eingentlich sehr (!) zufrieden. Wenn Du das Modul noch nicht aufgegeben hast, dann könntest du mal auf stackoverflow nachfragen bzw. nach openpyxl-Fragen sehen. Charlie Clark, einer der beiden Maintainer, ist da sehr aktiv und sehr hilfsbereit.

Möglicherweise verstehe ich deine Frage auch falsch, aber wenn du das ganze (!) sheet leeren willst und somit von 0 beginnen möchtest, dann wäre einfach löschen und wieder hinzufügen m. E. der einfache und gangbare Weg, weil du ansonsten nämlich alle Zeilen leeren müstest, um sie dann wieder zu füllen. Ich denke - habe es nicht getestet -, dass das länger dauert und möglicherweise auch ungewünschte Nebeneffekte haben könnte.
stefanxfg
User
Beiträge: 85
Registriert: Sonntag 2. April 2017, 14:11

Es geht darum, dass man das auf einen Ruck leert. Vielleicht sieht man das eher als Reset an einem bestimmten Zeitpunkt. Wenn so eine grundlegende Funktion nicht bereit steht, dann nützt mir das Modul nichts. Und die Alternativwege sind nicht schön. Das xlwing scheint das aber schon mitzubringen.
Das Leeren soll nicht für alle Zeiten gehen, sondern nur vor dem Speichern der Daten aus dem Dictionary soll das Sheet bereinigt werden, dann wird es gefüllt.
Das geschieht bei jeder neuen Zeile, oder beim Löschen von Zeilen. Mit einer Clear-Methode ist das auf einen Schlag getan. Jedenfalls kenne ich das aus VBA.
Benutzeravatar
pixewakb
User
Beiträge: 1405
Registriert: Sonntag 24. April 2011, 19:43

Ich will dich zu nichts drängen, aber schon mal was anmerken: Du hast eine Funktion, die du nutzt und was unter der Haube passiert, siehst du nicht. D. h. du könntest leicht für openpyxl eine Funktion schreiben, die das sheet leeren implementiert und z. B. die Tabelle löscht und eine Tabelle gleichen Namens hinzufügt.
stefanxfg
User
Beiträge: 85
Registriert: Sonntag 2. April 2017, 14:11

Das habe ich nun gemacht. Im Ergebnis ist es nun so, dass ich es sichtlich langsamer ist. Es läuft alles, aber nicht mir guter Performance.

Nur zur Erklärung. Ich füge die Tabellenzeilen so zu.

Code: Alles auswählen

    def add_section(self,name_line):
        
        self.data[name_line] = dict(self.default_setting)
        self.build_table()
      
        self.save_sections_excel()
        
        publish('UPDATE_PLOT')
Damit sieht man. Es bestehen Daten in data. Die Tabelle wird erzeugt bzw. aktualisiert, die Daten werden gespeichert. Dann wird gezeichnet.

Code: Alles auswählen

    def save_sections_excel(self): #Wenn die Speicherdatei noch nicht bekannt ist, erfolgt Fehlermeldung.
 
        wb = openpyxl.load_workbook(self.fname)
        sheet_name = 'Sections_YZ'    
        sheet_list = wb.get_sheet_names()
        
        if sheet_name in sheet_list: 
            ws = wb.get_sheet_by_name(sheet_name)
            wb.remove_sheet(ws)
            wb.create_sheet(title =sheet_name)
            ws = wb.get_sheet_by_name(sheet_name)
        else:
            wb.create_sheet(title =sheet_name)
            ws = wb.get_sheet_by_name(sheet_name)


        
        next_row=1
        next_col=1

        for outer_key,values in self.data.items():
            next_row += 1
            ws.cell(column=1, row=next_row, value=outer_key)

            for inner_key,inner_value in values.items():
                next_col += 1
                ws.cell(column=next_col, row=next_row, value=inner_key)
                next_col += 1
                ws.cell(column=next_col, row=next_row, value=inner_value)                
            next_col=1
            
        wb.save(self.fname) 
Aber der Ansatz ist sicher nicht gut. Was ist denn in den Zellen eingetragen, wenn das Sheet erzeugt wird? Genau so, muss das Sheet zurückgesetzt werden.
Übrigens Charlie Clark hat leider auch nur diesen Ansatz mit der Löschung und anschließender Erzeugung des Sheets genannt.
Benutzeravatar
pixewakb
User
Beiträge: 1405
Registriert: Sonntag 24. April 2011, 19:43

Ohne den Umfang deiner Daten jetzt zu kennen und genau zu wissen, was du machst: Die Zellen einzeln abfragen und prüfen, ob ein Zelleninhalt vorhanden ist, dann die Zelle zu leeren und das für 1.048.576 Zeilen x 16.384 Spalten dürfte länger dauern. Ich denke mal die Arbeitszeit hängt davon ab, was du da machst.

Ich nutze es selten, aber pandas hat auch eine Routine dabei, um ein Excel-File zu schreiben. Bislang lesen sich deine Posts danach, dass du ein komplexes Excel-File mit Diagrammen und einigen Tabellen updaten musst. Wenn es einfacher gestrickt ist, wäre pandas ggf. auch eine Option, da schreibt man aber ein pandas DataFrame in eine Tabelle.

PS Ansonsten: C. Clark ist schon für Excel der Experte schlechthin. Wenn er meint, es geht nicht besser, dann geht es wohl leider nicht besser.
Antworten