Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Variable wird nach DoCmd nicht aktualisiert

Begonnen von Manta1, Juni 29, 2025, 16:14:20

⏪ vorheriges - nächstes ⏩

Manta1

Hallo, als Neuzugang habe ich eine Frage zu VBA,
Mit VBA (am Anfang Stand QBA) etwas Erfahrung gesammelt in den Anwendungen Access 97, 03 und nun 07.
Als Unterstützung zum Sammeln habe ich mir eine kleine DB zusammengebastelt.
Nun ist folgender Effekt aufgetreten:
Bei einem Feld möchte ich die Hintergrundfarbe ändern sowie in Abhägigkeit des Inhalts ein Feld für Bemerkungen anzeigen bzw. verbergen.
Es Funktioniert auch bei Verwendung des DoCmd Befehls für DS go to acFirst, acLast, acPrevious und acNext.

"Private Sub ErsterDS_Click()
On Error GoTo Err_ErsterDS_Click
        DoCmd.GoToRecord , , acFirst
Exit_ErsterDS_Click:
    Farbe
    Exit Sub
Err_ErsterDS_Click:
    MsgBox Err.Description
    Resume Exit_ErsterDS_Click
End Sub"

Jetzt hingegen beim direkten Ansprung eines DS tritt folgender Effekt auf.

"Private Sub JDS_DblClick(Cancel As Integer)
    Forms![VerkaufFOR].ID.SetFocus
    On Error GoTo ERR_JDS
    DoCmd.FindRecord JDS, , True
exit_ERR_JDS:
    Me.JDS.SetFocus
    Me.JDS = ""
    Farbe
    Exit Sub
ERR_JDS:
    Resume exit_ERR_JDS
End Sub"

Der Datensatz wird korrekt angezeigt, aber der Feldinhalt "VKS" bleibt vom vorhergehenden DS erhalten, und der Aufruf von "Farbe" wird nicht korrekt dargestellt.

"Sub Farbe()
If VKS = "Verkauft" Then
        VKS.BackColor = QBColor(10)
        VKS.ForeColor = QBColor(0)
    ElseIf VKS = "Bezahlt" Then
        VKS.BackColor = QBColor(9)
        VKS.ForeColor = QBColor(15)
    ElseIf VKS = "Warten" Then
        VKS.BackColor = QBColor(11)
        VKS.ForeColor = QBColor(0)
    ElseIf VKS = "Versendet" Then
        VKS.BackColor = QBColor(14)
        VKS.ForeColor = QBColor(0)
    ElseIf VKS = "Eingestellt" Then
        VKS.BackColor = QBColor(13)
        VKS.ForeColor = QBColor(0)
    ElseIf VKS = "Bearbeiten" Then
        VKS.BackColor = QBColor(14)
        VKS.ForeColor = QBColor(0)
    ElseIf VKS = "Zurückgezogen" Then
        VKS.BackColor = QBColor(12)
        VKS.ForeColor = QBColor(15)
    End If
       
    If VKS = "Entsorgt" Or VKS = "Beendet" Then
        VKS.BackColor = QBColor(8)
        VKS.ForeColor = QBColor(15)
        BZF122.Visible = True
        AZR.Visible = True
        WEZ.Visible = True
    Else
        BZF122.Visible = False
        AZR.Visible = False
        WEZ.Visible = False
    End If
   
End Sub"

Hat jemand eine Idee? Refresh und Konsorten haben nicht funktioniert.

Gruß Manta1

Hondo

Hallo,
ist VKS ein Tabellenfeld oder ist es ein z.B: in einer Abfrage berechnetes Feld?
Wie sieht die Datenherkunft des betreffenden Formulars aus? Endlosformular?
Gruß Andi

Debus

Hey, ich würde das anders anfassen

1. Farbänderung an das Ereignis Form_Current binden
Das Ereignis Form_Current wird immer dann ausgelöst, wenn ein neuer Datensatz angezeigt wird (auch nach FindRecord). Dort kannst du die Farbänderung und Sichtbarkeit steuern:

Private Sub Form_Current()
    Farbe
End Sub



2. Farbe-Sub anpassen
Passe das Farbe-Sub so an, dass es den Wert des Steuerelements VKS korrekt ausliest und die Farben setzt:


Sub Farbe()
    Dim status As String
    status = Nz(Me.VKS.Value, "")

    Select Case status
        Case "Verkauft"
            Me.VKS.BackColor = QBColor(10)
            Me.VKS.ForeColor = QBColor(0)
        Case "Bezahlt"
            Me.VKS.BackColor = QBColor(9)
            Me.VKS.ForeColor = QBColor(15)
        Case "Warten"
            Me.VKS.BackColor = QBColor(11)
            Me.VKS.ForeColor = QBColor(0)
        Case "Versendet"
            Me.VKS.BackColor = QBColor(14)
            Me.VKS.ForeColor = QBColor(0)
        Case "Eingestellt"
            Me.VKS.BackColor = QBColor(13)
            Me.VKS.ForeColor = QBColor(0)
        Case "Bearbeiten"
            Me.VKS.BackColor = QBColor(14)
            Me.VKS.ForeColor = QBColor(0)
        Case "Zurückgezogen"
            Me.VKS.BackColor = QBColor(12)
            Me.VKS.ForeColor = QBColor(15)
        Case Else
            ' Standardfarbe, wenn kein Status passt
            Me.VKS.BackColor = vbWhite
            Me.VKS.ForeColor = vbBlack
    End Select

    If status = "Entsorgt" Or status = "Beendet" Then
        Me.VKS.BackColor = QBColor(15)
        Me.VKS.ForeColor = QBColor(15)
        Me.BZF122.Visible = True
        Me.AZR.Visible = True
        Me.WEZ.Visible = True
    Else
        Me.BZF122.Visible = False
        Me.AZR.Visible = False
        Me.WEZ.Visible = False
    End If
End Sub



3. FindRecord-Routine anpassen
Im JDS_DblClick-Event kannst du den Fokus und das Löschen des Feldes JDS nach dem Finden des Datensatzes machen, aber den Aufruf von Farbe kannst du weglassen, wenn du es im Form_Current hast.

Private Sub JDS_DblClick(Cancel As Integer)
    On Error GoTo ERR_JDS
    DoCmd.FindRecord Me.JDS.Value, , True
    Me.JDS.SetFocus
    Me.JDS = ""
    Exit Sub

ERR_JDS:
    MsgBox "Datensatz nicht gefunden."
End Sub

Noch was allgemeines:

Verwende immer Me. vor Steuerelementen im Formularmodul, um auf die aktuellen Steuerelemente zuzugreifen.

Vermeide das Setzen von Fokus auf ein Steuerelement, wenn es nicht unbedingt nötig ist, da dies zu unerwartetem Verhalten führen kann.

Nutze das Form_Current-Ereignis, um Zustände abhängig vom aktuellen Datensatz zu setzen.

Holger

Knobbi38

Hallo Manta,

ZitatDer Datensatz wird korrekt angezeigt, aber der Feldinhalt "VKS" bleibt vom vorhergehenden DS erhalten
Wie muß man sich das vorstellen? Entweder wird der DS korrekt angezeigt oder nicht.

Farbeinstellungen können i.d.R. über "Bedingte Formatierung" vorgenommen werden.

Ferner solltest du, Makro- oder Menüaufrufe durch VBA Code ersetzen, also DoCmd Aufrufe weitestgehend vermeiden, dort wo es möglich ist. Üblicherweise wird so eine Suche in VBA dann mit der Recordset.FindFirst() Methode durchgeführt.

Die Verwendung von QBColor() habe ich auch schon lange nicht mehr gesehen - ist etwas "oldSchool". Heutzutage wird eher die Funktion RGB() oder eine der Farbkonstanten von VBA verwendet.

Gruß Knobbi38

Manta1

Hallo danke für die schnelle Antwort. Leider war die Beschreibung etwas oberflächlich (Ich weiss ja, was ich möchte).-Sorry-
-> Hondo
VKS ist ein Feld in einem Formular. Beim anlegen eines Neuen DS wird ein Text (String) eingetragen.
Beim Datensatzwechsel wird dieser Textinhalt dazu verwendet die Text/Hintergrundfarbe und gegebenfalls ein Textfeld zu öffnen (visible.true) und darzustellen.
Dazu wird "Sub Farbe()" aufgerufen und abgearbeitet.
Was auch Funktioniert bei "DoCmd.GoToRecord , , acFirst" und den anderen aufrufen.
JDS ist ein ungebundenes Textfeld im Formular. Da ich als Kennung das Feld "ID" (Primärschlüssel) als DS-Kennung verwende setze ich den Fokus darauf, dass bei der anschliesenden Suche nach "ID" nicht alles Durchsucht werden muss. Die Suche mit "DoCmd.FindRecord JDS, , True" ist erfolgreich. Der gesuchte DS wird korrekt angezeigt.
Der Inhalt von VKS enthält aber noch den Text des vorherigen DS.
-> Debus
Die "Sub Form_Current()" mit diversen Parametern steht im Formular.
"Case-Select" werde ich ausprobieren.
Die "DoCmd.FindRecord JDS, , True" bereitet keinerlei Probleme.

->knobbi38
Der DS wird nach der Suche korrekt in vorgesehenen Feldern angezeigt.
Die "Bedingte Formatierung" ist ja nur drei oder vier Farben (AC07), bei mehr streckt sie die Flügel
Makros mag ich auch nicht, steht alles im VBA
RGB() fuuktioniert aber nicht überall (in Excel schon)

Falls es Hilfreich ist, kann ich auch eine Kopie der DB beisteuern (21 MB)

Gruss Manta1

Knobbi38

Hallo Manta,

ZitatMakros mag ich auch nicht, steht alles im VBA
Vielleicht ist dir das nicht bewußt, aber mit DoCmd rufst du aus VBA heraus Makroaktionen auf; das habe ich damit gemeint.

Dafür sollte eine FC ausreichen, wenn als Expression eine VBA Funktion aufgerufen wird.
 
Eine kl. Beispiel DB wäre hilfreich.

Gruß Knobbi38


Knobbi38

Hallo Manta,

noch ein Nachtrag:
Der Statustext steht ja eigentlich in einer Tabelle und wird mit einer Kombobox ausgewählt. Dort gehören auch die verschiedenen Farbinformationen für jeden Statustext hinein, dann kann die IF THEN ELSE Orgie auch entfallen. Nach jeder Änderung des Status rufst du dann einfach eine Routine auf, welche die Farbinformationen nachzieht.

Gruß Knobbi38

Manta1

#7
Hallo knobbi38,
zum Verständnis "Makro": mM nach wie von MS favorisiert und in den Annalen -> Makro ist eine Abfolge gespeicherten Tastenfogen die über Shortcut aufgerufen werden kann. Wahrscheinlich liege ich da total daneben (Word, Excel).
Ich habe mal die grosse Schere angesetzt und die DB von 4GB auf 0,6 MB eingedampft. Auf der rudimentären Form "VerkaufFOR" sind noch die entsprechenden Felder enthalten. Im VBA ist alles was nicht gebraucht auskommentiert.
in dem ungebundenen Feld "Status" erfolgt eine Vorauswahl die dann per Klick in das Feld "VKS" übernommen wird.
in dem ungebundenen Feld "Globalfilter" erfolgt eine Vorauswahl die dann per Klick in das Feld "Auktion" übernommen wird.
DS-Suche -> DS-Nr. per Doppelklick -> Datensatz anzeige, wenn unpassend -> nichts (hierbei tut sich im Feld "VKS" halt nicht das was es soll)



MzKlMu

#8
Hallo,
damit man als Fremder die Zusammenhänge besser versteht, wäre es sinnvoll, auch in der Beispieldb Beziehungen anzulegen.

Außerdem, Beispiele wegen des Speicherplatzes als Zip anhängen.
Habe ich oben gemacht.
Aus 700 KB werden dann 66 KB, was dann nur noch 1/10 tel ist.

Zitatdie DB von 4GB auf 0,6 MB eingedampft.
4GB kann nicht sein. Eine Access DB kann maximal 2GB groß sein.
Gruß Klaus

Knobbi38

#9
Hallo Manta,

ZitatWahrscheinlich liege ich da total daneben (Word, Excel).
So ist es. In Word und Excel gibt es keine eigenständige Makrosprache, sondern nur VBA, auch wenn dort hin und wieder von "Makros" gesprochen wird. In Access hingegeben gibt es neben VBA noch eine echte Makrosprache, die allerdings kaum genutzt wird und unter den Helfern hier nicht sehr beliebt ist. Aufrufe solcher Makroaktionen erfolgen dann von VBA aus mit DoCmd. Solche Sprünge zwischen diesen beiden "Welten" sind aber nicht immer ganz unproblematisch.

Wie Klaus schon geschrieben hat, kann eine 2007er DB max. 2 GB groß werden, schon gar nicht als *.mdb. Da muß ein Irrtum vorliegen.

Gruß Knobbi38

Knobbi38

#10
Hallo Manta,

da wirst du noch einiges an Arbeit investieren müssen, bevor das Projekt rund wird. Hier aber mal ein erstes Code-Beispiel, wie auf eine andere ID positioniert wird, denn mit DoCmd.FindRecord wird ja nicht wirklich auf eine bestimmte DS-Nummer positioniert:
  Dim rst As DAO.Recordset

  Set rst = Me.RecordsetClone
  rst.FindFirst "ID = " & txtJDS.Text

  If Not rst.NoMatch Then
    'ID found: move the form's recordset to the new location.
    Me.Bookmark = rst.Bookmark
  Else
    ' Todo: ID not found
  End If

  Set rst = Nothing
Wie du vielleicht bemerkt hast, habe ich das Textbox-Steuerelement mit dem Prafix 'txt' versehen und abgefragt. Setfokus entfällt, weil durch den Doppelklick die Textbox zwangsläufig  den Fokus hat.
Nach dem gleichen Schema solltest du dann die anderen Docmd-Aktionen auch nochmal anfassen und
DoCmd.DoMenuItem acFormBar, acEditMenu, 8, , acMenuVer70ist ein NoGo und bitte keine Feldnamen mit reservierten Bezeichnern wie z.B. 'Name'. Das ist eine viel verwendete Eigenschaft und auch der Bezeichner für eine VBA Anweisung.

Noch ein Hinweis:
im Form-Open Ereignis ist es ziemlich sinnlos, den Inhalt eines gebundenes Steuerelements auswerten zu wollen, weil diese Informationen erst im Form-Load Ereignis zur Verfügung stehen.

Dann solltest du für die Farbinformationen und den Statustext ein Tabelle verwenden, bevor man sich an die Umsetzung mit den Farben macht. Die Farbcodes selber haben nämlich nichts im Code verloren.

Im Übrigen ist es ohne eine vernünftige Namenskonvention sehr schwer, deinem Code zu folgen und eine Verknüpfung von HF/UF per Textfeld ist auch nicht gerade ideal.

Vielleicht solltest du doch nochmal ein paar Grundlagen zu Datenbanken, Beziehungen und Normalisierung von Tabellen nachschlagen.


Manta1

Guten Abend,
die "Dateigröße" umfasst auch ein Verzeichnis mit Bildern die in der DB per Aufruf eingebunden sind, daher die Gesamtgröße.In der Hochgeladenen Datei sind diese nicht enthalten. Die eigentliche mdb-Datei hat nur 21MB.

->knobbi38
ja, da werde ich noc einiges an Arbeit investieren müssen. Aber heute nicht mehr.

Danke und Gruß Manta1

Knobbi38

Das für Bilder nur ein Verweis in der DB steht und diese selber in einem ext. Verzeichnis gespeichert werden, ist auf jeden Fall schon mal ein richtiger Ansatz. :)

Gruß Knobbi38

Manta1

Danke - schon mal an alle.
Bin für ca. 14 Tg. on the road.

Manta1

Guten Abend zusammen,
ich habe mit dem Ganzen noch einiges ausprobiert und das Programm auf das Minimum reduziert so dass die DB nur aus einer Tabelle und einem Formblatt besteht.
Es gibt nur noch ein Feld zum Suchen eines DS und die Buttons zum Durchblättern durch die Datensätze.
Beim Durchblättern wird die Hintergrundfarbe des Feldes "VKS" korrekt angezeigt, bei der "DS-Suche" wird der DS im Feld "DSZ" zwar angezeigt, aber die Hintergrundfarbe im Feld "VKS" bleibt erhalten. Wird das Feld zur "DS-Suche" nochmals als leeres Feld angeklickt, ändert sich die Hintergrundfarbe zur gewünschten Füllfarbe.
Habe nochmals die abgespeckte Datei angehängt.

Hallo Knobbi38: Könnte der Effekt auf die Rollback Eigenschaft zurückzuführen sein? So dass der korrekte Inhalt erst im zweiten Anlauf vom Stack nach oben geschoben wird?