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

MFC Discussion :

excel, automation et VS 2005


Sujet :

MFC

Vue hybride

Nicolas Bauland excel, automation et VS 2005 24/08/2007, 19h47
Nicolas Bauland Bon j'ai un debut de piste... 26/08/2007, 17h46
Gabrielly OfficeImport.h : //... 27/08/2007, 00h10
Gabrielly Si tu veux, je peux te faire... 27/08/2007, 00h49
Nicolas Bauland Donc en gros, le plus simple... 29/08/2007, 12h05
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Nicolas Bauland
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 119
    Par défaut excel, automation et VS 2005
    Je cherche depuis le debut de l'apres midi a piloter excel a partir d'un programme MFC.

    Mon probleme est que je n'arrive pas a compiler: j'ai tente de suivre les procedures à partir d'une Typelib. Tout se passe bien, jusqu'a ce que je compile: je recois ca...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    ... \debug\excel.tlh(1219) : error C2371: 'FontPtr'*: redéfinition*; types de base différents
            C:\Program Files\Microsoft Visual Studio 8\VC\include\comdef.h(322)*: voir la déclaration de 'FontPtr'
    ... \debug\excel.tlh(1297) : error C2786: 'BOOL (__stdcall *)(HDC,int,int,int,int)'*: opérande non valide pour __uuidof
    ... \debug\excel.tlh(1297) : error C2923: '_com_IIID'*: 'Rectangle' n'est pas un argument de type modèle valide pour le paramètre '_Interface'
            C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\wingdi.h(3514)*: voir la déclaration de 'Rectangle'
    ...\debug\excel.tlh(1297) : error C3203: '_com_IIID'*: la classe non spécialisée modèle ne peut pas être utilisée comme argument modèle pour le paramètre modèle '_IIID'*; type réel attendu
    ... \debug\excel.tlh(1301) : error C2786: 'BOOL (__stdcall *)(HDC,int,int,int,int,int,int,int,int)'*: opérande non valide pour __uuidof
    ... \debug\excel.tlh(1301) : error C2923: '_com_IIID'*: 'Arc' n'est pas un argument de type modèle valide pour le paramètre '_Interface'
            C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include\wingdi.h(2765)*: voir la déclaration de 'Arc'
    ... \debug\excel.tlh(1301) : error C3203: '_com_IIID'*: la classe non spécialisée modèle ne peut pas être utilisée comme argument modèle pour le paramètre modèle '_IIID'*; type réel attendu
    Je n'ai mis que les premieres, il y en a plus de 100 ! Les points remplacent le chemin complet.

    Ceci vient-il de VS2005 (j'ai essaye avec VS2008 sans plus de succes !) ? D'une astuce a 2 francs six sous ?

    Dans l'ajout de classe par la typelib, j'ai essaye par le registre ou par le fichier en incluant excel.exe (c'est la version 2003).

    Tout debut de piste est le bien venu car la ...

  2. #2
    Membre expérimenté
    Avatar de Nicolas Bauland
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 119
    Par défaut
    Bon j'ai un debut de piste mais cela ne resoud pas completement mon probleme: je suis passe par un #import.

    Apres encore du temps de plantage, voila ce qui semble fonctionner:
    Dans le fichier stdafx.h, je rajoute juste apres les lignes de code suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #import "C:\Program Files\Fichiers communs\Microsoft Shared\OFFICE11\MSO.DLL" named_guids, rename("RGB", "MsoRGB")
    // The following #import is necessary for MS Office without raw_interfaces_only.. It defines VBEPtr among other things.
    #import "C:\Program Files\Fichiers communs\Microsoft Shared\VBA\\VBA6\\VBE6EXT.OLB" raw_interfaces_only
    // Import PPT's interfaces.
    #import "g:\\Program Files\\Microsoft Office\\OFFICE11\\excel.exe" \
    	rename("DialogBox","ExcelDialogBox") \
    	rename("RGB","ExcelRGB") \
    	rename("CopyFile","ExcelCopyFile") \
    	rename("ReplaceText","ExcelReplaceText") \
        exclude("IFont","IPicture")
    Je rajoute dans la fonction OnInitDialog (mon projet est une appli excel boite de dialogue):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AfxOleInit();
    CoInitialize(NULL)
    L'inconvenient de cette methode, est bien evidemment, qu'elle fait perdre les classes CApplication, CWorksheet ...

    Je ne clos pour l'instant pas le sujet car cette solution n'est pas vriament propre dans le sens ou elle ne repond pas directement au probleme pose.

  3. #3
    Membre émérite
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Par défaut
    OfficeImport.h :

    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
     
    // Define this according to the Microsoft Office Object Model version you are compiling under
    //#define OFFICE12				// MS Office 2007
    //#define OFFICE11				// MS Office 2003
    //#define OFFICE10				// MS Office 2002
    //#define OFFICE9				// MS Office 2000
    //#define OFFICE8				// MS Office 1997
     
    #if defined(OFFICE12)	// Office 2007
    	#import "E:\\Program Files\\Fichiers communs\\Microsoft Shared\\OFFICE12\\mso.dll" \
    		rename_namespace("Office") \
    		auto_rename
     
    #elif defined(OFFICE11)	// Office 2003
    	#import "E:\\Program Files\\Fichiers communs\\Microsoft Shared\\OFFICE11\\mso.dll" \
    		rename_namespace("Office") \
    		auto_rename
     
    #elif defined(OFFICE10) // Office 2002
    	#import "C:\\Program Files\\Fichiers communs\\Microsoft Shared\\OFFICE10\\mso.dll" \
    		rename_namespace("Office"), rename("DocumentProperties", "DocProps")
     
    #elif defined(OFFICE9)	// Office 2000
    	#import "C:\\Program Files\\Microsoft Office\\Office\\mso9.dll" \
    		rename_namespace("Office"), rename("DocumentProperties", "DocProps")
     
    #elif defined (OFFICE8) // Office 1997
    	#import "C:\\Program Files\\Microsoft Office\\Office\\mso97.dll" \
    		rename_namespace("Office"), rename("DocumentProperties", "DocProps")
     
    #endif // OFFICE12
     
    #if defined(VBA6)	// VBA 6
    	#import "E:\\Program Files\\Fichiers communs\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB" \
    		rename_namespace("VBA") \
    		auto_rename
     
    #endif // VBA6

    ExcelImport.h :

    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
     
    // Define this according to the Excel Object Model version you are compiling under
    //#define EXCEL12				// Excel 2007
    //#define EXCEL11				// Excel 2003
    //#define EXCEL10				// Excel 2002
    //#define EXCEL9				// Excel 2000
    //#define EXCEL8				// Excel 1997
     
    //#pragma warning(disable:4146)
     
    #define EXCEL_APPLICATION	"Excel.Application"
     
    #if defined(EXCEL12) // Excel 2007
     
    #define EXCEL_APPLICATION_2007	"Excel.Application.12"
    #define OFFICE12
    #define VBA6
    #include "..\Mcn.Office\OfficeImport.h"
     
    #import "E:\\Program Files\\Microsoft Office\\OFFICE12\\Excel.EXE" \
    	rename_namespace("Excel") \
    	auto_rename \
    	include("IFont", "IPicture")
     
    #elif defined(EXCEL11) // Excel 2003
     
    #define EXCEL_APPLICATION_2003	"Excel.Application.11"
    #define OFFICE11
    #define VBA6
    #include "..\Mcn.Office\OfficeImport.h"
     
    #import "E:\\Program Files\\Microsoft Office\\OFFICE11\\Excel.EXE" \
    	rename_namespace("Excel") \
    	auto_rename \
    	include("IFont", "IPicture")
     
    #elif defined(EXCEL10) // Excel 2002
     
    #define EXCEL_APPLICATION_2002	"Excel.Application.10"
    #define OFFICE10
    #define VBA6
    #include "..\Mcn.Office\OfficeImport.h"
     
    #import "C:\\Program Files\\Microsoft Office\\OFFICE10\\Excel.EXE" \
    	rename_namespace("Excel") \
    	auto_rename
     
    #elif defined(EXCEL9) // Excel 2000
     
    #define EXCEL_APPLICATION_2000	"Excel.Application.9"
    #define OFFICE9
    #define VBA6
    #include "..\Mcn.Office\OfficeImport.h"
     
    #import "C:\\Program Files\\Microsoft Office\\Office\\Excel9.olb" \
    	rename_namespace("Excel") \
    	auto_rename
     
    #elif defined(EXCEL8) // Excel 1997
     
    #define EXCEL_APPLICATION_1997	"Excel.Application.8"
    #define OFFICE8
    #define VBA6
    #include "..\Mcn.Office\OfficeImport.h"
     
    #import "C:\\Program Files\\Microsoft Office\\Office\\Excel8.olb" \
    	rename_namespace("Excel") \
    	auto_rename
     
    #endif // EXCEL12
     
    //#pragma warning(default:4146)
    Utilise les smart pointer tel que _ApplicationPtr ou RangePtr etc

  4. #4
    Membre émérite
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Par défaut
    Si tu veux, je peux te faire part de ma technique à moi pour piloter les applications de Microsoft Office aussi simplement.

    Par exemple, pour Excel, j'ai définit toute une DLL soit Mcn.Excel.dll qui renferme tous les objets principaux de Excel tels que des objets classeurs, feuilles, rangées et des objets collections.

    Cette dll se charge d'offrir des objets un peu plus futés que les objets primitifs d'Excel générés par le compilo à partir de la TypeLib.

    Et toutes mes applications se lient dynamiquement à celle DLL pour réaliser des opérations les plus communes dans MS Excel.


    Voici un exemple
    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
     
            MCN::Automation::McnExcel::CMcnExcelApp spExcelApp;
    	try
    	{
    		hr = spExcelApp.CreateInstance(EXCEL_APPLICATION);
    		if (FAILED(hr))
    		{
    			AfxMessageBox("Echec de chargement de Microsoft Excel", MB_ICONSTOP);
    			return hr;
    		}
    		MCN::Automation::McnExcel::CMcnWorkBook spWorkbook = spExcelApp.OpenWorkBook(strRegistreFile);
    		if( spWorkbook == NULL )
    		{
    			CString strMsg = "Aucune information de registre n'est enregistrée.";
    			AfxMessageBox(strMsg);
    			return E_UNEXPECTED;
    		}
    		bool bRet = spWorkbook.Show(pszRegName);
    		if(bRet == false)
    		{
    			if(pszRegName)
    			{
    				spWorkbook.Close();
    				CString strMsg = "Aucune valeur des ";
    				strMsg += pszRegName;
    				strMsg += " a été inscrit pour la zone ";
    				strMsg += pszZone;
    				AfxMessageBox(strMsg);
    				return S_FALSE;
    			}
    		}
    		return bRet? S_OK: S_FALSE;
    	}
    	catch(...)
    	{
    		spExcelApp.Release();
    		AfxMessageBox(IDS_E_EXCEL_APPLICATION, MB_ICONSTOP);
    		return E_FAIL;
    	}
    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
     
    BOOL CGeneralZonePage::WriteZoneSettings()
    {
    	if(m_Jan == 0 && m_Fev == 0 && m_Mar == 0 && m_Avr == 0 && m_Mai == 0 && m_Jun == 0 &&
    		m_Jul == 0 && m_Aou == 0 && m_Sep == 0 && m_Oct == 0 && m_Nov == 0 && m_Dec == 0)// les mois chauds
    	{
    		CString strMsg = "Vous n'avez indiquer aucun mois chaud pour cette zone.\n";
    		strMsg += "Voulez-vous continuer?";
    		int nRet = AfxMessageBox(strMsg, MB_YESNO);
    		if(nRet == IDNO)
    			return FALSE;
    	}
     
    	MCN::Automation::McnExcel::CMcnExcelApp spExcelApp;
    	try
    	{
    		HRESULT hr = spExcelApp.CreateInstance(EXCEL_APPLICATION);
    		if (FAILED(hr))
    		{
    			AfxMessageBox("Echec de chargement de Microsoft Excel", MB_ICONSTOP);
    			return hr;
    		}
    		CString strSettingsFile;
    		hr = HydroBil::API::AfxGetSafeSettingsFile(m_strZoneName, strSettingsFile);
    		if(hr != S_OK)
    		{
    			CString strMsg = "Impossible d'obtenir les paramètres hydrologiques de ";
    			strMsg += m_strZoneName;
    			AfxMessageBox(strMsg, MB_ICONSTOP);
    			return FALSE;
    		}
    		MCN::Automation::McnExcel::CMcnWorkBook spSettingsBook = spExcelApp.OpenWorkBook(strSettingsFile);
    		if(spSettingsBook == NULL)
    		{
    			CString strMsg = "Impossible d'obtenir les paramètres hydrologiques de ";
    			strMsg += m_strZoneName;
    			AfxMessageBox(strMsg, MB_ICONSTOP);
    			return FALSE;
    		}
    		MCN::Automation::McnExcel::CMcnWorkSheet spCoefficientsSheet = spSettingsBook.OpenWorkSheet("Coefficients");
    		if(spCoefficientsSheet == NULL)
    		{
    			spSettingsBook.Close();
    			CString strMsg = "Le classeur \"";
    			strMsg += m_strZoneName;
    			strMsg += "_Settings.xls\" est corrompu.\nLa feuille \"Coefficients\" est absente ou non définie";
    			AfxMessageBox(strMsg, MB_ICONSTOP);
    			return FALSE;
    		}
    		MCN::Automation::McnExcel::CMcnWorkSheet spZoneSheet = spSettingsBook.OpenWorkSheet("Zone");
    		if(spZoneSheet == NULL)
    		{
    			spSettingsBook.Close();
    			CString strMsg = "Le classeur \"";
    			strMsg += m_strZoneName;
    			strMsg += "_Settings.xls\" est corrompu.\nLa feuille \"Zone\" est absente ou non définie";
    			AfxMessageBox(strMsg, MB_ICONSTOP);
    			return FALSE;
    		}
     
    		MCN::Automation::McnExcel::CMcnRange spZoneRange = spZoneSheet.GetRange("F6", "F17");
    		spZoneRange.PutItem(1, 1, m_Jan);
    		spZoneRange.PutItem(2, 1, m_Fev);
    		spZoneRange.PutItem(3, 1, m_Mar);
    		spZoneRange.PutItem(4, 1, m_Avr);
    		spZoneRange.PutItem(5, 1, m_Mai);
    		spZoneRange.PutItem(6, 1, m_Jun);
    		spZoneRange.PutItem(7, 1, m_Jul);
    		spZoneRange.PutItem(8, 1, m_Aou);
    		spZoneRange.PutItem(9, 1, m_Sep);
    		spZoneRange.PutItem(10, 1, m_Oct);
    		spZoneRange.PutItem(11, 1, m_Nov);
    		spZoneRange.PutItem(12, 1, m_Dec);
     
    		// latitude
    		int n = m_LatitudeCB.GetCurSel();
    		if(n == -1)
    		{
    			spSettingsBook.Close();
    			return FALSE;
    		}
    		CString str;
    		m_LatitudeCB.GetLBText(n, str);
    		spZoneRange = spZoneSheet.GetRange("B6", "C6");
    		spZoneRange.PutItem(1, 1, str);
     
    		// latitude nord ou sud
    		if(m_geoSettings.m_nLatitudeType == HydroBil::SGeoSettings::NORTH)
    			spZoneRange.PutItem(1, 2, "N");
    		else
    			spZoneRange.PutItem(1, 2, "S");
     
    		// altitude
    		n = m_AltitudeCB.GetCurSel();
    		if(n == -1)
    		{
    			spSettingsBook.Close();
    			return FALSE;
    		}
    		m_AltitudeCB.GetLBText(n, str);
    		spZoneRange = spZoneSheet.GetRange("C8");
    		spZoneRange.PutValue(str);
     
    		// zone climatique
    		n = m_ClimatZoneCB.GetCurSel();
    		if(n == -1)
    		{
    			spSettingsBook.Close();
    			return FALSE;
    		}
    		m_ClimatZoneCB.GetLBText(n, str);
     
    		MCN::Automation::McnExcel::CMcnRange spCoeffRange = spCoefficientsSheet.GetRange("B5", "H7");
    		long nRowFound = -1;
    		long nColFound = -1;
    		spCoeffRange.GetLeftColumn().FindData(str, nRowFound, nColFound);
    		if(nRowFound == -1)
    		{
    			spSettingsBook.Close();
    			return FALSE;
    		}
     
    		double a = spCoeffRange.GetItem(nRowFound, 2);
    		double b = spCoeffRange.GetItem(nRowFound, 3);
    		double a1 = spCoeffRange.GetItem(nRowFound, 4);
    		double b1 = spCoeffRange.GetItem(nRowFound, 5);
    		double a2 = spCoeffRange.GetItem(nRowFound, 6);
    		double b2 = spCoeffRange.GetItem(nRowFound, 7);
     
    		spZoneRange = spZoneSheet.GetRange("H6", "N6");
    		spZoneRange.PutItem(1, 1, str);
    		spZoneRange.PutItem(1, 2, a);
    		spZoneRange.PutItem(1, 3, b);
    		spZoneRange.PutItem(1, 4, a1);
    		spZoneRange.PutItem(1, 5, b1);
    		spZoneRange.PutItem(1, 6, a2);
    		spZoneRange.PutItem(1, 7, b2);
    		spZoneRange.GetLeftColumn().AutoFitColumns();
     
    		spExcelApp.CloseAllUserExcelApp();
    		spSettingsBook.Save();
    		spSettingsBook.Close(true);
    		UpdateData(FALSE);
    		return TRUE;
    	}
    	catch(...)
    	{
    		spExcelApp.Close();
    		spExcelApp.Release();
    		AfxMessageBox(IDS_E_EXCEL_APPLICATION, MB_ICONSTOP);
    		return FALSE;
    	}
    }

  5. #5
    Membre expérimenté
    Avatar de Nicolas Bauland
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 119
    Par défaut
    Donc en gros, le plus simple est la mort du class wizard concernant office et la solution la plus souple est le #import.

    Merci pour tes deux .h qui facilitent, il est vrai l'utilisation des #import.

    Quant à tes dll, serait-il possible d'y jeter un oeil ? En tout cas, j'ai pas encore tout regarder en details, mais ca me semble assez pratique en effet.

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

Discussions similaires

  1. Importation d'une feuille excel vers sql server 2005
    Par transistor49 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 16/09/2009, 19h31
  2. [Excel] - Automation deux trois fichiers
    Par Invité dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 26/01/2007, 12h01
  3. Exportation données excel vers sql server 2005, en ASPX?
    Par Micke7 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 16/01/2007, 14h57
  4. Automation Excel et VS.NET 2005
    Par Rupella dans le forum MFC
    Réponses: 2
    Dernier message: 18/05/2006, 17h41
  5. Importé un fichier excel sous SQL Server 2005
    Par summer91 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 01/05/2006, 10h52

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