Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1228to1232
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
Zeilen untereinander kopieren
Horst
Hallo Excel-Freunde,
ich bin auf der Suche nach einem Makro, dass folgendes macht:
In Spalte B bis H sind verschiedene Zahlen enthalten. Ich will nun ein Eingabefeld erzeugen, in man eine Zahl x eingibt, wonach ein Suchalgorithmus startet, der alle Zeilen im Bereich B:H nach dieser Zahl absucht und bei einem Treffer (z.B. in Zelle C10), die nächste komplette Zeile (Bereich B11:H11) kopiert und in ein neues Tabellenblatt schreibt. Der VBA-Code soll alle so gefundenen Zeilen untereinander schreiben und die darin enthaltenen Zahlen ihrer Größe nach sortieren.
Besten Dank vorab!

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Benutzer
Anzeige
AW: Zeilen untereinander kopieren
10.09.2011 17:46:10
Tino
Hallo,
bin mir nicht sicher ob ich alles verstanden habe.
Die gesuchte Zahl kann in einer beliebigen Spalte/Zelle im Suchbereich vorkommen?
Sortieren mache ich über eine Hilfsspalte die den Min- Wert aus der Zeile zieht.
Kannst mal testen, Tabelle müsstest Du noch anpassen.

Sub Start()
Dim rngFind As Range, rngTmp As Range, rngSuchBereich As Range
Dim strEerste As String
Dim varSuchZahl
Dim iCalc As Integer

varSuchZahl = InputBox("Suche nach", "Geben Sie die zu suchende Zahl ein")
If Not IsNumeric(varSuchZahl) Then Exit Sub

'Tabelle anpassen 
Set rngSuchBereich = Tabelle1.Range("B:H")

Set rngFind = rngSuchBereich.Find(What:=varSuchZahl, LookIn:=xlValues, LookAt:= _
        xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
        , SearchFormat:=False)

If Not rngFind Is Nothing Then
    With Application
        iCalc = .Calculation
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlCalculationManual
        
            strEerste = rngFind.Address
            If rngFind.Row < rngSuchBereich.Rows.Count Then _
                Set rngTmp = rngSuchBereich.Rows(rngFind.Row + 1)
                
                Set rngFind = rngSuchBereich.FindNext(rngFind)
                Do While rngFind.Address <> strEerste
                    If rngFind.Row < rngSuchBereich.Rows.Count Then _
                    Set rngTmp = Union(rngSuchBereich.Rows(rngFind.Row + 1), rngTmp)
                    Set rngFind = rngSuchBereich.FindNext(rngFind)
                Loop
            
            With ThisWorkbook
                With .Sheets.Add(After:=.Sheets(.Sheets.Count))
                    rngTmp.Copy .Cells(1, 1)
                    With Union(.UsedRange, .UsedRange.Columns(.UsedRange.Columns.Count).Offset(0, 1))
                        .Columns(.Columns.Count).FormulaR1C1 = "=MIN(RC1:RC" & .Columns.Count - 1 & ")"
                        .Sort Key1:=.Cells(1, .Columns.Count), Order1:=xlAscending, Header:=xlNo
                        .Columns(.Columns.Count).EntireColumn.Delete
                    End With
                End With
            End With
        
        .Calculation = iCalc
        .ScreenUpdating = True
        .EnableEvents = True
    End With
End If
End Sub
Gruß Tino
Anzeige
AW: Zeilen untereinander kopieren
10.09.2011 21:37:15
Horst
Besten Dank, Tino!
Die Zeilen kopieren sich wie gewollt untereinander. Kannst du noch einbauen, dass das Ergebnis (die Matrix der rauskopierten Zeilen) so sortiert wird, dass jede Zahl aus dem Bereich A:E bzw. F:G nur 1x vorkommt. Das Ergebnis soll wie folgt aussehen:
Mittels Makro ausgelesene Zeilen:
Spalte:
A B C D E F G
.....
17 37 39 48 70 1 9
15 37 48 55 70 9 5
....
Die Matrix soll so sortiert werden, dass das Endergebnis wie folgt aussieht:
Zusammenfassung Spalte A bis E:
15
17
37
39
48
55
70
Zusammenfassung Spalte F:G
1
5
9
Gruß, Horst
Anzeige
AW: Zeilen untereinander kopieren
10.09.2011 21:50:15
Horst
... hab noch eine Kleinigkeit vergessen: Ganz toll wäre es, wenn beim Endergebnis auch dabei stehen würde, wie oft jede Zahl vorgekommen ist. Für das obige Beispiel also dann:
Zusammenfassung Spalte A bis E:
15 (1x)
17 (1x)
37 (2x)
39 (1x)
48 (2x)
55 (1x)
70 (2x)
Zusammenfassung Spalte F:G
1 (1x)
5 (1x)
9 (2x)
AW: Zeilen untereinander kopieren
11.09.2011 11:28:35
Tino
Hallo,
kannst mal testen.

Option Explicit

Sub Start()
Dim rngFind As Range, rngTmp As Range, rngSuchBereich As Range
Dim strEerste As String
Dim varSuchZahl
Dim iCalc As Integer
Dim varArray
Dim oWS As Worksheet

varSuchZahl = InputBox("Suche nach", "Geben Sie die zu suchende Zahl ein")
If Not IsNumeric(varSuchZahl) Then Exit Sub

'Tabelle anpassen 
Set rngSuchBereich = Tabelle1.Range("B:H")

Set rngFind = rngSuchBereich.Find(What:=varSuchZahl, LookIn:=xlValues, LookAt:= _
        xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
        , SearchFormat:=False)

If Not rngFind Is Nothing Then
    With Application
        iCalc = .Calculation
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlCalculationManual
        
            strEerste = rngFind.Address
            If rngFind.Row < rngSuchBereich.Rows.Count Then _
                Set rngTmp = rngSuchBereich.Rows(rngFind.Row + 1)
            
            Set rngFind = rngSuchBereich.FindNext(rngFind)
            Do While rngFind.Address <> strEerste
                If rngFind.Row < rngSuchBereich.Rows.Count Then _
                Set rngTmp = Union(rngSuchBereich.Rows(rngFind.Row + 1), rngTmp)
                Set rngFind = rngSuchBereich.FindNext(rngFind)
            Loop
        
            With ThisWorkbook
                'A bis E ********************************** 
                Zusammenfassen varArray, rngTmp, 1, 5
                If IsArray(varArray) Then
                    If oWS Is Nothing Then Set oWS = .Sheets.Add(After:=.Sheets(.Sheets.Count))
                    With oWS
                        .Cells(2, 1).Resize(Ubound(varArray)) = varArray
                        .Cells(1, 1) = "A-E"
                    End With
                End If
                varArray = Empty
                
                'F bis G ********************************** 
                Zusammenfassen varArray, rngTmp, 6, 7
                If IsArray(varArray) Then
                    If oWS Is Nothing Then Set oWS = .Sheets.Add(After:=.Sheets(.Sheets.Count))
                    With oWS
                        .Cells(2, 2).Resize(Ubound(varArray)) = varArray
                        .Cells(1, 2) = "F-G"
                    End With
                End If
                varArray = Empty
                
                If Not oWS Is Nothing Then
                    With oWS
                        .Rows(1).Font.Bold = True
                        .UsedRange.EntireColumn.AutoFit
                    End With
                End If
            End With
        
        .Calculation = iCalc
        .ScreenUpdating = True
        .EnableEvents = True
    End With
End If
End Sub

Sub Zusammenfassen(varArray, rngRange As Range, lngVonCol&, lngBisCol&)
Dim oDic As Scripting.Dictionary, meAr(), n&, nn&
Dim rng As Range
Set oDic = CreateObject("Scripting.Dictionary")

For Each rng In rngRange.Areas
    meAr = rng.Value2
    For n = Lbound(meAr) To Ubound(meAr)
        For nn = lngVonCol To lngBisCol
            If meAr(n, nn) <> "" Then _
                oDic(meAr(n, nn)) = oDic(meAr(n, nn)) + 1
        Next nn
    Next n
Next
Erase meAr
If oDic.Count = 0 Then Exit Sub
meAr = TransposeArray(oDic.Keys)
Redim Preserve meAr(Lbound(meAr) To Ubound(meAr), 1 To 2)
For n = Lbound(meAr) To Ubound(meAr)
    meAr(n, 2) = " (" & oDic(meAr(n, 1)) & ")"
Next n
prcQuickSort Lbound(meAr), Ubound(meAr), 1, True, meAr
For n = Lbound(meAr) To Ubound(meAr)
    meAr(n, 1) = meAr(n, 1) & meAr(n, 2)
Next n
Redim Preserve meAr(1 To Ubound(meAr), 1 To 1)
varArray = meAr
End Sub

Function TransposeArray(varArray)
Dim n&, NewArray()
Redim Preserve NewArray(Lbound(varArray) + 1 To Ubound(varArray) + 1, 1 To 1)
For n = Lbound(varArray) To Ubound(varArray)
    NewArray(n + 1, 1) = varArray(n)
Next n
TransposeArray = NewArray
End Function

'   Code Max Kaffl 
Private Sub prcQuickSort(lngLbound As Long, lngUbound As Long, _
    intSortColumn As Integer, bntSortKey As Boolean, vntArray() As Variant)
    Dim intIndex As Integer
    Dim lngIndex1 As Long, lngIndex2 As Long
    Dim vntTemp As Variant, vntBuffer As Variant
    lngIndex1 = lngLbound
    lngIndex2 = lngUbound
    vntBuffer = vntArray((lngLbound + lngUbound) \ 2, intSortColumn)
    Do
        If bntSortKey Then
            Do While vntArray(lngIndex1, intSortColumn) < vntBuffer
                lngIndex1 = lngIndex1 + 1
            Loop
            Do While vntBuffer < vntArray(lngIndex2, intSortColumn)
                lngIndex2 = lngIndex2 - 1
            Loop
        Else
            Do While vntArray(lngIndex1, intSortColumn) > vntBuffer
                lngIndex1 = lngIndex1 + 1
            Loop
            Do While vntBuffer > vntArray(lngIndex2, intSortColumn)
                lngIndex2 = lngIndex2 - 1
            Loop
        End If
        If lngIndex1 < lngIndex2 Then
            If vntArray(lngIndex1, intSortColumn) <> _
                vntArray(lngIndex2, intSortColumn) Then
                For intIndex = Lbound(vntArray, 2) To Ubound(vntArray, 2)
                    vntTemp = vntArray(lngIndex1, intIndex)
                    vntArray(lngIndex1, intIndex) = _
                        vntArray(lngIndex2, intIndex)
                    vntArray(lngIndex2, intIndex) = vntTemp
                Next
            End If
            lngIndex1 = lngIndex1 + 1
            lngIndex2 = lngIndex2 - 1
        ElseIf lngIndex1 = lngIndex2 Then
            lngIndex1 = lngIndex1 + 1
            lngIndex2 = lngIndex2 - 1
        End If
    Loop Until lngIndex1 > lngIndex2
    If lngLbound < lngIndex2 Then Call prcQuickSort(lngLbound, _
        lngIndex2, intSortColumn, bntSortKey, vntArray())
    If lngIndex1 < lngUbound Then Call prcQuickSort(lngIndex1, _
        lngUbound, intSortColumn, bntSortKey, vntArray())
End Sub
Gruß Tino
Anzeige
AW: Zeilen untereinander kopieren
11.09.2011 12:43:03
Horst
Hallo Tino,
habe anfänglich in der Zeile "Dim oDic As Scripting.Dictionary, meAr(), n&, nn&" die Fehlermeldung: "Fehler beim Kompilieren: Benutzerdefinierter Typ nicht definiert" bekommen. Nachdem ich allerdings MS Scripting Runtime aktiviert habe, funktioniert's problemlos. Wie müsste man angeben, dass die Anzahl der Redundanzen (der Wert in Klammer), also zb. bei 70 (2x): die "(2x)" in die nächste Spalte (die rechts daneben) geschrieben wird?
Besten Dank nochmal!
Gruß, Horst
AW: Zeilen untereinander kopieren
11.09.2011 12:59:21
Tino
Hallo,
den Verweis hatte ich zu testzwecken gesetzt und vergessen diesen wieder zu entfernen.
Hier die Anpassung u. den Verweis musst Du auch nicht mehr setzen.

Sub Start()
Dim rngFind As Range, rngTmp As Range, rngSuchBereich As Range
Dim strEerste As String
Dim varSuchZahl
Dim iCalc As Integer
Dim varArray
Dim oWS As Worksheet

varSuchZahl = InputBox("Suche nach", "Geben Sie die zu suchende Zahl ein")
If Not IsNumeric(varSuchZahl) Then Exit Sub

'Tabelle anpassen 
Set rngSuchBereich = Tabelle1.Range("B:H")

Set rngFind = rngSuchBereich.Find(What:=varSuchZahl, LookIn:=xlValues, LookAt:= _
        xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
        , SearchFormat:=False)

If Not rngFind Is Nothing Then
    With Application
        iCalc = .Calculation
        .ScreenUpdating = False
        .EnableEvents = False
        .Calculation = xlCalculationManual
        
            strEerste = rngFind.Address
            If rngFind.Row < rngSuchBereich.Rows.Count Then _
                Set rngTmp = rngSuchBereich.Rows(rngFind.Row + 1)
            
            Set rngFind = rngSuchBereich.FindNext(rngFind)
            Do While rngFind.Address <> strEerste
                If rngFind.Row < rngSuchBereich.Rows.Count Then _
                Set rngTmp = Union(rngSuchBereich.Rows(rngFind.Row + 1), rngTmp)
                Set rngFind = rngSuchBereich.FindNext(rngFind)
            Loop
        
            With ThisWorkbook
                'A bis E ********************************** 
                Zusammenfassen varArray, rngTmp, 1, 5
                If IsArray(varArray) Then
                    If oWS Is Nothing Then Set oWS = .Sheets.Add(After:=.Sheets(.Sheets.Count))
                    With oWS
                        .Cells(2, 1).Resize(Ubound(varArray), 2) = varArray
                        .Cells(1, 1) = "A-E"
                        .Cells(1, 2) = "Anzahl"
                    End With
                End If
                varArray = Empty
                
                'F bis G ********************************** 
                Zusammenfassen varArray, rngTmp, 6, 7
                If IsArray(varArray) Then
                    If oWS Is Nothing Then Set oWS = .Sheets.Add(After:=.Sheets(.Sheets.Count))
                    With oWS
                        .Cells(2, 3).Resize(Ubound(varArray), 2) = varArray
                        .Cells(1, 3) = "F-G"
                        .Cells(1, 4) = "Anzahl"
                    End With
                End If
                varArray = Empty
                
                If Not oWS Is Nothing Then
                    With oWS
                        .Rows(1).Font.Bold = True
                        .UsedRange.EntireColumn.AutoFit
                    End With
                End If
            End With
        
        .Calculation = iCalc
        .ScreenUpdating = True
        .EnableEvents = True
    End With
End If
End Sub

Sub Zusammenfassen(varArray, rngRange As Range, lngVonCol&, lngBisCol&)
Dim oDic As Object, meAr(), n&, nn&
Dim rng As Range
Set oDic = CreateObject("Scripting.Dictionary")

For Each rng In rngRange.Areas
    meAr = rng.Value2
    For n = Lbound(meAr) To Ubound(meAr)
        For nn = lngVonCol To lngBisCol
            If meAr(n, nn) <> "" Then _
                oDic(meAr(n, nn)) = oDic(meAr(n, nn)) + 1
        Next nn
    Next n
Next
Erase meAr
If oDic.Count = 0 Then Exit Sub
meAr = TransposeArray(oDic.Keys, oDic.items)
Redim Preserve meAr(Lbound(meAr) To Ubound(meAr), 1 To 2)
prcQuickSort Lbound(meAr), Ubound(meAr), 1, True, meAr
varArray = meAr
End Sub

Function TransposeArray(varArrayKeys, varArrayItems)
Dim n&, NewArray()
Redim Preserve NewArray(Lbound(varArrayKeys) + 1 To Ubound(varArrayKeys) + 1, 1 To 2)
For n = Lbound(varArrayKeys) To Ubound(varArrayKeys)
    NewArray(n + 1, 1) = varArrayKeys(n)
    NewArray(n + 1, 2) = varArrayItems(n)
Next n
TransposeArray = NewArray
End Function

'   Code Max Kaffl 
Private Sub prcQuickSort(lngLbound As Long, lngUbound As Long, _
    intSortColumn As Integer, bntSortKey As Boolean, vntArray() As Variant)
    Dim intIndex As Integer
    Dim lngIndex1 As Long, lngIndex2 As Long
    Dim vntTemp As Variant, vntBuffer As Variant
    lngIndex1 = lngLbound
    lngIndex2 = lngUbound
    vntBuffer = vntArray((lngLbound + lngUbound) \ 2, intSortColumn)
    Do
        If bntSortKey Then
            Do While vntArray(lngIndex1, intSortColumn) < vntBuffer
                lngIndex1 = lngIndex1 + 1
            Loop
            Do While vntBuffer < vntArray(lngIndex2, intSortColumn)
                lngIndex2 = lngIndex2 - 1
            Loop
        Else
            Do While vntArray(lngIndex1, intSortColumn) > vntBuffer
                lngIndex1 = lngIndex1 + 1
            Loop
            Do While vntBuffer > vntArray(lngIndex2, intSortColumn)
                lngIndex2 = lngIndex2 - 1
            Loop
        End If
        If lngIndex1 < lngIndex2 Then
            If vntArray(lngIndex1, intSortColumn) <> _
                vntArray(lngIndex2, intSortColumn) Then
                For intIndex = Lbound(vntArray, 2) To Ubound(vntArray, 2)
                    vntTemp = vntArray(lngIndex1, intIndex)
                    vntArray(lngIndex1, intIndex) = _
                        vntArray(lngIndex2, intIndex)
                    vntArray(lngIndex2, intIndex) = vntTemp
                Next
            End If
            lngIndex1 = lngIndex1 + 1
            lngIndex2 = lngIndex2 - 1
        ElseIf lngIndex1 = lngIndex2 Then
            lngIndex1 = lngIndex1 + 1
            lngIndex2 = lngIndex2 - 1
        End If
    Loop Until lngIndex1 > lngIndex2
    If lngLbound < lngIndex2 Then Call prcQuickSort(lngLbound, _
        lngIndex2, intSortColumn, bntSortKey, vntArray())
    If lngIndex1 < lngUbound Then Call prcQuickSort(lngIndex1, _
        lngUbound, intSortColumn, bntSortKey, vntArray())
End Sub
Gruß Tino
Anzeige
AW: Zeilen untereinander kopieren
11.09.2011 14:44:56
Horst
Funktioniert super!
Allerbesten Dank, einfach genial gemacht.
Gruß, Horst

304 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige