PDA

Vollständige Version anzeigen : Immer dieses Offset...


Vigo2
27.06.2014, 10:19
Hallo zusammen!

Ich hab echt Probleme diese Offset- Funktion zu begreifen!

Ich hab folgenden Code und mehrmals diese Offset-Funktion verwendet.
Schon beim ersten Verwenden, bekomme ich eine Fehlermeldung (laufzeitfehler0424: Objekt erforderlich)

Option Explicit

Sub xy()

Dim wkshinter As Worksheet
Dim wkshilf As Worksheet
Dim g As Long
Dim h As Long
Dim lest As Long
Dim llest As Long
Dim b As Integer
Dim par As Variant
Dim qar As Variant
Dim rar As Variant
Dim bereich As Range
Dim zelle As Range
Dim i As Long
Dim zelle1 As Variant
Dim x As Range
Dim strWort As String
Dim lngAnfang As Long, lngEnde As Long
Dim rngZelle As Range
Dim rngZelle2 As Range

Set wkshinter = Worksheets("Hintergrundtabelle")
Set wkshilf = Worksheets("Hilfstabelle")

With wkshinter
lest = Sheets("Hintergrundtabelle").Cells(Rows.Count, 6).End(xlUp).Row
If lest < 2 Then lest = 2
End With

With wkshilf
llest = Sheets("Hilfstabelle").Cells(Rows.Count, 2).End(xlUp).Row
If llest < 2 Then llest = 2
End With

With wkshinter
h = 2
For Each zelle1 In .Range("F2:F" & .Cells(Rows.Count, 6).End(xlUp).Row)
h = h + 1

par = wkshinter.Cells(h, 6).Value 'Rhythmus, an dem angeliefert wird
qar = wkshinter.Cells(h, 6).Offset(0, -2).Value 'Bedarfsvorlaufzeit
rar = -qar '"x" versetzen nach links um Bedarfsvorlaufzeit
If par = "TAG" Then
wkshilf.Range(Cells(llest, 2), Cells(llest, 21)) = "x"
'"x" unter Berücksichtigung Bedarfsvorlaufzeit versetzen (qar)
Application.ScreenUpdating = False
For i = 1 To qar
Range("B2:U2").Cut Destination:=Range("A2:T2")
Range("A2").Cut Destination:=Range("U2")
Application.ScreenUpdating = True
Next
'Abstand zwischen "x" ermitteln
strWort = "x"
'wenn "x" mehr als 1x vorkommt
If Application.CountIf(wkshilf.Range(Cells(llest, 2), Cells(llest, 21)), strWort) > 1 Then
Set rngZelle = wkshilf.Range(Cells(llest, 2), Cells(llest, 21)).Find(strWort, lookat:=xlWhole, LookIn:=xlValues)
If wkshilf.Cells(llest, 2) = strWort Then Set rngZelle = wkshilf.Cells(llest, 2)
lngAnfang = rngZelle.Row
rngZelle.Offset(1, 0) = par.Offset(0, 6) 'Startwert setzen
Do
Set rngZelle2 = wkshilf.Range(Cells(llest, 2), Cells(llest, 21)).FindNext(after:=rngZelle)
If Not rngZelle2 Is Nothing Then
lngEnde = rngZelle2.Row
If lngEnde > lngAnfang Then
rngZelle.Offset(2, 0) = (rngZelle2 - rngZelle + 1) * par.Offset(0, 6).Value
rngZelle.Offset(3, 0) = rngZelle.Offset(1, 0).Value + rngZelle.Offset(2, 0).Value
rngZelle.Offset(4, 0) = rngZelle.Offset(2, 0)
rngZelle.Offset(5, 0) = rngZelle.Offset(3, 0).Value - rngZelle.Offset(4, 0).Value
Set rngZelle = rngZelle2
lngAnfang = lngEnde
End If
End If
Loop Until lngEnde < lngAnfang
'wenn "x" nur 1 x vorkommt
ElseIf Application.CountIf(wkshilf.Range(Cells(llest, 2), Cells(llest, 21)), strWort) = 1 Then
Set rngZelle = wkshilf.Range(Cells(llest, 2), Cells(llest, 21)).Find(strWort, lookat:=xlWhole, LookIn:=xlValues)
rngZelle.Offset(1, 0) = par.Offset(0, 6).Value
End If
End If
Next
End With

End Sub


rngzelle als auch par sind doch als Objekt definiert. Oder etwa nicht?
Weiß jemand hier, was ich ändern muss? Das wäre super!

Viele Grüße, Vigo2

mumpel
27.06.2014, 10:22
Hallo!

par ist als Variant deklariert, rngZelle ist als Range deklariert. Wenn Du ein Object haben möchtest musst Du es auch so deklarieren. Das hat aber mit der Fehlermeldung nichts zu tun.

Gruß, René

Vigo2
27.06.2014, 10:32
Hallo Mumpel,

hat also nichts mit zu tun. Dann versteh ich erst recht nicht, was ich falsch gemacht hab.

Mit diesem Befehl möchte ich bewirken, dass wenn ein "x" gefunden wurde, darunter der Wert aus par.Offset(0, 6) eingetragen wird.

Achso und
rngZelle.Offset(1, 0) = par.Offset(0, 6).value
bringt leider denselben Fehler!

VG, Vigo

Vigo2
27.06.2014, 10:38
Ich hab nun folgendes hingeschrieben:

(Vorher)
rngZelle.Offset(1, 0) = par.Offset(0, 6)

(jetzt)
rngZelle.Offset(1, 0) = wkshinter.Cells(h, 6).Offset(0, 6)

Dann stört er sich wohl an dem .value bei par = wkshinter.Cells(h, 6).Value...

Mc Santa
27.06.2014, 10:39
Hallo,

in par steht ein Text und kein Verweis auf eine Zelle!
par = wkshinter.Cells(h, 6).Value

wenn du in par die Zelle selbst speicherst, dann kannst du auch offset benutzen.
Set par = wkshinter.Cells(h, 6)

Bitte beachte, dass sich das auf den restlichen Code auswirken könnte, das habe ich auf die schnelle nicht überprüft.
Hilft idr das weiter?

VG

EarlFred
27.06.2014, 10:40
Hallo Vigo2,

Grundlagenschulung, Kurzabriss:

Eine Zelle oder ein Bereich auf einem Tabellenblatt ist ein Objekt der Klasse Range. Also nimm für die Speicherung der Zellen und Bereiche selbst eine Variable des Typs RANGE.
Object ist der "Sammelbegriff" für alles, was ein Objekt ist: Bereich, Tabellenblatt, Mappe - endlose Liste. Mach es konkret, nimm Range, wenn Range gemeint ist!
Eine Objekt vom Typ Range besitzt Eigenschaften und Methoden.
Das Kopieren der Range übernimmt beispielsweise die METHODE Copy.
Eine Eigenschaft ist beispielsweise VALUE - der Wert in der Zelle.
Wenn Du einer Variable den WERT / Value zuweist, kann diese Variable selbst NIE eine Range sein! Entweder ist diese Zahl oder Text oder Datum oder... oder, wenn man es vorher nicht weiß, eben Variant.

"Variant" kann "alles" sein. Eben auch ein Objekt. Auch hier: Wenn Du eine RANGE ansprechen willst, nimm also weder Object noch Variant!


Dein Code:
Dim par As Variant
par = wkshinter.Cells(h, 6).Value
PAR IST DAMIT KEINE RANGE! Par kennt auch nicht die Methoden oder Eigenschaften einer Range - sondern ist ein "dummer" Wert. Nicht mehr.
Du kannst also OFFSET NICHT auf Par anwenden.

Klar soweit?

Grüße
EarlFred

mumpel
27.06.2014, 10:40
par sollte Range sein, nicht Variant.

R J
27.06.2014, 10:42
Hi,

Du kannst ein Offset nicht auf eine Variable mit dem Wert "TAG" machen. Wie soll das denn gehen?
Du kannst aber einen Offset von der Zelle, die "TAG" enthält machen. Und das ist, wenn ich das jetzt richtig sehe, die Zelle "wkshinter.Cells(h, 6)"
Hab jetzt nicht nachgesehen, ob sich h noch irgendwo verändert, wenn nicht, könntest Du also den Offset so gestalten:
rngZelle.Offset(1, 0) = wkshinter.Cells(h, 6).Offset(0, 6)

mumpel
27.06.2014, 10:45
[...] Das hat aber mit der Fehlermeldung nichts zu tun [...]

Muss ich auch ein wenig korrigieren. "Objekt erforderlich" sagt nicht dass man als "Object" deklarieren muss.

Vigo2
27.06.2014, 10:58
Danke für eure Rückmeldungen! Dann werd ich mir mal meinen Code noch einmal anschauen und eure Tipps und Erläuterungen berücksichtigen!

Viele Grüße, Vigo2

EarlFred
27.06.2014, 11:06
Hallo Vigo2,

noch als Ergänzung:
Die Zuweisung eines Objektes an eine Objektvariable erfordert immer das Schlüsselwort SET:Option Explicit
Sub test()


Dim rng As Range
Dim Wert As Variant

'---------------
'Den BEREICH (Zelle) A1 der Variable rng zuweisen:
Set rng = Range("A1")

'---------------

'Den WERT der Zelle A1 der Variable Wert zuweisen:
Wert = Range("A1")
'Wenn nichts angegeben ist, wird in den MEISTEN (nicht allen!) Fällen die Standardeigenschaft VALUE der Range angenommen.
'Die Zeile ist in diesem Fall deckungsgleich zu:
Wert = Range("A1").Value
'Die Eigenschaft Value anzugeben ist aber aus Gründen der Eindeutigkeit immer zu bevorzugen!

'---------------

'Variable = Range("A1") ist also etwas komplett anderes als
'Set Variable = Range("A1")
'Diesen Unterschied musst Du verstehen!

End Sub

Grüße
EarlFred