IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Remplissage feuille excel à partir d'un dbGrid


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 15
    Points
    15
    Par défaut Remplissage feuille excel à partir d'un dbGrid
    Bonjour,
    Je dois dans mon application remplir une feuille excel à partir des données d'un dbGrid, mon code marche mais est cependant relativement lent, quelqu'un aurait-il une idée pour l'accelerer?
    Merci davance

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        numLigne:=0;
        while not dbResultat.DataSource.DataSet.eof do
          begin
            inc(numLigne);
            for numCol:=0 to dbResultat.FieldCount-1 do
              begin
                MaFeuille.Cells.Item[numLigne,numCol+1].Value:=dbResultat.Fields[i].AsString;
              end;
            dbResultat.DataSource.DataSet.next;
          end;

  2. #2
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Je suis un peu dans le même cas,
    j'ai trouvé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ExcelApplication.ScreenUpdating[ lcid ] := False / True
    J'ai gagné 20% dans le remplissage d'une grille mais bon, c'est pas faramineux.

    Je suis preneur d'une solution meilleure

  3. #3
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 15
    Points
    15
    Par défaut
    C'est bon j'ai fini par trouver une solution satisfaisante, avec un datagrid de 13 colonnes et de 3000 tuples je mettais avant pratiquement 4 minutes (sur un vieux p3 900, 512ram), avec cet algo je met 4secondes, le gain n'est pa négligeable .
    L'astuce est de remplir une AnsiString avec le contenu du dbGrid, chaque champs est ajouté,suivi d'une tabulation, à chaque fin de ligne on place un retour chariot.
    Une fois la AnsiString remplie il ne reste plus qu'à la coller dans le fichier excel.
    Des commentaires et critiques seraient les bienvenues

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
     
    var
      ExcelApplication1: TExcelApplication;
      MonClasseur : _workbook;
      MaFeuille :_Worksheet;
      i,j,LCID:integer;
      ligne:AnsiString;//contiendra toutes les données
      destination,liens:Olevariant;//pour la methode 'paste'
    begin
      try
        Screen.Cursor :=crHourGlass;
        lcid := GetUserDefaultLCID;
        ExcelApplication1 := TExcelApplication.create(self);
        ExcelApplication1.Connect;
        MonClasseur := ExcelApplication1.Workbooks.Open(fichierIni.fichierMemIni.ReadString(nomSection,'DEST',''),False,False,
        EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam,
        EmptyParam,EmptyParam,EmptyParam,0);
     
        ExcelApplication1.visible[LCID]:=false;
        MaFeuille:=MonClasseur.Worksheets[1] as _worksheet;
        dbResultat.DataSource.DataSet.DisableControls;
        dbResultat.DataSource.DataSet.First;
        //copie des entetes
        for i := 0 to dbResultat.FieldCount - 1 do
          begin
            if dbResultat.Fields[i].Visible then
              begin
                ligne := ligne + dbResultat.Fields[i].DisplayLabel;
                if i <> dbResultat.FieldCount - 1 then
                  begin
                    ligne := ligne  + #9;
                  end;
              end;
          end;
        ligne := ligne + #13;
        j:=0;
        //copie du contenu
        while not dbResultat.DataSource.DataSet.eof do
        begin
          inc(j);
          for i:=0 to dbResultat.FieldCount-1 do
            begin
              ligne:= ligne + dbResultat.Fields[i].Text;
                if i <> dbResultat.FieldCount - 1 then
                  begin
                    ligne := ligne+ #9;//tab
                  end;
            end;
          ligne := ligne+ #13;//retour chariot
          dbResultat.DataSource.DataSet.next;//ligne suivante
        end;
        Clipboard.SetTextBuf(PChar(ligne));//copie ds la cache
        MaFeuille.Cells.Item[1, 1].Select;
        //pour la methode paste
        //mesLettres est une TstringList qui contient les lettres de l'alphabet
        destination:= MaFeuille.Range['A1',mesLettres[dbResultat.FieldCount-1] + inttostr(j)];
        liens :=false;
        MaFeuille.Paste(destination,liens,LCID);
        //on vide le cache
        Clipboard.Clear;
        dbResultat.DataSource.DataSet.EnableControls;
        dbResultat.DataSource.DataSet.First;
        MonClasseur.Close(True, emptyparam,emptyparam,0);
      finally
        ExcelApplication1.Disconnect;
        Screen.Cursor :=crDefault;
      end;
        ShowMessage('Exportation terminé');
    end;

  4. #4
    Membre à l'essai
    Inscrit en
    Février 2006
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Février 2006
    Messages : 20
    Points : 15
    Points
    15
    Par défaut
    Cette ligne est mauvaise :
    destination:= MaFeuille.Range['A1',mesLettres[dbResultat.FieldCount-1] + inttostr(j)];

    Correction :l'alphabet
    destination:= MaFeuille.Range['A1',mesLettres[dbResultat.FieldCount-1] + inttostr(j+1)]; //car il y a la ligne des entètes.

  5. #5
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    Merci

    Mais en fait, tout ca je l'ai déjà

    Je disable les controls à chaque fois que je fais un parcours.

    L'export via le presse-papier je l'ai déjà et c'est effectivement très rapide.

    Mais l'écriture cellule par cellule est interessante pour reprendre le style, couleur, changer de position etc...
    et c'est donc définitvement lent

    Merci pour l'info de toute manière !

  6. #6
    Membre actif

    Profil pro
    Personnel
    Inscrit en
    Septembre 2003
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France, Meuse (Lorraine)

    Informations professionnelles :
    Activité : Personnel

    Informations forums :
    Inscription : Septembre 2003
    Messages : 142
    Points : 210
    Points
    210
    Par défaut
    Salut,
    Il existe un composant Jedi qui fait cela très bien, est très rapidement:
    On peut reprendre ensuite la feuille créée, et l'agrémenter à son goût, ou alors éplucher le code source de l'unité correspondante:
    D'après ce que j'ai vu cela donne en gros:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    function TJvDBGridExcelExport.DoExport: Boolean;
     const
      ...
     var
      lTable: OleVariant;
      lCell: OleVariant;
     begin
      ...
      lTable := FExcel.ActiveWorkbook.ActiveSheet;
      ...            
      // boucle de lecture de la table
      ...
      DisableControls;
      ...
      lCell := lTable.Range[IndexFieldToExcel(K) + IntToStr(J)];
      try
        // Do not cast with string ! - copy Record DB to XLS
        lCell.Value := FRecordColumns[I].Field.Value;
      except
        Result := False;
        HandleException;
      end;
      ...
    Si cela peut vous aider...
    @+
    Fabrice

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/10/2006, 10h45
  2. insérer une nouvelle feuille Excel à partir d' Access
    Par Sebastien_INR59 dans le forum Access
    Réponses: 2
    Dernier message: 06/08/2006, 18h47
  3. [VBA]Renseigner une feuille excel à partir d'un site web
    Par DonKnacki dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 23/01/2006, 13h43
  4. Mise en forme d’une feuille excel à partir de
    Par rana dans le forum Access
    Réponses: 9
    Dernier message: 21/12/2005, 15h20
  5. Réponses: 5
    Dernier message: 05/07/2005, 20h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo