Access-o-Mania

Access-Forum (Deutsch/German) => Tabelle/Abfrage => Thema gestartet von: Mak am Oktober 09, 2010, 17:28:03

Titel: Vermeidung von IIF-Konstrukten
Beitrag von: Mak am Oktober 09, 2010, 17:28:03
Hallo zusammen,

wir haben heute einen Test in meinem Database-Kurs geschrieben.
Und da ware u.a. zwei Aufagaben zu bearbeiten die es in sich hatten.
Ich habe sie als doc datei angehängt, da ich es nicht zustande gebracht habe, alle grafiken hier einzubinden.
Mich würde mal eure Lösungsansätze interessieren.
Die Besonderheit war: Es dürfen keine IIF-Konstrukte verwendet werden und möglichst einfach programmiert werden.  

Als Grundlage dient die datenbank von oma

gruss
mak

[Anhang gelöscht durch Administrator]
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: DF6GL am Oktober 09, 2010, 17:37:56
Hallo,

IIF ??

Über Abfrage-Parameterfenster ist das eh eine Krücke... und das folgend benutzte Openquery auch...



Dim InputboxWert  as Long

InputboxWert =Inputbox (....)



Select Case InputboxWert

Case 1
docmd.Openquery "<<DeineAbfragefürdenFall1>>"

Case 2
docmd.Openquery "<<DeineAbfragefürdenFall2>>"

Case 3
docmd.Openquery "<<DeineAbfragefürdenFall3>>"


Case else
docmd.Openquery "<<DeineAbfragefürdenjedenanderenFall>>"


End Select


Andererseits könnte auch die Switch oder Choose-Funktion zum Erfolg führen.
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: Mak am Oktober 09, 2010, 17:54:25
danke für deine Antwort, aber ich hätte es nur über Abfragen machen müssen.

daher wäre es hilfreich wenn es mir einer mit normalen Abfragen zeigen könnte.

Mit IIF meine IF-Konstrukte.

gruss
markus
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: database am Oktober 09, 2010, 20:18:15
Hallo,
eine nette Vorgabe ...
ZitatEs dürfen keine IIF-Konstrukte verwendet werden

Nur das Gegenstück (CASE ... WHEN ... ELSE) existiert halt unter Access nicht und eine Inputbox wie in deiner Aufgabenstellung gibts beim SQL-Server nicht.

??? ???

Peter
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: Mak am Oktober 09, 2010, 21:12:24
hallo peter,

kannst du mir mal bitte zeigen, wie du es lösen würdest?
also nur über Abfragen (wenn IIF Konstrukte zulässig wären)

danke
gruss
Mak
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: database am Oktober 10, 2010, 11:03:20
Hallo Mak,

also NUR über Abfragen ... iss nicht, da muss ich passen.
So wie DF6GL eine VBA - Lösung vorgeschlagen hat kann ich mir eine ähnlice Variante vorstellen - die Inputbox in deiner Angabe läßt den Schluss zu, dass da VBA im Spiel sein müsste.

Erstelle eine Abfrage auf die PropertyForRent - Tabelle und speichere sie als 'AbfrageXY'
Den untenstehenden Code in ein Standardmodul und dann F5


Sub selection()

    Dim strSQL As String
   
    Select Case InputBox("Enter 1 / 2 for sorting then properties ...", "Enter Parameter Value")
   
        Case 1
            strSQL = "SELECT PropertyForRent.propertyNo, [street] & ', ' & [city] AS address, " & _
                    "PropertyForRent.type, PropertyForRent.rooms, PropertyForRent.rent " & _
                    "FROM PropertyForRent ORDER BY PropertyForRent.rooms;"
        Case 2
            strSQL = "SELECT PropertyForRent.propertyNo, [street] & ', ' & [city] AS address, " & _
                    "PropertyForRent.type, PropertyForRent.rooms, PropertyForRent.rent " & _
                    "FROM PropertyForRent ORDER BY PropertyForRent.rent DESC;"
    End Select
   
    CurrentDb.QueryDefs("AbfrageXY").SQL = strSQL
    DoCmd.OpenQuery "AbfrageXY"
   
End Sub


Ich weiß die Aufgabenstellung ist möglicherweise auch anders - was für mich nicht zwangsweise bedeutet dass die Sachen dadurch performanter werden - (Subqueries sind da so ein Thema)
Mit obigem Code wäre natürlich auch möglich eine bestehende Abfrage 'lediglich' um den ORDER BY - Teil zu erweitern bzw. diesen dynamisch zu ändern OHNE die gesamte SQL zu übergeben.
Theorie und Praxis gehen halt manchmal recht weit auseinander - daher obiges als BEISPIEL einer Möglichkeit zu sehen. ;)
Grüße
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: oma am Oktober 10, 2010, 12:50:52
Hallo Mak,

deine Jungs werden sich evt. etwas bei den Fragen gedacht haben, aber:

eine Parameter-Abfrage, in der mit verschiedene  Parameter unterschiedliche Sortierungen relisiert werden können, kann ich mir nicht vorstellen.
Ich kenne keine Lösung, ob mit oder ohne IIF-Konstrukte.

Das alle bisherigen Lösungen mit sub-queries eben "Schulbeispiele" sind, hatte ich ja schon erwähnt. aber in diesem Fall fällt mir nicht einmal eine "Schülerlösung" ein.

Natürlich geht der Weg von Franz u. Peter über VBA, wir sind aber sehr interessiert an einer Lösung , die sich deine Herren so vorgestellt haben!!!

Gruß Oma
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: database am Oktober 10, 2010, 15:40:19
Hallo,

@oma
;D "...werden sich evt. etwas bei den Fragen gedacht haben..."  - und die Betonung liegt auf evt. !  ;D

naja geben sollte es das schon - http://www.blueclaw-db.com/accessquerysql/dynamic_order_by.htm (http://www.blueclaw-db.com/accessquerysql/dynamic_order_by.htm)

- nur finde ich keinen Weg das Ding dazu zu bewegen einmal nach ersten Feld steigend und im anderen Fall nach dem zweiten Feld fallend zu sortieren - endet nämlich dann in einem Syntaxfehler sobald in diesem leidigen IIF-Construct DESC zum Einsatz kommt. So ein Schmarrn aber auch!

Da lob' ich mir halt die VBA-Variante, die funktioniert halt beim ersten Versuch, läuft problemlos, kostet nix und sieht dazu auch noch gut aus - na wenn das nichts ist?! ;D :D ;)

Zitat...interessiert an einer Lösung , die sich deine Herren so vorgestellt haben
- oh ja, die möcht ich unbedingt sehen!

Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: oma am Oktober 10, 2010, 16:20:41
Hallo,

@Peter: jo, das Wechseln der Felder nach dem sortiert wird geht schon (wie im angeführten Link), aber eben 2 Felder u. abwechselnd sortieren kann ich nicht erzeugen.

@Mak: mir kamen die Tabellenbezeichnungen deines Beispieles von Anfang an irgendwie bekannt vor. Habe mal gesucht und tatsächlich:

amerikanische Original-Ausgabe bei Addison-Wesley USA: Database Systems; ISBN 0-201-34287-1
deutsche Ausgabe:  Datenbank-Systeme; Thomas Connolly, Carolyn Begg, Anne Strachan; Addison-Wesley ; ISBN 3-8273-2013-5

Dort werden durchgehend die verschiedensten Beispiele mit einer DB "DreamHome" (Verwaltung von Miet-Immobilien) dargestellt; die Tabellenbezeichnung, einige Feldbezeichnungen u.a. sind mit deinem Beispiel identisch.

Deine Betreuer waren also nicht besonders kreativ ;D; aber zumindest waren deine konkreten Aufgabenstellungen nicht auch noch im Buch.

Nutzen kann Dir der Verweis auf das Buch natürlich nur, wenn du auch weiterhin im Studiom mit solchen Dingen "belegt" wirst.
Es ist tatsächlich eine sehr gute und gründliche Darstellung der verschiedensten Grundlagen (und etwas mehr) zur Arbeit mit relationalen Datenbanken!

Gruß Oma

Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: Mak am Oktober 17, 2010, 17:34:34
hallo zusammen,

danke oma für den tipp, aber das ist unser Kursbuch, sodass explizit vom dozenten darauf verwiesen wurde.

@ Peter

für welche Aufgabenstellung (1 oder 2) kann ich deinen vba code verwenden bzw. muss ich für mein explizites bsp noch etw. ändern?

ZitatSub selection()

    Dim strSQL As String
   
    Select Case InputBox("Enter 1 / 2 for sorting then properties ...", "Enter Parameter Value")
   
        Case 1
            strSQL = "SELECT PropertyForRent.propertyNo, [street] & ', ' & [city] AS address, " & _
                    "PropertyForRent.type, PropertyForRent.rooms, PropertyForRent.rent " & _
                    "FROM PropertyForRent ORDER BY PropertyForRent.rooms;"
        Case 2
            strSQL = "SELECT PropertyForRent.propertyNo, [street] & ', ' & [city] AS address, " & _
                    "PropertyForRent.type, PropertyForRent.rooms, PropertyForRent.rent " & _
                    "FROM PropertyForRent ORDER BY PropertyForRent.rent DESC;"
    End Select
   
    CurrentDb.QueryDefs("AbfrageXY").SQL = strSQL
    DoCmd.OpenQuery "AbfrageXY"
   
End Sub
 

falls es nur für einen der beiden funktioniert, könntest du mir mal bitte auch den anderen zeigen.
sorry aber ich kenn mich mit vbA noch nicht so im detail aus

gruss
mak
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: database am Oktober 17, 2010, 20:57:20
Hallo Mak,

ich habe beim ersten Posting der Lösung leider übersehen, dass die Aufgabe 1  drei Ergebnisvarianten haben muss.
...bei Eingabe von 1 in die Inputbox  gibt es eine Varainte a und eine Variante b
sowie dann das Ergebnis bei Eingabe von 2 in die Inputbox. Habe daher die SQL-Anweisung für die Eingabe von 1 um eine Sortierung erweitert.

Daher bitte den untenstehenden Code verwenden, der deckt nun alle 3 Möglichkeiten ab.

In der Tabelle PropertyForRent war das Feld 'rent' als Text deklariert - das sollte m.E. eine Zahl sein, sonst geht mit Sortieren nicht viel...   ;D

Der berichtigte Code für die erste Aufgabenstellung:
Erstelle bitte ZUVOR eine Abfrage auf die Tabelle PropertyForRent und speichere diese unter dem Namen 'qryRoomsRent' sowie eine Abfrage auf die Tabelle staff und speichere diese unter dem Namen 'qryStaffSalary'

Sodann wie bereits in der vorangegangenen Antwort geschrieben bitte die untenstehenden Codes in ein Standardmodul KOPIEREN und dann den Cursor in die jeweilige Sub stellen und F5 drücken.



Sub selection1()
    'Führt die Abfragen gemäß der 1. Aufgabenstellung durch
   Dim strSQL As String
   'Erzeugen und Anzeigen der Inputbox wie in der
    'Angabenbeschreibung zu sehen um die Eingaben 1 oder 2 zu erfragen
   Select Case InputBox("Enter 1 / 2 for sorting then properties ...", "Enter Parameter Value")
   
       Case 1
            'Es wurde 1 eingegeben daher wird die SQL der Abfrage entsprechend dem gewünschten Ergebnis erstellt
           strSQL = "SELECT PropertyForRent.propertyNo, [street] & ', ' & [city] AS address, " & _
                   "PropertyForRent.type, PropertyForRent.rooms, PropertyForRent.rent " & _
                   "FROM PropertyForRent ORDER BY PropertyForRent.rooms, PropertyForRent.rent DESC;"
       Case 2
            'Es wurde 2 eingegeben ....
           strSQL = "SELECT PropertyForRent.propertyNo, [street] & ', ' & [city] AS address, " & _
                   "PropertyForRent.type, PropertyForRent.rooms, PropertyForRent.rent " & _
                   "FROM PropertyForRent ORDER BY PropertyForRent.rent DESC;"
   End Select
   'Der Abfrage qryRoomsRent wird die oben definierte SQL zugewiesen
   CurrentDb.QueryDefs("qryRoomsRent").SQL = strSQL
    'Die Abfrage wird ausgeführt (geöffnet) und das Ergbnis angezeigt    
    DoCmd.OpenQuery "qryRoomsRent"
   
End Sub


..und hier der Code fü+r die 2 Aufgabe mit den Eingabemöglichkeiten 1,2 oder 3


Sub selection2()

   'Führt die Abfragen gemäß der 2. Aufgabenstellung durch
    'Die Vorgänge sind analog zu selection1 zu verstehen.
   Dim strSQL As String
   
   Select Case InputBox("Enter 1 / 2 / 3 to see the managers / assistents / whole stuff at every branch office", "Enter Parameter Value")
   
       Case 1
           strSQL = "SELECT staff.staffNo, [fname] & ' ' & [iname] AS sName, staff.position, staff.salary, staff.branchNo " & _
                    "FROM staff " & _
                    "WHERE staff.position = 'Manager' " & _
                    "ORDER BY staff.salary DESC;"
       
       Case 2
           strSQL = "SELECT staff.staffNo, [fname] & ' ' & [iname] AS sName, staff.position, staff.salary, staff.branchNo " & _
                    "FROM staff " & _
                    "WHERE staff.position = 'Assistent' " & _
                    "GROUP BY staff.staffNo, [fname] & ' ' & [iname], staff.position, staff.salary, staff.branchNo, staff.iName " & _
                    "ORDER BY staff.branchNo, staff.iname, staff.salary DESC;"
       Case 3
           strSQL = "SELECT staff.staffNo, [fname] & ' ' & [iname] AS sName, staff.position, staff.salary, staff.branchNo " & _
                    "FROM staff " & _
                    "GROUP BY staff.staffNo, [fname] & ' ' & [iname], staff.position, staff.salary, staff.branchNo, staff.iName " & _
                    "ORDER BY staff.branchNo, staff.iName;"
       
   End Select

   CurrentDb.QueryDefs("qryStaffSalary").SQL = strSQL
   DoCmd.OpenQuery "qryStaffSalary"

End Sub



Denke das sollte so klappen :)

Grüße
Peter
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: Mak am Oktober 18, 2010, 07:00:29
ZitatErstelle bitte ZUVOR eine Abfrage auf die Tabelle PropertyForRent und speichere diese unter dem Namen 'qryRoomsRent' sowie eine Abfrage auf die Tabelle staff und speichere diese unter dem Namen 'qryStaffSalary'
 

kannst du mir bitte kurz erkälren was du damit genau meinst?

Selcet ???
From PropertyForRent bzw. Staff

sowas in der Art

Und noch eine wahrscheinlich primitive Frage hinterhergeschickt: Was sind alles Standardmodule?

gruss
Mak
Titel: Re: Vermeidung von IIF-Konstrukten
Beitrag von: database am Oktober 18, 2010, 08:59:12
Hallo Mak, guten Morgen,

Standardmodule werden jene Datenbankobjekte genannt, die sich im Datenbankfenster unter 'Module' befinden bzw. dort erstellt werden.
Bei Access 2007 kann man das über die Ribbonleiste 'Datenbanktools' ---  ' Visual Basic' --- Rechtsklick im Navigationsbereich des VBA-Editors, der sich jetzt geöffnet hat --- 'Hinzufügen' --- 'Modul'
ODER  im Datenbankfenster drücken von ALT + F5 und dann ab Rechtsklick ... ,
bei Access 2000 bis Access 2003 im Datenbankfenster auf Module und dann in der Kopfleiste des Datenbankfensters auf 'Neu' klicken bewerkstelligen.

In allen Fällen wird dir nun ein leeres Standardmodul angezeigt. Wähle daraufhin 'Speichern' und vergib gleich mal einen vernünftigen Namen für dieses Modul.
In deinem Fall z.B. 'basQueries' - um zu kennzeichnen, dass sich innerhalb dieses Moduls Routinen befinden, die irgendwas mit Abfragen zu tun haben.
Danach kannst du die Codes aus meinem Vorschlag dorthin KOPIEREN (nicht abschreiben - Fehlervermeidung).

Die entsprechende, benötigte oder gewünschtee Sub kannst du dann IN DIESEM FALL WIE DU SIE VERWENDEN WIRST starten, indem du dich
mit dem Cursor irgendwo in die benötigte Sub stellst und F5 drückst. Willst du den Programmablauf mitverfolgen und eventuell Variabelenwerte zur Laufzeit auslesen
(man fährt dazu beispielsweise mit dem Mauszeiger langsam über den jeweiligen Variablennamen im Code) dann drückst du innerhlab der Sub F8,
jede Programmzeile wird dann durch drücken von F8 schrittweise abgearbeitet.

Die Namen der Abfragen, die du erstellen sollst sind abhängig davon, welchen Namen man in der Sub verwendet.
Sie sollten deshalb vor der Ausführung einer Sub schon bestehen damit sie vom Programm angesprochen werden können.
Es ist dabei vollkommen unerheblich wie die Abfrage beschaffen ist, da die SQL der Abfragen zur Laufzeit der Subs erstellt und der Abfrage dann neu  zugewiesen wird.

Also bedeutet dies für dich:
Um eine verwendbare, ansprechbare Abfrage für das erste Beispiel zu haben legst du eine Abfrage auf die Tabelle PropertiesForRent an. Die kann ruhig "SELECT * FROM PropertiesForRent" als SQL beinhalten.
Diese SQL wird dann durch die Sub 'selection1' so geändert, dass sie der Beispielsvorgabe entspricht. Speichere diese Abfrage unter dem Namen "qryRoomsRent"

Gleiches gilt für die 2. Abfrage auf die Tabelle 'staff' --- auch hier genügt eine SQL "SELECT * FROM staff" und das Speichern der Abfrage unter dem richtigen Namen. Speichere diese Abfrage unter dem Namen "qryStaffSalary"

Somit haben die Routinen nun die notwendigen Datenbankobjekte zur Verfügung mit denen sie hier ...


Sub selection1()
...
..
.
    CurrentDb.QueryDefs("qryRoomsRent").SQL = strSQL
    DoCmd.OpenQuery "qryRoomsRent"

End Sub


bzw. hier ...


Sub selection2()
...
..
.

    CurrentDb.QueryDefs("qryStaffSalary").SQL = strSQL
    DoCmd.OpenQuery "qryStaffSalary"

End Sub


... arbeiten können.
Wenn das Abfrage ergebnis angezeigt wird, Ergebnis kontrollieren und VOR AUSFÜHRUNG einer neuen Variante (Eingabe von 1,2 oder 3) das Abfragefenster schließen - lass jede Abfrage vollkommen unbehelligt NEU erstellen!
Wirst du beim Schließen ums Speichern der Änderungen gefragt kannst du das machen brauchst aber nicht, da ja sowieso bei jedem Durchlauf der Codes die SQL erneuert wird.

HTH

Peter

p.s. ich füge nun in die Codes in meiner Antwort noch Kommentarzeilen ein, dann wird der Ablauf auch ein wenig durchsichtiger für dich.