Hallo,
ich habe 7 Tabellen, eine Haupttabelle (Primärschlüssel ist die Artikelnummer) und 6 etwa gleichwertige Nebentabellen (ebenfalls incl. Artikelnummer). Jetzt habe ich in jeder der Nebentabellen eine Spalte mit einem booleschen "gesperrt" Wert.
Was ich jetzt brauche, ist eine zusammenfassende Tabelle / Abfrage, in der in Spalte A die Artikelnummer, und in Spalte B ein boolescher Wert angezeigt wird. Dieser Boolesche Wert "gesperrt" soll auf TRUE stehen, sobald einer der Werte von Nebentabelle 1 bis 6 auf TRUE gesetzt wurde, quasi eine Zusammenfassung... sobald auf einer der Nebentabellen gesperrt wird, soll in der Haupttabelle "gesperrt" auch auf TRUE stehen.
Also ist das Ganze eine ODER Abfrage. Wenn 1 oder 2 oder ... 6 = TRUE dann TRUE.
Das Ganze mit rekursiver Aktualisierung natürlich, sobald 1 bis 6 = FALSE, dann Haupt auch FALSE.
Wie bekomme ich soetwas hin?
Hallo,
ich würde eher mal bei den 6 etwa gleichwertigen Tabellen ansetzen.
Wozu 6 Tabellen, wie unterscheiden sich diese?
Hi,
diese 6 Tabellen unterscheiden sich durch Diverse andere Spalten, aus denen resultiert, warum ein Artikel gesperrt ist. Das können verweise, Begründungen, etc. sein, teilweise auch nur ein Datum "von" und ein Datum "bis". In diesen Spalten unterscheiden sich die Tabellen schon, da die Indikationen die zu einer Artikelsperre führen vielfältig sind. Am Ende steht nachher die Beurteilung einer Abteilung "gesperrt" oder "nicht gesperrt".
Diese Beurteilung der verschiedenen Abteilungen will ich zusammenfassen.
Hallo,
ich bin zwar der Überzeugung, dass das Datenmodell nicht stimmt, aber trotzdem mal ein Vorschlag.
=DomSumme("Gesperrt";"Nebentabelle1";"Artikelnummer = " & [Artikelnummer])+DomSumme("Gesperrt";"Nebentabelle2";"Artikelnummer = " & [Artikelnummer])+DomSumme("Gesperrt";"Nebentabelle3";"Artikelnummer = " & [Artikelnummer])
Bitte um die Nebentabellen 4-6 noch erweitern. Das ist der Steuerelementinhalt eine Hakenfeldes im Formular.
Der Haken wird automatisch gesetzt, wenn die Addition der 6 Summen <>0 ist.
Das Feld Artikelnummer muss im Formular vorhanden sein.
Ich würde aber eher das Datenmodell ändern, ich glaube nicht, dass die 6 Tabellen so sinnvoll sind.
Diese Indikationen gehören in eine Tabelle mit einem Fremdschlüssel zur Abteilung und zum Artikel. Jeder Grund/Indikationen gibt ein Datensatz.
Kann aber keine genauen Vorschläge machen, da mir Detailinfos fehlen.
Hi, und danke für die Antwort. Würde man sowas auch in eine Abfrage als Kriterium bekommen?
Das Problem ist, dass sich die Haupttabelle ständig ändert (und eigentlich nur eine Verknüpfung einer SQL-Datenbanbk ist)
Hallo,
ZitatWürde man sowas auch in eine Abfrage als Kriterium bekommen?
Ein Kriterium dient zur Auswahl einer bestimmten Datensatzzahl aus einer Gesamtmenge und ist daher für diese Aufgabe nicht geeignet.
Was stört Dich an dem Vorschlag, die Haupttabelle kann sich dabei ändern wie sie will. Die Formel enthält keinen Bezug zur Haupttabelle.
Meine Zweifel am Datenmodell werden immer größer, wenn ich einen solchen Satz lese:
ZitatDas Problem ist, dass sich die Haupttabelle ständig ändert
Warum ändert sich die Haupttabelle?
Nur die Daten oder auch die Tabelle selbst?
Sorry, ich habe mich falsch ausgedrückt... nur die Daten natürlich. Vielleicht habe ich nur nicht verstanden wo ich Deine Formel unterbringen soll.
Hallo,
ZitatVielleicht habe ich nur nicht verstanden wo ich Deine Formel unterbringen soll.
als Steuerelementinhalt eines Hakenfeldes im Hauptformular.
Hatte ich schon mal geschrieben:
Zitat von: MzKlMu als ist der Steuerelementinhalt eine Hakenfeldes im Formular.
Ja sorry, ich habe dann vermutlich nicht alle Kriterien genannt, mea culpa.
Ich habe eine Listbox im Hauptformular, wo ich eine Reihe Artikel aufliste (per VBA Code). In der Listbox ist eine Spalte, welche ich eben mit "gesperrt" oder "frei" füllen möchte.
Hallo,
lege in der Abfrage für das Listenfeld ein berechnetes Feld an:
Sperrvermerk: Wenn(DomSumme("Gesperrt";"Nebentabelle1";"Artikelnummer = " & [Artikelnummer])+DomSumme("Gesperrt";"Nebentabelle2";"Artikelnummer = " & [Artikelnummer])+DomSumme("Gesperrt";"Nebentabelle3";"Artikelnummer = " & [Artikelnummer])=0;"";"Gesperrt")Nebentabelle 4-6 noch ergänzen.
Aber das wird kein Renner, bei vielen Datensätzen wird das die Anzeige merklich verzögern.
Das Datenmodell halte ich nach wie vor für falsch, wie ich bereits anmerkte:
Zitat von: MzKlMuDiese Indikationen gehören in eine Tabelle mit einem Fremdschlüssel zur Abteilung und zum Artikel. Jeder Grund/Indikationen gibt ein Datensatz.
Kann aber keine genauen Vorschläge machen, da mir Detailinfos fehlen.
Ok, jetzt wirds irgendwie kompliziert, im Moment habe ich eine Abfrage, wo die 6 Indikationen nebeneinander stehen, aber wie geschrieben sollen sie ja statt dessen als Ergebnis in einer Spalte zusammengefasst werden. Ohne Zusammenfassung sieht die Abfrage wie folgt aus:
SELECT Bingodata.idprozessauftragsnummer, Bingodata.fimaterialnummer, Bingodata.dtmaterialkurztext, Bingodata.dteckstarttermin, Bingodata.dtcharge, IndicationData_Abweich.blnStatus AS IndicationData_Abweich_blnStatus, IndicationData_CAPA.blnStatus AS IndicationData_CAPA_blnStatus, IndicationData_CC.blnStatus AS IndicationData_CC_blnStatus, IndicationData_OOSAnalyt.blnStatus AS IndicationData_OOSAnalyt_blnStatus, IndicationData_OOSMibi.blnStatus AS IndicationData_OOSMibi_blnStatus, IndicationData_Valid.blnStatus AS IndicationData_Valid_blnStatus
FROM (((((Bingodata LEFT JOIN IndicationData_CAPA ON Bingodata.[idprozessauftragsnummer] = IndicationData_CAPA.[lngAuftragsNr]) LEFT JOIN IndicationData_CC ON Bingodata.[idprozessauftragsnummer] = IndicationData_CC.[lngAuftragsNr]) LEFT JOIN IndicationData_OOSAnalyt ON Bingodata.[idprozessauftragsnummer] = IndicationData_OOSAnalyt.[lngAuftragsNr]) LEFT JOIN IndicationData_OOSMibi ON Bingodata.[idprozessauftragsnummer] = IndicationData_OOSMibi.[lngAuftragsNr]) LEFT JOIN IndicationData_Valid ON Bingodata.[idprozessauftragsnummer] = IndicationData_Valid.[lngAuftragsNr]) LEFT JOIN IndicationData_Abweich ON Bingodata.[idprozessauftragsnummer] = IndicationData_Abweich.[lngAuftragsNr];
Nur wie ändere ich das jetzt in Bezug auf Deinen Codevorschlag?
Hallo,
ist das die Abfrage für das Listenfeld?
Diese Abfrage braucht nur die Artikeltabelle als Datenbasis. Die 6 Indikationstabellen werden da nicht benötigt.
Der Sperrvermerk wird mit dem berechneten Feld (und darin der Bezug auf die Indikationstabellen) erzeugt.
Meinen Hinweis auf das mit ziemlicher Sicherheit falsche Datenmodell ignorierst Du aber hartnäckig. ;D
Hi,
nein, das ist der Code für eine Abfragetabelle, das Füllen des Listenfelds dauert ewig lange (aufgrund Datensätze > 100.000). Ein Unterformular ist da wesentlich schneller, so dass ich diese Variante alternativ prüfe.
Bis auf dass ich die rechten 6 Spalten durch eine zusammengefasste ersetzen möchte, läuft alles reibungslos.
Ich ignoriere Deinen Hinweis nicht, nur wenn ich zu diesem Zeitpunkt das Datenmodell wieder infrage stelle, fange ich mit der Anwendung komplett von vorne an. Das ohne ein Mehr an Wissen meinerseits, bringts nicht. Dann bräuchte ich schon jemanden, der sich hier zu mir setzt. Trotzdem danke ich Dir für Deinen Hinweis und Deine Geduld.
Das außerdem zu einem Zeitpunkt zu tun, wo mir nur noch diese zusammengefasste Checkbox fehlt scheint mir nicht lunkrativ.
Beim nächsten Projekt werde ich Vorschläge zum Datenmodell früher posten.
Hallo,
anbei ein einfaches Beispiel.
Ob Du diese Abfrage für ein Formular oder ein Listenfeld verwendest ist egal.
Ob das mit 100.000 DS aber noch vernüftig schnell geht musst Du probieren.
PS:
Deine Angaben sind eher verwirrend, ich zitiere:
ZitatIch habe eine Listbox im Hauptformular, wo ich eine Reihe Artikel aufliste (per VBA Code).
und später:
Zitatnein, das ist der Code für eine Abfragetabelle, das Füllen des Listenfelds dauert ewig lange
[Anhang gelöscht durch Administrator]
Hallo,
das mit der Listbox funktioniert nur eben viel zu langsam (ich summiere per VBA die 6 Checkboxen und schreibe dann in jeden Datensatz TRUE oder FALSE an die entsprechende Spalte der Listbox). Daher probiere ich es jetzt über eine Abfrage, die ich per Unterformular an die Stelle der Listbox platzieren möchte. Sechs Checkboxen nebeneinander funktionieren, aber das ist ja nicht mein Ziel. Ich möchte wie gesagt nur eine, die die Ergebnisse zusammenfasst.
Danke für Deine Beispieldatei, so ähnlich sieht es bei mir auch aus. Nur eine Abfrage, in der das Resultat der 6 möglichen Sperren vereint als einzelne Checkbox angezeigt wird, bekomme ich nach wie vor nicht hin.
Ich hab mal versucht mit Deinem Code oben was zu basteln (erst mal mit 3 Checkbox-Ergebnissen
SELECT Bingodata.idprozessauftragsnummer, IIf(DSum("blnStatus","IndicationData_Abweich","lngAuftragsNr = " & [IndicationData_Abweich.lngAuftragsNr])+DSum("blnStatus","IndicationData_CAPA","lngAuftragsNr = " & [IndicationData_CAPA.lngAuftragsNr])+DSum("blnStatus","IndicationData_CC","lngAuftragsNr = " & [IndicationData_CC.lngAuftragsNr])=0,"",True) AS Sperrvermerk
FROM (((((Bingodata LEFT JOIN IndicationData_Abweich ON Bingodata.idprozessauftragsnummer = IndicationData_Abweich.lngAuftragsNr) LEFT JOIN IndicationData_CAPA ON Bingodata.idprozessauftragsnummer = IndicationData_CAPA.lngAuftragsNr) LEFT JOIN IndicationData_CC ON Bingodata.idprozessauftragsnummer = IndicationData_CC.lngAuftragsNr) LEFT JOIN IndicationData_OOSAnalyt ON Bingodata.idprozessauftragsnummer = IndicationData_OOSAnalyt.lngAuftragsNr) LEFT JOIN IndicationData_OOSMibi ON Bingodata.idprozessauftragsnummer = IndicationData_OOSMibi.lngAuftragsNr) LEFT JOIN IndicationData_Valid ON Bingodata.idprozessauftragsnummer = IndicationData_Valid.lngAuftragsNr;
Leider wird mir da ein Syntax-Fehler angezeigt.
Edit: SQL korrigiert, trotzdem Fehlerhaft... Fehlender Operator in Abfrageausdruck 'lngAuftragsNr = '.
Hallo,
die Joins sind alle überflüssig, oder siehst Du in meiner Abfrage weitere Tabellen für eine Beziehung? Die Nebentabellen kommen in der Abfrage für den Sperrvermerk nur in der Formel vor.
So jetzt, ich habe den Code exakt wie in Deinem Beispiel eingegeben (die Namen natürlich entsprechend verändert)
SELECT Bingodata.idprozessauftragsnummer, IIf(DSum("blnStatus","IndicationData_Abweich","lngAuftragsNr = " & [lngAuftragsNr])+DSum("blnStatus","IndicationData_CAPA","lngAuftragsNr = " & [lngAuftragsNr])+DSum("blnStatus","IndicationData_CC","lngAuftragsNr = " & [lngAuftragsNr])=0,"",True) AS Sperrvermerk
FROM Bingodata;
Jetzt fragt mich der Hund per Popup nach der lngAuftragsNr, wenn ich die Abfrage starte.
Hallo,
lade die DB mal hoch, mit Spieldaten, gezippt in Access2003.
Das Ding hat gezippt noch über 8 mb, ich fürchte das wird schwer
Ok, scheinbar musste ich den Spaltennamen der Haupt- und nicht der Nebentabelle nehmen:
SELECT Bingodata.idprozessauftragsnummer, IIf(DSum("blnStatus","IndicationData_Abweich","lngAuftragsNr = " & [idprozessauftragsnummer])+DSum("blnStatus","IndicationData_CAPA","lngAuftragsNr = " & [idprozessauftragsnummer])+DSum("blnStatus","IndicationData_CC","lngAuftragsNr = " & [idprozessauftragsnummer])=0,"frei","gesperrt") AS Sperrvermerk
FROM Bingodata;
Jetzt heißt der Fehler "Datentypen in Kriterienausdruck unverträglich"... nur welcher, sagt er nicht.
Zitat... nur wenn ich zu diesem Zeitpunkt das Datenmodell wieder infrage stelle, fange ich mit der Anwendung komplett von vorne an. Das ohne ein Mehr an Wissen meinerseits, bringts nicht.
Als
Wissen solltest Du auf jeden Fall mitnehmen, dass sich gescheite und performante Abfragen i.d.R. nur bei einem passenden Datenmodell erstellen lassen - immerhin benötigt der Sportwagen SQL zum Entfalten seiner erheblichen Fähigkeiten eine passende Rennbahn, bereitet u.a. durch gute Datenmodellierung und Normalisierung.
Und Du darfst die Gewissheit mitnehmen, dass ein späteres Neuanfangen noch aufwändiger und schmerzlicher sein wird.
Zu der Eingangsfrage:
SELECT
T.ArtNr,
EXISTS (SELECT Null FROM TabelleU1 U WHERE U.ArtNr = T.ArtNr AND U.Gesperrt = True)
+
EXISTS (SELECT Null FROM TabelleU2 U WHERE U.ArtNr = T.ArtNr AND U.Gesperrt = True)
+ ...
AS Gesperrt
FROM
TabelleH T
Wir sind auf dem richtigen Weg, danke, ebs17. Das, worüber Access jetzt noch meckert, ist wohl die Summierung mittels "+", allerdings kann man die Fehlermeldung nicht vollständig lesen:
"in Abfrageausdruck ...[SQL string]" steht dort nur.
Ersetze ich die "+" durch "&" erhalte ich als Ergebnis meine 6 Checkboxen-Stati, natürlich leider als verketteten String "-1 0 -1 -1 0 0".
Oder liege ich falsch mit meiner Vermutung (Summe)?
Zeige Deine vollständige SQL-Anweisung, dann bitte lesbar formatiert: SQL Formatter (http://www.sqlinform.com/free_online_sw.html)
Der verwendete Lösungsansatz (weg von den grässlichen Domänenaggregatfunktionen):
Ein EXISTS-Ausdruck ergibt True (-1) oder False (0). Diese Zahlen sollte man addieren (+) können. Ist das Ergebnis < 0, so liegt mindestens eine Sperrung vor.
Eine Verkettung (&) ist da nicht so sinnvoll.
Testausdruck:
SELECT True + False + True + False as X
MfGA
ebs
Hi,
im Moment sieht es wie folgt aus (zum Testen auf 3 Untertabellen reduziert):
SELECT Bingodata.idprozessauftragsnummer,
EXISTS
(SELECT NULL
FROM IndicationData_Abweich U
WHERE U.lngAuftragsNr = Bingodata.idprozessauftragsnummer
AND U.blnStatus = True
)
+ EXISTS
(SELECT NULL
FROM IndicationData_CAPA U
WHERE U.lngAuftragsNr = Bingodata.idprozessauftragsnummer
AND U.blnStatus = True
)
+ EXISTS
(SELECT NULL
FROM IndicationData_CC U
WHERE U.lngAuftragsNr = Bingodata.idprozessauftragsnummer
AND U.blnStatus = True
)
AS Gesperrt
FROM Bingodata
WHERE (
(
(
Bingodata.idprozessauftragsnummer
)
NOT LIKE "*44?????"
)
)
ORDER BY Bingodata.idprozessauftragsnummer DESC;
Diese Anweisung erzeugt den gleichen Fehler und funktioniert mit "&"? Da bin ich ratlos.
Ggf. müsste man testen mit einzelnen Teilausdrücken sowie mit verringerter Datenmenge (wenn Fehler aus Daten herrührt), und natürlich sollte man Schreibfehler bei den Bezeichnungen ausschließen.
Nebenbei:
WHERE Bingodata.idprozessauftragsnummer NOT LIKE "*44?????"Ein solches Kriterium unterstützt nicht die Verwendung eines Index auf die ID und bedeutet den Verzicht auf erhebliche Performance.
Sehr wahrscheinlich wäre hier auch ein zusätzlicher Normalisierungsschritt angeraten:
*44?????
=> Feld1: Inhalt von *
=> Feld2: 44 ' Kennzahl?
=> Feld3: ????? ' laufende Nummer?
WHERE Feld2 = 44
MfGA
ebs
ZitatGgf. müsste man testen mit einzelnen Teilausdrücken sowie mit verringerter Datenmenge (wenn Fehler aus Daten herrührt), und natürlich sollte man Schreibfehler bei den Bezeichnungen ausschließen.
Wenn ich den Ausdruck "exists" weglasse, nimmt Access auch den "+" Operator, natürlich kommt kein brauchbares Ergebnis raus, was mich aber zu der Frage drängt, ob man "EXISTS"-Ergebnbisse überhaupt so summieren kann?
ZitatEin solches Kriterium unterstützt nicht die Verwendung eines Index auf die ID und bedeutet den Verzicht auf erhebliche Performance.
Wie ändere ich das denn, damit es performanter wird? Die ProzessID ist eine mehr oder weniger beliebige 7-stellige Nummer, ich brauche für diesen Zweck nur die nicht, die mit 44 beginnen.
Zitatwas mich aber zu der Frage drängt, ob man "EXISTS"-Ergebnbisse überhaupt so summieren kann?
Das drängt mich zu der Frage, ob Du die obigen Beiträge
vollständig gelesen hast. Du kannst gerne noch mal eine Ehrenrunde drehen.
Zitatbeliebige 7-stellige Nummer, ich brauche für diesen Zweck nur die nicht, die mit 44 beginnen
In einer beliebigen Zahl ist es uninteressant, ob da bestimmte Ziffern an bestimmten Stellen vorkommen. Man muss schon erst seine Aufgabe begreifen, ehe man sie lösen kann.
ZitatWie ändere ich das denn ...
Wie gesagt: Im Idealfall einen zusätzlicher Normalisierungsschritt ausführen.
Alternativ: Zahlen kann man auch in der Programmierung als Zahlen behandeln, da ist keine Textverarbeitung notwendig:
WHERE ID < 4400000 OR ID >= 4500000MfGA
ebs
Zitat von: ebs17
Zitatwas mich aber zu der Frage drängt, ob man "EXISTS"-Ergebnbisse überhaupt so summieren kann?
Das drängt mich zu der Frage, ob Du die obigen Beiträge vollständig gelesen hast. Du kannst gerne noch mal eine Ehrenrunde drehen....
Ja, kein Grund garstig zu werden, mein Access verhält sich nicht anders, je öfter ich hier Ehrenrunden drehe, es lehnt die Kombi "EXISTS" und "+" in dieser Konstellation einfach ab. Ich habe mir inzwischen mit dem "OR" Operator an Stelle des "+" geholfen, also die EXISTS allesamt mit OR verknüpft.
Da meine Eingangsfrage hiermit gelöst ist, markiere ich den Thread dementsprechend. An dieser Stelle ein herzliches "Danke" an MzKlMu und ebs17!
Zitat von: ebs17Zitatbeliebige 7-stellige Nummer, ich brauche für diesen Zweck nur die nicht, die mit 44 beginnen
In einer beliebigen Zahl ist es uninteressant, ob da bestimmte Ziffern an bestimmten Stellen vorkommen. Man muss schon erst seine Aufgabe begreifen, ehe man sie lösen kann.....
Hilfe in der Form des kategorischen Imperativs ist selten wirklich hilfreich. Und nein, es ist nicht uninteressant, welche Ziffern an welchen Stellen vorkommen, da die Ziffer nach einem bestimmten System aufgebaut ist. Das alles passiert jedoch im SAP, und damit gänzlich unerreichbar für meine Access-Anwendung und auch für etwaige Normalisierungsbemühungen. Lokal gesehen ist es daher eine beliebige Zahl, global nicht.
Zitat von: ebs17ZitatWie ändere ich das denn ...
Wie gesagt: Im Idealfall einen zusätzlicher Normalisierungsschritt ausführen.
Alternativ: Zahlen kann man auch in der Programmierung als Zahlen behandeln, da ist keine Textverarbeitung notwendig:
WHERE ID < 4400000 OR ID >= 4500000...
Ich bekomme die "Zahlen" als Text formatiert aus SAP via externer MS-SQL-DB (ODBC) als Verknüpfte Tabelle in meine Abfrage.