Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1540to1544
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

Post-Check Loop, Abbruchbed. scheitert

Post-Check Loop, Abbruchbed. scheitert
17.02.2017 19:55:21
Thomas
Hallo,
ich lerne seit 3 Monaten Learning by Doin' VBA für Excel, um für die Arbeit Messreihen automatisiert auswerten zu können. Das klappt bis jetzt alles ganz gut und mal ein riesiges Danke, diese Internetseite hat bis jetzt immer meine Probleme lösen können! :)
nun komme ich leider nicht weiter und hoffe, dass diese Portal mir wie gewohnt helfen kann.
Wenn zum Verständnis etwas fehlt, bitte melden.
also:
Option Explicit
Dim rng As Range
Dim search As Variant
Dim slot As Variant
Dim b As Integer
Dim a As Integer
a = 6810
search = "10" '//z.B
'Do
Set rng = ActiveSheet.Range(Cells(a, 1), Cells(Sheets("Korrektur").UsedRange.Rows.Count, 1)).Find(search)
slot = rng.Value
'a = rng.Row + 1
'Loop Until Len(search) = Len(slot)
ich suche in meiner Spalte A, im gewählten Abshnitt ab Zelle 6810 den Wert 10. In dieser Spalte sind Die Zahlen von 4000 bis 600 absteigend eingetragen
im Anschluss will ich einen Bereich kopieren, beginnend bei meiner gefundenen Zielzeile. Der Kopierteil (nachfolgend) funktioniert
Sheets("Korrektur").Range(Cells(a, 1), Cells(a + 100, Sheets("Korrektur").UsedRange.Columns.Count)).Copy '//100 Zellen weit nach unten, 100 nur Bsp,das ist sonst eine Variable
Sheets("Normierung").Select
ActiveSheet.Rows(b).Range("A4").PasteSpecial xlValues '//b wird wo anders gesetzt
Application.CutCopyMode = False
ich hoffe, das reicht als Umriss.
wenn ich die Routine, wie sie dort steht, laufen lassen, funktioniert sie.
Problem ist, er findet, da absteigend gereiht in Spate A, nicht als erstes die 10 sondern die 3910 und meint er wäre fertig.
Daher habe ich die auskommentierte Loop entworfen.
Er soll so lange suchen, bis die Zeichenlänge meines Suchwortes 'search' der des gefundenen 'slot' entspricht. Wenn es keine Entsprechung ist, soll er die Zeilenzahl, rng.row in 'a' Speichern, die bei der nächsten Iteration den zu durchsuchenden Range verkleinert, sodass er nicht wieder denselben Wert liefert.
Ich dachte das wäre ganz fuchsig. Allerdings wird niemals die Bedingung der Schleife erfüllt und das verstehe ich nicht. Excel hängt sich jedesmal auf. Vllt übersehe ich auch etwas Banales.
Was ich auch nicht begreife ist, wenn ich das "+1" zu rng.Row addiere bekomme ich die Fehlermeldung "Objektvariable oder With-Blockvariable wurde nicht festgelegt", vorher nicht. Dies lässt sich aber durch ein IF à la "If Not rng ist Nothing Then" beheben. Das weiß ich aber erst genau, wenn ich mein Loop Problem gelöst habe.
Schon einmal vielen Dank fürs überhaupt Durchlesen
VG
Thomas

8
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Post-Check Loop, Abbruchbed. scheitert
17.02.2017 22:06:04
Max2
Hallo,
du verwendest hier eine Fuß gesteuerte Schleife, also eine Nachprüfende.
Die Schleife wird gestartet aber das Kriterium wird erst anschließend geprüft.
Auf die Länge zu Prüfen macht keinen Sinn !?
20 hat die gleiche Länge wie 10!
Prüfe also auf Inhalt und nicht auf Länge...
Am besten wäre es wenn du uns eine Beispiel Mappe mit dem Code gibst, dann kann sich jeder austoben.
Desweiteren solltest du versuchen die Code Zeilen relativ kurz zu halten.
Ich weiß viele sind faul beim deklarieren,
aber eine Variable für dein Sheet (z.B. "Dim ws As Worksheet")
würde den Code übersichtlicher machen.
Hier einfach Quick and Dirty ein bisschen Code:
(keine Ahnung ob das Funktioniert, hab es nicht getestet da ich
keine Mappe nachbauen möchte)

Option Explicit
Sub xy()
Dim ws As Worksheet
Dim rng, c As Range
Dim search As String 'Da du bei der Initialisierung einen String angibst
'brauchst du search nicht als Variant
Dim b As Long  'Zeilen gebe ich persönlich immer als Long an
Dim a As Long  'a und b würde ich umbenennen
'in z.B. lzeile u. lzeile_2
a = 6810
search = "10"
Set ws = ThisWorkbook.Sheets("Korrektur")
With ws
b = .Cells(.Rows.Count, 1).End(xlUp).Row 'letzte Zeile in Spalte A
Set rng = .Range(.Cells(a, 1), .Cells(b, 1))
For Each c In rng
If c.Value = search Then
.Range(.Cells(c.Row, 1), .Cells(b, 1)).Copy
...code code code
End If
End With
End Sub

Anzeige
AW: Post-Check Loop, Abbruchbed. scheitert
17.02.2017 22:25:09
Thomas
Servus Max,
danke für deine Antwort, ich arbeite das mal durch. Dennoch bleiben mir auf Anhieb zwei Fragen über
1. Was ist daran falsch es mittels einer fußgesteuerten Schleife zu probieren? Ich muss doch erst etwas finden, um die Bed. checken zu können?
2. 20 hat zwar die gleiche Länge wie 10, aber ich suche ja bspw die "10".. dann findet er keine 20 sondern nur andere Zahlen, die die "10" enthalten, wie zb 3910. Wenn ich dann die Länge des Gefundenen mit dem Gesuchten vergleiche, passt es oder nicht, aber es könnte niemals eine 20 auftauchen
im Anhang meine Excel Datei. Die Loop ist noch auskommentiert, das Sheet erscheint leer, aber ich musste einige Datensätze löschen, um hier nicht die Uploadgrenze zu sprengen.
https://www.herber.de/bbs/user/111561.xlsm
Bestes
Thomas
Anzeige
Mein Fehler!
17.02.2017 22:40:37
Max2
Sorry, da habe ich nicht richtig gelesen.
Da hast du natürlich recht!
Wenn du allerdings eine Zahl die 10 enthält suchst und anschließend den Bereich
bis zur letzten Zelle kopierst und einfügst und das ganze in einer Schleife
passiert, dann wird natürlich nach jeder gefundenen 10 der Bereich kopiert.
Sollte nur ab dem ersten Vorkommnis kopiert werden, dann sollte das ganze in einer
If Abfrage ö.ä. geschehen.
Deine Mappe mit Code schaue ich mir morgen nochmal genau an,
habe sie nur kurz überflogen.
Für heute ist mein Hirn Matsch.
Durchlaufe mal deinen Code Schritt für Schritt mit dem Debugger.
Anzeige
AW: Post-Check Loop, Abbruchbed. scheitert
17.02.2017 23:05:18
Werner
Hallo Thomas,
sorry, aber dein Code zum Suchen sieht mir etwas wirr aus.
Dim search As Variant
- warum? so wie es aussieht suchst du nach Ganzzahlen also besser As Long
search = "10"
-warum ""? so übergibst du einen Text
Set rng = ActiveSheet.Range(Cells(a, 1), Cells(Sheets("Korrektur").UsedRange.Rows.Count, 1)).Find(search)
- hier einmal ActivSheet dann Sheet("Korrektur") ist das nicht das gleiche Blatt?
- auf UsedRange zum Ermitteln der letzten Zeile würde ich verzichten, ist unsichder
-Abfrage für den Fall dass der Suchbegriff nicht gefunden wird fehlt (dann knallts)
-bei der Find-Methode sollten immer die Parameter mit angegeben werden
Vielleicht hilft dir ja das weiter:
Public Sub Suchen()
Dim loLetzte As Long
Dim loSuche As Long
Dim loZeile As Long
Dim rngFund As Range
Dim rngBereich As Range
loSuche = 10
loZeile = 6810
With Sheets("Korrektur")
loLetzte = .Cells(.Rows.Count, 1).End(xlUp).Row 'letzte Zeile in Spalte A, ggf. anpassen
Set rngBereich = .Range(.Cells(loZeile, 1), .Cells(loLetzte, 1))
Set rngFund = rngBereich.Find(what:=loSuche, LookIn:=xlValues, LookAt:=xlWhole)
If Not rngFund Is Nothing Then
MsgBox rngFund.Row
'hier statt MsgBox dein Code zum Kopieren
Else
MsgBox "Nichts gefunden"
End If
End With
End Sub
Gruß Werner
Anzeige
AW: Post-Check Loop, Abbruchbed. scheitert
18.02.2017 00:08:25
Thomas
Hallo Werner,
vielen Dank für die Antwort.
Mir ist klar, dass mein Anfänger Code für eure Augen etwas verwirrend und ineffektiv erscheint :D
Ich habe "search" als Variant deklariert, da ich dachte, .Find würde mit einem Variant arbeiten, da doch auch die Zellen eines Sheets grundsätzlich Format Variant haben - oder liege ich da falsch?
Die Zuweisung "10" war nur ein Bsp, im Programm selbst kommt der Wert wo anders her, aus einem Array in dem Integer gespeichert sind. Ich habe search nun erstmal auch als Integer deklariert. Ich glaube aber, es würde auch als Variant funktionieren, oder nicht?
Ich ändere die Integer wohl noch in Double, hier kommen schnell große Zahlen und Speicher ist ja heute kein Problem mehr :D
Abfrage als Anker, Suchparameter und auch die Alternative zum UsedRange.Rows habe ich eingebaut. Auch den Befehlsblock via With/End With, Alternative zum UsedRange.Coulumns werde ich auch noch einführen:
With Sheets("Korrektur")
search = x(j)
c = .Cells(.Rows.Count, 1).End(xlUp).Row
Set rng = .Range(Cells(a, 1), Cells(c, 1))
MsgBox search
Set target = rng.Find(what:=search, LookIn:=xlValues, LookAt:=xlWhole)
'
If Not target Is Nothing Then
MsgBox target.Row
a = target.Row
.Range(Cells(a, 1), Cells(a - y(j) + x(j), Sheets("Korrektur").UsedRange.Columns.Count)).Copy
Sheets("Normierung").Select
ActiveSheet.Rows(b).Range("A4").PasteSpecial xlValues
Application.CutCopyMode = False
Else
MsgBox "Nichts gefunden"
End If
End With
und siehe das, es funktioniert :) Vielen Dank euch beiden.. Ich habe das mit den With-Block nun verstanden und werde meinen Code mal überarbeiten, dass er ein wenig durchsichtiger wird, falls ich nochmal eine Frage habe.
Dank euch :)
Anzeige
AW: Post-Check Loop, Abbruchbed. scheitert
18.02.2017 01:36:06
Werner
Hallo Thomas,
ein paar Antworten zu deinen Fragen.
Eine Zelle auf einem Blatt ist ein Range Objekt
Eine Variable vom Typ Variant kann verschiedene Werte aufnehmen, deshalb auch Variant. Wenn du einer Variant Variablen eine Ganzzahl zuweist, dann wird sie quasi zu einer Long- Variablen. Nachteil ist, Excel braucht dafür Rechenzeit und es wird mehr Speicherplatz verbraucht.
Der Find Funktion übergibst du ja nicht die Variable selbst, sondern deren Inhalt. Ob das dann eine Variable vom Typ Long, Integer, String oder Variant ist, ist dann eigentlich egal. Es wird ja der Inhalt der Variablen in deinem angegebenen Bereich gesucht. Insofern hast du recht, das geht natürlich auch mit einer Variablen vom Typ Variant.
UsedRange würde ich vermeiden, das ist ein usicherer Kandidat, besser die letzte Zeile wenn möglich direkt in der entsprechenden Spalte bzw. die letzte Spalte direkt in der entsprechenden Zeile ermitteln.
So ganz verstanden hast du das mit dem With - End With doch noch nicht. Dabei geht es um die korrekte Referenzierung auf ein bestimmtes Objekt. Eigentlich müsstest du um z.B. eine Range korrekt zu Referenzieren vor jedes Range-Objekt (Range, Cells) das Tabellenblatt schreiben und das ist etwas umständlich. Vereinfachen kannst du das durch das With - End With. Dann musst du aber für die korrekte Referenierung innerhalb des With - End With Blocks vor jedes Range Objekt einen Punkt setzen. Bei deinem Code fehlen da welche.
ein Code
Set rng = .Range(Cells(a, 1), Cells(c, 1))
.Range(Cells(a, 1), Cells(a - y(j) + x(j), Sheets("Korrektur").UsedRange.Columns.Count)).Copy
korrekt Referenziert
Set rng = .Range(.Cells(a, 1), .Cells(c, 1))
.Range(.Cells(a, 1), .Cells(a - y(j) + x(j), .UsedRange.Columns.Count)).Copy
Dann übergibst du die Zeilennummer deiner target einer Variablen. Das kannst du dir eigentlich auch sparen, du kannst die target selbst benutzen.
.Range(.Cells(target.Row, 1), .Cells(target.Row - y(j) + x(j), .UsedRange.Columns.Count)).Copy
Und last but not least solltest du wenn immer möglich (und das ist fast immer) Select vermeiden (kostet nur Rechenzeit und meistens überflüssig).
Sheets("Normierung").Rows(b).Range("A4").PasteSpecial xlValues
Application.CutCopyMode = False
Gruß Werner
Anzeige
AW: Post-Check Loop, Abbruchbed. scheitert
18.02.2017 12:40:28
Thomas
Hej Werner,
vielen Dank noch mal, das sind alles Dinge, auf die man beim Lernen/Aneignen nicht direkt alleine kommt. Vor allem die Effizienz meine Makros ist mir im wichtig, da es um eine Menge Daten gehen wird, wenn es fertig ist. Ich werde deine Hinweise bestmöglich anwenden und glaube das "With" nun verstanden zu haben, eine Abkürzung zur Adressierung an ein bestimmtes Objekt, Befehle, die sich auf das gleiche Objekt beziehen, kann ich so zsm. packen in einen Block.
Bestes und ein schönes RestWE
Thomas
AW: Gerne u. Danke für die Rückmeldung. o.w.T.
18.02.2017 13:55:26
Werner

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige