Un caro saluto a tutto il forum, volevo sapere se qualcuno riscontra problemi nell'utilizzo del metodo CustomSort della TStringList.
Poiché il metodo Sort presenta un problema nell'ordinamento (in pratica l'underscore e gli altri caratteri diversi da lettere e numeri, anche se Unicode, vengono ordinati inseriti indicativamente tra la P e la S maiuscola), ho provato ad utilizzare il metodo CustomSort, creando una procedura ad hoc (in modo da poterla poi personalizzare) del tipo:
function TfrmStampeReg.StringListCompareStrings(List: TStringList; Index1,
Index2: Integer): Integer;
begin
Result := AnsiCompareStr (List[Index1], List[Index2]);
end;
oppure:
function TfrmStampeReg.StringListCompareStringsByOrdinalCharacterValue(
List: TStringList; Index1, Index2: Integer): Integer;
var
First: string;
Second: string;
begin
First := List[Index1];
Second := List[Index2];
if List.CaseSensitive then
Result := CompareStr(First, Second)
else
Result := CompareText(First, Second);
end;
oppure anche questa, trovata proprio sul forum di Lazarus:
function TfrmStampeReg.UTF8Compare(List: TStringList; Index1, Index2: Integer
): Integer;
begin
{http://www.lazarus.freepascal.org/index.php?topic=9443.0}
Result:=WideCompareStr(UTF8Decode(List[Index1]),UTF8Decode(List[Index2]));
end;
Le procedure non danno problemi, ma il metodo CustomSort da' sempre errore, sia con che senza @ davanti al nome della procedura, in particolare:
MiaStringList.CustomSort (@NomeProcedura);
da' il seguente errore:
Error: Incompatible type for arg no. 1: Got "<procedure variable type of function(TStringList,LongInt,LongInt):LongInt of object;Register>", expected "<procedure variable type of function(TStringList,LongInt,LongInt):LongInt;Register>"
mentre senza @:
MiaStringList.CustomSort (NomeProcedura);
ritorna l'errore:
Error: Wrong number of parameters specified for call to "NomeProcedura"
Alla fine, visto che il Sort mi crea problemi ed il CustomSort non riesco ad utilizzarlo ho "risolto" intervenendo sul mio codice in modo da bypassare il problema, ma... vorrei capire cosa c'è che non funziona.
Utilizzo Lazarus 0.9.28.2 stable su Debian Squeeze.
Un saluto a tutti,
Stefano
La mia situazione particolare è in un modulo piuttosto complesso che genera dei files e li vuole ordinare per una successiva spedizione via e-mail.
Sulla base della mia situazione provo a scrivere un codice di esempio (basato sull'evento OnClick di un bottone di una form chiamat frmMyForm), ricordarsi di cambiare Chr(13) con Chr(10) per gli utenti Windows.
type
function MySortProcedure(List: TStringList; Index1, Index2: Integer): Integer;
.........
procedure TfrmMyForm.Button1Click(Sender: TObject);
var
MyStringList: TStringList;
k: SmallInt;
S: String;
begin
S := '';
Invio := Chr (13); //Carattere di fine riga per Linux (10 per Windows)
MyStringList := TStringList.Create;
MyStringList.CaseSensitive := True;
MyStringList.Add ('/home/miopath/20_Partitari.pdf');
MyStringList.Add ('/home/miopath/20_BeniAmmortizzabili.pdf');
MyStringList.Add ('/home/miopath/20_CertCompensi.pdf');
MyStringList.Add ('/home/miopath/20_IvaAcquisti.pdf');
MyStringList.Add ('/home/miopath/20_IvaVendite.pdf');
MyStringList.Add ('/home/miopath/20_LiquidazioneIva.pdf');
MyStringList.Add ('/home/miopath/20S_BeniAmmortizzabili.pdf');
MyStringList.Add ('/home/miopath/20_Sit_econfisc.pdf');
MyStringList.Sort;
for k := 0 to (MyStringList.Count - 1) do S := S + MyStringList[k] + Invio;
showmessage ('Metodo Sort: ' + Invio + S);
MyStringList.CustomSort (MySortProcedure); //Qui da' errore
S := '';
for k := 0 to (MyStringList.Count - 1) do S := S + MyStringList[k] + Invio;
showmessage ('Metodo CustomSort: ' + Invio + S);
end;
function TfrmMyForm.MySortProcedure(
List: TStringList; Index1, Index2: Integer): Integer;
var
First: string;
Second: string;
begin
First := List[Index1];
Second := List[Index2];
if List.CaseSensitive then
Result := CompareStr(First, Second)
else
Result := CompareText(First, Second);
end;
Il codice dovrebbe comunque dare errore sul metodo CustomSort, almeno questo è quanto avviene con Lazarus 0.9.28.2 su Debian.
Aspetto le vostre considerazioni...
Ciao,
Stefano
Ha ragione goblin, se uso la chiocciola e dichiaro la funzione fuori dalla mia Form, funziona anche a me. Non deve far parte della classe della TForm.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
function MySortProcedure(List: TStringList; Index1, Index2: Integer): Integer;
var
First: string;
Second: string;
begin
First := List[Index1];
Second := List[Index2];
if List.CaseSensitive then
Result := CompareStr(First, Second)
else
Result := CompareText(First, Second);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyStringList: TStringList;
k: SmallInt;
S: String;
invio: char;
begin
S := '';
Invio := Chr (10); //Carattere di fine riga per Linux (10 per Windows)
MyStringList := TStringList.Create;
MyStringList.CaseSensitive := True;
MyStringList.Add ('/home/miopath/20_Partitari.pdf');
MyStringList.Add ('/home/miopath/20_BeniAmmortizzabili.pdf');
MyStringList.Add ('/home/miopath/20_CertCompensi.pdf');
MyStringList.Add ('/home/miopath/20_IvaAcquisti.pdf');
MyStringList.Add ('/home/miopath/20_IvaVendite.pdf');
MyStringList.Add ('/home/miopath/20_LiquidazioneIva.pdf');
MyStringList.Add ('/home/miopath/20S_BeniAmmortizzabili.pdf');
MyStringList.Add ('/home/miopath/20_Sit_econfisc.pdf');
MyStringList.Sort;
for k := 0 to (MyStringList.Count - 1) do S := S + MyStringList[k] + Invio;
showmessage ('Metodo Sort: ' + Invio + S);
MyStringList.CustomSort (@MySortProcedure); //Qui ci vuole la chiocciolina !!
S := '';
for k := 0 to (MyStringList.Count - 1) do S := S + MyStringList[k] + Invio;
showmessage ('Metodo CustomSort: ' + Invio + S);
end;
end.