Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Shell bricht nach 111 Vorgängen ab

Begonnen von crystal, Oktober 12, 2016, 18:16:42

⏪ vorheriges - nächstes ⏩

MzKlMu

#15
Hallo,
ZitatEs scheint sich also heraus zu kristallisieren, dass es deshalb "knallt", weil ich über ein Recordset "loope".
nein, es knallt weil Du das Ereignis "Beim Anzeigen" (Form_Current()) nimmst.
Dass das ungeeignet ist, wurde bereits mehrfach gesagt. Gehe durch die Datensätze per Schleife die Du über einen Button startest. Und da kannst Du deinen Code fast unverändert übernehmen.

Private Sub BefehlsButton_Click()
    Dim objShell  As Object
    Dim objFolder As Object
    Dim objFolderItem As Variant
    Dim sfolder As Variant
    Dim i Ss Long
    sfolder = TopDir & "\" & SDir & "\" & FDir & "\"
For i = 1 To Dcount("*","Abfragename")   
    Set objShell = CreateObject("Shell.Application")
    Set objFolder = objShell.NameSpace(sfolder)
    'Schleife über alle Dateien
    For Each objFolderItem In objFolder.Items
        If objFolderItem.Name = MovieFileName Then
            MovieFileType = Right(objFolder.GetDetailsOf(objFolderItem, 158), 3)
            MovieFileSize = objFolder.GetDetailsOf(objFolderItem, 1)
            MovieFileLength = objFolder.GetDetailsOf(objFolderItem, 27)
            MovieFileResX = objFolder.GetDetailsOf(objFolderItem, 306)
            MovieFileResY = objFolder.GetDetailsOf(objFolderItem, 308)
            Exit For
        End If
    Next
    Set objFolderItem = Nothing
    Set objFolder = Nothing
    Set objShell = Nothing
    DoCmd.GoToRecord , , acNext
Next i
End Sub

Ob die Schleife (For i = 1 ...) an der richtigen Stelle beginnt weis ich gerade nicht. Musst Du prüfen.
Das sollte durchlaufen.
Gruß Klaus

Josef P.

#16
Hallo!

Um das Problem von DoCmd.GoToRecord innerhalb der Ereignisbehandlung besser zu erkennen, bitte folgenden Code ausprobieren und die Ausgabe im Direktbereich lesen.

Private Sub Form_Current()

Static Cnt As Long
Dim TempCnt As Long

Cnt = Cnt + 1
TempCnt = Cnt

Debug.Print "Start ...", TempCnt

On Error Resume Next ' weil ich das Erreichen des letzten DS nicht prüfen will :)
   If Err.Number = 0 Then
      DoCmd.GoToRecord , , acNext
   End If

Debug.Print "... Ende ", TempCnt

End Sub


Wer die Ausgabe
Start ... 1
... Ende 1
Start ... 2
... Ende 2
...
erwartet, der irrt. ;-)

mfg
Josef

crystal

Dank an Josef P. und MzKlMu!

Neue Erkenntnisse: wenn ich das goto-next auskommentiere, kann ich im Formular durch Drücken und Festhalten der Bild-Runter-Taste komplett ohne Fehler durch mein Recordset 'loopen', z.B. auch über 250 DS (mehr als 2*111). Und alles im Current-Event.

Also arbeitet DoCmd.GoToRecord anders als die GUI-Funktion Bild-runter. Kann mir jemand den Unterschied erklären?
Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

Aus gesundheitlichen Gründen nur noch selten dabei...

daolix

Das problem ist das du durch DoCmd.GoToRecord in Form_Current einen rekursiven Aufruf provozierst, d.h. du startest das Formular, Form_Current wird ausgelöst, dieses ruft  DoCmd.GoToRecord auf wodurch für den nächsten Datensatz wiederum Form_Current aufgerufen wird, aber das vorhergehende Form_current nicht beendet wird. Mit jedem Aufruf der Funktion muss aber neuer Speicher für die Funktion und deren Variablen reserviert werden, aber dieser  ist beschränkt, so das das system irgendwann mit einem Stackoverflow reagiert.

MzKlMu

Hallo,
@daolix
Das dürfte die Ursache sein, ich habe ähnliches vermutet, konnte es aber nicht so in Worte fassen. Ich denke, Deine Erklärung trifft es. Man könnte sagen, das Ereignis verhapselt sich oder es überholt sich selbst.  ;D

@Crystal
Hast Du mal meinen Vorschlag in #15 probiert. Das sollte auch anstandslos durchlaufen.

Gruß Klaus

Josef P.

#20
@crystal: hast du den Code von mir ausprobiert und darüber nachgedacht, warum die Ausgabe im Direktbereich zuerst den Start-Text über alle Datensätze zeigt und erst danach die Ende-Texte kommen?

