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

Delphi Discussion :

Pilotage Excel par Delphi : Mettre du code VBA dans une feuille


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut Pilotage Excel par Delphi : Mettre du code VBA dans une feuille
    Bonjour,
    J’ai un programme Delphi qui créée des fichiers Excel et je voudrais placer du code VBA dans une feuille mais ne sais pas comment procéder.
    Certains parmi vous ont certainement la solution ; merci pour votre aide.

  2. #2
    Membre expérimenté
    Avatar de XeGregory
    Homme Profil pro
    Passionné par la programmation
    Inscrit en
    Janvier 2017
    Messages
    464
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Passionné par la programmation
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2017
    Messages : 464
    Par défaut
    Citation Envoyé par hescallier Voir le message
    Bonjour,
    J’ai un programme Delphi qui créée des fichiers Excel et je voudrais placer du code VBA dans une feuille mais ne sais pas comment procéder.
    Certains parmi vous ont certainement la solution ; merci pour votre aide.
    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
    uses
      ComObj;
     
    {$R *.dfm}
     
    procedure InsertVBAExcel();
    var
      ExcelApp, WorkBook, Feuille, VBComponent, CodeModule: OleVariant;
      CodeAJouter: string;
    begin
      ExcelApp := CreateOleObject('Excel.Application');
      ExcelApp.Visible := True;
     
      WorkBook := ExcelApp.Workbooks.Add;
      Feuille := WorkBook.Worksheets[1];
     
      // Récupération du module VBA associé à la feuille
      VBComponent := WorkBook.VBProject.VBComponents[Feuille.CodeName];
      CodeModule := VBComponent.CodeModule;
     
      CodeAJouter :=
        'Sub AfficherMessage()' + sLineBreak +
        '    MsgBox "Hello from VBA!"' + sLineBreak +
        'End Sub';
     
      CodeModule.AddFromString(CodeAJouter);
    end;
    Vous ne pouvez pas faire confiance à un code que vous n'avez pas totalement rédigé vous-même.
    Ce n’est pas un bogue - c’est une fonctionnalité non documentée.

  3. #3
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    Octobre 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2015
    Messages : 10
    Par défaut Pilotage Excel par Delphi : Mettre du code VBA dans une feuille
    Bonjour,
    Merci pour votre réponse.
    Je ne maîtrise pas les propriétés et paramètres d'une feuille Excel.
    L'exécution de la procédure InsertVBAExcel provoque une erreur avec valeur inaccessible pour CodeName !
    Merci pour votre aide.

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 083
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 083
    Par défaut
    Propriété Worksheet.CodeName (Excel)
    VBProject et VBComponents à lire

    Quelle est l'erreur exacte ?
    Est-ce la propriété CodeName qui n'est pas compilé en LateBinding ?
    Est-ce la valeur de la propriété CodeName qui n'est pas accepté par VBComponents ? Par exemple "l'indice n'appartient pas à la sélection"
    Est-ce que "Microsoft Visual Basic for Applications Extensibility 5.3" est installé ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ShowMessage(Feuille.CodeName);
    ShowMessage(WorkBook.VBProject.Name);
    ShowMessage(IntToStr(WorkBook.VBProject.VBComponents.Count));
    for I := 1 to WorkBook.VBProject.VBComponents.Count do
      ShowMessage(IntToStr(WorkBook.VBProject.VBComponents.Item[1].CodeName));
    ShowMessage(WorkBook.VBProject.VBComponents[Feuille.CodeName];
    Que donne aussi ShowMessage(ExcelApp.VBE.ActiveVBProject.Name) ?

    En LateBinding, avec OLE faut y aller pas à pas, c'est compilé en RunTime donc le code peut-être inexacte en DesignTime et les erreurs se produisent plus tard.
    Propriété mal nommée par exemple ou sur le mauvais objet receveur
    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

  5. #5
    Membre Expert Avatar de Godzestla
    Homme Profil pro
    Chercheur de bonheur
    Inscrit en
    Août 2007
    Messages
    2 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de bonheur
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2007
    Messages : 2 403
    Par défaut
    Bonjour,
    au cas ou le sujet est toujours ouvert j'ai une double solution en Delphi qui peut éventuellement connvenir :
    Solution 1 : Creation d'un fichier .XLSX par export de données depuis un serveur puis exécution d'un script VBA présent dans un .XLSM sur les données exportées. Au final, le fichier .XLSX est reformatté, mais il ne contient aucun code VBA.
    Solution 2 : Création d'un fichier .XLSL par export de données depuis un serveur puis insertion d'un code VBA dans ce fichier par import de ce meme code présent dans un fichier texte. Au final le fichier .XLSX est reformatté et le code .VBA n'est pas sauvé. (car XLSX au lieu de XLSM). Mais c'est simple a changer en XLSM pour conserver le VBA.

    le tout entiereent parametrable : fichier destination, feuille, code vba a exécuter, parametres a utiliser...

    Seule contrainte, l'accès programmatique au VBA ne doit pas être bloqué.

    Si besoin, faites moi un message et je partagerai.
    (\ _ /) Cordialement G@dz
    (='.'=)

    (")-(") Vous avez des neurones. Sollicitez-les. :zen::ptdr:. Si vous êtes aidé, pensez à Voter.:ave:

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 60
    Par défaut
    Citation Envoyé par hescallier Voir le message
    Bonjour,
    J’ai un programme Delphi qui créée des fichiers Excel et je voudrais placer du code VBA dans une feuille mais ne sais pas comment procéder.
    Certains parmi vous ont certainement la solution ; merci pour votre aide.
    salut regarde le code joint, il met du VBA dans ecxel
    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
    unit Unit11;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ComObj, Vcl.StdCtrls;
     
    type
      TForm11 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Button4: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        procedure CreateExcelWithMacro;
        procedure AjouterUserFormDansExcel;
        procedure InsererMacroDansFeuille;
     
     
      end;
     
    var
      Form11: TForm11;
     
    implementation
     
    {$R *.dfm}
    var
      ExcelApp, Workbook : OleVariant;
     
    procedure TForm11.InsererMacroDansFeuille;
    var
    //  ExcelApp, Workbook,
      VBComponent: OleVariant;
      MacroCode: string;
    begin
      // Lancer Excel
    //  ExcelApp := CreateOleObject('Excel.Application');
    //  ExcelApp.Visible := True;
     
      // Créer un nouveau classeur
    //  Workbook := ExcelApp.Workbooks.Add;
     
      // Accéder au module de code de la première feuille ("Feuil1")
      VBComponent := Workbook.VBProject.VBComponents.Item('Feuil1');  // ou "Sheet1" selon Excel
     
    {  // Code à insérer   ('ThisWorkbook');
      MacroCode :=
      'Private Sub Workbook_Open()' + #13#10 +
      '   MsgBox "Ce classeur vient d’être ouvert."' + #13#10 +
      'End Sub';  }
      // Code à insérer   ('Feuil1')
      MacroCode :=
        'Private Sub Worksheet_SelectionChange(ByVal Target As Range)' + #13#10 +
        '   MsgBox "Tu as sélectionné " & Target.Address' + #13#10 +
        'End Sub';
     
      // Écrire dans le module
      VBComponent.CodeModule.AddFromString(MacroCode);
    end;
     
     
    procedure TForm11.CreateExcelWithMacro;
    var
      Module: OleVariant;
      VBAcode: string;
    begin
      // Lancer Excel
      ExcelApp := CreateOleObject('Excel.Application');
      ExcelApp.Visible := True; // Optionnel
     
      // Créer un nouveau classeur
      Workbook := ExcelApp.Workbooks.Add;
     
      // Ajouter un module VBA
      Module := Workbook.VBProject.VBComponents.Add(1); // 1 = Module standard
      {1 – Module standard :
        Contient des fonctions et procédures générales (Sub, Function)
        C’est ce qu’on utilise pour ajouter une macro "classique"
        Exemple : Sub HelloWorld()
    2 – Module de classe :
        Contient du code orienté objet (Class)
        Tu peux créer des objets, définir des propriétés, méthodes, etc.
    3 – UserForm :
        Crée une interface utilisateur (formulaire avec boutons, zones de texte...)
        Tu peux ensuite modifier son design et son code via VBA ou Delphi
    100 – Module document :
        Lié aux objets comme Feuil1 ou ThisWorkbook
        Ne peut pas être ajouté dynamiquement
        Tu peux y accéder, mais pas le créer depuis Add(...)
        voir procedure  InsererMacroDansFeuille}
     
      // Définir le code VBA de la macro
      VBAcode :=
        'Sub HelloWorld()' + #13#10 +
        '    MsgBox "Bonjour depuis Delphi!"' + #13#10 +
        'End Sub';
     
      // Insérer le code dans le module
      Module.CodeModule.AddFromString(VBAcode);
     
      // Sauvegarder le fichier avec macros (.xlsm)
      Workbook.SaveAs('C:\Temp\DelphiMacro.xlsm', 52); // 52 = xlOpenXMLWorkbookMacroEnabled
     
      // Optionnel : exécuter la macro
      // ExcelApp.Run('HelloWorld');
     
      // Libérer Excel si nécessaire
      // ExcelApp.Quit;
    end;
     
    procedure TForm11.Button1Click(Sender: TObject);
    begin
      CreateExcelWithMacro;
    end;
     
    procedure TForm11.Button2Click(Sender: TObject);
    var ExcelSheet  : variant;
        CellRange: variant;
      CellLeft, CellTop, CellWidth, CellHeight: Double;
      Btn: Variant;
    begin
     
      ExcelSheet := ExcelApp.ActiveSheet;
     
      cellRange := ExcelSheet.Range['K4', 'K4'];
      CellLeft := CellRange.Left;
      CellTop := CellRange.Top;
      CellWidth := CellRange.Width;
      CellHeight := CellRange.Height;
     
      Btn := ExcelSheet.Buttons.Add(CellLeft, CellTop, CellWidth, CellHeight);
      Btn.OnAction := 'HelloWorld';
      Btn.Caption := 'Execute Macro';
      // 1 = déplace et redimensionne avec les cellules
      // 2 = déplace mais ne redimensionne pas
      // 3 = ne bouge pas
      Btn.Placement := 1;
     
     
    end;
     
    procedure TForm11.AjouterUserFormDansExcel;
    var
       VBComp, Btn, CodeModule: OleVariant;
      Ligne: Integer;
    begin
     
      if VarIsNull(ExcelApp) = false then
      begin
      // Lancer Excel
        ExcelApp := CreateOleObject('Excel.Application');
        ExcelApp.Visible := True;
      // Créer un nouveau classeur
        Workbook := ExcelApp.Workbooks.Add;
      end;
      // Ajouter un UserForm
     
      VBComp := Workbook.VBProject.VBComponents.Add(3); // UserForm
      VBComp.Name := 'MonFormulaire';
      VBComp.Designer.Caption := 'Formulaire depuis Delphi';
     
      // Ajouter un bouton au UserForm
      Btn := VBComp.Designer.Controls.Add('Forms.CommandButton.1');
      Btn.Name := 'btnBonjour';
      Btn.Caption := 'Dire Bonjour';
      Btn.Left := 20;
      Btn.Top := 20;
      Btn.Width := 100;
     
      // Ajouter du code VBA derrière le bouton
      CodeModule := VBComp.CodeModule;
      Ligne := CodeModule.CountOfLines + 1;
      CodeModule.InsertLines(Ligne,
        'Private Sub btnBonjour_Click()' + sLineBreak +
        '    MsgBox "Salut ! Ce formulaire a été généré avec Delphi."' + sLineBreak +
        'End Sub');
     
      // Ajouter une macro dans un module standard pour afficher le formulaire
      var ModStandard := Workbook.VBProject.VBComponents.Add(1); // Module standard
      ModStandard.CodeModule.AddFromString(
        'Sub AfficherFormulaire()' + sLineBreak +
        '    MonFormulaire.Show' + sLineBreak +
        'End Sub');
     
      // Exécuter la macro pour montrer le UserForm
      ExcelApp.Run('AfficherFormulaire');
    end;
     
    procedure TForm11.Button3Click(Sender: TObject);
    begin
      AjouterUserFormDansExcel;
    end;
     
    procedure TForm11.Button4Click(Sender: TObject);
    begin
      InsererMacroDansFeuille;
    end;
     
    end.
    en espérant que ça te convienne

Discussions similaires

  1. Réponses: 9
    Dernier message: 21/08/2020, 17h13
  2. [XL-2016] Problème de code vba dans une formulaire personalisé sur excel v2016
    Par ShadeKode dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 20/06/2018, 01h47
  3. Ajouter un code VBA dans une feuille Excel par macro
    Par arnaud03 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 27/09/2015, 03h57
  4. Réponses: 2
    Dernier message: 11/06/2008, 14h38
  5. Affectation code VBA dans une feuille xls
    Par anisr dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 24/02/2007, 13h52

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