2008-09-08 24 views
14

से मैक्रो (वीबीए) कोड प्रोग्रामेटिक रूप से निकालें क्या एपीआई का उपयोग करते हुए वर्ड 2007 "डॉकएम" दस्तावेज़ से सभी वीबीए कोड निकालना संभव है?वर्ड 2007 डॉक्स

मैं कैसे कार्यावधि में VBA कोड डालने के लिए, और कैसे सभी VBA कोड को हटाने के लिए है, लेकिन (भविष्य में और अन्य दस्तावेजों में डालने) एक स्ट्रीम या स्ट्रिंग है कि मैं स्टोर कर सकते हैं में बाहर वास्तविक कोड खींच नहीं पाया है।

किसी भी सुझाव या संसाधन की सराहना की जाएगी।

संपादित करें: सभी को धन्यवाद, Aardvark का जवाब वही था जो मैं ढूंढ रहा था। मैं सी # करने के लिए अपने कोड परिवर्तित, और यह एक वर्ग पुस्तकालय से फोन कर रहा था है विजुअल स्टूडियो 2008

using Microsoft.Office.Interop.Word; 
using Microsoft.Vbe.Interop; 

... 

public List<string> GetMacrosFromDoc() 
{ 
    Document doc = GetWordDoc(@"C:\Temp\test.docm"); 

    List<string> macros = new List<string>(); 

    VBProject prj; 
    CodeModule code; 
    string composedFile; 

    prj = doc.VBProject; 
    foreach (VBComponent comp in prj.VBComponents) 
    { 
     code = comp.CodeModule; 

     // Put the name of the code module at the top 
     composedFile = comp.Name + Environment.NewLine; 

     // Loop through the (1-indexed) lines 
     for (int i = 0; i < code.CountOfLines; i++) 
     { 
      composedFile += code.get_Lines(i + 1, 1) + Environment.NewLine; 
     } 

     // Add the macro to the list 
     macros.Add(composedFile); 
    } 

    CloseDoc(doc); 

    return macros; 
} 
का उपयोग कर
+1

स्मृति के उपयोग का अनुकूलन करने के StringBuilder का उपयोग करें: StringBuilder sb = नए StringBuilder(); .... sb.AppendLine ("कोड की आपकी रेखा"); ... macros.Add (sb.ToString()); – Skuami

उत्तर

9

आप अनुप्रयोग Extensibility 5.3 (या जो भी संस्करण के लिए माइक्रोसॉफ्ट विजुअल बेसिक के लिए एक संदर्भ जोड़ना होगा आपके पास)। मेरे पास वीबीए एसडीके है और इस तरह मेरे बॉक्स पर - तो यह बिल्कुल सही नहीं हो सकता है कि कार्यालय के जहाज क्या हैं।

इसके अलावा आपको विशेष रूप से वीबीए ऑब्जेक्ट मॉडल तक पहुंच सक्षम करना है - शब्द विकल्पों में "ट्रस्ट सेंटर" देखें। यह अन्य सभी मैक्रो सुरक्षा सेटिंग्स के अलावा कार्यालय प्रदान करता है।

यह उदाहरण उस वर्तमान दस्तावेज़ से कोड निकाल देगा जिसमें यह रहता है - यह स्वयं एक वीबीए मैक्रो है (और स्वयं और कोई अन्य कोड भी प्रदर्शित करेगा)। अन्य दस्तावेजों तक पहुंचने के लिए एक application.vbe.VBProjects संग्रह भी है। हालांकि मैंने इसे कभी नहीं किया है, मुझे लगता है कि एक बाहरी एप्लिकेशन इस वीबीप्रोजेक्ट संग्रह का उपयोग करके फ़ाइलों को खोलने के लिए भी मिल सकता है। सुरक्षा इस सामान के साथ मजाकिया है इसलिए यह मुश्किल हो सकता है।

मुझे आश्चर्य है कि डॉक फ़ाइल प्रारूप अब क्या है - एक्सएमएल डॉक्स की तरह है? क्या यह एक बेहतर दृष्टिकोण होगा?

Sub GetCode() 

    Dim prj As VBProject 
    Dim comp As VBComponent 
    Dim code As CodeModule 
    Dim composedFile As String 
    Dim i As Integer 

    Set prj = ThisDocument.VBProject 
     For Each comp In prj.VBComponents 
      Set code = comp.CodeModule 

      composedFile = comp.Name & vbNewLine 

      For i = 1 To code.CountOfLines 
       composedFile = composedFile & code.Lines(i, 1) & vbNewLine 
      Next 

      MsgBox composedFile 
     Next 

End Sub 
+1

यह कमाल है, धन्यवाद! मैंने आपके कोड को सी # में परिवर्तित कर दिया है, और इसे एक WPF एप्लिकेशन से कॉल करने और सूची बॉक्स में मैक्रो कोड प्रिंट करने में सक्षम हूं। मैं अपने संपादित उत्तर में कोड के सी # संस्करण को पोस्ट करूंगा। –

+1

यदि आपके पास अपनी परियोजना में फॉर्म हैं, तो यह आदर्श नहीं है। यह फॉर्म के नियंत्रण परिभाषा भाग को निर्यात नहीं करता है। – MarkJ

+0

बस '.xlsb' फ़ाइलों की पुष्टि करने के लिए ज़िप फ़ाइलें (अपेक्षित के रूप में) हैं, लेकिन vbaProject अभी भी '.bin' फ़ाइल में संग्रहीत है जो स्पष्ट रूप से एक कंपाउंड दस्तावेज़ है (पहले पठनीय तारों में से एक' रूट प्रविष्टि 'है)। –

25

आप फ़ाइलों को कोड का निर्यात कर सकता है और फिर उन्हें वापस पढ़ें।

मैं मेरे स्रोत नियंत्रण में कुछ एक्सेल मैक्रो रखने (सबवर्सन & TortoiseSVN का उपयोग) मदद करने के लिए नीचे दिए गए कोड का उपयोग कर रहा है। जब भी मैं वीबीए संपादक के साथ सहेजता हूं, यह मूल रूप से पाठ फ़ाइलों को सभी कोड निर्यात करता है। मैंने पाठ फ़ाइलों को उपversण में रखा ताकि मैं भिन्नता कर सकूं। आप वर्ड में काम करने के लिए इनमें से कुछ को अनुकूलित/चोरी करने में सक्षम होना चाहिए।

CanAccessVBOM() में रजिस्ट्री जांच सुरक्षा सेटिंग में "विजुअल बेसिक प्रोजेक्ट पर ट्रस्ट एक्सेस" से मेल खाती है।

Sub ExportCode() 

    If Not CanAccessVBOM Then Exit Sub ' Exit if access to VB object model is not allowed 
    If (ThisWorkbook.VBProject.VBE.ActiveWindow Is Nothing) Then 
     Exit Sub ' Exit if VBA window is not open 
    End If 
    Dim comp As VBComponent 
    Dim codeFolder As String 

    codeFolder = CombinePaths(GetWorkbookPath, "Code") 
    On Error Resume Next 
    MkDir codeFolder 
    On Error GoTo 0 
    Dim FileName As String 

    For Each comp In ThisWorkbook.VBProject.VBComponents 
     Select Case comp.Type 
      Case vbext_ct_ClassModule 
       FileName = CombinePaths(codeFolder, comp.Name & ".cls") 
       DeleteFile FileName 
       comp.Export FileName 
      Case vbext_ct_StdModule 
       FileName = CombinePaths(codeFolder, comp.Name & ".bas") 
       DeleteFile FileName 
       comp.Export FileName 
      Case vbext_ct_MSForm 
       FileName = CombinePaths(codeFolder, comp.Name & ".frm") 
       DeleteFile FileName 
       comp.Export FileName 
      Case vbext_ct_Document 
       FileName = CombinePaths(codeFolder, comp.Name & ".cls") 
       DeleteFile FileName 
       comp.Export FileName 
     End Select 
    Next 

End Sub 
Function CanAccessVBOM() As Boolean 
    ' Check resgistry to see if we can access the VB object model 
    Dim wsh As Object 
    Dim str1 As String 
    Dim AccessVBOM As Long 

    Set wsh = CreateObject("WScript.Shell") 
    str1 = "HKEY_CURRENT_USER\Software\Microsoft\Office\" & _ 
     Application.Version & "\Excel\Security\AccessVBOM" 
    On Error Resume Next 
    AccessVBOM = wsh.RegRead(str1) 
    Set wsh = Nothing 
    CanAccessVBOM = (AccessVBOM = 1) 
End Function 


Sub DeleteFile(FileName As String) 
    On Error Resume Next 
    Kill FileName 
End Sub 

Function GetWorkbookPath() As String 
    Dim fullName As String 
    Dim wrkbookName As String 
    Dim pos As Long 

    wrkbookName = ThisWorkbook.Name 
    fullName = ThisWorkbook.fullName 

    pos = InStr(1, fullName, wrkbookName, vbTextCompare) 

    GetWorkbookPath = Left$(fullName, pos - 1) 
End Function 

Function CombinePaths(ByVal Path1 As String, ByVal Path2 As String) As String 
    If Not EndsWith(Path1, "\") Then 
     Path1 = Path1 & "\" 
    End If 
    CombinePaths = Path1 & Path2 
End Function 

Function EndsWith(ByVal InString As String, ByVal TestString As String) As Boolean 
    EndsWith = (Right$(InString, Len(TestString)) = TestString) 
End Function 
+1

यह अच्छा है क्योंकि आप फॉर्म और इस तरह के बरकरार होंगे। +1 – Aardvark

संबंधित मुद्दे