Is it possible in Excel VBA to change the source code of Module in another Module

前端 未结 3 908
心在旅途
心在旅途 2020-12-06 14:41

I have an Excel .xlam file that adds a button in the ribbon to do the following:

  1. Scan the ActiveSheet for some pre-set parameters
  2. Take my source text
相关标签:
3条回答
  • 2020-12-06 15:15

    I realize now that what you really want to do is store some values in your document in a way that is accessible to your VBA, but that is not readable to a user of the spreadsheet. Following Charles Williams's suggestion to store the value in a named range in a worksheet, and addressing your concern that you don't want the user to have access to the values, you would have to encrypt the string...

    The "proper way" to do this is described in this article - but it's quite a bit of work.

    A much shorter routine is found here. It just uses simple XOR encryption with a hard coded key - but it should be enough for "most purposes". The key would be "hidden" in your macro, and therefore not accessible to prying eyes (well, not easily).

    Now you can use this function, let's call it encrypt(string), to convert your string to a value in the spreadsheet:

    range("mySecretCell").value = encrypt("The lazy dog jumped over the fox")
    

    and when you need to use it, you use

    Public Function GetSource()
        GetSource = decrypt(Range("mySecretCell").value)
    End Function
    

    If you use the XOR version (second link), encrypt and decrypt would be the same function...

    Does that meet your needs better?

    0 讨论(0)
  • 2020-12-06 15:21

    As @brettdj already pointed out with his link to cpearson.com/excel/vbe.aspx , you can programmatically change to code of a VBA module using the VBA Extensibility library! To use it, select the library in the VBA editor Tools->References. Note that you need to also change the options in your Trust center and select: Excel Options->Trust Center->Trust Center Settings->Macro Settings->Trust access to the VBA project object model

    Then something like the following code should do the job:

    Private mCodeMod As VBIDE.CodeModule
    
    Sub UpdateModule()
        Const cStrModuleName As String = "Source"
    
        Dim VBProj As VBIDE.VBProject
        Dim VBComp As VBIDE.VBComponent
    
        Set VBProj = Workbooks("___YourWorkbook__").VBProject
    
        'Delete the module
        VBProj.VBComponents.Remove VBProj.VBComponents(cStrModuleName)
    
        'Add module
        Set VBComp = VBProj.VBComponents.Add(vbext_ct_StdModule)
        VBComp.Name = cStrModuleName
        Set mCodeMod = VBComp.CodeModule
    
        'Add procedure header and start
        InsertLine "Public Function GetSource() As String"
        InsertLine "Dim s As String", 1
        InsertLine ""
    
        'Add text
        InsertText ThisWorkbook.Worksheets("Sourcetext") _
            .Range("___YourRange___")
    
        'Finalize procedure
        InsertLine "GetSource = s", 1
        InsertLine "End Function"
    
    End Sub
    
    Private Sub InsertLine(strLine As String, _
        Optional IndentationLevel As Integer = 0)
        mCodeMod.InsertLines _
            mCodeMod.CountOfLines + 1, _
            Space(IndentationLevel * 4) & strLine
    End Sub
    
    Private Sub InsertText(rngSource As Range)
        Dim rng As Range
        Dim strCell As String, strText As String
        Dim i As Integer
    
        Const cLineLength = 60
        For Each rng In rngSource.Cells
            strCell = rng.Value
            For i = 0 To Len(strCell) \ cLineLength
                strText = Mid(strCell, i * cLineLength, cLineLength)
                strText = Replace(strText, """", """""")
                InsertLine "s = s & """ & strText & """", 1
            Next i
        Next rng
    End Sub
    
    0 讨论(0)
  • 2020-12-06 15:28

    You can "export" and "import" .bas files programmatically. To do what you are asking, that would have to be the approach. I don't believe it's possible to modify the code in memory. See this article

    0 讨论(0)
提交回复
热议问题