locked
Scope/access of variables and objects throughout VB project RRS feed

  • Question

  • I apologize in advance for belaboring an issue which has been discussed many times, but apparenetly it has not sunk in for me.  Coming from legacy software development where variables shared among program modules were declared as global or in common declaration blocks at the top of each module, I am having a problem with scoping/accessing variables and configuration object properties initialized by the first executable (a windows form) which instantiates a configuration object as follows:

         Public myConfig As New config

    The config class is declared in a separate class file as follows:

    Public Class config
         Public dirJobFilePath As String
         Public dirLibraryPath As String
        
    Public dbSource As String
        
    Public dbDest As String
    End
    Class

    My specific question is how to make the config class accessible and settable from the various forms in my VB project? 
    Do I need to put the class declaration in a VB module rather than a VB class file?
    Do I need to add the 'shared' keyword anywhere?
    Do I need to reference the class in the declaration section of each form in the project?
    Do I need to add get and set code to the class definition?

    So many questions.  So little time.

    Thanks, -BGood

    Tuesday, January 6, 2009 8:36 PM

Answers

  • BGood said:

    Thanks for the suggestions.  I read the article and tried declaring "Public myConfig As New config" in a base module, but still loose the contents of myconfig object right after the transition from the 1st form to the 2nd form.

    Do I need to:

    • Do I need to put the class declaration in a VB module rather than a VB class file?
    • Do I need to add the 'shared' keyword anywhere?
    • Do I need to reference the class in the declaration section of each form in the project?
    • Do I need to add get and set code to the class definition?

    Thanks again, -BGood



    Hi BGood,

    If you only want one config just use a module like.>>

    Module myVariables
    Public dirJobFilePath As String
    Public dirLibraryPath As String
    Public dbSource As String
    Public dbDest As String
    End
    Module

    Then

    dbSource = "????"
    'or use.>>
    myVariables.dbSource = "????"

    If you would rather use a CLASS then use.>>

    Public Class sharedVariable
    Public Shared dirJobFilePath As String
    Public Shared dirLibraryPath As String
    Public Shared dbSource As String
    Public Shared dbDest As String
    End
    Class

    Then elsewhere within FORMs you can use.>>

    sharedVariable.dbSource = "Whatever string"

    As you have discovered the SHARED keyword makes a PUBLIC variable available without having to declare an instance of the CLASS.

    So this is not needed.>>

    Dim instance As New sharedVariable
    instance.dbSource =
    "Whatever string"

    as the SHARED keyword makes the variable SHARED with every instance. You can still use it with an instance if you really want to however in the PROJECT menu under PROPERTIES in the COMPILE tab you would have to turn the WARNING off to NONE for
    Instance variable accesses a SHARED member.

    In which case every instance of the CLASS would have the same SHARED values.

    >>

    Shared member

    To fully use GET and SET that would be part of setting up a PROPERTY for a CLASS which can be a more indepth subject on its own.

    As I said earlier, use a MODULE with PUBLIC variables or PUBLIC SHARED variables in a CLASS.

    I think PROFESSIONAL developers prefer the latter use of PUBLIC SHARED variables in a CLASS for global scope throughout your application or program.

    Try to keep your use of GLOBAL variables to a minimum though and pass objects and variables around using ByVal or ByRef as appropriate for your needs.


    Regards,

    John

    For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
    • Edited by John Anthony Oliver Wednesday, January 7, 2009 10:41 AM ............................................................
    • Marked as answer by Xingwei Hu Monday, January 12, 2009 7:02 AM
    Wednesday, January 7, 2009 10:19 AM

All replies

  • check this out from MSDN on Variable Scope

    http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx
    Tuesday, January 6, 2009 9:15 PM
  • If you want only one instance of your config, I would recommend to create a module and add the Public myConfig as New config to the module

    Ewald - Please remember to mark the replies as answers if they help.
    Tuesday, January 6, 2009 9:16 PM
  • Thanks for the suggestions.  I read the article and tried declaring "Public myConfig As New config" in a base module, but still loose the contents of myconfig object right after the transition from the 1st form to the 2nd form.

    Do I need to:

    • Do I need to put the class declaration in a VB module rather than a VB class file?
    • Do I need to add the 'shared' keyword anywhere?
    • Do I need to reference the class in the declaration section of each form in the project?
    • Do I need to add get and set code to the class definition?

    Thanks again, -BGood

    Wednesday, January 7, 2009 12:26 AM
  • BGood said:

    Thanks for the suggestions.  I read the article and tried declaring "Public myConfig As New config" in a base module, but still loose the contents of myconfig object right after the transition from the 1st form to the 2nd form.

    Do I need to:

    • Do I need to put the class declaration in a VB module rather than a VB class file?
    • Do I need to add the 'shared' keyword anywhere?
    • Do I need to reference the class in the declaration section of each form in the project?
    • Do I need to add get and set code to the class definition?

    Thanks again, -BGood



    Hi BGood,

    If you only want one config just use a module like.>>

    Module myVariables
    Public dirJobFilePath As String
    Public dirLibraryPath As String
    Public dbSource As String
    Public dbDest As String
    End
    Module

    Then

    dbSource = "????"
    'or use.>>
    myVariables.dbSource = "????"

    If you would rather use a CLASS then use.>>

    Public Class sharedVariable
    Public Shared dirJobFilePath As String
    Public Shared dirLibraryPath As String
    Public Shared dbSource As String
    Public Shared dbDest As String
    End
    Class

    Then elsewhere within FORMs you can use.>>

    sharedVariable.dbSource = "Whatever string"

    As you have discovered the SHARED keyword makes a PUBLIC variable available without having to declare an instance of the CLASS.

    So this is not needed.>>

    Dim instance As New sharedVariable
    instance.dbSource =
    "Whatever string"

    as the SHARED keyword makes the variable SHARED with every instance. You can still use it with an instance if you really want to however in the PROJECT menu under PROPERTIES in the COMPILE tab you would have to turn the WARNING off to NONE for
    Instance variable accesses a SHARED member.

    In which case every instance of the CLASS would have the same SHARED values.

    >>

    Shared member

    To fully use GET and SET that would be part of setting up a PROPERTY for a CLASS which can be a more indepth subject on its own.

    As I said earlier, use a MODULE with PUBLIC variables or PUBLIC SHARED variables in a CLASS.

    I think PROFESSIONAL developers prefer the latter use of PUBLIC SHARED variables in a CLASS for global scope throughout your application or program.

    Try to keep your use of GLOBAL variables to a minimum though and pass objects and variables around using ByVal or ByRef as appropriate for your needs.


    Regards,

    John

    For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
    • Edited by John Anthony Oliver Wednesday, January 7, 2009 10:41 AM ............................................................
    • Marked as answer by Xingwei Hu Monday, January 12, 2009 7:02 AM
    Wednesday, January 7, 2009 10:19 AM
  • Hi again BGood,

    If you have the following then myString is PRIVATE by default and not accessible outside of this CLASS.>>

    Private by default.
    _______________________________________________________________________


    Yes a FORM code block is an example of CLASS code.

    However FORMs have a default instance.

    So you could access a property directly elsewhere in code.>>  Form1.Text = "Hi!!"


    Option Strict On 
     
    Public Class Form1  
     
        Dim myString As String '<< This is PRIVATE by default.  
     
        Private Sub Sub1()  
     
            'myString is available here.>>  
            myString = "Hi there!!" 
     
        End Sub 
     
        Private Sub Sub2()  
     
            'myString is also available here.>>  
            myString = "Hello again!!" 
     
        End Sub 
     
    End Class 
     

    Here is another scope limitation.>>

    Option Strict On 
     
    Public Class Form1  
     
        Dim myString As String '<< This is PRIVATE by default.  
     
        Private Sub Sub1()  
     
            'myString is available here.>>  
            myString = "Hi there!!" 
     
            If myString = "Hi there!!" Then 
     
                Dim test As Boolean = True 
                MessageBox.Show(myString)  
     
            End If 
     
            'The variable test is not available outside the IF - THEN - ENDIF here.  
     
        End Sub 
     
        Private Sub Sub2()  
     
            'myString is also available here.>>  
            myString = "Hello again!!" 
     
        End Sub 
     
    End Class 
     

    The variables in the MODULE myVariables or the CLASS sharedVariables in my previous post would be available in Form1 , Form2 or anywhere in your application or program code within the same PROJECT.

    You can have more than one PROJECT in a SOLUTION too which I have not really experimented with a great deal so I can not comment with regards scope across a multiple-project solution.

    Finally if you are used to Visual C# or Visual C++ the keyword this which refers to the current CLASS code block has the equivalent of ME in Vb.Net.

    It is a common misconception that ME refers to Form1 , it would only within the Form1 CLASS code block.


    Regards,

    John

    For links to VB.Net tutorials see here.>> http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/29f2179b-997b-4115-a96d-a0834853b835
    Wednesday, January 7, 2009 10:57 AM
  • John, Thank you so much for your articulate and comprehensive explanation. I had spent days on this problem, and finally my global objects were persisted as intended, but I was not sure why. 

    With reference to the concepts and practices you explain, I used a Public declaration within an initial module and the objects so declared were persisted throughout the project.  I think the problem I was experiencing derived from my old habit from BASIC and FORTRAN program modules where COMMON variables must be explicitly declared in each module for global persistence.  By doing so, I think I was instantiating a new local variable which obscured the global object. 

    Anyway, it works now, and thanks to your posting I have a much better grasp of the concepts involved.  -BGood
    Monday, January 12, 2009 3:12 PM
  • PS: When I removed the interfering public declarations in the various forms, the global object was persisted as intended. -BGood
    Monday, January 12, 2009 3:15 PM