Кто нибудь подскажет как имея объект Document от ворда, добраться до текста макросов ?... У Document есть свойство VBProject далее можно получить VBE Object а вот как получить сам код макроса?... Описание VBE Object http://msdn.microsoft.com/en-us/library/aa443984(v=VS.60).aspx покопавшись в интернете вот что нашол: http://msoffice.nm.ru/faq/macros/module.htm проблема решена: http://pubs.logicalexpressions.com/pub0009/LPMArticle.asp?ID=307
Если, допустим, нужно получить текст макроса Macro1, то на VBA это выглядит так: Код (Text): Sub GetMacroText() Dim StartLine As Long Dim Lines As Long Dim szBuffer As String StartLine = ActiveDocument.VBProject.VBComponents.VBE.ActiveCodePane.CodeModule.ProcStartLine("Macro1", vbext_pk_Proc) Lines = ActiveDocument.VBProject.VBComponents.VBE.ActiveCodePane.CodeModule.ProcCountLines("Macro1", vbext_pk_Proc) szBuffer = ActiveDocument.VBProject.VBComponents.VBE.ActiveCodePane.CodeModule.Lines(StartLine, Lines) Debug.Print szBuffer End Sub
Странная штука: получаю количество строк в CodeModule (их там 26) далее получаю эти строки hr = GetProperty(IDCodeModule,OLESTR("Lines"),&p,&v); /// !!! не возвращает все строки "Lines(1, 26)" в итоге возвращает только последнюю строчку, а остальные где?... Код (Text): void ShowException(const EXCEPINFO *excep,const WCHAR *cap){ wstring wstr; if (excep->bstrDescription){ wstr = L"Description: "; wstr += excep->bstrDescription; wstr += L"\n"; }; if(excep->bstrSource){ wstr +=L"Source: "; wstr +=excep->bstrSource; wstr +=L"\n"; }; MessageBox(0,wstr.c_str(),cap,MB_ICONINFORMATION|MB_SYSTEMMODAL); }; HRESULT GetProperty(IDispatch *iDisp,LPOLESTR name,VARIANT* varResult,LCID lcid = GetSystemDefaultLCID()){ HRESULT hr; WORD wFlags = DISPATCH_PROPERTYGET; EXCEPINFO excepInfo={0}; UINT uArgErr; DISPPARAMS dp = {0}; DISPID dispid; hr = iDisp->GetIDsOfNames(IID_NULL,&name,1,lcid,&dispid); if (FAILED(hr)){ return hr; }; hr = iDisp->Invoke(dispid,IID_NULL, lcid, wFlags, &dp, varResult, &excepInfo, &uArgErr); if (FAILED(hr)){ wstring wstr = L"GetProperty_1 - "; wstr += name; ShowException(&excepInfo,wstr.c_str()); }; return hr; }; HRESULT GetProperty(IDispatch *iDisp,LPOLESTR name, DISPPARAMS* dp,VARIANT* varResult,LCID lcid = GetSystemDefaultLCID()){ HRESULT hr; WORD wFlags = DISPATCH_PROPERTYGET; EXCEPINFO excepInfo={0}; UINT uArgErr; DISPID dispid; hr = iDisp->GetIDsOfNames(IID_NULL,&name,1,lcid,&dispid); if (FAILED(hr)){ printf("Except in GetProperty GetIDsOfNames\n"); printf("description :%s",excepInfo.bstrDescription); return hr; }; hr = iDisp->Invoke(dispid,IID_NULL, lcid, wFlags, dp, varResult, &excepInfo, &uArgErr); if (FAILED(hr)){ wstring wstr = L"GetProperty_2 - "; wstr += name; ShowException(&excepInfo,wstr.c_str()); }; return hr; }; HRESULT SetProperty(IDispatch *iDisp,LPOLESTR name,VARIANT* varResult,DISPPARAMS *dp,LCID lcid = GetSystemDefaultLCID()){ HRESULT hr; WORD wFlags = DISPATCH_PROPERTYPUT; EXCEPINFO excepInfo={0}; UINT uArgErr; DISPID dispid; hr = iDisp->GetIDsOfNames(IID_NULL,&name,1,lcid,&dispid); if (FAILED(hr)) return hr; hr = iDisp->Invoke(dispid,IID_NULL, lcid, wFlags, dp, varResult, &excepInfo, &uArgErr); if (FAILED(hr)){ wstring wstr = L"SetProperty - "; wstr += name; ShowException(&excepInfo,wstr.c_str()); }; return hr; }; HRESULT CallMethod(IDispatch *iDisp,LPOLESTR name,DISPPARAMS *dp,VARIANT* varResult,LCID lcid=GetSystemDefaultLCID()){ HRESULT hr; WORD wFlags = DISPATCH_METHOD; EXCEPINFO excepInfo={0}; UINT uArgErr; DISPID dispid; hr = iDisp->GetIDsOfNames(IID_NULL,&name,1,lcid,&dispid); if (FAILED(hr)){ printf("Except in CallMethod GetIDsOfNames\n"); printf("description :%s",excepInfo.bstrDescription); return hr; }; hr= iDisp->Invoke(dispid,IID_NULL, lcid, DISPATCH_METHOD, dp, varResult, &excepInfo, &uArgErr); if (FAILED(hr)){ wstring wstr = L"CallMethod - "; wstr += name; ShowException(&excepInfo,wstr.c_str()); }; return hr; }; int VBCom::GetTextMacro(map<wstring,wstring> &res){ VARIANT varResult; DISPPARAMS dp = {0}; VARIANT nums[2]; HRESULT hr; IDispatch *IDVBProjects,*IDVBComponents; if (!IDWordVBEx) return 0; // VBProjects hr = GetProperty(IDWordVBEx,OLESTR("VBProjects"),&varResult); if(FAILED(hr)){ printf("fail CodePanes\n"); return 0; }; IDVBProjects = varResult.pdispVal; hr = GetProperty(IDVBProjects,OLESTR("Count"),&varResult); if(FAILED(hr)){ printf("fail Count\n"); return 0; }; //printf("Count = %d\n",Count); dp.cArgs = 1; dp.cNamedArgs = 0; dp.rgvarg = nums; dp.rgvarg[0].vt = VT_I4; for ( LONG CountProjects = varResult.ulVal; CountProjects ; --CountProjects){ dp.rgvarg[0].lVal=CountProjects; hr=CallMethod(IDVBProjects,OLESTR("Item"),&dp,&varResult); if(FAILED(hr)){ printf("fail Item\n"); break; }; //VBProjects.Item(x) - get -> VBComponents IDVBComponents = varResult.pdispVal; if (!IDVBComponents) break; hr = GetProperty(IDVBComponents,OLESTR("VBComponents"),&varResult); if(FAILED(hr)){ printf("fail VBComponents\n"); return 0; }; IDispatch * IDItemComponent = varResult.pdispVal; if (!IDItemComponent) break; hr = GetProperty(IDItemComponent,OLESTR("Count"),&varResult); if(FAILED(hr)){ printf("fail Count\n"); varResult.pdispVal->Release(); return 0; }; for (LONG Count = varResult.ulVal; Count; --Count){ DISPPARAMS p={0}; dp.rgvarg = nums; dp.rgvarg[0].lVal=Count; dp.rgvarg[0].vt = VT_I4; dp.cArgs = 1; hr=CallMethod(IDItemComponent,OLESTR("Item"),&dp,&varResult); if(FAILED(hr)){ printf("fail Item\n"); break; }; hr = GetProperty(varResult.pdispVal,OLESTR("CodeModule"),&varResult); IDispatch *IDCodeModule = varResult.pdispVal; if(FAILED(hr)){ printf("fail CodeModule\n"); break; }; hr=GetProperty(IDCodeModule,OLESTR("Name"),&varResult); if(FAILED(hr)){ printf("fail Name\n"); //MessageBox(0,L"GetProperty Name",L"Error",0); }; wstring & res_str = res[wstring(varResult.bstrVal)]; varResult.vt = 0; hr=GetProperty(IDCodeModule,OLESTR("CountOfLines"),&varResult); if(FAILED(hr)){ printf("fail CountOfLines\n"); //MessageBox(0,L"GetProperty CountOfLines",L"Error",0); }; if (varResult.lVal){ // если есть строки макроса получаем их p.cArgs = 2; p.rgvarg = nums; nums[0].llVal = 1; nums[1].llVal = varResult.lVal; nums[0].vt = nums[1].vt = VT_I4; VARIANT v; hr = GetProperty(IDCodeModule,OLESTR("Lines"),&p,&v); /// !!! не возвращает все строки if(FAILED(hr)){ printf("fail Lines\n"); //MessageBox(0,L"GetProperty Lines",L"Error",0); res_str = L"fail get...\n"; } else{ res_str=wstring(v.bstrVal); }; }; IDCodeModule->Release(); }; // end for (...;...;..) if (IDItemComponent) IDItemComponent->Release(); if (IDVBComponents) IDVBComponents->Release(); }; return res.size(); };