383 Aufrufe
Gefragt in Tabellenkalkulation von
Bearbeitet von halfstone
Hallo Excelprofis

Ich kommen einfach nicht weiter und bin für jede Hilfe dankbar

Folgendes Problem, ich möchte bei das bei geöffneter Userform eine Aktualisierung der TextBox 1 anhand

der laufenden Uhr in aus Textbox 2 stattfindet ohne das dafür die Userform neu gestartet werden muss und ohne dass Tabellenblätter als Datengrundlage benutz werden. Hab schon etliche Foren und Suchfunktion benutzt ohne Erfolg. Das derzeitge Makro funktioniert insofern derzeit nur wenn man die Userfom schließt und erneut öffnet. Zugegebener Maßen beschäftige ich mich erst seit kurzem mit VBA und daher ist viles für mich Neuland.

Gruß

Detlef

Private Sub UserForm_Activate()

  Call Uhrzeit_(True)
 
End Sub

Private Sub Uhrzeit_(booStart As Boolean)

Me.Tag = IIf(booStart, "", "1")
If Me.Tag = "1" Then Exit Sub
Application.OnTime Now + TimeSerial(0, 0, 1), "'GetTime """ & Me.Name & """,""" & TextBox2.Name & """'"

    If Time > TimeValue("06:00:00") And Time < TimeValue("14:00:00") Then
        UserForm1.TextBox1 = "Frühschicht"
    ElseIf Time > TimeValue("14:02:00") And Time < TimeValue("14:08:00") Then
        UserForm1.TextBox1 = "Spätschicht"
    ElseIf Time > TimeValue("14:09:00") And Time < TimeValue("22:00:00") Then
        UserForm1.TextBox1 = "Nachtschicht"
    End If
    
    
End Sub

Private Sub UserForm_Initialize()

TextBox2 = Format(Now, "hh:mm:ss")

End Sub

13 Antworten

+1 Punkt
Beantwortet von xlking Mitglied (383 Punkte)
Bearbeitet von xlking

Hallo Delef

dazu musst du das Userform per Makro im Stil vbModeless aufrufen. Dafür einfach in einem allgemeinen Modul z.B. diesen Code verwenden:

Sub Userform_Starten()
  UserForm1.Show vbModeless
  UserForm1.UserForm_Actualize
End Sub

Sub Userform_Aktualisieren()
  If UserForm1.Visible Then
    UserForm1.UserForm_Actualize
  End If
End Sub

im Userform selbst verwendest du dann diesen Code:

Public Sub UserForm_Actualize()
  
  Dim tm As Single
  tm = Time
  
  If tm > TimeValue("06:00:00") And tm <= TimeValue("14:00:00") Then
      If TextBox1 <> "Frühschicht" Then TextBox1 = "Frühschicht"
  ElseIf tm > TimeValue("14:00:00") And tm <= TimeValue("22:00:00") Then
      If TextBox1 <> "Spätschicht" Then TextBox1 = "Spätschicht"
  ElseIf tm > TimeValue("22:00:00") Or tm <= TimeValue("06:00:00") Then
      If TextBox1 <> "Nachtschicht" Then TextBox1 = "Nachtschicht"
  End If
  
  TextBox2 = Format(tm, "hh:mm:ss")
  
  Application.OnTime Now + TimeSerial(0, 0, 1), "Userform_Aktualisieren"
End Sub

Die Codezeile If Textbox1 <> "Frühschicht" Then TextBox1 = "Frühschicht" sorgt dafür dass, der Text in der Textbox1 nicht jede Sekunde neu gezeichnet wird, sondern nur, wenn er wechselt. Dadurch läuft der Code schneller und das Bild flackert nicht.

Im Stil vbModeless kannst du (zumindest größtenteils) ganz normal weiterarbeiten während dein Formular im Hintergrund läuft.

Falls du weitere Fragen hast meld dich einfach.

Gruß Mr. K.

0 Punkte
Beantwortet von
Hallo Mr.K

Vielen Dank für Deine schnelle Rückmeldung und die guten Erklärungen. Ich habe den Code unfunktioniert, damit dieser über einen CommandButton aktiviert wird. Hintergrund ist, dass ich mich gerade an einem Projekt für unsere

Arbeit versuche, welches mehrer Userformen, Labels Textboxen besitzt.

So habe ich gestern noch versucht die automatische Aktualisierung, in einem anderen Code einzubringen.

Sub MR1()
    
    Dim i As Integer
    Dim AusgewaehlteMilkrun As String

    Dim ZeitenMilkrunTxt As String
    ZeitenMilkrunTxt = "06:10,06:50,08:10,08:50,09:40,10:20,11:00,11:40,12:40,13:20,14:10,15:30,16:50,18:30,19:50,21:30,22:50,00:10,01:50,03:10,04:50"

    Dim ZeitenMilkrun As Variant
    ZeitenMilkrun = Split(ZeitenMilkrunTxt, ",")

    Dim TempDatumMitZeit, TempAktuelleZeit, TempMilkrunTime, TempMilkrunNextTime, MindstZeitAbstand  As Date

    'Mindestens Zeitabstand 5 Minutes
        MindstZeitAbstand = TimeSerial(0, 5, 0)

    TempDatumMitZeit = Now()
    TempAktuelleZeit = TimeSerial(Hour(TempDatumMitZeit), Minute(TempDatumMitZeit), Second(TempDatumMitZeit))
   
    AusgewaehlteMilkrun = ZeitenMilkrun(0)

    'Jede 'Zeile' der ZeitenMilkrun
    For i = 0 To UBound(ZeitenMilkrun) - 1 '-1 weil die nächste Position wird in der Funktion benutzt

        'in Type Time umwandeln
            TempMilkrunTime = TimeSerial(Split(ZeitenMilkrun(i), ":")(0), Split(ZeitenMilkrun(i), ":")(1), 0)
            TempMilkrunNextTime = TimeSerial(Split(ZeitenMilkrun(i + 1), ":")(0), Split(ZeitenMilkrun(i + 1), ":")(1), 0)

        
            
            
            If TempAktuelleZeit >= CDate(TempMilkrunTime - MindstZeitAbstand) And TempAktuelleZeit <= CDate(TempMilkrunNextTime - MindstZeitAbstand) Then
                AusgewaehlteMilkrun = ZeitenMilkrun(i + 1)

                Exit For
            End If

    Next i

'Milkrun Anzeigen
    Label64.Caption = AusgewaehlteMilkrun
    

End Sub

Und zwar in diesen. Allerdings hab ich das nicht hinbekommen, da hier dan die Fehlermeldung nicht ausreichender Stapelspeicher kommt. Warscheinlich laufen dann zu viele Routinen im Hintergrund.

Ziel diese Makros soll sein, dass die oben angegeben Zeiten sich im Label64 bei geöffneter Userform ebefalls

automatisch aktualisieren. Dies funktioniert in diesem Zustand aber nicht, sondern nur wenn die UserForm geschlossen und wieder geöffnet wird. Es müsste doch eigentlich auch möglich sein, die komplette Userform über eine Zeischiene zu aktualisiere, so dass die Label und Textboxen gleich mit neu eingelesen sind.

Mit Me.Repaint und Logistik.Repaint hab ich es versucht, geht aber irgenwie nicht. Noch zur Info die UserForm mit Namen Logistik um welche es hier geht, soll nur als Anzeige dienen. Das einzige was im Prinzip dann geändert wird, ist der Status in ComboBoxen von offen auf erledigt.mit Farbe Rot und Grün je nach Status. Jedoch ist das ein anderes Thema, genauso wie die Userformen zum Teil von einer Access - Datenbank gefüttert

werden.

Gruß

Detlef
0 Punkte
Beantwortet von xlking Mitglied (383 Punkte)
Hallo Detlef,

Dazu kann ich leider nicht allzuviel sagen, da ich dein Projekt nicht sehe. Leider hab ich auch kein Access, sodass ein Hochladen der Datei ausscheidet. Du müsstest also schon den ganzen Code posten oder als Textfile hochladen damit man dem Problem von extern auf den Grund gehen kann.

Das von dir gezeigte Codeschnipsel MR1 ist erstmal in Ordnung. Da sehe ich auf den ersten Blick keinen Fehler. Die Fehlermeldung "nicht ausreichender Stapelspeicher" deutet im allgemeinen darauf hin, dass an irgendeiner Stelle ein Code sich selbst aufruft ohne vorher über End Sub ordentlich beendet worden zu sein. Das passiert im allgemeinen bei Ereignissen, die ausgelöst werden, wenn ein bestimmter Befehl ausgeführt wird. z.B bei einem Textbox_Change-Ereignis welches einen Befehl ausführt, der den Text in dieser Textbox ändert. Sowas kannst du verhindern indem zu z.B. in Excel vor Ausführen des Befehls Application.EnableEvents = False setzt. Vergiss nicht das direkt nach dem Befehl wieder auf True zu setzen, sonst wird das Ereignis gar nicht mehr ausgeführt.

Da bleibt dir wohl nix anderes übrig als den Code ordentlich zu debuggen. Geh dazu einfach mal im Einzelschritt (also mit F8) alles durch. Um innerhalb von Ereignissen in den Einzelschritt zu wechseln kannst du ja Haltepunkte setzen oder vorübergehend den Befehl Stop einfügen.

Mehr fällt mir für den Moment erstmal nicht ein.

Gruß Mr. K.
0 Punkte
Beantwortet von d-lin Einsteiger_in (11 Punkte)
Bearbeitet von d-lin
Hallo Mr.K

Also ich wollte Dir nur mitteilen, das sich jetzt der Codeschnipsel (Makro MR1) wie oben eingefügt, automatisch in der UserForm aktuallisiert und ich das Makro zum laufen bekommen habe. Habe es anhand Deines Codes hinbekommen und ich spare mir dadurch etliche Codezeilen. Somit ist es dann auch einfacher, die Eingaben zu
ändern, da im Makro nur die Reihe der Zeitangabe geändert werden muss, sonst nichts. Hast mir damit sehr weiter geholfen, vielen Dank nochmal.

Gruß

Detlef
0 Punkte
Beantwortet von xlking Mitglied (383 Punkte)
Hi Detlef,

ich bin am Überlegen, wie ich dir hier noch weiterhelfen kann. Eigentlich hab ich ja schon alles Wichtige gesagt: Mit vbModeless kannst du halt das Formular ungebunden aufrufen. Das heißt der Code läuft nach dem .Show Befehl weiter und wartet nicht auf Formular-Eingaben des Nutzers.

Wenn du darüber hinaus weitere Formulare aufrufen willst, während das erste noch läuft, ist allerdings Vorsicht geboten. Einerseits sollte das Unterformular dann möglichst ebenfalls ungebunden sein. Andererseits macht Windows das nicht immer mit. Bei mir (Windows 11 und Excel 2019) funktioniert das zwar problemlos aber in früheren Versionen kam es auch schon mal zu PC-Abstürzen.

Sicher geht das auch einfacher. Aber wenn der Code erstmal funktioniert, ist es ja auch gut. Du solltest allerdings darauf achten, dass ein Timer erst neu gesetzt wird, nachdem ein anderer Timer bereits abgelaufen ist, sonst hast du irgendwann zu viele Timer gleichzeitig laufen, was dich wiederum am Arbeiten hindert. Auch das kann zum Absturz führen.

Deine weitere Frage verstehe ich nicht so ganz. Du hast doch bereits in deinem ersten Code gezeigt, dass du in der Lage bist, die Angaben des Unterformulars auf das Hauptformular zu übertragen. Dazu einfach  im Click-Ereignis des Buttons den Befehl Logistik.Textbox1 = Bestellung.Textbox1 machen. Dazu muss das Formular Logistik natürlich weiterhin aktiv sein. Wenn du z.B. das Hauptformular vorübergehend ausblendest, anstatt zu schließen (kannst mit Me.Hide machen) kannst du vom SubFormular oder aus dem Codemodul heraus weiterhin auf die Daten zugreifen.

Damit die Daten auch nach dem Schließen noch verfügbar sind, musst du sie irgendwo zwischenspeichern. Am besten direkt in deiner Datenbank. Wenn du das nicht willst, kannst du auch im Modulkopf (also vor der ersten Sub) ein paar Variablen definieren, denen du die Daten zuweist.

Visuell macht dein Projekt auf jeden Fall etwas her. Wusste gar nicht, dass man in Steuerelementen von VBA-Formularen auch abgerundete Ecken machen kann. Dachte das ginge nur in HTML.

Gruß Mr. K.
0 Punkte
Beantwortet von d-lin Einsteiger_in (11 Punkte)
Bearbeitet von d-lin
Hallo Mr.K

Danke für Deine Hilfe und guten Antworten. Alle UserFormen in meinem Projekt, werden nicht in den HideModus versetzt, sondern mit unload beendet, bevor die nächste geöffnet wird, auch wenn man wieder zurück wechselt. Somit scheidet ein Textbox_Change warscheilich  von zB UserformTextBox nach UserForm2TextBox aus. Wird dann nur über die Accesdatenbank gehen. Mal sehen wie ich das hinbekomme. da immer ganz bestimmte TextBoxen in der LogistikForm angesprochen werden müssen.

Aberundete Ecken geht auch nicht, so ohne Weiteres in VBA., was Du sieht sind in Excel erstellte Grafiken welche dann von png .nach gif umgewandelt wurden., da VBA wohl kein png kennt. Anschließend mit dem Bildsteuerelement in die UnserForm eingefügt, und dann auf Transparent gesetzt. TextBoxen und das Andere drauf gepackt, alles gruppiert und fertig.

Trotz der Grafiken und einem Intro was ich heute eingebunden habe, ist die Datei mit ca 6,5 MB noch sehr moderat. Ürigens arbeite ich auch mit Win 11 allerdings dann mit Office365. Probleme hatte ich noch keine.

Gruß

Detlef
0 Punkte
Beantwortet von

Hallo Mr.K

vieleicht kannst Du mir ja doch noch einmal Hilfestellung geben. Folgender Ausgangspunkt.

nach Benutzen der UserForm Bestellung, werden beim Speichern die Daten fortlaufend in die Accesdatenbank geschrieben. Soweit alles kein Problem. Beim Öffnen meines Projektes, wird die Datenbank gelesen und nach

Excel in die Arbeitsmappe eingelesen. siehe Screenshot

nun sollen diese Daten in TextBoxen angezeigt werden in der UserForm Logistik, wenn diese geöffnet ist und sich bei neuer Eingabe in der UserForm Bestellung auch automatisch in der geöffnetten UserForm Logistk aktualisieren. So soll es aussehen

Das Problem dabei ist, dass wenn die TextBoxen links mit Werten belegt sind, das Programm die Werte dann in die rechten TextBoxen eintragen soll. und umgekehrt genauso, wenn rechts belegt dann Werte nach links.In den Comboboxen sollen dann 2 Bedingen stehen (offen rot hinterlegt und erledigt,grün hinterlegt). Wenn dann erledigt ausgewählt wird, müssen die Textboxen für die nächste Abfrage geleert werden.

Bedingung ist: Wenn aktueller Wert in Spalte K = TN, dann in TexBox_X aktueller Wert aus Spalte I und in TextBox_Y der aktuelle Wert aus Spalte E sowie TextBox_Z aktueller Wert aus Spalte D, wobei das Datum dann durch eine Zeitangabe ersetzt wird.(Muss in der DatenBank noch angepasst werden)

Habe schon einiges versucht, bekomme das aber irgenwie nicht gebacken. Vieleich hast Du ja eine Lösung dafür..

Gruß

Detlef

+1 Punkt
Beantwortet von xlking Mitglied (383 Punkte)

Hallo Detlef,

Leider komme ich erst jetzt dazu dir zu antworten, da ich nicht so oft online bin. Das ist ja eine ganze Reihe von Fragen. Lass uns die mal Stück für Stück analysieren:

nach Benutzen der UserForm Bestellung, werden beim Speichern die Daten fortlaufend in die Accesdatenbank geschrieben. Soweit alles kein Problem. Beim Öffnen meines Projektes, wird die Datenbank gelesen

OK, das ist eine wichtige Info für die folgenden Schritte

nun sollen diese Daten in TextBoxen angezeigt werden in der UserForm Logistik, wenn diese geöffnet ist und sich bei neuer Eingabe in der UserForm Bestellung auch automatisch in der geöffneten UserForm Logistk aktualisieren.

Dazu musst du zunächst die Excelliste aktualisieren. Der einfachste Weg das zu erreichen ist folgender: Wenn du die Daten über das Form Bestellung in die Accessdatenbank schreibst, brauchst du dazu nur am Ende dieses Makros einen Befehl aufrufen, der das ÖffnenMakro aufruft. Dieses sollte dabei möglichst nicht direkt im Workbook_Open Makro stehen, sondern als separate Sub-Prozedur in einem allgemeinen Modul.

Beispiel:
Modul DieseArbeitsmappe:

Private Sub Workbook_Open()
  Call BeimOeffnen
End Sub

allgemeines Modul (z.B. Modul1)

Sub BeimOeffnen()
  'Dein Code zum Laden aus der AccessDatenbank
  MsgBox "Datei wurde geöffnet"
End Sub

Formular Bestellung

Sub CommandButton1_Click
  'Dein Code zum Import in die Access-Datenbank
  Call BeimOeffnen
End Sub

Das Problem dabei ist, dass wenn die TextBoxen links mit Werten belegt sind, das Programm die Werte dann in die rechten TextBoxen eintragen soll. und umgekehrt genauso, wenn rechts belegt dann Werte nach links.

Am einfachsten wäre es, hier über das Change-Ereignis der Textboxen zu gehen. Aber Achtung, damit erzeugst du eine Dauerschleife. Wenn das Change-Ereignis der linken Textbox die rechte aktualisiert, und diese ebenfalls ein Change-Ereignis besitzt, welche wiederum die linke aktualisiert. Das kannst du nur über eine Variable mit beliebigem Namen umgehen, die du ganz oben im Codefenster noch vor der ersten Prozedur definierst. z.B.:

Dim tbxchg As Boolean
Private Sub TextBox1_Change()
  If tbxchg = False Then
    tbxchg = True
      TextBox2 = TextBox1
    tbxchg = False
  End If
End Sub

Private Sub TextBox2_Change()
  If tbxchg = False Then
    tbxchg = True
    TextBox1 = TextBox2
    tbxchg = False
  End If
End Sub

In den Comboboxen sollen dann 2 Bedingen stehen (offen rot hinterlegt und erledigt,grün hinterlegt). Wenn dann erledigt ausgewählt wird, müssen die Textboxen für die nächste Abfrage geleert werden.

Das geht nicht. Du kannst die Liste in der Combobox nicht anders formatieren als die Combobox selbst. Und wenn doch dann nur gleichartig für alle Einträge. Aber wenn du einen Eintrag auswählst, kannst du das Layout der Combobox ändern:

Private Sub UserForm_Initialize()
  ComboBox1.ListStyle = fmListStyleOption
  ComboBox1.AddItem "offen"
  ComboBox1.AddItem "erledigt"
End Sub

Private Sub ComboBox1_Change()
  If ComboBox1 = "offen" Then
    ComboBox1.BackColor = RGB(255, 0, 0)
  ElseIf ComboBox1 = "erledigt" Then
    ComboBox1.BackColor = RGB(0, 255, 0)
    TextBox1 = ""
    TextBox2 = ""
  End If
End Sub

Bedingung ist: Wenn aktueller Wert in Spalte K = TN, dann ...

Was meinst du mit aktuellem Wert? Ich kann in deiner Tabelle keine Uhrzeit finden. Wie ermittelst du die Daten für deine Textboxen? Den Packsatz musst du vermutlich erst berechnen, da du Text und Zahl in einer Spalte stehen hast: aus PN 4041 wird dann Textbox1 = Right(cells(zeile, 9), 4)  Zeile ist dabei die Variable wo du die Zeile des aktuellen Datensatzes hinterlegst. Das geht aber nur, wenn alle Daten gleich aufgebaut sind. In deinem Beispiel weicht I5 von den übrigen Daten in Spalte I ab. Solltest du beachten.

Gruß Mr. K.

0 Punkte
Beantwortet von
Bearbeitet

Hallo Mr.K

Erst einmal vielen Dank für Deine Rückmeldung.

So jetzt  noch ein paar Infos, das farbige Hinterlegen der Comboxen, habe ich zwischenzeitlich schon rausgefunden und ist erledigt, trotzdem danke ich Dir für den Codeyes

Jetzt zum Thema:

               Über die UserForm werden bei der Bestellung die Daten aus der Accesdatenbank geholt

                                                

Nach drücken des Buttons Bestätigen, wird die Bestellung in der Datenbank gespeichert und die UserForm geschlossen. Gleichzeitig wird ein ClearContens Event ausgeführt, wobei sich die Exceltabelle sofort aktualisiert.

Hier der Codeabschnitt dazu:       Cells.ClearContents
                                                 Dim TempList As Variant
                                                 TempList = ListOffeneBestellungen
                                                 Call ListOffeneBestellungen
                                                 Unload Me

ist nur der letzte Teil des Codes, aber die Aktualisierung ist schon vorhanden und funktioniert. Das alles ist nicht das Problem.

Das ist mein Problem:crying

Zum besserem Verständnis: in der Tabelle steht in Spalte K die Anlage zb: CP1  diese hat wiederum die ID 1 welche in Spalte J steht und in der Accessdatenbank als ID 1  abgefragt wird. Die 15 welche Du erwähnt hast ist die ID für TN, ich danke mal das ist für Dich vieleicht jetzt besser zu verstehen.

So insgesamt gibt es 17 Anlagen mit demzufoge 17 ID Nummern in der Datenbank. Mit folgendem Code bekomme ich die linke Seite der UserFormtextboxen gefüllt, allerdings fragt er hier die letzte Zeile ab, was in dem Fall nicht zu gebrauchen ist, Erklärung weiter unten.

  so sieht es dann aus

Das Problem was sich ergiebt ist, dass ja beide Bestellungen die gleiche ID besitzen, in dem Fall die 1.

Was ich möchte ist, das z.B über die ID 1 Spalte (J) oder den Anlagennamen CP1 Spalte (K) die benötigten Werte Spalte I, in TextBox1, Spalte E in TextBox2, und Spalte D in TextBox3 aus der letzten Zeile der Tabelle mit ID 1 und die nächte Zeile mit der ID 1 in Textbox 4 , 5  und  6

abgefragt und angezeigt werden ohne das ein automatisches Überschreiben der TextBoxen stattfindet, sondern die Aktualisierung hier vom Benutzer über einen Button oder ahnlichem durchgeführt werden muss (Click Textboxen leeren und neu füllen).

Da aber zwischen den Bestellungen andere ID Nummer sein können/werden, wie zb ID 1, ID 15, ID 15, ID1

muss eine Abfage stattfinden, welche immer die letzten beiden Bestellungen der gleichen ID ermittelt.

Ich habe bisher keinen Plan, wie das gehen oder wie ich das machen soll.crying

Vieleicht ist das Ganze jetzt etwas verständlicher für Dich.

04:00 Uhr jetzt aber in die Heiawink

Bis denn Gruß

Detlef

0 Punkte
Beantwortet von xlking Mitglied (383 Punkte)

Hi Detlef,

sorry, dass ich dich hier ein bisschen schmoren lassen muss. Hab grad viel um die Ohren. Und dann ist da noch der Haushalt. Du kennst das ja sicher. Kaum ist man hinten fertig, fängt man vorne wieder an. Wäre schön, wenn man dafür auch mal ein Makro schreiben könnte. smiley

Dass die AnlagenID in Spalte J und der Anlagenname in Spalte K zusammengehören hab ich soweit verstanden. Der Rest ist aber immer noch nicht ganz klar. Liegt wohl daran, dass du dir oft selbst widersprichst. Mal willst du in den Textboxen 4, 5 und 6 die nächste Zeile nach der letzten Zeile sehen. Dann aber doch die letzten beiden Bestellungen mit der gleichen ID. Ich vermute daher, das du mit nächster Zeile den vorletzten Datensatz meinst, der die gleiche ID wie in der letzten Zeile hat. Das passt aber nicht zu dem Screenshot aus deinem vorherigen Post wo auf einem Formular zwei Packsätze von unterschiedlichen Anlagen dargestellt werden. Und was du nun von links nach rechts und von rechts nach links kopieren willst ist mir auch schleierhaft, wenn du doch die Daten per Button-Click aus der Tabelle ziehst.

wenn es dir also nur darum geht, den vorletzten Datensatz zu ermitteln, der die gleiche ID, wie der letzte trägt, so kannst du das entweder per Schleife oder mit Range.Find machen:

Sub Füllen()
  
  Dim letzterDS As Range, vorletzterDS As Range, ID As Long, x As Range
  
  letzterDS = Sheets("Temp").Cells(Rows.Count, "J").End(xlUp).EntireRow
  ID = letzterDS.Cells(1, "J")
  Set x = Sheets("Temp").Range("J:J").Find(ID, Searchdirection:=xlPrevious)
  If Not x Is Nothing Then Set x = Sheets("Temp").Range("J:J").FindPrevious(x)
  If Not x Is Nothing Then Set vorletzterDS = x.EntireRow
  
  Textbox1 = letzterDS.Cells(1, "I")
  Textbox2 = letzterDS.Cells(1, "E")
  Textbox3 = letzterDS.Cells(1, "B")
  Textbox4 = vorletzterDS.Cells(1, "I")
  Textbox5 = vorletzterDS.Cells(1, "E")
  Textbox6 = vorletzterDS.Cells(1, "B")
  
End Sub

Warum du in deinem Code jedoch eine Schleife durchläufst, wenn du dann doch immer nur auf die letzte Zeile zurückgreifst bleibt mir ein Rätsel. Auch ist deine Bedingung falsch. Du liest die .Row also die Zeilnr. eines jeden Datensatzes ab und ziehst davon dann 1 ab. Im Fall der Zeile 1 ergibt das 0. Du vergleichst also ob 0 <> "" ist. Das kann zu einem Laufzeitfehler "Typen unverträglich" führen.

Gruß Mr. K.

...