Ich schreibe eine Funktion, die einen Spaltenbereich und findet die erste und letzte Zelle in dieser Spalte, die einen bestimmten Wert haben. Dies ergibt eine erste Zeilennummer und eine letzte Zeilennummer, die dann verwendet werden, um den entsprechenden Unterbereich in einer anderen Spalte zurückzugeben.
Die Idee ist, dass ich mit dieser Funktion Excel-Funktionen auf einen (kontinuierlichen) Teilbereich eines Bereichs anwenden kann. Z.B. Angenommen, ich habe einen Tisch mit verschiedenen Preisen für Äpfel und Bananen, so gruppiert, dass alle Preise von Äpfeln zuerst kommen, dann Bananen. Ich möchte den Mindestpreis von Äpfeln und das Minimum von Bananen finden, aber den gesamten Bereich auswählen und ohne den Bereich zu ändern, über den minimiert werden soll. Ich würde meine gewünschte Funktion verwenden, um einen Bereich an Excel MIN-Funktion zu füttern, die nur Äpfel oder nur Bananen enthielt, ohne diese Teilbereiche manuell auswählen zu müssen. Ein MINIF, wenn Sie wollen - wie eine schwache Version von SUMMIF, aber für MIN (und möglicherweise viele andere Funktionen).
Ich habe einen Weg gefunden, es zu tun, aber es läuft wirklich ziemlich langsam. Ich denke, dass es mit der for-Schleife zu tun hat, aber ich verstehe nicht genug über die Effizienz in Excel/VBA, um zu wissen, wie man es verbessert. Ich verwende diesen Code in einer Excel-Tabelle, daher sind die Spalten, die ich übergebe, Spalten eines Tabellenobjekts. Ich verwende Excel 2010 unter Windows 7 Enterprise.Excel UDF zum ersten und letzten Zelle in Bereich mit einem bestimmten Wert finden - läuft langsam
Dankbar für jede Hilfe. Auch Lösungen zur bedingten Anwendung von Funktionen auf Bereiche, die davon stark abweichen, werden gut aufgenommen.
Code:
' ParentRange and CriterionRange are columns of the same table.
'I want to extract a reference to the part of ParentRange which corresponds
'by rows to the part of CriterionRange that contains cells with a certain value.
Function CorrespondingSubrange(CriterionRange As Range, Criterion As _
String, ParentRange As Range) As Range
Application.ScreenUpdating = False
Dim RowCounter As Integer
Dim SubRangeFirstRow As Integer
Dim SubRangeFirstCell As Range
Dim SubRangeLastRow As Integer
Dim SubRangeLastCell As Range
Dim RangeCountStarted As Boolean
RangeCountStarted = False
Set SubRangeFirstCell = CriterionRange.Find(What:=Criterion, LookIn:=xlValues, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not (SubRangeFirstCell Is Nothing) Then
RangeCountStarted = True
SubRangeFirstRow = SubRangeFirstCell.Row - CriterionRange.Range("A1").Row + 1
For RowCounter = SubRangeFirstRow To CriterionRange.Cells.Count
If Not (CriterionRange.Cells(RowCounter, 1).Value = Criterion) Then
SubRangeLastRow = RowCounter - 1
Exit For
End If
Next
End If
If RangeCountStarted = True And SubRangeLastRow = 0 Then SubRangeLastRow = RowCounter
Set CorrespondingSubrange = ParentRange.Range("A" & SubRangeFirstRow & ":A" & SubRangeLastRow)
Application.ScreenUpdating = True
End Function
Welche Version von Excel? Office 365/xl2016 hat eine native [MINIFS-Funktion] (https://support.office.com/de-de/article/MINIFS-function-6ca1ddaa-079b-4e74-80cc-72eef32e6599). [AGGREGATE-Funktion] (https://support.office.com/de-de/article/AGGREGATE-function-43B9278E-6AA7-4F17-92B6-E19993FA26DF) (xl2010 +) kann auch für einen einfachen Pseudo-MINIF verwendet werden. Es ist unwahrscheinlich, dass Sie diese nativen Funktionen sogar in strukturierten [ListObject] (https://msdn.microsoft.com/en-us/library/office/aa174247.aspx) -Tabellen übertreffen, aber Sie könnten Ihren Code mit dem * nach verbessern : = * und * SearchDirection: = * Parameter (keine Schleife). – Jeeped
Wenn dieser Code bereits funktioniert, könnte er ein guter Kandidat für http://codereview.stackexchange.com sein. Sie helfen dabei, den Arbeitscode zu verbessern. – TheEngineer
@Jeeped Leider Excel 2010. Gut zu wissen, dass, wenn mein Arbeitgeber auf Excel 2016 in 20 Jahren aufrüstet, wir es native haben werden ... – alfymbohm