Live-Forum - Die aktuellen Beiträge
Datum
Titel
20.05.2024 20:08:41
20.05.2024 18:23:06
20.05.2024 17:14:25
Anzeige
Archiv - Navigation
1960to1964
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

2 VBA Codes mergen

2 VBA Codes mergen
26.01.2024 15:43:21
Max
Hallo Zusammen, ich möchte gerne diese beiden Codes in einen VBA Code zusammenfassen so das beide funktionieren.
Hintergrund ist folgender: In Spalte 2 soll bei einer speziellen Statusauswahl die Zeile in ein anderes Tabellenblatt verschoben werden.
Gleichzeitig benötige ich stets Dropdown-Menüs mit Mehrfachauswahl und der Möglichkeit zum Entfernen von bereits ausgewählten Dropdown Elementen.
Beides soll aber weiterhin funktionieren. Da ich beide Male die Dropdown Menüs beeinflusse komme ich leider nicht weiter.

Private Sub Worksheet_Change(ByVal Target As Range)


Dim lngErste As Long
If Target.Column = 2 Then
If Target.Count = 1 Then
If Target = "Bestand" Then
With Worksheets("Bestand")
lngErste = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count) + 1
Rows(Target.Row).Copy
.Cells(lngErste, 1).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With


ElseIf Target = "Verkauft" Then
With Worksheets("Verkauft")
lngErste = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count) + 1
Rows(Target.Row).Copy
.Cells(lngErste, 1).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With


ElseIf Target = "Abgerechnet" Then
With Worksheets("Abgerechnet")
lngErste = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count) + 1
Rows(Target.Row).Copy
.Cells(lngErste, 1).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With


End If
End If
End If



End Sub



und




Option Explicit

Private Sub Worksheet_Change(ByVal Destination As Range)
Dim rngDropdown As Range
Dim oldValue As String
Dim newValue As String
Dim DelimiterType As String
DelimiterType = ", "
Dim DelimiterCount As Integer
Dim TargetType As Integer
Dim i As Integer
Dim arr() As String

If Destination.Count > 1 Then Exit Sub
On Error Resume Next

Set rngDropdown = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitError

If rngDropdown Is Nothing Then GoTo exitError

TargetType = 0
TargetType = Destination.Validation.Type
If TargetType = 3 Then ' is validation type is "list"
Application.ScreenUpdating = False
Application.EnableEvents = False
newValue = Destination.Value
Application.Undo
oldValue = Destination.Value
Destination.Value = newValue
If oldValue > "" Then
If newValue > "" Then
If oldValue = newValue Or oldValue = newValue & Replace(DelimiterType, " ", "") Or oldValue = newValue & DelimiterType Then ' leave the value if there is only one in the list
oldValue = Replace(oldValue, DelimiterType, "")
oldValue = Replace(oldValue, Replace(DelimiterType, " ", ""), "")
Destination.Value = oldValue
ElseIf InStr(1, oldValue, DelimiterType & newValue) Or InStr(1, oldValue, newValue & DelimiterType) Or InStr(1, oldValue, DelimiterType & newValue & DelimiterType) Then
arr = Split(oldValue, DelimiterType)
If Not IsError(Application.Match(newValue, arr, 0)) = 0 Then
Destination.Value = oldValue & DelimiterType & newValue
Else:
Destination.Value = ""
For i = 0 To UBound(arr)
If arr(i) > newValue Then
Destination.Value = Destination.Value & arr(i) & DelimiterType
End If
Next i
Destination.Value = Left(Destination.Value, Len(Destination.Value) - Len(DelimiterType))
End If
ElseIf InStr(1, oldValue, newValue & Replace(DelimiterType, " ", "")) Then
oldValue = Replace(oldValue, newValue, "")
Destination.Value = oldValue
Else
Destination.Value = oldValue & DelimiterType & newValue
End If
Destination.Value = Replace(Destination.Value, Replace(DelimiterType, " ", "") & Replace(DelimiterType, " ", ""), Replace(DelimiterType, " ", "")) ' remove extra commas and spaces
Destination.Value = Replace(Destination.Value, DelimiterType & Replace(DelimiterType, " ", ""), Replace(DelimiterType, " ", ""))
If Destination.Value > "" Then
If Right(Destination.Value, 2) = DelimiterType Then ' remove delimiter at the end
Destination.Value = Left(Destination.Value, Len(Destination.Value) - 2)
End If
End If
If InStr(1, Destination.Value, DelimiterType) = 1 Then ' remove delimiter as first characters
Destination.Value = Replace(Destination.Value, DelimiterType, "", 1, 1)
End If
If InStr(1, Destination.Value, Replace(DelimiterType, " ", "")) = 1 Then
Destination.Value = Replace(Destination.Value, Replace(DelimiterType, " ", ""), "", 1, 1)
End If
DelimiterCount = 0
For i = 1 To Len(Destination.Value)
If InStr(i, Destination.Value, Replace(DelimiterType, " ", "")) Then
DelimiterCount = DelimiterCount + 1
End If
Next i
If DelimiterCount = 1 Then ' remove delimiter if last character
Destination.Value = Replace(Destination.Value, DelimiterType, "")
Destination.Value = Replace(Destination.Value, Replace(DelimiterType, " ", ""), "")
End If
End If
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End If

exitError:
Application.EnableEvents = True
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub




LG Max

16
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: 2 VBA Codes mergen
26.01.2024 16:09:35
daniel
Hi
der zweite code braucht dann im Prinzip ein
If Target.Column > 2 then
damit sich die beiden Codes nicht überkreuzen.

die Frage ist, warum verwendet der eine Code "Target" als Übergabeparameter und der andere "Destination"?
warum hast du das gemacht?
man kann bei diesen Eventmakros zwar die Übergabeparameter frei benennen, aber sinnvoll ist das nicht. Man sollte die Kopfzeile eines Events immer so belassen, wie sie automatisch erzeugt wird. ich kenne keinen vernünftigen Grund, das anders zu machen.
Gruß Daniel
AW: 2 VBA Codes mergen
26.01.2024 16:15:56
Max
Meine vollkommen ehrliche Antwort: Ich habe mir die beiden Codes aus Internetrecherchen zusammen geschustert und habe auch wirklich wenig Ahnung von VBA.
Anzeige
AW: 2 VBA Codes mergen
26.01.2024 16:18:03
Max
Also ich weiß ehrlicherweise nicht mal wie ich die überhaupt logisch zusammen führen müsste. Beide funktionieren für sich alleine. Aber wie müsste der Code aussehen wenn beide gleichzeitig funktionieren sollen. Ich weiß leider nicht mal das.
AW: 2 VBA Codes mergen
26.01.2024 16:25:07
daniel
dann müssen die Codes ins selbe Makro, weil das Makro ja automatisch über ein bestimmtes Ereignis ausgelöst werden soll, und das läuft über den Namen, dh wenn das Change-Event (Änderung eines oder mehrere Zellwerte), wird das Makro mit dem Namen "Worksheet_Change" automatisch ausgeführt. Da in einem Modul ein Makroname immer nur einmal vorkommen darf, müssen beide Codes in dieses Makro.
Gruß Daniel
Anzeige
AW: 2 VBA Codes mergen
26.01.2024 16:36:47
Max
und diese Destination / Target Bezeichnung?
AW: 2 VBA Codes mergen
26.01.2024 16:46:46
daniel
tja, gute Frage.
ich hab den Code nicht geschrieben, du hast ihn dir ausgesucht. Dh du weißt mehr als ich.
wenn du zwei Markos zusammenmergst, die beide den Übergabeparameter verwenden, dann musst du auch im ganzen Code hierfür die gleiche Bezeichnung verwenden.
oder du kopierst dir den Übergabeparameter in eine Variable mit dem Namen, dann musst du den Code nicht ändern.

Also wenn du so zwei Makros hast
Sub Worksheet_Change(Target)

... code1 mit Target
End Sub

Sub Worksheet_Change(Target)

... code2 mit Destination
end sub


und du willst diese Vereinigen, dann entweder
Sub Worksheet_Change(Target)

... code1 mit Target
... code2 mit Target
end sub

oder
Sub Worksheet_Change(Target)

dim Destination
... code1 mit Target
Set Destination = Target
... code2 mit Destination
end sub
Anzeige
AW: 2 VBA Codes mergen
26.01.2024 16:56:39
Max
Also ich bin jetzt mit diesem Code soweit,




Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)


Dim lngErste As Long
If Target.Column = 2 Then
If Target.Count = 1 Then
If Target = "Bestand" Then
With Worksheets("Bestand")
lngErste = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count) + 1
Rows(Target.Row).Copy
.Cells(lngErste, 1).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With


ElseIf Target = "Verkauft" Then
With Worksheets("Verkauft")
lngErste = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count) + 1
Rows(Target.Row).Copy
.Cells(lngErste, 1).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With


ElseIf Target = "Abgerechnet" Then
With Worksheets("Abgerechnet")
lngErste = IIf(IsEmpty(.Cells(.Rows.Count, 1)), _
.Cells(.Rows.Count, 1).End(xlUp).Row, .Rows.Count) + 1
Rows(Target.Row).Copy
.Cells(lngErste, 1).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With


End If
End If
End If

Dim rngDropdown As Range
Dim oldValue As String
Dim newValue As String
Dim DelimiterType As String
DelimiterType = ", "
Dim DelimiterCount As Integer
Dim TargetType As Integer
Dim i As Integer
Dim arr() As String

If Target.Count > 1 Then Exit Sub
On Error Resume Next

Set rngDropdown = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitError

If rngDropdown Is Nothing Then GoTo exitError
If Not Target.Column = 10 Then GoTo exitError

TargetType = 0
TargetType = Target.Validation.Type
If TargetType = 3 Then ' is validation type is "list"
Application.ScreenUpdating = False
Application.EnableEvents = False
newValue = Target.Value
Application.Undo
oldValue = Target.Value
Target.Value = newValue
If oldValue > "" Then
If newValue > "" Then
If oldValue = newValue Or oldValue = newValue & Replace(DelimiterType, " ", "") Or oldValue = newValue & DelimiterType Then ' leave the value if there is only one in the list
oldValue = Replace(oldValue, DelimiterType, "")
oldValue = Replace(oldValue, Replace(DelimiterType, " ", ""), "")
Target.Value = oldValue
ElseIf InStr(1, oldValue, DelimiterType & newValue) Or InStr(1, oldValue, newValue & DelimiterType) Or InStr(1, oldValue, DelimiterType & newValue & DelimiterType) Then
arr = Split(oldValue, DelimiterType)
If Not IsError(Application.Match(newValue, arr, 0)) = 0 Then
Target.Value = oldValue & DelimiterType & newValue
Else:
Target.Value = ""
For i = 0 To UBound(arr)
If arr(i) > newValue Then
Target.Value = Target.Value & arr(i) & DelimiterType
End If
Next i
Target.Value = Left(Target.Value, Len(Target.Value) - Len(DelimiterType))
End If
ElseIf InStr(1, oldValue, newValue & Replace(DelimiterType, " ", "")) Then
oldValue = Replace(oldValue, newValue, "")
Target.Value = oldValue
Else
Target.Value = oldValue & DelimiterType & newValue
End If
Target.Value = Replace(Target.Value, Replace(DelimiterType, " ", "") & Replace(DelimiterType, " ", ""), Replace(DelimiterType, " ", "")) ' remove extra commas and spaces
Target.Value = Replace(Target.Value, DelimiterType & Replace(DelimiterType, " ", ""), Replace(DelimiterType, " ", ""))
If Target.Value > "" Then
If Right(Target.Value, 2) = DelimiterType Then ' remove delimiter at the end
Target.Value = Left(Target.Value, Len(Target.Value) - 2)
End If
End If
If InStr(1, Target.Value, DelimiterType) = 1 Then ' remove delimiter as first characters
Target.Value = Replace(Target.Value, DelimiterType, "", 1, 1)
End If
If InStr(1, Target.Value, Replace(DelimiterType, " ", "")) = 1 Then
Target.Value = Replace(Target.Value, Replace(DelimiterType, " ", ""), "", 1, 1)
End If
DelimiterCount = 0
For i = 1 To Len(Target.Value)
If InStr(i, Target.Value, Replace(DelimiterType, " ", "")) Then
DelimiterCount = DelimiterCount + 1
End If
Next i
If DelimiterCount = 1 Then ' remove delimiter if last character
Target.Value = Replace(Target.Value, DelimiterType, "")
Target.Value = Replace(Target.Value, Replace(DelimiterType, " ", ""), "")
End If
End If
End If
Application.EnableEvents = True
Application.ScreenUpdating = True
End If

exitError:
Application.EnableEvents = True
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub



dass er tut was er soll. Jedoch wenn ich den Status in Spalte 2 ändere, verschiebt er zwar die Zeile in das korrekte Tabellenblatt, öffnet aber direkt einen Laufzeitfehler 424: Objekt erforderlich und spring in diese Zeile im Code:

If Target.Count > 1 Then Exit Sub
Anzeige
AW: 2 VBA Codes mergen
26.01.2024 16:59:41
Yal
Richtig wäre eigentlich
If Target.Cells.Count > 1 Then Exit Sub


VG
Yal
AW: 2 VBA Codes mergen
26.01.2024 17:10:14
daniel
Hi
wenn man solche Makros merged, sollte man zum einen auf If ... Then Exit Sub verzichten, sondern korrekte IF-Blöcke mit If Then und End IF und dem code dazwischen erstellen, sonst bekommt man Probleme, wenn u.U. noch weitere Aktionen durchgeführt werden müssen.

das nächste Problem ist, dass diese Event-Makros sich selber aufrufen, wenn sie die entsprechende Aktion ausführen.
Dh wenn das Change-Makro eine oder mehrere Zellen ändert, wird das Change-Makro ein weiteres mal gestartet.
So kann man sich schnell in einer Endlosschleife mit Selbstaufrufen verfangen.

um die Endlosschleife zu vermeiden gibt es zwei Möglichkeiten:
a) durch eine geschickte Abfrage, die beim zweiten durchlauf den dritten Aufruf verhindert
das ist aber nicht immer zuverlässig, weil die eindeutige Ermittlung nicht immer möglich ist, und zum anderen wird das Makro zumindest einmal unnötig gestartet.
um dies zu verhindern, verwendet man besser Methode, nämlich
b) Application.EnableEvents = False nach diesem Befehl werden die automatischen Eventmakros nicht mehr ausgeführt und man kann im Change-Makro beliebig Zellen ändern, ohne das sich das Makro ständig selbst aufruft.
Am Ende des makros muss man allerdings wieder Application.EnableEvents = True programmieren, sonst bleiben die Events aus und werden nicht mehr automatisch gesstartet, wenn der Anwender was ändert.

Gruß Daniel
Anzeige
AW: 2 VBA Codes mergen
29.01.2024 11:23:20
Max
Hi Daniel, vielen herzlichen Dank erstmal für deine Bemühungen. An welche Stelle müsste ich das Application.EnableEvents = False / True setzen? LG Max
AW: 2 VBA Codes mergen
26.01.2024 17:01:44
Max
Da sagt er immer noch Error
AW: 2 VBA Codes mergen
26.01.2024 17:14:15
Luschi
Hallo Max,

der Fehler muß ja erscheinen, denn du hast ja 14 Vba-Zeilen über den Mecker-Befehl die Zeile, in der die Target-Zelle steckt gelöscht:
Rows(Target.Row).Delete shift:=xlUp
und damit hat das Target-Object den Zugriffswert 'Noting' - also nicht mehr existent.

Gruß von Luschi
aus klein-Paris
AW: 2 VBA Codes mergen
26.01.2024 16:21:05
daniel
Hi
es ist mir eigentlich egal, wo du die Codes her hast.
ich betrachte auch "aus dem Internet zusammengesucht" als quasi "selbst geschrieben"
Gruß Daniel
AW: 2 VBA Codes mergen
26.01.2024 16:31:43
Yal
Hallo Max,

könnte es sein, dass die zweite Teil nur eine Umformatierung von Listen, sodass alle Elemente mit je eine Komma + Leerzeichen getrennt werden, aber kein Komma am Anfang oder Ende?

Dementsprechend würde den Code so ausehen:
Private Function Formatiere(Eingang As String) As String

Dim Elt
Dim Erg
For Each Elt In Split(Eingang, ",")
If Trim(Elt) > "" Then Erg = Erg & "," & Trim(Elt)
Next
Formatiere = Replace(Mid(Erg, 2), ",", ", ")
End Function

Sub Test()
Debug.Print Formatiere("abc")
Debug.Print Formatiere("abc,")
Debug.Print Formatiere("abc, ")
Debug.Print Formatiere(",abc")
Debug.Print Formatiere(", abc")
Debug.Print Formatiere("abc,def")
Debug.Print Formatiere("abc, def")
Debug.Print Formatiere("abc,def")
Debug.Print Formatiere("abc,def,")
Debug.Print Formatiere("abc,def, ")
Debug.Print Formatiere(",abc,def, ")
Debug.Print Formatiere(", abc,def, ")
End Sub


Wenn es so ist kann man alles auf folgendes reduzieren:
Private Sub Worksheet_Change(ByVal Target As Range)


If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
If Target.Column = 2 Then
Select Case Target.Value
Case "Bestand", "Verkauft", "Abgerechnet"
With Worksheets(Target.Value)
Rows(Target.Row).Copy
WS.Cells(WS.Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End With
End Select
Else ' Target.Column > 2
Target.Value = Formatiere(Target.Value)
End If
Application.EnableEvents = True
End Sub


VG
Yal
Anzeige
Mist
26.01.2024 16:35:34
Yal
WS muss weg. Da Worksheets(Target.Value) nur an einer Stelle verwendet wird, braucht man keinen With.

Private Sub Worksheet_Change(ByVal Target As Range)


If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
If Target.Column = 2 Then
Select Case Target.Value
Case "Bestand", "Verkauft", "Abgerechnet"
Rows(Target.Row).Copy
Worksheets(Target.Value).Cells(WS.Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlValues
Rows(Target.Row).Delete shift:=xlUp
End Select
Else ' Target.Column > 2
Target.Value = Formatiere(Target.Value)
End If
Application.EnableEvents = True
End Sub


VG
Yal
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige