Supportnet Computer
Planet of Tech

Supportnet / Forum / Datenbanken

2 FORM-Felder vergleichen und ein drittes bedingt formatieren





Frage

Hallo, ich habe in einem Formular 2x zwei Felder, die ich miteinander vergleichen will und dann andere Felder in einer bestimmten Formatierung anzeigen lassen will. In den zu vergleichenden Feldern kann ich folgende Daten auswählen/eingeben: Feld 1: 1, 2, 3, 4, 5, ... Feld 2: A, B, C, D, E, ... Feld 3: 1, 2, 3, 4, 5, ... Feld 4: A, B, C, D, E, ... Die zu formatierenden Felder heißen: 1A, 1B, 1C, 1D, 1E, ... 2A, 2B, 2C, 2D, 2E, ... 3A, 3B, 3C, 3D, 3E, ... usw... Das sieht dann etwa so aus: Vergleiche Feld 1 und Feld 2. - Wenn der Wert in Feld 1 = "1" und der Wert in Feld 2 = "A" ist, dann formatiere Feld 1A. - Wenn der Wert in Feld 1 = "5" und der Wert in Feld 2 = "C" ist, dann formatiere Feld 5C. Vergleiche Feld 3 und Feld 4. - Wenn der Wert in Feld 3 = "1" und der Wert in Feld 4 = "A" ist, dann formatiere Feld 1A. - Wenn der Wert in Feld 3 = "5" und der Wert in Feld 4 = "C" ist, dann formatiere Feld 5C. Als Ergebnis der Formatierung soll immer ein roter Rahmen um das entsprechende Formularfeld kommen. Das Setzten des ersten Rahmens soll nach Eingabe in Feld 1 und 2 erfolgen, das Setzen des zweiten Rahmens soll nach Eingabe in Feld 3 und 4 erfolgen. Also bei Feld 2 "nach aktualisieren" und Feld 4 "nach aktualisieren" Kann man da einfach im CodeGenerator folgende Zeilen Schreiben? [code] If [Feld 1] = "1" and [Feld 2] = "A" Then [Feld 1A] = ... (Rahmenfarbe rot und Rahmenbreite 2) If [Feld 1] = "5" and [Feld 2] = "C" Then [Feld 5C] = ... (Rahmenfarbe rot und Rahmenbreite 2) usw... [/code] Welche Anweisung muss ich verwenden, um die Rahmenfarbe rot zu machen und die Rahmenbreite 2? Geht das ganze auch einfacher, damit ich bei so vielen Feldern nicht elendig viele If - Then - Anweisungen schreiben muss? Vielen Dank schonmal im Voraus. Gruß Sven

Antwort 1 von oliverV

Hallo Sven,

ich dürfte eine Lösung für das Problem habe, komme aber erst morgen dazu ausführlich zu antworten.

Gruß

Oliver


Antwort 2 von sv_t

@Oliver,

Kein Problem, bin für jede Hilfe dankbar und kann da auch mal warten!

Gruß Sven

Antwort 3 von El Bobbele

Hallo Sven!

Das Ganze kann sogar stark gestrafft werden, unabhängig davon, wieviele Steuerelemente überhaupt vorhanden sind - vorausgesetzt, die betroffenen Steuerelemente sind immer nach dem gleichen Namensschema benannt. Dann kann aus den Inhalten der jeweiligen Textfelder ein String zusammengesetzt werden, der den Namen des betroffenen Steuerelements darstellt. Anschliessend greifst du in der Steuerelemente-Auflistung einfach nur auf ein Objekt zu, das eben diesen Namen trägt.


Private Sub Feld1_AfterUpdate()
    'Dieses Ereignis bei Bedarf entfernen,
    'wenn die Formatierung nur durch Feld2
    'ausgelöst werden soll
    'Feldpaar übergeben
    FormatControl Me.Feld1, Me.Feld2
End Sub

Private Sub Feld2_AfterUpdate()
    'Feldpaar übergeben
    FormatControl Me.Feld1, Me.Feld2
End Sub

Private Sub Feld3_AfterUpdate()
    'Dieses Ereignis bei Bedarf entfernen,
    'wenn die Formatierung nur durch Feld4
    'ausgelöst werden soll
    'Feldpaar übergeben
    FormatControl Me.Feld3, Me.Feld4
End Sub

Private Sub Feld4_AfterUpdate()
    'Feldpaar übergeben
    FormatControl Me.Feld3, Me.Feld4
End Sub

Private Sub FormatControl(ctl1 As Control, ctl2 As Control)
    Dim strControlName As String

    On Error Goto ErrHandler

    'Enthalten beide Steuerelemente Daten?
    If Not IsNull(ctl1) And Not IsNull(ctl2) Then
        'Name des zu formatierenden Steuerelements erzeugen
        strControlName = ctl1.Value & ctl2.Value

        'Auf Steuerelement zugreifen und Eigenschaften einstellen
        With Me.Controls(strControlName)
            .BorderColor = vbRed
            .BorderWidth = 2
        End With
   End If

ExitSub:
   Exit Sub
ErrHandler:
   'Diese Zeile löschen, wenn keine Fehlermeldung erfolgen soll
   MsgBox "Das angegebene Steuerelement existiert nicht.", vbExclamation
   Resume ExitSub
End Sub


Gruss
El Bobbele

Antwort 4 von oliverV

Hallo Sven,

ich bin einen anderen Weg gegangen als El Bobbele, ich habe mir die Marke genutzt um die Felder zu formatieren.

Ich bin davon das deine Felder 1-4 gebunden sind, das also schon beim Formularöffnen und beim Datensatzwechsel Werte vorhanden sind.

Gehe in die Feldeigenschaften der zu formatierenden Felder, schreibe in jedes Feld eine Marke (Feldeigenschaften – Register Andere), für das Feld 1A schreibe A1, Feld 1B schreibe B1, usw.

Verwende nun „Beim Anzeigen“ der Formulars folgenden Code:
[Code]
Private Sub Form_Current()
Dim Var1 As String, Var2 As String
Dim Var3 As String, Var4 As String
Dim Var5 As String, Var6 As String
Dim ctl As Control

If Not IsNull(Me.Feld1) And Not IsNull(Me.Feld2) And Not IsNull(Me.Feld3) And Not IsNull(Me.Feld4) Then

Var1 = Me!Feld1
Var2 = Me!Feld2
Var3 = Me!Feld3
Var4 = Me!Feld4

Var5 = Var2 + Var1
Var6 = Var4 + Var3

For Each ctl In Me.Controls
With ctl
If ctl.Tag = Var5 Or ctl.Tag = Var6 Then
ctl.BorderColor = 255
ctl.BorderWidth = 2
End If
End With
Next

For Each ctl In Me.Controls
With ctl
If ctl.Tag <> Var5 And ctl.Tag <> Var6 Then
ctl.BorderColor = 0
ctl.BorderWidth = 0
End If
End With
Next

Else
For Each ctl In Me.Controls
With ctl
ctl.BorderColor = 0
ctl.BorderWidth = 0
End With
Next
End If

End Sub


Bei „Nach Aktualisierung“ des Feldes 2 verwende die „abgespeckte“ Variante:

Private Sub Feld2_AfterUpdate()
Dim Var1 As String, Var2 As String, Var5 As String
Dim ctl As Control

If Not IsNull(Me.Feld1) And Not IsNull(Me.Feld2) Then

Var1 = Me!Feld1
Var2 = Me!Feld2

Var5 = Var2 + Var1

For Each ctl In Me.Controls
    With ctl
        If ctl.Tag = Var5 Then
            ctl.BorderColor = 255
            ctl.BorderWidth = 2
        End If
    End With
Next

For Each ctl In Me.Controls
    With ctl
        If ctl.Tag <> Var5 Then
            ctl.BorderColor = 0
            ctl.BorderWidth = 0
        End If
    End With
Next

Else
For Each ctl In Me.Controls
    With ctl
            ctl.BorderColor = 0
            ctl.BorderWidth = 0
    End With
Next
End If

End Sub


Bei „Nach Aktualisierung“ des Feldes 4 verwende die identische Variante die du „Beim Anzeigen“ des Formulars verwendet hast.

Der Vorteil bei meiner Variante ist, das bei „Falscheingaben“ durch den Benutzer keine Probleme entstehen. Wenn durch Falscheingabe z.B. das Feld mit der Marke „K9“ formatiert werden soll (was es natürlich nicht gibt), passiert einfach nichts, denn die Formatierungsbedingung trifft nicht zu.

Was willst du eigentlich damit machen ? Access–Tic-Tac-Toe spielen ?


Gruß

Oliver




Antwort 5 von sv_t

Also ich habe in der letzten Nachtschicht die billigste Anfängervariante ausprobiert:
Für jedes Feld eine IF Then Anweisung geschrieben.
Funktioniert auch. Wusste erst nicht, welcher Code für den Rahmen steht, aber die Access-Hilfe ist ganz brauchbar.

Bin dabei etwa so vorgegangen:


If [Feld 1] = "1" And [Feld 2] = "A" Then [Feld 1A].BorderColor = "255"
If [Feld 1] = "2" And [Feld 2] = "A" Then [Feld 2A].BorderColor = "255"
If [Feld 1] = "3" And [Feld 2] = "A" Then [Feld 3A].BorderColor = "255"
.
.
.


Wie gesagt, das aller primitivste, aber auch möglich.

Ich will mich nächste Nachtschicht mal an Eure Varianten herantasten.

Ziel des Ganzen ist folgendes:

Archivierung von Flüssigkeitstransfers (Ölbewegungen zwischen mehreren Behältern in einem Kraftwerk)

Das neu geöffnete FORM ist komplett leer.
Nun fange ich an Datum und Uhrzeit einzugeben.
Die Felder [Feld 1] - [Feld 4] bedeuten eigentlich:
Feld 1 = Öl entnommen (von System 1, 2, 3, ...)
Feld 2 = Öl entnommen (von Behälter A, B, C, ...)
Feld 3 = Öl zugeführt (von System 1, 2, 3, ...)
Feld 4 = Öl zugeführt (in Behälter A, B, C, ...)
Es gibt also mehrere identische Systeme mit mehreren identischen Behältern.
Das Öl wird immer nur zwischen 2 Behältern hin und her gepumpt.
Insgesamt 4 Systeme mit 7 Behältern und 1 System mit 4 Behältern.
Also habe ich noch weitere 32 Felder im FORM, in die ich die Füllstände eintrage (das Ausrechnen Füllstand aus altem Datensatz minus Transfermenge = neuer Füllstand kriege ich nicht hin -> also händisch eingeben).

Nach Datum und Uhrzeit erfolgt mittels Listenfeld die Auswahl Öl entnommen aus [System] und [Behälter] sowie Öl zugeführt in [System] und [Behälter].
Nun wollte ich ja in meiner anderen Frage erreichen, dass ich die Ölstände aus dem letzten Datensatz hier wieder angezeigt kriege.
Das klappt aber nicht wenn ich das FORM neu öffne.
Also habe ich mir gedacht, ich markiere einfach die Felder der Behälter, die vom Öltransfer betroffen sind. Ist eigentlich nur spielerei, aber sehr effektiv.
Wenn ich jetzt also bei entnommen / zugeführt beide Felder ausgewählt habe, kriege ich jetzt von den 32 Feldern die 2 betroffenen markiert.

Wenn Ihr Ideen habt wie ich entweder die Werte ausrechnen kann oder die alten Werte anzeigen kann, bin ich für jeden Vorschlagdankbar.

Gruß Sven.


Antwort 6 von oliverV

Hallo Sven,

ungefähr weiß ich was du machen willst.
Die andere Frage war ja die nach dem Standartwert aus einem vorherigen Datensatz, das wäre IMHO eine Lösungsmöglichkeit für eine „fortlaufende“ Datenerfassung bei der sich nur wenige Feldinhalte ändern.
Du willst aber glaube ich die letzten erfassten Werte angezeigt bekommen, wenn du das Formular erneut öffnest.
Das dürfte über die Domänn-Funktionen zu realisieren sein (DCount, DLookup, usw).

Er wird aber jetzt glaube ich fürs Forum etwas zu komplex und zu abstrakt.
Wenn du möchtest kann ich mal eine Blick in die DB werfen, lies dazu bitte mal den Punkt 9.

Ich nutze A2000, E-Mail ovogelei@web.de

Gruß

Oliver


Antwort 7 von mapet

Hallo Sven

Wenn Deine DB folgendermassen aufgebaut ist sollte Deine Problemstellung einfach zu lösen sein. (Ist im Grunde nichts anderes als eine Lagerbewirtschaftung)

Tabelle Behälter mit Spalten
BehälterID; Behältername; Bestand; max Füllmenge,usw

Tabelle Bewegungen mit Spalten
BewegungID;BehälterID_zunahme;BehälterID_Abnahme;Datum, Menge

Dann kannst Du Dir in einer Form immer den letzeten DS der Bewegungen und die Betroffenen Behälter mit aktueller Füllmenge anzeigen lassen.

mapet


Antwort 8 von sv_t

Lagerbewirtschaftung ist das treffende Wort.

@Olover: ich habe Access XP, kann dir die DB gezipt schicken. Absender wäre dann sven.weide@vattenfall.de (müsste auch gezipt zurückgeschickt werden, sonst wirds abgeblockt).

@mapet: Habe bei mir nur eine Tabelle.
Kann mir auch alle möglichen Formulare anzeigen lassen, weil ich für jedes FORM immer auf eine Abfrage zugreife.

Habe also ein Hauptformular aus dem ich mit Button meine verschiedenen Ölbewegungen anzeige (nur lesen, nichts anfügen) und wo ich zum Eingabeformular gehe (nur anfügen, nicht ändern, nicht löschen).
Ich kriege also hier schon nur einen leeren Datensatz angezeigt.

Gruß Sven




Antwort 9 von mapet

Hallo

Wenn oliver Zeit hat Dir zu helfen ists O.K. ansonsten kannst die DB auch mir schicken gezippt.

mapet

Antwort 10 von El Bobbele

Hallo Oliver!

Ist es wirklich von Vorteil, wenn man auf eine Fehlerbehandlung verzichtet? Als Anwender hätte ich schon gerne gewusst, ob und warum eine Aktion fehlgeschlagen ist. Ansonsten könnte ich der Meinung sein, dass meine Falscheingabe funktioniert hat. ;-)

Eine Falscheingabe mag bei den hier formatierten Steuerelementen eher auffallen, aber prinzipiell sollte sowas abgefangen werden, um Fehler oder Missverständnisse vorzubeugen.

Gruss
El Bobbele

Antwort 11 von sv_t

@mapet: kein Problem, ich kann dir die DB auch schicken. Dann wissen wenigstens alle 3 worums geht. Mach ich dann nächste Nachtschicht.

Gruß Sven.

Antwort 12 von sv_t

@mapet:

jetzt weiß ich auch wieder, warum Du die DB nicht bekommen hast.

Deine E-Mail-Adresse ist unvollständig.
Da dachte ich mir, ich hänge einfach mal ein .de oder .com ran.
Bei .com und .net kam die Mail zurück mit dem Anhang "Empfänger unbekannt".
Bei .de kam was ganz komisches zurück. Konnte ich garnichts mit anfangen.

Sage mir doch bitte Deine Mail-Adresse, dann probier ich es nochmal.

Gruß Sven




Antwort 13 von mapet

@sven

sorry ich habe die kleine Schweiz vergessen

mapet