Mit for-Schleife in Excel Tabelle schreiben

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.
Krystek
User
Beiträge: 23
Registriert: Mittwoch 10. November 2021, 10:12

Hi,

ich hätte da noch eine Frage zu deinem Code.

Code: Alles auswählen

def iter_tests(file_path):
    workbook = load_workbook(file_path)
    print(workbook.sheetnames)
    sheet = workbook["boolean"]
    return (
        Test(test_id_cell.value, test_name_cell.value, signal_name_cell.value)
        for (
            test_id_cell,
            _,
            signal_name_cell,
            _,
            _,
            _,
            test_name_cell,
        ) in sheet.rows
    )


def process_tests(tests):
    return (
        (signal_name, {test.name: test.id for test in group})
        for signal_name, group in groupby(tests, lambda test: test.signal_name)
    )

ich habe in meiner Quelldatei weitere Reiter, aus denen ich in der gleichen Form das "Wörterbuch" erstellen möchte. Ich habe verschiedene Variante ausprobiert aber es hat nichts funktioniert.

In deiner Version liegen die Daten am Ende in test_name_to_id vor. Ich hätte gerne, dass dann weitere Daten in test_name_to_id_sheet_2, test_name_to_id_sheet_3 usw. vorliegen. Ich hoffe, dass man verstehen kann, was ich meine.

VG
Krystek
Benutzeravatar
__blackjack__
User
Beiträge: 13133
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Krystek: Warum willst Du da nummerierte Namen haben? Brauchst Du denn diese Werte alle gleichzeitig, oder werden die nicht unabhängig voneinander verarbeitet, Arbeitsblatt für Arbeitsblatt? Wenn die die gleiche Struktur haben, müsste man bei `iter_tests()` doch nur den Blattnamen als Argument übergeben können. Und dann kann man eine weitere Schleife über die Blattnamen hinzufügen. Oder eine Datenstruktur die Blattnamen und eventuell weitere Informationen enthält durch die sich die Arbeitsblätter unterscheiden.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Krystek
User
Beiträge: 23
Registriert: Mittwoch 10. November 2021, 10:12

Ich habe in meinem ersten sheet Signale vom Typ boolean. Diese sollen in ein Wörterbuch, da diese später als ein gemeinsamer Block in das template geladen werden soll.

Im nächsten sheet habe ich Signale vom Typ int8, die auch in ein eigenes Wörterbuch sollen. Das liegt daran, dass ich diese Daten im weiteren Verlauf in folgender Form aufrufe bzw. ins template lade:

Code: Alles auswählen

template_workbook_sheet.cell(row=j, column=4).value = test_name_to_id_["Testen des Max. Wertebereichs"]
Hier suche ich nach der ID des Max-Tests. Wenn die Signale vom Typ boolean und int8 sich in einem Wörterbuch befinden würden und ich den gezeigten Code verwende, würde ich die ID von allen Signalen erhalten.
Allerdings möchte ich einmal auf die ID des Max-Test von zB Signal_1 (Datentyp: boolean, erstes sheet) zugreifen können ohne dabei gleichzeitig auf die ID des Max-Test von zB Signal_8 (Datentyp:int8, zweites sheet) zuzugreifen.

Der folgende Code funktioniert so nicht aber verdeutlicht vielleicht, wie das Ergebnis aussehen sollte

Code: Alles auswählen

def iter_tests(file_path):
    workbook = load_workbook(file_path)
    print(workbook.sheetnames)
    sheet_bool = workbook["boolean"]
    sheet_int8 = workbook["int8"]
    sheet_uint8 = workbook["uint8"]
    sheet_int16 = workbook["int16"]
    sheet_uint16 = workbook["uint16"]
    sheet_int32 = workbook["int32"]
    sheet_uint32 = workbook["uint32"]

    return (
        Test(test_id_cell.value, test_name_cell.value, signal_name_cell.value)
        for (
            test_id_cell_bool,
            _,
            signal_name_cell_bool,
            _,
            _,
            _,
            test_name_cell_bool,
            _,
            _,
            _,
            _,
            _,
            _,
            _,
            _,
            _,
            _,
        ) in sheet_bool.rows


        for (
        test_id_cell_int8,
        _,
        signal_name_cell_int8,
        _,
        _,
        _,
        test_name_cell_int8,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        ) in sheet_int8.rows
    )
    
    def main():

    template_workbook = load_workbook('C:/.../template.xlsx')
    template_workbook_sheet = template_workbook.active

    

    j = 9
    for signal_name, test_name_to_id_bool in process_tests(iter_tests(SOURCE_PATH)):
        print(">", signal_name)
        pprint(test_name_to_id_bool)


        template_workbook_sheet.cell(row=j, column=3).value = signal_name


      
            template_workbook_sheet.cell(row=j, column=4).value = test_name_to_id_bool["Testen des Max. Wertebereichs"]
            template_workbook_sheet.cell(row=j, column=5).value = test_name_to_id_bool["Timeout"]
            template_workbook_sheet.cell(row=j, column=6).value = test_name_to_id_bool["Testen des Min. Wertebereichs"]
            template_workbook_sheet.cell(row=j, column=7).value = test_name_to_id_bool["Init+Timeout"]
            template_workbook_sheet.cell(row=j, column=8).value = test_name_to_id_bool["Init"]
            template_workbook_sheet.cell(row=j, column=9).value = test_name_to_id_bool["Init+Timeout (Busruhe) "]
            template_workbook_sheet.cell(row=j, column=10).value = test_name_to_id_bool["Init (Busruhe)"]

        j += 1
        
    k = 15
    for signal_name, test_name_to_id_int8 in process_tests(iter_tests(SOURCE_PATH)):
        print(">", signal_name)
        pprint(test_name_to_id_int8)


        template_workbook_sheet.cell(row=j, column=3).value = signal_name


      
            template_workbook_sheet.cell(row=k, column=4).value = test_name_to_id_int8["Testen des Max. Wertebereichs"]
            template_workbook_sheet.cell(row=k, column=5).value = test_name_to_id_int8["Timeout"]
            template_workbook_sheet.cell(row=k, column=6).value = test_name_to_id_int8["Testen des Min. Wertebereichs"]
            template_workbook_sheet.cell(row=k, column=7).value = test_name_to_id_int8["Init+Timeout"]
            template_workbook_sheet.cell(row=k, column=8).value = test_name_to_id_int8["Init"]
            template_workbook_sheet.cell(row=k, column=9).value = test_name_to_id_int8["Init+Timeout (Busruhe) "]
            template_workbook_sheet.cell(row=k, column=10).value = test_name_to_id_int8["Init (Busruhe)"]

       k += 1
    
    template_workbook.save('C:/.../tab_2.xlsx')

if __name__ == "__main__":
    main()
    
    
Krystek
User
Beiträge: 23
Registriert: Mittwoch 10. November 2021, 10:12

Hallo nochmal,

könntest du mir vielleicht noch kurz erklären wie du das gemeint hattest.
Wenn die die gleiche Struktur haben, müsste man bei `iter_tests()` doch nur den Blattnamen als Argument übergeben können. Und dann kann man eine weitere Schleife über die Blattnamen hinzufügen.
So wie ich das verstanden habe, müsste ich das wie folgt machen.

Code: Alles auswählen

def iter_tests(file_path):
    workbook = load_workbook(file_path)
    print(workbook.sheetnames)
    sheet_bool = workbook["boolean"]
    sheet_int8 = workbook["int8"]
    return (
        Test(test_id_cell.value, test_name_cell.value, signal_name_cell.value)
        for (
        test_id_cell,
        _,
        signal_name_cell,
        _,
        _,
        _,
        test_name_cell,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        ) in sheet_bool.rows

        for (
        test_id_cell_int8,
        _,
        signal_name_cell_int8,
        _,
        _,
        _,
        test_name_cell_int8,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ) in sheet_int8.rows
    )
Was muss ich nun in def main() ändern bzw. hinzufügen, damit ich ein weiteres test_name_to_id erhalte und es nicht einfach überschrieben wird.

Vielen Dank!

Gruß
Krystek
Benutzeravatar
__blackjack__
User
Beiträge: 13133
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Krystek: Nein, man muss da anders parametrisieren. Wenn man mehrere Arbeitsblätter aus der gleichen Exceldatei verarbeiten will, dann macht der Dateiname/-pfad als Argument keinen Sinn, denn man will die Datei ja nicht für jedes Arbeitsblatt neu laden. Und der Name des Arbeitsblattes müsste dann auch ein Argument sein. Und falls die Arbeitsblätter nicht ähnlich strukturiert sind, aber die Spalten anders angeordnet sind, dann wäre neben dem Arbeitsblattnamen auch diese Spaltenanordnung ein Argument damit der Code für jedes Arbeitsblatt gleich bleiben kann.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Krystek
User
Beiträge: 23
Registriert: Mittwoch 10. November 2021, 10:12

Vielen Dank für deine Antwort.

Die einzelnen Blätter haben die gleiche Struktur, sodass die Spaltenordnung kein Argument sein muss.

Was meinst du exakt mit dem Begriff "Argument" bezogen auf den Namen des Arbeitsblattes?
Benutzeravatar
__blackjack__
User
Beiträge: 13133
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Krystek: Mit Argument meine ich Argumente von Funktionen. Wenn das einzige was sich für die Verarbeitung eines Arbeitsblattes ändert der Name des Arbeitsblattes ist, dann muss man ja nur *den* im Code ändern, beziehungsweise eben als Argument übergeben. Das mit dem Dateinamen kann man so lassen, aber es ist halt ineffizienter die gleiche Exceldatei jedes mal zu laden um ein Arbeitsblatt zu verarbeiten, statt die auch als Argument zu übergeben und vorher beim Aufrufer *einmal* zu laden.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Krystek
User
Beiträge: 23
Registriert: Mittwoch 10. November 2021, 10:12

Ok! Super! Vielen Dank für den Tipp. Ich habe es so umgesetzt und das funktioniert auch :)
Antworten