Hilfreiche Funktionen und Prozeduren

    • VBA: Excel

      Hilfreiche Funktionen und Prozeduren

      Ich möchte hier ein paar Funktionen und Prozeduren vorstellen, die mir beim Programmieren in Excel hilfreich sind:


      Folgende Prozedur bewirkt, dass alle Zellen im Bereich quadratisch sind. Ist HöheBeibehalten False, wird die Breite beibehalten.

      Visual Basic-Quellcode

      1. Sub QuadratischeZellen(Bereich As Range, Optional HöheBeibehalten As Boolean = True)
      2. Dim Zelle As Range
      3. For Each Zelle In Bereich
      4. If HöheBeibehalten Then
      5. While Zelle.Width <> Zelle.Height
      6. Zelle.ColumnWidth = Zelle.ColumnWidth / Zelle.Width * Zelle.Height
      7. Wend
      8. Else
      9. While Zelle.Width <> Zelle.Height
      10. Zelle.RowHeight = Zelle.RowHeight / Zelle.Height * Zelle.Width
      11. Wend
      12. End If
      13. Next
      14. End Sub


      Folgende Funktion liefert die Mappe, die unter Dateipfad gespeichert ist. Ist die Mappe bereits offen, wird die geöffnete Mappe zurückgegeben.

      Visual Basic-Quellcode

      1. Function DateiMappe(Dateipfad As String) As Workbook
      2. Dim i As Integer
      3. For i = 1 To Workbooks.Count
      4. If Workbooks(i).FullName = Dateipfad Then
      5. Set DateiMappe = Workbooks(i)
      6. Exit Function
      7. End If
      8. Next
      9. Set DateiMappe = Workbooks.Open(Dateipfad)
      10. End Function


      Folgende Prozedur schließt die Mappe, die unter Dateipfad gespeichert ist, sofern sie geöffnet ist.

      Visual Basic-Quellcode

      1. Sub DateiSchließen(Dateipfad As String, Optional ÄnderungenSpeichern As Boolean = False)
      2. Dim i As Integer
      3. For i = 1 To Workbooks.Count
      4. If Workbooks(i).FullName = Dateipfad Then
      5. Workbooks(i).Close SaveChanges:=ÄnderungenSpeichern
      6. Exit Sub
      7. End If
      8. Next
      9. End Sub


      Folgende Prozedur speichert die Mappe unter Dateipfad, wobei eine evtl. bestehende Datei überschrieben wird. Sollte so eine Mappe bereits geöffnet sein, wird sie vorher mit DateiSchließen (s. o.) geschlossen. Bei Excel 2007 speichere ich meistens als „.xlsm“-Datei also als XML-Mappe mit Makros. Für ältere Excel-Versionen empfiehlt sich statt xlOpenXMLWorkbookMacroEnabled xlNormal.

      Visual Basic-Quellcode

      1. Sub DateiNeuSpeichern(Mappe As Workbook, Dateipfad As String, Optional Dateiformat As XlFileFormat = xlOpenXMLWorkbookMacroEnabled)
      2. DateiSchließen Dateipfad
      3. Application.DisplayAlerts = False
      4. Mappe.SaveAs Dateipfad, Dateiformat
      5. Application.DisplayAlerts = True
      6. End Sub


      Folgende Funktion erstellt eine neue Mappe und speichert sie mit obiger Prozedur DateiNeuSpeichern. Diese neue Mappe ist der Rückgabewert der Funktion.

      Visual Basic-Quellcode

      1. Function NeueDateiSpeichern(Dateipfad As String, Optional Dateiformat As XlFileFormat = xlOpenXMLWorkbookMacroEnabled) As Workbook
      2. Set NeueDateiSpeichern = Workbooks.Add()
      3. DateiNeuSpeichern NeueDateiSpeichern, Dateipfad, Dateiformat
      4. End Function


      Folgende Funktion liefert einen String, der die Werte im Bereich enthält.

      Visual Basic-Quellcode

      1. Function RangeString(Bereich As Range, Zeilentrennung As String, Spaltentrennung As String, Optional Rahmen As Boolean = True) As String
      2. Dim z As Long, s As Integer
      3. With Bereich
      4. For z = 1 To .Rows.Count
      5. If z > 1 Then RangeString = RangeString & Zeilentrennung
      6. For s = 1 To .Columns.Count
      7. If s > 1 Then RangeString = RangeString & Spaltentrennung
      8. RangeString = RangeString & .Cells(z, s)
      9. Next
      10. Next
      11. End With
      12. If Rahmen Then RangeString = Zeilentrennung & RangeString & Zeilentrennung
      13. End Function


      Bei folgender Funktion wird in der UsedRange der Tabelle in der Suchspalte der Suchtext gesucht. Wird er gefunden, werden die Werte der entsprechenden Zeile als Array zurückgegeben. Wenn nicht, wird ein Array zurückgegeben, das nur das Element 0 enthält, welches leer ist.

      Visual Basic-Quellcode

      1. Function SuchArray(Tabelle As Worksheet, Suchtext As String, Optional Suchspalte As Integer = 1) As Variant()
      2. Dim Erg() As Variant, Bereich As Range, Zeile As Long, i As Integer
      3. ReDim Erg(0)
      4. Set Bereich = Tabelle.UsedRange
      5. If WorksheetFunction.CountIf(Bereich.Columns(Suchspalte), Suchtext) > 0 Then
      6. Zeile = WorksheetFunction.Match(Suchtext, Bereich.Columns(Suchspalte), 0)
      7. ReDim Erg(Bereich.Columns.Count)
      8. For i = 1 To Bereich.Columns.Count
      9. Erg(i) = Bereich.Cells(Zeile, i)
      10. Next
      11. End If
      12. SuchArray = Erg
      13. End Function


      Folgende Funktion fügt der Tabelle die Werte hinzu. Die Schlüsselspalte gibt dabei die Spalte mit dem Primärschlüssel an, also die Spalte, in der ein Wert nur einmal vorkommen darf. Gibt es keine solche Spalte, muss man 0 angeben.

      Visual Basic-Quellcode

      1. Function WerteHinzufügen(Tabelle As Worksheet, Schlüsselspalte As Integer, ParamArray Werte() As Variant) As Long
      2. Dim hinzufügen As Boolean, Zeile As Long, i As Integer
      3. If Schlüsselspalte = 0 Then
      4. hinzufügen = True
      5. Else
      6. hinzufügen = (WorksheetFunction.CountIf(Tabelle.Columns(Schlüsselspalte), Werte(Schlüsselspalte - 1)) = 0)
      7. End If
      8. If hinzufügen Then
      9. Zeile = Tabelle.UsedRange.Rows.Count + 1
      10. If Zeile = 2 Then If Tabelle.UsedRange.Cells.Count = 1 Then Zeile = 1
      11. For i = 0 To UBound(Werte)
      12. Tabelle.Cells(Zeile, i + 1) = Werte(i)
      13. Next
      14. WerteHinzufügen = Zeile
      15. End If
      16. End Function


      Folgende Prozedur sortiert die UsedRange der Tabelle nach den Spalten. Ob auf- oder absteigend sortiert werden soll, wird durch das Vorzeichen der Spalte bestimmt.

      Beispiel:

      Visual Basic-Quellcode

      1. UsedRangeSort Sheets("Tabelle1"), False, 3, 1, -5, 4
      sortiert die UsedRange von Tabelle1, die keine Überschriften hat, erst nach Spalte 3 aufsteigend, dann nach Spalte 1 aufsteigend, dann nach Spalte 5 absteigend und dann nach Spalte 4 aufsteigend.

      Zu erwähnen wäre noch, dass ich es so eingestellt habe, dass Zahlen, die als Text formatiert sind, als Text behandelt werden (DataOption:=xlSortNormal) und dass Groß-/Kleinschreibung nicht beachtet wird (MatchCase:=False).

      Version für Excel 2007:

      Visual Basic-Quellcode

      1. Sub UsedRangeSort(Tabelle As Worksheet, Überschriften As Boolean, ParamArray Spalten() As Variant)
      2. Dim i As Integer, Bereich As Range
      3. Set Bereich = Tabelle.UsedRange
      4. With Tabelle.Sort
      5. .SortFields.Clear
      6. For i = 0 To UBound(Spalten)
      7. .SortFields.Add Key:=Bereich.Columns(Abs(Spalten(i))), SortOn:=xlSortOnValues, Order:=1.5 - Sgn(Spalten(i)) / 2, DataOption:=xlSortNormal
      8. Next
      9. .SetRange Bereich
      10. .Header = IIf(Überschriften, xlYes, xlNo)
      11. .MatchCase = False
      12. .Orientation = xlTopToBottom
      13. .SortMethod = xlPinYin
      14. .Apply
      15. End With
      16. End Sub


      Version für ältere Excel-Versionen:

      Visual Basic-Quellcode

      1. Sub UsedRangeSortAlt(Tabelle As Worksheet, Überschriften As Boolean, ParamArray Spalten() As Variant)
      2. Dim i As Integer, StartNr As Integer, Bereich As Range
      3. Set Bereich = Tabelle.UsedRange
      4. Select Case UBound(Spalten)
      5. Case 0
      6. Bereich.Sort _
      7. Key1:=Bereich.Cells(1 - Überschriften, Spalten(0)), Order1:=1.5 - Sgn(Spalten(0)) / 2, DataOption1:=xlSortNormal, _
      8. Header:=IIf(Überschriften, xlYes, xlNo), OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
      9. Case 1
      10. Bereich.Sort _
      11. Key1:=Bereich.Cells(1 - Überschriften, Spalten(0)), Order1:=1.5 - Sgn(Spalten(0)) / 2, DataOption1:=xlSortNormal, _
      12. Key2:=Bereich.Cells(1 - Überschriften, Spalten(1)), Order2:=1.5 - Sgn(Spalten(1)) / 2, DataOption2:=xlSortNormal, _
      13. Header:=IIf(Überschriften, xlYes, xlNo), OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
      14. Case 2
      15. Bereich.Sort _
      16. Key1:=Bereich.Cells(1 - Überschriften, Spalten(0)), Order1:=1.5 - Sgn(Spalten(0)) / 2, DataOption1:=xlSortNormal, _
      17. Key2:=Bereich.Cells(1 - Überschriften, Spalten(1)), Order2:=1.5 - Sgn(Spalten(1)) / 2, DataOption2:=xlSortNormal, _
      18. Key3:=Bereich.Cells(1 - Überschriften, Spalten(2)), Order3:=1.5 - Sgn(Spalten(2)) / 2, DataOption3:=xlSortNormal, _
      19. Header:=IIf(Überschriften, xlYes, xlNo), OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
      20. Case Else
      21. StartNr = (UBound(Spalten) \ 3) * 3
      22. Select Case UBound(Spalten) Mod 3
      23. Case 0: UsedRangeSortAlt Tabelle, Überschriften, Spalten(StartNr)
      24. Case 1: UsedRangeSortAlt Tabelle, Überschriften, Spalten(StartNr), Spalten(StartNr + 1)
      25. Case 2: UsedRangeSortAlt Tabelle, Überschriften, Spalten(StartNr), Spalten(StartNr + 1), Spalten(StartNr + 2)
      26. End Select
      27. For i = 0 To StartNr - 3 Step 3
      28. UsedRangeSortAlt Tabelle, Überschriften, Spalten(i), Spalten(i + 1), Spalten(i + 2)
      29. Next
      30. End Select
      31. End Sub