{"id":55001191,"date":"2019-06-01T00:00:00","date_gmt":"2020-05-13T20:54:53","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=1191"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Berechtigungen_per_HTML_verwalten","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/","title":{"rendered":"Berechtigungen per HTML verwalten"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Im Beitrag &#8222;Benutzerverwaltung mit verschl&uuml;sselten Kennw&ouml;rtern&#8220; stellen wir eine L&ouml;sung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort ben&ouml;tigen wir ein Formular, mit dem wir die Berechtigungen f&uuml;r die einzelnen Objekte f&uuml;r die jeweilige Benutzergruppe definieren wollen. Dazu wollen wir eine Matrix anzeigen, welche die Berechtigungen und die Objekte als Spalten- und Zeilen&uuml;berschriften anzeigt und die M&ouml;glichkeit bietet, in den Zellen anzugeben, ob die Berechtigung gesetzt ist oder nicht. Dies erledigen wir mit einem Webbrowser-Steuerelement, indem wir die notwendigen Elemente per HTML darstellen.<\/b><\/p>\n<p>Der erste Entwurf des Formulars sieht wie in Bild 1 aus. Wir haben dem Formular ein Kombinationsfeld namens <b>cboBenutzergruppeID <\/b>hinzugef&uuml;gt sowie ein Webbrowser-Steuerelement namens <b>objWebbrowser<\/b>.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_03\/pic_1191_001.png\" alt=\"Erster Entwurf des Formulars\" width=\"424,7115\" height=\"407,5986\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 1: Erster Entwurf des Formulars<\/span><\/b><\/p>\n<p>Das Kombinationsfeld soll die Benutzergruppen aus der Tabelle <b>tblBenutzergruppen <\/b>anzeigen, und zwar so, dass das Feld <b>BenutzergruppeID <\/b>als gebundene Spalte ausgeblendet wird und nur die Bezeichnung der Benutzergruppe erscheint. Dazu weisen wir der Eigenschaft <b>Datensatzherkunft <\/b>die folgende Abfrage zu:<\/p>\n<pre>SELECT BenutzergruppeID, Benutzergruppe \r\nFROM tblBenutzergruppen \r\nORDER BYBenutzergruppe;<\/pre>\n<p>Damit nur die Benutzergruppe angezeigt wird, stellen wir die Eigenschaft <b>Spaltenanzahl <\/b>auf <b>2 <\/b>und die Eigenschaft <b>Spaltenbreiten <\/b>auf <b>0cm <\/b>ein.<\/p>\n<p>F&uuml;r das Zusammenstellen des HTML-Code ben&ouml;tigen wir noch die Objektbibliothek <b>Microsoft HTML Object Library<\/b>, die wir wie in Bild 2 &uuml;ber den <b>Verweise<\/b>-Dialog des VBA-Editors hinzuf&uuml;gen (Men&uuml;eintrag <b>Extras|Verweise<\/b>).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_03\/pic_1191_002.png\" alt=\"Verweise des VBA-Projekts\" width=\"424,7115\" height=\"334,8159\"\/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 2: Verweise des VBA-Projekts<\/span><\/b><\/p>\n<h2>Gew&uuml;nschte Darstellung<\/h2>\n<p>Wir m&ouml;chten nicht einfach nur eine Darstellung mit Kontrollk&auml;stchen oder &auml;hnlichen Steuer-elementen, sondern einmal etwas Besonderes programmieren: n&auml;mlich eine Darstellung, bei der die gesetzten Rechte in Gr&uuml;n und die nicht gesetzten Rechte in Rot dargestellt werden. Das sieht dann etwa f&uuml;r die Benutzergruppe <b>Administratoren <\/b>wie in Bild 3 aus.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_03\/pic_1191_003.png\" alt=\"Setzen der Berechtigungen &uuml;ber verschiedene Farben\" width=\"649,559\" height=\"429,8691\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 3: Setzen der Berechtigungen &uuml;ber verschiedene Farben<\/span><\/b><\/p>\n<h2>Funktionen des Formulars<\/h2>\n<p>Das Formular soll, wie oben erw&auml;hnt, die Auswahl einer der Benutzergruppen &uuml;ber das Kombinationsfeld oben im Formular erm&ouml;glichen. Nach der Auswahl sollen die Berechtigungen f&uuml;r die gew&auml;hlte Benutzergruppe angezeigt werden.<\/p>\n<p>Au&szlig;erdem wollen wir die folgenden Funktionen durch Anklicken der verschiedenen Bereiche der HTML-Seite im Webbrowser-Steuerelement realisieren:<\/p>\n<ul>\n<li>Wenn der Benutzer auf die rot markierte Berechtigung <b>Keine <\/b>klickt und diese so auf Gr&uuml;n einstellt, sollen automatisch die &uuml;brigen Berechtigungen f&uuml;r die Tabelle f&uuml;r diesen Benutzer auf Rot eingestellt werden.<\/li>\n<li>Wenn der Benutzer die gr&uuml;n markierte Berechtigung <b>Keine <\/b>anklickt und diese so auf Rot einstellt, sollen die &uuml;brigen Berechtigungen f&uuml;r diese Tabelle auf Gr&uuml;n eingestellt werden.<\/li>\n<li>Wenn der Benutzer eine der Berechtigungen <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen <\/b>anklickt, w&auml;hrend diese Rot ist, soll diese auf Gr&uuml;n eingestellt werden und umgekehrt.<\/li>\n<li>Dabei gilt die folgende Sonderregel: Wenn er die letzte gr&uuml;n markierte Berechtigung (also <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen<\/b>) anklickt und diese so auf Rot einstellt, soll automatisch die Berechtigung <b>Keine <\/b>auf Gr&uuml;n eingestellt werden.<\/li>\n<li>Klickt der Benutzer auf einen der Spaltenk&ouml;pfe <b>Keine<\/b>, <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen<\/b>, werden alle Eintr&auml;ge dieser Spalte auf <b>Gr&uuml;n <\/b>eingestellt. Handelt es sich um den Spaltenkopf <b>Keine<\/b>, werden alle anderen Spalten komplett auf Rot eingestellt. Handelt es sich um eine der anderen Spalten, wird diese komplett auf Gr&uuml;n eingestellt und die Spalte <b>Keine <\/b>logischerweise komplett auf Rot.<\/li>\n<\/ul>\n<p>Wenn <b>Keine <\/b>gr&uuml;n ist, m&uuml;ssen also alle anderen Spalten f&uuml;r diese Tabelle rot sein, wenn eine der anderen Spalten gr&uuml;n ist, muss <b>Keine <\/b>rot sein.<\/p>\n<h2>Initialisieren des Formulars<\/h2>\n<p>Im Klassenmodul des Formulars deklarieren wir die folgenden Variablen im allgemeinen Teil, das hei&szlig;t, die Variablen sind modulweit zugreifbar:<\/p>\n<pre><span style=\"color:blue;\">Dim <\/span>WithEvents objWebbrowser<span style=\"color:blue;\"> As <\/span>WebBrowser\r\n<span style=\"color:blue;\">Dim <\/span>WithEvents objDocument<span style=\"color:blue;\"> As <\/span>HTMLDocument\r\n<span style=\"color:blue;\">Public <\/span>colCells<span style=\"color:blue;\"> As <\/span>Collection\r\n<span style=\"color:blue;\">Public <\/span>colCellWrapper<span style=\"color:blue;\"> As <\/span>Collection<\/pre>\n<p>Die ersten beiden Variablen referenzieren sp&auml;ter das Webbrowser-Steuerelement sowie das darin angezeigte Dokument. Die &uuml;brigen beiden, <b>colCells<\/b> und <b>colCellWrapper<\/b>, sind <b>Collection<\/b>-Objekte, welche Objekte aufnehmen, die wir auf Basis zweier weiter unten beschrieben Klassen erstellen &euro;&#8220; und zwar f&uuml;r jedes Element der Tabelle aus der Kopfzeile und den farbig zu markierenden Tabellenzellen.<\/p>\n<p>Beim &Atilde;-ffnen des Formulars weisen wir der Variablen <b>obj-Webbrowser <\/b>das Steuer-element <b>ctlWebbrowser.Object <\/b>zu. Au&szlig;erdem stellen wir die Eigenschaft <b>TimerInterval <\/b>auf <b>50 <\/b>ein, was dazu f&uuml;hrt, dass die Ereignisprozedur <b>Bei Zeitgeber <\/b>50 Millisekunden nach dem Einstellen dieser Eigenschaft aufgerufen wird:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Open(Cancel<span style=\"color:blue;\"> As Integer<\/span>)\r\n     <span style=\"color:blue;\">Set<\/span> objWebbrowser = Me!ctlWebbrowser.Object\r\n     Me.TimerInterval = 50\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die durch das Ereignis <b>Bei Zeitgeber <\/b>ausgel&ouml;ste Prozedur zeigt zun&auml;chst eine leere Seite im <b>Webbrowser<\/b>-Steuerelement an und stellt die Variable <b>objDocument <\/b>auf die Eigenschaft <b>Document <\/b>des <b>Webbrowser<\/b>-Steuerelements ein. Dann stellt sie <b>TimerInterval <\/b>auf <b>0<\/b>, damit das Ereignis <b>Bei Zeitgeber <\/b>nicht nochmals ausgel&ouml;st wird. Schlie&szlig;lich stellt sie das Kombinationsfeld <b>cboBenutzergruppeID <\/b>auf den ersten Eintrag der Datensatzherkunft ein und ruft die Prozedur <b>TabelleErstellen <\/b>auf. Dieser &uuml;bergibt sie die aktuell im Kombinationsfeld ausgew&auml;hlte Benutzergruppe als Parameter, damit die Prozedur die dazu geh&ouml;renden Berechtigungen im <b>Webbrowser<\/b>-Steuerelement anzeigt:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>Form_Timer()\r\n     objWebbrowser.Navigate \"about:blank\"\r\n     <span style=\"color:blue;\">Set<\/span> objDocument = objWebbrowser.Document\r\n     Me.TimerInterval = 0\r\n     DoEvents\r\n     Me!cboBenutzergruppeID =  Me!cboBenutzergruppeID.ItemData(0)\r\n     TabelleErstellen Me!cboBenutzergruppeID\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p>Die Prozedur <b>TabelleErstellen <\/b>wird au&szlig;erdem aufgerufen, wenn der Benutzer im Kombinationsfeld <b>cboBenutzergruppe <\/b>einen anderen Eintrag ausw&auml;hlt. Dazu legen wir die folgende Prozedur an, die durch das Ereignis <b>Nach Aktualisierung <\/b>des Kombinationsfeldes aufgerufen wird:<\/p>\n<pre><span style=\"color:blue;\">Private Sub <\/span>cboBenutzergruppeID_AfterUpdate()\r\n     TabelleErstellen Me!cboBenutzergruppeID\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<h2>CSS-Definition<\/h2>\n<p>In der nachfolgend mit der Prozedur <b>TabelleErstellen <\/b>zusammengestellten HTML-Tabelle verwenden wir auch einige Zeilen CSS-Code. Diese stellen wir mit der folgenden Funktion zusammen. Die ersten CSS-Anweisungen legen die Schriftart, Schriftgr&ouml;&szlig;e, Ausrichtung und Rahmeneigenschaften f&uuml;r die Tabellen fest:<\/p>\n<pre><span style=\"color:blue;\">Public Function <\/span>CSS()\r\n     <span style=\"color:blue;\">Dim <\/span>strCSS<span style=\"color:blue;\"> As String<\/span>\r\n     strCSS = strCSS & \"table {\"\r\n     strCSS = strCSS & \"  font-family: Calibri;\"\r\n     strCSS = strCSS & \"  text-align: center;\"\r\n     strCSS = strCSS & \"  width: 100%;\"\r\n     strCSS = strCSS & \"  border-collapse: collapse;\"\r\n     strCSS = strCSS & \"}\"\r\n     strCSS = strCSS & \"td.columnHeader {\"\r\n     strCSS = strCSS & \"  font-weight: bold;\"\r\n     strCSS = strCSS & \"  border-bottom: 1px solid black;\"\r\n     strCSS = strCSS & \"}\"\r\n     strCSS = strCSS & \"td.rowHeader {\"\r\n     strCSS = strCSS & \"  font-weight: bold;\"\r\n     strCSS = strCSS & \"  border-right: 1px solid black;\"\r\n     strCSS = strCSS & \"  text-align: left;\"\r\n     strCSS = strCSS & \"}\"<\/pre>\n<p>Dann folgen zwei Definitionen f&uuml;r CSS-Klassen, welche die Hintergrundfarben f&uuml;r die roten und gr&uuml;nen Zellen festlegen:<\/p>\n<pre>     strCSS = strCSS & \"td.redcell{\"\r\n     strCSS = strCSS & \"  border-color: white;\"\r\n     strCSS = strCSS & \"  border-width: 1px;\"\r\n     strCSS = strCSS & \"  border-style: solid;\"\r\n     strCSS = strCSS & \"  background: red;\"\r\n     strCSS = strCSS & \"}\"\r\n     strCSS = strCSS & \"td.greencell{\"\r\n     strCSS = strCSS & \"  border-color: white;\"\r\n     strCSS = strCSS & \"  border-width: 1px;\"\r\n     strCSS = strCSS & \"  border-style: solid;\"\r\n     strCSS = strCSS & \"  background: green;\"\r\n     strCSS = strCSS & \"}\"<\/pre>\n<p>Dann ben&ouml;tigen wir noch zwei Klassen f&uuml;r die Breite der ersten Spalte (50%) und die der folgenden f&uuml;nf Spalten (jeweils 10%):<\/p>\n<pre>     strCSS = strCSS & \".th1 {\"\r\n     strCSS = strCSS & \"  width:50%;\"\r\n     strCSS = strCSS & \"  text-align:left;\"\r\n     strCSS = strCSS & \"}\"\r\n     strCSS = strCSS & \".th2 {\"\r\n     strCSS = strCSS & \"  width:10%;\"\r\n     strCSS = strCSS & \"  text-align:left;\"\r\n     strCSS = strCSS & \"}\"<\/pre>\n<p>Schlie&szlig;lich fehlt noch eine CSS-Klasse namens <b>scrolling<\/b>, welche die H&ouml;he des zu scrollenden Bereiches festlegt und dass dieser gescrollt werden kann:<\/p>\n<pre>     strCSS = strCSS & \".scrolling {\"\r\n     strCSS = strCSS & \"  height:300px;\"\r\n     strCSS = strCSS & \"  overflow:auto;\"\r\n     strCSS = strCSS & \"}\"\r\n     CSS = strCSS\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<h2>Tabelle zusammenstellen<\/h2>\n<p>Nach dieser Vorbereitung kommen wir zur Prozedur <b>TabelleErstellen<\/b>, deren ersten Teil Sie in Listing 1 finden. Diese Prozedur deklarieren wir als &ouml;ffentliche Prozedur, damit wir sp&auml;ter von Klassenobjekten, die wir von dieser Prozedur aus erstellt haben, erneut auf diese Prozedur zugreifen k&ouml;nnen, um die Tabelle neu zu erstellen.<\/p>\n<pre><span style=\"color:blue;\">Public Sub <\/span>TabelleErstellen(lngBenutzergruppeID<span style=\"color:blue;\"> As Long<\/span>)\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rstSpaltenkoepfe<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstZeilen<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>rstWerte<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>objTable<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTable\r\n     <span style=\"color:blue;\">Dim <\/span>objRow<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableRow\r\n     <span style=\"color:blue;\">Dim <\/span>objCell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell\r\n     <span style=\"color:blue;\">Dim <\/span>objCSS<span style=\"color:blue;\"> As Object<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>objCellHeaderWrapper<span style=\"color:blue;\"> As <\/span>clsCellHeaderWrapper\r\n     <span style=\"color:blue;\">Dim <\/span>objInnerTable<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTable\r\n     <span style=\"color:blue;\">Dim <\/span>objDiv<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLDivElement\r\n     <span style=\"color:blue;\">Set<\/span> colCells = <span style=\"color:blue;\">New<\/span> Collection\r\n     <span style=\"color:blue;\">Set<\/span> colCellWrapper = <span style=\"color:blue;\">New<\/span> Collection\r\n     <span style=\"color:blue;\">Set<\/span> objCSS = objDocument.createStyleSheet(\"\")\r\n     objCSS.cssText = CSS\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     objDocument.body.innerHTML = \"\"\r\n     <span style=\"color:blue;\">Set<\/span> objTable = objDocument.createElement(\"Table\")\r\n     objDocument.body.appendChild objTable\r\n     <span style=\"color:blue;\">Set<\/span> objRow = objTable.insertRow\r\n     <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n     objCell.className = \"columnHeader rowHeader th1\"\r\n     <span style=\"color:blue;\">Set<\/span> rstSpaltenkoepfe = db.OpenRecordset(\"SELECT BerechtigungID, Berechtigung FROM tblBerechtigungen\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstSpaltenkoepfe.EOF\r\n         <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n         objCell.className = \"columnHeader th2\"\r\n         objCell.innerText = rstSpaltenkoepfe!Berechtigung\r\n         <span style=\"color:blue;\">Set<\/span> objCellHeaderWrapper = <span style=\"color:blue;\">New<\/span> clsCellHeaderWrapper\r\n         <span style=\"color:blue;\">With<\/span> objCellHeaderWrapper\r\n             <span style=\"color:blue;\">Set<\/span> .cell = objCell\r\n             .BerechtigungID = rstSpaltenkoepfe!BerechtigungID\r\n             .BenutzergruppeID = Me!cboBenutzergruppeID\r\n             <span style=\"color:blue;\">Set<\/span> .Form = Me\r\n         End <span style=\"color:blue;\">With<\/span>\r\n         colCellWrapper.Add objCellHeaderWrapper\r\n         rstSpaltenkoepfe.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 1: Prozedur TabelleErstellen, Teil 1<\/span><\/b><\/p>\n<p>Die Prozedur erwartet die ID der Benutzergruppe, deren Berechtigungen an den verschiedenen Tabellen der Datenbank in der HTML-Tabelle dargestellt werden sollen. Sie deklariert eine ganze Reihe von Variablen. Die drei Variablen <b>rstSpaltenkoepfe<\/b>, <b>rstZeilen <\/b>und <b>rstWerte <\/b>nehmen die Recordsets auf, deren Daten wir in der HTML-Tabelle abbilden wollen. Wie wir diese genau f&uuml;llen, erfahren Sie weiter unten.<\/p>\n<p>Dazu ben&ouml;tigen wir einige Objekte, mit denen wir die Objekte der HTML-Seite definieren und hierarchisch anordnen. Wir wollen in diesem Beispiel nicht wie etwa in dem Beispiel zum Beitrag <b>HTML-Tabellen mit fester Kopfzeile <\/b>(<b>www.access-im-unternehmen.de\/1188<\/b>) den HTML-Code in einer <b>String<\/b>-Variablen zusammensetzen, sondern diesmal das Objektmodell f&uuml;r HTML verwenden (DOM, Document Object Model).<\/p>\n<p>Die ersten Anweisungen der Prozedur erzeugen jeweils neue <b>Collection<\/b>-Objekte f&uuml;r die beiden Variablen <b>colCells <\/b>und <b>colCellWrapper<\/b>, die wie im Kopf des Klassenmoduls deklariert haben. Dann erstellen wir die Klasse, welche den Code der Funktion <b>CSS <\/b>als Wert der Eigenschaft <b>cssText <\/b>aufnimmt. Au&szlig;erdem ben&ouml;tigen wir ein Database-Objekt f&uuml;r den Zugriff auf die Objekte der aktuellen Datenbank.<\/p>\n<p>F&uuml;r das mit der Variablen <b>objDocument <\/b>referenzierten Objektvariablen f&uuml;r das Dokument im <b>Webbrowser<\/b>-Steuerelement stellen wir die Eigenschaft <b>body.innerHTML <\/b>auf eine leere Zeichenkette ein. Dann erstellen wir f&uuml;r <b>objDocument <\/b>mit der <b>createElement<\/b>-Methode ein neues Element des Typs <b>Table<\/b> und h&auml;ngen es mit der <b>appendChild<\/b>-methode an das <b>body<\/b>-Objekt von <b>objDocument <\/b>an. Als N&auml;chstes f&uuml;gen wir unterhalb des <b>Table<\/b>-Objekts aus <b>objTable <\/b>mit der <b>insertRow<\/b>-Methode ein neues <b>Row<\/b>-Element ein und referenzieren es mit <b>objRow<\/b>. Darin f&uuml;gen wir nun ein erstes <b>Cell<\/b>-Objekt ein, welches der linken, oberen Zelle entspricht, die keinen Text aufnehmen soll. Dazu verwenden wir die <b>insertCell<\/b>-Methode von <b>objRow <\/b>und speichern das Ergebnis in <b>objCell<\/b>. <b>objCell<\/b> ist das erste Objekt, dem wir CSS-Klassen zuweisen. Das erledigen wir &uuml;ber die Eigenschaft <b>className<\/b>, der wir den Text <b>columnHeader rowHeader th1 <\/b>zuweisen. Dadurch nimmt das Element die in den drei CSS-Klassen <b>td.columnHeader<\/b>, <b>td.rowHeader <\/b>und <b>th1 <\/b>angegebenen Attribute an.<\/p>\n<p>Danach f&uuml;llen wir die erste <b>Recordset<\/b>-Variable namens <b>rstSpaltenkoepfe<\/b>, und zwar mit den Feldern <b>BerechtigungID <\/b>und <b>Berechtigung <\/b>der Datens&auml;tze der Tabelle <b>tblBerechtigungen<\/b>. Diese durchlaufen wir anschlie&szlig;end in einer <b>Do While<\/b>-Schleife &uuml;ber alle Eintr&auml;ge des Recordsets. In der <b>Do While<\/b>-Schleife erstellen wir jeweils ein neues <b>Cell<\/b>-Objekt und referenzieren diese wieder mit <b>objCell<\/b>. Wir weisen &uuml;ber die Eigenschaft <b>className <\/b>die beiden CSS-Klassen <b>columnHeader <\/b>und <b>th2 <\/b>zu. Au&szlig;erdem wollen wir den in den Zellen anzuzeigenden Text definieren. Diesen entnehmen wir dem Feld <b>Berechtigung <\/b>des aktuellen Datensatzes des Recordsets <b>rstSpaltenkoepfe<\/b>.<\/p>\n<h2>Ereignisse f&uuml;r Spaltenk&ouml;pfe<\/h2>\n<p>F&uuml;r diese Spaltenk&ouml;pfe, jeweils einer f&uuml;r jeden Berechtigungstyp, wollen wir nun jeweils eine Ereignisprozedur definieren, die beim Anklicken des Spaltenkopfes ausgel&ouml;st wird. Das k&ouml;nnen wir nicht so einfach wie bei einer Schaltfl&auml;che in einem Access-Formular erledigen, denn es handelt sich ja bei den Tabellenzellen nicht um Steuerelemente, die wir dem Formularentwurf hinzuf&uuml;gen und deren Ereigniseigenschaften wir dann definieren und mit Ereignisprozeduren hinterlegen k&ouml;nnen. Es ist etwas komplizierter. Wir ben&ouml;tigen f&uuml;r jedes mit Ereignissen zu versehende Element eine eigene Instanz einer Klasse, die dann wiederum auf das darin deklarierte Element verweist und die gew&uuml;nschten Ereignisse des Elements implementiert.<\/p>\n<p>Wir schauen uns die Sache erst einmal der Seite unserer Prozedur an, mit der wir die HTML-Tabelle erstellen. Dort legen wir f&uuml;r jedes <b>Cell<\/b>-Element f&uuml;r eine Berechtigung ein neues Objekt auf Basis der Klasse <b>clsCellHeaderWrapper <\/b>an und speichern es in der Variablen <b>objCellHeaderWrapper<\/b>. Diesem weisen wir dann &uuml;ber die Eigenschaft <b>cell <\/b>die Objektvariable <b>objCell <\/b>zu. Die Eigenschaft <b>BerechtigungID <\/b>erh&auml;lt den Wert des Feldes <b>BerechtigungID <\/b>des aktuellen Datensatzes des Recordsets <b>rstSpaltenkoepfe<\/b>. Die Eigenschaft <b>BenutzergruppeID <\/b>erh&auml;lt den Wert des Kombinationsfeldes <b>cboBenutzergruppeID<\/b> des Formulars. Au&szlig;erdem stellen wir &uuml;ber die Eigenschaft <b>Form <\/b>noch einen Verweis auf das Formular ein (<b>Me<\/b>).<\/p>\n<p>Da wir <b>objCellHeaderWrapper <\/b>schon im n&auml;chsten Schleifendurchlauf mit den Eigenschaften des n&auml;chsten <b>Cell<\/b>-Objekts f&uuml;llen, speichern wir die aktuelle Instanz noch schnell mit der <b>Add<\/b>-Methode in der Collection <b>colCellWrapper<\/b>. Danach bewegen wir den Datensatzzeiger zu n&auml;chsten Datensatz und beginnen die Schleife von vorn, bis alle f&uuml;nf Berechtigungen durchlaufen sind. Damit steht schon einmal die erste Zeile der Tabelle.<\/p>\n<h2>Tabellenk&ouml;rper hinzuf&uuml;gen<\/h2>\n<p>Den zweiten Teil der Prozedur <b>TabelleErstellen <\/b>finden Sie in Listing 2. Hier f&uuml;llen wir das Recordset <b>rstZeilen <\/b>mit allen Datens&auml;tzen der Tabelle <b>tblTabellen<\/b>. Bevor wir diese durchlaufen, legen wir noch einige weitere Elemente an. Dem Objekt <b>objTable <\/b>f&uuml;gen wir mit <b>insertRow <\/b>eine neue Zeile hinzu, die wir in <b>objRow <\/b>speichern. Dieser f&uuml;gen wir diesmal nur eine einzige Zelle hinzu, die sich aber durch den Wert <b>6 <\/b>f&uuml;r die Eigenschaft <b>colSpan <\/b>&uuml;ber die kompletten sechs Spalten der ersten Zeile der Tabelle erstreckt.<\/p>\n<pre>     <span style=\"color:blue;\">Set<\/span> rstZeilen = db.OpenRecordset(\"SELECT * FROM tblTabellen\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Set<\/span> objRow = objTable.insertRow\r\n     <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n     objCell.colSpan = 6\r\n     <span style=\"color:blue;\">Set<\/span> objDiv = objDocument.createElement(\"Div\")\r\n     objCell.appendChild objDiv\r\n     objDiv.className = \"scrolling\"\r\n     <span style=\"color:blue;\">Set<\/span> objInnerTable = objDocument.createElement(\"Table\")\r\n     objDiv.appendChild objInnerTable\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstZeilen.EOF\r\n         <span style=\"color:blue;\">Set<\/span> objRow = objInnerTable.insertRow\r\n         rstSpaltenkoepfe.MoveFirst\r\n         <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n         objCell.innerText = rstZeilen!Tabelle\r\n         objCell.className = \"rowHeader th1\"\r\n         <span style=\"color:blue;\">Set<\/span> rstWerte = db.OpenRecordset(\"SELECT BerechtigungszuordnungID, BenutzergruppeID, TabelleID, \" _\r\n             \"BerechtigungID FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" & lngBenutzergruppeID _\r\n             & \" AND TabelleID = \" & rstZeilen!TabelleID, dbOpenDynaset)\r\n         <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rstSpaltenkoepfe.EOF\r\n             rstWerte.FindFirst \"BerechtigungID = \" & rstSpaltenkoepfe!BerechtigungID\r\n             <span style=\"color:blue;\">If <\/span><span style=\"color:blue;\">Not<\/span> rstWerte.NoMatch<span style=\"color:blue;\"> Then<\/span>\r\n                 colCells.Add ZelleHinzufuegen(objRow, \"greencell\", rstWerte!BerechtigungszuordnungID, _\r\n                     rstSpaltenkoepfe!BerechtigungID, rstZeilen!TabelleID, lngBenutzergruppeID)\r\n             <span style=\"color:blue;\">Else<\/span>\r\n                 colCells.Add ZelleHinzufuegen(objRow, \"redcell\", 0, rstSpaltenkoepfe!BerechtigungID, _\r\n                     rstZeilen!TabelleID, lngBenutzergruppeID)\r\n             <span style=\"color:blue;\">End If<\/span>\r\n             rstSpaltenkoepfe.Move<span style=\"color:blue;\">Next<\/span>\r\n         <span style=\"color:blue;\">Loop<\/span>\r\n         rstZeilen.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     Inzwischenablage <span style=\"color:blue;\">Replace<\/span>(<span style=\"color:blue;\">Replace<\/span>(objDocument.documentElement.innerHTML, \"&gt;&lt;\/\", \"&gt;\" & <span style=\"color:blue;\">vbCrLf<\/span> & \"&lt;\/\"), \"&gt;&lt;\", \"&gt;\" _\r\n         & <span style=\"color:blue;\">vbCrLf<\/span> & \"&lt;\")\r\n<span style=\"color:blue;\">End Sub<\/span><\/pre>\n<p><!--30percent--><\/p>\n<p><b><span style=\"color:darkgrey;\">Listing 2: Prozedur TabelleErstellen, Teil 2<\/span><\/b><\/p>\n<p>Wir erstellen in <b>objDiv <\/b>ein neues <b>Div<\/b>-Objekt f&uuml;r <b>objDocument <\/b>und f&uuml;gen es mit der <b>appendChild<\/b>-Methode in das Objekt <b>objCell <\/b>ein. Diesem <b>Div<\/b>-Element weisen wir die Klasse <b>scrolling <\/b>zu. Das <b>Div<\/b>-Element umfasst also den scrollbaren Bereich der Tabelle &euro;&#8220; wir wollen ja, dass nur der untere Teil der Tabelle gescrollt wird und die Spaltenk&ouml;pfe am oberen Rand der HTML-Tabelle fixiert werden.<\/p>\n<p>Danach erstellen wir ein weiteres <b>Table<\/b>-Element, das wir dem <b>Div<\/b>-Element unterordnen. Dieses <b>Table<\/b>-Element f&uuml;llen wir dann in einer <b>Do While<\/b>-Schleife &uuml;ber alle Datens&auml;tze des Recordsets <b>rstZeilen <\/b>mit der entsprechenden Anzahl Zeilen beziehungsweise <b>Row<\/b>-Elementen.<\/p>\n<p>In der <b>Do While<\/b>-Schleife kommen wir nun auf das Recordset <b>rstSpaltenkoepfe <\/b>zur&uuml;ck, dessen Datensatzzeiger wir mit der <b>MoveFirst<\/b>-Methode wieder an die erste Position verschieben. Bevor wir dieses Recordset nutzen, folgen noch einige neue Elemente: Zun&auml;chst ein erstes <b>Cell<\/b>-Element, das wir dem aktuellen <b>objRow<\/b>-Element, also der neuen Zeile der HTML-Tabelle, unterordnen. Diesem ersten Element weisen wir als Text den Namen der Tabelle aus dem Feld <b>Tabelle <\/b>des Recordsets <b>rstZeilen <\/b>zu. Au&szlig;erdem stellen wir die CSS-Klassen <b>rowHeader <\/b>und <b>th1 <\/b>f&uuml;r die Eigenschaft <b>className <\/b>ein.<\/p>\n<p>Damit haben wir die erste Zelle der aktuellen Zeile der HTML-Tabelle mit dem Namen der Tabelle gef&uuml;llt, deren Berechtigungen nun in Form von roten oder gr&uuml;nen K&auml;stchen folgen. Dazu f&uuml;llen wir das Recordset <b>rstWerte <\/b>mit den Daten der Tabelle <b>tblBerechtigungszuordnungen<\/b>, deren Benutzergruppe der im Kombinationsfeld ausgew&auml;hlten Benutzergruppe und deren Tabelle der Tabelle f&uuml;r die aktuelle Zeile entspricht.<\/p>\n<p>Die Datens&auml;tze des Recordsets <b>rstSpaltenkoepfe <\/b>durchlaufen wir nun in einer untergeordneten <b>Do While<\/b>-Schleife. Nun suchen wir im Recordset <b>rstWerte <\/b>nach dem Datensatz, dessen Feld <b>BerechtigungID <\/b>dem Wert des Feldes <b>BerechtigungID <\/b>des aktuellen Datensatzes des Recordsets <b>Spaltenkoepfe <\/b>entspricht.<\/p>\n<p>Ist ein solcher Datensatz vorhanden, wurde diese Berechtigung f&uuml;r die Kombination aus Benutzergruppe und Tabelle in der Tabelle <b>tblBerechtigungszuordnungen <\/b>zugeordnet. Dies pr&uuml;ft die folgende <b>If&#8230;Then<\/b>-Bedingung, welche den Wert von <b>rstWerte.NoMatch <\/b>untersucht.<\/p>\n<p>Ist die Berechtigung f&uuml;r die Kombination aus Tabelle und Benutzergruppe gesetzt, f&uuml;gen wir der Collection <b>colCells <\/b>ein neues Objekt hinzu, das wir mit der Funktion <b>ZelleHinzufuegen <\/b>ermitteln. Dieser &uuml;bergeben wir als Parameter das <b>Row<\/b>-Objekt aus <b>objRow<\/b>, den Namen der zuzuweisenden Klasse (im Falle einer Berechtigungszuweisung <b>greencell<\/b>), die Werte der Tabellen <b>tblBerechtigungszuordnungen<\/b>, <b>tblBerechtigungen <\/b>und <b>tblTabellen <\/b>aus den jeweiligen Recordsets sowie die ID der Benutzergruppe.<\/p>\n<p>Wenn kein solcher Datensatz vorhanden ist, wird ebenfalls die Funktion <b>ZelleHinzufuegen <\/b>aufgerufen. Diesmal wird allerdings der Wert <b>0 <\/b>f&uuml;r den Parameter mit der Berechtigungszuordnung &uuml;bergeben sowie der Klassenname <b>redcell<\/b>.<\/p>\n<p>Auf diese Weise durchl&auml;uft die Prozedur alle Spalten f&uuml;r die aktuelle Tabelle und dann die Spalten in den Zeilen f&uuml;r die &uuml;brigen Tabellen. Die letzte Anweisung f&uuml;gt zu Kontrollzwecken den so erstellen HTML-Code in die Zwischenablage ein &euro;&#8220; Sie k&ouml;nnen diesen dann etwa in einen Texteditor kopieren, um den Code zu kontrollieren.<\/p>\n<h2>Hinzuf&uuml;gen einer Zelle mit der Funktion ZelleHinzufuegen<\/h2>\n<p>Die Anweisungen der Funktion <b>ZelleHinzufuegen <\/b>haben wir in eine eigene Funktion ausgegliedert, weil wir in der zuletzt beschriebenen <b>If&#8230;Then<\/b>-Bedingung in der Prozedur <b>TabelleErstellen <\/b>sonst ann&auml;hernd den gleichen Quellcode zwei Mal abgebildet h&auml;tten.<\/p>\n<p>Die Funktion sieht wie in Listing 3 aus. Sie erwartet die weiter oben bereits beschriebenen Parameter. Sie erstellt ein neues <b>Cell<\/b>-Objekt und ordnet dies dem mit dem Parameter <b>objRow <\/b>&uuml;bergebenen <b>Row<\/b>-Objekt unter. Dann stellt sie die Eigenschaft <b>ID <\/b>dieses Objekts auf den Wert des Parameters <b>lngBerechtigungszuordnung <\/b>fest. Au&szlig;erdem stellt Sie die Eigenschaft <b>className <\/b>auf den entsprechenden Parameter ein, also entweder <b>greencell <\/b>oder <b>redcell<\/b>.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>ZelleHinzufuegen(objRow<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableRow, strClassname<span style=\"color:blue;\"> As String<\/span>, lngBerechtigungszuordnungID _\r\n        <span style=\"color:blue;\"> As Long<\/span>, lngBerechtigungID<span style=\"color:blue;\"> As Long<\/span>, lngTabelleID<span style=\"color:blue;\"> As Long<\/span>, lngBenutzergruppeID<span style=\"color:blue;\"> As Long<\/span>)<span style=\"color:blue;\"> As <\/span>clsCellWrapper\r\n     <span style=\"color:blue;\">Dim <\/span>objCell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell\r\n     <span style=\"color:blue;\">Dim <\/span>objCellWrapper<span style=\"color:blue;\"> As <\/span>clsCellWrapper\r\n     <span style=\"color:blue;\">Set<\/span> objCell = objRow.insertCell\r\n     objCell.ID = lngBerechtigungszuordnungID\r\n     objCell.className = strClassname\r\n     <span style=\"color:blue;\">Set<\/span> objCellWrapper = <span style=\"color:blue;\">New<\/span> clsCellWrapper\r\n     <span style=\"color:blue;\">With<\/span> objCellWrapper\r\n         .BerechtigungzuordnungID = lngBerechtigungszuordnungID\r\n         .BerechtigungID = lngBerechtigungID\r\n         .TabelleID = lngTabelleID\r\n         .BenutzergruppeID = lngBenutzergruppeID\r\n         <span style=\"color:blue;\">Set<\/span> .cell = objCell\r\n     End <span style=\"color:blue;\">With<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> ZelleHinzufuegen = objCellWrapper\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 3: Die Funktion ZelleHinzufuegen<\/span><\/b><\/p>\n<p>Dann legen wir auch f&uuml;r dieses Zellen jeweils ein neues Objekt auf Basis einer Wrapperklasse an, diesmal des Typs <b>clsCellWrapper<\/b>. Auch dieses Klasse betrachten wir weiter unten. Der neuen Instanz dieser Klasse weisen wir f&uuml;r die Eigenschaften <b>BerechtigungszuordnungID<\/b>, <b>BerechtigungID<\/b>, <b>TabelleID <\/b>und <b>BenutzergruppeID <\/b>die Werte der entsprechenden Parameter zu sowie einen Verweis auf das <b>Cell<\/b>-Objekt, welches diese Kombination der Parameter repr&auml;sentiert.<\/p>\n<p>Dieses neue Objekt ist gleichzeitig das Ergebnis der Funktion, das wir dann in der aufrufenden Prozedur <b>TabelleErstellen <\/b>zur Collection <b>colCells <\/b>hinzuf&uuml;gen.<\/p>\n<h2>Die Wrapper-Klasse f&uuml;r die Spalten&uuml;berschriften<\/h2>\n<p>Die Klasse <b>clsCellHeaderWrapper <\/b>soll die Ereignisse f&uuml;r die Zellen mit den Spaltenk&ouml;pfen der HTML-Tabelle implementieren. Das hei&szlig;t, dass wir f&uuml;r jedes der f&uuml;nf (es k&ouml;nnen auch mehr sein, wenn Sie noch weitere Berechtigungsstufen anlegen) <b>HTMLTableCell<\/b>-Elemente eine Instanz der Klasse <b>clsCellHeaderWrapper <\/b>anlegen und dieser einen Verweis auf das <b>HTMLTableCell<\/b>-Element zuweisen. Au&szlig;erdem weisen wir dieser Klasse noch ein paar weitere Eigenschaften zu. Diese deklarieren wir wie folgt im Kopf des &uuml;ber den Befehl <b>Einf&uuml;gen|Klassenmodul <\/b>im VBA-Editor neu einzuf&uuml;genden Klassenmoduls:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>WithEvents m_Cell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell\r\n<span style=\"color:blue;\">Private <\/span>m_BerechtigungID<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>m_BenutzergruppeID<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>m_Form<span style=\"color:blue;\"> As <\/span>Form<\/pre>\n<p>Die Variable f&uuml;r das <b>HTMLTableCell<\/b>-Objekte deklarieren wir mit dem Schl&uuml;sselwort <b>WithEvents<\/b>. Dadurch erhalten wir die M&ouml;glichkeit, die Ereignisse f&uuml;r diese Objektvariable in diesem Klassenmodul zu implementieren. Damit wir diese Variable etwa von der Funktion <b>TabelleErstellen <\/b>aus mit dem gew&uuml;nschten <b>HTMLTableCell<\/b>-Objekt f&uuml;llen k&ouml;nnen, legen wir die folgende <b>Property Set<\/b>-Methode an:<\/p>\n<pre><span style=\"color:blue;\">Public Property <span style=\"color:blue;\">Set<\/span> <\/span>cell(cell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell)\r\n     <span style=\"color:blue;\">Set<\/span> m_Cell = cell\r\n<span style=\"color:blue;\">End Property<\/span><\/pre>\n<p>Wenn der Benutzer auf einen der Spaltenk&ouml;pfe klickt, um die Berechtigungen f&uuml;r alle Tabellen zu aktivieren, sind umfangreichere &Auml;nderungen an der HTML-Tabelle n&ouml;tig. So viele, dass wir diese nicht einzeln durchf&uuml;hren wollen, sondern lieber direkt die vollst&auml;ndige Tabelle neu erstellen. Also wollen wir in diesem Fall die Methode <b>TabelleErstellen <\/b>des Formulars erneut aufrufen. Damit wir dies k&ouml;nnen, &uuml;bergeben wir vom Formular aus &uuml;ber die Prozedur <b>TabelleErstellen <\/b>einen Verweis auf das Formular selbst. &Uuml;ber dieses k&ouml;nnen wir dann die Methode <b>TabellenErstellen <\/b>aufrufen, wie wir sp&auml;ter sehen werden. Die Objektvariable <b>m_Form <\/b>haben wir weiter oben bereits deklariert. Mit der folgenden <b>Property Set<\/b>-Prozedur nimmt die Klasse den Verweis auf das <b>Form<\/b>-Objekt entgegen:<\/p>\n<pre><span style=\"color:blue;\">Public Property <span style=\"color:blue;\">Set<\/span> <\/span>Form(frm<span style=\"color:blue;\"> As <\/span>Form)\r\n     <span style=\"color:blue;\">Set<\/span> m_Form = frm\r\n<span style=\"color:blue;\">End Property<\/span><\/pre>\n<p>Schlie&szlig;lich wollen wir noch die <b>BerechtigungID <\/b>zu dem <b>HTMLTableCell<\/b>-Objekte &uuml;bergeben sowie die <b>Benutzergruppe-ID <\/b>des aktuell mit dem Kombinationsfeld ausgew&auml;hlten Benutzergruppe. Diese Informationen nimmt die Klasse mit den folgenden beiden <b>Property Let<\/b>-Prozeduren entgegen:<\/p>\n<pre><span style=\"color:blue;\">Public Property Let <\/span>BerechtigungID(lng<span style=\"color:blue;\"> As Long<\/span>)\r\n     m_BerechtigungID = lng\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Public Property Let <\/span>BenutzergruppeID(lng<span style=\"color:blue;\"> As Long<\/span>)\r\n     m_BenutzergruppeID = lng\r\n<span style=\"color:blue;\">End Property<\/span><\/pre>\n<p>Damit kommen wir zu der Ereignisprozedur, die beim Anklicken des <b>HTMLTableCell<\/b>-Objektes ausgel&ouml;st wird. Diese Prozedur legen Sie im Klassenmodul <b>clsCellHeaderWrapper <\/b>an, indem Sie im linken Kombinationsfeld des Codefensters den Eintrag <b>m_Cell <\/b>ausw&auml;hlen und im rechten Kombinationsfeld den Eintrag <b>onclick <\/b>(siehe Bild 4).<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_03\/pic_1191_004.png\" alt=\"Anlegen der Ereignisprozedur onclick f&uuml;r das Objekt m_Cell\" width=\"649,559\" height=\"286,2463\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 4: Anlegen der Ereignisprozedur onclick f&uuml;r das Objekt m_Cell<\/span><\/b><\/p>\n<p>Danach erg&auml;nzen Sie den Code der Prozedur wie in Listing 4. Die Ereignisprozedur f&uuml;llt zun&auml;chst ein Recordset namens <b>rst <\/b>mit den Datens&auml;tzen der Tabelle <b>tblTabellen<\/b>. Diese durchl&auml;uft die Prozedur dann in einer <b>Do While<\/b>-Schleife. Nach dem Deaktivieren der Fehlerbehandlung versucht die Prozedur, jeweils einen neuen Datensatz zur Tabelle <b>tblBerechtigungszuordnung <\/b>hinzuzuf&uuml;gen, deren Benutzergruppe und Berechtigung den Werten aus den Variablen <b>m_BenutzergruppeID <\/b>und <b>m_BerechtigungID <\/b>entspricht und deren Feld <b>TabelleID <\/b>mit dem Prim&auml;rschl&uuml;sselfeld des aktuellen Datensatzes des Recordsets gef&uuml;llt wird.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>m_Cell_onclick()<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblTabellen\", dbOpenDynaset)\r\n     <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n         On Error Resume <span style=\"color:blue;\">Next<\/span>\r\n         db.Execute \"INSERT INTO tblBerechtigungszuordnungen(BenutzergruppeID, TabelleID, BerechtigungID) VALUES(\" _\r\n             & m_BenutzergruppeID & \", \" & rst!TabelleID & \", \" & m_BerechtigungID & \")\", dbFailOnError\r\n         <span style=\"color:blue;\">If <\/span>Err.Number = 3022<span style=\"color:blue;\"> Then<\/span>\r\n             db.Execute \"UPDATE tblBerechtigungszuordnungen SET BenutzergruppeID = \" & m_BenutzergruppeID _\r\n                 & \" AND TabelleID = \" & rst!TabelleID & \" AND BerechtigungID = \" & m_BerechtigungID, dbFailOnError\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">On Error GoTo<\/span> 0\r\n         <span style=\"color:blue;\">If <\/span>m_BerechtigungID = 0<span style=\"color:blue;\"> Then<\/span>\r\n             db.Execute \"DELETE FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" & m_BenutzergruppeID _\r\n                 & \" AND NOT BerechtigungID = 0\", dbFailOnError\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             db.Execute \"DELETE FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" & m_BenutzergruppeID _\r\n                 & \" AND BerechtigungID = 0\", dbFailOnError\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         rst.Move<span style=\"color:blue;\">Next<\/span>\r\n     <span style=\"color:blue;\">Loop<\/span>\r\n     m_Form.TabelleErstellen m_BenutzergruppeID\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 4: Ereignis, das beim Anklicken einer der Cell-Objekten f&uuml;r die Spalten&uuml;berschriften ausgel&ouml;st wird.<\/span><\/b><\/p>\n<p>Das kann zu einem Fehler f&uuml;hren, wenn ein Datensatz mit diesen Werten bereits in der Tabelle <b>tblBerechtigungszuordnung <\/b>vorhanden ist. In diesem Fall, den wir durch eine <b>If&#8230;Then<\/b>-Bedingung mit der Pr&uuml;fung der Fehlernummer identifizieren, aktualisieren wir diesen Datensatz einfach mit einer <b>UPDATE<\/b>-Anweisung. Danach ist der entsprechende Datensatz auf jeden Fall mit den korrekten Werten in der Tabelle enthalten.<\/p>\n<p>Danach folgt noch eine <b>If&#8230;Then<\/b>-Bedingung, die pr&uuml;ft, ob die Berechtigung <b>Keine <\/b>festgelegt werden soll, also ob der Benutzer auf die Spalten&uuml;berschrift <b>Keine <\/b>geklickt hat. Dies w&uuml;rde dem Wert <b>0 <\/b>f&uuml;r die Variable <b>m_Berechtigung-ID <\/b>entsprechen. In diesem Fall sollen f&uuml;r diese Kombination aus Benutzer und den Tabellen alle Berechtigungen entzogen werden, was gleichzeitig bedeutet, dass wir alle &uuml;brigen Berechtigungen wie Lesen, Anlegen, &Auml;ndern oder L&ouml;schen f&uuml;r alle Tabellen f&uuml;r diesen Benutzer entziehen m&uuml;ssen. Dann f&uuml;hren wir eine <b>DELETE<\/b>-Anweisung aus, die alle Eintr&auml;ge aus der Tabelle <b>tblBerechtigungszuordnungen <\/b>l&ouml;scht, deren Feld <b>BenutzergruppeID <\/b>den Wert aus <b>m_BenutzergruppeID <\/b>enth&auml;lt sowie deren Feld <b>BerechtigungID <\/b>nicht den Wert <b>0 <\/b>hat.<\/p>\n<p>Legt der Benutzer hingegen eine der anderen Berechtigungen f&uuml;r eine der Benutzergruppen fest, m&uuml;ssen wir nat&uuml;rlich die Berechtigung <b>Keine <\/b>f&uuml;r alle Tabellen f&uuml;r diese Benutzergruppe l&ouml;schen, denn die Benutzergruppe kann ja nicht gleichzeitig keine und eine andere Berechtigung besitzen. Also l&ouml;schen wir mit einer <b>DELETE<\/b>-Anweisung alle Datens&auml;tze der Tabelle <b>tblBerechtigungszuordnungen<\/b>, welche den Wert aus <b>m_BenutzergruppeID <\/b>im Feld <b>BenutzergruppeID <\/b>enthalten und deren Feld <b>BerechtigungID <\/b>den Wert <b>0 <\/b>aufweist.<\/p>\n<p>Danach durchlaufen wir die &uuml;brigen Datens&auml;tze f&uuml;r die &uuml;brigen Tabellen und passen deren Berechtigungen an. Nach dem Durchlaufen aller Datens&auml;tze rufen wir schlie&szlig;lich die Methode <b>TabelleErstellen <\/b>des Objekts aus <b>m_Form <\/b>auf, um die HTML-Tabelle neu zu erstellen. Dabei &uuml;bergeben wir die Benutzergruppe aus <b>m_Benutzergruppe <\/b>als Parameter.<\/p>\n<h2>Die Wrapper-Klasse f&uuml;r die einzelnen Zellen<\/h2>\n<p>Genau wie f&uuml;r die Zellen mit den Spaltenk&ouml;pfen erstellen wir auch f&uuml;r die Zellen mit den zugewiesenen Berechtigungen, die jeweils rot oder gr&uuml;n anzeigen, ob eine Berechtigung festgelegt wurde oder nicht, eine Wrapper-Klasse. Diese hei&szlig;t <b>clsCellWrapper <\/b>und sie deklariert zun&auml;chst die folgenden Variablen:<\/p>\n<pre><span style=\"color:blue;\">Private <\/span>WithEvents m_Cell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell\r\n<span style=\"color:blue;\">Private <\/span>m_TabelleID<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>m_BerechtigungID<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>m_BerechtigungszuordnungID<span style=\"color:blue;\"> As Long<\/span>\r\n<span style=\"color:blue;\">Private <\/span>m_BenutzergruppeID<span style=\"color:blue;\"> As Long<\/span><\/pre>\n<p>Die folgenden <b>Property Set<\/b>&#8211; beziehungsweise <b>Property Let<\/b>-Prozeduren erm&ouml;glichen das Zuweisen der privaten Variablen &uuml;ber &ouml;ffentliche Eigenschaften der Objektinstanzen der Klasse:<\/p>\n<pre><span style=\"color:blue;\">Public Property <span style=\"color:blue;\">Set<\/span> <\/span>cell(cell<span style=\"color:blue;\"> As <\/span>MSHTML.HTMLTableCell)\r\n     <span style=\"color:blue;\">Set<\/span> m_Cell = cell\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Public Property Let <\/span>BerechtigungID(lng<span style=\"color:blue;\"> As Long<\/span>)\r\n     m_BerechtigungID = lng\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Public Property Let <\/span>BerechtigungzuordnungID(lng<span style=\"color:blue;\"> As Long<\/span>)\r\n     m_BerechtigungszuordnungID = lng\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Public Property Let <\/span>TabelleID(lng<span style=\"color:blue;\"> As Long<\/span>)\r\n     m_TabelleID = lng\r\n<span style=\"color:blue;\">End Property<\/span>\r\n<span style=\"color:blue;\">Public Property Let <\/span>BenutzergruppeID(lng<span style=\"color:blue;\"> As Long<\/span>)\r\n     m_BenutzergruppeID = lng\r\n<span style=\"color:blue;\">End Property<\/span><\/pre>\n<p>Hier stellen Sie bereits fest, dass es keine Variable f&uuml;r die Zuweisung des aufrufenden Formulars gibt. Das ist auch nicht n&ouml;tig, denn im Gegensatz zur Aktualisierung der Daten nach dem Anklicken der Spaltenk&ouml;pfe wollen wir die &Auml;nderungen an der Darstellung der Berechtigungen in der HTML-Tabelle hier direkt in der Ereigniseigenschaft f&uuml;r das <b>onclick<\/b>-Ereignis programmieren.<\/p>\n<p>Den ersten Teil dieser Prozedur finden Sie in Listing 5. Hier pr&uuml;ft die Prozedur zun&auml;chst, ob die Eigenschaft <b>ID <\/b>des <b>HTMLTableCell<\/b>-Objekts den Wert <b>0 <\/b>enth&auml;lt. Wir erinnern uns: Die Eigenschaft <b>ID <\/b>eines <b>HTMLTableCell<\/b>-Objekts wird nur auf einen anderen Wert als <b>0 <\/b>eingestellt, wenn f&uuml;r die Kombination aus Benutzergruppe, Tabelle und Berechtigung in der Tabelle <b>tblBerechtigungszuweisungen <\/b>eine der Berechtigungen <b>Keine<\/b>, <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen <\/b>festgelegt wurde.<\/p>\n<pre><span style=\"color:blue;\">Private Function <\/span>m_Cell_onclick()<span style=\"color:blue;\"> As Boolean<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>db<span style=\"color:blue;\"> As <\/span>DAO.Database\r\n     <span style=\"color:blue;\">Dim <\/span>rst<span style=\"color:blue;\"> As <\/span>DAO.Recordset\r\n     <span style=\"color:blue;\">Dim <\/span>lngBerechtigungszuordnungID<span style=\"color:blue;\"> As Long<\/span>\r\n     <span style=\"color:blue;\">Dim <\/span>i<span style=\"color:blue;\"> As Integer<\/span>\r\n     <span style=\"color:blue;\">Set<\/span> db = CurrentDb\r\n     <span style=\"color:blue;\">If <\/span>m_Cell.ID = 0<span style=\"color:blue;\"> Then<\/span>\r\n         db.Execute \"INSERT INTO tblBerechtigungszuordnungen(BenutzergruppeID, TabelleID, BerechtigungID) VALUES(\" _\r\n             & m_BenutzergruppeID & \",\" & m_TabelleID & \", \" & m_BerechtigungID & \")\", dbFailOnError\r\n         <span style=\"color:blue;\">If <\/span>m_BerechtigungID = 0<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" _\r\n                 & m_BenutzergruppeID & \" AND TabelleID = \" & m_TabelleID & \" AND NOT BerechtigungID = 0\", dbOpenDynaset)\r\n             <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n                 <span style=\"color:blue;\">With<\/span> m_Cell.parentElement.Children(CStr(rst!BerechtigungszuordnungID))\r\n                     .className = \"redcell\"\r\n                     .ID = 0\r\n                 End <span style=\"color:blue;\">With<\/span>\r\n                 rst.Move<span style=\"color:blue;\">Next<\/span>\r\n             <span style=\"color:blue;\">Loop<\/span>\r\n             db.Execute \"DELETE FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" & m_BenutzergruppeID _\r\n                 & \" AND TabelleID = \" & m_TabelleID & \" AND NOT BerechtigungID = 0\", dbFailOnError\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" _\r\n                 & m_BenutzergruppeID & \" AND TabelleID = \" & m_TabelleID & \" AND BerechtigungID = 0\", dbOpenDynaset)\r\n             <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n                 <span style=\"color:blue;\">With<\/span> m_Cell.parentElement.Children(CStr(rst!BerechtigungszuordnungID))\r\n                     .className = \"redcell\"\r\n                     .ID = 0\r\n                 End <span style=\"color:blue;\">With<\/span>\r\n                 rst.Move<span style=\"color:blue;\">Next<\/span>\r\n             <span style=\"color:blue;\">Loop<\/span>\r\n             db.Execute \"DELETE FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" & m_BenutzergruppeID _\r\n                 & \" AND TabelleID = \" & m_TabelleID & \" AND BerechtigungID = 0\", dbFailOnError\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         m_BerechtigungszuordnungID = db.OpenRecordset(\"SELECT @@IDENTITY\").Fields(0)\r\n         m_Cell.ID = m_BerechtigungszuordnungID\r\n         m_Cell.className = \"GreenCell\"\r\n         ...<\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 5: Ereignis, das beim Anklicken einer der Cell-Objekten f&uuml;r die Berechtigungen ausgel&ouml;st wird (Teil 1).<\/span><\/b><\/p>\n<p>Hat <b>ID <\/b>also den Wert <b>0<\/b>, dann ist diese Berechtigung nicht gesetzt und es gibt auch keinen Datensatz f&uuml;r die Kombination aus dieser Berechtigung, der Benutzergruppe und der Tabelle in der Tabelle <b>tblBerechtigungszuweisungen<\/b>. Dann steuert die Ereignisprozedur den ersten Teil der <b>If&#8230;Then<\/b>-Bedingung an.<\/p>\n<p>Hier f&uuml;gt sie zun&auml;chst einen neuen Datensatz in die Tabelle <b>tblBerechtigungszuordnungen <\/b>ein, deren Felder <b>BenutzergruppeID<\/b>, <b>TabelleID <\/b>und <b>BerechtigungID <\/b>mit den Werten der Variablen <b>m_BenutzergruppeID<\/b>, <b>m_TabelleID <\/b>und <b>m_BerechtigungID <\/b>gef&uuml;llt werden.<\/p>\n<p>Hat <b>m_BerechtigungID <\/b>den Wert <b>0<\/b>, was bedeutet, dass der Benutzer die Berechtigung <b>Keine <\/b>f&uuml;r diese Tabelle angeklickt hat, ermitteln wir alle Datens&auml;tze der Tabelle <b>tblBerechtigungszuweisungen<\/b>, deren Felder <b>BenutzergruppeID <\/b>und <b>TabelleID <\/b>die Werte aus <b>m_BenutzergruppeID <\/b>und <b>m_TabelleID <\/b>aufweisen und deren <b>BerechtigungID <\/b>nicht <b>0 <\/b>ist und schreiben diese in das Recordset namens <b>rst<\/b>.<\/p>\n<p>Wir suchen also alle zuvor f&uuml;r diese Kombination aus Benutzergruppe und Tabelle vergebenen Berechtigungen aus der Tabelle heraus. Wenn wir n&auml;mlich die Berechtigung mit dem Wert <b>0<\/b>, also <b>Keine<\/b>, setzen wollen, dann m&uuml;ssen die &uuml;brigen Berechtigungen f&uuml;r die gleiche Kombination aus Benutzergruppe und Tabelle l&ouml;schen.<\/p>\n<p>Mit diesen Elementen f&uuml;hren wir nun zwei Dinge durch: Als Erstes werden diese in der HTML-Tabelle wieder rot eingef&auml;rbt, weil diese Berechtigungen ja nicht mehr vergeben sind. Und wir stellen den Wert der Eigenschaft <b>ID <\/b>wieder auf <b>0 <\/b>ein. Das erledigen wir in einer <b>Do While<\/b>-Schleife f&uuml;r alle zuvor gesetzten Berechtigungen f&uuml;r diese Kombination aus Benutzergruppe und Tabelle.<\/p>\n<p>Wie aber referenzieren wir die entsprechenden Elemente &euro;&#8220; immerhin haben wir ja aktuell nur einen Verweis auf das <b>HTMLTableCell<\/b>-Element, das der Benutzer soeben angeklickt hat<\/p>\n<p>Dazu referenzieren wir zun&auml;chst das &uuml;bergeordnete Element mit <b>m_Cell.parentElement<\/b>. Dessen Auflistung <b>Children <\/b>enth&auml;lt alle <b>HTMLTableCell<\/b>-Elemente, die in der gleichen Spalte liegen, also auch das <b>HTMLTableCell<\/b>-Element aus <b>m_Cell<\/b>.<\/p>\n<p>Wie finden wir nun das gew&uuml;nschte Element heraus Nun: Wir haben ja f&uuml;r die Eigenschaft <b>ID <\/b>den Prim&auml;rschl&uuml;sselwert der Tabelle <b>tblBerechtigungszuordnungen <\/b>f&uuml;r diesen Datensatz eingetragen. Diesen k&ouml;nnen wir als Index der <b>Children<\/b>-Auflistung verwenden und so das gew&uuml;nschte Element identifizieren: <b>m_Cell.parentElement.Children(CStr(rst!BerechtigungszuordnungID))<\/b>. Und f&uuml;r dieses Element stellen wir nun die Eigenschaft <b>ID <\/b>wieder auf <b>0 <\/b>ein sowie den Klassennamen der CSS-Klasse &uuml;ber die Eigenschaft <b>className <\/b>auf <b>redcell<\/b>. Auf diese Weise durchlaufen wir alle Elemente der gleichen Zeile, f&uuml;r die in der Tabelle <b>tblBerechtigungszuordnungen <\/b>Datens&auml;tze vorhanden sind.<\/p>\n<p>Damit haben wir aber noch nicht die entsprechenden Datens&auml;tze aus der Tabelle <b>tblBerechtigungszuordnungen <\/b>gel&ouml;scht. Das erledigen wir dann im Anschluss durch den Aufruf einer <b>DELETE<\/b>-Anweisung, mit der wir alle Datens&auml;tze aus der Tabelle <b>tblBerechtigungszuweisungen <\/b>l&ouml;schen, deren Felder <b>BenutzergruppeID <\/b>und <b>TabelleID <\/b>die Werte aus <b>m_BenutzergruppeID <\/b>und <b>m_TabelleID <\/b>enthalten und deren Feld <b>BerechtigungID <\/b>nicht den Wert <b>0 <\/b>enth&auml;lt &euro;&#8220; also genau die gleichen Datens&auml;tze, die wir weiter oben &uuml;ber das Recordset ermittelt und in der <b>Do While<\/b>-Schleife durchlaufen haben.<\/p>\n<p>Danach folgt der <b>Then<\/b>-Teil der inneren <b>If&#8230;Then<\/b>-Bedingung, die pr&uuml;ft, ob <b>m_BerechtigungID <\/b>den Wert <b>0 <\/b>enth&auml;lt. Hier schauen wir uns also nun die Zellen an, die zu einer der Berechtigungen <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen <\/b>geh&ouml;ren.<\/p>\n<p>Das sind also die F&auml;lle, in denen der Benutzer auf eine der noch roten Zellen geklickt hat, die eine der Berechtigungen au&szlig;er <b>Keine <\/b>markieren. Geschieht dies, m&uuml;ssen wir sicherstellen, dass diese Zelle nun die gr&uuml;ne Farbe erh&auml;lt und au&szlig;erdem die Zelle mit der Berechtigung <b>Keine <\/b>f&uuml;r die Kombination aus Tabelle und Benutzergruppe die rote Farbe erh&auml;lt &euro;&#8220; und die &Auml;nderungen sich auch in der Tabelle <b>tblBerechtigungszuordnungen <\/b>niederschlagen.<\/p>\n<p>Den ersten Teil erledigen wir mit der n&auml;chsten Erstellung eines Recordsets, das diesmal alle Datens&auml;tze der Tabelle <b>tblBerechtigungszuordnungen <\/b>aufnimmt, deren Felder <b>BenutzergruppeID <\/b>und <b>TabelleID <\/b>mit den Werten f&uuml;r <b>m_BenutzergruppeID <\/b>und <b>m_TabelleID <\/b>&uuml;bereinstimmen und deren Feld <b>BerechtigungID <\/b>den Wert <b>0 <\/b>enth&auml;lt. Das ist maximal ein Datensatz, daher h&auml;tten wir auch einfach mit <b>rst.NoMatch <\/b>pr&uuml;fen k&ouml;nnen, ob das Recordset einen Datensatz zur&uuml;ckliefert.<\/p>\n<p>Sicherheitshalber verwenden wir dennoch eine <b>Do While<\/b>-Schleife, in der wir f&uuml;r alle gefundenen Datens&auml;tze genau das ebenfalls in dieser Zeile liegende <b>HTMLTableCell<\/b>-Element ausfindig machen, das der Berechtigung <b>Keine <\/b>entspricht. F&uuml;r dieses stellen wir den Wert der Eigenschaft <b>ID <\/b>auf <b>0 <\/b>ein und <b>className <\/b>auf <b>redcell<\/b>. Schlie&szlig;lich entfernen wir auch dieses Element noch mit einer <b>DELETE<\/b>-Anweisung aus der Tabelle <b>tblBerechtigungszuordnungen<\/b>.<\/p>\n<p>Egal, welche der Berechtigungen der Benutzer nun angeklickt hat: Wir m&uuml;ssen auch noch den Prim&auml;rschl&uuml;sselwert des weiter oben neu zur Tabelle <b>tblBerechtigungszuordnungen <\/b>hinzugef&uuml;gten Datensatzes ermitteln und diesen in die Eigenschaft <b>ID <\/b>der betroffenen Zelle eintragen. Au&szlig;erdem soll die Zelle nun auch noch gr&uuml;n markiert werden.<\/p>\n<p>Den zweiten Teil der Prozedur <b>m_cell_onclick <\/b>finden Sie in Listing 6. Dieser Teil behandelt einen Klick auf ein <b>HTMLTableCell<\/b>-Element, dessen Eigenschaft <b>ID <\/b>nicht den Wert <b>0 <\/b>enth&auml;lt. Dabei handelt es sich um die Elemente, die bereits gr&uuml;n eingef&auml;rbt sind und somit eines der Elemente markieren, f&uuml;r die in der Tabelle <b>tblBerechtigungszuordnungen <\/b>bereits ein Datensatz vorliegt.<\/p>\n<pre>     ...\r\n     <span style=\"color:blue;\">Else<\/span>\r\n         <span style=\"color:blue;\">If <\/span>m_BerechtigungID = 0<span style=\"color:blue;\"> Then<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblBerechtigungen WHERE NOT BerechtigungID = 0\", dbOpenDynaset)\r\n             <span style=\"color:blue;\">Do While<\/span> <span style=\"color:blue;\">Not<\/span> rst.EOF\r\n                 db.Execute \"INSERT INTO tblBerechtigungszuordnungen(BenutzergruppeID, TabelleID, BerechtigungID) \" _\r\n                     & \"VALUES(\" & m_BenutzergruppeID & \", \" & m_TabelleID & \", \" & rst!BerechtigungID & \")\", dbFailOnError\r\n                 lngBerechtigungszuordnungID = db.OpenRecordset(\"SELECT @@IDENTITY\").Fields(0)\r\n                 i = i + 1\r\n                 m_Cell.parentElement.Children.Item(i + 1).ID = lngBerechtigungszuordnungID\r\n                 m_Cell.parentElement.Children.Item(i + 1).className = \"GreenCell\"\r\n                 rst.Move<span style=\"color:blue;\">Next<\/span>\r\n             <span style=\"color:blue;\">Loop<\/span>\r\n         <span style=\"color:blue;\">Else<\/span>\r\n             <span style=\"color:blue;\">Set<\/span> rst = db.OpenRecordset(\"SELECT * FROM tblBerechtigungszuordnungen WHERE BenutzergruppeID = \" _\r\n                 & m_BenutzergruppeID & \" AND TabelleID = \" & m_TabelleID, dbOpenDynaset)\r\n             rst.MoveLast\r\n             rst.MoveFirst\r\n             <span style=\"color:blue;\">If <\/span>rst.RecordCount = 1<span style=\"color:blue;\"> Then<\/span>\r\n                 db.Execute \"INSERT INTO tblBerechtigungszuordnungen(BenutzergruppeID, TabelleID, BerechtigungID) \" _\r\n                     & \"VALUES(\" & m_BenutzergruppeID & \", \" & m_TabelleID & \", 0)\", dbFailOnError\r\n                 lngBerechtigungszuordnungID = db.OpenRecordset(\"SELECT @@IDENTITY\").Fields(0)\r\n                 m_Cell.parentElement.Children.Item(1).ID = lngBerechtigungszuordnungID\r\n                 m_Cell.parentElement.Children.Item(1).className = \"GreenCell\"\r\n             <span style=\"color:blue;\">End If<\/span>\r\n         <span style=\"color:blue;\">End If<\/span>\r\n         db.Execute \"DELETE FROM tblBerechtigungszuordnungen WHERE BerechtigungszuordnungID = \" _\r\n             & m_BerechtigungszuordnungID, dbFailOnError\r\n         m_Cell.ID = 0\r\n         m_Cell.className = \"redCell\"\r\n     <span style=\"color:blue;\">End If<\/span>\r\n<span style=\"color:blue;\">End Function<\/span><\/pre>\n<p><b><span style=\"color:darkgrey;\">Listing 6: Ereignis, das beim Anklicken einer der Cell-Objekten f&uuml;r die Berechtigungen ausgel&ouml;st wird (Teil 2).<\/span><\/b><\/p>\n<p>Hier wollen wir also eine Berechtigung f&uuml;r die aktuelle Kombination von Benutzergruppe und Tabelle entfernen, wozu wieder drei Aufgaben geh&ouml;ren:<\/p>\n<ul>\n<li>&Auml;ndern der Farbe des angeklickten Elements auf Rot,<\/li>\n<li>entfernen des Datensatzes f&uuml;r das angeklickte Element aus der Tabelle <b>tblBerechtigungszuordnungen <\/b>sowie<\/li>\n<li>pr&uuml;fen, ob es sich bei der entfernten Berechtigung um die Berechtigung <b>Keine <\/b>handelt (in diesem Fall sollen alle anderen Berechtigungen aktiviert werden) oder ob es sich bei der entfernten Berechtigung um die letzte der Berechtigungen <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen <\/b>handelt. In diesem Fall soll die Berechtigung <b>Keine <\/b>wieder aktiviert werden.<\/li>\n<\/ul>\n<p>Unabh&auml;ngig von der angeklickten Zelle k&ouml;nnen wir den Datensatz aus der Tabelle <b>tblBerechtigungszuordnungen <\/b>l&ouml;schen, dessen Prim&auml;rschl&uuml;sselfeld dem Wert der Variablen <b>m_Berechtigungszuordnung <\/b>entspricht (dieser Wert ist &uuml;brigens mit dem der Eigenschaft <b>ID <\/b>des <b>HTMLTableCell<\/b>-Objekts identisch). Das erledigen wir mit dem Aufruf einer entsprechenden <b>DELETE<\/b>-Anweisung. Danach stellen wir die Eigenschaft <b>ID <\/b>auf <b>0 <\/b>ein und die Eigenschaft <b>className <\/b>auf <b>redCell<\/b>, damit die Zelle wieder rot angezeigt wird.<\/p>\n<p>Der bisherige Teil war einfach. Nun kommt der <b>Else<\/b>-Teil der inneren <b>If&#8230;Then<\/b>-Bedingung. Hier pr&uuml;fen wir zun&auml;chst den Wert der Variablen <b>m_BerechtigungID<\/b>. Ist dieser Wert gleich <b>0<\/b>, dann hat der Benutzer die Berechtigung <b>Keine <\/b>angeklickt und da wir uns im <b>Else<\/b>-Teil der &auml;u&szlig;eren <b>If&#8230;Then<\/b>-Bedingung befinden, wissen wir auch, dass hier eine Berechtigung abgew&auml;hlt werden soll. Also will der Benutzer die Berechtigung <b>Keine <\/b>entfernen, was nach sich zieht, dass wir stattdessen alle anderen Berechtigungen f&uuml;r diese Kombination aus Benutzergruppe und Tabelle aktivieren wollen (siehe Bild 5). Das erledigen wir, indem wir zun&auml;chst ein Recordset definieren, das alle Datens&auml;tze der Tabelle <b>tblBerechtigungen <\/b>enth&auml;lt mit Ausnahme der Berechtigung mit dem Prim&auml;rschl&uuml;sselwert <b>0<\/b>, was der Berechtigung <b>Keine <\/b>entspricht. Dieses Recordset durchlaufen wir anschlie&szlig;end in einer <b>Do While<\/b>-Schleife. Darin f&uuml;gen wir zun&auml;chst die jeweilige Berechtigung zur Tabelle <b>tblBerechtigungszuordnungen <\/b>hinzu. Danach ermitteln wir den Prim&auml;rschl&uuml;sselwert des neu hinzugef&uuml;gten Datensatzes. Damit ermitteln wir nun &uuml;ber den Ausdruck <b>m_Cell.parentElement.Children.Item(i + 1) <\/b>die Zelle f&uuml;r die jeweilige Berechtigung und stellen f&uuml;r diese die Eigenschaften <b>ID <\/b>und <b>className <\/b>ein &euro;&#8220; auf den neuen Prim&auml;rschl&uuml;sselwert und die Klasse <b>GreenCell<\/b>. Auf die gleiche Weise durchl&auml;uft die Prozedur die <b>Do While<\/b>-Schleife f&uuml;r die &uuml;brigen Datens&auml;tze des Recordsets.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_03\/pic_1191_006.png\" alt=\"Abw&auml;hlen der Berechtigung Keine f&uuml;r eine Tabelle\" width=\"549,6265\" height=\"206,6596\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 5: Abw&auml;hlen der Berechtigung Keine f&uuml;r eine Tabelle<\/span><\/b><\/p>\n<p>Der <b>Else<\/b>-Teil der inneren <b>If&#8230;Then<\/b>-Bedingung betrachtet die F&auml;lle, wo der Benutzer eine der Berechtigungen <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>oder <b>L&ouml;schen <\/b>abw&auml;hlen m&ouml;chte. Hier k&ouml;nnen wieder zwei F&auml;lle auftreten, wobei der eine lediglich ein Sonderfall des anderen ist. Der Sonderfall ist n&auml;mlich der Fall, wo die abzuw&auml;hlende Berechtigung die letzte der vier genannten Berechtigungen ist (siehe Bild 6). In diesem Fall soll n&auml;mlich die Berechtigung <b>Keine <\/b>wieder f&uuml;r die aktuelle Kombination aus Benutzer und Tabelle aktiviert werden.<\/p>\n<p class=\"image\"><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2019_03\/pic_1191_005.png\" alt=\"Abw&auml;hlen der letzten Berechtigung f&uuml;r eine Tabelle\" width=\"549,6265\" height=\"156,0874\" \/><\/p>\n<p><b><span style=\"color:darkgrey;\">Bild 6: Abw&auml;hlen der letzten Berechtigung f&uuml;r eine Tabelle<\/span><\/b><\/p>\n<p>Wir erstellen zu Beginn wieder ein Recordset und ermitteln damit alle Datens&auml;tze, deren Benutzergruppe und Tabelle zur aktuellen Berechtigung geh&ouml;ren. F&uuml;r dieses Recordset bewegen wir den Datensatzzeiger einmal zum letzten Datensatz und wieder zum ersten, damit die <b>RecordCount<\/b>-Eigenschaft die korrekte Anzahl liefert. Wenn wir das nicht machen, liefert <b>RecordCount <\/b>normalerweise den Wert <b>1<\/b>, was nicht immer der korrekten Anzahl entspricht (nur dann, wenn diese auch <b>1 <\/b>betr&auml;gt).<\/p>\n<p>Betr&auml;gt <b>RecordCount <\/b>danach dennoch <b>1<\/b>, bedeutet dies, dass der Benutzer soeben die letzte der vier Berechtigungen <b>Lesen<\/b>, <b>Anlegen<\/b>, <b>&Auml;ndern <\/b>und <b>L&ouml;schen <\/b>entfernen m&ouml;chte. In diesem Fall f&uuml;gen wir einen neuen Datensatz f&uuml;r den aktuellen Benutzer und die aktuelle Tabelle mit der Berechtigung <b>0 <\/b>(<b>Keine<\/b>) zur Tabelle <b>tblBerechtigungszuordnungen <\/b>hinzu. Danach ermitteln wir den Prim&auml;rschl&uuml;sselwert des neu hinzugef&uuml;gten Datensatzes und speichern ihn in <b>lngBerechtigungszuordnungID<\/b>. Diesen Wert tragen wir dann in das erste <b>HTMLTableCell<\/b>-Element der der angeklickten Zelle &uuml;bergeordneten Zeile f&uuml;r die Eigenschaft <b>ID <\/b>ein. Au&szlig;erdem stellen wir f&uuml;r <b>className <\/b>f&uuml;r dieses Element den Wert <b>greenCell <\/b>ein.<\/p>\n<p>Unabh&auml;ngig davon, ob dieser Spezialfall auftritt, l&ouml;schen wir den Datensatz f&uuml;r die abgew&auml;hlte Berechtigung aus der Tabelle <b>tblBerechtigungszuordnungen<\/b>. Danach stellen wir den Wert der Eigenschaft <b>ID <\/b>des betroffenen <b>HTMLTableCell<\/b>-Elements auf <b>0 <\/b>und <b>className <\/b>auf <b>redCell <\/b>ein.<\/p>\n<h2>Zusammenfassung und Ausblick<\/h2>\n<p>Die hier vorgestellte L&ouml;sung bietet eine optisch ansprechende M&ouml;glichkeit, die Daten der Tabelle <b>tblBerechtigungszuordnungen<\/b>, die ja faktisch einer Verkn&uuml;pfungstabelle einer m:n:o-Verkn&uuml;pfung entspricht, durch das einfache Anklicken von Elementen zu verwalten.<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>BerechtigungenPerHTML.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/A4A39489-5C8F-41ED-BC0B-3ECA2E744C36\/aiu_1191.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Beitrag &#8222;Benutzerverwaltung mit verschl&uuml;sselten Kennw&ouml;rtern&#8220; stellen wir eine L&ouml;sung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort ben&ouml;tigen wir ein Formular, mit dem wir die Berechtigungen f&uuml;r die einzelnen Objekte f&uuml;r die jeweilige Benutzergruppe definieren wollen. Dazu wollen wir eine Matrix anzeigen, welche die Berechtigungen und die Objekte als Spalten- und Zeilen&uuml;berschriften anzeigt und die M&ouml;glichkeit bietet, in den Zellen anzugeben, ob die Berechtigung gesetzt ist oder nicht. Dies erledigen wir mit einem Webbrowser-Steuerelement, indem wir die notwendigen Elemente per HTML darstellen.<\/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":[662019,66032019,44000038],"tags":[],"class_list":["post-55001191","post","type-post","status-publish","format-standard","hentry","category-662019","category-66032019","category-Sicherheit"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Berechtigungen per HTML verwalten - 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\/Berechtigungen_per_HTML_verwalten\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Berechtigungen per HTML verwalten\" \/>\n<meta property=\"og:description\" content=\"Im Beitrag &quot;Benutzerverwaltung mit verschl&uuml;sselten Kennw&ouml;rtern&quot; stellen wir eine L&ouml;sung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort ben&ouml;tigen wir ein Formular, mit dem wir die Berechtigungen f&uuml;r die einzelnen Objekte f&uuml;r die jeweilige Benutzergruppe definieren wollen. Dazu wollen wir eine Matrix anzeigen, welche die Berechtigungen und die Objekte als Spalten- und Zeilen&uuml;berschriften anzeigt und die M&ouml;glichkeit bietet, in den Zellen anzugeben, ob die Berechtigung gesetzt ist oder nicht. Dies erledigen wir mit einem Webbrowser-Steuerelement, indem wir die notwendigen Elemente per HTML darstellen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-13T20:54:53+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131\" \/>\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=\"33\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Berechtigungen per HTML verwalten\",\"datePublished\":\"2020-05-13T20:54:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/\"},\"wordCount\":5431,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/1ab3a84664884b1ea62200e86e4dd131\",\"articleSection\":[\"2019\",\"3\\\/2019\",\"Sicherheit\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/\",\"name\":\"Berechtigungen per HTML verwalten - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/1ab3a84664884b1ea62200e86e4dd131\",\"datePublished\":\"2020-05-13T20:54:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/1ab3a84664884b1ea62200e86e4dd131\",\"contentUrl\":\"http:\\\/\\\/vg06.met.vgwort.de\\\/na\\\/1ab3a84664884b1ea62200e86e4dd131\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Berechtigungen_per_HTML_verwalten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Berechtigungen per HTML verwalten\"}]},{\"@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":"Berechtigungen per HTML verwalten - 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\/Berechtigungen_per_HTML_verwalten\/","og_locale":"de_DE","og_type":"article","og_title":"Berechtigungen per HTML verwalten","og_description":"Im Beitrag \"Benutzerverwaltung mit verschl&uuml;sselten Kennw&ouml;rtern\" stellen wir eine L&ouml;sung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort ben&ouml;tigen wir ein Formular, mit dem wir die Berechtigungen f&uuml;r die einzelnen Objekte f&uuml;r die jeweilige Benutzergruppe definieren wollen. Dazu wollen wir eine Matrix anzeigen, welche die Berechtigungen und die Objekte als Spalten- und Zeilen&uuml;berschriften anzeigt und die M&ouml;glichkeit bietet, in den Zellen anzugeben, ob die Berechtigung gesetzt ist oder nicht. Dies erledigen wir mit einem Webbrowser-Steuerelement, indem wir die notwendigen Elemente per HTML darstellen.","og_url":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-13T20:54:53+00:00","og_image":[{"url":"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"33\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Berechtigungen per HTML verwalten","datePublished":"2020-05-13T20:54:53+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/"},"wordCount":5431,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131","articleSection":["2019","3\/2019","Sicherheit"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/","url":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/","name":"Berechtigungen per HTML verwalten - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131","datePublished":"2020-05-13T20:54:53+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#primaryimage","url":"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131","contentUrl":"http:\/\/vg06.met.vgwort.de\/na\/1ab3a84664884b1ea62200e86e4dd131"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Berechtigungen_per_HTML_verwalten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Berechtigungen per HTML verwalten"}]},{"@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\/55001191","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=55001191"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55001191\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55001191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55001191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55001191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}