1.8k Aufrufe
Gefragt in Tabellenkalkulation von

Hallo alle miteinanderwink

Ich bin hier im Forum eh auch schon alle Beiträge die irgendwie mit meinen Problem zusammen hängen durch gegangen und getestet aber ich finde den Fehler einfach nicht angry

Kurzerklärung. Die Datei wird geöffnet -> mit UserForm1.Show -> mit "Ja" bestätigt und mit Sub Mail() soll er den ganzen Code auf jedes TB ausführen. Nur irgendwie macht er das nicht er macht es immer nur für das akutelle TB angry wenn ich die Sub Mail() in jedem TB manuell aufrufe dann macht er es frown


Private Sub Workbook_Open()
UserForm1.Show
End Sub


Private Sub CommandButton1_Click()
Application.Run "Mail"
End Sub


Private Sub Mail()

Dim Zeile As Long
Zeile = 1
Check (Zeile)  'Sprung in den Aufruf Check()

End Sub

Private Sub Check(ByVal Zeile As Long)
    Dim WS As Worksheet
    Dim Urgenz1 As String
    Dim Urgenz2 As String
    Urgenz1 = "x"
    Urgenz2 = "x"
    Dim i As Long
    
    For Each WS In ThisWorkbook.Worksheets 'alle Tabellenblätter durchlaufen
    
    Const xlUp As Long = &HFFFFEFBE
    Debug.Print CStr(Cells(Rows.Count, 1).End(xlUp).Row) 
      
    For i = Zeile + 1 To Cells(Rows.Count, 1).End(xlUp).Row
        If (CDate(Cells(i, 7).Value) < DateTime.Date) And (CStr(Cells(i, 13).Value) = "x") Then ' Wenn Spalte "G" Datum = heutiges Datum & Spalte "M" auf "Leer" Dann
        'MsgBox "Email schon geschickt", vbInformation, "Fertig" 'Message Box als Hilfe stellung

        ElseIf (CDate(Cells(i, 7).Value) < DateTime.Date) And (CStr(Cells(i, 13).Value) = vbNullString) Then 'Wenn Spalte "G" Datum = heutiges Datum & Spalte "M" auf "Leer" Dann
            Cells(i, 13).Value = Urgenz1 'Füge Urgenz1 in Spalte M
            Call Send_Email(i)  'Aufruf Prozedur "Send_Email()"
        End If
        
        If (CDate(Cells(i, 8).Value) < DateTime.Date) And (CStr(Cells(i, 14).Value) = vbNullString) Then 'Wenn Spalte "H" Datum = heutiges Datum & Spalte "N" auf "Leer" Dann
            Cells(i, 14).Value = Urgenz2 'Füge Urgenz2 in Spalte N
            Call Send_Erinnerung(i)  'Aufruf Prozedur "Send_Erinnerung" 
        End If
    Next i
'    Call MsgBox("Fertig!", vbOKOnly)
    Next WS
End Sub


Kann mir bitte wer sagen was ich falsch mache und wo der verdammte Fehler ist cheeky. Bin echt schon am verzweifeln devil

Über dringende Hilfe wäre ich sehr dankbar.

LG SnowWhite

75 Antworten

0 Punkte
Beantwortet von snowwhite Mitglied (121 Punkte)

Hallo M.O.,

Kein Problem wink fürs Testen bin ich ja da laugh Das heißt dann quasi 

wksL.Cells(Wiederholungen, 2).Value

Du kannst ja per Code auf den Inhalt aller Zellen in jeder Tabelle zugreifen (auslesen, in andere Zellen kopieren etc; deshalb auch meine Verwunderung mit deinen Variablen Urgenz -siehe oben).

Mit "Value" = Liest du Inhalte aus, kopierst gleichzeitig mit "Value" und weißt aber auch gleichzeitig Inhalte zu?
Mir hätte da irgend ein Befehl gefehlt wink. Vielleicht irritiert mit auch die Komische Variable"Wiederholung" das kommt davon wenn man Fremde "Code" verwendet frown

Die "Urgenz" lässt dich nicht so wirklich los wink

Dann schau mal, was in Tabelle2 in Zelle A1 steht. Das ist genau das selbe Prinzip, wie ich es für das Kopieren des Städtenamens in das neue Tabellenblatt nutze.

Hat funktioniert wink ok es ist ein reines "Copy & Paste" quasi ? Soviel dazu "Halte den Code kurz wink)

Und bzgl 

Natürlich kannst du nach dem Anlegen auch die Spalten A und B löschen, dann musst du aber auch das Check-Makro ändern, da hier die Namen der neu angelegten Tabellenblätter aus dem Tabellenblatt "urliste" genutzt werden, um diese zu durchlaufen. Die Spalte B könnte man ohne Probleme löschen. Vielleicht reicht es auch aus, die Schriftfarbe in Spalte A in Weiß zu ändern oder das ganze Tabellenblatt auszublenden, da es ja nur für das Anlegen der neuen Tabellen genutzt wird.

Muss ich die ganze Sub Check Ändern ?

GLG SnowWhite

0 Punkte
Beantwortet von m-o Profi (22.8k Punkte)

Hallo SnowWhite,

zum Kopieren: Ich sage ihm einfach, er soll den Inhalt der einen Zelle in eine andere Zelle übertragen. Das ist genauso, wie wenn du in Zelle B1 die folgende Formel schreibst: =A1 Nur eben in VBA. Und die Variable Wiederholung gibt hier nur die Zeile an.

Im Check-Makro sollen ja nur die neu angelegten Tabellenblätter überprüft werden. Deshalb hatte ich ja zu Beginn nachgefragt, ob die Namen in der Tabelle urliste erhalten bleiben.

Du hattest ja geschrieben:

Die Namen ändern sich "Liste1" usw ist jetzt nur ein Test-Text (für mich)  blush die Namen legen dann die Mitarbeiter fest aus denen dann die TB generiert werden! Aber JA die Namen bleiben im TB "urliste" (hoffe der Name "urliste" wird nicht geändert cheeky) und auf alle Fälle "fix"  in der "Spalte A" dauerhaft.

Wenn die Mitarbeiter die Namen frei wählen können und diese bleiben nicht gespeichert, musst du dir überlegen, wie du nur die neu angelegten Tabellenblätter prüfst.

Wenn die Namen unbedingt aus der Tabelle urliste gelöscht werden sollen, dann würde ich beim Anlegen der Tabellen die Namen der neu anzulegenden Tabellenblätter in ein ausgeblendetes Tabellenblatt schreiben und dann darauf zugreifen. Wenn du das Tabellenblatt mit

ActiveSheet.Visible = xlVeryHidden

ausblendest, dann kann es auch nur per VBA wieder eingeblendet werden. Dann bräuchte man im Check-Makro nur den Namen der Tabelle ändern, aus der die zu prüfenden Tabellenblätter eingelesen werden. Ansonsten müsstest du beim Durchlauf der Tabellenblätter z.B. alle Tabellenblätter, die nicht geprüft werden sollen, aufzählen und so ausschließen, dass das Check-Makro hier ausgeführt wird.

Gruß

M.O.

0 Punkte
Beantwortet von snowwhite Mitglied (121 Punkte)

Guten Morgen M.O.

zum Kopieren: Ich sage ihm einfach, er soll den Inhalt der einen Zelle in eine andere Zelle übertragen. Das ist genauso, wie wenn du in Zelle B1 die folgende Formel schreibst: =A1 Nur eben in VBA. Und die Variable Wiederholung gibt hier nur die Zeile an.

Aha ok jetzt ist da der Knopf bei mir auch aufgegangen wink vielen Dank für die Unterrichts Stunde laugh

Die Namen ändern sich "Liste1" usw ist jetzt nur ein Test-Text (für mich)  blush die Namen legen dann die Mitarbeiter fest aus denen dann die TB generiert werden! Aber JA die Namen bleiben im TB "urliste" (hoffe der Name "urliste" wird nicht geändert cheeky) und auf alle Fälle "fix"  in der "Spalte A" dauerhaft.

Ja das war auch so geplant aber es wird ständig alles umgeworfen angry So wie mit dem Spalten raus löschen devil
 

Wenn die Namen unbedingt aus der Tabelle urliste gelöscht werden sollen, dann würde ich beim Anlegen der Tabellen die Namen der neu anzulegenden Tabellenblätter in ein ausgeblendetes Tabellenblatt schreiben und dann darauf zugreifen. Wenn du das Tabellenblatt mit

Das heißt wenn ich dich jetzt richtig verstanden habe, Sollen die Spalten Inhalte von der "urliste" mit dem aktivieren des Button in ein verstecktes TB z.B. mit den Namen "Test" kopiert werden und in der "Sub Check" ändere ich nur den TB Namen gegen die "urliste" ?

ActiveSheet.Visible = xlVeryHidden

Die Zeile macht was ? bzw in welche Sub gehört die ?

GLG  SnowWhite

0 Punkte
Beantwortet von m-o Profi (22.8k Punkte)

Hallo SnowWhite,

lege das Tabellenblatt Test an und kopiere die beiden folgenden Makros in ein allgemeines Modul:

Sub test_ausblenden()
  ThisWorkbook.Worksheets("Test").Visible = xlVeryHidden
End Sub

Sub test_einblenden()
  ThisWorkbook.Worksheets("Test").Visible = True
End Sub

Führe dann das Makro test_ausblenden aus. Natürlich kannst du auch nur das Ausblenden-Makro in die Datei schreiben und nach dem Ausblenden löschen. Das ausgeblendete Tabellenblatt taucht nicht bei ausgeblendete Tabellenblätter auf (über die rechte Maustaste) und kann nur per VBA wieder eingeblendet werden.

Ändere das Makro für das Anlegen der neuen Blätter wie folgt:

Sub Anlegen()
Dim Wiederholungen As Long
Dim wksL As Worksheet
Set wksL = Worksheets("urliste")
Application.ScreenUpdating = False
wksL.Activate

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

If Cells(Wiederholungen, 1) <> vbNullString Then
    'Name des neu angelegten Tabellenblatts wird in versteckte Tabelle geschrieben
    Worksheets("Test").Cells(Wiederholungen, 1) = wksL.Cells(Wiederholungen, 1)
    Worksheets("Leer").Copy After:=Sheets(Sheets.Count) 'Tabellenblatt "Leer" wird kopiert
    With ActiveSheet
      'Neues Blatt umbenennen
      .Name = wksL.Cells(Wiederholungen, 1).Text 'Als TB Name des neu erstellten TB wird der Name aus der aktiven Zelle genommen von TB urliste.
      .Range("O2:O50") = wksL.Cells(Wiederholungen, 2).Value
    End With
  'Einträge in Tabelle urliste löschen
   With wksL
    .Range(.Cells(Wiederholungen, 1), .Cells(Wiederholungen, 2)).ClearContents
   End With
    
Else
Exit Sub
End If
wksL.Activate
Next

Set wksL = Nothing

Application.ScreenUpdating = True
End Sub

Ich gehe mal davon aus, dass das Anlegen der neuen Tabellenblätter nur einmal pro Datei erfolgt.

Dann musst in deinem Check-Makro nur den folgenden Teil ändern:

 'Namen der neu angelegten Tabellenblätter aus versteckter Tabelle einlesen
    With Worksheets("Test")
            arrTabellen = .Range(.Cells(1, 1), .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, 1))
    End With

Dann sollte alles funktionieren.

Gruß

M.O.

0 Punkte
Beantwortet von snowwhite Mitglied (121 Punkte)

Hallo M.O.,

Vielen lieben Dank für deine Rückmeldung. Du bist echt ein Schatz angel
Soweit war es für mich auch Verständlich und es hat auch alles super funktioniert wink

Sieht so aus als wärst du mich jetzt endlich los cheeky Was bin ich dir Schuldig blushlaugh!!! (Fürn Kaffee bist wahrscheinlich zu weit weg !)
Hat aber Spaß gemacht mit Dir zu programmieren und ich hab neue Programmier-Schiene gelernt wink 
Steige vielleicht doch wieder in die Programmierung ein cheeky.
Ich danke dir mal vorerst sehr Herzlich -> Ich leg dem Projekt Leiter das heute mal so vor smiley

Hab tausend Dank für Deine Hilfe.
GLG SnowWhite

P.s Was programmierst du noch ? bzw in welchen Programmiersprachen bist du so unterwegs ?

0 Punkte
Beantwortet von m-o Profi (22.8k Punkte)

Hallo SnowWhite,

Sieht so aus als wärst du mich jetzt endlich los cheeky 

Na endlich!! laughdevil.

Spaß beiseite, schuldig bist du mir nichts. Ich mache das hier aus Spaß smiley. Da ich beruflich viel mit Office - und hier hauptsächlich mit Excel - arbeite, programmiere ich nur VBA.

Und falls du bei der VBA-Programmierung bei Excel mal Hilfe brauchst, dann weißt du ja wo du fragen kannst wink.

Gruß

M.O.

0 Punkte
Beantwortet von snowwhite Mitglied (121 Punkte)

Hallo M.O.

Na endlich!! laughdevil.

Na Super das hab ich jetzt davon laughwink Na freu dich nicht zu früh blush ich warte noch auf die Rückmeldung angel.
Ok also bist du dann Quasi nur der reine VBA Excel Professionalist! Ok wink 
Na dann weiß ich wo und an wem ich mich wende wenn ich wieder mal hänge cheeky
 

Noch einmal vielen lieben Dank für deine Hilfe

GLG SnowWhite

0 Punkte
Beantwortet von snowwhite Mitglied (121 Punkte)
Bearbeitet von snowwhite

Guten Abend  M.O.

Ich hab doch gesagt "nicht zu früh freuen"  sad
Komischerweise hat es vor der Übergabe noch bei mir funktioniert angel

Er hängt in der " in der Sub "Schlüssel_Daten_löschen bei dem Punkt

  For t = LBound(arrTabellen) To UBound(arrTabellen) 
      With ThisWorkbook.Worksheets(arrTabellen(t, 1)) 

mit der Debug Meldung "laufzeitfehler '13' Typen unverträglich 
Kannst du mir die beiden Zeilen bitte noch einmal erklären ?blush

Dann musst in deinem Check-Makro nur den folgenden Teil ändern:

 'Namen der neu angelegten Tabellenblätter aus versteckter Tabelle einlesen
    With Worksheets("Test")
            arrTabellen = .Range(.Cells(1, 1), .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, 1))
    End With

Bei der Sub "Schlüssel_Daten_löschen" Bei der "With Worksheets" muss ich auch die "urliste" gegen das "Test" TB austauschen ?

GLG SnowWhite

0 Punkte
Beantwortet von m-o Profi (22.8k Punkte)

Hallo SnowWhite,

in der Tabelle von dir, die ich habe, kommt in der Sub Schlüssel_Daten_löschen die Zeile gar nicht vor. Wenn du aber auch hier die angelegten Tabellen ausgelesen hast, dann musst du natürlich auch hier auf das versteckte Arbeitsblatt zugreifen, d.h. in der With-Anweisung die "urliste" gegen "Test" austauschen.

'Namen der neu angelegten Tabellenblätter aus versteckter Tabelle einlesen
    With Worksheets("Test")
            arrTabellen = .Range(.Cells(1, 1), .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, 1))
    End With

Wie in der Erläuterung bereits beschrieben werden hier die Namen der neu angelegten Tabellen in ein Array / Datenfeld eingelesen. Natürlich könnte man auch Zeile für Zeile die Namen aus der Tabelle einlesen und einer Variablen zuweisen. Aber gerade bei größeren Datenmengen ist das Einlesen in ein Array und die Nutzung dieser Daten deutlich schneller.

Gruß

M.O.

0 Punkte
Beantwortet von snowwhite Mitglied (121 Punkte)

Guten Morgen M.O.

aber das ist doch von dir vom 17.05.

Und falls du doch einmal z.B. die x abfragen willst, dann geht das auch einfach direkt ohne irgendwelche Variablen. Das selbe gilt übrigens für deinen Löschen-Code. Bei mir würde er so aussehen:

Private Sub Schlüssel_Daten_löschen()
Dim i As Long
Dim t As Long
Dim arrTabellen As Variant
        
With Worksheets("urliste")
     arrTabellen = .Range(.Cells(1, 1), .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, 1))
End With

For t = LBound(arrTabellen) To UBound(arrTabellen)
   With ThisWorkbook.Worksheets(arrTabellen(t, 1))
    
        For i = 2 To .Cells(Rows.Count, 1).End(xlUp).Row
            If LCase(.Cells(i, 3).Value) = "x" Then         'mit LCase wird der Inhalt der Zelle in Kleinschrift dargestellt
                .Cells(i, 4).ClearContents
                .Cells(i, 6).ClearContents
                .Cells(i, 9).ClearContents
                .Cells(i, 12).ClearContents
                .Cells(i, 13).ClearContents
                .Cells(i, 14).ClearContents
            End If
        Next i
       End With
     Next t
Call Mail
End Sub

Warum weist du u.a. der Variablen Zeile die 1 zu, beginnst aber den Durchlauf mit

 Und er hängt genau bei

For t = LBound(arrTabellen) To UBound(arrTabellen)
   With ThisWorkbook.Worksheets(arrTabellen(t, 1))

 mit der Fehlermeldung  "laufzeitfehler '13' Typen unverträglich   frown Was macht den die "  For t = LBound(arrTabellen) To UBound(arrTabellen)" weil das sind die beiden Zeilen wo ich hänge! 

GLG SnowWhite

...