Contact étroit entre Delphi et Excel [Wang Anpeng ([email protected]) 2002/4/14] En tant qu'excellent RAD, la puissante fonction de base de données de Delphi est l'une de ses fonctionnalités les plus importantes, mais le contrôle QuickReport, difficile à utiliser, ne peut souvent pas satisfaire les besoins de reporting de la base de données. Si votre rapport est très complexe ou nécessite une flexibilité dans les changements de format, utiliser Excel comme serveur de rapports est un bon choix. Le composant Excel fourni par Delphi à partir de la version 5 simplifie grandement l'application de la technologie d'automatisation OLE. Cependant, les fichiers d'aide manquants ont toujours été l'aspect le plus critiqué de Delphi, et ces nouveaux composants ne font pas exception. Le modèle objet d'Excel est une structure hiérarchique arborescente. La racine est l'application elle-même et l'objet attribut de l'objet racine. La feuille de travail utilisée pour l'échange de données principalement abordée dans cet article est l'objet attribut du classeur. Pour plus de détails, veuillez vous référer au fichier d'aide MSOffice Excel VBA. Pour contrôler Excel dans Delphi, vous devez d'abord établir une connexion avec le programme serveur, ouvrir le classeur, puis échanger des données avec la feuille de calcul cible et enfin vous déconnecter. Ouvrir le classeur Excel Notre exemple commence avec un formulaire principal avec un TStringGrid (bien sûr, certaines données doivent être renseignées) et deux boutons Faites glisser un contrôle TExcelapplication depuis l'onglet Serveurs du panneau de configuration et placez-le sur le formulaire. Tout d’abord, définissez ConnectKind sur ckRunningOrNew, ce qui signifie que si l’instance Excel en cours d’exécution peut être détectée, établissez le contact avec elle, sinon démarrez Excel. De plus, si vous souhaitez que le programme établisse un contact avec le programme serveur dès son exécution, vous pouvez définir la propriété AutoConnect sur True. Il suffit d'une seule instruction pour établir le contact avec Excel : Excel . Connect ; Vous avez peut-être remarqué qu'il existe plusieurs autres contrôles Excel sur l'onglet Serveurs. Ces contrôles peuvent être liés à l'Excel précédent via la méthode ConnectTo : ExcelWorkbook1.ConnectTo(. Excel . ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel . ActiveSheet comme _Worksheet2.ConnectTo(Excel . Worksheets.Item['Sheet2'] comme _Worksheet); Il convient de noter que le classeur ou la feuille de calcul correspondant doit être ouvert avant d'utiliser la méthode ConnectTo. De plus, ces contrôles n'apporteront pas de commodité supplémentaire dans la plupart des cas, il est donc préférable d'utiliser un seul TExcelApplication. Une fois le contact établi avec le serveur Excel, un nouveau classeur peut être créé : var wkBook : _WorkBook; LCID : Integer; ... LCID := GetUserDefaultLCID(); function Le premier paramètre est utilisé pour définir le modèle utilisé pour le nouveau classeur. Vous pouvez utiliser xlWBATChart, xlWBATExcel4IntlMacroSheet, Constante xlWBATExcel4MacroSheet ou xlWBATWorksheet, ou il peut s'agir du nom d'un fichier xls existant. Le EmptyParam est ici l'unité Variants et la variable définie, ce qui signifie utiliser le modèle universel par défaut pour créer un nouveau classeur. Si vous ouvrez un document xls existant, vous devez passer le nom du fichier à ouvrir en premier paramètre à la fonction Open : wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam , Param Vide, Param Vide, Param Vide, Param Vide, EmptyParam,EmptyParam,LCID); Vous devez savoir que toutes les opérations sur les données concernent principalement la feuille de calcul active. L'instruction suivante utilise une variable _WorkSheet pour représenter la cellule active actuelle. Si vous connaissez le nom de la feuille de calcul, le numéro d'index peut être remplacé par le nom de la feuille de calcul : wkSheet:=wkBook.Sheets[1] as _WorkSheet Après avoir terminé l'échange de données, vous devez enregistrer le classeur : Excel.ActiveWorkBook.SaveAs ; ('MaSortie', VideParam, VideParam, VideParam, VideParam, VideParam, VideParam, VideParam, VideParam, EmptyParam, EmptyParam, LCID); ou : Excel.ActiveWorkBook.Save(LCID); Enfin, fermez le classeur et déconnectez-vous d'Excel : wkBook.Close(True, SaveAsName, EmptyParam, LCID); ; La méthode Close contient ici la fonction de sauvegarde. Le premier paramètre indique s'il faut enregistrer les modifications avant de fermer le classeur. Le deuxième paramètre donne le nom du fichier à enregistrer. Le troisième paramètre est utilisé pour que plusieurs auteurs traitent la situation du document. La deuxième ligne demande de mettre fin à Excel. Échange de données avec la feuille de calcul Les données d'entrée sont effectuées sur une certaine cellule ou plage de la feuille de calcul active. La plage et les cellules sont toutes deux des propriétés d'objet de la feuille de calcul. Cells est une collection de cellules si aucun emplacement spécifique n'est spécifié, elle peut représenter toutes les cellules de la feuille de calcul entière. Cependant, elle est généralement utilisée pour faire référence à une cellule spécifique. représente la cellule la plus récente. Cell A1 dans le coin supérieur gauche. Notez que Item est la propriété par défaut des cellules dans VBA et peut être omise, mais cette commodité n'existe pas dans Delphi. Pour attribuer une valeur à une cellule, vous devez vous référer à sa propriété Value. Il va de soi que cette propriété est une variable Variant, par exemple : wkSheet.Cells.Item[1, 1].Value := 'Address Book'; Bien sûr, vous pouvez également attribuer une valeur à une cellule. Spécifiez la formule : var AFormula:String …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; La méthode ci-dessus est très directe et simple, mais elle est très lente et ne convient pas aux rapports volumineux. Alors, toutes les données peuvent-elles être transférées vers Excel dans l’ordre ? Nous pouvons utiliser Range. Cet objet représente une zone dans la feuille de calcul. Lorsque nous faisons glisser la souris, il s'agit généralement d'une zone rectangulaire. Donnez simplement les positions de ses cellules du coin supérieur gauche et du coin inférieur droit, telles que Range[ 'C3. ','J42']. Il y a ici un petit problème, car si les données dépassent 26 colonnes (par exemple, il y a 100 colonnes) ou si la plage cible doit être déterminée à la volée, il est plus gênant d'utiliser des noms de caractères pour marquer les cellules. Rappelez-vous que puisque "C3" est l'étiquette de la cellule, nous pouvons bien sûr également utiliser des cellules, telles que Range[Cells.Item[1,1], Cells.Item[100,100]]. Il est concevable que la valeur de Range soit un tableau, mais vous ne devez pas utiliser Array dans Delphi pour lui attribuer une valeur ! Rappelons que dans Delphi, la valeur d'un objet Excel est toujours de type Variant. var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //Créez un tableau dynamique 100*100 ici… //Attribuez des valeurs au éléments du tableau ici avec wkSheet do Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; Il convient de noter que la feuille de calcul et Range ont la propriété Cells Pour plus de clarté, l'instruction with est utilisée ici. De plus, Range est directionnel. Un tableau unidimensionnel créé avec VarArrayCreate ne peut être affecté qu'à une plage à une seule ligne. Si vous souhaitez définir une valeur pour une plage à une seule colonne, vous devez utiliser un tableau à deux dimensions, par exemple. exemple : Datas:=VarArrayCreate([1,100,1 ,1], varVariant); //Créer un tableau dynamique 100*1. À propos, Cells.Item[] renvoie en fait un objet Range. La récupération des données de la feuille de calcul est essentiellement le processus inverse de l'écriture des données. Il faut prêter attention à la façon de déterminer la plage de données de la feuille de calcul : var ir, ic : Integer; ).Activer ; ir := Excel.ActiveCell.Row; ic := Excel.ActiveCell.Column; La fonction de cellule spéciale SpecialCells est ici intelligemment utilisée pour obtenir la dernière cellule contenant des données. Édition des données Vous trouverez ci-dessous deux exemples d'édition de données. var DestRange: OleVariant; start DestRange := Excel.Range['C1', 'D4']; Excel.Range['A1', 'B4'].Copy(DestRange); Si vous transmettez un paramètre vide à la fonction Copier, les données de cette zone sont copiées dans le presse-papiers et peuvent être collées ultérieurement vers d'autres emplacements à l'aide de la méthode Coller. var WS: _Worksheet; …… Excel.Range['A1', 'B4'].Copy(EmptyParam); // Copier les données d'une feuille de calcul dans le presse-papiers WS := Excel.Activesheet as _Worksheet; .Range['C1', 'D4'].Select; WS.Paste(EmptyParam, EmptyParam, lcid); //Collez le contenu du presse-papiers dans une nouvelle feuille de calcul. Paramètres de format Choisissez Excel comme serveur de rapports principalement en raison de ses puissantes capacités de formatage. Nous fusionnons d'abord les cellules avec le titre « Carnet d'adresses » et l'affichons au centre, puis changeons la police en « script officiel » de 18 points en gras : avec wkSheet.Range['A1','D1'],Font do start Merge(True ); //Fusionner les cellules HorizontalAlignment:= xlCenter; Size:=18; Si le contenu de la cellule est long, une partie du contenu ne sera pas affichée. L'approche habituelle consiste à double-cliquer sur le bord droit de la zone sélectionnée afin que la largeur de chaque colonne s'adapte automatiquement à la longueur du contenu. Dans Delphi, la largeur de colonne et la hauteur de ligne adaptatives peuvent également être obtenues via la méthode AutoFit. Il convient de noter que cette méthode ne peut être utilisée que pour la ligne entière et la colonne entière, sinon une erreur de refus d'exécution de la méthode OLE sera générée : wkSheet.Columns.EntireColumn.AutoFit ; les rapports de style chinois nécessitent généralement des lignes de tableau majuscules en haut et en bas, et vous pouvez utiliser la propriété de collection Borders. Il convient de noter que les objets de collection dans VBA ont généralement une propriété Item par défaut, qui ne peut être omise dans Delphi. La propriété Weight est utilisée pour définir l'épaisseur des lignes du tableau : avec Aname.RefersToRange,Borders do start HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium; Item[xlEdgeTop].Weight:=xlMedium; .Poids : =xlThin ; item[xlInsideVertical].Weight:=xlThin end; La mise en page et la mise en page d'impression sont définies via la propriété d'objet PageSetUp de la feuille de calcul. Il existe plus de 40 constantes de papier prédéfinies dans Excel VBA. Il convient de noter que certaines imprimantes ne prennent en charge que certains types de papier. L'attribut Orientation est utilisé pour contrôler la direction de l'impression, et la constante paysage = 2 indique une impression horizontale. Les propriétés booléennes CenterHorizontally et CenterVertical sont utilisées pour déterminer si le contenu imprimé est centré horizontalement et verticalement. avec wkSheet.PageSetUp do start PaperSize:=xlPaperA4; //Type de papier A4 PRintTitleRows := 'A1:D1'; //Répétez cette ligne/page LeftMargin:=18; 0,25" varie selon les imprimantes. TopMargin:=36; //0.5" BottomMargin:=36; //0.5" CenterHorizontally:=True; Orientation:=1; //Impression horizontale (paysage)=2, portrait=1 fin; Pour imprimer un rapport, vous pouvez appeler la méthode PrintOut de la feuille de calcul. Cette méthode définie par VBA a 8 paramètres facultatifs. , les deux premiers sont utilisés pour spécifier les pages de début et de fin, ainsi que le nombre de copies à imprimer dans le troisième format. Cependant, dans Delphi, un paramètre LCID est ajouté à la fin, et EmptyParam ne peut pas être utilisé. pour ce paramètre. De même, la méthode d'aperçu avant impression PrintPreview n'a aucun paramètre dans VBA, mais nécessite deux paramètres lorsqu'elle est appelée dans Delphi. // wkBook.PrintPreview(True,LCID); //pour prévisualiser wkSheet.PrintOut(EmptyParam,EmptyParam,1, EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,LCID); plus complexe, une meilleure approche consiste à nommer des plages de tables spécifiques, puis à les référencer par leur nom. Names est une propriété d'objet de collection de WorkBook, qui possède une méthode Add capable d'effectuer ce travail. Var Aname : Excel2000.Name; …… Aname := wkBook.Names.Add('Carnet d'adresses','=Sheet1!$A$3:$D$7', EmptyParam, EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam, EmptyParam, EmptyParam,EmptyParam); Le premier paramètre de la fonction Ajouter est le nom défini et le deuxième paramètre est la plage de cellules représentée par le nom. A noter que le type du nom de plage doit utiliser un qualificateur Si une bibliothèque de types (D4) est utilisée, le qualificateur est Excel_TLB. De plus, la plage nommée doit utiliser une référence absolue, c'est-à-dire ajouter le symbole « $ ». Une fois que vous avez nommé une plage, vous pouvez la référencer par ce nom. La ligne de code suivante fait apparaître le contenu du carnet d'adresses en gras : AName.RefersToRange.Font.Bold:=True Mais la chose la plus surprenante est peut-être que vous pouvez le faire de manière dynamique ; modifiez les programmes de macros Excel dans Delphi ! Le code suivant crée une macro pour notre classeur qui enregistre l'heure du dernier accès lors de la fermeture du classeur : var LineNo: integer; CM: CodeModule; sDate:String; begin CM := WkBook.VBProject.VBComponents.Item( 'ThisWorkbook'). Codemodule; LineNo := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='Date du dernier accès:'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+''"'); la macro Ajouter une unité à la section d'utilisations précédente : VBIDE2000 Si une bibliothèque de types est utilisée, l'unité correspondante est VBIDE_TLB. La clé de ce code est l'objet CodeModule. Malheureusement, il n'y a aucune trace de cet objet dans le document d'aide Excel VBA, nous ne pouvons donc rechercher que MSDN. Delphi4 et versions précédentes Delphi4 ne fournit pas l'objet TExcelApplication et une bibliothèque de types doit être introduite pour utiliser la technologie d'automatisation OLE. La bibliothèque de types d'Excel97 est Excel8.olb. La principale différence entre ces deux méthodes réside dans la méthode d'établissement d'une connexion avec le programme serveur. Voici le cadre du programme pour contrôler Excel via la bibliothèque de types : utilise Windows, ComObj, ActiveX, var Excel : _Application ; ; Inconnu : IUnknown ; Résultat : HResult ; début LCID := LOCALE_USER_DEFAULT ; Résultat := GetActiveObject (CLASS_Application, nil, Inconnu); //Essayez de capturer l'instance de programme en cours d'exécution si (Result = MK_E_UNAVAILABLE) then Excel := CoApplication.Create //Démarrez une nouvelle instance de programme sinon commencez {Vérifier les erreurs lors de l'appel de la méthode GetActiveObject} OleCheck(Result); (Unknown.QueryInterface(_Application, Excel)); end; …… //Effectuer le traitement des données Excel.Visible[LCID] := True; // Excel.DisplayAlerts[LCID] := False; //Afficher la boîte de dialogue d'invite Excel.Quit; La structure try...sauf habituelle n'est pas utilisée ici car le mécanisme de gestion des exceptions nécessite des vérifications OLE complexes, ce qui réduit le coût La vitesse d'exécution de la pièce exceptée. Il convient de noter que la fonction CoApplication qui l'accompagne et certains noms de constantes générés par différentes versions de Delphi peuvent être différents, vous devez donc vérifier la bibliothèque de types correspondante. Avant d'appeler la méthode Quit, assurez-vous de libérer toutes les variables de classeur et de feuille de calcul créées dans le programme, sinon Excel risque de résider en mémoire et de s'exécuter (vous pouvez appuyer sur Ctrl+Alt+Suppr pour afficher). Il existe un petit problème lors de l'appel de GetActiveObject pour capturer l'instance du programme. Si Excel est dans un état d'exécution réduit, seul le cadre principal du programme peut être affiché et la zone utilisateur n'est pas visible. De plus, si vous ne souhaitez pas introduire de bibliothèque de types, vous pouvez également utiliser la liaison retardée, mais elle est beaucoup plus lente. L'exemple suivant déclare une variable Variant pour représenter l'application Excel : var Excel: Variant; ... try Excel := GetActiveOleObject('Excel.Application' except Excel := CreateOleObject('Excel.Application'); .Visible := Vrai; Lorsque la liaison retardée est utilisée, le compilateur ne vérifie pas la méthode objet Excel appelée, mais laisse ces tâches au programme serveur pendant l'exécution. De cette manière, un grand nombre de paramètres par défaut définis par VBA (souvent plus d'une douzaine) sont utilisés comme ils le devraient, cette méthode présente donc un avantage inattendu : le code est concis : var WBk, WS, SheetName: OleVariant; ..... WBk := Excel.WorkBooks.Open('C:/Test. xls') ;WS := WBk.Worksheets.Item['SheetName']; WS.Activate; …… WBk.Close(SaveChanges := True Excel.Quit); , juste Vous ne pouvez le faire que vous-même : const xlWBATWorksheet = -4167; …… XLApp.Workbooks.Add(xlWBatWorkSheet); Enfin, n'oubliez pas de libérer les variables après la fermeture d'Excel : Excel := Unassigned Voici le code source utilisé dans l'exemple de cet article, passé sous Delphi6+MSOffice2000; unité Unit1 ; l'interface utilise Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, OleServer, Excel2000, Grids, StdCtrls ; tapez TForm1 = class(TForm) Button1 : TButton ; procédure FormActivate (Expéditeur : TObject); Button1Click (Expéditeur : TObject ); procédure privée { Déclarations privées } ; procédure OpenExl ; procédure AddFormula ; procédure Formats ; procédure Récupérer ; procédure publique ; fin ; ; l'implémentation {$R *.dfm} utilise VBIDE2000 ; wkSheet:_WorkSheet; LCID:Entier; wkBook:_WorkBook; Rows[1].CommaText:='Zhang San, homme, 25 010-33775566'; Rows[2].CommaText:='Li Si, homme, 47 012-6574906'; Rows[3].CommaText:='Vendredi, femme ,18 061-7557381' ; Rows[4].CommaText:='Sun Tao, femme, 31,3324559'; fin; fin; procédure TForm1.OpenExl; début Connect; , LCID); wkSheet:=wkBook.Sheets[1] comme fin de procédure ; TForm1.Write2Xls; var Datas:Variant; i,j:Integer; commencer ir:=StringGrid1.RowCount; ic:=StringGrid1.ColCount Datas:=varArrayCreate([1,ir,1,ic],varVariant); :=1 à ir faire pour j:=1 à ic faire Datas[i,j]:=StringGrid1.Cells[j-1,i-1]; avec wkSheet, commencez Activate(LCID).Value:='Address Book'; .Item[3,1],cells.Item[ir+2,ic]].Value:=Fin des données; // Excel.Visible[LCID]:=True; Datas:=Non affecté ; fin de la procédure TForm1.Retrieve ; var Datas:Variant; i,j:Integer; commence par wkSheet et commence Cells.SpecialCells(xlCellTypeLastCell,EmptyParam).Activate ; =Excel.ActiveCell.Column ; Datas:=Range[Cells.Item[1,1],Cells.Item[ir,ic]].Value ; avec StringGrid1, commencez ColCount:=ic; ScrollBars:=ssBoth; à ir-1 faire pour j:=0 à ic-1 faire Cells[j,i]:=Datas[i+1,j+1] end; Datas:=Non affecté ; fin ; procédure TForm1.CloseExl ; const SaveAsName='test.xls' ; début wkBook.Close(True,SaveAsName,EmptyParam,LCID) ; Feuille de nom ; commencer AName:=wkBook.Names.Add('Carnet d'adresses','=Sheet1!$A$3:$D$7',EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam fin de la procédure TForm1); .AddFormula ; var AFormula : String ; AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula end; procédure TForm1.Formats; Font do start Merge(True); //Fusionner les cellules HorizontalAlignment:= xlCenter Size:=18; FontStyle:=Fin grasse; wkSheet.Columns.EntireColumn.AutoFit; avec Aname.RefersToRange, les bordures commencent HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium; Item[xlInsideHorizontal].Weight:=xlThin; item[xlInsideVertical].Weight:=xlThin end; procédure TFOrm1.AddMacro; entier CM: CodeModule; VBComponents.Item('ThisWorkbook').Codemodule; := CM.CreateEventProc('BeforeClose', 'Workbook'); SDate:='Date du dernier accès :'+DateToStr(Date()); CM.InsertLines(LineNo + 1, ' Range("B2").Value = "'+sDate+'"'); fin; procédure TForm1.Printit; commence par wkSheet.PageSetUp PaperSize:=xlPaperA4; //Type de papier A4 PrintTitleRows := 'A1:D1'; //Répétez cette ligne/page LeftMargin:=18; //0.25" Left Margin RightMargin:=18; //0.25" varie selon les imprimantes Marge supérieure : = 36 ; //0,5" Marge inférieure : = 36 ; //0,5 » CentreHorizontalement : = Vrai ; Orientation :=1 ; //Paysage=2, portrait=1 fin ; wkSheet.PrintOut(EmptyParam,EmptyParam,1, EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,LCID end ; ; commencez à essayer OpenExl; NameSheet; Formats; AddMacro; enfin CloseExl end; Contact étroit de Delphi avec Excel [Wang [email protected]] Delphi est une excellente base de données RAD. l'une de ses fonctionnalités les plus importantes, mais le contrôle QuickReport, difficile à utiliser, ne peut souvent pas répondre aux besoins des rapports de base de données. Si votre rapport est très complexe ou nécessite une flexibilité dans les changements de format, utiliser Excel comme serveur de rapports est un bon choix. Le composant Excel fourni par Delphi à partir de la version 5 simplifie grandement l'application de la technologie d'automatisation OLE. Cependant, les fichiers d'aide manquants ont toujours été l'aspect le plus critiqué de Delphi, et ces nouveaux composants ne font pas exception. Le modèle objet d'Excel est une structure hiérarchique arborescente. La racine est l'application elle-même et l'objet attribut de l'objet racine. La feuille de travail utilisée pour l'échange de données principalement abordée dans cet article est l'objet attribut du classeur. Pour plus de détails, veuillez vous référer au fichier d'aide MSOffice Excel VBA. Pour contrôler Excel dans Delphi, vous devez d'abord établir une connexion avec le programme serveur, ouvrir le classeur, puis échanger des données avec la feuille de calcul cible et enfin vous déconnecter. Ouvrir le classeur Excel Notre exemple commence avec un formulaire principal avec un TStringGrid (bien sûr, certaines données doivent être renseignées) et deux boutons Faites glisser un contrôle TExcelApplication depuis l'onglet Serveurs du panneau de configuration et placez-le sur le formulaire. Tout d’abord, définissez ConnectKind sur ckRunningOrNew, ce qui signifie que si l’instance Excel en cours d’exécution peut être détectée, établissez le contact avec elle, sinon démarrez Excel. De plus, si vous souhaitez que le programme établisse un contact avec le programme serveur dès son exécution, vous pouvez définir la propriété AutoConnect sur True. Il suffit d'une seule instruction pour établir le contact avec Excel : Excel . Connect ; Vous avez peut-être remarqué qu'il existe plusieurs autres contrôles Excel sur l'onglet Serveurs. Ces contrôles peuvent être liés à l'Excel précédent via la méthode ConnectTo : ExcelWorkbook1.ConnectTo(. Excel . ActiveWorkbook); ExcelWorksheet1.ConnectTo(Excel . ActiveSheet comme _Worksheet2.ConnectTo(Excel . Worksheets.Item['Sheet2'] comme _Worksheet); Il convient de noter que le classeur ou la feuille de calcul correspondant doit être ouvert avant d'utiliser la méthode ConnectTo. De plus, ces contrôles n'apporteront pas de commodité supplémentaire dans la plupart des cas, il est donc préférable d'utiliser un seul TExcelApplication. Une fois le contact établi avec le serveur Excel, un nouveau classeur peut être créé : var wkBook : _WorkBook; LCID : Integer; ... LCID := GetUserDefaultLCID(); function Le premier paramètre est utilisé pour définir le modèle utilisé pour le nouveau classeur. Vous pouvez utiliser xlWBATChart, xlWBATExcel4IntlMacroSheet, Constante xlWBATExcel4MacroSheet ou xlWBATWorksheet, ou il peut s'agir du nom d'un fichier xls existant. Le EmptyParam est ici l'unité Variants et la variable définie, ce qui signifie utiliser le modèle universel par défaut pour créer un nouveau classeur. Si vous ouvrez un document xls existant, vous devez passer le nom du fichier à ouvrir en premier paramètre à la fonction Open : wkBook:=Excel.WorkBooks.Open(edtDesFile.text,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam , Param Vide, Param Vide, Param Vide, Param Vide, EmptyParam,EmptyParam,LCID); Vous devez savoir que toutes les opérations sur les données concernent principalement la feuille de calcul active. L'instruction suivante utilise une variable _WorkSheet pour représenter la cellule active actuelle. Si vous connaissez le nom de la feuille de calcul, le numéro d'index peut être remplacé par le nom de la feuille de calcul : wkSheet:=wkBook.Sheets[1] as _WorkSheet Après avoir terminé l'échange de données, vous devez enregistrer le classeur : Excel.ActiveWorkBook.SaveAs ; ('MaSortie', VideParam, VideParam, VideParam, VideParam, VideParam, VideParam, VideParam, VideParam, EmptyParam, EmptyParam, LCID); ou : Excel.ActiveWorkBook.Save(LCID); Enfin, fermez le classeur et déconnectez-vous d'Excel : wkBook.Close(True, SaveAsName, EmptyParam, LCID); ; La méthode Close contient ici la fonction de sauvegarde. Le premier paramètre indique s'il faut enregistrer les modifications avant de fermer le classeur. Le deuxième paramètre donne le nom du fichier à enregistrer. Le troisième paramètre est utilisé pour que plusieurs auteurs traitent la situation du document. La deuxième ligne demande de mettre fin à Excel. Échange de données avec la feuille de calcul Les données d'entrée sont effectuées sur une certaine cellule ou plage de la feuille de calcul active. La plage et les cellules sont toutes deux des propriétés d'objet de la feuille de calcul. Cells est une collection de cellules si aucun emplacement spécifique n'est spécifié, elle peut représenter toutes les cellules de la feuille de calcul entière. Cependant, elle est généralement utilisée pour faire référence à une cellule spécifique. représente la cellule la plus récente. Cell A1 dans le coin supérieur gauche. Notez que Item est la propriété par défaut des cellules dans VBA et peut être omise, mais cette commodité n'existe pas dans Delphi. Pour attribuer une valeur à une cellule, vous devez vous référer à sa propriété Value. Il va de soi que cette propriété est une variable Variant, par exemple : wkSheet.Cells.Item[1, 1].Value := 'Address Book'; Bien sûr, vous pouvez également attribuer une valeur à une cellule. Spécifiez la formule : var AFormula:String …… AFormula:='=Rand()'; wkSheet.Range['F3','G6'].Value:=AFormula; La méthode ci-dessus est très directe et simple, mais elle est très lente et ne convient pas aux rapports volumineux. Alors, toutes les données peuvent-elles être transférées vers Excel dans l’ordre ? Nous pouvons utiliser Range. Cet objet représente une zone dans la feuille de calcul. Lorsque nous faisons glisser la souris, il s'agit généralement d'une zone rectangulaire. Donnez simplement les positions de ses cellules du coin supérieur gauche et du coin inférieur droit, telles que Range[ 'C3. ','J42']. Il y a ici un petit problème, car si les données dépassent 26 colonnes (par exemple, il y a 100 colonnes) ou si la plage cible doit être déterminée à la volée, il est plus gênant d'utiliser des noms de caractères pour marquer les cellules. Rappelez-vous que puisque "C3" est l'étiquette de la cellule, nous pouvons bien sûr également utiliser des cellules, telles que Range[Cells.Item[1,1], Cells.Item[100,100]]. Il est concevable que la valeur de Range soit un tableau, mais vous ne devez pas utiliser Array dans Delphi pour lui attribuer une valeur ! Rappelons que dans Delphi, la valeur d'un objet Excel est toujours de type Variant. var Datas: Variant; Ir, ic: Integer; …… Datas:= varArrayCreate([1,ir,1,ic],varVariant); //Créez un tableau dynamique 100*100 ici… //Attribuez des valeurs au éléments du tableau ici avec wkSheet do Range[cells.Item[3,1],cells.Item[ir+2,ic]].Value:=Datas; Il convient de noter que la feuille de calcul et Range ont la propriété Cells Pour plus de clarté, l'instruction with est utilisée ici. De plus, Range est directionnel. Un tableau unidimensionnel créé avec VarArrayCreate ne peut être affecté qu'à une plage à une seule ligne. Si vous souhaitez définir une valeur pour une plage à une seule colonne, vous devez utiliser un tableau à deux dimensions, par exemple. exemple : Datas:=VarArrayCreate([1,100,1 ,1], varVariant); //Créer un tableau dynamique 100*1. À propos, Cells.Item[] renvoie en fait un objet Range. La récupération des données de la feuille de calcul est essentiellement le processus inverse de l'écriture des données. Il faut prêter attention à la façon de déterminer la plage de données de la feuille de calcul : var ir, ic : Integer; ).Activer ; ir := Excel.ActiveCell.Row; ic := Excel.ActiveCell.Column; La fonction de cellule spéciale SpecialCells est ici intelligemment utilisée pour obtenir la dernière cellule contenant des données. Édition des données Vous trouverez ci-dessous deux exemples d'édition de données. var DestRange: OleVariant; start DestRange := Excel.Range['C1', 'D4']; Excel.Range['A1', 'B4'].Copy(DestRange); Si vous transmettez un paramètre vide à la fonction Copier, les données de cette zone sont copiées dans le presse-papiers et peuvent être collées ultérieurement vers d'autres emplacements à l'aide de la méthode Coller. var WS: _Worksheet; …… Excel.Range['A1', 'B4'].Copy(EmptyParam); // Copier les données d'une feuille de calcul dans le presse-papiers WS := Excel.Activesheet as _Worksheet; .Range['C1', 'D4'].Select; WS.Paste(EmptyParam, EmptyParam, lcid); //Collez le contenu du presse-papiers dans une nouvelle feuille de calcul. Paramètres de format Choisissez Excel comme serveur de rapports principalement en raison de ses puissantes capacités de formatage. Nous fusionnons d'abord les cellules avec le titre « Carnet d'adresses » et l'affichons au centre, puis changeons la police en « script officiel » de 18 points en gras : avec wkSheet.Range['A1','D1'],Font do start Merge(True ); //Fusionner les cellules HorizontalAlignment:= xlCenter; Size:=18; Si le contenu de la cellule est long, une partie du contenu ne sera pas affichée. L'approche habituelle consiste à double-cliquer sur le bord droit de la zone sélectionnée afin que la largeur de chaque colonne s'adapte automatiquement à la longueur du contenu. Dans Delphi, la largeur de colonne et la hauteur de ligne adaptatives peuvent également être obtenues via la méthode AutoFit. Il convient de noter que cette méthode ne peut être utilisée que pour la ligne entière et la colonne entière, sinon une erreur de refus d'exécution de la méthode OLE sera générée : wkSheet.Columns.EntireColumn.AutoFit ; les rapports de style chinois nécessitent généralement des lignes de tableau majuscules en haut et en bas, et vous pouvez utiliser la propriété de collection Borders. Il convient de noter que les objets de collection dans VBA ont généralement une propriété Item par défaut, qui ne peut être omise dans Delphi. La propriété Weight est utilisée pour définir l'épaisseur des lignes du tableau : avec Aname.RefersToRange,Borders do start HorizontalAlignment:= xlRight; Item[xlEdgeBottom].Weight:=xlMedium; Item[xlEdgeTop].Weight:=xlMedium; .Poids : =xlThin ; item[xlInsideVertical].Weight:=xlThin end; La mise en page et la mise en page d'impression sont définies via la propriété d'objet PageSetUp de la feuille de calcul. Il existe plus de 40 constantes de papier prédéfinies dans Excel VBA. Il convient de noter que certaines imprimantes ne prennent en charge que certains types de papier. L'attribut Orientation est utilisé pour contrôler la direction de l'impression, et la constante paysage = 2 indique une impression horizontale. Les propriétés booléennes CenterHorizontally et CenterVertical sont utilisées pour déterminer si le contenu imprimé est centré horizontalement et verticalement. avec wkSheet.PageSetUp do start PaperSize:=xlPaperA4; //Type de papier A4 PrintTitleRows := 'A1:D1'; //Répétez cette ligne/page LeftMargin:=18; //0.25" Left Margin RightMargin:=18; // 0,25" varie selon les imprimantes. TopMargin:=36; //0.5" BottomMargin:=36; CenterHorizontally:=True; Orientation:=1; //Impression horizontale (paysage)=2, portrait=1 end; Pour imprimer un rapport, vous pouvez appeler la méthode PrintOut de la feuille de calcul. Cette méthode définie par VBA en a un total de 8. paramètres facultatifs, les deux premiers Il est utilisé pour spécifier les pages de début et de fin et le nombre de copies imprimées dans le troisième format. Cependant, dans Delphi, un paramètre LCID est ajouté à la fin, et EmptyParam ne peut pas être utilisé pour ce paramètre. De même, la méthode d'aperçu avant impression PrintPreview n'a aucun paramètre dans VBA, mais nécessite deux paramètres lorsqu'elle est appelée dans Delphi. // wkbook.printpreview (true, lcid); Plus complexe, une meilleure approche consiste à nommer des gammes de table spécifiques, puis à les référencer par son nom. Noms est une propriété d'objet de collection de Workbook, qui a une méthode ADD qui peut faire ce travail. Var aname: excel2000.name; …… aname: = wkbook.names.add ('book d'adresse', '= shee VideParam, videParam); Le premier paramètre de la fonction ADD est le nom défini, et le deuxième paramètre est la plage de cellules représentée par le nom. Il convient de noter que le type de nom de plage doit utiliser un qualificatif. De plus, la plage nommée doit utiliser la référence absolue, c'est-à-dire ajouter le symbole "$". Une fois que vous nommez une plage, vous pouvez le référencer par ce nom. Modifiez les programmes de macro Excel à Delphi! Le code suivant crée une macro pour notre classeur qui enregistre le dernier temps d'accès lors de la fermeture du classeur: var lineno: entier; CodeModule; Lineno: = CM.CreateEventProc («Beforeclose», «classeur»); SDATE: = 'Dernière date d'accès:' + DateToStr (Date ()); La macro ajoute une unité à la section Utilisation précédente: vbide2000. La clé de ce code est l'objet CodeModule. Delphi4 et les versions précédentes Delphi4 ne fournit pas l'objet TexcelApplication, et une bibliothèque de type doit être introduite pour utiliser la technologie d'automatisation OLE. La principale différence entre ces deux méthodes est la méthode pour établir une connexion avec le programme du serveur. ; Inconnu); (Inconnu.QueryInterface (_Application, Excel)); Vrai; le coût à la vitesse d'exécution de la partie sauf. Il convient de noter que la coapplication de la fonction d'accompagnement et certains noms constants générés par différentes versions Delphi peuvent être différents, vous devez donc vérifier la bibliothèque de type correspondante. Avant d'appeler la méthode QUIT, assurez-vous de publier toutes les variables de classeur et de feuille de calcul créées dans le programme, sinon Excel peut résider dans la mémoire et s'exécuter (vous pouvez appuyer sur Ctrl + Alt + Del pour afficher). Il y a un petit problème avec l'appel GetActiveObject pour capturer l'instance du programme. De plus, si vous ne souhaitez pas introduire une bibliothèque de type, vous pouvez également utiliser la liaison à la traîne, mais elle est beaucoup plus lente. L'exemple suivant déclare une variante pour représenter l'application Excel: var Excel: variant; .Visible: = true; Lorsque la liaison en retard est utilisée, le compilateur ne vérifie pas la méthode d'objet Excel appelé, mais laisse ces tâches au programme de serveur à terminer pendant l'exécution. sont utilisés comme ils le devraient. xls '); ws : = Wbk.worksheets.item ['sheetname']; ws.Activate; , vous ne pouvez que le faire vous-même: const xlwbatworksheet = -4167; …… xlapp.workbooks.add (xlwbatworksheet); Enfin, n'oubliez pas de libérer les variables après la fermeture Excel: Excel: = non assisté; UNITÉ UNIQUE 1; Procédure Formativate (expéditeur: tobject); Button1Click (Procédure Privated Priva ; implémentation {$ r * .dfm} utilise vbide2000; wksheet: _Worksheet; Lignes [1] .Comatext: = 'Zhang San, mâle, 25 010-33775566'; , 18 061-7557381 '; Lignes [4] .commatext: = 'Sun Tao, 31 332459'; , LCID); Tform1.write2xls; : = 1 à ir do pour j: = 1 à ic do Datas [i, j]: = StringGrid1.Cells [J-1, i-1]; .Item [3,1], cells.item [ir + 2, ic]]. Valeur: = datas; end; Datas: = UNS ASSIGNÉ; = Excel.ActiveCell.Column; Datas: = plage [Cellules.Item [1,1], Cells.Item [ir, ic]]. à ir-1 faire pour j: = 0 à ic-1 do Cellules [j, i]: = datas [i + 1, j + 1]; DATA: = UNE ASSIGNÉ; Feuille de nom Aname: = wkbook.names.add ('Address Book', '= sheet1! $ A 3: $ d 7 $', videParam, videParam, videParam, videParam, videParam, videParam, videParam, videParam, videParam); .AddFormula; Aformula: = '= rand ()'; La police commence à fusionner (true); Fontstyle: = Bold; fin Item [xlinsideHorizontal]. VbComponents.item ('Thisworkbook'). CodeModule; : = Cmoral "+ sdate + '"); PAPERSIZE: = xlpapera4; TopMargin: = 36;; Orientation: = 1; // paysage = 2, portrait = 1 fin; ; commencer OpenExl; Format de nom