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

Bases de données Delphi Discussion :

Problème de conversion de type lors d'exportation vers Excel


Sujet :

Bases de données Delphi

  1. #1
    Membre actif

    Inscrit en
    Mai 2010
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 401
    Points : 294
    Points
    294
    Par défaut Problème de conversion de type lors d'exportation vers Excel
    Bonjour à tous,
    J'ai une table appelée leBon , qui contient les informations suivantes :
    CodeArticle , Designation , Quantite , Prix.

    Pour l'exportation des données vers Excel , j'utilise le bout de code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
              j:=13;
              LeBon.First;
              While not LeBon.Eof do
              begin
                 For i:= 1 To  LeBon.FieldCount Do
                 begin
                    s := MonTableau[i]+inttostr(j);
                    Feuil.Range[s,s].Value[xlRangeValueDefault] := LeBon.Fields.Fields[i-1].Value;
                 end;
                 LeBon.Next;
                 j:=j+1;
              end;
    L'exportation se fait parfaitement , seulement un de mes clients codifie ces articles de la façons suivante :
    00001
    00002
    00003

    car le code Article est de type String .

    mais lors de l' exportation vers Excel , il convertit les codes Article vers un type entier....
    c'est-à-dire qu'au lieu de 00001 il met 1,
    00002 il met 2
    et ainsi de suite...
    Il ne garde pas le même type (String)

    Quelqu'un a-t-il une idée, SVP ?...

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 197
    Points : 300
    Points
    300
    Par défaut
    Bonjour,

    Tu peux essayer en mettant une apostrophe devant le code article par exemple : '0002

    Ca force excel à considérer la valeur numérique comme un texte.

  3. #3
    Membre actif

    Inscrit en
    Mai 2010
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 401
    Points : 294
    Points
    294
    Par défaut
    Citation Envoyé par EddiGordo Voir le message
    Bonjour,

    Tu peux essayer en mettant une apostrophe devant le code article par exemple : '0002

    Ca force excel à considérer la valeur numérique comme un texte.
    merci pour la réponse ,
    je vais essayé et je reviens.

  4. #4
    Membre actif

    Inscrit en
    Mai 2010
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 401
    Points : 294
    Points
    294
    Par défaut
    Bonjour,
    ça ne résous pas le problème!!!!
    ça donne 002' (+ un apostrophe à la fin) .

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    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 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Vous êtes sûr de ne pas avoir inversé dans la code ?

    On peut voir comment c'est écrit ?

  6. #6
    Membre actif

    Inscrit en
    Mai 2010
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 401
    Points : 294
    Points
    294
    Par défaut
    Ok ,
    Voici la procédure complète :

    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
     
    procedure TFBonV.ExportExcelClick(Sender: TObject);
    var Tab: _workbook;
        Feuil: _worksheet;
        i,j:Integer;
        S:shortstring;
    begin
     
       try
         LeBon.Close ;
         LeBon.ParamByName('N').AsString := NumerBon.Text ;
         LeBon.Open ;
        ExcelApplication1.Connect;
        ExcelApplication1.Visible[0]:=False;
        Tab:=ExcelApplication1.Workbooks.Add(xlWBATWorksheet,0);
        //ExcelApplication1.Visible[0]:=true;
        feuil:=Tab.Worksheets[1] as _worksheet;
     
     
     
              For i:=0 to LeBon.FieldCount-1 do
              begin
                  with Feuil.Range[MonTableau[i+1]+'12',MonTableau[i+1]+'12'] do
                  begin
                     Value[xlRangeValueDefault]:= LeBon.Fields.Fields[i].DisplayLabel;
                     Font.Name:='times new roman';
                     Font.Size:=10;
                     Font.Bold:=True;
                     With Interior do
                     begin
                          ColorIndex := 15;
                          Pattern := xlSolid;
                          PatternColorIndex := xlAutomatic;
                     End;
                     With Borders do
                     begin
                          LineStyle := xlContinuous;
                          Weight := xlThin;
                          ColorIndex := xlAutomatic;
                     End;
                  end;
              end;
              j:=13;
              LeBon.First;
              While not LeBon.Eof do
              begin
                 For i:= 1 To  LeBon.FieldCount Do
                 begin
                    s := MonTableau[i]+inttostr(j);
                    Feuil.Range[s,s].Value[xlRangeValueDefault] := LeBon.Fields.Fields[i-1].Value;
                 end;
                 LeBon.Next;
                 j:=j+1;
              end;
       finally
     
            ExcelApplication1.Visible[0]:=true;
            ExcelApplication1.Cells.Select;
            ExcelApplication1.Columns.AutoFit;
            ExcelApplication1.Range['A1','A1'].Select;
            ExcelApplication1.Disconnect;
            LeBon.Close ;
       end;
     
    end;

  7. #7
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    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 385
    Points : 2 999
    Points
    2 999
    Par défaut
    où est l'ajout d'apostrophe ??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil.Range[s,s].Value[xlRangeValueDefault] := LeBon.Fields.Fields[i-1].Value;
    et en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil.Range[s,s].Value[xlRangeValueDefault] := '''' + LeBon.Fields.Fields[i-1].asString;

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 453
    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 453
    Points : 24 864
    Points
    24 864
    Par défaut
    Pour éviter la conversion, je force plutôt le type de la colonne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const
      TEXT_FORMAT: WideString = '@'; // @ indique un texte, le typage en WideString est nécessaire pour qu'Excel le comprenne correctement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ExcelOLEWorkSheet.Columns[I + 1].NumberFormat := TEXT_FORMAT;
    Voici le code complet qui contient un export TDataSet vers Excel

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    //------------------------------------------------------------------------------
    (*                SoLuTions is an Versatile Library for Delphi                 -
     *                                                                             -
     *  Version alternative publiée sur "www.developpez.net"                       -
     *  Post : "c++ builder 2007 + ole excel"                                      -
     *  Post Number : 5628011                                                      -
     *  Post URL = "http://www.developpez.net/forums/d1006909/c-cpp/outils-c-cpp/cppbuilder/cpp-builder-2007-p-ole-excel/#post5628011"
     *                                                                             -
     *  Version alternative publiée sur "www.developpez.net"                       -
     *  Post : "excel et delphi"                                                   -
     *  Post Number : 6375536                                                      -
     *  Post URL = "http://www.developpez.net/forums/d1158956/environnements-developpement/delphi/debutant/excel-delphi/#post6375536"
     *                                                                             -
     *  Copyright ou © ou Copr. "SLT Solutions", (2006)                            -
     *  contributeur : ShaiLeTroll (2012) - Renommage Fichier et Correction XE2    -
     *  contributeur : ShaiLeTroll (2012) - Documentation Insight                  -
     *  contributeur : ShaiLeTroll (2014) - Reprise de la SLT<2012> sous C++Builder XE2/XE3 vers la SLT<2013> sous Delphi XE2
     *                                                                             -
     * ShaiLeTroll-
     *                                                                             -
     * Ce logiciel est un programme informatique servant à aider les développeurs  -
     * Delphi avec une bibliothèque polyvalente, adaptable et fragmentable.        -
     *                                                                             -
     * Ce logiciel est régi par la licence CeCILL-C soumise au droit français et   -
     * respectant les principes de diffusion des logiciels libres. Vous pouvez     -
     * utiliser, modifier et/ou redistribuer ce programme sous les conditions      -
     * de la licence CeCILL-C telle que diffusée par le CEA, le CNRS et l'INRIA    -
     * sur le site "http://www.cecill.info".                                       -
     *                                                                             -
     * En contrepartie de l'accessibilité au code source et des droits de copie,   -
     * de modification et de redistribution accordés par cette licence, il n'est   -
     * offert aux utilisateurs qu'une garantie limitée.  Pour les mêmes raisons,   -
     * seule une responsabilité restreinte pèse sur l'auteur du programme,  le     -
     * titulaire des droits patrimoniaux et les concédants successifs.             -
     *                                                                             -
     * A cet égard  l'attention de l'utilisateur est attirée sur les risques       -
     * associés au chargement,  à l'utilisation,  à la modification et/ou au       -
     * développement et à la reproduction du logiciel par l'utilisateur étant      -
     * donné sa spécificité de logiciel libre, qui peut le rendre complexe à       -
     * manipuler et qui le réserve donc à des développeurs et des professionnels   -
     * avertis possédant  des  connaissances  informatiques approfondies.  Les     -
     * utilisateurs sont donc invités à charger  et  tester  l'adéquation  du      -
     * logiciel à leurs besoins dans des conditions permettant d'assurer la        -
     * sécurité de leurs systèmes et ou de leurs données et, plus généralement,    -
     * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.          -
     *                                                                             -
     * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez      -
     * pris connaissance de la licence CeCILL-C, et que vous en avez accepté les   -
     * termes.                                                                     -
     *                                                                             -
     *----------------------------------------------------------------------------*)
    unit SLT.Common.Office.Excel;
     
    interface
     
    uses System.SysUtils, System.Classes, System.Variants, System.Types,
      Vcl.Dialogs, Vcl.ComCtrls,
      Data.DB;
     
    type
      { Forward class declarations }
      TSLTExcelDataSetExporter = class;
      TSLTExcelListViewer = class;
      ISLTXLSReader = interface;
      ISLTXLSFormatSpecification = interface;
      TSLTXLSReader = class;
     
      /// <summary>Erreur de base liée à la création d'un classeur excel à partir d'un TDataSet</summary>
      ESLTExcelDataSetExporterError = class(Exception);
     
      /// <summary>Création d'un classeur excel à partir d'un TDataSet</summary>
      TSLTExcelDataSetExporter = class(TObject)
      public
        type
          TProgressInfo = record
            Position: Integer;
          end;
      private
        // Membres privés
        FDataSet: TDataSet;
        FOnProgress: TNotifyEvent;
        FOnBeforeActivateExcel: TNotifyEvent;
        FCellWithBorder: Boolean;
        FShowWaitMessage: Boolean;
        FProgressInfo: TProgressInfo;
     
        // Méthodes privées - Evenement
        procedure DoProgress(APosition: Integer);
        procedure DoBeforeActivateExcel();
      public
        // Constructeurs
        constructor Create(ADataSet: TDataSet);
     
        // Méthodes publiques
        procedure ViewInExcel(const ASheetName: string; const AFieldsNames, ATitles: array of string);
     
        // Propriétés publiques
        property CellWithBorder: Boolean read FCellWithBorder write FCellWithBorder;
        property ProgressInfo: TProgressInfo read FProgressInfo;
        property ShowWaitMessage: Boolean read FShowWaitMessage write FShowWaitMessage;
     
        // Évènements publiques
        property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
        property OnBeforeActivateExcel: TNotifyEvent read FOnBeforeActivateExcel write FOnBeforeActivateExcel;
      end;
     
      /// <summary>Erreur de base liée à la création d'un classeur excel à partir d'un TListView</summary>
      ESLTExcelListViewerError = class(Exception);
     
      /// <summary>Création d'un classeur excel à partir d'un TListView</summary>
      TSLTExcelListViewer = class(TObject)
      public
        type
          TProgressInfo = record
            Position: Integer;
            Count: Integer;
          end;
      private
        // Membres privés
        FListView: TListView;
        FOnProgress: TNotifyEvent;
        FOnBeforeActivateExcel: TNotifyEvent;
        FCheckedOnly: Boolean;
        FShowWaitMessage: Boolean;
        FProgressInfo: TProgressInfo;
     
        // Méthodes privées - Evenement
        procedure DoProgress(APosition: Integer; ACount: Integer = -1);
        procedure DoBeforeActivateExcel();
      public
        // Constructeurs
        constructor Create(AListView: TListView);
     
        // Méthodes publiques
        procedure ViewInExcel(const ASheetName: string; const AColumnTypes: array of TVarType);
     
        // Propriétés publiques
        property CheckedOnly: Boolean read FCheckedOnly write FCheckedOnly;
        property ProgressInfo: TProgressInfo read FProgressInfo;
        property ShowWaitMessage: Boolean read FShowWaitMessage write FShowWaitMessage;
     
        // Évènements publiques
        property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
        property OnBeforeActivateExcel: TNotifyEvent read FOnBeforeActivateExcel write FOnBeforeActivateExcel;
      end;
     
     
      /// <summary>Erreur de base liée au fichier XLS</summary>
      ESLTXLSError = class(Exception);
      /// <summary>Erreur de base liée à lecture de fichier XLS</summary>
      ESLTXLSReaderError = class(ESLTXLSError);
      /// <summary>Erreur de base liée à la génération de fichier XLS</summary>
      ESLTXLSWriterError = class(ESLTXLSError);
     
      /// <summary>Cette interface défini les prototypes nécessaires à lecture d'un fichier XLS</summary>
      ISLTXLSReader = interface
        ['{66E9D4BB-5EAB-4642-8A31-6C3E7721167B}']
     
        // Méthodes
        procedure Open();
        procedure Close();
        function ReadNextLine(out AXLSLine: TStringDynArray): Boolean;
        procedure Next();
     
        // Accesseurs
        function GetFileName(): TFileName;
        procedure SetFileName(const Value: TFileName);
        function GetFormatSpecification(): ISLTXLSFormatSpecification;
        function GetEOF(): Boolean;
     
        // Propriétés
        /// <summary>Source des données à lire en format XLS</summary>
        property FileName: TFileName read GetFileName write SetFileName;
        /// <summary>Spécifications de format d'un fichier XLS/summary>
        property FormatSpecification: ISLTXLSFormatSpecification read GetFormatSpecification;
        /// <summary>Détermine si la position en cours du pointeur se trouve en fin de fichier XLS</summary>
        property EOF: Boolean read GetEOF;
      end;
     
      /// <summary>Cette interface défini les prototypes nécessaires fournissant les spécifications de format d'un fichier XLS</summary>
      ISLTXLSFormatSpecification = interface
        ['{3B736580-8294-48BB-A841-AB81E053F891}']
     
        // Accesseurs
        function GetExpectedSheetName(): string;
        procedure SetExpectedSheetName(const Value: string);
        function GetExpectedColumnCount(): Integer;
        procedure SetExpectedColumnCount(const Value: Integer);
     
        // Propriétés
        /// <summary>Nom de la feuille attendue dans le fichier Excel</summary>
        property ExpectedSheetName: string read GetExpectedSheetName write SetExpectedSheetName;
        /// <summary>Nombre de colonnes attendues</summary>
        property ExpectedColumnCount: Integer read GetExpectedColumnCount write SetExpectedColumnCount;
      end;
     
      TSLTXLSReader = class(TInterfacedObject, ISLTXLSReader, ISLTXLSFormatSpecification)
      private
        // Membres Privés - Propriétés
        FFileName: TFileName;
        FExpectedColumnCount: Integer;
        FExpectedSheetName: string;
        FExcelOLE: OLEVariant;
        FExcelOLEWorkbook: OLEVariant;
        FExcelOLEWorkSheet: OLEVariant;
        FExcelOLEWorkRows: OLEVariant;
        FRow: Integer;
     
      public
        // Accesseurs - Implémentation de ISLTXLSReader
        function GetFileName(): TFileName;
        procedure SetFileName(const Value: TFileName);
        function GetFormatSpecification(): ISLTXLSFormatSpecification;
        function GetEOF(): Boolean;
     
        // Accesseurs - Implémentation de ISLTXLSFormatSpecification
        function GetExpectedSheetName(): string;
        procedure SetExpectedSheetName(const Value: string);
        function GetExpectedColumnCount(): Integer;
        procedure SetExpectedColumnCount(const Value: Integer);
     
        // Méthodes - Implémentation de ISLTXLSReader
        procedure Open();
        procedure Close();
        function ReadNextLine(out AXLSLine: TStringDynArray): Boolean;
        procedure Next();
      public
        // Constructeurs
        constructor Create();
        destructor Destroy(); override;
      end;
     
    implementation
     
    uses Winapi.Windows, System.Win.ComObj, System.UITypes,
      SLT.Controls.VCL.DialogsEx;
     
    { procedural code forward declarations }
     
    /// <summary>Equivalent de SetForegroundWindow avec un délai retardant la mise au premier plan, cela laisse le temps d'afficher le TSLTMessageDlg </summary>
    procedure SetForegroundWindowAsync(const AWindowExcelCaption: string; Delay: Cardinal = INFINITE); forward;
     
    { TSLTExcelDataSetExporter }
     
    //------------------------------------------------------------------------------
    constructor TSLTExcelDataSetExporter.Create(ADataSet: TDataSet);
    begin
      inherited Create();
     
      FDataSet := ADataSet;
      FShowWaitMessage := True;
     
      if not Assigned(FDataSet) then
        raise ESLTExcelDataSetExporterError.Create('Aucune donnée disponible pour la Visualisation sous Excel !');
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelDataSetExporter.DoBeforeActivateExcel();
    begin
      if Assigned(FOnBeforeActivateExcel) then
        FOnBeforeActivateExcel(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelDataSetExporter.DoProgress(APosition: Integer);
    begin
      FProgressInfo.Position := APosition;
      if Assigned(FOnProgress) then
        FOnProgress(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelDataSetExporter.ViewInExcel(const ASheetName: string; const AFieldsNames, ATitles: array of string);
     
      procedure RenderCellWithBorder(var AMSCellItem: OleVariant);
      const
        xlEdgeBottom = $00000009;
        xlEdgeLeft = $00000007;
        xlEdgeRight = $0000000A;
        xlEdgeTop = $00000008;
      begin
        AMSCellItem.Borders[xlEdgeRight].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeRight].Weight := 2;
        AMSCellItem.Borders[xlEdgeLeft].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeLeft].Weight := 2;
        AMSCellItem.Borders[xlEdgeBottom].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeBottom].Weight := 2;
        AMSCellItem.Borders[xlEdgeTop].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeTop].Weight := 2;
      end;
     
    const
      TEXT_FORMAT: WideString = '@'; // @ indique un texte, le typage en WideString est nécessaire pour qu'Excel le comprenne correctement
    var
      ExcelOLE: OLEVariant;
      ExcelOLEWorkbook: OLEVariant;
      ExcelOLEWorkSheet: OLEVariant;
      ExcelOLEWorkSheetCell: OLEVariant;
      ExcelCaption: string;
      I, R: Integer;
      Bookmark: TBookmark;
      Field: TField;
      KeepOpenedExcel: Boolean;
    begin
      Assert(Length(AFieldsNames) = Length(ATitles), 'TSLTExcelDataSetExporter.ViewInExcel : Length(AFieldsNames) <> Length(ATitles)');
     
      DoProgress(0);
     
      KeepOpenedExcel := False;
      try
        // Code en LateBinding !
        ExcelOLE := System.Win.ComObj.CreateOleObject('Excel.Application');
        try
          ExcelOLE.UserControl := False;
          ExcelOLE.Visible := False;
          ExcelOLEWorkbook := ExcelOLE.WorkBooks.Add;
          try
            // Sheets.Item is one-based !
            for I := ExcelOLEWorkbook.Sheets.Count downto 2 do
              ExcelOLEWorkbook.Sheets.Item[I].Delete;
     
            // Le nom d'une feuille Excel est limité à 31 caractères
            ExcelOLEWorkSheet := ExcelOLEWorkbook.Sheets.Item[1];
            ExcelOLEWorkSheet.Name := Copy(ASheetName, 1, 31);
            // Le passage d'un Texte préfixé par ' vers une Formule permet de forcer le typage texte d'un nombre mais en masquant la guillemet !
            // Je génère Excel directement en OLE
     
            // Cells is one-based !
            R := 1;
            for I := Low(ATitles) to High(ATitles) do
            begin
              ExcelOLEWorkSheetCell := ExcelOLEWorkSheet.Cells[R, I + 1];
              ExcelOLEWorkSheetCell.Value := ATitles[I];
              if CellWithBorder then
                RenderCellWithBorder(ExcelOLEWorkSheetCell);
            end;
     
            // Columns is one-based !
            for I := Low(AFieldsNames) to High(AFieldsNames) do
            begin
              // Force une chaine ce qui évite la perte des Zéros en début d'un texte, comme un code barre par exemple
              Field := FDataSet.FieldByName(AFieldsNames[I]);
              if Field.DataType = ftString then
                ExcelOLEWorkSheet.Columns[I + 1].NumberFormat := TEXT_FORMAT;
            end;
     
            Inc(R);
            FDataSet.DisableControls();
            try
              Bookmark := FDataSet.Bookmark;
              try
                FDataSet.First();
                while not FDataSet.EOF do
                begin
                  for I := Low(AFieldsNames) to High(AFieldsNames) do
                  begin
                    Field := FDataSet.FieldByName(AFieldsNames[I]);
                    ExcelOLEWorkSheetCell := ExcelOLEWorkSheet.Cells[R, I + 1];
     
                    // FormulaLocal utilise les options régionales pour traduire une valeur,
                    // cela gère ainsi le séparateur décimal correctement
                    if Field.DataType = ftFloat then
                      ExcelOLEWorkSheetCell.FormulaLocal := Field.AsString
                    // cela gère ainsi le format de date français correctement
                    else if Field.DataType in [ftDate, ftDateTime, ftTime] then
                      ExcelOLEWorkSheetCell.FormulaLocal := Field.AsString
                    // Force une chaine ce qui évite la perte des Zéros du RH_NUMSAL ou du MHO_CH_CODE
                    else if Field.DataType = ftString then
                      ExcelOLEWorkSheetCell.Formula := Field.AsString
                    // Les autres données sont recopiées brutes
                    else
                      ExcelOLEWorkSheetCell.Value := Field.AsString;
     
                    if CellWithBorder then
                      RenderCellWithBorder(ExcelOLEWorkSheetCell);
                  end;
     
                  FDataSet.Next();
                  Inc(R);
     
                  // Patience tout les 16 lignes, c'est suffisant !
                  if not ByteBool(R and $0F) then
                    DoProgress(R);
                end;
     
              finally
                FDataSet.Bookmark := Bookmark;
              end;
            finally
              FDataSet.EnableControls();
            end;
     
            // Redimensionnement des colonnes par rapport aux données
            for I := Low(ATitles) to High(ATitles) do
              ExcelOLEWorkSheet.Columns[I + 1].AutoFit;
     
            ExcelOLE.Visible := True;
            ExcelOLE.UserControl := True;
            ExcelCaption := ExcelOLE.Caption;
     
            DoBeforeActivateExcel();
     
            // Affichera l'excel lancé (différé pour éviter que le TSLTMessageDlg reprenne le Focus)
            SetForegroundWindowAsync(ExcelCaption, 100);
     
            // un simple message servira de système d'attente, c'est pauvre mais efficace !
            if FShowWaitMessage then
              KeepOpenedExcel := (TSLTMessageDlg.Show('Excel est ouvert, continuez ...', mtConfirmation, [mbYes, mbNo], ['Fermer Excel', 'Continuer sans fermer Excel']) = mrNo);
     
          finally
            if not VarIsClear(ExcelOLEWorkbook) then
            begin
              if not KeepOpenedExcel then
                ExcelOLEWorkbook.Close(SaveChanges := False);
              ExcelOLEWorkbook := Unassigned;
            end;
          end;
     
        finally
          if not VarIsClear(ExcelOLE) then
          begin
            if not KeepOpenedExcel then
              if ExcelOLE.WorkBooks.Count = 0 then
                ExcelOLE.Quit;
            ExcelOLE := Unassigned;
          end;
        end;
     
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTExcelDataSetExporterError.CreateFmt('Erreur durant la Fermeture de la Visualisation sous Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTExcelDataSetExporterError.CreateFmt('Erreur durant la Visualisation sous Excel : %s', [E.Message]);
      end;
    end;
     
    { TSLTExcelListViewer }
     
    //------------------------------------------------------------------------------
    constructor TSLTExcelListViewer.Create(AListView: TListView);
    begin
      inherited Create();
     
      FListView := AListView;
      FShowWaitMessage := True;
     
      if not Assigned(FListView) then
        raise ESLTExcelListViewerError.Create('Aucune donnée disponible pour la Visualisation sous Excel !');
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelListViewer.DoBeforeActivateExcel();
    begin
      if Assigned(FOnBeforeActivateExcel) then
        FOnBeforeActivateExcel(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelListViewer.DoProgress(APosition: Integer; ACount: Integer = -1);
    begin
      if ACount > 0 then
        FProgressInfo.Count := ACount;
      FProgressInfo.Position := APosition;
      if Assigned(FOnProgress) then
        FOnProgress(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelListViewer.ViewInExcel(const ASheetName: string; const AColumnTypes: array of TVarType);
    const
      TEXT_FORMAT: WideString = '@'; // @ indique un texte, le typage en WideString est nécessaire pour qu'Excel le comprenne correctement
    var
      ExcelOLE: OLEVariant;
      ExcelOLEWorkbook: OLEVariant;
      ExcelOLEWorkSheet: OLEVariant;
      ExcelCaption: string;
      I, R, Rx: Integer;
      KeepOpenedExcel: Boolean;
    begin
      DoProgress(0, FListView.Items.Count);
     
      KeepOpenedExcel := False;
      try
        // Code en LateBinding !
        ExcelOLE := System.Win.ComObj.CreateOleObject('Excel.Application');
        try
          ExcelOLE.UserControl := False;
          ExcelOLE.Visible := False;
          ExcelOLEWorkbook := ExcelOLE.WorkBooks.Add;
          try
            // Sheets.Item is one-based !
            for I := ExcelOLEWorkbook.Sheets.Count downto 2 do
              ExcelOLEWorkbook.Sheets.Item[I].Delete;
     
            // Le nom d'une feuille Excel est limité à 31 caractères
            ExcelOLEWorkSheet := ExcelOLEWorkbook.Sheets.Item[1];
            ExcelOLEWorkSheet.Name := Copy(ASheetName, 1, 31);
            // Le passage d'un Texte préfixé par ' vers une Formule permet de forcer le typage texte d'un nombre mais en masquant la guillemet !
            // Je génère Excel directement en OLE
     
            // Cells is one-based !
            Rx := 1;
            for I := 0 to FListView.Columns.Count - 1 do
            begin
              ExcelOLEWorkSheet.Cells.Item[Rx, I + 1].Value := FListView.Columns[I].Caption;
     
              // Force une chaine ce qui évite la perte des Zéros en début d'un texte, comme un code barre par exemple
              if (I <= High(AColumnTypes)) and (AColumnTypes[I] = varString) then
                ExcelOLEWorkSheet.Columns[I + 1].NumberFormat := TEXT_FORMAT;
            end;
     
            // Cells is one-based !
            // Les données en deuxieme ligne
            Rx := 2;
            for R := 0 to FListView.Items.Count - 1 do
            begin
              with FListView.Items[R] do
              begin
                // On ajoute soit
                // - c'est tout et pas seulement les cochés (not FCheckedOnly)
                // - les case à cocher ne sont pas activé dans la liste (not FListView.Checkboxes)
                // - on filtre seulement les cochés (Checked)
                if not FCheckedOnly or not FListView.Checkboxes or Checked then
                begin
                  // 1er colonne c'est le texte
                  ExcelOLEWorkSheet.Cells[Rx, 1].Value := Caption;
                  // les colonnes suivantes c'est les sous-texte
                  for I := 0 to SubItems.Count - 1 do
                    ExcelOLEWorkSheet.Cells[Rx, I + 2].FormulaLocal := SubItems[I];
     
                  Inc(Rx);
                end;
              end;
     
              // Patience tout les 16 lignes, c'est suffisant !
              if not ByteBool(R and $0F) then
                DoProgress(R);
            end;
     
            // Redimensionnement des colonnes par rapport aux données
            for I := 0 to FListView.Columns.Count - 1 do
              ExcelOLEWorkSheet.Columns[I + 1].AutoFit;
     
            ExcelOLE.Visible := True;
            ExcelOLE.UserControl := True;
            ExcelCaption := ExcelOLE.Caption;
     
            DoBeforeActivateExcel();
     
            // Affichera l'excel lancé (différé pour éviter que le TSLTMessageDlg reprenne le Focus)
            SetForegroundWindowAsync(ExcelCaption, 100);
     
            // un simple message servira de système d'attente, c'est pauvre mais efficace !
            if FShowWaitMessage then
              KeepOpenedExcel := (TSLTMessageDlg.Show('Excel est ouvert, continuez ...', mtConfirmation, [mbYes, mbNo], ['Fermer Excel', 'Continuer sans fermer Excel']) = mrNo);
     
          finally
            if not VarIsClear(ExcelOLEWorkbook) then
            begin
              if not KeepOpenedExcel then
                ExcelOLEWorkbook.Close(SaveChanges := False);
              ExcelOLEWorkbook := Unassigned;
            end;
          end;
     
        finally
          if not VarIsClear(ExcelOLE) then
          begin
            if not KeepOpenedExcel then
              if ExcelOLE.WorkBooks.Count = 0 then
                ExcelOLE.Quit;
            ExcelOLE := Unassigned;
          end;
        end;
     
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTExcelListViewerError.CreateFmt('Erreur durant la Fermeture de la Visualisation sous Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTExcelListViewerError.CreateFmt('Erreur durant la Visualisation sous Excel : %s', [E.Message]);
      end;
    end;
     
    { TSLTXLSReader }
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.Close();
    begin
      try
        FExcelOLEWorkSheet := Unassigned;
     
        try
          if not VarIsClear(FExcelOLEWorkbook) then
          begin
            FExcelOLEWorkbook.Close(SaveChanges := False);
            FExcelOLEWorkbook := Unassigned;
          end;
        except
          // On ignore cette erreur !
          FExcelOLEWorkbook := Unassigned;
        end;
     
        if not VarIsClear(FExcelOLE) then
        begin
          if FExcelOLE.WorkBooks.Count = 0 then
            FExcelOLE.Quit;
          FExcelOLE := Unassigned;
        end;
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTXLSReaderError.CreateFmt('Erreur durant la Fermeture du lecteur de fichier Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTXLSReaderError.CreateFmt('Erreur durant la Fermeture du lecteur de fichier Excel : %s', [E.Message]);
      end;
    end;
     
    //------------------------------------------------------------------------------
    constructor TSLTXLSReader.Create();
    begin
      inherited Create();
     
    end;
     
    //------------------------------------------------------------------------------
    destructor TSLTXLSReader.Destroy();
    begin
      Close();
     
      inherited Destroy();
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetEOF(): Boolean;
    begin
      Result := FRow >= FExcelOLEWorkRows.Count;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetExpectedColumnCount(): Integer;
    begin
      Result := FExpectedColumnCount;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetExpectedSheetName(): string;
    begin
      Result := FExpectedSheetName;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetFileName(): TFileName;
    begin
      Result := FFileName;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetFormatSpecification(): ISLTXLSFormatSpecification;
    begin
      Result := Self;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.Next();
    begin
      Inc(FRow);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.Open();
     
      function FindFirstSheet(AWorkbook: OleVariant): OleVariant;
      begin
        // Sheets.Item is one-based !
        Result := Unassigned;
        if FExcelOLEWorkbook.Sheets.Count >= 1 then
          Result := FExcelOLEWorkbook.Sheets.Item[1];
      end;
     
      function FindSheet(AWorkbook: OleVariant; const ASheetName: string): OleVariant;
      var
        I: Integer;
      begin
        // Sheets.Item is one-based !
        for I := 1 to FExcelOLEWorkbook.Sheets.Count do
        begin
          Result := FExcelOLEWorkbook.Sheets.Item[I];
          if SameText(Result.Name, ASheetName) then
            Exit;
        end;
     
        Result := Unassigned;
      end;
     
    begin
      FExcelOLEWorkRows := Unassigned;
      FExcelOLEWorkSheet := Unassigned;
      FExcelOLEWorkbook := Unassigned;
      FExcelOLE := Unassigned;
      // Cells is one-based, la première opération de ReadNextLine doit être l'incrémentation de l'indice de ligne FRow  !
      FRow := 0;
     
      try
        // Code en LateBinding !
        FExcelOLE := System.Win.ComObj.CreateOleObject('Excel.Application');
     
        // Excel caché
        FExcelOLE.UserControl := False;
        FExcelOLE.Visible := False;
        FExcelOLEWorkbook := FExcelOLE.WorkBooks.Open(FFileName);
     
        // Recherche de la Feuille
        if FExpectedSheetName <> '' then
        begin
          FExcelOLEWorkSheet := FindSheet(FExcelOLEWorkbook, FExpectedSheetName);
          if VarIsEmpty(FExcelOLEWorkSheet) then
            raise ESLTXLSReaderError.CreateFmt('Erreur durant l''Ouverture du fichier Excel : Feuille "%s" non trouvée', [FExpectedSheetName]);
        end
        else
        begin
          FExcelOLEWorkSheet := FindFirstSheet(FExcelOLEWorkbook);
          if VarIsEmpty(FExcelOLEWorkSheet) then
            raise ESLTXLSReaderError.Create('Erreur durant l''Ouverture du fichier Excel : Aucune feuille trouvée');
        end;
     
        // Obtention des données présentes de la Feuille
        FExcelOLEWorkRows := FExcelOLEWorkSheet.UsedRange.Rows;
     
        if VarIsEmpty(FExcelOLEWorkSheet) then
          raise ESLTXLSReaderError.Create('Erreur durant l''Ouverture du fichier Excel : Aucune donnée trouvée');
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTXLSReaderError.CreateFmt('Erreur durant l''Ouverture du lecteur de fichier Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTXLSReaderError.CreateFmt('Erreur durant l''Ouverture du lecteur de fichier Excel : %s', [E.Message]);
      end;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.ReadNextLine(out AXLSLine: TStringDynArray): Boolean;
    var
      I, Col, ColCount, OutCount: Integer;
    begin
      Inc(FRow);
     
      ColCount := FExcelOLEWorkRows.Columns.Count;
      // Le nombre de colonne attendu n'est fourni qu'après avoir lu l'entête
      if FExpectedColumnCount > 0 then
        OutCount := FExpectedColumnCount
      else
        OutCount := ColCount;
     
      SetLength(AXLSLine, OutCount);
      for I := Low(AXLSLine) to High(AXLSLine) do
      begin
        // Columns is one-based !
        Col := I + 1;
        if Col <= ColCount then
          AXLSLine[I] := FExcelOLEWorkRows.Cells.Item[FRow, Col];
      end;
     
      Result := True;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.SetExpectedColumnCount(const Value: Integer);
    begin
      FExpectedColumnCount := Value;
    end;
     
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.SetExpectedSheetName(const Value: string);
    begin
      FExpectedSheetName := Value;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.SetFileName(const Value: TFileName);
    begin
      FFileName := Value;
    end;
     
    { procedural code declarations }
     
    //------------------------------------------------------------------------------
    procedure SetForegroundWindowAsync(const AWindowExcelCaption: string; Delay: Cardinal = INFINITE);
    begin
      TThread.CreateAnonymousThread(
        procedure
        var
          Tentative: Integer;
          ExcelWnd: HWND;
          ForegroundedExcel: Boolean;
        begin
          Tentative := 0;
          repeat
            if Delay <> INFINITE then
              Sleep(Delay);
     
            ExcelWnd := FindWindow(nil, PChar(AWindowExcelCaption));
            ForegroundedExcel := (SetForegroundWindow(ExcelWnd) or LongBool(SetActiveWindow(ExcelWnd)))
              and (GetForegroundWindow() = ExcelWnd);
     
            Inc(Tentative);
          until ForegroundedExcel or (Tentative > 5);
     
        end).Start();
    end;
     
     
    end.
    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

  9. #9
    Membre actif

    Inscrit en
    Mai 2010
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 401
    Points : 294
    Points
    294
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    où est l'ajout d'apostrophe ??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil.Range[s,s].Value[xlRangeValueDefault] := LeBon.Fields.Fields[i-1].Value;
    et en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil.Range[s,s].Value[xlRangeValueDefault] := '''' + LeBon.Fields.Fields[i-1].asString;
    Merci beaucoup pour la réponse , c'est ce que je cherche.

    voici mon erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil.Range[s,s].Value[xlRangeValueDefault] := ''''+LeBon.Fields.Fields[i-1].Value + '''';
    j'ai ajouter une apostrophe a la fin .

    merci beaucoup encore une fois .

  10. #10
    Membre actif

    Inscrit en
    Mai 2010
    Messages
    401
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 401
    Points : 294
    Points
    294
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Pour éviter la conversion, je force plutôt le type de la colonne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const
      TEXT_FORMAT: WideString = '@'; // @ indique un texte, le typage en WideString est nécessaire pour qu'Excel le comprenne correctement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ExcelOLEWorkSheet.Columns[I + 1].NumberFormat := TEXT_FORMAT;
    Voici le code complet qui contient un export TDataSet vers Excel

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    //------------------------------------------------------------------------------
    (*                SoLuTions is an Versatile Library for Delphi                 -
     *                                                                             -
     *  Version alternative publiée sur "www.developpez.net"                       -
     *  Post : "c++ builder 2007 + ole excel"                                      -
     *  Post Number : 5628011                                                      -
     *  Post URL = "http://www.developpez.net/forums/d1006909/c-cpp/outils-c-cpp/cppbuilder/cpp-builder-2007-p-ole-excel/#post5628011"
     *                                                                             -
     *  Version alternative publiée sur "www.developpez.net"                       -
     *  Post : "excel et delphi"                                                   -
     *  Post Number : 6375536                                                      -
     *  Post URL = "http://www.developpez.net/forums/d1158956/environnements-developpement/delphi/debutant/excel-delphi/#post6375536"
     *                                                                             -
     *  Copyright ou © ou Copr. "SLT Solutions", (2006)                            -
     *  contributeur : ShaiLeTroll (2012) - Renommage Fichier et Correction XE2    -
     *  contributeur : ShaiLeTroll (2012) - Documentation Insight                  -
     *  contributeur : ShaiLeTroll (2014) - Reprise de la SLT<2012> sous C++Builder XE2/XE3 vers la SLT<2013> sous Delphi XE2
     *                                                                             -
     * ShaiLeTroll-
     *                                                                             -
     * Ce logiciel est un programme informatique servant à aider les développeurs  -
     * Delphi avec une bibliothèque polyvalente, adaptable et fragmentable.        -
     *                                                                             -
     * Ce logiciel est régi par la licence CeCILL-C soumise au droit français et   -
     * respectant les principes de diffusion des logiciels libres. Vous pouvez     -
     * utiliser, modifier et/ou redistribuer ce programme sous les conditions      -
     * de la licence CeCILL-C telle que diffusée par le CEA, le CNRS et l'INRIA    -
     * sur le site "http://www.cecill.info".                                       -
     *                                                                             -
     * En contrepartie de l'accessibilité au code source et des droits de copie,   -
     * de modification et de redistribution accordés par cette licence, il n'est   -
     * offert aux utilisateurs qu'une garantie limitée.  Pour les mêmes raisons,   -
     * seule une responsabilité restreinte pèse sur l'auteur du programme,  le     -
     * titulaire des droits patrimoniaux et les concédants successifs.             -
     *                                                                             -
     * A cet égard  l'attention de l'utilisateur est attirée sur les risques       -
     * associés au chargement,  à l'utilisation,  à la modification et/ou au       -
     * développement et à la reproduction du logiciel par l'utilisateur étant      -
     * donné sa spécificité de logiciel libre, qui peut le rendre complexe à       -
     * manipuler et qui le réserve donc à des développeurs et des professionnels   -
     * avertis possédant  des  connaissances  informatiques approfondies.  Les     -
     * utilisateurs sont donc invités à charger  et  tester  l'adéquation  du      -
     * logiciel à leurs besoins dans des conditions permettant d'assurer la        -
     * sécurité de leurs systèmes et ou de leurs données et, plus généralement,    -
     * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.          -
     *                                                                             -
     * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez      -
     * pris connaissance de la licence CeCILL-C, et que vous en avez accepté les   -
     * termes.                                                                     -
     *                                                                             -
     *----------------------------------------------------------------------------*)
    unit SLT.Common.Office.Excel;
     
    interface
     
    uses System.SysUtils, System.Classes, System.Variants, System.Types,
      Vcl.Dialogs, Vcl.ComCtrls,
      Data.DB;
     
    type
      { Forward class declarations }
      TSLTExcelDataSetExporter = class;
      TSLTExcelListViewer = class;
      ISLTXLSReader = interface;
      ISLTXLSFormatSpecification = interface;
      TSLTXLSReader = class;
     
      /// <summary>Erreur de base liée à la création d'un classeur excel à partir d'un TDataSet</summary>
      ESLTExcelDataSetExporterError = class(Exception);
     
      /// <summary>Création d'un classeur excel à partir d'un TDataSet</summary>
      TSLTExcelDataSetExporter = class(TObject)
      public
        type
          TProgressInfo = record
            Position: Integer;
          end;
      private
        // Membres privés
        FDataSet: TDataSet;
        FOnProgress: TNotifyEvent;
        FOnBeforeActivateExcel: TNotifyEvent;
        FCellWithBorder: Boolean;
        FShowWaitMessage: Boolean;
        FProgressInfo: TProgressInfo;
     
        // Méthodes privées - Evenement
        procedure DoProgress(APosition: Integer);
        procedure DoBeforeActivateExcel();
      public
        // Constructeurs
        constructor Create(ADataSet: TDataSet);
     
        // Méthodes publiques
        procedure ViewInExcel(const ASheetName: string; const AFieldsNames, ATitles: array of string);
     
        // Propriétés publiques
        property CellWithBorder: Boolean read FCellWithBorder write FCellWithBorder;
        property ProgressInfo: TProgressInfo read FProgressInfo;
        property ShowWaitMessage: Boolean read FShowWaitMessage write FShowWaitMessage;
     
        // Évènements publiques
        property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
        property OnBeforeActivateExcel: TNotifyEvent read FOnBeforeActivateExcel write FOnBeforeActivateExcel;
      end;
     
      /// <summary>Erreur de base liée à la création d'un classeur excel à partir d'un TListView</summary>
      ESLTExcelListViewerError = class(Exception);
     
      /// <summary>Création d'un classeur excel à partir d'un TListView</summary>
      TSLTExcelListViewer = class(TObject)
      public
        type
          TProgressInfo = record
            Position: Integer;
            Count: Integer;
          end;
      private
        // Membres privés
        FListView: TListView;
        FOnProgress: TNotifyEvent;
        FOnBeforeActivateExcel: TNotifyEvent;
        FCheckedOnly: Boolean;
        FShowWaitMessage: Boolean;
        FProgressInfo: TProgressInfo;
     
        // Méthodes privées - Evenement
        procedure DoProgress(APosition: Integer; ACount: Integer = -1);
        procedure DoBeforeActivateExcel();
      public
        // Constructeurs
        constructor Create(AListView: TListView);
     
        // Méthodes publiques
        procedure ViewInExcel(const ASheetName: string; const AColumnTypes: array of TVarType);
     
        // Propriétés publiques
        property CheckedOnly: Boolean read FCheckedOnly write FCheckedOnly;
        property ProgressInfo: TProgressInfo read FProgressInfo;
        property ShowWaitMessage: Boolean read FShowWaitMessage write FShowWaitMessage;
     
        // Évènements publiques
        property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
        property OnBeforeActivateExcel: TNotifyEvent read FOnBeforeActivateExcel write FOnBeforeActivateExcel;
      end;
     
     
      /// <summary>Erreur de base liée au fichier XLS</summary>
      ESLTXLSError = class(Exception);
      /// <summary>Erreur de base liée à lecture de fichier XLS</summary>
      ESLTXLSReaderError = class(ESLTXLSError);
      /// <summary>Erreur de base liée à la génération de fichier XLS</summary>
      ESLTXLSWriterError = class(ESLTXLSError);
     
      /// <summary>Cette interface défini les prototypes nécessaires à lecture d'un fichier XLS</summary>
      ISLTXLSReader = interface
        ['{66E9D4BB-5EAB-4642-8A31-6C3E7721167B}']
     
        // Méthodes
        procedure Open();
        procedure Close();
        function ReadNextLine(out AXLSLine: TStringDynArray): Boolean;
        procedure Next();
     
        // Accesseurs
        function GetFileName(): TFileName;
        procedure SetFileName(const Value: TFileName);
        function GetFormatSpecification(): ISLTXLSFormatSpecification;
        function GetEOF(): Boolean;
     
        // Propriétés
        /// <summary>Source des données à lire en format XLS</summary>
        property FileName: TFileName read GetFileName write SetFileName;
        /// <summary>Spécifications de format d'un fichier XLS/summary>
        property FormatSpecification: ISLTXLSFormatSpecification read GetFormatSpecification;
        /// <summary>Détermine si la position en cours du pointeur se trouve en fin de fichier XLS</summary>
        property EOF: Boolean read GetEOF;
      end;
     
      /// <summary>Cette interface défini les prototypes nécessaires fournissant les spécifications de format d'un fichier XLS</summary>
      ISLTXLSFormatSpecification = interface
        ['{3B736580-8294-48BB-A841-AB81E053F891}']
     
        // Accesseurs
        function GetExpectedSheetName(): string;
        procedure SetExpectedSheetName(const Value: string);
        function GetExpectedColumnCount(): Integer;
        procedure SetExpectedColumnCount(const Value: Integer);
     
        // Propriétés
        /// <summary>Nom de la feuille attendue dans le fichier Excel</summary>
        property ExpectedSheetName: string read GetExpectedSheetName write SetExpectedSheetName;
        /// <summary>Nombre de colonnes attendues</summary>
        property ExpectedColumnCount: Integer read GetExpectedColumnCount write SetExpectedColumnCount;
      end;
     
      TSLTXLSReader = class(TInterfacedObject, ISLTXLSReader, ISLTXLSFormatSpecification)
      private
        // Membres Privés - Propriétés
        FFileName: TFileName;
        FExpectedColumnCount: Integer;
        FExpectedSheetName: string;
        FExcelOLE: OLEVariant;
        FExcelOLEWorkbook: OLEVariant;
        FExcelOLEWorkSheet: OLEVariant;
        FExcelOLEWorkRows: OLEVariant;
        FRow: Integer;
     
      public
        // Accesseurs - Implémentation de ISLTXLSReader
        function GetFileName(): TFileName;
        procedure SetFileName(const Value: TFileName);
        function GetFormatSpecification(): ISLTXLSFormatSpecification;
        function GetEOF(): Boolean;
     
        // Accesseurs - Implémentation de ISLTXLSFormatSpecification
        function GetExpectedSheetName(): string;
        procedure SetExpectedSheetName(const Value: string);
        function GetExpectedColumnCount(): Integer;
        procedure SetExpectedColumnCount(const Value: Integer);
     
        // Méthodes - Implémentation de ISLTXLSReader
        procedure Open();
        procedure Close();
        function ReadNextLine(out AXLSLine: TStringDynArray): Boolean;
        procedure Next();
      public
        // Constructeurs
        constructor Create();
        destructor Destroy(); override;
      end;
     
    implementation
     
    uses Winapi.Windows, System.Win.ComObj, System.UITypes,
      SLT.Controls.VCL.DialogsEx;
     
    { procedural code forward declarations }
     
    /// <summary>Equivalent de SetForegroundWindow avec un délai retardant la mise au premier plan, cela laisse le temps d'afficher le TSLTMessageDlg </summary>
    procedure SetForegroundWindowAsync(const AWindowExcelCaption: string; Delay: Cardinal = INFINITE); forward;
     
    { TSLTExcelDataSetExporter }
     
    //------------------------------------------------------------------------------
    constructor TSLTExcelDataSetExporter.Create(ADataSet: TDataSet);
    begin
      inherited Create();
     
      FDataSet := ADataSet;
      FShowWaitMessage := True;
     
      if not Assigned(FDataSet) then
        raise ESLTExcelDataSetExporterError.Create('Aucune donnée disponible pour la Visualisation sous Excel !');
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelDataSetExporter.DoBeforeActivateExcel();
    begin
      if Assigned(FOnBeforeActivateExcel) then
        FOnBeforeActivateExcel(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelDataSetExporter.DoProgress(APosition: Integer);
    begin
      FProgressInfo.Position := APosition;
      if Assigned(FOnProgress) then
        FOnProgress(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelDataSetExporter.ViewInExcel(const ASheetName: string; const AFieldsNames, ATitles: array of string);
     
      procedure RenderCellWithBorder(var AMSCellItem: OleVariant);
      const
        xlEdgeBottom = $00000009;
        xlEdgeLeft = $00000007;
        xlEdgeRight = $0000000A;
        xlEdgeTop = $00000008;
      begin
        AMSCellItem.Borders[xlEdgeRight].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeRight].Weight := 2;
        AMSCellItem.Borders[xlEdgeLeft].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeLeft].Weight := 2;
        AMSCellItem.Borders[xlEdgeBottom].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeBottom].Weight := 2;
        AMSCellItem.Borders[xlEdgeTop].LineStyle := 1;
        AMSCellItem.Borders[xlEdgeTop].Weight := 2;
      end;
     
    const
      TEXT_FORMAT: WideString = '@'; // @ indique un texte, le typage en WideString est nécessaire pour qu'Excel le comprenne correctement
    var
      ExcelOLE: OLEVariant;
      ExcelOLEWorkbook: OLEVariant;
      ExcelOLEWorkSheet: OLEVariant;
      ExcelOLEWorkSheetCell: OLEVariant;
      ExcelCaption: string;
      I, R: Integer;
      Bookmark: TBookmark;
      Field: TField;
      KeepOpenedExcel: Boolean;
    begin
      Assert(Length(AFieldsNames) = Length(ATitles), 'TSLTExcelDataSetExporter.ViewInExcel : Length(AFieldsNames) <> Length(ATitles)');
     
      DoProgress(0);
     
      KeepOpenedExcel := False;
      try
        // Code en LateBinding !
        ExcelOLE := System.Win.ComObj.CreateOleObject('Excel.Application');
        try
          ExcelOLE.UserControl := False;
          ExcelOLE.Visible := False;
          ExcelOLEWorkbook := ExcelOLE.WorkBooks.Add;
          try
            // Sheets.Item is one-based !
            for I := ExcelOLEWorkbook.Sheets.Count downto 2 do
              ExcelOLEWorkbook.Sheets.Item[I].Delete;
     
            // Le nom d'une feuille Excel est limité à 31 caractères
            ExcelOLEWorkSheet := ExcelOLEWorkbook.Sheets.Item[1];
            ExcelOLEWorkSheet.Name := Copy(ASheetName, 1, 31);
            // Le passage d'un Texte préfixé par ' vers une Formule permet de forcer le typage texte d'un nombre mais en masquant la guillemet !
            // Je génère Excel directement en OLE
     
            // Cells is one-based !
            R := 1;
            for I := Low(ATitles) to High(ATitles) do
            begin
              ExcelOLEWorkSheetCell := ExcelOLEWorkSheet.Cells[R, I + 1];
              ExcelOLEWorkSheetCell.Value := ATitles[I];
              if CellWithBorder then
                RenderCellWithBorder(ExcelOLEWorkSheetCell);
            end;
     
            // Columns is one-based !
            for I := Low(AFieldsNames) to High(AFieldsNames) do
            begin
              // Force une chaine ce qui évite la perte des Zéros en début d'un texte, comme un code barre par exemple
              Field := FDataSet.FieldByName(AFieldsNames[I]);
              if Field.DataType = ftString then
                ExcelOLEWorkSheet.Columns[I + 1].NumberFormat := TEXT_FORMAT;
            end;
     
            Inc(R);
            FDataSet.DisableControls();
            try
              Bookmark := FDataSet.Bookmark;
              try
                FDataSet.First();
                while not FDataSet.EOF do
                begin
                  for I := Low(AFieldsNames) to High(AFieldsNames) do
                  begin
                    Field := FDataSet.FieldByName(AFieldsNames[I]);
                    ExcelOLEWorkSheetCell := ExcelOLEWorkSheet.Cells[R, I + 1];
     
                    // FormulaLocal utilise les options régionales pour traduire une valeur,
                    // cela gère ainsi le séparateur décimal correctement
                    if Field.DataType = ftFloat then
                      ExcelOLEWorkSheetCell.FormulaLocal := Field.AsString
                    // cela gère ainsi le format de date français correctement
                    else if Field.DataType in [ftDate, ftDateTime, ftTime] then
                      ExcelOLEWorkSheetCell.FormulaLocal := Field.AsString
                    // Force une chaine ce qui évite la perte des Zéros du RH_NUMSAL ou du MHO_CH_CODE
                    else if Field.DataType = ftString then
                      ExcelOLEWorkSheetCell.Formula := Field.AsString
                    // Les autres données sont recopiées brutes
                    else
                      ExcelOLEWorkSheetCell.Value := Field.AsString;
     
                    if CellWithBorder then
                      RenderCellWithBorder(ExcelOLEWorkSheetCell);
                  end;
     
                  FDataSet.Next();
                  Inc(R);
     
                  // Patience tout les 16 lignes, c'est suffisant !
                  if not ByteBool(R and $0F) then
                    DoProgress(R);
                end;
     
              finally
                FDataSet.Bookmark := Bookmark;
              end;
            finally
              FDataSet.EnableControls();
            end;
     
            // Redimensionnement des colonnes par rapport aux données
            for I := Low(ATitles) to High(ATitles) do
              ExcelOLEWorkSheet.Columns[I + 1].AutoFit;
     
            ExcelOLE.Visible := True;
            ExcelOLE.UserControl := True;
            ExcelCaption := ExcelOLE.Caption;
     
            DoBeforeActivateExcel();
     
            // Affichera l'excel lancé (différé pour éviter que le TSLTMessageDlg reprenne le Focus)
            SetForegroundWindowAsync(ExcelCaption, 100);
     
            // un simple message servira de système d'attente, c'est pauvre mais efficace !
            if FShowWaitMessage then
              KeepOpenedExcel := (TSLTMessageDlg.Show('Excel est ouvert, continuez ...', mtConfirmation, [mbYes, mbNo], ['Fermer Excel', 'Continuer sans fermer Excel']) = mrNo);
     
          finally
            if not VarIsClear(ExcelOLEWorkbook) then
            begin
              if not KeepOpenedExcel then
                ExcelOLEWorkbook.Close(SaveChanges := False);
              ExcelOLEWorkbook := Unassigned;
            end;
          end;
     
        finally
          if not VarIsClear(ExcelOLE) then
          begin
            if not KeepOpenedExcel then
              if ExcelOLE.WorkBooks.Count = 0 then
                ExcelOLE.Quit;
            ExcelOLE := Unassigned;
          end;
        end;
     
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTExcelDataSetExporterError.CreateFmt('Erreur durant la Fermeture de la Visualisation sous Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTExcelDataSetExporterError.CreateFmt('Erreur durant la Visualisation sous Excel : %s', [E.Message]);
      end;
    end;
     
    { TSLTExcelListViewer }
     
    //------------------------------------------------------------------------------
    constructor TSLTExcelListViewer.Create(AListView: TListView);
    begin
      inherited Create();
     
      FListView := AListView;
      FShowWaitMessage := True;
     
      if not Assigned(FListView) then
        raise ESLTExcelListViewerError.Create('Aucune donnée disponible pour la Visualisation sous Excel !');
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelListViewer.DoBeforeActivateExcel();
    begin
      if Assigned(FOnBeforeActivateExcel) then
        FOnBeforeActivateExcel(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelListViewer.DoProgress(APosition: Integer; ACount: Integer = -1);
    begin
      if ACount > 0 then
        FProgressInfo.Count := ACount;
      FProgressInfo.Position := APosition;
      if Assigned(FOnProgress) then
        FOnProgress(Self);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTExcelListViewer.ViewInExcel(const ASheetName: string; const AColumnTypes: array of TVarType);
    const
      TEXT_FORMAT: WideString = '@'; // @ indique un texte, le typage en WideString est nécessaire pour qu'Excel le comprenne correctement
    var
      ExcelOLE: OLEVariant;
      ExcelOLEWorkbook: OLEVariant;
      ExcelOLEWorkSheet: OLEVariant;
      ExcelCaption: string;
      I, R, Rx: Integer;
      KeepOpenedExcel: Boolean;
    begin
      DoProgress(0, FListView.Items.Count);
     
      KeepOpenedExcel := False;
      try
        // Code en LateBinding !
        ExcelOLE := System.Win.ComObj.CreateOleObject('Excel.Application');
        try
          ExcelOLE.UserControl := False;
          ExcelOLE.Visible := False;
          ExcelOLEWorkbook := ExcelOLE.WorkBooks.Add;
          try
            // Sheets.Item is one-based !
            for I := ExcelOLEWorkbook.Sheets.Count downto 2 do
              ExcelOLEWorkbook.Sheets.Item[I].Delete;
     
            // Le nom d'une feuille Excel est limité à 31 caractères
            ExcelOLEWorkSheet := ExcelOLEWorkbook.Sheets.Item[1];
            ExcelOLEWorkSheet.Name := Copy(ASheetName, 1, 31);
            // Le passage d'un Texte préfixé par ' vers une Formule permet de forcer le typage texte d'un nombre mais en masquant la guillemet !
            // Je génère Excel directement en OLE
     
            // Cells is one-based !
            Rx := 1;
            for I := 0 to FListView.Columns.Count - 1 do
            begin
              ExcelOLEWorkSheet.Cells.Item[Rx, I + 1].Value := FListView.Columns[I].Caption;
     
              // Force une chaine ce qui évite la perte des Zéros en début d'un texte, comme un code barre par exemple
              if (I <= High(AColumnTypes)) and (AColumnTypes[I] = varString) then
                ExcelOLEWorkSheet.Columns[I + 1].NumberFormat := TEXT_FORMAT;
            end;
     
            // Cells is one-based !
            // Les données en deuxieme ligne
            Rx := 2;
            for R := 0 to FListView.Items.Count - 1 do
            begin
              with FListView.Items[R] do
              begin
                // On ajoute soit
                // - c'est tout et pas seulement les cochés (not FCheckedOnly)
                // - les case à cocher ne sont pas activé dans la liste (not FListView.Checkboxes)
                // - on filtre seulement les cochés (Checked)
                if not FCheckedOnly or not FListView.Checkboxes or Checked then
                begin
                  // 1er colonne c'est le texte
                  ExcelOLEWorkSheet.Cells[Rx, 1].Value := Caption;
                  // les colonnes suivantes c'est les sous-texte
                  for I := 0 to SubItems.Count - 1 do
                    ExcelOLEWorkSheet.Cells[Rx, I + 2].FormulaLocal := SubItems[I];
     
                  Inc(Rx);
                end;
              end;
     
              // Patience tout les 16 lignes, c'est suffisant !
              if not ByteBool(R and $0F) then
                DoProgress(R);
            end;
     
            // Redimensionnement des colonnes par rapport aux données
            for I := 0 to FListView.Columns.Count - 1 do
              ExcelOLEWorkSheet.Columns[I + 1].AutoFit;
     
            ExcelOLE.Visible := True;
            ExcelOLE.UserControl := True;
            ExcelCaption := ExcelOLE.Caption;
     
            DoBeforeActivateExcel();
     
            // Affichera l'excel lancé (différé pour éviter que le TSLTMessageDlg reprenne le Focus)
            SetForegroundWindowAsync(ExcelCaption, 100);
     
            // un simple message servira de système d'attente, c'est pauvre mais efficace !
            if FShowWaitMessage then
              KeepOpenedExcel := (TSLTMessageDlg.Show('Excel est ouvert, continuez ...', mtConfirmation, [mbYes, mbNo], ['Fermer Excel', 'Continuer sans fermer Excel']) = mrNo);
     
          finally
            if not VarIsClear(ExcelOLEWorkbook) then
            begin
              if not KeepOpenedExcel then
                ExcelOLEWorkbook.Close(SaveChanges := False);
              ExcelOLEWorkbook := Unassigned;
            end;
          end;
     
        finally
          if not VarIsClear(ExcelOLE) then
          begin
            if not KeepOpenedExcel then
              if ExcelOLE.WorkBooks.Count = 0 then
                ExcelOLE.Quit;
            ExcelOLE := Unassigned;
          end;
        end;
     
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTExcelListViewerError.CreateFmt('Erreur durant la Fermeture de la Visualisation sous Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTExcelListViewerError.CreateFmt('Erreur durant la Visualisation sous Excel : %s', [E.Message]);
      end;
    end;
     
    { TSLTXLSReader }
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.Close();
    begin
      try
        FExcelOLEWorkSheet := Unassigned;
     
        try
          if not VarIsClear(FExcelOLEWorkbook) then
          begin
            FExcelOLEWorkbook.Close(SaveChanges := False);
            FExcelOLEWorkbook := Unassigned;
          end;
        except
          // On ignore cette erreur !
          FExcelOLEWorkbook := Unassigned;
        end;
     
        if not VarIsClear(FExcelOLE) then
        begin
          if FExcelOLE.WorkBooks.Count = 0 then
            FExcelOLE.Quit;
          FExcelOLE := Unassigned;
        end;
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTXLSReaderError.CreateFmt('Erreur durant la Fermeture du lecteur de fichier Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTXLSReaderError.CreateFmt('Erreur durant la Fermeture du lecteur de fichier Excel : %s', [E.Message]);
      end;
    end;
     
    //------------------------------------------------------------------------------
    constructor TSLTXLSReader.Create();
    begin
      inherited Create();
     
    end;
     
    //------------------------------------------------------------------------------
    destructor TSLTXLSReader.Destroy();
    begin
      Close();
     
      inherited Destroy();
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetEOF(): Boolean;
    begin
      Result := FRow >= FExcelOLEWorkRows.Count;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetExpectedColumnCount(): Integer;
    begin
      Result := FExpectedColumnCount;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetExpectedSheetName(): string;
    begin
      Result := FExpectedSheetName;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetFileName(): TFileName;
    begin
      Result := FFileName;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.GetFormatSpecification(): ISLTXLSFormatSpecification;
    begin
      Result := Self;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.Next();
    begin
      Inc(FRow);
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.Open();
     
      function FindFirstSheet(AWorkbook: OleVariant): OleVariant;
      begin
        // Sheets.Item is one-based !
        Result := Unassigned;
        if FExcelOLEWorkbook.Sheets.Count >= 1 then
          Result := FExcelOLEWorkbook.Sheets.Item[1];
      end;
     
      function FindSheet(AWorkbook: OleVariant; const ASheetName: string): OleVariant;
      var
        I: Integer;
      begin
        // Sheets.Item is one-based !
        for I := 1 to FExcelOLEWorkbook.Sheets.Count do
        begin
          Result := FExcelOLEWorkbook.Sheets.Item[I];
          if SameText(Result.Name, ASheetName) then
            Exit;
        end;
     
        Result := Unassigned;
      end;
     
    begin
      FExcelOLEWorkRows := Unassigned;
      FExcelOLEWorkSheet := Unassigned;
      FExcelOLEWorkbook := Unassigned;
      FExcelOLE := Unassigned;
      // Cells is one-based, la première opération de ReadNextLine doit être l'incrémentation de l'indice de ligne FRow  !
      FRow := 0;
     
      try
        // Code en LateBinding !
        FExcelOLE := System.Win.ComObj.CreateOleObject('Excel.Application');
     
        // Excel caché
        FExcelOLE.UserControl := False;
        FExcelOLE.Visible := False;
        FExcelOLEWorkbook := FExcelOLE.WorkBooks.Open(FFileName);
     
        // Recherche de la Feuille
        if FExpectedSheetName <> '' then
        begin
          FExcelOLEWorkSheet := FindSheet(FExcelOLEWorkbook, FExpectedSheetName);
          if VarIsEmpty(FExcelOLEWorkSheet) then
            raise ESLTXLSReaderError.CreateFmt('Erreur durant l''Ouverture du fichier Excel : Feuille "%s" non trouvée', [FExpectedSheetName]);
        end
        else
        begin
          FExcelOLEWorkSheet := FindFirstSheet(FExcelOLEWorkbook);
          if VarIsEmpty(FExcelOLEWorkSheet) then
            raise ESLTXLSReaderError.Create('Erreur durant l''Ouverture du fichier Excel : Aucune feuille trouvée');
        end;
     
        // Obtention des données présentes de la Feuille
        FExcelOLEWorkRows := FExcelOLEWorkSheet.UsedRange.Rows;
     
        if VarIsEmpty(FExcelOLEWorkSheet) then
          raise ESLTXLSReaderError.Create('Erreur durant l''Ouverture du fichier Excel : Aucune donnée trouvée');
      except
        on EOSE: EOleSysError do
          if EOSE.ErrorCode <> RPC_E_DISCONNECTED then
            raise ESLTXLSReaderError.CreateFmt('Erreur durant l''Ouverture du lecteur de fichier Excel : %s', [EOSE.Message]);
        on E: Exception do
          raise ESLTXLSReaderError.CreateFmt('Erreur durant l''Ouverture du lecteur de fichier Excel : %s', [E.Message]);
      end;
    end;
     
    //------------------------------------------------------------------------------
    function TSLTXLSReader.ReadNextLine(out AXLSLine: TStringDynArray): Boolean;
    var
      I, Col, ColCount, OutCount: Integer;
    begin
      Inc(FRow);
     
      ColCount := FExcelOLEWorkRows.Columns.Count;
      // Le nombre de colonne attendu n'est fourni qu'après avoir lu l'entête
      if FExpectedColumnCount > 0 then
        OutCount := FExpectedColumnCount
      else
        OutCount := ColCount;
     
      SetLength(AXLSLine, OutCount);
      for I := Low(AXLSLine) to High(AXLSLine) do
      begin
        // Columns is one-based !
        Col := I + 1;
        if Col <= ColCount then
          AXLSLine[I] := FExcelOLEWorkRows.Cells.Item[FRow, Col];
      end;
     
      Result := True;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.SetExpectedColumnCount(const Value: Integer);
    begin
      FExpectedColumnCount := Value;
    end;
     
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.SetExpectedSheetName(const Value: string);
    begin
      FExpectedSheetName := Value;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSLTXLSReader.SetFileName(const Value: TFileName);
    begin
      FFileName := Value;
    end;
     
    { procedural code declarations }
     
    //------------------------------------------------------------------------------
    procedure SetForegroundWindowAsync(const AWindowExcelCaption: string; Delay: Cardinal = INFINITE);
    begin
      TThread.CreateAnonymousThread(
        procedure
        var
          Tentative: Integer;
          ExcelWnd: HWND;
          ForegroundedExcel: Boolean;
        begin
          Tentative := 0;
          repeat
            if Delay <> INFINITE then
              Sleep(Delay);
     
            ExcelWnd := FindWindow(nil, PChar(AWindowExcelCaption));
            ForegroundedExcel := (SetForegroundWindow(ExcelWnd) or LongBool(SetActiveWindow(ExcelWnd)))
              and (GetForegroundWindow() = ExcelWnd);
     
            Inc(Tentative);
          until ForegroundedExcel or (Tentative > 5);
     
        end).Start();
    end;
     
     
    end.
    Merci beaucoup ShaiLeTroll pour le code.
    mais je crois que mon niveau et bien loin pour comprendre ton bout de code.

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

Discussions similaires

  1. [C# 2.0] Problème de conversion de type
    Par freerider1 dans le forum Windows Forms
    Réponses: 18
    Dernier message: 11/08/2017, 13h50
  2. [WD10] Problème de conversion de type
    Par rphenix dans le forum WinDev
    Réponses: 2
    Dernier message: 15/01/2007, 14h22
  3. [Excel] Problème de conversion de type de données
    Par keiserjo dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 25/07/2006, 12h26
  4. Réponses: 2
    Dernier message: 20/05/2006, 17h57
  5. Réponses: 6
    Dernier message: 07/04/2006, 18h23

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