Mein Code sollte genau das zeigen, was daolix im letzten Beitrag beschrieben hat. ;)

Die Ausgabe im Direktbereich durch den Codeablauf zeigt:
Start ... 1
Start ... 2
Start ... 3
...
Start ... n
... Ende n
...
... Ende 3
... Ende 2
... Ende 1

Auch das Verfolgen des Codeablaufs im Einzelschrittmodus sollte zeigen, wie der Code abgearbeitet wird.

mfg
Josef

crystal

Danke daolix!!!!

Das ist endlich eine plausible Erklärung, die selbst ich  ;) nachvollziehen kann.

Die Antwort meiner Frage ist also jetzt gegeben: Verwende kein docmd.gotorecord, weil es ein gewisses Eigenleben hat. Wo kann man es dann überhaupt benutzen? Immerhin arbeitet man doch immer mit dem current record. Vielleicht bei After_Update? Darf man es nur über einen Button aufrufen? Mir erscheint das doch etwas komisch und letztlich nicht logisch. Sorry.

Interessant wäre jetzt noch, das gute alte SendKeys zu bemühen, aber das ist wohl nicht nötig.

Wie in einem anderen Thread auch schon mitgeteilt, besteht die Lösung also schlicht und einfach darin, die Bild-Runter-Taste festzuklemmen.
Welch wunderbare Löung im Zeitalter der elektronischen Datenverarbeitung (Gruß an Eberhard). Ja - bei Konrad Zuse konnte man noch zusehen, wie Daten über Kabel huschten, um Relais anzustoßen. Ab und zu leuchtete eine Röhre auf und dann wußte man, dass gerade eine Multiplikation stattfand...

Und an Microsoft: wann werdet ihr endlich beginnen, zu dokumentieren, was ihr macht oder gemacht habt? Ein einfacher Hinweis würde ja schon reichen: "'docmd.gotorecord' verhält sich etwas anders, als man erwarten könnte, vor allem, wenn man es im current-eventhandler benutzt. Somit gibt es keine sinnvolle Verwendung dafür."

Ich verstehe schon. Docmd stammt aus einer Zeit, als man glaubte, alles über Menüs machen zu können, die man doch einfach nur ansteuern müsste. Ähnlich wie SendKeys. Und mit diesen Altlasten plagt man sich noch immer.

Aber genug: ich will hier nicht die Vor- und Nachteile von Microsofts Strategien, Qualitätskriterien usw. aufzählen. Es ist halt so, wie es ist und wie es sich kleine Programmierer kurz vor Release-Termin ausgedacht haben - ohne Rücksicht auf Konsequenzen, weil es dafür ja keine Zeit gab. Und deshalb kann Microsoft den Code auch nicht offenlegen, wie es früher bei VMS der Fall war und heute bei diversen Unix-Derivaten und anderen Betriebssystemen. Denn Microsoft würde sich der Lächerlichkeit preisgeben.

Wieder genug geschwafelt. Danke für eure Mitarbeit und eure Antworten!

Gruß

crystal
Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

Aus gesundheitlichen Gründen nur noch selten dabei...

MzKlMu

Hallo,
sag mal, liest Du eigentlich was man Dir schreibt ?
Probiere doch einfach mal meinen Vorschlag in #15.

Du musst Dich ja nur von Current verabschieden. Mit einer For Next Schleife sollte das mit DoCmd.GoToRecord , , acNext auch funktionieren. Auch ein Recordset zu öffnen und mit einer Schleife über die DS zu laufen wird auch gehen. Siehe #12.
Und dass Form_Current ungeeignet ist, hat Dir daolix in #2 schon geschrieben. Und nicht nur er.
Gruß Klaus

ebs17

Dim rs As DAO.Recordset
Set rs = Me.Recordset
With rs
   .MoveFirst
   Do While Not .EOF
      ' mach etwas
      .MoveNext
   Loop
   .Close
End With
Set rs = Nothing


Das wäre ein Beispiel für das Durchlaufen eines Formularrecordsets, wie oben schon mal angesprochen.
Aber die Verwendung von SendKeys oder das Festklemmen/-leimen einer Taste ist bestimmt spannender und bietet Raum für viel Diskussionen, insbesondere wenn man seine Thesen unter Ignoration von Hinweisen ständig wiederholt.

Viel Spaß und Glück.
Mit freundlichem Glück Auf!

Eberhard

Josef P.

#24
Hallo!

ZitatDie Antwort meiner Frage ist also jetzt gegeben: Verwende kein docmd.gotorecord, weil es ein gewisses Eigenleben hat.
Das wäre eine falsche Aussage.

GotoRecord hat überhaupt keine Besonderheiten in diesem Zusammenhang. Die Besonderheit wird eher sein, dass du noch etwas auf der Leitung stehst und noch nicht erkannt hast, was du programmiert hast.
Setzt doch einmal in meinem Beispiel einen Haltepunkt bei GotoRecord und lauf den Code im Einzelschrittmodus durch.
Dann solltest du sehen, dass die Ereignisbehandlungs-Methode nicht fertig durchlaufen wird, sondern nach dem GotoRecord ein neuer Aufruf erfolgt.

Vielleicht ist das Problem bei folgendem Code besser erkennbar:
private sub MachWas()

   ' irgendein Code
   ' ...

   MachNochWas

end Sub

private sub MachNochWas

   ' irgendein Code
   ' ...
   
   MachWas

end Sub


mfg
Josef

crystal

Hallo Klaus,

natürlich habe ich deinen Vorschlag gesehen und er ist ja auch absolut vernünftig.

Inzwischen hatte ich jedoch schon die "Bild-nach-unten"-Lösung gefunden und mich zuvor 111er-häppchenweise durch einen Großteil der DS gewühlt und auch einen Teil der Offline-Daten "scannen" und integrieren können, so wie ebs es vorgeschlagen hat.

Richtig ist, dass mehrere Menschen geantwortet und die Verwendung im Current-Event in Frage gestellt haben. Allerdings hat es niemand nachhaltig begründet. Erst jetzt werden die Abläufe klar (Dank daolix und Josef P.).

Und natürlich habe ich auch nicht immer die Gelegenheit, Vorschläge sofort zu testen.

Ich danke dir und anderen für die Vorschläge und euren Willen, sich mit diesem Thema zu beschäftigen.

Du musst aber auch zugeben, dass ein paar Antworten etwas am Kern-Thema vorbei gingen und so eine Lösung etwas verzögert haben.

Ich habe deine Lösung aus Antwort 15 tatsächlich nicht probiert, aber mir den Code (für eventuelle spätere Zwecke) kopiert. Denn ich bin sicher, dass er funktioniert.

Auch habe ich im Debugger das Local-Fenster intensiv beobachtet, dabei aber nur feststellen können, das form.currentrecord und form.seltop bis 111 hochlaufen. Weitere Erkenntnisse konnte ich nicht gewinnen, weil ich da zu unerfahren bin.


Ich habe den Thread auf erledigt gesetzt, weil ich eine vernünftige Erklärung dafür erhalten habe, was docmd.goto... macht.


Und an ebs17
Genau. Das ist die Lösung, auf die alle gewartet haben. Besonders die Erklärung zeigt, wie gut du doch einen generellen Blick für die Lösung von Problemen entwickeln kannst, selbst wenn du dabei bisweilen das Ziel und den Kern der Fragestellung ignorierst. Meisterhaft, wie du deine Denkweise einbringst und zum Paradigma zu machen in der Lage zu sein glaubst.

Josef P.
Ich habe deinen Code durchaus begriffen und gelernt, dass docmd... eine neue Instanz des Records erzeugt  und somit durch Rekursion irgendwann einen Overflow erzeugt. Oder so ähnlich.
Warum das so ist, hast du aber nicht gesagt, denn du hast nur gezeigt, was die Auswirkungen sind. Dass allein ist ja schon extrem hilfreich, beantwortet aber nicht alle meiner Fragen.
Und: wer oder was setzt die Sache nach Drücken von "Beenden" so zurück, dass es wieder für 111 DS funktioniert???


Nochmal: ich denke, meine Frage ist hinreichend gut beantwortet, weshalb ich den Thread ja auch auf erledigt gesetzt habe.

Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

Aus gesundheitlichen Gründen nur noch selten dabei...

ebs17

#26
ZitatDas ist die Lösung, auf die alle gewartet haben
Die steht aber schon in Antwort #6, Absatz 4.
Man muss es nur wahrnehmen wollen.
Und es ändert nichts daran, dass man auch da nur ein Shell-Objekt einsetzen würde.
Mit freundlichem Glück Auf!

Eberhard

crystal

Hallo ebs17,

herzlichen Glückwunsch zu deinem 600. Beitrag!

Glück noch mehr auf!

crystal
Wer Fehler in meinen Antworten findet, darf sie behalten, muss sie aber kommentieren. ;-)
Dies ist keineswegs arrogant gemeint, sondern soll nur unterstreichen, dass meine Antworten - natürlich - nicht immer fehlerfrei sind und sein können.
Devise: bitte immer erst selbst probieren!

Aus gesundheitlichen Gründen nur noch selten dabei...