Excel-Spalte mit VBA lesen, Abfragen tätigen und Werte in andere Spalte schreiben

  • Excel

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Excel-Spalte mit VBA lesen, Abfragen tätigen und Werte in andere Spalte schreiben

    Hallo liebe VBA-Community,

    ich bin neu hier und stehe vor folgendem Problem :/ . Ich möchte bzgl. einer Schaltpunktermittlung im KFZ-Bereich gerne eine Excel-Spalte mittels VBA einlesen und anschließend verschiedene Abfragen tätigen. Anschließend sollen diese Werte wieder in eine andere Excel-Spalte geschrieben warden.

    Bsp.:

    In Spalte A stehen untereinander folgende Gänge (jede Zeile bezieht sich auf eine Sekunde):

    4
    4
    3
    4
    4

    Ein Gesetz besagt, dass wenn ein Gang nur für eine Sekunde existiert (hier: Gang 3), soll dieser durch eine Neutralstellung (0) ersetzt werden.
    D.h. folgende Abfragen müssen getätigt werden:

    Wenn die Ist-Zelle ungleich der Vorgänger-Zelle und Ist-Zelle ungleich der Nachfolger-Zelle, dann Ist-Zelle = 0
    Anschließend sollen die korrigierten Werte in Spalte B geschrieben werden:

    4
    4
    0
    4
    4

    Kann mir hierbei jemand weiterhelfen? Wie müsste der Programmcode dazu aussehen?

    Vielen Dank schon jetzt!

    Grüße
    Bassi90
    Die Lösung für das beschriebene Problem wär sehr einfach, aber da es hier häufiger mal die Geschichte gibt von wegen: "Hat jemand fertigen Code für mich?" (was eine passende Frage für die Jobbörse wäre), stellt sich erstmal die Frage: Hast Du bereits Erfahrung mit VB-Programmieren? Wie weit bist Du schon gekommen? Bei welchem Problemschritt hängst Du fest? Wie sieht Dein bisheriger Code aus?

    PSEUDOCode wäre ja (wie Du schon allgemein angesetzt hast):
    • Gehe mit einer Schleife durch alle Zellen einer Spalte, angefangen bei Zeile 2.
    • Vergleiche Zellenwert mit Vorgängerzellenwert.
    • Wenn Vorgängerzellenwert = Zellenwert, dann schreib den aktuellen Zellenwert in die neue Spalte und weiter mit der nächsten Zelle
    • Wenn ungleich, da schau, ob es eine Nachfolgerzelle gibt.
    • Wenn ja, dann schau, ob der Wert gleich dem aktuellen Zellenwert ist
    • Wenn ja, mach aus dem aktuellen Zellenwert eine 0 und schreib diese Null in die neue Spalte
    Was ist eigentlich, wenn die Reihenfolge 4, 4, 3, 2, 3, 4 ist? Soll dann 4, 4, 0, 0, 0, 0 rauskommen?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Hallo VaporiZed,

    ich bin in Sachen VBA ein Neuling. Ich habe mich an dem Code bereits versucht, jedoch lediglich in ersten Schritten:

    Sub Gangwahl()

    Dim i As Single

    For i = 1 To Range("A8").End(xlUp).Row
    If Not IsEmpty(Cells(i, 1)) Then
    If Cells(i, 1).Value <> Cells(i + 1, 1).Value And Cells(i, 1).Value <> Cells(i - 1, 1).Value Then
    Sheets("Sheet 1").Cells(i, 2).Value = 0
    End If
    End If
    Next i

    End Sub


    "Wenn ja, dann schau, ob der Wert gleich dem aktuellen Zellenwert ist" --> Müsste es nciht heißen: "....,ob der Wert ungleich..."
    Die Reihenfolge 4,4,3,2,3,4 wird erst einmal ignoriert. Später werden viele verschiedene Abfragen getätigt. Jedoch muss ich erst einmal den Durchblick mit der Reihenfolge 4,4,3,4,4 erhalten.


    Grüße
    Bassi90

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Bassi90“ ()

    Hab zu meinem Post noch was ergänzt.

    Na, das sieht doch schon ganz gut aus! (btw: mach um Deinen Code noch CodeTags, dann sieht's schöner aus, also einfach vor dem Code [code=vb*] und danach [/code=vb*] schreiben, jeweils ohne *).
    Jetzt nur noch 2 Sachen: Vor das erste End If ein Else Sheets("Sheet 1").Cells(i, 2).Value = Sheets("Sheet 1").Cells(i, 1).Value, damit der unveränderte Wert in die neue Spalte übernommen wird, falls er nicht gegen Null getauscht werden muss und ggf. die For-Schleife bei 2 anfangen, sonst gibt's nen Crash bei <> Cells(i - 1, 1).Value, da Cells(0, 1) nicht ausgewertet werden kann, da Zeile 0 nicht existiert.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Habe jetzt folgenden Code:

    Sub Gangwahl()

    Dim i As Integer

    For i = 2 To Range("A7").End(xlUp).Row
    If Not IsEmpty(Cells(i, 1)) Then
    If Cells(i, 1).Value <> Cells(i + 1, 1).Value And Cells(i, 1).Value <> Cells(i - 1, 1).Value Then
    Sheets("Sheet 1").Cells(i, 2).Value = 0
    Else: Sheets("Sheet 1").Cells(i, 2).Value = Sheets("Sheet 1").Cells(i, 1).Value
    End If
    End If
    Next i

    End Sub

    Leider tut sich beim Ausführen gar nichts (es erscheint auch kein Error).
    Das mit deinem [code=vb*] und [/code=vb*] verstehe ich leider nicht.
    Mach mal statt For i = 2 To Range("A7").End(xlUp).Row provisorisch For i = 2 To 7. Sheets("Sheets 1"). mal rauslassen, denn sonst müssen die Tabellennamen immer stimmen. Etwas allgemeiner wäre z.B. Sheets(1). Dann müsste schon mal was kommen. vor der ganzen Schleife noch Sheets(1).Cells(1, 2).Value = Sheets(1).Cells(1, 1).Value, da der allererste Wert natürlich immer stimmt, oder? Kann der auch Null sein?

    bzgl. CodeTags folgt ein Anhang
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    OK, dann braucht es für die erste Gangart-Zeile ne extra Bedingung, die ganz zum Anfang durchlaufen wird und nur die folgende, nicht die davorkommende Zeile prüft. Das müsste ja wohl in Deinem Sinne sein, oder? Weiß ja nicht, ob das zu Deiner Testpraxis gehört. Ist also fast die gleiche Prüfung wie bisher, nur eben ohne den Vergleich mit Cells(i - 1, 1).Value.

    Zum Anhang. Für Code entweder Deinen Code markieren und auf den rot markierten EditorButton klicken oder was entsprechendes selber in den Text reinschreiben. Auswirkungen siehst Du ja im Bild.
    Bilder
    • CodeButton und CodeTag.png

      17,31 kB, 506×295, 187 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Nun stehe ich vor einem anderen Problem.

    Ich möchte, dass wenn ein Gang nur 2 Sekunden lang gefahren wird diesen in der ersten Sekunde auf Null und in der zweiten Sekunde auf den flgenden Gang ändern (siehe Bsp.)

    5,4,4,2 --> 5,0,2,2

    Als Code habe ich folgenden:

    Sub Gangwahl()

    Dim i As Integer
    Sheets("Sheet1").Cells(1, 2).Value = Sheets("Sheet1").Cells(1, 1).Value
    For i = 2 To 5
    If Not IsEmpty(Cells(i, 1)) Then
    If Sheets("Sheet1").Cells(i, 1).Value <> Sheets("Sheet1").Cells(i - 1, 1).Value And _
    Sheets("Sheet1").Cells(i, 1).Value = Sheets("Sheet1").Cells(i + 1, 1).Value And _
    Sheets("Sheet1").Cells(i, 1).Value <> Sheets("Sheet1").Cells(i + 2, 1).Value Then
    Sheets("Sheet1").Cells(i, 2).Value = 0
    Sheets("Sheet1").Cells(i + 1, 2).Value = Sheets("Sheet1").Cells(i + 2, 1).Value
    Else: Sheets("Sheet1").Cells(i, 2).Value = Sheets("Sheet1").Cells(i, 1).Value
    End If
    End If
    Next i

    End Sub

    Kann es sein, dass VBA nicht mit der zweiten Anweisung (Sheets("Sheet1").Cells(i + 1, 2).Value = Sheets("Sheet1").Cells(i + 2, 1).Value) zurecht kommt?
    Ausgespuckt wird mir nämlich folgendes:

    5,0,4,2

    Danke im Voraus!
    Der Code funktioniert schon, Du hast nur eine Sache nicht beachtet: Es wird jede Zelle ausgewertet, leider auch die, die schon feststehen. Du musst nach Veränderung eine Zeile überspringen:

    Visual Basic-Quellcode

    1. Sub Gangwahl()
    2. Dim i As Integer
    3. Sheets("Sheet1").Cells(1, 2).Value = Sheets("Sheet1").Cells(1, 1).Value
    4. For i = 2 To 5
    5. If Not IsEmpty(Cells(i, 1)) Then
    6. If Sheets("Sheet1").Cells(i, 1).Value <> Sheets("Sheet1").Cells(i - 1, 1).Value And _
    7. Sheets("Sheet1").Cells(i, 1).Value = Sheets("Sheet1").Cells(i + 1, 1).Value And _
    8. Sheets("Sheet1").Cells(i, 1).Value <> Sheets("Sheet1").Cells(i + 2, 1).Value Then
    9. Sheets("Sheet1").Cells(i, 2).Value = 0
    10. Sheets("Sheet1").Cells(i + 1, 2).Value = Sheets("Sheet1").Cells(i + 2, 1).Value
    11. i = i + 1 'das fehlte in Deinem Code
    12. Else
    13. Sheets("Sheet1").Cells(i, 2).Value = Sheets("Sheet1").Cells(i, 1).Value
    14. End If
    15. End If
    16. Next i
    17. End Sub

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Guten Morgen VBA-Freunde,

    ich habe noch ein weiteres Anliegen. Dieses Mal sieht die Gangfolge wie folgt aus:

    1,2,3,3,3,3,3

    Bei einer Beschleunigung soll jeder Gang mindestens zwei Sekunden lang aktiv sein und es darf kein Gang übersprungen warden.
    Also sollte es heißen:

    1,1,2,2,3,3,3

    Mein aktueller Code dazu lautet:

    Sub Gangwahl()

    Dim i As Integer

    Sheets("Sheet1").Cells(1, 2).Value = Sheets("Sheet1").Cells(1, 1).Value

    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row

    If Not IsEmpty(Cells(i, 1)) Then
    If Sheets("Sheet1").Cells(i, 1).Value + 1 = Sheets("Sheet1").Cells(i + 1, 1).Value And _
    Sheets("Sheet1").Cells(i, 1).Value > 0 And _
    Sheets("Sheet1").Cells(i, 1).Value <> Sheets("Sheet1").Cells(i - 1, 1).Value Then
    Sheets("Sheet1").Cells(i + 1, 2).Value = Sheets("Sheet1").Cells(i, 1).Value
    i = i + 1

    ElseIf Cells(i + 1, 1).Value > Cells(i, 1).Value + 1 And Cells(i, 1).Value > 0 Then
    Sheets("Sheet1").Cells(i + 1, 2).Value = Sheets("Sheet1").Cells(i + 1, 1).Value - 1
    i = i + 1

    Else: Sheets("Sheet1").Cells(i, 2).Value = Sheets("Sheet1").Cells(i, 1).Value

    End If

    End If

    Next i

    End Sub

    Leider muss da noch irgend etwas falsch sein. Ich hoffe, ihr könnt mir helfen. Danke!

    Grüße
    Bassi90
    Editier mal bitte Deine Einträge so, dass Du schreibst:
    <vb>
    Sub Gangwahl
    End Sub
    </vb>
    statt den Zeichen < und > müssen eckige Klammern, also [ und ] hin. Musste ich so kompliziert schreiben, sonst wär tatsächlich ein Codeblock rausgekommen.
    Dann muss man sich nicht mehr durch den Text durcharbeiten, um zu sehen, was noch zum Code gehört:

    Visual Basic-Quellcode

    1. Sub Gangwahl
    2. End Sub


    Zurück zum Thema:
    Es wird kompliziert, da nun auch andere, erst noch folgende Werte mitverändert werden müssen. Daher wär es spätestens jetzt sinnvoll, ein Ergebnisstring zu erzeugen, der am Ende die Daten in die Tabelle schreibt. Außerdem muss nun auch die erste Zeile wieder ausgewertet werden, da sie im gegebenen Fall auch schon zu Veränderungen führt.

    Visual Basic-Quellcode

    1. Sub Gangwahl()
    2. Dim i As Integer
    3. Dim ResultString As String
    4. Dim Counter As Integer
    5. ResultString = ""
    6. Counter = 0
    7. For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
    8. If Not IsEmpty(Cells(i, 1)) Then
    9. If Sheets(1).Cells(i, 1).Value > 0 And Sheets(1).Cells(i, 1).Value = Sheets(1).Cells(i + 1, 1).Value - 1 Then
    10. If i = 1 Then
    11. ResultString = ResultString & Sheets(1).Cells(i, 1).Value & Sheets(1).Cells(i, 1).Value
    12. Counter = Counter + 1
    13. ElseIf Sheets(1).Cells(i, 1).Value <> Sheets(1).Cells(i - 1, 1).Value Then
    14. ResultString = ResultString & Sheets(1).Cells(i, 1).Value & Sheets(1).Cells(i, 1).Value
    15. Counter = Counter + 1
    16. End If
    17. Else
    18. ResultString = ResultString & Sheets(1).Cells(i, 1).Value
    19. i = i + Counter
    20. Counter = 0
    21. End If
    22. End If
    23. Next i
    24. 'MsgBox ResultString
    25. For i = 1 To Len(ResultString)
    26. Sheets(1).Cells(i, 2).Value = Mid(ResultString, i, 1)
    27. Next
    28. End Sub

    btw: Wieviele Aufgabenstellungen kommen da eigentlich noch? Und in welcher Aufgabe fungierst Du in jenem Betrieb? Oder ist das alles reine Theorie wie Berufsschulaufgabe?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Danke VaporiZed,

    das waren jetzt nur mal ein paar Aufgabenstellungen die ich mir ausgedacht habe, um mich in die grundlegenden Befehle in VBA einzuarbeiten bzw. es zu verstehen.
    Ich frage mich nur gerade wie ich meine letzte Aufgabenstellung bewältige, wenn ich die erste Zeile leer lasse und erst dann mit der Gangfolge anfange :S

    Bassi90 schrieb:

    um mich in die grundlegenden Befehle in VBA einzuarbeiten

    puh, wenn Du meinst, dass diese Beispiele Dir weiterhelfen. Da gibt es zweifellos bessere Wege, um mit VB anzufangen.

    Bassi90 schrieb:

    wenn ich die erste Zeile leer lasse

    Da versteh ich wohl nicht, was Du meinst, denn der Code macht aus 0,2,3,3,3,3 0> 0,2,2,3,3,3 und aus 2,3,3,3,3,3 => 2,2,3,3,3,3
    Erwartest Du da noch irgendwo einen Gang 1? Wenn ja: Alles ist möglich, aber da wäre es wohl langsam sinnvoll, was komplett anderes aufzubauen. Das bisherige ist ja nur ein sehr spezifisches Regeln-Abarbeiten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.