Newsgroup: it.comp.lang.delphi
Titolo: misteri di excelworksheet

Ho trovato il sistema per trasportare un astringgrid in excel.. attreverso i
server di D% standard...
il problema si presenta quando le righe superano le 3900 unità..
La procedura si blocca e devo resettare tutto.
Posto la procedura.. forse saràutile ad altri..
Vi sarei grato se mi indicaste come fare per fissare il numero delle righe
al massimo possibile
PROCeDURE tquadro1.ESPORTASTRINGGRIDINEXCEL(SG:tstringgrid);
  var lcid:integer;
    Row: integer;
    ColumnTitles: olevariant;
    x,y:integer;
    invert:boolean;
begin
  lcid := GetUserDefaultLCID;
  ExcelApplication1.Visible[lcid]:=True;
  // connetto ad un workbook un foglio di lavoro
excelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.Add(TOleEnum(xlWBATWork
sheet), lcid));
  excelworksheet1.ConnectTo(excelWorkbook1.Worksheets[1] as _Worksheet);
 
excelworksheet1.name
 := 'Dati';
  ExcelApplication1.ScreenUpdating[lcid] := true;
  screen.cursor:=crhourglass;
  try
    invert:=sg.colcount>255;// siccome non può superare le 255 colonne lo
inverto
    // riempio le celle
    for x:= 1 to sg.colcount-1 do
    for y:= 1 to sg.rowcount-1 do
     if invert then    // inverto righe e colonne se necessario
     excelworksheet1.Cells.Item[x, y].Value :=sg.cells[x-1,y-1]
     else
     excelworksheet1.Cells.Item[y, x].Value :=sg.cells[x-1,y-1];
  finally // disconnetto
  ExcelApplication1.ScreenUpdating[lcid] := True;
  excelworksheet1.Disconnect;
  excelworkbook1.Disconnect;
  ExcelApplication1.Disconnect;
end;
screen.cursor:=crdefault;
  end;

  ExcelApplication1.Visible[lcid]:=True;
Questo "true" rallenta di TANTISSIMO le operazioni.
In pratica è come se ad ogni inserimento il foglio xls debba essere
ridisegnato. Se lo metti a false, aumenti le performance di brutto. :-)
Poi, io la riscriverei grosso modo cosi:
type
  TExcelCallback = procedure(sender: TObject, const ARow, ACol:
integer; var ABreak: boolean) of object;
PROCeDURE tquadro1.ESPORTASTRINGGRIDINEXCEL(
  const ACallBackLimit: integer;
  SG:tstringgrid;
  ACallback: TExcelCallBack;
  var lcid:integer;
    Row: integer;
    ColumnTitles: olevariant;
    x,y:integer;
    invert:boolean;
    CallBackCounter: integer;
     StopFlag: boolean;
begin
  CallBackCounter := 0;
  lcid := GetUserDefaultLCID;
  ExcelApplication1.Visible[lcid]:=FALSE;
  // connetto ad un workbook un foglio di lavoro
excelWorkbook1.ConnectTo(ExcelApplication1.Workbooks.Add(TOleEnum(xlWBATWork
sheet), lcid));
  excelworksheet1.ConnectTo(excelWorkbook1.Worksheets[1] as
_Worksheet);
 
excelworksheet1.name
 := 'Dati';
  ExcelApplication1.ScreenUpdating[lcid] := true;
  screen.cursor:=crhourglass;
  try
    invert:=sg.colcount>255;// siccome non può superare le 255 colonne
lo
inverto
    // riempio le celle
    for x:= 1 to sg.colcount-1 do
    begin
        StopFlag := false;
        INC(CALLBACKCOUNTER);
        IF (CALLBACKCOUNTER > ACALLBACKLIMIT ) AND
                 (ASSIGNED(ACALLBACK)) THEN
        BEGIN
            CallBackCounter := 0;
           ACallBack(Self, x, y,  StopFlag);
         end;
        if StopFlag then
        begin
              // esce da tutto!
        end;
         for y:= 1 to sg.rowcount-1 do
...
Nella callback puoi mettere una Application.ProcessMessages (magari si
inkazza xche restano troppe cose in coda...), l'aggiornamento di
qualche progressbar per mostrare lo stato di avanzamento della
operazione, etc etc etc
Infine, xche la riassegnazione del cursore a crDefault è fuori del
blocco finally? :-/
AS

  ExcelApplication1.Visible[lcid]:=True;
Questo "true" rallenta di TANTISSIMO le operazioni.
In pratica è come se ad ogni inserimento il foglio xls debba essere
ridisegnato. Se lo metti a false, aumenti le performance di brutto. :-)
in effetti è vero, l'avevo messo così per rendermi conto direttamente del
processo.
Poi, io la riscriverei grosso modo cosi:
type
  TExcelCallback = procedure(sender: TObject, const ARow, ACol:
integer; var ABreak: boolean) of object;
questa procedura.. consente di inserire colonne fino al limite consentito..
però il problema è che non tutte le colonne verrebbero inserite e quindi
l'utente potrebbe essere tratto in inganno: potrebbe pensare che
l'operazione è andata a buon fine quando non è vero.
Comunque, dico la verità, non ho ben capito come funziona. Per esempio la
chiamata della procedura da unit esterne prevede il parametro"ACallback:
TExcelCallBack" definito a livello globale.
Almeno credo!






    // riempio le celle



...


ops.. onerror ... :)
Il problema da risolvere è far in modo che le righe da inserire possano
superare il limite di 3900
Le colonne sonoi al massimo 255, ma le righe potrebbero superare ogni
limite... il fatto è che fino a 3000 le inserisce, ma poi si blocca.
Dopo avere resettato (CRTL+ALT+CANC TERMINA OPERAZIONE EXCEL) il compilatore
mi dà:
eolesyserror: chiamata a procedura remota non riuscita
Ho provato a mettere un processmessages all'interno dei cicli for... ma
peggiora la situazione
vabbè..
Grazie comunque, Ciao!

1) la callback è un puntatore ad un metodo.
2) ovviamente, deve essere visibile alle entita che nella tua app la
usano
3) butta via qeui server e vai a mano di ole automation.
Ho scritto circa 20.000 righe su excel e non si è mai bloccato, usando
questa tecnica.
AS

 ha scritto nel messaggio
news:1123833169.3...@g49g2000cwa.googlegroups.com...

mica mi puoi dare un link ove trovare i file di help per le ole automation?
Il mio D5 standard non ce l'ha!
Grazie!

 Il mio D5 standard non ce l'ha!
Rifletti bene...
A te serve l'ole automation non di DELPHI, ma di Microsoft Office...
Giusto?
Ora, spero che tu non sia uno di quelli che, quando installa office, non 
  usa un setup custom.....
AS