Excel und Objektorientiert?

Tach Community,

ich programmiere vorwiegend in PHP.
Ich habe so meine Schwierigkeiten mit VB

Ich schreibe gerade einen Makro in Excel und stehe vor folgendem problem:

ich brauche eine art klassenvariable,
in die ich einen array speichern kann.
auf die dann alle funktionen zugreifen koennen.

ich habe keine ahnung wie ich das in vb umsetzen muss.
hier mein gedankenansatz

Dim meinArray As String

Function setArray ( strElem As String)
 meinArray = this.meinArray
 arrayLaenge = meinArray.length
 meinArray(arrayLaenge+1) = strElem

 setArray = meinArray


End Function

das ist natuerlich alles unsinn… aber ich hoffe dennoch,
dass man versteht was ich moechte.

merci

PixelKoenig

Hallo PixelKoenig,

ich brauche eine art klassenvariable,
in die ich einen array speichern kann.
auf die dann alle funktionen zugreifen koennen.

Damit alle Funktionen darauf zugreifen können musst du das Array einfach ganz oben im Code (außerhalb der Subs und Functions) deklarieren, z.B.:
Dim MeinArray() as String

Wenn mehrere Formulare oder zusätzliche Objekte wie Module, etc. verwendes und überall auf das Array zugreifen willst kannst du es entweder als Public deklarieren:
Public MeinArray() as String

und außerhalb dieses Formulars folgendermaßen zugreifen:
Wert = Form1.MeinArray(Index)

oder du Deklarierst das Array in einem Modul als Global:
Global MeinArray() as String

ich habe keine ahnung wie ich das in vb umsetzen muss.

Gut, kleiner Crash-Kurs zu Arrays:

arrayLaenge = meinArray.length

Die Anzahl der Element im Array kannst du z.B. bei der Deklaration festlegen:
Dim MeinArray(0 to 10) as String

wenn du nur
Dim MeinArray(10) as String
schreibst, wird als Untergrenze 0 verwendet.

Wenn du nur
Dim MeinArray() as String
schreibst musst du die größe später im Code festlegen:
ReDim MeinArray(0 to 10)

Wenn du später ermitteln willst wie groß ein Array ist geht das so:

Untergrenze = LBound(MeinArray) 'ergibt z.B. 0
Obergrenze = UBound(MeinArray) 'ergibt z.B. 10

Der Zugriff auf die Elemente erfolgt z.B. folgendermaßen:

Wert = „Test5“
MeinArray(5) = Wert
'…
Wert2 = MeinArray(5) 'ergibt „Test5“

So, das sollte fürs erste reichen.

Gruß, Phil

Hi Phil,

nein, das ist es nicht, dann gibt es ja keine verschiedenen Instanzen des Arrays. Arr(0) kann dann nur einen Wert enthalten, wiest Du Arr(0) einen andren wert zu, wird der Erste überschrieben, das soll nicht sein.

Gruß, Rainer

Hallo PixelKoenig,

Excel VBA kennt Klassenmodule.

Du musst das Array im Klassenmodul deklarieren und Instanzen der Klasse aufrufen, dann funktioniert das so, wie Du das vor hast.
Code füge ich noch ein, den muss ich erst tippen, sobald ich Zeit habe.

In der Klasse darf man Arrays nicht als Public deklarieren, deshalb wird der Code bei mir etwas umständlich, funktioniert aber. Über Verbesserungen würde ich mich freuen …

In der Klasse ‚Klasse1‘:

Option Explicit

Dim Arr() As String

Public Sub RD(ByVal LB As Long, ByVal UB As Long)
 ReDim Arr(LB To UB)
End Sub

Public Sub setzen(ByVal idx As Long, ByVal Wert As String)
 Arr(idx) = Wert
End Sub

Public Function lesen(ByVal idx As Long) As String
 lesen = Arr(idx)
End Function

und der Beispielcode in der Userform sieht so aus:

Option Explicit

Dim Cl As Klasse1

Private Sub CommandButton1\_Click()
 Set cl1 = New Klasse1
 Set cl2 = New Klasse1

 cl1.RD 1, 10
 cl2.RD 0, 20

 cl1.setzen 5, "Test"
 cl2.setzen 5, "Versuch"

 MsgBox "Arr(5) in Instanz 1 enthält: " + cl1.lesen(5)
 MsgBox "Arr(5) in Instanz 2 enthält: " + cl2.lesen(5)
End Sub

Gruß, Rainer

Tach, Pixelkönig!

Ich würde kein Array nehmen, sondern eine Collection. Ein Array hat eine fest vorgegebene Größe, und es wird dann knirschen, wenn Du diese überschreitest. Wenn Du das sauber abfängst, kannst Du Dir dann zwar ein größeres Array bauen und die Werte übernehmen, aber dennoch ist das ein gewisser Aufwand.

Die Collection-Klasse hat eigentlich alles, was man braucht…

Gruß, Manfred

Hallo Manfred,

Die Collection-Klasse hat eigentlich alles, was man braucht…

die ist nur etwas langsam. Beispiel:

Option Explicit

Dim Cl As Collection
Dim Arr(1000000) As Long

Private Sub Command1\_Click()
 Dim i As Long, t As Double
 t = Timer
 Set Cl = New Collection

 For i = 1 To 1000000
 Cl.Add i
 Next
 Me.Caption = Round(Timer - t, 3)
End Sub

Private Sub Command2\_Click()
 Dim i As Long, t As Double
 t = Timer

 For i = 1 To 1000000
 Arr(i) = i
 Next
 Me.Caption = Round(Timer - t, 3)
End Sub

Die Variante mit dem Array ist etwa 10 mal so schnell.

Gruß, Rainer

Hi Rainer,

nein, das ist es nicht, dann gibt es ja keine verschiedenen
Instanzen des Arrays. Arr(0) kann dann nur einen Wert
enthalten, wiest Du Arr(0) einen andren wert zu, wird der
Erste überschrieben, das soll nicht sein.

Daran hab ich auch schon gedacht, aber er schreibt, dass er von VB nicht viel Ahnung hat und dachte er hat sein Problem wahrscheinlich nur ein bischen falsch formuliert. Vieleicht geht man ja in PHP anders vor…

Halte auch nicht besonders viel von Klassenmodulen und Collections; hab das ein paar mal Probiert und große Geschwindigkeitseinbußen erlitten.

Gruß, Phil

Hi Phil,

Daran hab ich auch schon gedacht, aber er schreibt, dass er
von VB nicht viel Ahnung hat und dachte er hat sein Problem
wahrscheinlich nur ein bischen falsch formuliert. Vieleicht
geht man ja in PHP anders vor…

daß ich das nur falsch verstanden habe, kann natürlich auch sein. In der Titelzeile steht aber Objektorientierung und das bedeutet mehrere Instanzen, also Klassen.

Halte auch nicht besonders viel von Klassenmodulen und
Collections; hab das ein paar mal Probiert und große
Geschwindigkeitseinbußen erlitten.

Mit Collections habe ich auch noch nicht viel gearbeitet, weil die mir zu langsam sind, volle Zustimmung. :smile:

Gruß, Rainer

Hallo, Rainer!

Die Collection-Klasse hat eigentlich alles, was man braucht…

die ist nur etwas langsam. Beispiel: […]
Die Variante mit dem Array ist etwa 10 mal so schnell.

Spiel das mal mit einem Stringarray durch, und Du kommst auf deutlich ähnlichere Zeiten.

Es hängt vor allem davon ab, was man machen will. Wenn ich der Collection noch einen Key mitgebe, brauche ich zwar wieder deutlich länger, um die Daten zu füllen, aber der Zugriff via Key findet praktisch in Echtzeit statt, wohin gegen ich das Array entsprechend lange durchsuchen muss.

Auch könnte ich in einer Collection Objekte verarbeiten, das Array ist auf Basistypen beschränkt.

Es hat schon seinen Grund, warum beides existiert. There’s a time and a place for everything.

Gruß, Manfred

Hallo Manfred,

Spiel das mal mit einem Stringarray durch, und Du kommst auf
deutlich ähnlichere Zeiten.

hab ich gamacht, nur noch Faktor acht. (*gg* das reimt sich. :smile:)

Es hängt vor allem davon ab, was man machen will.

Ja sicher. Ich habe ja auch gar nicht gesagt, daß Collection überflüssig wäre oder ähnliches, nur daß es etwas anderes als ein Array ist und das Array nicht ersetzen kann.

Wenn ich der
Collection noch einen Key mitgebe, brauche ich zwar wieder
deutlich länger, um die Daten zu füllen, aber der Zugriff via
Key findet praktisch in Echtzeit statt, wohin gegen ich das
Array entsprechend lange durchsuchen muss.

Relativ. :smile: Ich finde auch in einem Array Daten schnell wieder. Das soll doch jetzt kein Wettbewerb werden? Ich vermute, daß wir auf vergleichbare Zeiten kommen, wenn ich jetzt anfangen würde, die Daten in ein Array sortiert einzutragen und im sortierten Array Daten zu suchen. Ich schätze nämlich, daß ich die Collection nur nachbauen würde. :smile:

Auch könnte ich in einer Collection Objekte verarbeiten, das
Array ist auf Basistypen beschränkt.

Das klingt interessant, werde ich versuchen, mir zu merken.

Es hat schon seinen Grund, warum beides existiert. There’s a
time and a place for everything.

Sicher hat es einen Grund, warum beides existiert. Alles für seinen Zweck.

Gruß, Rainer

DANKE SCHOEN
Hi VBA Experten,

vielen Dank für die Antworten.
Ich denke ich werde zunaechst
die Antwort mit der Collection
fuer mich nutzen. auch die anderen
waren sehr hilfreich.

danke schoen

grusz

PixelKoenig