Der Titel sagt eigentlich schon Alles: Ich möchte in einem
Endlosformular unterschiedliche Detailinformationen für Listeneinträge
anzeigen, je nach Wert eines Typenfeldes.
Dazu habe ich einen großen JOIN mit allen Detailtabellen erstellt, so
daß ich eine (read only) Datenmenge habe, die alle gewünschten Felder
enthält. Nun würde ich gerne die Steuerelemente, die die leeren Felder
beinhalten, Datensatzbasiert ausblenden. Nach Lektüre von donkarl.com
(Mal wieder danke @Karl!) scheint es mir, nur die Format -> Bedingte
Formatierung kommt dieser Anforderung tendenziell nahe, leider sind die
Möglichkeiten hier auf ein paar Formatierungselemente und
aktivieren/deaktivieren von Steuerelementen begrenzt.
In Berichten geht das ja im Format oder Print-Ereignis - aber ich
brauche ein paar Eingabeelemente, um die zugrundeliegenden
Detailtabellen manuell zu aktualisieren.
Hat jemand ne zündende Idee, oder ist Access an diesem Punkt schon mit
seinem Latein am Ende?
Gruß,
Lars
Lars Uffmann wrote:
> Der Titel sagt eigentlich schon Alles: Ich möchte in einem
> Endlosformular unterschiedliche Detailinformationen für Listeneinträge
> anzeigen, je nach Wert eines Typenfeldes.
>
> Dazu habe ich einen großen JOIN mit allen Detailtabellen erstellt, so
> daß ich eine (read only) Datenmenge habe, die alle gewünschten Felder
> enthält. Nun würde ich gerne die Steuerelemente, die die leeren Felder
> beinhalten, Datensatzbasiert ausblenden. Nach Lektüre von donkarl.com
> (Mal wieder danke @Karl!) scheint es mir, nur die Format -> Bedingte
> Formatierung kommt dieser Anforderung tendenziell nahe, leider sind die
> Möglichkeiten hier auf ein paar Formatierungselemente und
> aktivieren/deaktivieren von Steuerelementen begrenzt.
>
> In Berichten geht das ja im Format oder Print-Ereignis - aber ich
> brauche ein paar Eingabeelemente, um die zugrundeliegenden
> Detailtabellen manuell zu aktualisieren.
Liegt dein Problem bei der Aktualisierbarkeit oder der Darstellung?
Zur Aktualisierbarkeit kann man wenig sagen, wenn man die Abfrage nicht
kennt.
Bez. leere Felder:
Wenn ich dich richtig verstehe, willst du statt eines leeren Feldes ein
anderes mit Inhalt sehen. Das hat mit bedingter Formatierung nix zu tun.
Ich wuerde das bereits in der zugrundeliegenden Abfrage loesen:
SELECT Nz(Feld1, Feld2) AS Irgendwas, ...
Schneller wird die Abfrage dadurch uebrigens nicht. ;-)
Gruss - Peter
--
Mitglied im http://www.dbdev.org
FAQ: http://www.donkarl.com
> Bez. leere Felder:
> Wenn ich dich richtig verstehe, willst du statt eines leeren Feldes ein
> anderes mit Inhalt sehen. Das hat mit bedingter Formatierung nix zu tun.
Nicht, wenn man Formatierung auf die Schriftgröße, ~farbe, etc.
beschränkt. Ansonsten ist es tatsächlich das, was ich bräuchte.
> Ich wuerde das bereits in der zugrundeliegenden Abfrage loesen:
> SELECT Nz(Feld1, Feld2) AS Irgendwas, ...
Das löst das Problem nicht.
Stell Dir das einfache Beispiel vor:
Ich habe eine Liste von Anweisungen für jemanden, und es gibt zwei Typen
von Anweisungen:
Typ A: Überprüfe einen Meßwert
Typ B: Führe einen Befehl aus (mit Parametern)
In der Liste möchte ich eine beliebige Sequenz solcher Anweisungen
zusammenstellen. Wenn ein Eintrag vom Typ A ist, soll die Kennung des
Meßwertes sowie der zu erwartende Wert angezeigt werden
(Detailinformationen A), wenn ein Eintrag Typ B hat, soll das
auszuführende Kommando sowie eine kurze Beschreibung, was dieses
Kommando tut, angezeigt werden. Ggf. auch z.B. 2 (oder x) Parameter.
Gemeinsam ist allen Anweisungen (unabhängig vom Typ) eine ID (Primary
Key), eine Sequenz-ID (zu welcher Sequenz gehört diese Anweisung) eine
Sortier-ID sowie ein Typen-Feld, das in A oder B unterscheidet.
Anweisungen vom Typ A haben einen entsprechenden Detaildatensatz in der
Tabelle A, und Typ B entsprechend in Tabelle B. Das Zusammenführen der
Datenmengen (als nicht aktualisierbarer Join) ist trivial, jetzt geht es
nur noch darum, nicht benötigte Informationen auszublenden.
Beispieldarstellung für die Anweisungsliste einer einzigen Sequenz
(schematisch, Zeichensatz mit fester Zeichenbreite sinnvoll):
ID| Sortier-ID| Typ| Details
--+-----------+----+----------
1| 1| A| prüfe Meßwert: _Prüfspannung_ (ComboBox)
| | | erwarteter Wert: __15__ Volt (Textfeld)
| | |
2| 2| B| sende Befehl: _erhöhe Spannung_ (ComboBox)
| | | Parameter welche: _Prüfspannung_ (ComboBox)
| | | Parameter Sollwert: _30_ Volt (Textfeld)
| | | Erklärung: __für die nächste Messung wird
| | | eine erhöhte Spannung benötigt_ (Memo)
| | |
3| 3| A| prüfe Meßwert: _Prüfspannung_ (ComboBox)
| | | erwarteter Wert: __30__ Volt (Textfeld)
| | |
Wird klar, worum es geht?
> Schneller wird die Abfrage dadurch uebrigens nicht. ;-)
Auf Geschwindigkeit kommt es in diesem Fall nicht an, das Bottleneck ist
hier die Eingabegeschwindigkeit des Benutzers.
Gruß,
Lars
Lars Uffmann wrote:
>> Ich wuerde das bereits in der zugrundeliegenden Abfrage loesen:
>> SELECT Nz(Feld1, Feld2) AS Irgendwas, ...
> Das löst das Problem nicht.
> Stell Dir das einfache Beispiel vor:
> Ich habe eine Liste von Anweisungen für jemanden, und es gibt zwei Typen
> von Anweisungen:
> Typ A: Überprüfe einen Meßwert
> Typ B: Führe einen Befehl aus (mit Parametern)
>
> In der Liste möchte ich eine beliebige Sequenz solcher Anweisungen
> zusammenstellen. Wenn ein Eintrag vom Typ A ist, soll die Kennung des
> Meßwertes sowie der zu erwartende Wert angezeigt werden
> (Detailinformationen A), wenn ein Eintrag Typ B hat, soll das
> auszuführende Kommando sowie eine kurze Beschreibung, was dieses
> Kommando tut, angezeigt werden. Ggf. auch z.B. 2 (oder x) Parameter.
...
> Beispieldarstellung für die Anweisungsliste einer einzigen Sequenz
> (schematisch, Zeichensatz mit fester Zeichenbreite sinnvoll):
>
> ID| Sortier-ID| Typ| Details
> --+-----------+----+----------
> 1| 1| A| prüfe Meßwert: _Prüfspannung_ (ComboBox)
> | | | erwarteter Wert: __15__ Volt (Textfeld)
> | | |
> 2| 2| B| sende Befehl: _erhöhe Spannung_ (ComboBox)
> | | | Parameter welche: _Prüfspannung_ (ComboBox)
> | | | Parameter Sollwert: _30_ Volt (Textfeld)
> | | | Erklärung: __für die nächste Messung wird
> | | | eine erhöhte Spannung benötigt_ (Memo)
> | | |
Ich würde versuchen, diese Informationen bereits in der Query in das Details
Feld reinzubekommen. z.B
SELECT .... IIf([Typ]='A'; [Feld1] ; [Feld2]) AS Details
Alternativ zu IIf kannst Du auch ein Konstrukt mit Choose() oder Switch()
machen. Details siehe OH.
Gruss
Henry
--
Die NEK1 verpasst? Kein Problem. Details in FAQ
Microsoft MVP Office Access
Keine E-Mails auf Postings in NGs. Danke.
Access FAQ www.donkarl.com
> Wird klar, worum es geht?
Nicht so ganz.
Zur reinen Darstellung der Detailzeilen braucht du keine speziellen Felder,
ein mehrzeiliges Textfeld, das von einem Funktionsaufruf mit den
zeilenweise umgebrochenen Text gefüllt wird, würde reichen.
Wenn die Detailinformationen aber einzeln in den in Klammern stehenden
Steuerelementtypen dargestellt werden sollen, geht das nicht innerhalb des
Endlosformulars. In dem Fall würde sich eine Kombination aus einem (nur
textanzeigenden) Unterforumlar und einem Satz ungebundener Eingabefelder im
Hauptformular anbieten, deren Inhalt und Sichtbarkeit vom aktuellen
Datensatz des Unterformular abhängt und in denen die Inhalte des jeweils
aktiven Datensatzes auch geändert werden können.
Siegfried
--
http://www.schmidt.ath.cx
Ich habe kein Problem auf der Datenseite - es geht mir um die
Eingabeelemente, die ich dem Benutzer zur Verfügung stelle. Da die
zugrundeliegenden Daten read-only sind, müßte ich ohnehin ungebundene
Eingabeelemente per Code mit den Daten füllen.
Eine Modifikation der Datenmenge löst mein Problem leider nicht.
Gruß,
Lars
Es geht um die Eingabeelemente.
> Wenn die Detailinformationen aber einzeln in den in Klammern stehenden
> Steuerelementtypen dargestellt werden sollen, geht das nicht innerhalb des
> Endlosformulars.
Genau das ist mein Problem. Es geht - aber nur indem ich *alle*
Eingabe-Steuerelemente anzeige. Das Einzige, was ich können will (nicht
optimal, aber ausreichend), ist die Veränderung der Visible-Eigenschaft
auf Datensatzbasis. Den Rest hab ich schon gelöst.
Ich fürchte aber, daß es tatsächlich nicht geht.
> In dem Fall würde sich eine Kombination aus einem (nur
> textanzeigenden) Unterforumlar und einem Satz ungebundener Eingabefelder im
> Hauptformular anbieten, deren Inhalt und Sichtbarkeit vom aktuellen
> Datensatz des Unterformular abhängt und in denen die Inhalte des jeweils
> aktiven Datensatzes auch geändert werden können.
Diese Lösung ist mir bewußt, ich will die anti-intuitive Bedienung
vermeiden, die damit einhergeht (Auswahl des zu bearbeitenden
Datensatzes unten in der Liste, Editieren der Feldinhalte oben im
Formularkopf). Bevor ich so eine Lösung wähle, programmiere ich mir ein
Frontend mit einer Programmiersprache, anstatt einen Interpreter wie
Access zu benutzen. Leider ist das ungleich aufwändiger :/
Gruß,
Lars
Lars Uffmann wrote:
> Peter Doering wrote:
>
>> Ich wuerde das bereits in der zugrundeliegenden Abfrage loesen:
>> SELECT Nz(Feld1, Feld2) AS Irgendwas, ...
> Das löst das Problem nicht.
> [...]
> ID| Sortier-ID| Typ| Details
> --+-----------+----+----------
> 1| 1| A| prüfe Meßwert: _Prüfspannung_ (ComboBox)
> | | | erwarteter Wert: __15__ Volt (Textfeld)
> | | |
> 2| 2| B| sende Befehl: _erhöhe Spannung_ (ComboBox)
> | | | Parameter welche: _Prüfspannung_ (ComboBox)
> | | | Parameter Sollwert: _30_ Volt (Textfeld)
> | | | Erklärung: __für die nächste Messung wird
> | | | eine erhöhte Spannung benötigt_ (Memo)
> | | |
> 3| 3| A| prüfe Meßwert: _Prüfspannung_ (ComboBox)
> | | | erwarteter Wert: __30__ Volt (Textfeld)
> | | |
>
> Wird klar, worum es geht?
Das laesst sich im Endlosformular so nicht darstellen. Du kannst alternativ
die bedingten Felder in Kopf oder Fuss verlagern und da nach Bedarf aus-/
einblenden. Zu sehen ist da immer nur der aktuelle DS, insofern ist die
Logik gewahrt.
Das ist leider keine akzeptable Lösung (Bedienkomfort = grottig). Meine
derzeitige Überlegung geht dahin, das Endlosformular nur aus einem (per
VBA individuell zusammengesetzten) Memo-Feld bestehen zu lassen und dann
jeweils den aktiven Datensatz im Endlosformular mit einem Container des
Hauptformulars zu überblenden, in dem die Eingabe dann erfolgen kann.
Die Schwierigkeit liegt jetzt darin, a) die Position (.top) des
aktuellen Detail-Formulars in der Endlosreihe zu ermitteln, sowie b) ein
Element in den Vordergrund *vor* das Subformular zu holen - das scheint
nicht trivial zu sein.
Gruß,
Lars
> Diese Lösung ist mir bewußt, ich will die anti-intuitive Bedienung
> vermeiden, die damit einhergeht (Auswahl des zu bearbeitenden
> Datensatzes unten in der Liste, Editieren der Feldinhalte oben im
> Formularkopf).
Man kann das mit etwas Aufwand genauso anordnen wie auf der Vorlage, wenn
es sein muss auch mit Syncronisation der Vertikalpositionen.
> Bevor ich so eine Lösung wähle, programmiere ich mir
> ein Frontend mit einer Programmiersprache, anstatt einen Interpreter
> wie Access zu benutzen. Leider ist das ungleich aufwändiger :/
Ein kompletter Nachbau der Funktionalität durch ein Formular mit hundert
geschalteten Steuerelementen geht genauso in Access - das Tempo bestimmt
nicht die Programmiersprache sondern die Laufzeit der
Steuerelementbibliotheken, an denen eine Sprachänderung nichts bewirkt.
Siegfried
--
http://www.schmidt.ath.cx
Auf den Ansatz bin ich in der Zwischenzeit als scheinbar einzig mit
Access gangbaren Weg gekommen. Dazu müssen die Eingabeelemente Teil des
Hauptformulars sein - dann lassen sie sich allerdings nicht im
Vordergrund des Endlos-Subforms darstellen, also muß ich sie in ein
zweites Subform verschieben, das ich dann ohne Ränder in den Vordergrund
positioniere und vertikal positioniere.
Problematisch ist allerdings im Moment die Vertikalpositionierung, da
ich nicht die TWIPs-Position des aktuellen Datensatzes kenne -
me.WindowTop im Endlosformular gibt mir leider nicht die Position des
aktuellen Datensatzes, sondern die, wo das Endlosformular beginnt.
> Ein kompletter Nachbau der Funktionalität durch ein Formular mit hundert
> geschalteten Steuerelementen geht genauso in Access - das Tempo bestimmt
> nicht die Programmiersprache sondern die Laufzeit der
> Steuerelementbibliotheken, an denen eine Sprachänderung nichts bewirkt.
Moment mal - was heißt hier "mit hundert geschalteten Steuerelementen
[..] genauso"? Wenn ich sowas selber programmiere nehme ich keine
hunderte geschaltete Steuerelemente sondern ein einziges Objekt für das
Unterformular, eine einzige Instanz davon, und iteriere die über die
Datensätze, die im sichtbaren Fenster liegen, nur eben mit dem
Unterschied, daß ich ein "BeforePaint"-Event habe, in dem ich das
Formulardesign anpassen kann.
Das geht in Access definitiv nicht, einfach deshalb schon nicht, weil
mir Access nicht die Möglichkeit gibt, auf so tiefer Ebene in den Prozeß
einzugreifen.
Wieso Du das Tempo erwähnst, ist mir übrigens schleierhaft - denn ich
habe nirgendwo etwas von Geschwindigkeitsoptimierung erwähnt (und
brauche es in diesem Fall auch nicht).
Gruß,
Lars
Lars Uffmann wrote:
> Auf den Ansatz bin ich in der Zwischenzeit als scheinbar einzig mit
> Access gangbaren Weg gekommen. Dazu müssen die Eingabeelemente Teil des
> Hauptformulars sein - dann lassen sie sich allerdings nicht im
> Vordergrund des Endlos-Subforms darstellen, also muß ich sie in ein
> zweites Subform verschieben, das ich dann ohne Ränder in den Vordergrund
> positioniere und vertikal positioniere.
Ich werf' einfach (inzwischen Gewohnheitsbedingt) einfach mal "Disconnected
Recordsets" in die Runde. Gruppengoogle mal danach in dieser NG.
Henry Habermacher wrote:
> Ich werf' einfach (inzwischen Gewohnheitsbedingt) einfach mal
> "Disconnected Recordsets" in die Runde. Gruppengoogle mal danach in
> dieser NG.
Ist ja u.U. ganz interessant, aber der Zusammenhang mit datenbasiertem
Layout eines Endlosformular-Eintrages ist mir nicht ersichtlich...
Gruß,
Lars
Derzeitiges Fazit: nicht möglich
Derzeitiger Workaround:
Im Endlosformular wird datenbasiert ein Memo-Feld zusammengeschustert,
daß die typspezifischen Detailinformationen optisch ansprechend aufbereitet.
Nur der jeweils aktive Detaildatensatz wird durch eine flexible
Eingabemaske (teilweise) überblendet. Die Eingabemaske befindet sich
dazu in einem Unterformular frmEditDetails des Hauptformulars (um
überhaupt im Vordergrund vor dem Endlosformular gezeichnet zu werden)
und wird jeweils neu positioniert, wenn ein neuer Datensatz den Fokus
erhält. Dann werden (unsichtbare) Austauschfelder im Hauptformular
aktualisiert und der Fokus an das Edit-Formular übergeben, welches dann
entsprechend neu formatiert wird (im Code des Hauptformulars).
Code hierzu:
' Endlos-Unterformular
Const MARGIN = 14
Private Sub Form_Current()
Me.Parent.Form.frmEditDetails.Top = Me.Parent.frmProcedureItems.Top
+ Me.CurrentSectionTop - MARGIN
Me.Parent.Form.txtId.value = [id]
Me.Parent.Form.txtType.value = [cboType]
Me.Parent.Form.frmEditDetails.SetFocus
End Sub
' Hauptformular
Private Sub frmEditDetails_Enter()
On Error GoTo errFrmEditDetails_Enter
Select Case txtType.Value
Case 1: ' format frmEditDetails for type 1
Case 2: ' format frmEditDetails for type 2
Case Else: ' do whatever
End Select
errFrmEditDetails_Enter:
End Sub
PROBLEM (ToDo-Liste):
Wenn die Darstellung des Endlosformulars verschoben wird, ohne den
aktuellen Datensatz zu verändern (Mausrad, Scrollbar), bleibt das
Edit-Formular an Ort und Stelle stehen.
Vielleicht hilft es ja jemand...
Gruß,
Lars
Lars Uffmann wrote:
> Peter Doering wrote:
>> Das laesst sich im Endlosformular so nicht darstellen. Du kannst alternativ
>> die bedingten Felder in Kopf oder Fuss verlagern und da nach Bedarf aus-/
>> einblenden. Zu sehen ist da immer nur der aktuelle DS, insofern ist die
>> Logik gewahrt.
>
> Das ist leider keine akzeptable Lösung (Bedienkomfort = grottig).
Geschmacksache. Man kann per SetFocus gewissen Komfort erzeugen, aehnlich
wie es gewisse ERP-Systeme machen.
> Meine
> derzeitige Überlegung geht dahin, das Endlosformular nur aus einem (per
> VBA individuell zusammengesetzten) Memo-Feld bestehen zu lassen und dann
> jeweils den aktiven Datensatz im Endlosformular mit einem Container des
> Hauptformulars zu überblenden, in dem die Eingabe dann erfolgen kann.
>
> Die Schwierigkeit liegt jetzt darin, a) die Position (.top) des
> aktuellen Detail-Formulars in der Endlosreihe zu ermitteln, sowie b) ein
> Element in den Vordergrund *vor* das Subformular zu holen - das scheint
> nicht trivial zu sein.
Du kannst vielleicht aus
http://www.lebans.com/alternatecolordetailsection.htm was abkupfern.
Nur so eine Idee:
Lies' die Daten in ein Recordset ein, indem Du die Felder in das gleiche
Feld einliest, die Du da wahlweise vom Typ angezeigt haben willst. Danach
disconnecte das Recordset. Vor dem BatchUpdate der geänderten Daten
schreibst Du die Daten dann per VBA in die unterschiedlichen Felder zurück,
damit diese in die richtigen Felder in der Datenbank zurückgeschrieben
werden.
Analog könntest Du übrigens auch mit einem gebundenen Formular vorgehen. Du
liest die Felder zum einen in separate Felder ein, zum anderen gibst Du
diese in einem Feld aus, das wahlweise vom einen oder anderen Feld gespiesen
wird, abhängig vom Typ. Also über IIf() in der Abfrage.
Beim Form_BeforeUpdate schreibst Du dann abhängig vom Typ das nicht
aktualisierbare Feld in die anderen Felder zurück und lässt das Formular das
Recordset (zumindest das, was davon aktualisierbar ist) updaten. Auch nur so
eine Idee ohne es jetzt ausprobiert zu haben. Tricky wird es allenfalls
werden, das konsolidierte Feld zu einem Eingabefeld zu machen.
Gruss
Henry
Ich will ja nicht undankbar sein, ich freue mich auch über Deine (Eure)
Hilfsbereitschaft, aber die Notwendigkeit der Aufteilung in
Detailtabellen bedeutet zwangsläufig, daß Dein Vorschlag nicht umsetzbar
ist: Wenn ich pro Listeneintrag immer die gleiche Anzahl an
Eingabefeldern hätte, die zudem noch das gleiche Eingabeelement
bräuchten (Textfeld/ComboBox/Checkbox), könnte ich mir die
Unterscheidung in verschiedene Detailtabellen gleich sparen...
> Du diese in einem Feld aus, das wahlweise vom einen oder anderen Feld
> gespiesen wird, abhängig vom Typ. Also über IIf() in der Abfrage.
"gespiesen" - Auf jeden Fall eine kreative Wortschöpfung >:)
> Auch nur so eine Idee ohne es jetzt ausprobiert zu haben. Tricky wird es
> allenfalls werden, das konsolidierte Feld zu einem Eingabefeld zu machen.
Nä nich wirklich - wenn es gebunden ist, geht's nich (außer es ist an
ein Dummy-Textfeld gebunden, in dem genug Platz ist), und wenn es
ungebunden ist, weist man den Wert einfach per VBA beim Aufrufen eines
Datensatzes zu, und schreibt ihn beim Verlassen des Datensatzes weg in
die Datenbank. Aber wie gesagt - das hilft mir nicht. Hab meinen
Workaround gestern noch gepostet, falls er Dich interessiert.
Gruß,
Lars