Entwickler-Ecke

Sonstiges (Delphi) - Problem mit einer Stringsortierroutine II


davidgippner - Mo 23.01.06 19:39
Titel: Problem mit einer Stringsortierroutine II
Hallo an alle!
Die folgende Stringsortierroutine soll aus einer Datei eingelesene Daten nach Benutzern sortieren und die Seiten und Kosten zusammenrechnen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure TForm1.Zusammen(satz: integer);
begin
{ Stringsortierroutine}
i:=1// Zähler rücksetzen
for i:=1 to n do 
begin
  for j:=1 to n do
    if user[i]=addiert[j].zuser then 
    begin
      addiert[j].zpages:=InttoStr(StrtoInt(pages[i])+StrtoInt(addiert[j].zpages));
      addiert[j].zcost:=FloattoStr(StrtoInt(addiert[j].zpages)*0.02)+' €';
    end else 
    begin
      if ub<>1 then begin
        addiert[ub+1].zuser:=user[i];
        addiert[ub+1].zpages:=pages[i];
        addiert[ub+1].zcost:=cost[i];
      end else 
      begin
        addiert[ub].zuser:=user[i];
        addiert[ub].zpages:=pages[i];
        addiert[ub].zcost:=cost[i];
        ub:=ub+1;
      end;
    end;
end;
end;

Das Problem ist nur: es wird nicht alles ausgelesen. Wo könnte mein Denkfehler liegen?
Danke für alle Hilfe im Voraus!

David

Moderiert von user profile iconGausi: Code neu formatiert durch entfernen einer ganzen Menge Leerzeichen


Martin1966 - Mi 25.01.06 11:19

Hallo! :wink2:

Es wäre besonders hilfreich wenn Du mal die Variablen erklären würdest. Also was bedeutet Variable N, user und addiert. Und vor allem auch wie diese Definiert sind.

Ansonsten können wir dir kaum helfen. ;-)

Lg Martin


davidgippner - Fr 27.01.06 13:17

n ist die Anzahl der eingelesenen Datensätze
addiert ist ein array of record
mit zuser,zpages,zcost als String-Variablen
user,pages sind die String-Variablen die eingelesen werden aus einer Druck-Logdatei.


Horst_H - Fr 27.01.06 14:19

Hallo,
Was soll dieser Teil machen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
//ub =???? -> soll neuer User eingetragen werden?
//dann sollte immer ein ub:= ub+ 1 eingbaut sein
  else
    begin   
      if ub<>1 then begin   
        addiert[ub+1].zuser:=user[i];   
        addiert[ub+1].zpages:=pages[i];   
        addiert[ub+1].zcost:=cost[i];   
      end else    
      begin   
        addiert[ub].zuser:=user[i];   
        addiert[ub].zpages:=pages[i];   
        addiert[ub].zcost:=cost[i];   
        ub:=ub+1;   
      end;   
    end;


Und warum soll es soviele user wie log-Datei Zeilen geben.
Beide Schleifen von 1 bis n (= DatensatzZahl oder UserZahl)
ub =???? -> soll neuer User eingetragen werden?

Du solltest Dir mal jeden Abschnitt mit Worten zu beschreiben versuchen.
Das ist etwas undurchsichtig, worum es Dir dabei geht.

Gruss Horst


davidgippner - Di 07.02.06 20:24
Titel: Nach längerer Abwesenheit wieder da, jetzt ein neues Problem
Nach längerer Pause habe ich nun wieder weitergemacht und mein Programm von Grund auf neu strukturiert.
Es funktionierte alles, solange ich mehr als einen Datensatz hatte. Nun stürzt das Programm jedesmal beim Erstellen eines Berichtes ab.

Ich bitte um sachdienliche Hinweise, woran das liegen könnte; zur Übersichtlichkeit habe ich hier den gesamten Code meines MainForm mitgegeben. Es ist leider etwas lang, das kann man nicht ändern.

Danke schon mal für jegliche Mithilfe!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
unit vigilimpmain;

interface

uses Windows, SysUtils, Printers, Winspool, Typinfo, Classes, Graphics, Forms,
  Controls, Menus, StdCtrls, Dialogs, Buttons, Messages, ExtCtrls, ComCtrls,
  StdActns, ActnList, ToolWin, ImgList, PBPrintersmonitorU, CoolTrayIcon;

type
  TSDIAppForm = class(TForm)
    ToolBar1: TToolBar;
    StatusBar: TStatusBar;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    FileExitItem: TMenuItem;
    Help1: TMenuItem;
    HelpAboutItem: TMenuItem;
    CoolTrayIcon1: TCoolTrayIcon;
    CheckBox1: TCheckBox;
    PopupMenu1: TPopupMenu;
    Fensterzeigen1: TMenuItem;
    Label1: TLabel;
    Label2: TLabel;
    Hilfe1: TMenuItem;
    Bericht1: TMenuItem;
    erstellen1: TMenuItem;
    drucken1: TMenuItem;
    Memo1: TMemo;
    ListView1: TListView;
    RichEdit1: TRichEdit;
    Admin1: TMenuItem;
    procedure HelpAboutItemClick(Sender: TObject);
    procedure Admin1Click(Sender: TObject);
    procedure drucken1Click(Sender: TObject);
    procedure erstellen1Click(Sender: TObject);
    procedure Fensterzeigen1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure WMQueryEndSession(var Message: TMessage);
    procedure positionieren(datensatz: integer);
  private
    { Private-Deklarationen }
    FMonitor: TPBPrintersMonitor;
    formShowed: boolean;
    SessionEnding: boolean;
    FMonitorAlreadyRunning: Boolean;
    procedure JobNotification( const jobinfo: TPBJobInformation);
  public
    { Public-Deklarationen }
  end;
Type
Druckauftrag = record  {wird benötigt für Dateioperationen sowie Auslese}
   user: string[25]; {Druckender User}
   pn: integer;      {Seiten des Druckauftrages}
end;

var
  SDIAppForm: TSDIAppForm;
  erstellen: boolean;
  jobident: integer;
  Counter: integer;
  Datei: file of Druckauftrag;
  aktdatensatz,sortdata: array[0..300of Druckauftrag;
const
  WM_TASKBAREVENT = WM_USER + 1;
implementation

uses about, vigilimpadmin;

{$R *.dfm}

procedure TSDIAppForm.WMQueryEndSession(var Message: TMessage);
begin
  SessionEnding := True;
  Message.Result := 1;
end;

procedure TSDIAppForm.JobNotification(const jobinfo: TPBJobInformation);
var
  Kopien,Seiten: integer;
  Datei: file of Druckauftrag;
  Satz: Druckauftrag;

begin
  jobident:=0;
  Try
    // Druckjobinfo: Codeteile von Dr. Peter Below
    if GetEnumName( Typeinfo( TPBJobStatus), Ord( jobinfo.Status))='jsCompleted' then begin //nur reagieren wenn Job fertig abgearbeitet!
      ShowMessage(jobinfo.user+' '+InttoStr(jobinfo.TotalPages));
      if jobident<>jobinfo.JobID then begin
      jobident:=jobinfo.JobID;
       if jobinfo.Copies = 0 then Kopien:=1 else Kopien:=jobinfo.Copies;
      Seiten:=Kopien*jobinfo.TotalPages;
      Label1.caption:='Letzter druckender User: '+jobinfo.user;
      Label2.caption:='Seiten: '+InttoStr(Seiten);
      Satz.user:=jobinfo.user;
      Satz.pn:=Seiten;
      AssignFile(Datei,'C:\report.dat');
      if not fileexists('C:\report.dat'then Rewrite(Datei) else Reset(Datei);
      Seek(Datei,Filesize(Datei));
      Write(Datei,Satz);
      Closefile(Datei);
      end;
  end;
  Finally
  End{ Finally }

end;

procedure TSDIAppForm.FormCreate(Sender: TObject);
begin
  // Druckmonitor starten
  FMonitor:= TPBPrintersMonitor.Create( self );
  FMonitor.OnNewJob := JobNotification;
  FMonitor.OnJobChange := JobNotification;
  FMonitor.OnJobComplete := JobNotification;
  FMonitor.Active := true;
  FMonitorAlreadyRunning := true;
end;

procedure TSDIAppForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := ((not CheckBox1.Checked) or SessionEnding);
  if not CanClose then
  begin
    CoolTrayIcon1.HideMainForm;
    CoolTrayIcon1.IconVisible := True;
  end;
end;

procedure TSDIAppForm.Fensterzeigen1Click(Sender: TObject);
begin
 CoolTrayIcon1.ShowMainForm;
 formshowed:=true;
end;

procedure TSDIAppForm.erstellen1Click(Sender: TObject);
var
i,n: integer;
item: TListItem;
begin
  for i:=0 to 300 do begin
   sortdata[i].user:='';
   sortdata[i].pn:=0;
   end;
  Listview1.Items.Clear;
  AssignFile(Datei,'C:\report.dat');
  Reset(Datei);
  {hier geht das Sortier-Gewürge los - und hierin liegt auch der Hund begraben,
  meine ich}

  Listview1.items.BeginUpdate;
  for i:=0 to FileSize(Datei) do begin
    positionieren(i);
    item:= listview1.Items.Add;
    if aktdatensatz[i].user<>'' then begin item.Caption:=aktdatensatz[i].user;
    item.SubItems.Add(InttoStr(aktdatensatz[i].pn));
    end;
    end;
  ListView1.SortType:=stText;
  ListView1.Items.EndUpdate;
  n:=1;
  sortdata[n].user:=ListView1.Items[n].Caption;
  sortdata[n].pn:=StrToInt(ListView1.Items[n].SubItems.Strings[0]);
  if ListView1.Items.Count>2 then for i:=2 to ListView1.Items.Count do begin
  if Listview1.Items[i].Caption=sortdata[n].user then
             sortdata[n].pn:=sortdata[n].pn+StrToInt(ListView1.Items[i].SubItems.Strings[0])
                                                    else begin
             inc(n);
             sortdata[n].user:=ListView1.Items[i].Caption;
             sortdata[n].pn:=StrToInt(ListView1.Items[i].SubItems.Strings[0]);
                                                    end;
                                       end;
  Memo1.lines.beginupdate;
  Memo1.lines.clear;
  for i:=0 to n do
    if sortdata[i].user<>'' then Memo1.lines.add('User: '+sortdata[i].user+', Seiten: '+InttoStr(sortdata[i].pn)+
                                                 ', Kosten: '+Floattostr(0.03*sortdata[i].pn)+' €.');
  Memo1.lines.endupdate;
  Richedit1.lines.beginupdate;
  Richedit1.lines.clear;
  Richedit1.Lines.Add('Druckerkostenabrechnung vom '+DatetoStr(date));
  Richedit1.Lines.Add('');
  for i:=0 to n do
    if sortdata[i].user<>'' then Richedit1.lines.add('User: '+sortdata[i].user+', Seiten: '+InttoStr(sortdata[i].pn)+
                                                 ', Kosten: '+Floattostr(0.03*sortdata[i].pn)+' €.');
  Richedit1.lines.endupdate;
  Closefile(Datei);
  erstellen:=true;
end;
procedure TSDIAppForm.positionieren(datensatz: integer);
begin
  if (datensatz<0or (datensatz>=FileSize(Datei)) then exit
  else begin
    seek(Datei, datensatz);
    read(Datei, aktdatensatz[datensatz]);
  end;
end;
procedure TSDIAppForm.drucken1Click(Sender: TObject);
begin
  if erstellen=true then Richedit1.Print('VigilImp 0.2');
  
end;

procedure TSDIAppForm.Admin1Click(Sender: TObject);
begin
 PasswordDlg.ShowModal;
  if PasswordDlg.Password.Text='catholica' then Bericht1.enabled:=true
  else ShowMessage('Passwort falsch!');
end;
procedure TSDIAppForm.HelpAboutItemClick(Sender: TObject);
begin
 Aboutbox.ShowModal;
end;

end.


davidgippner - Mi 22.02.06 04:52

hab eben neuen Code reingestellt. Danke für alles bisher!


davidgippner - Fr 24.02.06 12:45

Problem ist gelöst: mit der Zeile:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
procedure TSDIAppForm.erstellen1Click(Sender: TObject);
var
//sortdata ist ein Record vom Typ Druckauftrag, das mit user(string[25]) und pn(Integer) definiert ist.
//Datei ist eine Datei dieses Records Druckauftrag
i,n,gesp: integer;
item: TListItem;
begin
  gesp:=0;
  for i:=0 to 300 do begin
   sortdata[i].user:='';
   sortdata[i].pn:=0;
   end;
  Listview1.Items.Clear;
  AssignFile(Datei,'C:\report.dat');
  Reset(Datei);
  Listview1.items.BeginUpdate;
  for i:=0 to FileSize(Datei) do begin
    positionieren(i);

    if aktdatensatz[i].user<>'' then begin
    item:=listview1.Items.Add;
    item.Caption:=aktdatensatz[i].user;
    item.SubItems.Add(InttoStr(aktdatensatz[i].pn));
    end;
    end;
  ListView1.SortType:=stText;
  ListView1.Items.EndUpdate;
  n:=0;
  sortdata[n].user:=ListView1.Items[n].Caption;
  sortdata[n].pn:=StrToInt(ListView1.Items[n].SubItems.Strings[0]);
  //so funktioniert es immer..
  for i:=1 to ListView1.Items.Count-1 do begin
  if Listview1.Items[i].Caption=sortdata[n].user then
             sortdata[n].pn:=sortdata[n].pn+StrToInt(ListView1.Items[i].SubItems.Strings[0])
                                                    else begin
             inc(n);
             sortdata[n].user:=ListView1.Items[i].Caption;
             sortdata[n].pn:=StrToInt(ListView1.Items[i].SubItems.Strings[0]);
                                                    end;
                                       end;
  Memo1.lines.beginupdate;
  Memo1.lines.clear;
  for i:=0 to n do
    if sortdata[i].user<>'' then Memo1.lines.add('User: '+sortdata[i].user+', Seiten: '+InttoStr(sortdata[i].pn)+
                                                 ', Kosten: '+Floattostr(0.03*sortdata[i].pn)+' €.');
  Memo1.lines.endupdate;
  Richedit1.lines.beginupdate;
  Richedit1.lines.clear;
  Richedit1.Lines.Add('Druckerkostenabrechnung vom '+DatetoStr(date));
  Richedit1.Lines.Add('');
  for i:=0 to n do
    if sortdata[i].user<>'' then Richedit1.lines.add('User: '+sortdata[i].user+', Seiten: '+InttoStr(sortdata[i].pn)+
                                                 ', Kosten: '+Floattostr(0.03*sortdata[i].pn)+' €.');
  for i:=0 to n do gesp:=gesp+sortdata[i].pn;
  Richedit1.Lines.add('');
  Richedit1.Lines.Add('Gesamt gedruckte Seiten: '+InttoStr(gesp)+', gesamte Kosten: '+Floattostr(0.03*gesp)+' €.');
  Richedit1.lines.endupdate;
  Closefile(Datei);
        if SetFileAttributes('C:\report.dat', FILE_ATTRIBUTE_HIDDEN) then begin end;
  erstellen:=true;
end;