Anzeige
Archiv - Navigation
1508to1512
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

Funktion für das min/max eines arrays

Funktion für das min/max eines arrays
26.08.2016 15:11:59
Gerhard
Hallo Leute
Ich versuche seit geraumer Zeit mir eine Funktion zu schreiben, welche mir die Min bzw Maximalwerte eines mehrdimensionalen Arrays in einem neuen Array ausgibt.
Das Array beinhaltet auch leere Datenfelder, was zu dem Problem führt, dass der Rückgabewert Null ist. Da es sich bei dem Daten um Koordinatenpunkte handelt brauche ich allerdings die null auch, weshalb ich das Array mit Daten des types string fülle.
Nachfolgend findet Ihr die Funktionen mit einem Beispiels des Arrays
Sub test1()
Dim myarray(10, 1)
Dim myarray_min()
myarray(0, 0) = -25
myarray(1, 0) = 55
myarray(2, 0) = 0
myarray(2, 0) = 45
myarray(3, 0) = -15
myarray(4, 0) = ""
myarray(5, 0) = ""
myarray(6, 0) = ""
myarray(7, 0) = ""
myarray(8, 0) = ""
myarray(9, 0) = ""
myarray(10, 0) = ""
myarray(0, 1) = ""
myarray(1, 1) = ""
myarray(2, 1) = ""
myarray(3, 1) = ""
myarray(4, 1) = ""
myarray(5, 1) = -15
myarray(6, 1) = -35
myarray(7, 1) = -47
myarray(8, 1) = -15
myarray(9, 1) = 0
myarray(10, 1) = ""
myarray_min = MIN_von_arr_test(myarray)
myarray_max = MAX_von_arr_test(myarray)
For i = 0 To 1
Debug.Print (myarray_min(i))
Debug.Print (myarray_max(i))
Next i
End Sub

Function MAX_von_arr_test(ByVal arr As Variant)
Dim Dim_arr As Long
Dim_arr = arr_Dim_count_Test(arr)
ReDim arr_max(Dim_arr - 1)
If Not IsArray(arr) Then Exit Function
On Error Resume Next
For i = 0 To Dim_arr
For j = LBound(arr) To UBound(arr)
For k = LBound(arr) To UBound(arr)
If IsNumeric(arr(j, i)) And IsNumeric(arr(k, i)) And _
CDbl(arr(j, i)) > CDbl(arr(k, i)) And CDbl(arr(j, i)) > arr_max(i) Then
arr_max(i) = CDbl(arr(j, i))
End If
Next k
Next j
Next i
MAX_von_arr_test = arr_max
End Function

Function MIN_von_arr_test(ByVal arr As Variant)
Dim Dim_arr As Long
Dim_arr = arr_Dim_count_Test(arr)
ReDim arr_min(Dim_arr - 1)
If Not IsArray(arr) Then Exit Function
On Error Resume Next
For i = 0 To Dim_arr
For j = LBound(arr) To UBound(arr)
For k = LBound(arr) To UBound(arr)
If IsNumeric(arr(j, i)) And IsNumeric(arr(k, i)) And _
CDbl(arr(j, i)) 

Function arr_Dim_count_Test(arr As Variant)
Dim i As Long
Dim LB As Long
If Not IsArray(arr) Then Exit Function
On Error Resume Next
' Es wird bis 61 gegangen, um in jedem Fall einen
' Fehler zu provozieren, so dass keine weitere
' Fallunterscheidung notwendig ist, falls das Array
' 60 Dimensionen haben sollte:
For arr_Dim_count_Test = 1 To 61
LB = LBound(arr, arr_Dim_count_Test)
If Err.Number  0 Then Exit For
Next
arr_Dim_count_Test = arr_Dim_count_Test - 1
End Function
Danke vorab für eure Unterstützung

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Funktion für das min/max eines arrays
26.08.2016 17:02:07
Gerhard
Nachsatz:
Habe vergessen zu erwähne das es ja vielleicht auch möglich wäre verschachtelte Arrays zu verwenden. Mit diesen würde ich das Problem mit den Datentyp String zumindest umgehen können. - Habe jedoch keine Ahnung wie ich mit diesen Arbeiten kann - Syntax und co.. Vielleicht hat hierzu jemand Literaturvorschläge etc.
Wäre für eure Hilfe wirklich Dankbar
AW: Funktion für das min/max eines arrays
26.08.2016 17:11:02
Michael
Hi,
die Frage ist, ob Du wirklich MEHRdimensional mit "mehr als 2" meinst ODER ein zweidmensionales mit einer unbekannten Anzahl von Zeilen + Spalten.
DREI-dimensional wäre etwa ein Zellbereich von B2:C11, das sind zwei Spalten á 10 Zeilen, und das z.B. 5 Mal "hintereinander", also gedanklich eine Datei mit 5 Blättern, bei denen Du den immer gleichen Bereich verarbeiten willst.
Kläre das mal, oder lade am besten eine Beispieldatei hoch, aus der man entnehmen kann, worum es geht.
Bis dahin bekommst Du eine "Spieldatei", die einige zusätzliche Schritte für Dein Makro enthält, damit Du nachvollziehen kannst (F8-Taste zeilenweise), was passiert: https://www.herber.de/bbs/user/107856.xlsm
Schöne Grüße,
Michael
Anzeige
AW: Funktion für das min/max eines arrays
26.08.2016 21:10:05
Gerhard
Hallo Michael
Danke für deine Antwort. Das Array bewegt sich im 2 Dimensionalen. Jedoch mit Variablen Zeilen und Spalten. Genau so wie im Beispiel. In diesem Beispiel bekomme ich als min Wert für die erste Spalte -15 was aber -25 ergeben sollte, für die zweite Spalte 0 und nicht -47.
Beste Grüße
Gerhard
AW: Funktion für das min/max eines arrays
Michael
Hi Gerhard,
bei einem "normalen", 2-dimensionalen Array gibt ubound(array) die Anzahl Zeilen und ubound(array,2) die Anzahl der Spalten zurück - nein, stimmt so nicht: vielmehr die höchste Nummer von Zeilen bzw. Spalten. Die ANZAHL hängt vom untersten Wert ab...
Wenn man ein Array aus einem Tabellenbereich übernimmt, sind beide Werte 1-basiert, d.h. Du machst Schleifen von 1 to ubound(...); wenn Du Arrays "programmierst", kannst Du es Dir aussuchen, ob 0 oder 1 (oder sonstwas).
Für die Programmierung ist es eigentlich wurscht, da kann man Schleifen von lbound to ubound laufen lassen, dann hat man immer die richtigen Anfangs-Indexnummern.
In meinem Beispiel lese ich einen Tabellenbereich ein...
Der Code:
Sub dannSo()
Dim myarray ' Variant zum Einlesen eines beliebigen Bereichs
Dim ergmin(), ergmax(), z&, s&
Dim lb&, ub& ' Indexnr. lbound/ubound um beides nicht jedesmal
' aufrufen zu müssen
Dim lb0&, ub0& ' Indexnr. lbound/ubound um beides nicht jedesmal
' aufrufen zu müssen
myarray = Range("B2:C11")   ' Array aus Bereich, immer 1-basiert
lb = LBound(myarray, 2): ub = UBound(myarray, 2) ' Spalten
lb0 = LBound(myarray): ub0 = UBound(myarray)     ' Zeilen
ReDim ergmin(0, lb To ub)
ReDim ergmax(0, lb To ub)
For s = lb To ub
ergmin(0, s) = "noch nix": ergmax(0, s) = "noch nix"
For z = lb0 To ub0
If myarray(z, s)  "" And Not IsEmpty(myarray(z, s)) Then
If IsNumeric(myarray(z, s)) Then
If ergmin(0, s) = "noch nix" Then
ergmin(0, s) = myarray(z, s)
ergmax(0, s) = myarray(z, s)
Else
'minimum
If ergmin(0, s) > myarray(z, s) Then ergmin(0, s) = myarray(z, s)
'maximum
If ergmax(0, s) 

... aber mit Deiner händischen Array-Definition läuft das genauso.
Mit Datei: https://www.herber.de/bbs/user/107859.xlsm
Eine Spitzfindigkeit zur Ermittlung von min/max: ich belege den Wert erst vor, wenn im Array ein numerischer Wert gefunden wurde: durch ein reines redim wie in Deinem Code wird das Array genullt - d.h., falls Du in einer Spalte nur positive Werte hättest, wäre das Minimum 0 - wenn Du nur negative hättest, wäre das Maximum 0. Das wird durch meine Vorgehensweise vermieden.
Schöne Grüße,
Michael
Anzeige
AW: Funktion für das min/max eines arrays
Michael
Hi Gerhard,
bei einem "normalen", 2-dimensionalen Array gibt ubound(array) die Anzahl Zeilen und ubound(array,2) die Anzahl der Spalten zurück - nein, stimmt so nicht: vielmehr die höchste Nummer von Zeilen bzw. Spalten. Die ANZAHL hängt vom untersten Wert ab...
Wenn man ein Array aus einem Tabellenbereich übernimmt, sind beide Werte 1-basiert, d.h. Du machst Schleifen von 1 to ubound(...); wenn Du Arrays "programmierst", kannst Du es Dir aussuchen, ob 0 oder 1 (oder sonstwas).
Für die Programmierung ist es eigentlich wurscht, da kann man Schleifen von lbound to ubound laufen lassen, dann hat man immer die richtigen Anfangs-Indexnummern.
In meinem Beispiel lese ich einen Tabellenbereich ein...
Der Code:
Sub dannSo()
Dim myarray ' Variant zum Einlesen eines beliebigen Bereichs
Dim ergmin(), ergmax(), z&, s&
Dim lb&, ub& ' Indexnr. lbound/ubound um beides nicht jedesmal
' aufrufen zu müssen
Dim lb0&, ub0& ' Indexnr. lbound/ubound um beides nicht jedesmal
' aufrufen zu müssen
myarray = Range("B2:C11")   ' Array aus Bereich, immer 1-basiert
lb = LBound(myarray, 2): ub = UBound(myarray, 2) ' Spalten
lb0 = LBound(myarray): ub0 = UBound(myarray)     ' Zeilen
ReDim ergmin(0, lb To ub)
ReDim ergmax(0, lb To ub)
For s = lb To ub
ergmin(0, s) = "noch nix": ergmax(0, s) = "noch nix"
For z = lb0 To ub0
If myarray(z, s)  "" And Not IsEmpty(myarray(z, s)) Then
If IsNumeric(myarray(z, s)) Then
If ergmin(0, s) = "noch nix" Then
ergmin(0, s) = myarray(z, s)
ergmax(0, s) = myarray(z, s)
Else
'minimum
If ergmin(0, s) > myarray(z, s) Then ergmin(0, s) = myarray(z, s)
'maximum
If ergmax(0, s) 

... aber mit Deiner händischen Array-Definition läuft das genauso.
Mit Datei: https://www.herber.de/bbs/user/107859.xlsm
Eine Spitzfindigkeit zur Ermittlung von min/max: ich belege den Wert erst vor, wenn im Array ein numerischer Wert gefunden wurde: durch ein reines redim wie in Deinem Code wird das Array genullt - d.h., falls Du in einer Spalte nur positive Werte hättest, wäre das Minimum 0 - wenn Du nur negative hättest, wäre das Maximum 0. Das wird durch meine Vorgehensweise vermieden.
Schöne Grüße,
Michael
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige