none
Public Variable - VBA to VB RRS feed

  • Question

  • I'm converting all my VBA macros to a dll class library. Due to the number of subs and functions that work on their own and together I had to make a common structure to keep it tidy.

    In VBA I would create a module called... "bbb_PublicVariables" ... and under that I would have all my common variables.

    And then in a different module called "aaa_MasterFunctions" I would have a function called "mfSetVariables" that would, amazingly enough, set the variables.

    At the start of a sub I would call the "mfSetVariables" then when I create a new file or switch to a different file etc I would call on the "mfSetVariables" function again.

    In VB I have done the same but the Public variables don't update. It's almost like they are static?

    Public Class NCT_Toolkit_Addin_AC
    
        Private Shared myroutine As Action
    
        <CommandMethod("Micromat_DrillFile_Import")>
        Public Sub DrillFile_Import()
    
            If mfSetVariables() = False Then Exit Sub
    
            Dim answer = MsgBox("This tool will import a drill file!", vbOKCancel, "Drill File Import Readiness Check")
            If answer = vbCancel Then Exit Sub
    
    RetryGetFilePath:
            Dim OpenFilePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop
            Dim DrillFilePath = mfOpenDialog(OpenFilePath, "Text Based Files (*.txt;*.asc)|*.txt;*.asc|All files (*.*)|*.*")
    
            If TypeName(DrillFilePath) = "Boolean" Then If DrillFilePath = False Then Exit Sub
    
            Dim DrillFile() As Object = mfLoadFile_Txt(DrillFilePath, 1)
            If DrillFile Is Nothing Then
                MsgBox("Please select another file!", vbOKOnly + vbExclamation, "Selected File is Empty")
                GoTo RetryGetFilePath
            Else
                Micromat_ToolSetup()
                mfCreateNewDrawing()
                DrawTemplate_Genrad()
                Micromat_DrillFile_Read(DrillFile)
    
            End If
    
        End Sub
    
    End Class


    Module bbb_PublicVariables
    
        Public acApp As Object
        Public acDocMgr As DocumentCollection
        Public acActiveDoc As Document
        Public acDatabase As Database
    
        Public acTransaction As Transaction
        Public acCircle As Circle
        Public acText As MText
        Public acLine As Line
    
        Public acLayerTable As LayerTable
        Public acLayerTable_Record As LayerTableRecord
        Public acBlockTable As BlockTable
        Public acBlockTable_Record As BlockTableRecord
    
        Public acView As ViewTableRecord
    
        Public acSpace As Integer
    
        Public mfFilePath As Object
        Public mfFolderPath As String
        Public mfProjNumber As String
        Public mfFileName_wExt As String
        Public mfFileExt As String
        Public mfFileName As String
        Public mfFileStatus As String
        Public mfTemplatePath As Object
    
        Public Micromat_DrillArray As Object '(0 = Tool# 1 = X 2 = Y, HoleCount)
        Public Micromat_ToolArray As Object
    
    end module

    Module aaa_MasterFunctions Function mfSetVariables() acApp = Application.AcadApplication acDocMgr = Application.DocumentManager acActiveDoc = acDocMgr.MdiActiveDocument acDatabase = acActiveDoc.Database acSpace = System.Convert.ToInt32(Application.GetSystemVariable("CVPORT")) Return True End Function

        Function mfCreateNewDrawing(Optional TemplateType As Integer = 0) ', Optional MakeDrawingActive As Boolean = True)

            aMsgBox("mfCreateNewDrawing1 = " & acActiveDoc.Name)

            acDocMgr.MdiActiveDocument = acDocMgr.Add(mfTemplatePath(TemplateType))
            acActiveDoc = acDocMgr.MdiActiveDocument
            acDatabase = acActiveDoc.Database

            MsgBox("mfCreateNewDrawing2 = " & acActiveDoc.Name)

            Return True
        End Function

    End Module


    The "mfCreateNewDrawing" above will activate the new drawing but will not update the public variable.

    This then messes with the future code by drawing in the previous drawing file.

    Am I right is saying that these variables in vb are now static?

    Can you suggest a more appropriate structure where I can have a single place to dim common "UPDATABLE" variables?

    My Autocad dll will have only about a dozen main subs but when I do my solidworks one... I have hundreds.

    Saturday, March 14, 2020 7:17 PM

All replies

  • Hi

    All Public variables in  Modules are available throughout a Project.


    Regards Les, Livingston, Scotland

    Saturday, March 14, 2020 8:36 PM
  • Thanks Les, I understand that they are available, but are they updatable? I cannot get mine to update.
    Sunday, March 15, 2020 4:55 PM
  • Thanks Les, I understand that they are available, but are they updatable? I cannot get mine to update.

    Hi

    Here is an example using Form1 and 3 Modules

    Public Class Form1
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim a As Double = Module1.Mod1 + Module2.Mod2 + Module3.Mod3 + Module3.Mod1
        ' = 7.8999r
    
        Module1.Mod1 += 1
        Module2.Mod2 += 2
        Module3.Mod1 += 3
        Module3.Mod3 += 3
    
        Dim b As Double = Module1.Mod1 + Module2.Mod2 + Module3.Mod3 + Module3.Mod1
        ' = 16.90000
    
      End Sub
    End Class
    Module Module1
      Public Mod1 As Double = 1.1
    End Module
    
    Module Module2
      Public Mod2 As Double = 2.2
    End Module
    
    Module Module3
      Public Mod1 As Double = 1.3
      Public Mod3 As Double = 3.3
    End Module
    





    Regards Les, Livingston, Scotland

    Sunday, March 15, 2020 5:16 PM
  • Note that if your DLL is unloaded and reloaded, then the variables are lost.

    Sunday, March 15, 2020 5:56 PM

  • Am I right is saying that these variables in vb are now static?


    Hi Stuart,

    A pity is that you simply use the wrong word for constant. "Static" means that an identifier is always available (it does not go out of scope as it is called outside a sub or a function). The synonym for Module in C# is a static class but because of that static has already that meaning in VB that has in VB for Net the name "Shared". It are not constants. 

    It is the same as in this VBA code.

    ' Function definition. 
    Function KeepTotal(Number) 
        ' Only the variable Accumulate preserves its value between calls. 
        Static Accumulate 
        Accumulate = Accumulate + Number 
        KeepTotal = Accumulate 
    End Function 
     

    Values available on module level (and not in subs of those) are available inside the whole program. 

    (Of course likewise VBA you have to save them to preserve the values when your program stops). 

    I agree with you that when you read the VBA documentation it is easy to make the same mistake as you do. 


    Success
    Cor




    Sunday, March 15, 2020 6:46 PM
  • Hi,

    Forgive me I may not fully understand your updated question. Your question is whether the public variables in the module can be updated after the program finishes running? Or is it that your question is to modify the public variables in the module in the current main program?

    If it is the first one, as far as the example you give, it cannot be updated. Once the program is finished, it will return to the initial value. If it is the second one, you can manipulate the variables, but when you re-run the program, it will return to the state before it was updated.

    Module can be understood as a static class that cannot be instantiated, in which we can define some global variables and functions. Modules can define global variables, entry functions Main and other shared or private functions and methods. You do not need to instantiate New when referring to variables, functions, and methods defined in the module.

    You can try the small example below.

    Module Module1
        Public i As Integer = 1
    
        Public Sub AddOne(ByVal i As Integer)
            MsgBox(i + 1)
        End Sub
    
    End Module
    
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim j As Integer = 2
            MsgBox(j + Module1.i)
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            MsgBox(Module1.i)
            AddOne(Module1.i)
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            MsgBox(Module1.i)
            Module1.i = 3
            MsgBox(Module1.i)
        End Sub
    End Class

    Hope it be helpful to you.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, March 16, 2020 7:32 AM
    Moderator
  • Many thanks for the replies... I'll run the examples tonight.

    Just to clarify the workflow:-

    Program starts...
    1) The class calls a function in module 1 which sets the public variables in module 2

          (eg. x = 1)

    2) The class then calls functions in various modules which use "x"

    ***Up to here the workflow is fine***

    3) The class then calls the function in module 1 which changes the public variables in module 2, the same variables that were set in step 2.

          (eg. x = 2)***this is where the code doesnt changes the variable***

    4) The class then calls functions in various modules which use "x"

          ***This is where "x" still = 1 instead of "x" = 2***

    ...Program ends

    This is pretty much how all my vba code works and ive never had an issue.

    But if I am understanding Les, Cor and yourself correctly... Public variables in a Module can only be changed by functions and subs inside the same Module?


    Monday, March 16, 2020 9:05 AM
  • Thanks Cor... looks like my understanding of those terms is not quite right. I did indeed think that static meant that once the variable was set it cannot be changed until the program ends.

    I'll need to review my fundamentals. Thanks for pointing that out.

    Monday, March 16, 2020 9:16 AM
  • Many thanks for the replies... I'll run the examples tonight.

    Just to clarify the workflow:-

    But if I am understanding Les, Cor and yourself correctly... Public variables in a Module can only be changed by functions and subs inside the same Module?


    Hi

    No, Public variables in a Module can be reaf and changed Globally. The variavles are available in all parts of the project.


    Regards Les, Livingston, Scotland

    Monday, March 16, 2020 12:26 PM
  • Hi,

    Based on your description, the change you want is the second of two possibilities I suggested earlier.

    For your understanding, I changed the code to the following. As explained before, X is a global variable.

    You can test the code, it can be changed from X = 1 to X = 2.

    It is possible to change X before the program ends, not to say that it can only be modified in the current module.

    Public Class Form1
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Module1.AddSetMod1(1)
            MsgBox(Module2.x)
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Module2.AddAltMod2(1)
            MsgBox(Module2.x)
            Module2.x = 3
            MsgBox(Module2.x)
        End Sub
    End Class

    Module Module1
        Public i As Integer = 1
    
        Public Function SetMod2()
            Module2.x = 1
            Return Module2.x
        End Function
    
        Public Function AddSetMod1(ByVal i As Integer)
            MsgBox(SetMod2() + i)
            Return (SetMod2() + i)
        End Function
    
        Public Function AltMod2()
            Module2.x = 2
            Return Module2.x
        End Function
    
        Public Function AddAltMod1(ByVal i As Integer)
            MsgBox(AltMod2() + i)
            Return (AltMod2() + i)
        End Function
    
    End Module
    

    Module Module2
        Public x As Integer
    
        Public Sub AddSetMod2(ByVal j As Integer)
            MsgBox(Module1.AddSetMod1(j) + j)
        End Sub
    
        Public Sub AddAltMod2(ByVal j As Integer)
            MsgBox(Module1.AddAltMod1(j) + j)
        End Sub
    
    End Module
    

    Hope it be helpful.

    Best Regards,

    Julie


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, March 17, 2020 2:03 AM
    Moderator
  • Many thanks again for all your help...

    After much investigation it had nothing to do with the public variables.

    It has something to do with how autocad see which drawing is active. Something to do with command flag. I haven't been able to get it to work so i'm just leaving that part of the code until the end and just work within the active document.

    Wednesday, March 25, 2020 11:22 AM