{"id":55000729,"date":"2010-08-01T00:00:00","date_gmt":"2020-05-22T22:06:13","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=729"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Datumsbereiche_auswaehlen","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/","title":{"rendered":"Datumsbereiche ausw&auml;hlen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Das aktuelle Datum ist unter Access schnell eingegeben &#8211; es reicht die Tastenkombination Strg + Semikolon. Sonstige Daten w&auml;hlt man ab Access 2007 schnell mit dem eingebauten Datepicker aus. Oder Sie verwenden die L&ouml;sung aus dem Beitrag &#8222;Flexible Datumsfelder&#8220; (www.access-im-unternehmen.de\/690). Wenn Sie aber gleich einen Zeitraum, bestehend aus zwei Datumsangaben, eingeben m&uuml;ssen, brauchen Sie gr&ouml;&szlig;ere Kaliber &#8211; so eines wie wir im vorliegenden Beitrag beschreiben.<\/b><\/p>\n<p>Viele Anwendungen erfordern die Eingabe nicht nur eines einzigen Datums, sondern gleich eines ganzen Bereichs. Das sieht im einfachsten Fall wie in Bild 1 aus.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Einfaches Beispiel f&uuml;r die Eingabe eines Datumsbereichs<\/span><\/b><\/p>\n<p>Das dort dargestellte Formular enth&auml;lt zwei Textfelder zur Eingabe des Start- und des Enddatums. Das Ziel dieses Beitrags ist, ein Formular zu erstellen, das entweder per Doppelklick in eines der betroffenen Datumsfelder oder &uuml;ber eine entsprechende Schaltfl&auml;che angezeigt werden kann. Es soll gegebenenfalls einen eventuell bereits in den Textfeldern vorhandenen Datumsbereich gleich beim &Ouml;ffnen anzeigen und die M&ouml;glichkeit bieten, diesen anzupassen beziehungsweise neu zu setzen.<\/p>\n<p>Am einfachsten w&auml;re die Auswahl eines Datumsbereichs, wenn diese mit einer Mausgeste funktionieren k&ouml;nnte &#8211; Klick auf das erste Datum in einer Datums&uuml;bersicht, mit gedr&uuml;ckter Maus zum zweiten Datum fahren, loslassen, fertig. Aber wie l&auml;sst sich dies realisieren Zun&auml;chst einmal ben&ouml;tigen wir ein Formular, das die infrage kommenden Datumsangaben zur Auswahl anzeigt. Und bevor dieses &uuml;berhaupt irgendein Datum anzeigt, m&uuml;ssen wir uns erstmal &uuml;berlegen, welche Zeitr&auml;ume &uuml;berhaupt erfassbar sein sollen. Zeitr&auml;ume in der Vergangenheit In der Zukunft Oder einfach ein paar Monate vor und hinter dem aktuellen Datum Nun: Wenn uns diese Frage am Erstellen einer schicken L&ouml;sung hindert, dann parametrisieren wir dies einfach und legen je nach Anwendung fest, wie der Zeitraum aussehen soll. <\/p>\n<p>Wie aber soll die Datums&uuml;bersicht zur Auswahl eines Datumsbereichs genau aufgebaut sein Angenommen, wir w&uuml;rden jeweils ein Jahr abdecken, wobei wir ein bestimmtes Intervall im Code festlegen und dem Benutzer die M&ouml;glichkeit geben, monatsweise vor- und zur&uuml;ckzubl&auml;ttern, w&auml;re eine zeilenweise Anzeige der Monate mit ihren Tagen wohl am geeignetsten.<\/p>\n<p>Bauen wir also zun&auml;chst ein Formular, das f&uuml;r jeden Tag eines Jahres ein Steuerelement enth&auml;lt und das wie in Bild 2 aussieht.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: So soll das Formular f&uuml;r die Datumsauswahl sp&auml;ter aussehen.<\/span><\/b><\/p>\n<p>Das Formular soll nach folgenden Regeln arbeiten:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Wenn keines der beiden Datumsfelder des aufrufenden Formulars gef&uuml;llt ist, wird das aktuelle Datum als Start- und Enddatum verwendet &#8211; es wird also nur der aktuelle Tag markiert.<\/li>\n<li class=\"aufz-hlung\">Wenn das Startdatum angegeben ist und kein Enddatum, wird das Enddatum gleich dem Startdatum gesetzt und dieses im Formular zur Datumsauswahl eingestellt.<\/li>\n<li class=\"aufz-hlung\">Gleiches gilt umgekehrt, wenn nur das Enddatum angegeben ist.<\/li>\n<li class=\"aufz-hlung\">Wenn beide Daten angegeben sind, aber das Enddatum vor dem Startdatum liegt, werden die Daten einfach vertauscht und der entsprechende Zeitraum angezeigt.<\/li>\n<\/ul>\n<p><b>Einsatz des Datumsauswahlformulars<\/b><\/p>\n<p>M&ouml;glicherweise m&ouml;chten Sie gar nicht so genau wissen, wie dieses Formular funktioniert, sondern es einfach nur in Ihren eigenen Anwendungen einsetzen. F&uuml;r diesen Fall erfahren Sie nun, wie Sie diese L&ouml;sung in eine eigene Anwendung integrieren und verwenden. Zuerst importieren Sie die folgenden Elemente der Beispieldatenbank in die Zielanwendung:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Formular <b>frmDatumsauswahl<\/b><\/li>\n<li class=\"aufz-hlung\">Klassenmodul <b>clsDatumsauswahl<\/b><\/li>\n<li class=\"aufz-hlung\">Klassenmodul <b>clsLabel<\/b><\/li>\n<li class=\"aufz-hlung\">Standardmodul <b>mdlDatumsauswahl<\/b><\/li>\n<\/ul>\n<p>Anschlie&szlig;end ben&ouml;tigen Sie nur noch ein paar Zeilen Code, die Sie f&uuml;r die Ereignisprozedur <b>Beim Laden <\/b>des betroffenen Formulars hinterlegen.<\/p>\n<p>Hierzu gehen Sie folgenderma&szlig;en vor:<\/p>\n<ul>\n<li class=\"aufz-hlung\">&Ouml;ffnen Sie das Formular mit den beiden Datumsfeldern in der Entwurfsansicht.<\/li>\n<li class=\"aufz-hlung\">W&auml;hlen Sie auf der Registerseite <b>Ereignis<\/b> f&uuml;r die Eigenschaft <b>Beim Laden <\/b>den Wert <b>[Ereignisprozedur]<\/b> aus und klicken Sie auf die Schaltfl&auml;che mit den drei Punkten (siehe Bild 3).<\/li>\n<li class=\"aufz-hlung\">F&uuml;gen Sie den Code aus Listing 1 hinzu.<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic003.png\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Anlegen des Ereignisses, das unser Formular um die Funktion zum Ausw&auml;hlen von Datumsbereichen erweitern soll<\/span><\/b><\/p>\n<p class=\"listingueberschrift\">Listing 1: F&uuml;llen der Tabelle tblSuchfelder mit allen m&ouml;glichen Suchfeldern<\/p>\n<p class=\"qf\">Dim objDatumsauswahl As clsDatumsauswahl<\/p>\n<p class=\"qf\">Private Sub Form_Load()<\/p>\n<p class=\"qf\">  Set objDatumsauswahl = New clsDatumsauswahl<\/p>\n<p class=\"qf\">  With objDatumsauswahl<\/p>\n<p class=\"qf\">    Set .Form = Me<\/p>\n<p class=\"qf\">    Set .StartdateTextbox = Me!txtStartdatum<\/p>\n<p class=\"qf\">     Set .EnddateTextbox = Me!txtEnddatum<\/p>\n<p class=\"qf\">   End With<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p>Fertig! Sie brauchen nun nur noch in die Formularansicht zu wechseln und einen Doppelklick auf einem der Textfelder auszuf&uuml;hren.<\/p>\n<p><b>Erstellung und individuelle Anpassung<\/b><\/p>\n<p>Nach der Einf&uuml;hrung geht es an die technischen Hintergr&uuml;nde. Die erste Frage ist: Wie stellen wir die ganzen Tage der Jahres&uuml;bersicht dar Die Antwort lautet: Mit Bezeichnungsfeldern. Diese bieten, wie wir gleich sehen werden, alle notwendigen Ereignisprozeduren, sie k&ouml;nnen Texte anzeigen und wir k&ouml;nnen verschiedene Hintergrundfarben f&uuml;r sie einstellen.<\/p>\n<p>Welche Elemente brauchen wir f&uuml;r das Formular<\/p>\n<ul>\n<li class=\"aufz-hlung\">Ein Bezeichnungsfeld als Beschriftung der Zeilen- und Spalten&uuml;berschriften (<b>Monat\/Tag<\/b>),<\/li>\n<li class=\"aufz-hlung\">12 Bezeichnungsfelder f&uuml;r die Monate (Zeilen&uuml;berschriften),<\/li>\n<li class=\"aufz-hlung\">37 Bezeichnungsfelder f&uuml;r die Spalten&uuml;berschriften, die durchlaufend mit den Anfangsbuchstaben der Wochentage belegt werden &#8211; die Samstage und Sonntage werden zus&auml;tzlich fett gedruckt, um eine einfachere Orientierung zu erm&ouml;glichen, und<\/li>\n<li class=\"aufz-hlung\">366 Bezeichnungsfelder f&uuml;r die eigentlichen Tage. Das letzte davon brauchen wir allerdings nur alle vier Jahre.<\/li>\n<\/ul>\n<p>Die ersten drei Kategorien von Bezeichnungsfeldern erhalten immer die gleiche Position &#8211; egal, welche Monate welchen Jahres angezeigt werden. Es &auml;ndern sich lediglich die Beschriftungen der Zeilen&uuml;berschriften, also die Monate.<\/p>\n<p>Die 366 Bezeichnungsfelder f&uuml;r die Tage werden je nach Startmonat unterschiedlich in der Matrix zwischen Monaten und Tagen aufgeteilt. Das liegt daran, dass wir in den Spalten&uuml;berschriften feste Wochentage festlegen und die Datumsangaben eines jeden Monats daran ausrichten m&uuml;ssen. Der 1. Januar 2010 ist beispielsweise ein Freitag, der 1. Februar 2010 ein Montag. Dementsprechend besitzt der erste Tag eines jeden Monats einen unterschiedlichen Abstand zum linken Rand, die &uuml;brigen Tage reihen sich dahinter ein.<\/p>\n<p>Und auch die Beschriftungen m&uuml;ssen je nach dem in der ersten Zeile angezeigten Monat dynamisch angepasst werden. F&uuml;r diese L&ouml;sung schien es am sinnvollsten, die Bezeichnungsfelder f&uuml;r die Tage schlicht von <b>001<\/b> bis <b>366 <\/b>durchzunummerieren und den Rest zur Laufzeit einzustellen. Beim Erstmaligen Anlegen werden diese Steuerelemente also einfach links oben im Formularentwurf abgelegt.<\/p>\n<p><b>Erstellen des Formulars zur Anzeige des Jahreskalenders<\/b><\/p>\n<p>Zu Beginn bekommen wir es gleich mal mit einer richtigen Flei&szlig;aufgabe zu tun: Das Anlegen der Bezeichnungsfelder. Wenn wir richtig gez&auml;hlt haben, kommen wir immerhin auf 416 Felder, die wir anlegen und mit Namen versehen m&uuml;ssen. Einige davon, die als Spalten- und Zeilen&uuml;berschriften dienen, m&uuml;ssen wir gar noch genau ausrichten. Das Ausrichten m&uuml;ssen wir anschlie&szlig;end wahrscheinlich noch mehrfach wiederholen, da wir ja die Breite und H&ouml;he der Felder mit denen der 366 Bezeichnungsfelder abstimmen m&uuml;ssen, welche die Tage anzeigen.<\/p>\n<p>Na, klingelt&#8220;s Das ist nat&uuml;rlich keine Aufgabe f&uuml;r <b>Access im Unternehmen<\/b>-Leser. Daf&uuml;r stellen wir entweder einen Hilfsprogrammierer ein oder &#8211; noch besser &#8211; Sie automatisieren das Ganze.<\/p>\n<p>Immerhin stellt Access-VBA einige Methoden zur Verf&uuml;gung, um nicht nur Formulare, sondern auch die enthaltenen Steuerelemente anzulegen und mit den gew&uuml;nschten Eigenschaften zu versehen.<\/p>\n<p>Bevor Sie beginnen, legen Sie ein Formular namens <b>frmDatumsauswahl <\/b>an und stellen seine Eigenschaften <b>Navigationsschaltfl&auml;chen<\/b>, <b>Bildlaufleiste<\/b>, <b>Datensatzmarkierer <\/b>und <b>Trennlinie <\/b>auf <b>Nein <\/b>und <b>Automatisch zentrieren <\/b>auf <b>Ja <\/b>ein.<\/p>\n<p>Anschlie&szlig;end rufen Sie einfach die Prozedur <b>SteuerelementeErstellen<\/b> auf. Das Ergebnis sieht wie in Bild 4 aus, die &uuml;brigen dort sichtbaren Steuerelemente legen wir sp&auml;ter an.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic004.png\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Das Formular zur Datumsauswahl mit allen Steuerelementen in der Entwurfsansicht<\/span><\/b><\/p>\n<p>Listing 2 zeigt den Code, der f&uuml;r das Anlegen der Bezeichnungsfelder n&ouml;tig ist. Zu Beginn schlie&szlig;t die Prozedur das Formular, falls dieses noch ge&ouml;ffnet ist. Dann &ouml;ffnet sie das Formular in der Entwurfsansicht und f&uuml;llt die Objektvariable <b>frm<\/b> mit einem Verweis auf das Formular, um sp&auml;ter einfacher darauf verweisen zu k&ouml;nnen.<\/p>\n<p class=\"listingueberschrift\">Listing 2: F&uuml;llen des Formulars mit den n&ouml;tigen Bezeichnungsfeldern<\/p>\n<p class=\"qf\">Public Sub SteuerelementeErstellen()<\/p>\n<p class=\"qf\">  Dim frm As Form<\/p>\n<p class=\"qf\">  Dim ctl As Control<\/p>\n<p class=\"qf\">  Dim strForm As String<\/p>\n<p class=\"qf\">  Dim i As Integer<\/p>\n<p class=\"qf\">  DoCmd.Close acForm, &quot;frmDatumsauswahl&quot;<\/p>\n<p class=\"qf\">  DoCmd.OpenForm &quot;frmDatumsauswahl&quot;, acDesign<\/p>\n<p class=\"qf\">  Set frm = Forms!frmDatumsauswahl<\/p>\n<p class=\"qf\">  For i = frm.Controls.Count To 1 Step -1<\/p>\n<p class=\"qf\">     Application.DeleteControl &quot;frmDatumsauswahl&quot;, frm.Controls(i &#8211; 1).Name<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">  Set ctl = Application.CreateControl(strForm, acLabel, acDetail, , , cBorder, cBorder, 6 * cMass, cMass)<\/p>\n<p class=\"qf\">  ctl.Name = &quot;lblTopLabel&quot;<\/p>\n<p class=\"qf\">  ctl.Caption = &quot;Monat\/Tag&quot;<\/p>\n<p class=\"qf\">  ctl.FontWeight = 700<\/p>\n<p class=\"qf\">  For i = 1 To 12<\/p>\n<p class=\"qf\">     Set ctl = Application.CreateControl(strForm, acLabel, acDetail, , , cBorder, _<\/p>\n<p class=\"qf\">      i * cMass + cBorder, 6 * cMass, cMass)<\/p>\n<p class=\"qf\">    ctl.Name = &quot;lblLabel&quot; &amp; Format(i, &quot;000&quot;)<\/p>\n<p class=\"qf\">    ctl.FontWeight = 700<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">  For i = 0 To 36<\/p>\n<p class=\"qf\">     Set ctl = Application.CreateControl(strForm, acLabel, acDetail, , , _<\/p>\n<p class=\"qf\">      cBorder + (i + 6) * cMass, cBorder, cMass, cMass)<\/p>\n<p class=\"qf\">    ctl.Name = &quot;lblTop&quot; &amp; Format(i, &quot;000&quot;)<\/p>\n<p class=\"qf\">    ctl.Caption = Choose(i Mod 7 + 1, &quot;M&quot;, &quot;D&quot;, &quot;M&quot;, &quot;D&quot;, &quot;F&quot;, &quot;S&quot;, &quot;S&quot;)<\/p>\n<p class=\"qf\">    ctl.FontWeight = CBool(i Mod 7 &gt; 4) * -700<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">  For i = 1 To 366<\/p>\n<p class=\"qf\">     Set ctl = Application.CreateControl(strForm, acLabel, acDetail, , , 0, 0, cMass, cMass)<\/p>\n<p class=\"qf\">    ctl.Name = Format(i, &quot;000&quot;)<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">  DoCmd.Close acForm, strForm, acSaveYes<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p>Da wir diese Prozedur wie oben angek&uuml;ndigt wohl &ouml;fter durchlaufen m&uuml;ssen, l&ouml;schen wir zu Beginn jeweils die bereits vorhandenen Bezeichnungsfelder, deren Name entweder mit <b>lbl <\/b>beginnt oder nur aus Zahlen besteht (<b>IsNumeric<\/b>).<\/p>\n<p>Auf diese Weise verhindern wir, dass bereits bestehende Steuerelemente, wie die in Bild 4 bereits sichtbaren Schaltfl&auml;chen, jedesmal neu anlegen m&uuml;ssen.<\/p>\n<p>Die <b>For&#8230;Next<\/b>-Schleife zum L&ouml;schen der Bezeichnungsfelder ermittelt zun&auml;chst die Anzahl der Bezeichnungsfelder und l&ouml;scht diese dann, wobei sie beim letzten Bezeichnungsfeld beginnt (anderenfalls w&uuml;rde die <b>For&#8230;Next<\/b>-Schleife durch das L&ouml;schen von Elementen mit dem Index durcheinanderkommen).<\/p>\n<p>Beim L&ouml;schen kommt die Methode <b>DeleteControl <\/b>zum Einsatz, die schlicht den Formular- und den Steuerelementnamen als Parameter erwartet.<\/p>\n<p>Die folgenden vier Anweisungen erstellen das Bezeichnungsfeld mit der Beschriftung <b>Monat\/Tag<\/b>, das ganz links oben positioniert wird. Das Erstellen &uuml;bernimmt die Methode <b>CreateControl<\/b>, der wir den Namen des Zielformulars, die Steuerelementart (<b>acLabel<\/b>), den Detailbereich als Zielbereich (<b>acDetail<\/b>) sowie die linke und obere Position und die H&ouml;he und Breite mitgeben.<\/p>\n<p>Die hier verwendeten Konstanten werden im Modul <b>mdlDatumsauswahl<\/b> deklariert:<\/p>\n<p class=\"qf\">Public Const cMass As Integer = 300<\/p>\n<p class=\"qf\">Public Const cBorder As Integer = 80<\/p>\n<p><b>cBorder <\/b>gibt dabei den Standardabstand zum Formularrahmen an und <b>cMass <\/b>liefert die Standardbreite und -h&ouml;he eines der 366 Tag-Bezeichnungsfelder.<\/p>\n<p>Die Breite der Zeilen&uuml;berschriften muss bei der Schriftart und -gr&ouml;&szlig;e aus Bild 2 sechs Mal so breit sein wie die der Tag-Bezeichnungsfelder, deshalb taucht in der Anweisung der Ausdruck <b>6 x cMass <\/b>auf. Die folgenden drei Anweisungen legen Name, Beschriftung und Schriftbreite des frisch angelegten Steuerelements fest.<\/p>\n<p>Nachdem wir nun vier Zeilen zum Anlegen eines einzigen Steuerelements ben&ouml;tigt haben, geht es ab jetzt etwas effizienter zu: Die Anweisungen der folgenden <b>For&#8230;Next<\/b>-Schleife zeichnen immerhin f&uuml;r das Anlegen von zw&ouml;lf Steuerelementen verantwortlich, n&auml;mlich der Zeilen&uuml;berschriften mit den Monatsnamen.<\/p>\n<p>Auch hier erstellt die <b>CreateControl<\/b>-Methode die Bezeichnungsfelder, wobei hier bei der Angabe des Abstands vom oberen Rand eine Variable ins Spiel kommt: <b>i * cMass + cBorder<\/b>. Dadurch werden die Steuerelemente jeweils um <b>cMass <\/b>nach unten versetzt.<\/p>\n<p>Auch der Name des Steuerelements wird in Abh&auml;ngigkeit von der Laufvariablen <b>i <\/b>vergeben (<b>lblLabel001<\/b>, <b>lblLabel002<\/b>&#8230;).<\/p>\n<p>F&uuml;r die Zeilen&uuml;berschriften ben&ouml;tigen wir genau 37 Steuerelemente. Warum gerade 37 Ein Monat kann an jedem Tag von Montag bis Sonntag beginnen und hat maximal 31 Tage. Der erste Tag liegt also im Extremfall auf der siebten Position von links, plus die fehlenden maximal 30 Tage ergibt 37 Tage. Die <b>For&#8230;Next<\/b>-Schleife mit den Anweisungen zum Anlegen der Spalten&uuml;berschriften l&auml;uft von <b>0 <\/b>bis <b>36<\/b>. Die Steuerelemente werden mit dem Abstand <b>cBorder + (i + 6) * cMass <\/b>vom linken Rand angelegt.<\/p>\n<p>Beim ersten Element ist <b>i = 0<\/b>, es beginnt also genau am rechten Rand des ganz links oben positionierten Bezeichnungsfeldes <b>Monat\/Tag<\/b>. Die &uuml;brigen Elemente werden dann jeweils um die Breite eines Elements nach rechts verschoben, damit alle genau nebeneinanderliegen. Der Name wird auf <b>lblTop001<\/b>, <b>lblTop002<\/b>&#8230; festgelegt. Der Ausdruck f&uuml;r die Bezeichnung ist erkl&auml;rungsbed&uuml;rftig:<\/p>\n<p class=\"qf\">Choose(i Mod 7 + 1, &quot;M&quot;, &quot;D&quot;, &quot;M&quot;, &quot;D&quot;, &quot;F&quot;, &quot;S&quot;, &quot;S&quot;)<\/p>\n<p>Die <b>Choose<\/b>-Methode erwartet im ersten Parameter einen Index f&uuml;r die Auswahl der in der folgenden Parameterliste enthaltenen Elemente. Ist der erste Wert <b>1<\/b>, dann liefert sie <b>&quot;M&quot; <\/b>zur&uuml;ck, ist der Wert <b>7<\/b>, hei&szlig;t der R&uuml;ckgabewert <b>&quot;S&quot;<\/b>.<\/p>\n<p>Interessant ist die Ermittlung des Indexes: Dieser basiert wiederum auf der Laufvariablen <b>i <\/b>der <b>For&#8230;Next<\/b>-Schleife. <b>i <\/b>wird durch <b>7 <\/b>geteilt und mit <b>Mod <\/b>der Rest ermittelt, zu dem noch der Wert <b>1 <\/b>hinzuaddiert wird. Ist <b>i <\/b>also beispielsweise <b>0<\/b>, lautet der Index <b>1<\/b>. Die ganz linke Spalten&uuml;berschrift soll also die Beschriftung <b>&quot;M&quot; <\/b>f&uuml;r Montag erhalten. <\/p>\n<p>F&uuml;r die elfte Spalte hat <b>i <\/b>den Wert <b>10<\/b>. <b>10 Mod 7 <\/b>liefert den Rest <b>3<\/b>, plus <b>1 <\/b>ergibt <b>4<\/b>. Die zehnte Spalten&uuml;berschrift lautet <b>&quot;D&quot; <\/b>f&uuml;r Donnerstag. Sie sehen: Man kann in einer Zeile Funktionalit&auml;t unterbringen, die zwar auch ohne Verwendung spezieller VBA-Funktionen m&ouml;glich ist, aber wesentlich mehr Zeilen ben&ouml;tigen w&uuml;rde.<\/p>\n<p>Fehlen noch die 366 Bezeichnungsfelder f&uuml;r die eigentlichen Tage. Die <b>For&#8230;Next<\/b>-Schleife durchl&auml;uft folgerichtig 366 Elemente, wobei einfach nur Bezeichnungsfelder mit dem Namen <b>001<\/b>, <b>002<\/b>&#8230; und der H&ouml;he und Breite <b>cMass <\/b>angelegt werden.<\/p>\n<p>Den Rest erledigen wir zur Laufzeit, denn die Position und Beschriftung der Steueuerelemente ist ohnehin von den jeweils anzuzeigenden Monaten abh&auml;ngig. Sie k&ouml;nnten maximal die ersten 28 Elemente mit den Zahlen 1 bis 28 beschriften, aber bereits die Position dieser Elemente kann erst festgelegt werden, wenn der Monat bekannt ist, der in der ersten Zeile angezeigt werden soll: Sie wissen einfach vorher nicht, auf welchen Wochentag der erste Tag des jeweiligen Monats f&auml;llt.<\/p>\n<p><!--30percent--><\/p>\n<p><b>Formatierung der Bezeichnungsfelder<\/b><\/p>\n<p>Eigentlich m&uuml;ssten wir beim Erstellen der Steuerelemente noch weitere Eigenschaften einstellen wie beispielsweise die Schriftart, die Schriftgr&ouml;&szlig;e, die Rahmenfarbe, die Ausrichtung des Inhalts, die Hintergrundart et cetera.<\/p>\n<p>Wenn Sie allerdings einige Male die Prozedur aus Listing 2 durchlaufen, werden Sie feststellen, dass das Anlegen von &uuml;ber 400 Steuerelementen einige Zeit in Anspruch nimmt. Um hier Zeit zu sparen, legen wir einfach Standardwerte f&uuml;r das Anlegen von Bezeichnungsfeldern fest. Dazu gehen Sie folgenderma&szlig;en vor:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Markieren Sie die Schaltfl&auml;che zum Hinzuf&uuml;gen eines Bezeichnungsfeldes, entweder in der Toolbox (Access 2003 und &auml;lter) oder im Ribbon (Access 2007 und j&uuml;nger). F&uuml;gen Sie dieses aber nicht zum Formular hinzu!<\/li>\n<li class=\"aufz-hlung\">Zeigen Sie mit <b>F4<\/b> das Eigenschaftsfenster an und stellen Sie die Eigenschaften ein. <\/li>\n<li class=\"aufz-hlung\">Speichern Sie die aktuellen Einstellungen mit <b>Strg + S<\/b>.<\/li>\n<\/ul>\n<p>Fertig! Wenn Sie nun ein Bezeichnungsfeld zum Formular hinzuf&uuml;gen, werden die neuen Eigenschaften gleich ber&uuml;cksichtigt. Dies gilt allerdings nur f&uuml;r das aktuelle Formular.<\/p>\n<p><b>Kalender zur Laufzeit aufbauen<\/b><\/p>\n<p>Nicht ganz ohne ist die Aufgabe, die 366 Bezeichnungsfelder zur Anzeige der einzelnen Tage zu arrangieren und zu beschriften &#8211; ganz zu schweigen von der Funktion, die sie sp&auml;ter ausf&uuml;hren sollen (mehr dazu im Anschluss).<\/p>\n<p>Der Aufbau des Formulars geschieht in der Ereignisprozedur <b>Beim Laden <\/b>des Formulars (s. Listing 3). Diese Prozedur enth&auml;lt einige Zeilen, die sich mit Objekten wie <b>colLabels <\/b>und <b>objLabel <\/b>besch&auml;ftigen &#8211; auf diese Objekte kommen wir sp&auml;ter zur&uuml;ck, sie haben eine besondere Aufgabe.<\/p>\n<p class=\"listingueberschrift\">Listing 3: Einstellen der Tages-Bezeichnungsfelder zur Laufzeit<\/p>\n<p class=\"qf\">Private Sub Form_Open(Cancel As Integer)<\/p>\n<p class=\"qf\">  Dim intMonthStart As Integer, intYearStart As Integer<\/p>\n<p class=\"qf\">  Dim datAktuell As Date, datEnd As Date, datStart As Date, datCenter As Date<\/p>\n<p class=\"qf\">  Dim x As Integer, y As Integer, i As Integer<\/p>\n<p class=\"qf\">  Dim intDaycount As Integer<\/p>\n<p class=\"qf\">  Dim objLabel As clsLabel<\/p>\n<p class=\"qf\">  Set colLabels = New Collection<\/p>\n<p class=\"qf\">  datStart = Split(Me.OpenArgs, &quot;|&quot;)(0)<\/p>\n<p class=\"qf\">  datEnd = Split(Me.OpenArgs, &quot;|&quot;)(1)<\/p>\n<p class=\"qf\">  Me!txtStartdatum = datStart<\/p>\n<p class=\"qf\">  Me!txtEnddatum = datEnd<\/p>\n<p class=\"qf\">  intDaycount = DateDiff(&quot;d&quot;, datStart, datEnd)<\/p>\n<p class=\"qf\">  datCenter = DateDiff(&quot;d&quot;, intDaycount \/ 2, datEnd)<\/p>\n<p class=\"qf\">  intMonthStart = Month(datCenter &#8211; 180)<\/p>\n<p class=\"qf\">  intYearStart = Year(datCenter &#8211; 180)<\/p>\n<p class=\"qf\">  datAktuell = DateSerial(intYearStart, intMonthStart, 1)<\/p>\n<p class=\"qf\">  For i = 1 To 366<\/p>\n<p class=\"qf\">    With Me.Controls(Format(i, &quot;000&quot;))<\/p>\n<p class=\"qf\">    Set objLabel = New clsLabel<\/p>\n<p class=\"qf\">    Set objLabel.Label = Me.Controls(Format(i, &quot;000&quot;))<\/p>\n<p class=\"qf\">    colLabels.Add objLabel<\/p>\n<p class=\"qf\">    .Caption = Day(datAktuell)<\/p>\n<p class=\"qf\">    If datAktuell &gt;= datStart And datAktuell &lt;= datEnd Then<\/p>\n<p class=\"qf\">      .BackColor = &amp;HCCCCCC<\/p>\n<p class=\"qf\">    End If<\/p>\n<p class=\"qf\">    If Day(datAktuell) = 1 Then<\/p>\n<p class=\"qf\">      x = Weekday(datAktuell, vbMonday) &#8211; 1<\/p>\n<p class=\"qf\">      y = y + 1<\/p>\n<p class=\"qf\">    Else<\/p>\n<p class=\"qf\">      x = x + 1<\/p>\n<p class=\"qf\">    End If<\/p>\n<p class=\"qf\">    .FontWeight = CBool(x Mod 7 &gt; 4) * -700<\/p>\n<p class=\"qf\">    .Left = cMass * (x + 6) + cBorder<\/p>\n<p class=\"qf\">    .Top = cMass * y + cBorder<\/p>\n<p class=\"qf\">    .Tag = datAktuell<\/p>\n<p class=\"qf\">    .Visible = y &lt;= 12<\/p>\n<p class=\"qf\">    If y &lt; 13 Then<\/p>\n<p class=\"qf\">      Me.Controls(&quot;lbllabel&quot; &amp; Format(y, &quot;000&quot;)).Caption = Format(datAktuell, _<\/p>\n<p class=\"qf\">      &quot;mmmm yyyy&quot;)<\/p>\n<p class=\"qf\">    End If<\/p>\n<p class=\"qf\">    datAktuell = DateAdd(&quot;d&quot;, 1, datAktuell)<\/p>\n<p class=\"qf\">    End With<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p class=\"listingueberschrift\">F&uuml;r die ersten Zeilen m&uuml;ssen Sie wissen, dass das Formular einen Wert f&uuml;r seinen &Ouml;ffnungsparameter, also die Eigenschaft <b>OpenArgs<\/b>, erwartet, den die aufrufende Funktion entsprechend zusammenstellen muss &#8211; auch hierzu sp&auml;ter mehr.<\/p>\n<p>Dieser &Ouml;ffnungsparameter enth&auml;lt die beiden Datumsangaben der Textfelder wie in Bild 1 zu sehen. Der enthaltene Ausdruck k&ouml;nnte etwa so aussehen:<\/p>\n<p class=\"qf\">1.1.2010|31.4.2010<\/p>\n<p>Die Prozedur <b>Form_Load <\/b>ermittelt aus diesem mit dem Pipe-Zeichen getrennten Ausdruck die Werte f&uuml;r seine Variablen <b>datStart <\/b>und <b>datEnd<\/b>, die fortan unseren Datumsbereich enthalten.<\/p>\n<p>Mit diesen Werten werden auch gleich die beiden Textfelder <b>txtStartdatum <\/b>und <b>txtEnddatum <\/b>des Formulars gef&uuml;llt, damit der Datumsbereich nicht nur visuell, sondern auch schriftlich vorliegt.<\/p>\n<p>Der &uuml;bergebene Bereich soll m&ouml;glichst in der Mitte des Kalenders zur Datumsauswahl angezeigt werden. Dazu ermitteln wir zun&auml;chst den Tag, der in der Mitte des Bereichs liegt:<\/p>\n<p class=\"qf\">intDaycount = DateDiff(&quot;d&quot;, datStart, datEnd)<\/p>\n<p class=\"qf\">datCenter = DateDiff(&quot;d&quot;, intDaycount \/ 2, datEnd)<\/p>\n<p>Von diesem Tag aus bewegen wir uns circa ein halbes Jahr in die Vergangenheit und bestimmen den Monat und das Jahr f&uuml;r die erste Zeile des Kalenders:<\/p>\n<p class=\"qf\">intMonthStart = Month(datCenter &#8211; 180)<\/p>\n<p class=\"qf\">intYearStart = Year(datCenter &#8211; 180)<\/p>\n<p>Die maximal 366 anzuzeigenden Tage durchlaufen wir mit einer Schleife. Innerhalb dieser Schleife z&auml;hlen wir die Tage hoch, wobei wir mit dem ersten Tag des ersten Monats der Kalenderanzeige beginnen und den wir wie folgt bestimmen:<\/p>\n<p class=\"qf\">datAktuell = DateSerial(intYearStart, intMonthStart, 1)<\/p>\n<p>Danach beginnt der Hauptteil der Arbeit, n&auml;mlich eine <b>For&#8230;Next<\/b>-Schleife mit 366 Durchl&auml;ufen. Innerhalb der Schleife werden haupts&auml;chlich die Bezeichnungsfelder <b>001 <\/b>bis <b>366 <\/b>bearbeitet. Diese werden in Abh&auml;ngigkeit vom Wert des Schleifenz&auml;hlers referenziert:<\/p>\n<p class=\"qf\">With Me.Controls(Format(i, &quot;000&quot;))<\/p>\n<p>Zun&auml;chst wird die Beschriftung auf den Tag des aktuellen Datums eingestellt:<\/p>\n<p class=\"qf\">.Caption = Day(datAktuell)<\/p>\n<p>Danach pr&uuml;ft die Prozedur, ob sich der Tag innerhalb des beim Start des Formulars &uuml;bergebenen Datumsbereichs befindet, und, falls ja, wird der Hintergrund der betroffenen Bezeichnungsfelder entsprechend eingestellt:<\/p>\n<p class=\"qf\">If datAktuell &gt;= datStart And datAktuell &lt;= datEnd Then<\/p>\n<p class=\"qf\">  .BackColor = &amp;HCCCCCC<\/p>\n<p class=\"qf\">End If<\/p>\n<p>Danach k&uuml;mmern wir uns um die Position des jeweiligen Bezeichnungsfeldes. Dieses muss ja unterhalb der entsprechenden Spalten&uuml;berschrift (Wochentag) und auf H&ouml;he der richtigen Zeilen&uuml;berschrift (Monat) positioniert werden. Dazu ermittelt die folgende <b>If&#8230;Then<\/b>-Bedingung zun&auml;chst die notwendigen Koordinaten in Form von <b>x <\/b>und <b>y<\/b>. Die erste Bedingung ist erf&uuml;llt, wenn der Tag-Teil des aktuellen Datums <b>1 <\/b>ist, also wenn ein neuer Monat beginnt. Dann wird die Koordinate <b>x<\/b> auf die Position eingestellt, die dem Wochentag des aktuellen Datums, also des ersten Tags des Monats entspricht, und die <b>y<\/b>-Koordinate um <b>1 <\/b>erh&ouml;ht.<\/p>\n<p>Ist der aktuelle Tag nicht der erste Tag des Monats, wird die <b>x<\/b>-Position einfach um <b>1 <\/b>erh&ouml;ht:<\/p>\n<p class=\"qf\">If Day(datAktuell) = 1 Then<\/p>\n<p class=\"qf\">  x = Weekday(datAktuell, vbMonday) &#8211; 1<\/p>\n<p class=\"qf\">  y = y + 1<\/p>\n<p class=\"qf\">Else<\/p>\n<p class=\"qf\">  x = x + 1<\/p>\n<p class=\"qf\">End If<\/p>\n<p>Mit diesen Koordinaten erledigen wir den Rest. F&uuml;r Samstage und Sonntage soll der Tag jeweils fett gedruckt werden:<\/p>\n<p class=\"qf\">.FontWeight = CBool(x Mod 7 &gt; 4) * -700<\/p>\n<p>Die Position kann nach Ermittlung der x- und y-Koordinaten leicht berechnet werden:<\/p>\n<p class=\"qf\">.Left = cMass * (x + 6) + cBorder<\/p>\n<p class=\"qf\">.Top = cMass * y + cBorder<\/p>\n<p>Damit wir sp&auml;ter leicht auslesen k&ouml;nnen, welche Daten der Benutzer eingestellt hat, schreiben wir in die Eigenschaft <b>Tag <\/b>der Beschriftungsfelder jeweils das komplette Datum:<\/p>\n<p class=\"qf\">.Tag = datAktuell<\/p>\n<p>Schlie&szlig;lich sollen nur Tage sichtbar sein, die innerhalb der ersten zw&ouml;lf Reihen beziehungsweise Monate liegen &#8211; in Nicht-Schaltjahren landet der 366. Tag n&auml;mlich in der 13. Reihe:<\/p>\n<p class=\"qf\">.Visible = y &lt;= 12<\/p>\n<p>Und schlie&szlig;lich m&uuml;ssen wir noch die Zeilen&uuml;berschriften mit den entsprechenden Monats-\/Jahresbezeichnungen im Format <b>&lt;Monat&gt; &lt;Jahr&gt; <\/b>ausstatten:<\/p>\n<p class=\"qf\">If y &lt; 13 Then<\/p>\n<p class=\"qf\">  Me.Controls(&quot;lbllabel&quot; &amp; Format(y, &quot;000&quot;)).Caption = Format(datAktuell, &quot;mmmm yyyy&quot;)<\/p>\n<p class=\"qf\">End If<\/p>\n<p>Im letzten Schritt wird das aktuelle Datum um einen Tag weiter in Richtung Zukunft geschoben, damit innerhalb der Schleife auch alle Tage richtig gef&uuml;llt und positioniert werden:<\/p>\n<p class=\"qf\">datAktuell = DateAdd(&quot;d&quot;, 1, datAktuell)<\/p>\n<p>Damit sind wir mit der Gestaltung des Jahreskalenders rund um den gew&auml;hlten Bereich fertig. Alle Tage befinden sich an Ort und Stelle, die Wochenenden sind fett markiert und die Tage, die sich innerhalb des beim Aufruf &uuml;bergebenen Datumsbereichs befinden, sind mit einem grauen Hintergrund versehen.<\/p>\n<p><b>Datumsbereiche markieren<\/b><\/p>\n<p>Damit kommen wir zum eigentlichen Markieren des Datumsbereichs. Dies soll so aussehen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Der Benutzer klickt auf das erste Datum des gew&uuml;nschten Bereichs. Eventuell bereits vorhandene Markierungen werden gel&ouml;scht und der ausgew&auml;hlte Tag wird grau hinterlegt.<\/li>\n<li class=\"aufz-hlung\">Bei gedr&uuml;ckter Maustaste bewegt der Benutzer den Mauszeiger zum letzten Tag des Datumsbereichs. Dabei wird der jeweils &uuml;berfahrene Tag rot hinterlegt, damit der Benutzer immer erkennen kann, welcher Tag als letzter Tag markiert ist.<\/li>\n<li class=\"aufz-hlung\">Wenn der Benutzer die linke Maustaste losl&auml;sst, wird der gesamte Bereich vom ersten bis zum letzten Datum grau hinterlegt und die beiden Textfelder werden mit den ausgew&auml;hlten Daten gef&uuml;llt.<\/li>\n<\/ul>\n<p>Dazu sind nat&uuml;rlich einige Ereignisse notwendig, die durch das Herunterdr&uuml;cken der linken Maustaste, dem Bewegen des Mauszeigers &uuml;ber verschiedene Tage bis zum gew&uuml;nschten Tag bis zum Loslassen der linken Maustaste reichen. Wenn wir in die Entwurfsansicht des Formulars wechseln, ein Bezeichnungsfeld markieren und die Ereignisse im Eigenschaftsfenster betrachten, entdecken wir, dass es die notwendigen Ereigniseigenschaften anbietet: <b>Bei Maustaste ab<\/b>, <b>Bei Maustaste auf <\/b>und <b>Bei Mausbewegung<\/b> (siehe Bild 5).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic005.png\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Bezeichnungsfelder liefern alle notwendigen Ereigniseigenschaften.<\/span><\/b><\/p>\n<p>Beim Dr&uuml;cken der Maustaste &uuml;ber einem der Datumsbezeichnungsfelder soll durch die Ereignisprozedur <b>Bei Maustaste ab <\/b>Folgendes geschehen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Alle vorhandenen Markierungen sollen gel&ouml;scht werden.<\/li>\n<li class=\"aufz-hlung\">Das Bezeichnungsfeld des angeklickten Tages soll markiert werden.<\/li>\n<li class=\"aufz-hlung\">Die Nummer dieses Feldes soll in einer Variablen gespeichert werden.<\/li>\n<\/ul>\n<p>Dann f&auml;hrt der Benutzer bei gedr&uuml;ckter Maustaste zum Zieldatum. Dabei wird st&auml;ndig das Ereignis <b>Bei Mausbewegung <\/b>ausgel&ouml;st, was hierzu f&uuml;hrt:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Es soll gepr&uuml;ft werden, ob die linke Maustaste gedr&uuml;ckt ist, die folgenden Schritte werden nur dann ausgef&uuml;hrt.<\/li>\n<li class=\"aufz-hlung\">Dann wird gepr&uuml;ft, ob sich der Mauszeiger noch &uuml;ber dem Datum befindet, auf dem die Taste gedr&uuml;ckt wurde. Ist dies der Fall, wird ebenfalls abgebrochen.<\/li>\n<li class=\"aufz-hlung\">Die letzte Pr&uuml;fung stellt sicher, dass der Mauszeiger nicht mehr &uuml;ber dem gleichen Datum steht, f&uuml;r welches das Ereignis zuletzt ausgel&ouml;st wurde (beim &Uuml;berfahren nur eines Steuerelements wird <b>Bei Mausbewegung <\/b>bereits einige Male aufgerufen). Stehen wir auf dem gleichen Bezeichnungsfeld wie zuvor, bricht die Prozedur ebenfalls ab.<\/li>\n<li class=\"aufz-hlung\">Erst wenn die vorherigen Pr&uuml;fungen positive Ergebnisse lieferten, geschehen die letzten Schritte: Die Markierung des zuvor &uuml;berfahrenen Tages wird aufgehoben, die Markierung des aktuell &uuml;berfahrenen Tages wird gesetzt und die Nummer des Steuerelements in einer Variablen gespeichert.<\/li>\n<\/ul>\n<p>Schlie&szlig;lich fehlt noch das Loslassen der linken Maustaste &uuml;ber dem gew&uuml;nschten Enddatum. Im dadurch ausgel&ouml;sten Ereignis <b>Bei Maustaste auf <\/b>soll Folgendes geschehen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Die Nummer des aktuellen Bezeichnungsfeldes wird in einer Variablen gespeichert.<\/li>\n<li class=\"aufz-hlung\">Wenn die Nummer kleiner als die Nummer des Bezeichnungsfeldes des ausgew&auml;hlten Startdatums ist, werden diese beiden Werte vertauscht.<\/li>\n<li class=\"aufz-hlung\">Die Textfelder zur Anzeige von Start- und Enddatum werden gef&uuml;llt.<\/li>\n<li class=\"aufz-hlung\">Alle Bezeichungsfelder zwischen dem ausgew&auml;hlten Start- und Enddatum werden markiert.<\/li>\n<\/ul>\n<p>Das ist schon alles &#8211; aber nur fast: Denn wir m&uuml;ssen die drei Ereignisse nicht nur programmieren, sondern dies auch noch f&uuml;r gleich 366 Steuerelemente erledigen. Immerhin soll ja jedes der Steuerelemente auf das Anklicken, &Uuml;berfahren und Loslassen der Maus reagieren!<\/p>\n<p>Sie ahnen es bereits: Wir werden nun nicht insgesamt &uuml;ber 1.000 Ereignisprozeduren anlegen. Stattdessen erzeugen wir ein Klassenmodul, das wir f&uuml;r jedes Bezeichnungsfeld einmal instanzieren und das dann die Ausf&uuml;hrung der Ereignisprozeduren f&uuml;r das jeweilige Steuerelement &uuml;bernimmt. Den Code dieser Klasse, die Sie unter dem Namen <b>clsLabel <\/b>speichern, finden Sie in Listing 4. Erst einmal schauen wir uns jedoch an, wie diese Klasse verwendet wird.<\/p>\n<p class=\"listingueberschrift\">Listing 4: Einstellen der Tages-Bezeichnungsfelder zur Laufzeit<\/p>\n<p class=\"qf\">Private WithEvents m_lbl As Label<\/p>\n<p class=\"qf\">Public Property Set Label(lbl As Label)<\/p>\n<p class=\"qf\">  Set m_lbl = lbl<\/p>\n<p class=\"qf\">  With m_lbl<\/p>\n<p class=\"qf\">    .OnMouseDown = &quot;[Event Procedure]&quot;<\/p>\n<p class=\"qf\">    .OnMouseUp = &quot;[Event Procedure]&quot;<\/p>\n<p class=\"qf\">    .OnMouseMove = &quot;[Event Procedure]&quot;<\/p>\n<p class=\"qf\">  End With<\/p>\n<p class=\"qf\">End Property<\/p>\n<p class=\"qf\">Private Sub m_lbl_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)<\/p>\n<p class=\"qf\">  Dim i As Integer<\/p>\n<p class=\"qf\">  For i = 1 To 366<\/p>\n<p class=\"qf\">    m_lbl.Parent.Controls(Format(i, &quot;000&quot;)).BackColor = &amp;HFFFFFF<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">  m_lbl.BackColor = &amp;HCCCCCC<\/p>\n<p class=\"qf\">  intDown = m_lbl.Name<\/p>\n<p class=\"qf\">  DoCmd.CancelEvent<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p class=\"qf\">Private Sub m_lbl_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)<\/p>\n<p class=\"qf\">  If Button = 1 Then<\/p>\n<p class=\"qf\">    If Not m_lbl.Name = CStr(Format(intDown, &quot;000&quot;)) Then<\/p>\n<p class=\"qf\">      If Not intUp = CInt(m_lbl.Name) Then<\/p>\n<p class=\"qf\">        If Not intUp = 0 Then<\/p>\n<p class=\"qf\">          m_lbl.Parent.Controls(CStr(Format(intUp, &quot;000&quot;))).BackColor = &amp;HFFFFFF<\/p>\n<p class=\"qf\">        End If<\/p>\n<p class=\"qf\">        intUp = m_lbl.Name<\/p>\n<p class=\"qf\">        m_lbl.BackColor = &amp;HFF<\/p>\n<p class=\"qf\">      End If<\/p>\n<p class=\"qf\">    End If<\/p>\n<p class=\"qf\">  End If<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p class=\"qf\">Private Sub m_lbl_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)<\/p>\n<p class=\"qf\">  Dim i As Integer<\/p>\n<p class=\"qf\">  Dim intHelp As Integer<\/p>\n<p class=\"qf\">  intUp = m_lbl.Name<\/p>\n<p class=\"qf\">  If intUp &lt; intDown Then<\/p>\n<p class=\"qf\">    intHelp = intUp<\/p>\n<p class=\"qf\">    intUp = intDown<\/p>\n<p class=\"qf\">    intDown = intHelp<\/p>\n<p class=\"qf\">  End If<\/p>\n<p class=\"qf\">  m_lbl.Parent.txtStartdatum = m_lbl.Parent.Controls(Format(intDown, &quot;000&quot;)).Tag<\/p>\n<p class=\"qf\">  m_lbl.Parent.txtEnddatum = m_lbl.Parent.Controls(Format(intUp, &quot;000&quot;)).Tag<\/p>\n<p class=\"qf\">  For i = intDown To intUp<\/p>\n<p class=\"qf\">    m_lbl.Parent.Controls(Format(i, &quot;000&quot;)).BackColor = &amp;HCCCCCC<\/p>\n<p class=\"qf\">  Next i<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p class=\"listingueberschrift\">F&uuml;r das Instanzieren dieser Klasse sind die Zeilen der Ereignisprozedur <b>Beim Laden <\/b>des Formulars <b>frmDatumsauswahl <\/b>zust&auml;ndig, die wir vorhin nicht ber&uuml;cksichtigt haben. Zun&auml;chst wird im Klassenmodul des Formulars <b>frmDatumsauswahl <\/b>ein <b>Collection<\/b>-Objekt namens <b>colLabels <\/b>deklariert:<\/p>\n<p class=\"qf\">Dim colLabels As Collection<\/p>\n<p>Dieses <b>Collection<\/b>-Objekt wird sp&auml;ter jeweils eine Instanz der Klasse <b>clsLabel <\/b>f&uuml;r jedes der 366 Tages-Bezeichnungsfelder aufnehmen. Warum deklarieren wir dieses im Modulkopf und nicht innerhalb des <b>Form_Load<\/b>-Ereignisses Weil die Variable und ihr Inhalt sonst gleich nach Beenden der <b>Form_Load<\/b>-Prozedur ung&uuml;ltig w&uuml;rde. <\/p>\n<p>Innerhalb dieser Prozedur deklarieren wir jedoch ein Objekt namens <b>objLabel<\/b>, das jeweils auf eine Instanz der Klasse <b>clsLabel <\/b>verweisen wird.<\/p>\n<p class=\"qf\">Dim objLabel As clsLabel<\/p>\n<p>Warum kann diese Variable innerhalb der Prozedur deklariert werden, obwohl sie doch nach deren Ablauf ebenfalls ihre G&uuml;ltigkeit verlieren d&uuml;rfte Weil wir einen Verweis auf diese Objektvariable zum <b>Collection<\/b>-Objekt <b>colLabels <\/b>hinzuf&uuml;gen, dessen Lebensdauer der Lebensdauer des Formulars <b>frmDatumsauswahl <\/b>entspricht.<\/p>\n<p>In <b>Form_Load <\/b>erzeugen wir die ben&ouml;tigte Instanz des <b>Collection<\/b>-Objekts:<\/p>\n<p class=\"qf\">Set colLabels = New Collection<\/p>\n<p>Danach geht es in der Schleife weiter, die alle 366 <b>Label<\/b>-Steuerelemente durchl&auml;uft und deren Position und Beschriftung einstellt. Dort erstellen wir zun&auml;chst eine neue Instanz der Klasse <b>clsLabel<\/b>:<\/p>\n<p class=\"qf\">Set objLabel = New clsLabel<\/p>\n<p>Damit wir wissen, auf welches <b>Label<\/b>-Steuerelement sich dieses Objekt bezieht, weisen wir seiner Eigenschaft <b>Label <\/b>einen Verweis auf das aktuell in der Schleife behandelte Steuerelement zu:<\/p>\n<p class=\"qf\">Set objLabel.Label = Me.Controls(Format(i, &quot;000&quot;))<\/p>\n<p>Und damit dieses nicht in den ewigen Jagdgr&uuml;nden verschwindet, wenn die Prozedur endet, f&uuml;gen wir die Objektvariable zum <b>Collection<\/b>-Objekt <b>colLabels <\/b>hinzu, dessen Lebensdauer deutlich l&auml;nger ist:<\/p>\n<p class=\"qf\">colLabels.Add objLabel<\/p>\n<p>Das war es: Die Prozedur <b>Form_Load<\/b> hat 366 Instanzen der Klasse <b>clsLabel <\/b>erstellt und diese in einer Collection konserviert. Was die auf dieser Klasse basierenden Objekte genau tun, schauen wir uns nun an.<\/p>\n<p><b>Die Klasse clsLabel<\/b><\/p>\n<p>Neben dem Instanzieren der Objekte auf Basis der Klasse <b>clsLabel <\/b>ist bislang nur wichtig, dass wir diesen einen Verweis auf jeweils ein <b>Label<\/b>-Steuerelement &uuml;bergeben k&ouml;nnen. Dieses wird in der Klasse <b>clsLabel <\/b>in der folgenden Variablen gespeichert:<\/p>\n<p class=\"qf\">Private WithEvents m_lbl As Label<\/p>\n<p>Die Variable ist mit dem Schl&uuml;sselwort <b>WithEvents <\/b>deklariert, was dazu f&uuml;hrt, dass Sie innerhalb der Klasse, in der es deklariert wurde, auf die durch das Steuerelement ausgel&ouml;sten Ereignisse reagieren k&ouml;nnen &#8211; Sie k&ouml;nnen also Ereignisprozeduren f&uuml;r die ben&ouml;tigten Ereignisse <b>OnMouseDown<\/b>, <b>OnMouseUp <\/b>und <b>OnMouseMove <\/b>f&uuml;r den Objektverweis auf das Steuerelement anlegen. <\/p>\n<p>Erst einmal m&uuml;ssen Sie der Klasse <b>clsLabel <\/b>jedoch den Verweis auf das jeweilige Label &uuml;bergeben. Dies geschieht &uuml;ber die <b>Property Set<\/b>-Methode, die als Parameter den Verweis auf das <b>Label<\/b>-Steuerelement erwartet.<\/p>\n<p>Diese Prozedur speichert jedoch nicht nur den Verweis in der Variablen <b>m_lbl<\/b>, sondern sie stellt gleich noch ein paar Eigenschaften dieses Objekts ein &#8211; dies ist problemlos m&ouml;glich, wenn ein Verweis darauf vorliegt.<\/p>\n<p>Bei diesen Eigenschaften handelt es sich um die drei Ereigniseigenschaften <b>OnMouseDown<\/b>, <b>OnMouseUp <\/b>und <b>OnMouseMove<\/b>. Sie werden jeweils auf den Wert <b>[Event Procedure]<\/b> eingestellt. Wenn Sie das Eigenschaftsfenster eines dieser Steuerelemente zu diesem Zeitpunkt anzeigen k&ouml;nnten, w&uuml;rde es wie in Bild 6 aussehen.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic006.png\" alt=\"pic006.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Eigenschaften eines der 366 Tages-Bezeichnungsfelder<\/span><\/b><\/p>\n<p>Das Eintragen dieser Werte f&uuml;hrt dazu, dass Access beim Ausl&ouml;sen eines dieser Ereignisse pr&uuml;ft, ob das Klassenmodul des Formulars selbst oder ein Klassenmodul, welches das betreffende Steuerelement referenziert, eine entsprechende Ereignisprozedur enth&auml;lt.<\/p>\n<p>In diesem Fall schreiben wir die Ereignisprozeduren gleich in das Klassenmodul <b>clsLabel<\/b>. Den Prozedurkopf legen Sie am schnellsten an, indem Sie im Codefenster erst im linken Kombinationsfeld den Eintrag <b>lbl <\/b>und dann im rechten Codefenster das gew&uuml;nschte Ereignis ausw&auml;hlen (siehe Bild 7).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2010_04\/DatumsbereicheAuswaehlen_5-web-images\/pic007.png\" alt=\"pic007.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Anlegen von Ereignisprozeduren f&uuml;r Objektvariablen<\/span><\/b><\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Wenig Code, viel Funktion<\/p>\n<p>Das Ergebnis nach dem Erzeugen aller Instanzen von <b>clsLabel <\/b>nach dem Durchlaufen der <b>Form_Load<\/b>-Prozedur ist, dass wir die in <a href=\"#anker-10-anchor\">Listing 4<\/a> dargestellten Prozeduren f&uuml;r jedes einzelne der 366 <b>Label<\/b>-Steuerelemente bereitstellen. Jedes einzelne Steuerelement wird also nun reagieren, wenn Sie die linke Maustaste dr&uuml;cken, bei gedr&uuml;ckter Maustaste dar&uuml;berfahren oder die Maustaste loslassen.<\/p>\n<p>Die Prozedur <b>m_lbl_MouseDown <\/b>wird gleich beim Dr&uuml;cken der linken Maustaste &uuml;ber einem der 366 Steuerelemente ausgel&ouml;st. Sie stellt die Hintergrundfarbe aller 366 Tage auf Wei&szlig; ein, f&auml;rbt das aktuelle Label grau und speichert den Namen in der Variablen <b>intDown<\/b>. Diese wird &uuml;brigens, genau wie die Variable <b>intUp<\/b>, im Standardmodul <b>mdlDatumsauswahl <\/b>deklariert:<\/p>\n<p class=\"qf\">Public intDown As Integer<\/p>\n<p class=\"qf\">Public intUp As Integer<\/p>\n<p>Die wichtigste Anweisung dieser Prozedur ist jedoch die letzte:<\/p>\n<p class=\"qf\">DoCmd.CancelEvent<\/p>\n<p>Wenn Sie die <b>MouseDown<\/b>-Prozedur nicht abbrechen, werden nachfolgend keine weiteren Maus-Ereignisse ausgel&ouml;st, bis der Benutzer die linke Maustaste wieder losl&auml;sst. Durch das Abbrechen aber wird nach dem Herunterdr&uuml;cken der Maus beispielsweise jede Bewegung &uuml;ber einem der 366 Tage registriert, und zwar durch die Prozedur <b>m_lbl_MouseMove <\/b>(siehe ebenfalls Listing 4). Diese Prozedur pr&uuml;ft anhand des Parameters <b>Button<\/b>, ob die linke Maustaste aktuell gedr&uuml;ckt ist, ob der Mauszeiger sich nicht gerade &uuml;ber dem Label befindet, auf dem die Maustaste heruntergedr&uuml;ckt wurde, und ob der Mauszeiger sich nicht &uuml;ber dem Label befindet, &uuml;ber dem diese Prozedur das letzte Mal ausgel&ouml;st wurde. Ist dies alles der Fall, wird die Nummer des aktuellen Labels in der Variablen <b>intUp <\/b>gespeichert, dieses als aktuelles Enddatum markiert und die Markierung eines eventuell bereits markierten Enddatums aufgehoben.<\/p>\n<p>Schlie&szlig;lich wird der Benutzer &uuml;ber irgendeinem Label die linke Maustaste loslassen. In diesem Fall wird die Ereignisprozedur <b>m_lbl_MouseUp <\/b>des jeweiligen Steuerelements ausgel&ouml;st. Diese Prozedur speichert die Nummer des Labels in <b>intUp<\/b> und pr&uuml;ft, ob <b>intUp <\/b>kleiner als <b>intDown <\/b>ist, und tauscht beide gegebenenfalls aus. Die in der <b>Tag<\/b>-Eigenschaft der als Start- und Enddatum markierten <b>Label<\/b>-Steuerelemente werden in die beiden Textfelder <b>txtStartdatum <\/b>und <b>txtEnddatum <\/b>geschrieben. In einer <b>For&#8230;Next<\/b>-Schleife werden schlie&szlig;lich alle <b>Label<\/b>-Steuerelemente vom Startdatum bis zum Enddatum grau hinterlegt.<\/p>\n<p><b>Kein Komfort ohne Vorarbeit<\/b><\/p>\n<p>Fehlt nur noch die Schnittstelle f&uuml;r den einfachen Aufruf dieses Formulars, den wir in Listing 1 vorgestellt haben: Dort waren immerhin nur rund eine Handvoll VBA-Anweisungen notwendig, um diese doch sehr praktische Erweiterung zu integrieren.<\/p>\n<p>Die hier verborgene Arbeit wird von der Klasse <b>clsDatumsauswahl <\/b>erledigt. Sie ben&ouml;tigt drei Objektvariablen, die Verweise auf das Formular und die beiden Textfelder aufnehmen, von denen das Formular zur Datumsauswahl aufgerufen werden soll:<\/p>\n<p class=\"qf\">Private WithEvents m_txtStartdate As TextBox<\/p>\n<p class=\"qf\">Private WithEvents m_txtEnddate As TextBox<\/p>\n<p class=\"qf\">Private m_Form As Form<\/p>\n<p>Zwei davon sind wiederum mit dem Schl&uuml;sselwort <b>WithEvents<\/b> deklariert, was darauf hindeutet, dass die Klasse diesen Steuerelementen wiederum zus&auml;tzliche Funktionalit&auml;t hinzuf&uuml;gt. Zun&auml;chst brauchen wir drei &ouml;ffentliche <b>Property Set<\/b>-Prozeduren, mit denen Verweise auf das Formular und die beiden Textfelder an die Klasse &uuml;bergeben werden k&ouml;nnen, nachdem diese instanziert wurde. Diese beiden Prozeduren sehen wie in Listing 5 aus.<\/p>\n<p class=\"listingueberschrift\">Listing 5: Property Set-Prozeduren zum &Uuml;bergeben des Formulars und der Datums-Steuerelemente<\/p>\n<p class=\"qf\">Public Property Set StartdateTextbox(txt As TextBox)<\/p>\n<p class=\"qf\">  Set m_txtStartdate = txt<\/p>\n<p class=\"qf\">  With m_txtStartdate<\/p>\n<p class=\"qf\">    .OnDblClick = &quot;[Event Procedure]&quot;<\/p>\n<p class=\"qf\">  End With<\/p>\n<p class=\"qf\">End Property<\/p>\n<p class=\"qf\">Public Property Set EnddateTextbox(txt As TextBox)<\/p>\n<p class=\"qf\">  Set m_txtEnddate = txt<\/p>\n<p class=\"qf\">  With m_txtEnddate<\/p>\n<p class=\"qf\">    .OnDblClick = &quot;[Event Procedure]&quot;<\/p>\n<p class=\"qf\">  End With<\/p>\n<p class=\"qf\">End Property<\/p>\n<p class=\"qf\">Public Property Set Form(frm As Form)<\/p>\n<p class=\"qf\">  Set m_Form = frm<\/p>\n<p class=\"qf\">End Property<\/p>\n<\/p>\n<p class=\"listingueberschrift\">Der Formular-Verweis wird einfach nur der Variablen <b>m_Form<\/b>, die Verweise auf die beiden Textfelder werden <b>m_txtStartdate <\/b>und <b>m_txtEnddate <\/b>zugewiesen. Die beiden Objektvariablen f&uuml;r die Textfelder erhalten zus&auml;tzlich den Wert <b>[Event Procedure] <\/b>f&uuml;r die Eigenschaft <b>OnDblClick<\/b>. Dadurch l&ouml;st ein Doppelklick auf die beiden Textfelder die beiden in Listing 6 enthaltenen Ereignisprozeduren aus, die beide nur zwei Anweisungen enthalten &#8211; und die speichern den aktuell im Steuerelement enthaltenen Text und rufen die Prozedur <b>DatumsauswahlStarten <\/b>auf.<\/p>\n<p class=\"listingueberschrift\">Listing 6: Diese Prozeduren werden beim Doppelklick auf die Datumstextfelder ausgel&ouml;st.<\/p>\n<p class=\"qf\">Private Sub m_txtEnddate_DblClick(Cancel As Integer)<\/p>\n<p class=\"qf\">  m_txtEnddate.Value = m_txtEnddate.Text<\/p>\n<p class=\"qf\">  DatumsauswahlStarten<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p class=\"qf\">Private Sub m_txtStartdate_DblClick(Cancel As Integer)<\/p>\n<p class=\"qf\">  m_txtStartdate.Value = m_txtStartdate.Text<\/p>\n<p class=\"qf\">  DatumsauswahlStarten<\/p>\n<p class=\"qf\">End Sub<\/p>\n<\/p>\n<p>Diese Prozedur finden Sie schlie&szlig;lich in Listing 7. Sie schlie&szlig;t das Formular <b>frmDatumsauswahl<\/b>, falls dieses ge&ouml;ffnet sein sollte, und &ouml;ffnet es wieder. So stellen Sie sicher, dass die &Ouml;ffnungsargumente ihren Dienst tun (beim Aufruf eines bereits ge&ouml;ffneten Formulars wirken diese nicht). <\/p>\n<p class=\"listingueberschrift\">Listing 7: Diese Prozeduren werden beim Doppelklick auf die Datumstextfelder ausgel&ouml;st.<\/p>\n<p class=\"qf\">Private Sub DatumsauswahlStarten()<\/p>\n<p class=\"qf\">  Dim strForm As String<\/p>\n<p class=\"qf\">  Dim datStart As Date, datEnd As Date, datHelp As Date<\/p>\n<p class=\"qf\">  Dim intDaycount As Integer<\/p>\n<p class=\"qf\">  strForm = &quot;frmDatumsauswahl&quot;<\/p>\n<p class=\"qf\">  DoCmd.Close acForm, strForm<\/p>\n<p class=\"qf\">  If IsDate(Nz(m_txtStartdate)) Then<\/p>\n<p class=\"qf\">    datStart = m_txtStartdate<\/p>\n<p class=\"qf\">    If IsDate(Nz(m_txtEnddate)) Then<\/p>\n<p class=\"qf\">      datEnd = Nz(m_txtEnddate)<\/p>\n<p class=\"qf\">    Else<\/p>\n<p class=\"qf\">      datEnd = datStart<\/p>\n<p class=\"qf\">    End If<\/p>\n<p class=\"qf\">  Else<\/p>\n<p class=\"qf\">    If IsDate(Nz(m_txtEnddate)) Then<\/p>\n<p class=\"qf\">      datEnd = Nz(m_txtEnddate)<\/p>\n<p class=\"qf\">      datStart = datEnd<\/p>\n<p class=\"qf\">    Else<\/p>\n<p class=\"qf\">      datStart = Date<\/p>\n<p class=\"qf\">      datEnd = Date<\/p>\n<p class=\"qf\">    End If<\/p>\n<p class=\"qf\">  End If<\/p>\n<p class=\"qf\">  If DateDiff(&quot;d&quot;, datEnd, datStart) &gt;= 0 Then<\/p>\n<p class=\"qf\">    datHelp = datEnd<\/p>\n<p class=\"qf\">    datEnd = datStart<\/p>\n<p class=\"qf\">    datStart = datHelp<\/p>\n<p class=\"qf\">  End If<\/p>\n<p class=\"qf\">  intDaycount = DateDiff(&quot;d&quot;, datStart, datEnd)<\/p>\n<p class=\"qf\">  If intDaycount &lt; 0 Or DateDiff(&quot;d&quot;, _<\/p>\n<p class=\"qf\">      DateSerial(Year(datStart), Month(datStart), 1), _<\/p>\n<p class=\"qf\">      DateSerial(Year(datEnd), Month(datEnd), 1)) &gt; _<\/p>\n<p class=\"qf\">      364 Then<\/p>\n<p class=\"qf\">    MsgBox &quot;Der Zeitraum muss innerhalb von 12 Kalendermonaten liegen.&quot;<\/p>\n<p class=\"qf\">    Exit Sub<\/p>\n<p class=\"qf\">  End If<\/p>\n<p class=\"qf\">  DoCmd.OpenForm strForm, OpenArgs:=datStart &amp; &quot;|&quot; _<\/p>\n<p class=\"qf\">    &amp; datEnd, WindowMode:=acDialog<\/p>\n<p class=\"qf\">  If IstFormularGeoeffnet(strForm) Then<\/p>\n<p class=\"qf\">     m_txtStartdate.Value = Forms(strForm)!txtStartdatum<\/p>\n<p class=\"qf\">    m_txtEnddate.Value = Forms(strForm)!txtEnddatum<\/p>\n<p class=\"qf\">    DoCmd.Close acForm, strForm<\/p>\n<p class=\"qf\">  End If<\/p>\n<p class=\"qf\">End Sub<\/p>\n<p>Die Prozedur pr&uuml;ft die Inhalte der Textfelder f&uuml;r die Eingabe von Start- und Enddatum. Sind beide leer, wird das aktuelle Datum als Start- und Enddatum an das Formular &uuml;bergeben. Ist nur das Startdatum angegeben, wird das Enddatum mit dem gleichen Wert gef&uuml;llt und umgekehrt. Wenn das Enddatum vor dem Startdatum liegt, werden beide vertauscht. Schlie&szlig;lich erfolgt noch die Pr&uuml;fung, ob das angegebene Intervall innerhalb von zw&ouml;lf Kalendermonaten liegt.<\/p>\n<p>Erst dann wird das Formular <b>frmDatumsauswahl <\/b>ge&ouml;ffnet, und zwar als modaler Dialog. Das hei&szlig;t, dass der aufrufende Code erst weiterl&auml;uft, wenn das Formular den Fokus verliert &#8211; entweder, weil es geschlossen wird oder weil die Eigenschaft <b>Visible <\/b>den Wert <b>False <\/b>erh&auml;lt.<\/p>\n<p>Sollte der Benutzer das Formular mit der <b>Abbrechen<\/b>-Schaltfl&auml;che schlie&szlig;en, wird diese mit <b>DoCmd.Close <\/b>tats&auml;chlich geschlossen. Die Prozedur <b>DatumsauswahlStarten <\/b>erkennt dies, weil die Hilfsfunktion <b>IstFormularGeoeffnet <\/b>den Wert <b>False <\/b>liefert, und wird einfach beendet.<\/p>\n<p>Wenn der Benutzer hingegen die <b>OK<\/b>-Schaltfl&auml;che verwendet, um seine Eingabe zu &uuml;bernehmen, wird das Formular nur durch Setzen der Eigenschaft <b>Visible <\/b>auf den Wert <b>False <\/b>unsichtbar gemacht. <b>IstFormularGeoeffnet <\/b>liefert in der Folge den Wert <b>True<\/b>, was die Prozedur <b>DatumsauswahlStarten <\/b>veranlasst, die beiden Textfelder <b>txtStartdatum <\/b>und <b>txtEnddatum <\/b>des Formulars <b>frmDatumsauswahl <\/b>auszulesen und die Werte an die Felder des aufrufenden Formulars zu &uuml;bergeben.<\/p>\n<p>Die beiden Felder des aufrufenden Formulars, aus denen wir bereits zuvor gegebenenfalls vorhandene Datumsvorgaben ausgelesen haben, werden zu diesem Zeitpunkt noch durch die Objektvariablen <b>m_txtStartdatum <\/b>und <b>m_txtEnddatum <\/b>referenziert, wodurch die Prozedur die ermittelten Datumsangaben einfach nur an diese Objektvariablen &uuml;bergeben muss. Danach kann das bereits nicht mehr sichtbare Formular <b>frmDatumseingabe <\/b>schlie&szlig;lich geschlossen werden.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Eine ergonomischere M&ouml;glichkeit zum Eingeben von Datumsbereichen ist schwer vorstellbar. Denkbare Erweiterungen w&auml;ren weitere M&ouml;glichkeiten, das Formular zur Datumseingabe aufzurufen &#8211; beispielsweise eine Schaltfl&auml;che. Diese k&ouml;nnte man leicht in Form einer weiteren Eigenschaft zur Klasse <b>clsDatumsauswahl<\/b> hinzuf&uuml;gen. Eine st&auml;ndige Anzeige des kompletten markierten Bereichs haben wir wegen des starken Flackerns weggelassen.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>DatumsbereicheAuswaehlen.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{FD6F1814-A944-4271-B784-1BBA44F84CAF}\/aiu_729.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das aktuelle Datum ist unter Access schnell eingegeben &#8211; es reicht die Tastenkombination Strg + Semikolon. Sonstige Daten w&auml;hlt man ab Access 2007 schnell mit dem eingebauten Datepicker aus. Oder Sie verwenden die L&ouml;sung aus dem Beitrag &#8222;Flexible Datumsfelder&#8220; (www.access-im-unternehmen.de\/690). Wenn Sie aber gleich einen Zeitraum, bestehend aus zwei Datumsangaben, eingeben m&uuml;ssen, brauchen Sie gr&ouml;&szlig;ere Kaliber &#8211; so eines wie wir im vorliegenden Beitrag beschreiben.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662010,66042010,44000027],"tags":[],"class_list":["post-55000729","post","type-post","status-publish","format-standard","hentry","category-662010","category-66042010","category-Loesungen"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Datumsbereiche ausw&auml;hlen - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Datumsbereiche ausw&auml;hlen\" \/>\n<meta property=\"og:description\" content=\"Das aktuelle Datum ist unter Access schnell eingegeben - es reicht die Tastenkombination Strg + Semikolon. Sonstige Daten w&auml;hlt man ab Access 2007 schnell mit dem eingebauten Datepicker aus. Oder Sie verwenden die L&ouml;sung aus dem Beitrag &quot;Flexible Datumsfelder&quot; (www.access-im-unternehmen.de\/690). Wenn Sie aber gleich einen Zeitraum, bestehend aus zwei Datumsangaben, eingeben m&uuml;ssen, brauchen Sie gr&ouml;&szlig;ere Kaliber - so eines wie wir im vorliegenden Beitrag beschreiben.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:06:13+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"32\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Datumsbereiche ausw&auml;hlen\",\"datePublished\":\"2020-05-22T22:06:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/\"},\"wordCount\":6457,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/1fb5f02e936f4451a4b19dc7c6defdaa\",\"articleSection\":[\"2010\",\"4\\\/2010\",\"L\u00f6sungen\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/\",\"name\":\"Datumsbereiche ausw&auml;hlen - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/1fb5f02e936f4451a4b19dc7c6defdaa\",\"datePublished\":\"2020-05-22T22:06:13+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/1fb5f02e936f4451a4b19dc7c6defdaa\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/1fb5f02e936f4451a4b19dc7c6defdaa\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Datumsbereiche_auswaehlen\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Datumsbereiche ausw&auml;hlen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Datumsbereiche ausw&auml;hlen - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/","og_locale":"de_DE","og_type":"article","og_title":"Datumsbereiche ausw&auml;hlen","og_description":"Das aktuelle Datum ist unter Access schnell eingegeben - es reicht die Tastenkombination Strg + Semikolon. Sonstige Daten w&auml;hlt man ab Access 2007 schnell mit dem eingebauten Datepicker aus. Oder Sie verwenden die L&ouml;sung aus dem Beitrag \"Flexible Datumsfelder\" (www.access-im-unternehmen.de\/690). Wenn Sie aber gleich einen Zeitraum, bestehend aus zwei Datumsangaben, eingeben m&uuml;ssen, brauchen Sie gr&ouml;&szlig;ere Kaliber - so eines wie wir im vorliegenden Beitrag beschreiben.","og_url":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:06:13+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"32\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Datumsbereiche ausw&auml;hlen","datePublished":"2020-05-22T22:06:13+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/"},"wordCount":6457,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa","articleSection":["2010","4\/2010","L\u00f6sungen"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/","url":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/","name":"Datumsbereiche ausw&auml;hlen - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa","datePublished":"2020-05-22T22:06:13+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/1fb5f02e936f4451a4b19dc7c6defdaa"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Datumsbereiche_auswaehlen\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Datumsbereiche ausw&auml;hlen"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000729","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000729"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000729\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000729"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000729"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000729"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}