2 Stimmen

VB6 Control Iteration: ein Control gibt mir einen Fehler; welches?

Ich versuche, eine Schleife durch alle Steuerelemente in einem Formular zu ziehen: For Each ctrl in Me.Controls um das Steuerelement auf der Grundlage einiger Bedingungen zu aktivieren/deaktivieren. Aber es gibt ein Steuerelement im Formular, das einen Fehler auslöst, wenn ich versuche, darauf zuzugreifen. Was für ein Steuerelement ist das, und wie finde ich es?

1voto

Jay Riggs Punkte 52013

Wenn Sie Ihren Fehler erhalten und auf Debuggen klicken, ist der Fehler in der Zeile, die die Eigenschaft Enabled eines Steuerelements festlegt?

Wenn ja, fügen Sie eine Debug.Print-Anweisung hinzu, die den Namen des Steuerelements ausgibt. Tun Sie dies in der Zeile vor der Einstellung der Eigenschaft Enabled.

Ich meine Folgendes:

Dim ctrl As Control
For Each ctrl In Me.Controls
    Debug.Print ctrl.Name
    ctrl.Enabled = True      
Next

Die Anweisung Debug.Print schreibt den Namen des Steuerelements, das zuletzt in der Schleife verarbeitet wurde, vermutlich das, das den Fehler verursacht hat, in das Immediate Window.

EDIT

Diese puede arbeiten. Setzen Sie dieses Steuerelement in ein Panel-Steuerelement und setzen Sie die Eigenschaft Enabled des Panels auf False. Wenn ich mich richtig erinnere, wird in VB6, wenn die Eigenschaft Enabled eines Container-Steuerelements auf False gesetzt wird, auch die untergeordneten Steuerelemente des Containers Enabled auf False gesetzt. Wenn die Enabled-Eigenschaft Ihres Steuerelements wirklich schreibgeschützt ist, bin ich neugierig, was passieren würde.

0 Stimmen

Wenn Sie versuchen, auf dieses Steuerelement zuzugreifen (z. B. in einer Schleife durch alle Steuerelemente, um sie zu debug.print), wird ein Popup-Fenster mit dem Hinweis "Property is write only" angezeigt, wenn dieses Steuerelement gefunden wird.

0 Stimmen

Der Fehler, den Sie beschreiben, ist, wenn Sie versuchen, die Eigenschaft "Aktiviert" des Steuerelements festzulegen, das Ihnen Probleme bereitet. Um welche Art von Steuerelement handelt es sich? Gibt es eine Eigenschaft Enabled, die Sie für das Steuerelement festlegen können, wenn Sie Ihr Formular im Designer anzeigen? Es ist möglich, dass die Enabled-Eigenschaft des Steuerelements schreibgeschützt ist - das ist es, was die Fehlermeldung, die Sie setzen, besagt. Siehe meine Bearbeitung für eine andere Idee, die funktionieren könnte.

1voto

Dan S Punkte 1176

Versuchen Sie dies:

Dim ctr As Control
Dim CtrStatus Boolean

CtrStatus = False

For Each ctr In Me.Controls

  If (SSTab.hwnd = GetParent(ctr.hwnd)) Then
    Call CallByName(ctr, "Enabled", VbLet, CtrStatus)
  else
    ctr.Enabled = CtrStatus
  End If

Next

0voto

AngryHacker Punkte 56638

Ein anderer Ansatz, der auch zur Laufzeit funktioniert (und nicht nur in der IDE), ist der folgende:

private sub SetEnabled()
  on error goto errHandle

  Dim ctrl As Control
  For Each ctrl In Me.Controls
    ctrl.Enabled = True      
  Next

  exitPoint:
    exit sub
  errHandle:
    MsgBox "Error " & err.Description & " with Control " & ctrl.Name
    resume exitPoint
end sub

0 Stimmen

SSTab gibt den Geist auf. Ich prüfe, ob der Container des Steuerelements ein bestimmter Frame ist, und aktiviere/deaktiviere ihn dann... "If ctrl.Container = fraMovies Then...". Aber wenn das Programm eine Schleife durchläuft und versucht, den Container von SSTab zu überprüfen, wird eine Ausnahme ausgelöst.

1 Stimmen

Ich vermute, dass SSTab keine Eigenschaft Enabled hat.

0 Stimmen

@AngryHacker: zuerst dachte ich auch, dass SSTab keine Enabled-Eigenschaft haben darf: aber tosa Die problematische Codezeile lautet keine Verwendung der Eigenschaft Enabled . Siehe meine Antwort für meine Sicht des Problems (= nicht Is). Ihre Antwort ist eine gute Antwort auf die ursprüngliche Frage, die stark darauf hindeutet, dass das Problem beim Ändern der Eigenschaft Enabled auftritt, anstatt zu versuchen, den Container des Steuerelements festzulegen.

0voto

MarkJ Punkte 29670

Tosa: aus Ihrem Kommentar zu AngryHacker's Antwort Ich glaube, Sie prüfen den Container falsch.

Ihr Code sieht folgendermaßen aus

 ' BAD CODE '
 If ctrl.Container = fraMovies Then

Bei mir ergibt das den Fehler 450 Wrong number of arguments or invalid property assignment . Erhalten Sie denselben Fehler?

Der Code sollte Folgendes verwenden Is statt = wie diese

 ' GOOD CODE '
 If ctrl.Container Is fraMovies Then

Erläuterung. Sie möchten prüfen, ob zwei Variablen auf dasselbe Steuerelement "zeigen". Steuerelemente sind Objekte: müssen Sie Is no = um zu prüfen, ob zwei Objektvariablen auf dasselbe Objekt "zeigen". Dies ist ein klassischer Fallstrick in VB6.

Ein letztes Wort. Könnten Sie das nächste Mal versuchen, 10 Zeilen oder weniger des tatsächlichen Codes zu posten, der den Fehler reproduziert, und die genaue Fehlernummer und -meldung sowie die genaue Zeile, in der er auftritt, angeben? Das macht es für uns viel einfacher, Ihr Problem zu lösen - ich weiß, dass es für Sie Arbeit ist, den Code zu kürzen, aber so bekommen Sie bessere Antworten.

EDIT Willkommen zurück! :) Sie sagten, einige Steuerelemente haben keine Container-Eigenschaft. Sie könnten versuchen, den Test in On Error Resume Next in etwa so.

 ' GOOD CODE '
 Dim bMatch As Boolean  
 Dim ctrl As Control 
 For Each ctrl In Me.Controls 
   bMatch = False  
   On Error Resume Next  
   bMatch = (ctrl.Container Is fraMovies)  
   On Error Goto 0 
   If bMatch Then  
     ctrl.Enabled = True       
   End If
 Next

0 Stimmen

Hallo, ich beschäftige mich wieder mit diesem Thema. Danke, das "is" funktioniert. Jetzt ist das Problem an der .container check portion. Es gibt Steuerelemente, die keinen Container haben (z. B. commondialog), und die Überprüfung auf einen Container gibt einen Fehler. Ich versuche, eine Schleife durch alle Objekte in einem Rahmen zu machen und sie zu deaktivieren. Dies sollte auch für alle Objekte in Frames gelten, die sich im ursprünglichen Frame befinden (iterative Schleife). Was ist der beste Weg dafür?

0 Stimmen

Hallo, danke für Ihre Antwort. Anstatt die Verarbeitung in der nächsten Zeile fortzusetzen (über On Error Resume Next, wie gehe ich stattdessen zum nächsten Objekt in der For Each-Schleife? Das Problem ist, dass, obwohl einige Steuerelemente keine Container haben, sie eine aktivierte Eigenschaft haben, und daher werden sie auf dem Resume-Teil deaktiviert/aktiviert. Besser noch, wie kann ich überprüfen, ob ein Objekt eine Container-Eigenschaft hat (ohne einen Fehler-Catcher zu verwenden)?

0 Stimmen

Hallo, es gibt keine Cycle Anweisung in VB6, mit der Sie direkt zum nächsten Objekt wechseln können. Mein Vorschlag ist die Verwendung einer If Block, um die Verwendung der Eigenschaft Enabled zu verpacken. Ich werde meine Antwort noch einmal überarbeiten, um das klarer zu machen. Ich glaube nicht, dass es einen einfacheren Weg gibt, um zu erkennen, ob ein Objekt eine Containereigenschaft hat, als eine Fehlerfalle zu verwenden.

0voto

jasonk Punkte 1570

Unterdrücken Sie die Fehlermeldungen vor der Schleife und schalten Sie dann auf die Standardfehlerbehandlung zurück:

On Error Resume Next
 For Each ctrl In Me.Controls
      ctrl.Enabled = lIsEnabled
 Next
 On Error GoTo 0

ODER benennen Sie Ihre Steuerelemente mit einem Standard-Präfix/Suffix, das Sie nach Namen prüfen und in der Schleife überspringen können.

For Each ctrl In Me.Controls
      If Left(ctrl.Name, 3) = "sst" Then
           ctrl.Enabled = lIsEnabled
      End If
 Next

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X