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
|
Fichier .h
#pragma once
#include <vector>
#pragma warning (disable:4146)
#pragma warning (disable:4786)
// Word 97 (librairie indipensable pour utiliser les objet (word97 et excel97)
#import "c:\Tools\MSO97.DLL" rename ( "RGB", "OfficeRGB" )//on les renome car il y a doublon
#import "c:\Tools\VBEEXT1.OLB"//on les renome car il y a doublon
#import "c:\Tools\MsWord8.olb" rename ( "ExitWindows", "WordExitWindows" ) rename ( "FindText", "WordFindText" )//on les renome car il y a doublon
#pragma warning (default:4146)
#pragma warning (default:4786)
class CUtilitairePublipostage
{
public:
CUtilitairePublipostage(void);
static CUtilitairePublipostage* m_pInstanceUnique;
public:
static CUtilitairePublipostage& GetInstance ();
~CUtilitairePublipostage(void);
bool InsertionWord( CString, CString );
void Run() ;
void AddFieldAtSelection(CString sMergeField);
public:
//Pointeur sur l'application Word
Word::_ApplicationPtr m_spWord;
//Pointeur sur l'objet de fusion
Word::MailMergeFieldsPtr pMailMergeField;
//Pour sélectionner par champ à utiliser avec FindRecord
Word::SelectionPtr pSelection;
//1 document word (=1 fichier .doc)
Word::_DocumentPtr pDoc;
//un ensemble de document (=plusieurs .doc ouvert dans Word)
Word::DocumentsPtr pDocs;
};
Fichier .cpp
#include "StdAfx.h"
#include "utilitairepublipostage.h"
//
// Mécanisme de singleton, et utilisation de word 97
//
CUtilitairePublipostage* CUtilitairePublipostage::m_pInstanceUnique = NULL;
CUtilitairePublipostage& CUtilitairePublipostage::GetInstance ()
{
if ( m_pInstanceUnique == NULL )
/* { //Uniquement pour instancier Word si y a besoin
//pour notre appli il ne faut le faire ici sinon word restera process fantome
m_pInstanceUnique = new CUtilitairePublipostage ();
try
{
//
// Initialisation de COM et démarrage de Excel (qui seront conservés ouverts
// durant toute la vie du singleton, sauf en cas de plantage)
//
CoInitialize ( NULL ); //initialise l'interface COM
//Création de l'objet Word
HRESULT hr = m_pInstanceUnique->m_spWord.CreateInstance ( __uuidof ( Word::Application ) );
ASSERT ( hr == S_OK );
//Rend visible l'ouverture de Word
m_pInstanceUnique->m_spWord->Visible = VARIANT_FALSE;//VARIANT_TRUE;
}
catch (_com_error& comError)
{
AfxMessageBox( "Impossible de démarrer Excel. Vérifiez que Excel 97 sont correctement installés sur la machine SVP." );
m_pInstanceUnique->m_bExcelOK = false;
}
}
*/
return *m_pInstanceUnique;
}
//A la création de l'objet on instancie Word puis à sa mort on tue word
//la manière la plus propre de faire si on a pas des betes de course
CUtilitairePublipostage::CUtilitairePublipostage()
//: m_bExcelOK ( true )
{
CoInitialize ( NULL ); //initialise l'interface COM
//Création de l'objet Word (on gros lancer Word)
m_spWord.CreateInstance ( __uuidof ( Word::Application ) );
//Rend visible ou non l'ouverture de Word
m_spWord->Visible = VARIANT_FALSE;//VARIANT_TRUE;
}
// on tue word à la destruction de l'objet
CUtilitairePublipostage::~CUtilitairePublipostage(void)
{
COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR),
vTrue((short)TRUE),
vFalse((short)FALSE);
m_spWord->Quit(&vFalse,&vOpt,&vOpt);
}
#include "windows.h"
//Dans cette méthode on va récupérer une lettre type et on va fusionner les champs avec
//une source de donnée(un fichier texte). On nomme cette opération du publipostage
bool CUtilitairePublipostage::InsertionWord( CString strNomFichierWord,CString strPathModelWord)
{
VARIANT *vPath;
VARIANT *vFormatWORD ;
//création d'un objet MaVariant (ce type contient un ensemble
//de type pour plus de portabilité)
VARIANT MaVariant, vType;
// initialisation de la variable Variant
::VariantInit(&MaVariant);
::VariantInit(&vType);
//Petit rappel sur le type Variant
// MaVariant.vt <- on lui dit le type qu'il devra utiliser
// MaVariant."Letype dans la structure" <- on y met la valeur
//Selection du type BSTR dans la variable VARIANT (BSTR=string)
MaVariant.vt = VT_BSTR; //(on indique le type utilisé)
vType.vt = VT_I4;
try
{
//affectation d'une valeur à notre variable
MaVariant.bstrVal = strPathModelWord.AllocSysString();//on initialise
//Creation d'une collection de document
//rmq: Word peut contenir plusieurs documents
if (pDocs == NULL )
pDocs = m_spWord->Documents;
//Ouverture d'un document dans la collection (dans Word)
pDoc = pDocs->Open(&MaVariant);
//Instantiation et init des objets Variant
COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR),
vTrue((short)TRUE),
vFalse((short)FALSE);
//Pour ajouter un nouveau Document
//rmq:Ce document a été choisi parmi les Documents dispo
//----------pDoc = pDocs->Add(vOpt,vOpt);
//On peut utiliser l'objet selection pour publiposter aussi
//il permet de selectionner un ou plusieurs mot
//pSelection = m_spWord->GetSelection();
//Recupere le pointeur de fusion
Word::MailMergePtr oMerge = pDoc->GetMailMerge();
//Selection du type de document (wdCatalog, wdEnvelope, wdFormLetter, and wdMailingLabels)
oMerge->put_MainDocumentType( Word::wdFormLetters);
//Recupere l outil de fusion par champ du document
pMailMergeField = oMerge->GetFields();
//ouverture de la source de données
oMerge->OpenDataSource("e:\\rep\\data.txt",
vOpt, vOpt,
vOpt, vOpt,
vOpt, vOpt,
vOpt, vOpt,
vOpt, vOpt,
vOpt, vOpt,
vOpt);
//Recupere l'objet de fusion sur la source de donnée
Word::MailMergeDataSourcePtr pMMDS = oMerge->GetDataSource();
//Recherche l enregistrement "kor" dans le champ "Contact_Name"
//bool bOk = pMMDS->FindRecord("kor","Contact_Name");
//On indique merging de la datasource de pointer sur le premier champ et le quatrième
pMMDS->PutFirstRecord(1);
pMMDS->PutLastRecord(4);
//redirection dans un nouveau document
oMerge->put_Destination(Word::wdSendToNewDocument);
//Execute the mail merge.
oMerge->Execute(vOpt);
//Pour sauvegarder il faut qu'on sache quelle est le doc qu'on vient de créer
long lNumberOfDocuments=0;
lNumberOfDocuments=pDocs->GetCount();
VARIANT vPos;
::VariantInit(&vPos);
vPos.vt = VT_I4;
//On considère que à créer la dernier doc dans Word
vPos.lVal = lNumberOfDocuments-1;
//On crée un pointeur de doc
Word::_DocumentPtr pDocNew = pDocs->Item(&vPos);
//Close the original mail merge document and make Word visible.
//pDoc->Save();
//Texte resultant de la fusion
VARIANT vNoParam,vFileName;
::VariantInit(&vNoParam);
::VariantInit(&vFileName);
vNoParam.vt = VT_ERROR;
vNoParam.scode = DISP_E_PARAMNOTFOUND;
vFileName.vt = VT_BSTR;
vFileName.bstrVal = strNomFichierWord.AllocSysString();
/* ------\\\\\|||||| Warning |||||//////----- */
// La variable "vNoParam" est nécessaire en MFC pour signaler au compilo //
// qu'il n'y a pas de parametre (contrairement au VB //
pDocNew->SaveAs(&vFileName,&vNoParam,&vNoParam,&vNoParam,
&vNoParam,&vNoParam,&vNoParam,&vNoParam,&vNoParam,&vNoParam,&vNoParam);
pDocNew->Close(vFalse, vOpt, vOpt);
//pDocs->Save(&vTrue,&vNoParam);
pDoc->Close(&vOpt, &vOpt, &vOpt);
//pDocs->Close(vSavesChanges,vFormat,&vOpt);
}
catch( _com_error &e)
{
//Instantiation et init des objets Variant
//Si une exception survient on quitte word
COleVariant vOpt(DISP_E_PARAMNOTFOUND, VT_ERROR),
vTrue((short)TRUE),
vFalse((short)FALSE);
AfxMessageBox("Un problème est survenue lors du publipostage. Vérifier l'espace disque et la présence des modèles de lettres dans le répertoire rep.");
m_spWord->Quit(&vFalse,&vOpt,&vOpt);
}
return true;
}
void CUtilitairePublipostage::AddFieldAtSelection(CString sMergeField)
{
//Si on utilise l'objet selection
/* Word::SelectionPtr pSelection = m_spWord->GetSelection();
Word::RangePtr pSelRange = pSelection->GetRange();
*/
} |
Partager