Live-Forum - Die aktuellen Beiträge
Datum
Titel
29.03.2024 13:14:12
28.03.2024 21:12:36
28.03.2024 18:31:49
Anzeige
Archiv - Navigation
1576to1580
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

Kein Zugriff auf Array ... und: ja, es ist gefüllt

Kein Zugriff auf Array ... und: ja, es ist gefüllt
08.09.2017 16:54:41
Martin
Hallo VBA-Spezies,
ich sitze mal wieder an einem VBA-Problem, habe nichts brauchbares im inet gefunden ... daher die Bitte an Euch: Bitte helft mir doch noch mal !
-> Was soll das Makro tun?
Um einen Drehpunkt sollen x-y-Koordinaten rotiert werden (in einem bestimmtem Winkel).
-> Lösungsweg:
Mittels Inputbox frage ich die x-y-Koordinaten und Daten ab (Bediener gibt die Bereiche und Werte ein).
Die Koordinaten werden in Ein-Arrays aufgenommen, ein paar Plausi-Prüfungen durchgeführt und schließlich wird gerechnet. Die Ergebnisse sollen in Aus-Arrays gespeichert und ausgegeben werden.
-> Problem:
Die Ein-Arrays sind zwar gefüllt (UBound und LBound werden im Debugger richtig angezeigt), aber trotzdem kann während der Berechnung nicht darauf zugegriffen werden! Ich habe schon alles (mir mögliche) versucht. Z.B. mit ReDim Preserve, aber davon wird's auch nicht besser - funktioniert auch nicht: Ganz im Gegenteil, auf einmal unwillkürlich ganze Codeabschnitte übersprungen werden.
Ich hoffe, dass sich einer von den Profis erbarmt ...
Danke schon mal im Voraus, nachfolgend das Makro,
Martin
Sub PolygonRotation()
'rotierte Abbildung: x' = x0 + [(x-x0)*cos(w)] - [(y-y0)*sin(w)]
'rotierte Abbildung: y' = y0 + [(x-x0)*sin(w)] + [(y-y0)*cos(w)]
Const Pi As Single = 3.14159265358979
Dim i As Long
Dim UntArrEinGrz As Long
Dim ObeArrEinGrz As Long
Dim xEin As Variant '1D-Array
Dim yEin As Variant '1D-Array
Dim xAus As Variant '1D-Array
Dim yAus As Variant '1D-Array
Dim xDrehpunkt As Single, yDrehpunkt As Single
Dim WinkelGrad As Single, WinkelBogen As Single
'Bereich der Ausgangs-Koordinaten abfragen
xEin = Application.InputBox("Bereich der zu rotierenden x-Koordinaten", "Ausgangs-Koordinaten:  _
Bereich wählen", , , , , , 64)
If VarType(xEin) = vbBoolean Then Exit Sub
yEin = Application.InputBox("Bereich der zu rotierenden y-Koordinaten", "Ausgangs-Koordinaten:  _
Bereich wählen", , , , , , 64)
If VarType(yEin) = vbBoolean Then Exit Sub
'Plausibilitaetspruefung Ein-Koordinaten
If (UBound(xEin) - LBound(xEin))  (UBound(yEin) - LBound(yEin)) Then
MsgBox "Abbruch: Anzahl der x/y - Koordinaten waren ungleich !"
Exit Sub
End If
'Array-Grenzen zwischenspeichern
UntArrEinGrz = LBound(xEin)
ObeArrEinGrz = UBound(xEin)
'Redimensionieren der Ein-Arrays
'ReDim Preserve xEin(UntArrEinGrz To ObeArrEinGrz)
'ReDim Preserve yEin(UntArrEinGrz To ObeArrEinGrz)
'Drehpunkt-Koordinaten und Drehwinkel abfragen
xDrehpunkt = Application.InputBox("x-Koordinaten Drehpunkt", "Drehpunkt und -winkel", , , , , ,  _
1)
If VarType(xDrehpunkt) = vbBoolean Then Exit Sub
yDrehpunkt = Application.InputBox("y-Koordinaten Drehpunkt", "Drehpunkt und -winkel", , , , , ,  _
1)
If VarType(yDrehpunkt) = vbBoolean Then Exit Sub
WinkelGrad = Application.InputBox("Drehwinkel in Grad", "Bereich wählen", , , , , , 1)
If VarType(WinkelGrad) = vbBoolean Then Exit Sub
'Winkelumrechnung
WinkelBogen = WinkelGrad * Pi / 180
'Ausgabe-Arrays initialisieren
ReDim xAus(UntArrEinGrz To ObeArrEinGrz)
ReDim yAus(UntArrEinGrz To ObeArrEinGrz)
'Rotation: Berechnen der Koord.-AusArrays
For i = LBound(xEin) To UBound(xEin)
xAus(i) = xDrehpunkt + ((xEin(i) - xDrehpunkt) * Cos(WinkelBogen)) - ((yEin(i) - yDrehpunkt) _
* Sin(WinkelBogen))
yAus(i) = yDrehpunkt + ((xEin(i) - xDrehpunkt) * Sin(WinkelBogen)) + ((yEin(i) - yDrehpunkt) _
* Cos(WinkelBogen))
Next i
'Ausgabe der rotierten Koordinaten
For i = LBound(xEin) To UBound(xEin)
Cells(9 + i, 2) = xAus(i)
Cells(9 + i, 3) = yAus(i)
Next i
End Sub

16
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 17:05:37
Daniel
Hi
wenn du einen Zellbereich aus mehreren Zellen einer Variant-Variablen zuweist, dann entsteht immer ein zweidimensionales Array, auch wenn dieser Zellbereich nur aus einer Zeile oder einer Spalte besteht.
du müsstest also, wenn du auf xEin bzw xAus zugreifst, immer noch die zweite Koordinate mit 1 angeben:
also xEin(i, 1) bzw xEin(1, i), je nachdem ob die Werte in einer Spalte untereinander oder in einer Zeile nebeneinander stehen.
Gruß Daniel
AW: 2-D-Array in 1-D-Array wandeln
08.09.2017 17:20:23
Daniel
wenn du lieber mit 1-D-Arrays arbeitest, kannst einspaltige oder einzeilige 2-d-Arrays mit Worksheetfunction.Transpose in ein 1-D-Array wandeln:
a) bei einem einspaltigen Array:
=Worksheetfunction.Transpose(xEin)
b) beine einem einzeiligen Array:
=Worksheetfunction.transpose(Worksheetfunction.transpose(xEin))
wenns nicht festgelegt ist, ob einzeilig oder einspaltig gearbeitet wird, dann könntest du so ein eindimensionales Array aus einem 2-Dimensionalen erzeugen:
dim x
dim i as long
xEin = Inputbox(...)
redim xEinNeu(1 to (Ubound(xEin, 1) - Lbound(xEin, 1) + 1) * (Ubound(xEin, 2) - Lbound(xEin, 2)  _
+ 1))
for each x in xEin
i = i + 1
xEinNeu(i) = x
Next

dein xEinNeu ist dann eindimensional mit allen Elementen aus xEin, egal wie diese vorher angeordnet waren (einzeilig, einspaltig, oder auch als echtes 2-D mit mehrern Zeilen oder Spalten)
Gruß Daniel
Anzeige
AW: kleine Korrektur:
08.09.2017 17:30:55
Daniel
deine Zeile:
xEin = Inputbox(...,Type:=64) erzeugt ein eindimensionales Array, wenn die eingelesen Werte nebeneinander stehen (A1:D1)
stehen sie untereinander(A1:A4) bekommst du ein zweidimensionales Array.
Besser wärs vielleicht, wenn in der Inputbox zunächst die Zellbereiche abfragst (Type:=8), dann kannst du einfacher abfragen, ob ein- oder zweidimensional und entsprechen reagieren.
Bei Arrays wüsste ich jetzt nicht, wie man das ermittelt, bei Ranges einfach über .Rows.Count bzw .Columns.Count
Gruß Daniel
LBound/UBound(..., 1 bzw 2) -- orT
09.09.2017 06:09:11
Luc:-?
Morrn, Luc :-?
Besser informiert mit …
Anzeige
AW: LBound/UBound(..., 1 bzw 2) -- orT
10.09.2017 13:31:33
Daniel
nicht ganz passend Luc.
es geht primär nicht um die Anzahl der indizes einer bestimmten Dimension, sondern um die Anzahl der Dimensionen des Arrays.
Die Inputbox typ 64 kann nämlich sowohl 1-d als auch 2-d Arrays erzeugen.
Gruß Daniel
Man kann aus der TextEingabe jeder IpBox ...
10.09.2017 16:04:51
Luc:-?
…2d-Arrays erzeugen, Daniel,
wenn man entsprd trennbar notiert. Und deren Elemente-Anzahl kann man auch mit UBound+1-LBound pro Dimension bestimmen. Hat das Array nur 1 Dimension, läuft L/UBound(…,2) in einen Fehler, den man abfangen/-fragen kann. Schon weiß man, wieviel-di­men­sional das Array ist! Nichts Anderes war gemeint…
Luc :-?
Anzeige
AW: Man kann aus der TextEingabe jeder IpBox ...
10.09.2017 16:09:11
Daniel
warum schreibst du das nicht gleich so, wie du es meinst?
und mit abzufangenden Fehlern zu arbeiten ist jetzt auch nicht besonders elegant.
Gruß Daniel
Viell, mache ich aber schon lange so! ;-] owT
10.09.2017 16:54:10
Luc:-?
:-?
Die gibt's auch noch weiter, Lupo! ;-] orT
10.09.2017 04:06:45
Luc:-?
Das Tutorial gehört ja PHs FirmenSeite…
Morrn, Luc :-?
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 17:27:02
Martin
Mensch Daniel,
das ist ja unglaublich ! Du bist ein echter VBA-Held ... Da wäre ich NIE drauf gekommen, hätte nicht mal die Möglichkeit in Erwägung gezogen.
Vielen Dank an Dich !
Schade, dass die Flexibilität durch die Methode "Inputbox-64-2D-Array" verloren geht. Kannst du mir noch abschließend einen Tip geben, wie ich abfragen / auswerten kann, ob in Zeilen oder Spalten eingegeben wurde (ohne den Bediener zu fragen, was er zu tun gedenkt)?
Viele Grüße,
Martin
Anzeige
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 17:45:12
Daniel
Hi
hast du meine anderen Antworten gelesen?
ich würde in der Inputbox zunächst nur die Zellbereiche ermitteln (range-Variable und Typ 8) und dann die Werte aus diesen Range-Variablen in ein Array schreiben.
Dann sind diese Arrays immer 2-D mit 1 als LBound-Wert (außer es wird nur ein Wert eingegeben, dann bekommst du kein Array, sondern einen Einzelwert)
allerdings brauchst du dann zwei Schleifen, nämlich über Zeilen und Spalten:
for z = 1 to Ubound(arr, 1)
for s = 1 to Ubound(arr, 2)
... arr(z, s)...
next
next
für die Ergebnisausgabe würde ich auch ein 2-D-Array verwenden, weil du dass dann ohne Schleife diretk in die Exceltabelle zurückschreiben kannst.
Hierbei kannst du dir dann immer noch aussuchen, ob du das Ergebnis einzeilig, einspaltig oder entsprechend der User-Vorgaben ausgeben willst.
Im Prinzip kannst du damit dann auch echte 2-D-Arrays mit mehren Zeilen und mehren Spalten verarbeiten.
Den Sonderprozess, denn du allerdings abfangen musst, ist wie schon erwähnt der Fall, das jeweils nur ein Wert eingegeben wird.
Aber auch das könnte man entsprechend lösen:

dim RngEingabe as Range
dim arr
Set RngEingabe = Application.Inputbox(...Type:=8)
if rngEingabe.Cells.Count = 1 then
redim arr(1 to 1, 1 to 1)
arr(1, 1) = RngEingabe.Value
Else
arr = RngEingabe.Value
end If
dann ist dein arr auch bei einem Einzelwert ein echtes 2-D-Array, so dass du in der Folge keine weitere Fallunterscheidung benötigst.
Gruß Daniel
Anzeige
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 19:14:45
Martin
Hallo Daniel,
ich bin noch am verkraften und am verarbeiten ... Nett, dass Du Dich so kümmerst ! Deine letzte Antwort hatte ich noch nicht gesehen, da:
Ich hatte mich für die 2. Möglichkeit (aus evl. 2D-Array mach' ein 1D-Array) entschieden. Bin jetzt aber auf ein Phänomen gestoßen, das mich grübeln lässt und ich nicht nochmal ins Forum gesehen habe. Ich mache ja für x und y (fast) das gleiche. Daher ist die Überraschung groß, da beim Befüllen des neuen y-Array der Indexbereich nicht gültig ist [yEin(i) = ykoo].
Wenn Du Lust und Zeit hast würde es mich freuen, wenn Du da nochmal kritisch drüber sehen würdest. Nachfolgend das Makro.

Danke nochmal an Dich !

Viele Grüße,
Martin
Sub PolygonRotation()
'rotierte Abbildung: x' = x0 + [(x-x0)*cos(w)] - [(y-y0)*sin(w)]
'rotierte Abbildung: y' = y0 + [(x-x0)*sin(w)] + [(y-y0)*cos(w)]
Const Pi As Single = 3.14159265358979
Dim i As Long 'Zaehlvariable
Dim xkoo 'nicht definiert, da x-Koordinaten in Array verwendet werden
Dim ykoo 'nicht definiert, da y-Koordinaten in Array verwendet werden
Dim xEinRoh As Variant '2D-Array
Dim yEinRoh As Variant '2D-Array
Dim xEin As Variant '1D-Array
Dim yEin As Variant '1D-Array
Dim xAus As Variant '1D-Array
Dim yAus As Variant '1D-Array
Dim xDrehpunkt As Single, yDrehpunkt As Single
Dim WinkelGrad As Single, WinkelBogen As Single
'Bereich der EinRoh-Koordinaten abfragen
xEinRoh = Application.InputBox(prompt:="Bereich der zu rotierenden x-Koordinaten", Title:=" _
Ausgangs-Koordinaten: Bereich wählen", Type:=64)
If VarType(xEinRoh) = vbBoolean Then Exit Sub
yEinRoh = Application.InputBox(prompt:="Bereich der zu rotierenden y-Koordinaten", Title:=" _
Ausgangs-Koordinaten: Bereich wählen", Type:=64)
If VarType(yEinRoh) = vbBoolean Then Exit Sub
'Plausibilitaetspruefung der EinRoh-Koordinaten
If (UBound(xEinRoh) - LBound(xEinRoh))  (UBound(yEinRoh) - LBound(yEinRoh)) Then
MsgBox "Abbruch: Anzahl der x/y - Koordinaten waren ungleich !"
Exit Sub
End If
'EinRoh-Arrays in 1D-EinArrays umwandeln, KnowHow: Daniel, http:/ _
/www.herber.de
(08.09.2017)
ReDim xEin(1 To (UBound(xEinRoh, 1) - LBound(xEinRoh, 1) + 1) * (UBound(xEinRoh, 2) - LBound( _
xEinRoh, 2) + 1))
For Each xkoo In xEinRoh
i = i + 1
xEin(i) = xkoo
Next xkoo
ReDim yEin(1 To (UBound(yEinRoh, 1) - LBound(yEinRoh, 1) + 1) * (UBound(yEinRoh, 2) - LBound( _
yEinRoh, 2) + 1))
For Each ykoo In yEinRoh
i = i + 1
yEin(i) = ykoo
Next ykoo
'Drehpunkt-Koordinaten und Drehwinkel abfragen
xDrehpunkt = Application.InputBox(prompt:="Drehpunkt: x-Koordinate", Title:="Drehpunkt und - _
winkel", Type:=1)
If VarType(xDrehpunkt) = vbBoolean Then Exit Sub
yDrehpunkt = Application.InputBox(prompt:="Drehpunkt: y-Koordinate", Title:="Drehpunkt und - _
winkel", Type:=1)
If VarType(yDrehpunkt) = vbBoolean Then Exit Sub
WinkelGrad = Application.InputBox(prompt:="Drehwinkel in Grad", Title:="Drehpunkt und -winkel",  _
Type:=1)
If VarType(WinkelGrad) = vbBoolean Then Exit Sub
'Winkelumrechnung
WinkelBogen = WinkelGrad * Pi / 180
'Ausgabe-Arrays initialisieren
ReDim xAus(LBound(xEin) To UBound(xEin))
ReDim yAus(LBound(yEin) To UBound(yEin))
'Rotation: Berechnen der Koord.-AusArrays
For i = LBound(xEin) To UBound(xEin)
xAus(i) = xDrehpunkt + ((xEin(i) - xDrehpunkt) * Cos(WinkelBogen)) - ((yEin(i) - yDrehpunkt) _
* Sin(WinkelBogen))
yAus(i) = yDrehpunkt + ((xEin(i) - xDrehpunkt) * Sin(WinkelBogen)) + ((yEin(i) - yDrehpunkt) _
* Cos(WinkelBogen))
Next i
'Ausgabe der rotierten Koordinaten
For i = LBound(xEin) To UBound(xEin)
Cells(9 + i, 2) = xAus(i)
Cells(9 + i, 3) = yAus(i)
Next i
End Sub

Anzeige
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 19:20:40
Daniel
Schau dir mal deine Zählervariable i an.
Wenn du die für beide Arrays benutzt und der Index beim zweiten Array wieder bei 1 beginnt, was musst du dann mit i machen?
Gruß Daniel
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 19:32:01
Martin
... zurück auf 0 setzen.
Dank' Dir !
Martin
(etwas überfordert)
AW: Zuweisung aus Zellbereich ist IMMER 2-D
08.09.2017 19:27:13
Martin
P.S. zu meiner letzte Nachricht ...
Ich fand' die Idee, die Arraygröße mit 1 zu multiplizieren (so rum oder so rum) echt genial. Deshalb bin ich da auch rein.
Nun werde ich es doch mit den 2D-Arrays versuchen Inputbox(Type:=8).
Viele Grüße,
Martin

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige