Hoi
Ik heb een probleem in mijn applicatie waarbij de items niet goed geladen worden, of wellicht niet goed opgeruimd.
Ik lees een ';'-seperated bestand in:
Het inlezen gaat prima voor de eerste keer, daarna krijg ik de volgende issues:Code:TestFile.CSV
;Col1,Col2,Col3,Col4,profile
test1a;test1b;test1c;blah1;prof1
test2a;test2b;test2c;blah2;prof2
test3a;test3b;test3c;blah3;prof1
- Toevoegen regel aan TestFile.CSV (middels Edit button, gevolgd door een reload button)
Attachment 8168- Verwijderen regel uit TestFile.CSV (middels Edit button, gevolgd door een reload button)
Attachment 8169- Reload zonder edit zorgt voor extra entries
Attachment 8170
Ik vermoed dat het ergens in de ObjectList mis gaat maar ben er nu al een tijd op aan het puzzelen maar zie niet waar het mis gaat.
Het valt me op dat de OBJ counter in het memo niet dezelfde items aangeeft als wat er in de EasyListview (ELV) staat.
Heb het geheel even in een test applicatie gezet wat het makkelijk reproduceerd.
ZipFile Attachment 8171
Code:unit uTest;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls, MPCommonObjects, EasyListview, System.Contnrs,
System.IOUtils, Winapi.ShlObj, Winapi.ShellAPI;
type
TCSVFileItem = class
private
FCol1 : string;
FCol2 : string;
FCol3 : string;
FCol4 : string;
FProfile : string;
public
property Col1 : string read FCol1;
property Col2 : string read FCol2;
property Col3 : string read FCol3;
property Col4 : string read FCol4;
property Profile : string read FProfile;
end;
TForm1 = class(TForm)
ELV : TEasyListview;
PanelTop : TPanel;
btReload : TSpeedButton;
btEdit : TSpeedButton;
cbProfileFilter : TComboBox;
edFilter : TEdit;
Memo1 : TMemo;
procedure ELVItemGetCaption (Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; var Caption: WideString);
procedure FormCreate (Sender: TObject);
procedure FormDestroy (Sender: TObject);
procedure edFilterChange (Sender: TObject);
procedure btReloadClick (Sender: TObject);
procedure btEditClick (Sender: TObject);
procedure cbProfileFilterChange(Sender: TObject);
private
{ Private declarations }
FCSVFileItemObjList : TObjectList;
FActiveListItems : TList;
FStringListItems : TStringList;
FStringListGroups : TStringList;
public
{ Public declarations }
FCsvFile : string;
procedure AddCSVFileItem (const aCol1, aCol2, aCol3, aCol4, aProfile: string);
procedure ApplyFilter (const aFilter : string; aGroupsItemIndex : integer);
procedure FileOpen;
end;
function GetSpecialFolderPath(CSIDLFolder: Integer): string;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FCsvFile := '.\TestFile.CSV';
FCSVFileItemObjList := TObjectList.Create;
FActiveListItems := TList.Create;
FStringListItems := TStringList.Create;
FStringListGroups := TStringList.Create;
with FStringListGroups do
begin
Sorted := true;
Duplicates := dupIgnore;
end;
FileOpen;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FStringListItems.Free;
FStringListGroups.Free;
FActiveListItems.Free;
FCSVFileItemObjList.Free;
end;
procedure TForm1.ELVItemGetCaption(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; var Caption: WideString);
var
CSVFileItem: TCSVFileItem;
begin
CSVFileItem := FActiveListItems[Item.Index];
case Column of
0: Caption := CSVFileItem.Col1;
1: Caption := CSVFileItem.Col2;
2: Caption := CSVFileItem.Col3;
3: Caption := CSVFileItem.Col4;
4: Caption := CSVFileItem.Profile;
end;
end;
procedure TForm1.AddCSVFileItem(const aCol1, aCol2, aCol3, aCol4, aProfile: string);
var
CSVFileItem: TCSVFileItem;
begin
CSVFileItem := TCSVFileItem.Create;
try
CSVFileItem.FCol1 := aCol1;
CSVFileItem.FCol2 := aCol2;
CSVFileItem.FCol3 := aCol3;
CSVFileItem.FCol4 := aCol4;
CSVFileItem.FProfile := aProfile;
FCSVFileItemObjList.Add(CSVFileItem);
except
CSVFileItem.Free;
end;
end;
procedure TForm1.ApplyFilter(const aFilter : string; aGroupsItemIndex : integer);
var
I: Integer;
begin
ELV.BeginUpdate;
try
ELV.Items.Clear;
FActiveListItems.Clear;
for I := 0 to FCSVFileItemObjList.Count - 1 do
begin
if cbProfileFilter.Items[aGroupsItemIndex] = 'Show All' then
begin
if (aFilter = '')
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col1)) <> 0)
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col2)) <> 0)
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col3)) <> 0)
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col4)) <> 0)
then
FActiveListItems.Add(FCSVFileItemObjList[I]);
end
else
begin
if ((aFilter = '')
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col1)) <> 0)
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col2)) <> 0)
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col3)) <> 0)
or (Pos(UpperCase(aFilter), UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Col4)) <> 0))
and (UpperCase(cbProfileFilter.Items[aGroupsItemIndex]) = UpperCase(TCSVFileItem(FCSVFileItemObjList[I]).Profile)) then
FActiveListItems.Add(FCSVFileItemObjList[I]);
end;
end;
for I := 0 to FActiveListItems.Count -1 do
ELV.Items.AddVirtual;
finally
ELV.EndUpdate;
end;
end;
procedure TForm1.btEditClick(Sender: TObject);
var
ExeFile : string;
begin
ExeFile := IncludeTrailingPathDelimiter(GetSpecialFolderPath(CSIDL_WINDOWS)) + 'notepad.exe';
if TFile.Exists (ExeFile) then
begin
ShellExecute( Handle,
'open',
PChar(ExeFile),
PChar(FCsvFile),
nil,
SW_SHOWNORMAL );
end;
end;
procedure TForm1.btReloadClick(Sender: TObject);
begin
FileOpen;
end;
procedure TForm1.cbProfileFilterChange(Sender: TObject);
begin
ApplyFilter(edFilter.Text, cbProfileFilter.ItemIndex);
end;
procedure TForm1.edFilterChange(Sender: TObject);
begin
ApplyFilter(edFilter.Text, cbProfileFilter.ItemIndex);
end;
procedure TForm1.FileOpen;
var
I : Integer;
S : String;
SArray : TArray<String>;
begin
if TFile.Exists(FCSVFile) then
begin
FStringListItems.LoadFromFile(FCSVFile);
if FStringListItems.Count <> -1 then
begin
ELV.Items.Clear;
FStringListGroups.Clear;
ELV.BeginUpdate;
try
for I := 0 to FStringListItems.Count -1 do
begin
S := FStringListItems[I];
if (not S.StartsWith(';')) AND (not S.IsEmpty) AND
(not S.IsNullOrEmpty(S)) AND (not S.IsNullOrWhiteSpace(S)) then
begin
SArray := S.Split([';']);
if Length(SArray) = ELV.Header.Columns.Count then
begin
AddCSVFileItem (SArray[0], SArray[1], SArray[2], SArray[3], SArray[4]);
ELV.Items.AddVirtual;
FStringListGroups.Add(SArray[4]);
Memo1.Lines.Add(format('ItemCounter=%d | ELV=%d | OBJ=%d | Active=%d ',[I, ELV.Items.Count, FCSVFileItemObjList.Count, FActiveListItems.Count]));
end
else
ShowMessage (format('Invalid line: "%s"',[S]));
end;
end;
finally
ELV.EndUpdate();
end;
Memo1.Lines.Add('================================================================================');
cbProfileFilter.Items := FStringListGroups;
cbProfileFilter.Items.Insert(0, 'Show All');
cbProfileFilter.ItemIndex := 0;
ApplyFilter(edFilter.Text, cbProfileFilter.ItemIndex);
end;
end;
end;
function GetSpecialFolderPath(CSIDLFolder: Integer): string;
var
FilePath: array [0..MAX_PATH] of char;
begin
SHGetFolderPath(0, CSIDLFolder, 0, 0, FilePath);
Result := FilePath;
end;
end.
Ik hoop dat er iemand hier tijd en zin heeft om eens naar mijn geknutsel te kijken en me een zetje in de juiste richting kan geven, want wat ik ook probeer, een echt suc6 wordt het allemaal nog niet.
Alvast bedankt.
Herby