![]() |
dynamisch Records ansprechen
Hallo,
ich habe in meinem Programm zum Auslesen von AD-Infos eine Frage zum 'dynamischen' ansprechen von Records. Zuerst habe ich ein Record-Type definiert:
Code:
Bei der Abfrage des AD kann ich folgende Infos ermitteln:
type TADUser = record
cn,name,sn,givenName,displayName: String; end;
Code:
Statt der Variable 'displayName' möchte ich in die Records 'ADUser.*' in einerhalb einer Schleife schreiben.
var
ADUser: TADUser; displayName: String; Begin ... CONNECTIONString := 'select cn,givenname,displayname,sn,objectsid from '+Domain+' where objectclass='+'''user'''+' and objectclass<>'+'''computer'' ORDER by cn'; ... Typ := rs.fields[2].type; Name := rs.fields[2].name; displayName:= rs.fields[2].Value; In etwa so:
Code:
Ist so etwas möglich?
if not VarIsNull(rs.Fields[0].Value) then
Name := rs.fields[2].name; // name des AD-Feldes ADUser.(rs.fields[2].name) := rs.fields[2].Value; //Wert des AD-Feldes ... Gruß |
AW: dynamisch Records ansprechen
Herzlich Willkommen in der DP :dp:
Bitte liefere doch mal alle relevanten Stellen deines Codes. Was genau ist den rs? Ja, es ist sicherlich möglich das in einer Schleife abzuarbeiten. |
AW: dynamisch Records ansprechen
In etwa so:
Code:
Ist so etwas möglich?
if not VarIsNull(rs.Fields[0].Value) then
Name := rs.fields[2].name; // name des AD-Feldes ADUser.(rs.fields[2].name) := rs.fields[2].Value; //Wert des AD-Feldes ... [/QUOTE] Ja aber wofür soll es gut sein, da rs ja alle Daten enthält? Aber was hat das mit TADUser zu tun? Gruß K-H |
AW: dynamisch Records ansprechen
Ich vermute er sucht so etwas:
Delphi-Quellcode:
Sollte ab Delphi 2007 funktionieren.
type
PString = ^String; TADUser = record private function FindField(const AFieldName: string): PString; procedure SetField(const AFieldName, AFieldValue: string); function GetField(const AFieldName: string): string; public cn,name,sn,givenName,displayName: string; property Field[const AFieldName: string]: string read GetField write SetField; default; end; function TADUser.FindField(const AFieldName: string): PString; begin if AnsiSameText(AFieldName, 'givenName') then Result := @givenName else if AnsiSameText(AFieldName, 'displayName') then Result := @displayName else Result := nil; end; procedure TADUser.SetField(const AFieldName, AFieldValue: string); var lField: PString; begin lField := FindField(AFieldName); if Assigned(lField) then lField^ := AFieldValue; end; function TADUser.GetField(const AFieldName: string): string; var lField: PString; begin lField := FindField(AFieldName); if Assigned(lField) then Result := lField^ else Result := ''; end; var ADUser: TADUser; begin ADUser['givenName'] := 'Max Mayer'; end; |
AW: dynamisch Records ansprechen
*autsch* Nun habe ich gerafft, was gewünscht wird... Nun ja, Stichwort ist hier ganz klar RTTI. Interessant wäre hier aber noch zu wissen, welche Delphi-Version du nutzt?
|
AW: dynamisch Records ansprechen
Gefällt!
Wenn das aufgebohrte Record noch nicht zur Verfügung steht, sollte man es eigentlich auch mit einer Klasse hinbekommen. Gruß K-H |
AW: dynamisch Records ansprechen
Hallo,
erst einmal herzlichen Dank für die schnellen antworten! Ich bin relativ neu in Delphi :stupid: und arbeite mit der Version XE2. Zum besseren Verständnis hier noch einmal ein ausführlicherer Code Ausschnitt:
Delphi-Quellcode:
Meine Frage bezieht sich auf die rot geschriebene Zeile:
type TADUser = record
cn,name,sn,givenName,displayName,department,company: String; streetAddress,l,telephoneNumber,userPrincipalName: String; mail,createTimeStamp,objectSid,distinguishedName: String; objectGUID,lastLogon,pwdLastSet,badPasswordTime: String; end; ... var ADUser: TADUser; ... function read_ADFields(OBJECTClass):ADUser; var rs, conn, com: Variant; DOMAIN: String; count: Integer; begin DOMAIN := '''LDAP://dc=xx,dc=xx-xxxxxxxxx,dc=de'''; CoInitialize(nil); try conn := CreateOleObject('ADODB.Connection'); com := CreateOleObject('ADODB.Command'); conn.Provider := 'ADsDSOObject'; conn.open; com.ActiveConnection := conn; Com.CommandText := 'select cn,givenname,displayname,sn from '+Domain+' where objectclass='+''''+OBJECTClass+''''+' and objectclass<>'+'''computer'' ORDER by cn'; com.Properties['Page Size'] := 10; Com.Properties['Timeout'] := 600; Com.Properties['Cache Results'] := False; Com.Properties['Size Limit'] := 200; rs := COm.Execute; count := 0; While Not rs.EOF do begin if not VarIsNull(rs.Fields[0].Value) then begin [COLOR="Red"]ADUser.[B](rs.fields[1].name)[/B] := rs.fields[1].Value;[/COLOR] inc(count,1); end; rs := NULL; finally CoUninitialize; com := NULL; conn.Close; conn := NULL; end; end; Ich definiere ein Record mit dem Namen TADUser und ddefinierten Feldern, die namentlich auch im AD existieren. Nach meiner AD-Abfrage möchte ich innerhalb einer Schleife die Werte aus den AD-Feldern in die zugehörigen Recordfelder schreiben. Wie bringe ich Delphi bei, dass die AD-Werte z.B. aus displayName nach 'ADUser.displayName' geschrieben werden. @Blup Dein Code ist für einen Anfänger wie mich ein verdammt harter Toback! :shock: |
AW: dynamisch Records ansprechen
UUPS!
Innerhalb des Code-Abschnitts gibt es keinen roten und fetten Text! Hier noch einmal die Zeile ohne HTML-Code:
Delphi-Quellcode:
ADUser.(rs.fields[1].name) := rs.fields[1].Value;
|
AW: dynamisch Records ansprechen
Jetz mal ehrlich: als Anfäger würde ich in diesem Fall von der empfohlenen RTTI-Lösung die Finger lassen und das Ganze stracks durchprogrammieren. Du gibst die Reihenfolge der Felder in der Select-Anweisung vor und so kannst du auch die Feldnamen des Records entsprechend zuordnen. Das Ganze mit einem entsprechenden Kommentar versehen ist es auch nach zwei Jahren noch zu verstehen.
Bei der Lösung mit RTTI bekommst du zwar immer die passende Zuordnung der Felder aus der Select-Anweisung zu den Recordfeldern, allerdings sieht man das später auch nicht gleich und es bläht den Code ziemlich auf. Zuätzlich musst du dafür sorgen, daß die Record-Felder immer exakt so heißen, wie die Felder in der AD-Tabelle, was schon mal zu Problemen führen kann oder einfach nur unschön ist (wer nennt ein Record-Feld denn einfach nur "l" oder "cn"). Bei der einfachen Lösung kannst du im Record auch "CommonName" statt "cn" schreiben und "Location" statt einfach nur "l". |
AW: dynamisch Records ansprechen
Zitat:
Ebenso muss dazu gesagt werden, dass potentielle Fehler bei der ausprogrammieren Version auch schon durch den Compiler gefunden werden, also z.B. Schreibfehler, und nicht erst zur Laufzeit. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz