Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Sortieren im Clientdataset nach ID(autoinc) (https://www.delphipraxis.net/177583-sortieren-im-clientdataset-nach-id-autoinc.html)

Natcree 14. Nov 2013 17:05

Sortieren im Clientdataset nach ID(autoinc)
 
Hallo ich möcht in meinem Clientdataset meine Datensätze nach der ID Nummer aufwärtz sortieren. Die Daten werden in einem DBGrid angezeigt.

Habe mal folgenden Code

Delphi-Quellcode:
var
   IndexName: String;
 begin
   IndexName:= 'ID'+'0';//ID= Spaltenname 0= index
   ClientDataSet1.AddIndex(IndexName, 'ID',[ixDescending],'','',0);
   ClientDataSet1.IndexName:= IndexName;
   clientdataset1.First;
 end;
Funktioniert aber nicht ???

Union 14. Nov 2013 17:23

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Verwende IndexDefs und lies diesen Artikel.

Perlsau 14. Nov 2013 19:03

AW: Sortieren im Clientdataset nach ID(autoinc)
 
... oder trage in IndexFieldNames den Feldnamen ein, nach dem du sortieren möchtest.

Natcree 14. Nov 2013 21:03

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Ich will ja nach dem id count der datensätze sortieren. clientdataset1.fieldbyname['ID'] und das ganze aufwärts.

ID Name Adresse
1 Max musterstrasse
2 Moritz Bleibträu
3 Mia ichhaumichweg
.. .. ..

Den Artikel habe ich mir schon angeschaut hat mir aber nicht weiter geholfen...... .

Union 14. Nov 2013 21:15

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von Natcree (Beitrag 1235978)
Den Artikel habe ich mir schon angeschaut hat mir aber nicht weiter geholfen...... .

Woran liegts? Dort ist genau das beschrieben was Du suchst. Auch noch mit Beispielsource.

Natcree 14. Nov 2013 22:13

AW: Sortieren im Clientdataset nach ID(autoinc)
 
@Union

Danke hast recht XDDD

Delphi-Quellcode:
function SortClientDataSet(ClientDataSet: TClientDataSet;
  const FieldName: String): Boolean;
var
  i: Integer;
  NewIndexName: String;
  IndexOptions: TIndexOptions;
  Field: TField;
begin
Result := False;
Field := ClientDataSet.Fields.FindField(FieldName);
//If invalid field name, exit.
if Field = nil then Exit;
//if invalid field type, exit.
if (Field is TObjectField) or (Field is TBlobField) or
  (Field is TAggregateField) or (Field is TVariantField)
   or (Field is TBinaryField) then Exit;
//Get IndexDefs and IndexName using RTTI
//Ensure IndexDefs is up-to-date
ClientDataSet.IndexDefs.Update;
//If an ascending index is already in use,
//switch to a descending index
if ClientDataSet.IndexName = FieldName + '__IdxA'
then
  begin
    NewIndexName := FieldName + '__IdxD';
    IndexOptions := [ixDescending];
  end
else
  begin
    NewIndexName := FieldName + '__IdxA';
    IndexOptions := [];
  end;
//Look for existing index
for i := 0 to Pred(ClientDataSet.IndexDefs.Count) do
begin
  if ClientDataSet.IndexDefs[i].Name = NewIndexName then
    begin
      Result := True;
      Break
    end; //if
end; // for
//If existing index not found, create one
if not Result then
    begin
      ClientDataSet.AddIndex(NewIndexName,
        FieldName, IndexOptions);
      Result := True;
    end; // if not
//Set the index
ClientDataSet.IndexName := NewIndexName;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
sortclientdataset(clientdataset1,'ID');
end;

Danke das war es

Hansa 15. Nov 2013 12:05

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von Natcree (Beitrag 1235988)
Danke das war es

Mit dem Source da? :shock: Ich liebe es, erst gar nichts von überhaupt zu wissen und dann mit 100 Zeilen abgekupfertem Quelltext zu kommen. :lol:

Nene, Perlsau hat schon gesagt, wie einfach das geht. Bei mir sieht das z. B. so aus :

Delphi-Quellcode:
CDS.IndexFieldNames := 'NR';
Das ClientDataSet hat da eben mehrere Felder und sortiert wird in dem Fall nach NR. Vorher stehen halt noch die Felddefinitionen an der Stelle :

Delphi-Quellcode:
CDS.FieldDefs.Add ('ID', ftInteger, 0, False);
CDS.FieldDefs.Add ('NR', ftInteger, 0, False);
...

Natcree 9. Dez 2013 15:37

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Habe eine Fehlermeldung wenn ich das Programm auf nen anderen Rechner starte

Exception Clientdataset1.Field'ID' not Found.

Hier der Form Create Code

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
MediaPlayer1.Notify := true;
Mediaplayer1.Play;
clientdataset1.LoadFromFile('c:\programme\vereintool\daten\adressen.xml');
TWheelDBGrid(DBGrid1).OnMouseWheel := DBGridMouseWheel;
FormatDateTime('dd.mm.yyyy', now);
pagecontrol1.ActivePageIndex:=0;
pagecontrol2.ActivePageIndex:=0;
ForceDirectories('c:\Programme\Vereintool\Daten\Konten');
ForceDirectories('c:\Programme\Vereintool\Daten\Mitgliedsausweis');
ForceDirectories('c:\Programme\Vereintool\Daten\Schreiben');
ForceDirectories('c:\Programme\Vereintool\Daten\Kassenbuch');
ForceDirectories('c:\Programme\Vereintool\Daten\Kassenbuch\'+FormatDateTime('yyyy', now));
dbcomboBox1.Items.LoadFromFile('c:\Programme\Vereintool\Daten\abteilung.txt') ;
dbcomboBox5.Items.LoadFromFile('c:\Programme\Vereintool\Daten\Funktion.txt') ;
form1.eltreestringgrid1.Cells[0,0]:='01.01'+FormatDateTime('.yyyy', now);
form1.eltreestringgrid1.Cells[4,0]:='0,00 €';
form1.eltreestringgrid1.Cells[6,0]:='Kassenstand vom 31.12. des Vorjahres';
if SysUtils.FileExists('c:\Programme\Vereintool\Daten\Kassenbuch\'+FormatDateTime('yyyy', now)+'\Handkasse '+FormatDateTime('yyyy', now)+'.xls') then
if SysUtils.FileExists('c:\Programme\Vereintool\Daten\Kassenbuch\'+FormatDateTime('yyyy', now)+'\Handkasse '+FormatDateTime('yyyy', now)+' leer.xls')then
DeleteFile('c:\Programme\Vereintool\Daten\Kassenbuch\'+FormatDateTime('yyyy', now)+'\Handkasse '+FormatDateTime('yyyy', now)+' leer.xls');
SaveAsExcelFile1(form1.eltreestringGrid1, 'Tabelle1', 'c:\Programme\Vereintool\Daten\Kassenbuch\'+FormatDateTime('yyyy', now)+'\Handkasse '+FormatDateTime('yyyy', now)+' leer.xls');
Xls_To_StringGrid1(form1.ElTreeStringGrid1,'c:\Programme\Vereintool\Daten\Kassenbuch\'+FormatDateTime('yyyy', now)+'\Handkasse '+FormatDateTime('yyyy', now)+'.xls');
self.ElTreeStringGrid1HeaderColumnClick(sender,0);
end;
Und Form Show

Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
begin
self.DBGrid1TitleClick(nil);
sortclientdataset(Clientdataset1,'ID');// Hier soll das dataset sortiert werden
clientdataset1.first;
end;

Union 9. Dez 2013 15:40

AW: Sortieren im Clientdataset nach ID(autoinc)
 
In welcher Zeile tritt denn der Fehler auf?

Natcree 9. Dez 2013 15:41

AW: Sortieren im Clientdataset nach ID(autoinc)
 
auf meinem rechner nicht nur auf dem Anderem auf dem ich kein delphi habe

DeddyH 9. Dez 2013 15:43

AW: Sortieren im Clientdataset nach ID(autoinc)
 
UndwersollsichdurchdiesenvölligunformatiertenQuell codedurchwühlenohnedieKrisezukriegen?

Union 9. Dez 2013 15:44

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Dann mußt Du entweder remote debuggen oder Du tastest Dich per Logging an den Fehler heran. Existiert überhaupt die cds-Datei? Und eine Anmerkung ab vom Thema: Bilde Dir doch für das aktuelle Jahr eine Variable, dann sparst Du das dauernde FormatDateTime. Und Einrückungen wären auch nicht schlecht ;)

DeddyH 9. Dez 2013 15:46

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Hartkodierte Pfade sind auch noch eine mögliche Fehlerquelle, genau wie der Zugriff auf die benannte Instanz Form1.

himitsu 9. Dez 2013 15:58

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Entweder du baust dir selbst Debug-/Logging-Code ein, welcher beim Kunden zeigt was wo schief läuft
oder man nutzt ein externes System

z.B.
- try-except
- EurekaLog, MadExcept und Co.


Zitat:

Zitat von DeddyH (Beitrag 1239146)
Hartkodierte Pfade sind auch noch eine mögliche Fehlerquelle, genau wie der Zugriff auf die benannte Instanz Form1.

Und dazu noch C:\Programme , worin rumgeschrieben wird.
> http://www.delphipraxis.net/177967-m...speichern.html

Form1 von innerhalb TForm1 aus aufgerufen. => Man kann sich gleich selber (self) fragen, wo man sich befindet, oder man geht erstmal zur globalen Instanz (NSA) und fragt die.

Die etwas grauenhafte Codeformatierung.
[edit] übersehn, daß es schon gesehn wurde "UndwersollsichdurchdiesenvölligunformatiertenQuel lcodedurchwühlenohnedieKrisezukriegen? "
Hab den Quellcode gesehn und verlohr die Lust genauer reinzugucken, aber die Pfade und Form1 stachen noch schnell schmerzhaft ins Auge, bevor ich weggucken konnte.

p80286 9. Dez 2013 16:35

AW: Sortieren im Clientdataset nach ID(autoinc)
 
weil in dieser Datei:
Code:
clientdataset1.LoadFromFile('c:\programme\vereintool\daten\adressen.xml');
das Feld 'ID' nicht definiert wurde!?

Gruß
K-H

Natcree 9. Dez 2013 16:38

AW: Sortieren im Clientdataset nach ID(autoinc)
 
na doch ist definiert. Die datei habe ich auch mit kopiert. wie gesagt bei mir auf dem rechner läuft es ja nur auf dem anderen nicht

DeddyH 9. Dez 2013 16:40

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Wie ist es, wenn Du ein anderes Verzeichnis nimmst (C:\Temp oder so)?

Natcree 9. Dez 2013 16:41

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <DATAPACKET Version="2.0"><METADATA><FIELDS><FIELD attrname="ID" fieldtype="i4" readonly="true" SUBTYPE="Autoinc"/><FIELD attrname="Anrede" fieldtype="string" WIDTH="5"/><FIELD attrname="Vorname" fieldtype="string" WIDTH="30"/><FIELD attrname="Nachname" fieldtype="string" WIDTH="30"/><FIELD attrname="PLZ" fieldtype="string" WIDTH="5"/><FIELD attrname="Ort" fieldtype="string" WIDTH="50"/><FIELD attrname="Strasse" fieldtype="string" WIDTH="50"/><FIELD attrname="Hausnummer" fieldtype="string" WIDTH="5"/><FIELD attrname="Abteilung" fieldtype="string" WIDTH="20"/><FIELD attrname="Geburtsdatum" fieldtype="string" WIDTH="15"/><FIELD attrname="Mitgliedsbeitrag" fieldtype="string" WIDTH="10"/><FIELD attrname="Mahnstufe" fieldtype="string" WIDTH="20"/><FIELD attrname="Telefonnummer" fieldtype="string" WIDTH="30"/><FIELD attrname="Handynummer" fieldtype="string" WIDTH="30"/><FIELD attrname="Email" fieldtype="string" WIDTH="30"/><FIELD attrname="Mitgliedsnummer" fieldtype="string" WIDTH="50"/><FIELD attrname="Beitrag" fieldtype="string" WIDTH="15"/><FIELD fieldname="Gezahlter Beitrag" attrname="Gezahlter_Beitrag" fieldtype="string" WIDTH="15"/><FIELD fieldname="Strasse und Hausnummer" attrname="Strasse_und_Hausnummer" fieldtype="string" WIDTH="50"/><FIELD fieldname="Vorname Nachname" attrname="Vorname_Nachname" fieldtype="string" WIDTH="150"/><FIELD attrname="Passbild" fieldtype="bin.hex" SUBTYPE="Graphics" WIDTH="1"/><FIELD fieldname="Personalausweis neu" attrname="Personalausweis_neu" fieldtype="bin.hex" SUBTYPE="Graphics" WIDTH="1"/><FIELD fieldname="Personalausweis alt" attrname="Personalausweis_alt" fieldtype="bin.hex" SUBTYPE="Graphics" WIDTH="1"/><FIELD fieldname="Führerschein neu" attrname="Führerschein_neu" fieldtype="bin.hex" SUBTYPE="Graphics" WIDTH="1"/><FIELD fieldname="Führerschein alt" attrname="Führerschein_alt" fieldtype="bin.hex" SUBTYPE="Graphics" WIDTH="1"/><FIELD attrname="Funktionen" fieldtype="string" WIDTH="50"/><FIELD fieldname="Mitglied seit" attrname="Mitglied_seit" fieldtype="date"/><FIELD attrname="EWE" fieldtype="string" WIDTH="20"/></FIELDS><PARAMS AUTOINCVALUE="73"/></METADATA>

Natcree 9. Dez 2013 16:42

AW: Sortieren im Clientdataset nach ID(autoinc)
 
für xml datei? ein anderes verzeichnis?
kann es vielleicht sein das ich im oi den filename schon drinne habe und diesen bei creat nochmal lade?

Sir Rufo 9. Dez 2013 16:52

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von Natcree (Beitrag 1239158)
kann es vielleicht sein das ich im oi den filename schon drinne habe

Ja, da schauen wir doch mal auf deinen Bildschirm, das geht bestimmt schneller, als wenn du selber schaust :wall:

Perlsau 9. Dez 2013 17:04

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von Sir Rufo (Beitrag 1239161)
Zitat:

Zitat von Natcree (Beitrag 1239158)
kann es vielleicht sein das ich im oi den filename schon drinne habe

Ja, da schauen wir doch mal auf deinen Bildschirm, das geht bestimmt schneller, als wenn du selber schaust :wall:

Kiffen und Saufen vertragen sich nicht wirklich mit dem Programmieren :drunken:

Natcree 9. Dez 2013 17:09

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Ich brauchte nur Als Admin starten. nun gehts sche... Berechtigungen kann mann das nicht gleich mit in die exe compilieren oder so ?

Natcree 9. Dez 2013 17:10

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Wie recht du hast Perlsau:lol:

DeddyH 9. Dez 2013 17:14

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von Natcree (Beitrag 1239164)
Ich brauchte nur Als Admin starten. nun gehts sche... Berechtigungen kann mann das nicht gleich mit in die exe compilieren oder so ?

Berechtigungen nicht (wäre ja auch noch schöner), aber Du könntest per Manifest dafür sorgen, dass Windows ggf. nach einem Admin-Login fragt. Allerdings: willst Du das wirklich? Deine Daten stehen einfach an der falschen Stelle, pack sie nach APPDATA bzw. COMMONAPPDATA, und gut is.

p80286 9. Dez 2013 17:29

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von DeddyH (Beitrag 1239167)
willst Du das wirklich? Deine Daten stehen einfach an der falschen Stelle, pack sie nach APPDATA bzw. COMMONAPPDATA, und gut is.

abgesehen davon, sollte ein LoadfromFile nicht trotzdem funktionieren?

Gruß
K-H

DeddyH 9. Dez 2013 17:29

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Hätte ich jetzt auch gedacht, aber wer weiß?

Sir Rufo 9. Dez 2013 17:56

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Vermutlich steht im VirtualStore eine Datei mit ohne Daten ;)

himitsu 9. Dez 2013 18:13

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Zitat:

Zitat von DeddyH (Beitrag 1239167)
Zitat:

Zitat von Natcree (Beitrag 1239164)
Ich brauchte nur Als Admin starten. nun gehts sche... Berechtigungen kann mann das nicht gleich mit in die exe compilieren oder so ?

Berechtigungen nicht (wäre ja auch noch schöner), aber Du könntest per Manifest dafür sorgen, dass Windows ggf. nach einem Admin-Login fragt. Allerdings: willst Du das wirklich? Deine Daten stehen einfach an der falschen Stelle, pack sie nach APPDATA bzw. COMMONAPPDATA, und gut is.

Jupp, stattdessen würde ich auch das Programm besser so schreiben, daß es "ordentlich" funktioniert.

- ich darf nicht in das verbotene Verzeichnis schreiben, dann hole ich mir eben die übelsten Adminrechte und mach es dennoch, anstatt da hinzuschreiben, wo ich darf
- ich darf nicht durch die große Chef-Tür in den Speisesaal, also mach ich mich zum Chef, anstatt die kleine Angestelltentür zu nehmen


Man könnte fast Wetten Natcree und alle, wo es geht, arbeiten schön mit Adminrechten?
Tja, selbst Schuld.

Sir Rufo 9. Dez 2013 18:29

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Dabei könnte das Leben so einfach sein
Delphi-Quellcode:

program dp_177583;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  SysUtils,
  TypInfo,
  uAppPath in 'uAppPath.pas';

procedure OutputPath;
  begin
    Writeln( AppPath.Data );
    Writeln( AppPath.Konten );
    Writeln( AppPath.Mitgliedsausweis );
    Writeln( AppPath.Schreiben );
    Writeln( AppPath.Kassenbuch );
    Writeln( AppPath.Handkasse );
  end;

procedure Main;
  var
    LLocation : TAppDataLocation;
  begin
    for LLocation := low( TAppDataLocation ) to high( TAppDataLocation ) do
      begin
        AppPath.Location := LLocation;
        Writeln;
        Writeln( 'AppPath.Location=', GetEnumName( TypeInfo( TAppDataLocation ), Integer( LLocation ) ) );
        Writeln;
        OutputPath;
      end;
  end;

begin
  try

    Main;

  except
    on E : Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;

  ReadLn;

end.
mit
Delphi-Quellcode:
unit uAppPath;

interface

  type
    TAppDataLocation = ( adlUser, adlCommon, adlPortable );

    TAppPath = class
    private
      FLocation : TAppDataLocation;
    public
      function Data : string;
      function Kassenbuch : string; overload;
      function Kassenbuch( const ADate : TDateTime ) : string; overload;
      function Konten : string;
      function Mitgliedsausweis : string;
      function Schreiben : string;
      function Handkasse : string; overload;
      function Handkasse( const ADate : TDateTime ) : string; overload;

      property Location : TAppDataLocation read FLocation write FLocation;
    end;

  function AppPath : TAppPath;

implementation

  uses
    Windows,
    ShellApi,
    ShlObj,
    SysUtils;

  var
    _AppPath : TAppPath;

  function AppPath : TAppPath;
    begin
      if not Assigned( _AppPath )
      then
        begin
          _AppPath := TAppPath.Create;
        end;
      Result := _AppPath;
    end;

  function GetKnownFolder( const FolderID : TGUID ) : string;
    var
      LPath : PChar;
    begin
      if SHGetKnownFolderPath( FolderID, 0, 0, LPath ) >= 0
      then
        Result := LPath
      else
        Result := #0;
    end;

  function GetSpecialFolder( FolderID : longint ) : string;
    var
      Path  : PChar;
      idList : PItemIDList;
    begin
      GetMem( Path, MAX_PATH );
      SHGetSpecialFolderLocation( 0, FolderID, idList );
      SHGetPathFromIDList( idList, Path );
      Result := string( Path );
      FreeMem( Path );
    end;

  function WinVersionMinVista : Boolean;
    begin
      Result := CheckWin32Version( 6, 0 );
    end;

  function UserAppDataFolder : string;
    begin
      if WinVersionMinVista
      then
        Result := GetKnownFolder( StringToGUID( '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}' ) )
      else
        Result := GetSpecialFolder( CSIDL_APPDATA )
    end;

  function CommonAppDataFolder : string;
    begin
      if WinVersionMinVista
      then
        Result := GetKnownFolder( StringToGUID( '{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}' ) )
      else
        Result := GetSpecialFolder( CSIDL_COMMON_APPDATA )
    end;

  { TAppPath }

  function TAppPath.Data : string;
    begin
      case Location of
        adlUser :
          Result := UserAppDataFolder + '\Vereintool\';
        adlCommon :
          Result := CommonAppDataFolder + '\Vereintool\';
        adlPortable :
          Result := ExtractFilePath( ParamStr( 0 ) + 'Daten\' );
      end;
      Result := Result + 'Daten\';
    end;

  function TAppPath.Handkasse( const ADate : TDateTime ) : string;
    begin
      Result := Kassenbuch( ADate ) + FormatDateTime( '"Handkasse "yyyy".xls"', ADate );
    end;

  function TAppPath.Handkasse : string;
    begin
      Result := Handkasse( Now );
    end;

  function TAppPath.Kassenbuch( const ADate : TDateTime ) : string;
    begin
      Result := Data + FormatDateTime( '"Kassenbuch\"yyyy"\"', ADate );
    end;

  function TAppPath.Kassenbuch : string;
    begin
      Result := Kassenbuch( Now );
    end;

  function TAppPath.Konten : string;
    begin
      Result := Data + 'Konten\';
    end;

  function TAppPath.Mitgliedsausweis : string;
    begin
      Result := Data + 'Mitgliedsausweis\';
    end;

  function TAppPath.Schreiben : string;
    begin
      Result := Data + 'Schreiben\';
    end;

initialization

finalization

  FreeAndNil( _AppPath );

end.
bekommt man
Code:

AppPath.Location=adlUser

C:\Users\user123\AppData\Roaming\Vereintool\Daten\
C:\Users\user123\AppData\Roaming\Vereintool\Daten\Konten\
C:\Users\user123\AppData\Roaming\Vereintool\Daten\Mitgliedsausweis\
C:\Users\user123\AppData\Roaming\Vereintool\Daten\Schreiben\
C:\Users\user123\AppData\Roaming\Vereintool\Daten\Kassenbuch\2013\
C:\Users\user123\AppData\Roaming\Vereintool\Daten\Kassenbuch\2013\Handkasse 2013.xls

AppPath.Location=adlCommon

C:\ProgramData\Vereintool\Daten\
C:\ProgramData\Vereintool\Daten\Konten\
C:\ProgramData\Vereintool\Daten\Mitgliedsausweis\
C:\ProgramData\Vereintool\Daten\Schreiben\
C:\ProgramData\Vereintool\Daten\Kassenbuch\2013\
C:\ProgramData\Vereintool\Daten\Kassenbuch\2013\Handkasse 2013.xls

AppPath.Location=adlPortable

C:\Users\user123\Documents\RAD Studio\Projekte\_dp\dp_177583\Win32\Debug\dp_177583.exeDaten\Daten\
C:\Users\user123\Documents\RAD Studio\Projekte\_dp\dp_177583\Win32\Debug\dp_177583.exeDaten\Daten\Konten\
C:\Users\user123\Documents\RAD Studio\Projekte\_dp\dp_177583\Win32\Debug\dp_177583.exeDaten\Daten\Mitgliedsausweis\
C:\Users\user123\Documents\RAD Studio\Projekte\_dp\dp_177583\Win32\Debug\dp_177583.exeDaten\Daten\Schreiben\
C:\Users\user123\Documents\RAD Studio\Projekte\_dp\dp_177583\Win32\Debug\dp_177583.exeDaten\Daten\Kassenbuch\2013\
C:\Users\user123\Documents\RAD Studio\Projekte\_dp\dp_177583\Win32\Debug\dp_177583.exeDaten\Daten\Kassenbuch\2013\Handkasse 2013.xls
Da kann man noch weiter mit spielen ;)

Natcree 9. Dez 2013 18:43

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Danke Das ist aber viel viel code. XD
Ich Danke euch zum tausendstenmal.

BergLoewe 2. Mai 2024 16:58

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Moin,

wenn auch 11 Jahre alt, dieser Tröt war einer, der sich mit Datenbank-Sortieren beschäftigt. Deshalb kram ich den noch mal raus.

Ich habe Interbase XE7, bzw. mir gestern die 2020-Version runtergladen. Diese Entwicklerversion, mit der man wohl kein selbstgemachtes Programm ohne IDE starten kann. Dazu Delphi 11 und da mit FireDac. Nun hab ich mir da was zusammengebastelt, in dem ich mit verscheidenen Tabellen und einder ganzen menge Feldern arbeiten muß. Ich habe die VCL-Komponenten von TMS, da dass DBAdvGrid und mich darüber wiederum nach der Sortiererei erkundigt. Da kommt man über ein Beispielprogramm darauf, dass man -wenn man auf einen Spaltenkopf clickt- das Event abfangen und da reinprgogrammieren kann, dass er sich von zur Entwurfszeit festgelegten Indizes einen raussuchen,den im DataSet unter IndexName eintragen soll. Das funktionierte auch. So habe ich für jedes Feld einen incrementalen und einen decrementalen Index gemacht. Was deren Zahl natürlich mächtig bläht.

Bei einem Index der ersten tabelle, den ich hier ziemlich zuletzt gemacht habe, bringt er mir zur Laufzeit aber eine Fehlermeldung, dass er diesen Index nicht finden könne. Der ist zur Entwurfszeit aber da. Bei der zweiten Tabelle funktioniert von 52 Indizes gleiche mal kein einziger.

Ich wurde auch auf den Gedanken gebracht, die Indizes ohnehin erst zur Laufzeit anzulegen. Nur, das krieg ich trotz punktgenauen Abschreibens von diversen Vorlagen(einmal aus dem TMS-Beispiel und einmal aus diesen Tröt hier) nicht hin. Das Ding kompiliert, zur Laufzeit kann man sich über den Befehl zur Erstellung des Indexes hindebuggen. Aber wenn man den IndexName in das Property IndexName eintragen will, kommt eine Fehlermeldung, der sei nicht zu finden.

Code:
procedure Sort(aField: TField; desc: Boolean);
// create or set clientdataset index on field
var
  ixName: string;
  ixDef: TIndexDef;

    function ExistsIndex(const aName: string): Boolean;
    var
      i: Integer;
    begin
      for i := 0 to Form2.AccStatesTable.IndexDefs.Count - 1 do begin
        if Form2.AccStatesTable.IndexDefs[i].Name = aName then begin
          Result := True;
          Exit;
        end;
      end;
      Result := False;
    end;

begin
  ixName := aField.FieldName + '_IX';
  if desc then
    ixName := ixName + '_D';

  // if index exists switch to that index
  if not ExistsIndex(ixName) then
  begin
    if desc then
      Form2.AccStatesTable.AddIndex('',aField.Name,'',[],ixName,'',False)
    else
      Form2.AccStatesTable.AddIndex(ixName,aField.Name,'',[],'','',False);
==>> hier kommt der Fehler:   Form2.AccStatesTable.IndexName := ixName;
    Form2.AccStatesTable.First;
  end
  else
  begin
    Form2.AccStatesTable.IndexName := ixName;
    Form2.AccStatesTable.First;
  end;

end;
Die TMS-Variante wäre:

Code:
procedure SwitchBiolifeIndex(aField: TField; desc: Boolean);
// create or set clientdataset index on field
var
  ixName: string;
  ixDef: TIndexDef;

    function ExistsIndex(const aName: string): Boolean;
    var
      i: Integer;
    begin
      for i := 0 to Form2.AccStatesTable.IndexDefs.Count - 1 do begin
        if Form2.AccStatesTable.IndexDefs[i].Name = aName then begin
          Result := True;
          Exit;
        end;
      end;
      Result := False;
    end;

begin
  ixName := aField.FieldName + '_IX';
  if desc then
    ixName := ixName + '_D';

  // if index exists switch to that index
  if not ExistsIndex(ixName) then
  begin
    ixDef := Form2.AccStatesTable.IndexDefs.AddIndexDef;
    ixDef.Fields := aField.FieldName;
    ixDef.Name := ixName;
    if desc then
      ixDef.DescFields := aField.FieldName;}
  end;
  Form2.AccStatesTable.IndexName := ixName;
  Form2.AccStatesTable.First;
end;
Hier kommt dann der gleiche Fehler auch wieder bei
Code:
Form2.AccStatesTable.IndexName := ixName;
Kann das erstens sein, dass diese Entwicklerversion von Interbase nur eine bestimmte Anzahl von Indizes zuläßt?
Wieso bringt mir das Ding weder bei
Code:
ixDef := Form2.AccStatesTable.IndexDefs.AddIndexDef;
, noch bei
Code:
Form2.AccStatesTable.AddIndex('',aField.Name,'',[],ixName,'',False)
weder Fehlermeldung noch Ergebnis?

ergeka 2. Mai 2024 17:52

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Müsste die ClientDataSet Variante nicht so aussehen?
Delphi-Quellcode:
if desc then
  Form2.AccStatesTable.AddIndex(ixName,'',[],aField.Name,'',False)
else
  Form2.AccStatesTable.AddIndex(ixName,aField.Name,'',[],'','',False);
Der 1. Parameter ist der Name des Indexes.
Der 2. die Liste der Ascending Fields.
Der 4. die Liste der Descending Fields.

https://docwiki.embarcadero.com/Libr...taSet.AddIndex


Gruß

Ralf

BergLoewe 4. Mai 2024 09:12

AW: Sortieren im Clientdataset nach ID(autoinc)
 
Nee, das ist leider auch nicht richtig. Der DataSet ist eine TFDQuery und für diese wäre das hier zuständig.

https://docwiki.embarcadero.com/Libr...taSet.AddIndex

Nun ist es aber komischerweise generell so, dass ich -egal, was und wie- nur Indizes verwenden kann, die ich vor Tagen zur Entwurfszeit angelegt hatte. Lösch ich einen, nimmt der den zur Laufzeit nicht mehr. Wie verhext.
Wenn ich zur Laufzeit einen Index anlege, macht Delphi das zwar. Ich kann mir den IndexCount anzeigen lassen und sehe, wie der sich erhöht. Aber es läßt sich ein solcher Indesx nicht in das Property IndexName eintragen. Dann kommt die Fehlermeldung, er fände den nicht. Gleiches geschieht mit Indizes, die ich zur Entwurfszeit anlege. Die will der weder zur Entwurfszeit, noch zur Laufzeit finden, obwohl sie definitiv vereinbart sind.

Es ist nochwas anderes komisch: Wenn ich zur Entwurfszeit einen Index anlege und die Option 'soDescendig' setze, hat das mal funktioniert. Setze ich im Code aber ein 'soDescending' in die entsprechende eckige Klammer, will der Compiler die Bezeichnung soDescending nicht kennen und meckert "inkompatible Typen 'TFDSortOptions' und 'Set'" an. Nun hab ich gegoogelt, unter TFDSortOptions findet man wirklich 'soDescending' etc..

Irgendwie ist hier vollständig der Wurm drin.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:37 Uhr.

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