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

Langage Delphi Discussion :

Clipboard et mémoire


Sujet :

Langage Delphi

  1. #1
    Membre habitué
    Homme Profil pro
    Chef de projets
    Inscrit en
    Août 2008
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2008
    Messages : 127
    Points : 195
    Points
    195
    Par défaut Clipboard et mémoire
    Bonjour,

    Voici mon souci, je travaille une grosse source de données que je souhaite insérer dans Excel. Au départ je générais un fichier à plat sur le disque et je l'intégrais à Excel avec une commande COM. Ma source de données peut atteindre 100 000 - 150 000 lignes.

    Pour optimiser les temps de traitement je créé les lignes dans une TStringList et tous les X lignes je prends le contenu je le mets dans le Clipboard. Puis je colle dans Excel.

    Le fonctionnement est très aléatoire, car d'un poste à l'autre, une exception peut être relevée pour mémoire insuffisante. Par contre soit l'autre de la mise dans le Clipboard, soit au moment du past dans Excel.

    Voici un extrait du code

    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
    72
    73
    74
    75
     
    function AjouteData(sReq, sNomOnglet : String ; ListeOptions : TStringList) : boolean;
    var
       iCpt            : Integer;
       sChaineEntete   : string;
       RensParam       : TYRensParamFusion;
       iLigne          : Integer;
       ListeData       : TStringList;
       iLigneExcel     : Integer;
    begin
       try
          Screen.Cursor := CrHourGlass;
          ListeData := TStringList.Create;
     
     
          fdmTCD.SqlTabXl.SQL.Clear;
     
          fdmTCD.SqlTabXl.Open;
     
          fdmTCD.SqlTabXl.First;
          result := not fdmTCD.SqlTabXl.Eof;
     
          iLigne        := 0;
          iLigneExcel   := 1;
          sChaineEntete := '';
          // recherche des noms de colonne
          for iCpt := 0 to fdmTCD.SqlTabXl.FieldCount - 1 do
             // Ecriture des noms de colonne
             sChaineEntete := sChaineEntete + UpperCase(fdmTCD.SqlTabXl.Fields[iCpt].FieldName) + ';';
     
     
          ListeData.Add(sChaineEntete);
          Inc(iLigne);
     
          // Ecriture des données
          while not fdmTCD.SqlTabXl.Eof do
          begin
             inc(iLigne);
             ListeData.Append(GetUneLigneDeDonnee);
     
             //Toutes les 100 000 lignes on va écrire dans le fichier afin de soulager la mémoire.
             if (iLigne mod 50000) = 0 then
             begin
                Clipboard.AsText := ListeData.Text;
                fdmTCD.EwsModeleTabXl.Range['A' + IntToStr(iLigneExcel), 'A' + IntToStr(iLigneExcel)].Select;
                fdmTCD.EwsModeleTabXl.Paste;
     
                ListeData.Clear;
                iLigneExcel := iLigneExcel + iLigne;
                iLigne := 0;
             end;
     
     
             fdmTCD.SqlTabXl.Next;
          end;
          fdmTCD.SqlTabXl.Close;
     
          //Si on a dépassé notre seuil on a stocké les données
          // dans un fichier. On met les dernieres lignes dedans.
          if ListeData.Count > 0 then
          begin
             Clipboard.AsText := ListeData.Text;
             fdmTCD.EwsModeleTabXl.Range['A' + IntToStr(iLigneExcel), 'A' + IntToStr(iLigneExcel)].Select;
             fdmTCD.EwsModeleTabXl.Paste;
     
             ListeData.Clear;
          end;
     
       finally
          fdmTCD.SqlTabXl.Close;
          Screen.Cursor := crDefault;
          DetruitObjet(RensParam);
          DetruitObjet(ListeData);
       end;
    end;

    J'ai tenté un essai avec le code suivant, qui marche bien sur un petit ensemble de données, mais pas sur de 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
    25
    26
    27
    28
     
    procedure TForm5.Button1Click(Sender: TObject);
    var mem: Cardinal;
        ptr: Pointer;
        s: string;
        zero: Word;
    begin
       try
          Clipboard.Open;
       Clipboard.Clear;
        s := Liste.Text;
        Liste.Clear;
        mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Length(s)+2);
        if mem=0 then
          raise Exception.Create('Mem');
     
        ptr := GlobalLock(mem);
        Move(PChar(s)^,ptr^, Length(s));
        zero := 0;
        Move(zero,(PChar(ptr)+Length(s))^, 2);
        GlobalUnlock(mem);
        Clipboard.SetAsHandle(CF_UNICODETEXT ,mem);
     
       finally
          Clipboard.Close;
     
       end;
    end;

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 464
    Points : 24 888
    Points
    24 888
    Par défaut
    EwsModeleTabXl semble être un objet excel !
    Pourquoi ne pas modifier le excel proprement via la propriété Value ?

    Sache que tu peux aussi générer un fichier CSV ou DBase, l'ouvrir avec Excel via OLE puis faire un SaveAs en XLS, cela fonctionne très bien !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre habitué
    Homme Profil pro
    Chef de projets
    Inscrit en
    Août 2008
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2008
    Messages : 127
    Points : 195
    Points
    195
    Par défaut
    A cause des temps de traitement.

    Si vous essayer de charger un gros ensemble de données de cette facon, le temps va être multiplié. Je n'ai plus mes Benchmark sous le coude, mais en gros il me semble pour pour 100 000 et 50 colonnes on mets 5 minutes à connecter un fichier à plat à la feuille Excel, 10 minutes en passant par la value, et 3 en passant par le buffer.

  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    je mon expérience, l'accès COM à Excel est lourd et peu pratique.

    j'ai toujours utilisé DDE (et oui le bon vieux DDE) qui marche très bien pour des mise à jours rapides et récurrentes (je n'ai pas testé avec 100.000 lignes) - dans mon cas c'était la mise ne jour en direct des résultats d'une élection...je suppose que c'est toujours supporté bien que déprécié depuis longtemps, mais développé sous Delphi 1 au départ, ça a survécu à toutes les versions de Delphi et Excel que j'ai eu jusque Office 97 (pas testé plus loin)

    http://tothpaul.free.fr/sources.php?dprdoc.excel

    Sinon pour les exports de bcp de données je suis toujours passé par une génération native du fichier, avec mes sources ou XLSReadWriteII (payant) qui est beaucoup plus complet

    http://tothpaul.free.fr/sources.php?dprdoc.biff8
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre habitué
    Inscrit en
    Juillet 2007
    Messages
    113
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2007
    Messages : 113
    Points : 170
    Points
    170
    Par défaut
    Si travailles sur du xslx (format openXML), tu as aussi la possibilité de dézippé un fichier excel et d'aller écrire directement en XML dans la feuille ou tu veux insérer tes données http://msdn.microsoft.com/fr-fr/library/bb727304.aspx. Ensuite tu rezip ton document.
    La procédure est un peu complexe mais en terme de temps d'exécution tu es sur de l'écriture de fichier et donc sur des choses bien plus rapide. A voir si il existe des compos qui permettent de faire ça simplement...

  6. #6
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 391
    Points : 3 003
    Points
    3 003
    Par défaut
    En son temps, mais j'ai plus les sources sous la main, je faisais des transferts très rapides entre delphi et excel en utilisant les plages de valeurs. Ca se posait dans un variant et récupéré sous forme de tableau dans delphi et inversement. C'était très rapide. Je recherche ça si ça peut aider.

  7. #7
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 391
    Points : 3 003
    Points
    3 003
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    En son temps, mais j'ai plus les sources sous la main, je faisais des transferts très rapides entre delphi et excel en utilisant les plages de valeurs. Ca se posait dans un variant et récupéré sous forme de tableau dans delphi et inversement. C'était très rapide. Je recherche ça si ça peut aider.
    http://delphi.developpez.com/faq/?pa...xcelvaltableau

Discussions similaires

  1. fichier mappé en mémoire
    Par WinBernardo dans le forum Delphi
    Réponses: 7
    Dernier message: 01/12/2006, 09h38
  2. Accéder à un espace mémoire sous XP
    Par keny dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 02/08/2002, 12h37
  3. Déterminer l'adresse d'une application en mémoire
    Par Gib dans le forum x86 32-bits / 64-bits
    Réponses: 9
    Dernier message: 11/06/2002, 14h27
  4. Vitesse de la mémoire vidéo
    Par Anonymous dans le forum x86 16-bits
    Réponses: 3
    Dernier message: 06/06/2002, 20h20
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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