ReDim eines String-Array in SUB

27/01/2008 - 19:27 von Josef Zins | Report spam
Hallo zusammen
in einem TreeView-Element werte ich die über Checkboxes markierten
Knoten aus.
Hierfür verwende ich für die Auswertung eine SUB, welche im Aufruf das
String-Array ByREF übergeben bekommt.
Die Anpassung auf die erforderliche Größe des String-Array erfolgt in
der SUB über ReDim Preserve
Der Code ist in etwa so:

Private Sub btnPosTreeDelete_Click()
Dim strNodeKey() As String
FindCheckedNode strNodeKey 'Aufruf ByREF
.
End Sub
'

Private Sub FindCheckedNode(strNodeKey)
Dim Node As MSComctlLib.Node
Dim l As Long
Dim loCheckedNodes As Long
loCheckedNodes = 0
For l = 1 To tvwLVInhalt.Nodes.count
Set Node = tvwLVInhalt.Nodes.Item(l)
If Node.Checked Then
loCheckedNodes = loCheckedNodes + 1
ReDim Preserve strNodeKey(loCheckedNodes)
strNodeKey(loCheckedNodes) = Mid(Node.Key, 5, Len(Node.Key) - 4)
End If
Next l
End Sub

Das funktioniert alles problemlos, auch der Kompiler meckert nicht.
Ich bin mir aber nicht sicher, ob durch das ReDim in der SUB einer ByREF
übergebenen Vriablen nicht irgenwelche negativen Seiteneffekte zu
erwarten sind.
Besteht die Unsicherheit zu Recht ?

Grüsse
Josef Zins



Teile dein Wissen mit anderen. Dies ist eine gute Möglichkeit, Unsterblichkeit zu erlangen (Dalai Lama)
 

Lesen sie die antworten

#1 Thorsten Albers
27/01/2008 - 22:18 | Warnen spam
Josef Zins schrieb im Beitrag
...
Private Sub FindCheckedNode(strNodeKey)


Hier solltest Du unbedingt den Datentyp mit "As String" angeben, wenn kein
anderer Datentyp von der Prozedur unterstützt wird. Das fördert in Deinem
Programm die Typensicherheit und nimmt der Prozedur einen unnötigen
Datenüberhang (Variablen ohne Datentypenangabe legt VB automatisch als
Variant an; d.h. hier muß bei Aufruf der String-Array-Descriptor in den
Variant übertragen werden und bei Rückkehr umgekehrt. Das ist zwar kein
gewaltiger Aufwand, aber überflüssig.

For l = 1 To tvwLVInhalt.Nodes.count
Set Node = tvwLVInhalt.Nodes.Item(l)
If Node.Checked Then
loCheckedNodes = loCheckedNodes + 1
ReDim Preserve strNodeKey(loCheckedNodes)
strNodeKey(loCheckedNodes) = Mid(Node.Key, 5, Len(Node.Key) -


4)
Hier solltest Du Mid$() verwenden. Mid() gibt einen String in einem Variant
zurück, Mid$() einen String. Wenn Du das oben angegebene befolgst, wird
dann nur noch mit Strings gearbeitet, was hier sinnvoll ist.

End If
Next l


'ReDim Preserve' in einer Schleife ist, wenn zahlreiche Operationen
erfolgen, ungünstig. Stattdessen empfiehlt es sich in einem solchen Fall
zunàchst die Anzahl der Elemente zu ermitteln, dann das Array neu zu
dimensionieren, und anschließend die Array-Eintràge zu setzen. Dann kannst
Du auch auf das 'Preserve' verzeichten, daß eine gewisse Unsicherheit
darstellt (s.u.).

Das funktioniert alles problemlos, auch der Kompiler meckert nicht.
Ich bin mir aber nicht sicher, ob durch das ReDim in der SUB einer ByREF
übergebenen Vriablen nicht irgenwelche negativen Seiteneffekte zu
erwarten sind.
Besteht die Unsicherheit zu Recht ?



Welche Seiteneffekte sollten das sein? Voraussetzung ist allerdings, daß Du
weißt, was Du tust: Du verwendest 'Preserve', was bekanntlich bedeutet, daß
der vorherige Array-Inhalt bestehen bleibt. 'loCheckedNodes' nimmt aber in
Deinem Code als niedrigsten Wert 1 an, und bei entsprechender
VB-Einstellung (Option Base 0, Standard bei VB) wird dann durch 'ReDim
Preserve strNodeKey(loCheckedNodes)' das Array strNodeKey() mit 0 - 1/n minimal 2 Eintràgen dimensioniert; d.h. der Eintrag mit dem Index 0 bleibt
immer< erhalten, und es ist im Array immer ein Eintrag mehr vorhanden als


durch 'loCheckedNodes' angegeben. Nach Deinem Code zu schließen, spielt das
keine Rolle, es sei denn, Du verwendest spàter 'LBound(strNodeKey)', was
Dir 0 und nicht 1 liefern würde mit strNodeKey(0) = Leerstring.
Um keine unliebsamen Überraschungen zu erleben, empfiehlt es sich immer,
die Unter- und Obergrenze bei Dim() und ReDim() explizit anzugeben, auch um
unabhàngig von der Einstellung 'Option Base' zu sein. Und wenn der Inhalt
des der Prozedur übergebenen Arrays keinesfalls erhalten bleiben sondern
durch einen neuen ersetzt werden soll, empfiehlt sich ein 'Erase
strNodeKey' zu Beginn der Prozedur - einfach zur Sicherheit.

-
THORSTEN ALBERS Universitàt Freiburg
albers@
uni-freiburg.de
-

Ähnliche fragen