Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi dynamisch Records ansprechen (https://www.delphipraxis.net/169654-dynamisch-records-ansprechen.html)

Hackerl 2. Aug 2012 15:10

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:
   type TADUser = record
     cn,name,sn,givenName,displayName: String;
   end;
Bei der Abfrage des AD kann ich folgende Infos ermitteln:
Code:
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;
Statt der Variable 'displayName' möchte ich in die Records 'ADUser.*' in einerhalb einer Schleife schreiben.
In etwa so:
Code:
   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
...
Ist so etwas möglich?

Gruß

s.h.a.r.k 2. Aug 2012 15:19

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.

p80286 2. Aug 2012 15:37

AW: dynamisch Records ansprechen
 
In etwa so:
Code:
   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
...
Ist so etwas möglich?
[/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

Blup 2. Aug 2012 16:41

AW: dynamisch Records ansprechen
 
Ich vermute er sucht so etwas:
Delphi-Quellcode:
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;
Sollte ab Delphi 2007 funktionieren.

s.h.a.r.k 2. Aug 2012 16:44

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?

p80286 2. Aug 2012 16:50

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

Hackerl 3. Aug 2012 07:27

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:
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;
Meine Frage bezieht sich auf die rot geschriebene Zeile:
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:

Hackerl 3. Aug 2012 07:31

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;

Uwe Raabe 3. Aug 2012 08:06

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".

s.h.a.r.k 3. Aug 2012 10:35

AW: dynamisch Records ansprechen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1176783)
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".

Das geht mit der RTTI auch, man muss sich nur zu helfen wissen. Du kannst für jedes Feld ein Attribut führen, um das Mapping zu gewährleisten. Oder du definierst dir eine Config-Datei für sowas. Aber gut, das ist dann auch wieder mit Kanonen auf Spatzen geschossen :stupid:

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 00:35 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz