2017-01-24 11 views
6

में वर्ग मॉड्यूल को संरक्षित करें मान लें कि मैं एक्सेल वीबीए में बाइक डिजाइनर प्रोग्राम बनाना चाहता हूं। मेरे पास क्लास ऑब्जेक्ट है (cBike) जिसमें कुछ डिफ़ॉल्ट सेटिंग्स हैं। अब मैं एक फॉर्म (छवि में से एक की तरह) बनाना चाहता हूं जिसका उपयोग डेटाबेस में बाइक को संग्रहीत करने से पहले इन सेटिंग्स को बदलने के लिए किया जा सकता है। भंडारण के लिए विधि (उप), cBike में स्थित है।फॉर्म

Example of a userform for designing a bicycle.

मैं प्रपत्र कोड में एक सार्वजनिक चर के रूप में वस्तु की रक्षा कर सकता है, इस तरह:

Public objBike As cBike 
Public Sub StoreBikeToDatabase() 
'database storing code goes here 
End Sub 

कि काम करेंगे, मैं के इस्तेमाल के खिलाफ उनका तर्क है बहुत से लोगों को देखा है सार्वजनिक (वैश्विक) चर। मुझे पूरा यकीन नहीं है कि, इस तथ्य को छोड़कर कि यदि आपके पास बहुत अधिक वैश्विक चर हैं, तो आपका कोड गड़बड़ होगा।

वैकल्पिक रूप से मैं ऑब्जेक्ट को भूल सकता हूं, और क्लास मॉड्यूल cBike के गुणों के बजाय विभिन्न फ़ॉर्म नियंत्रणों से मूल्यों का उपयोग कर सकता हूं। हालांकि यह एक बेवकूफ समाधान की तरह लगता है।

मेरा प्रश्न यह है: उपरोक्त में से कौन सा समाधान सबसे अच्छा है, यदि कोई है? और यदि उनमें से कोई नहीं, तो मुझे इसके बजाय क्या करना चाहिए?

अद्यतन: मैं दृढ़ता से सुझाव दूंगा कि आप स्वीकार किए गए उत्तर दोनों को पढ़ लेंगे, और एक और आगे नीचे। दोनों उत्तरों के कुछ महान विचार हैं और डीई की पोस्ट में कुछ व्यापक कोड उदाहरण हैं जो दूसरों के लिए मेरे जैसे प्रश्नों के लिए उपयोग किए जा सकते हैं।

+0

आप प्रॉपर्टी में फार्म पर तीन मानों बना सकता है एक रद्द संपत्ति, कि पढ़ने के लिए हैं/बुला कोड जो अद्यतन करने का ख्याल रखता है द्वारा लिखित के साथ ' आवश्यकतानुसार cBike' ऑब्जेक्ट। – Rory

+0

यह इस बात पर निर्भर करता है कि आपको उस डेटा को स्टोर करने की आवश्यकता क्यों है और क्यों (डेटाबेस के विपरीत स्मृति में)। यदि आप प्रत्येक बार कक्षा का एक नया उदाहरण बनाते हैं, गुणों को संपादित करते हैं और डेटाबेस में सहेजते हैं, तो आपको फ़ॉर्म के अंदर 'cBike' का' निजी 'उदाहरण बनाना चाहिए, या फ़ॉर्म में पहले से बनाए गए' cBike' को पास करना होगा इसे दिखाने से पहले। – GSerg

+0

विचार यह था कि मुझे फॉर्म में 'cBike' के पहले से बनाए गए उदाहरण को पास करने की आवश्यकता है, जो उस ऑब्जेक्ट को तब तक सुरक्षित रखता है जब तक इसे संग्रहीत करने की आवश्यकता न हो। 'CBike' की गुण फ़ॉर्म में इसे पारित करने के बाद फ़ॉर्म द्वारा बदला जा सकता है, लेकिन इससे पहले कि यह डेटाबेस में संग्रहीत हो। – Noceo

उत्तर

4

एक फॉर्म अनिवार्य रूप से एक वर्ग है, इसलिए मैं आपके बाइक ऑब्जेक्ट को पकड़ने के लिए फॉर्म में एक निजी संपत्ति बनाने की अनुशंसा करता हूं। फिर आप मौजूदा बाइक ऑब्जेक्ट को प्रॉपर्टी सेट रूटीन के माध्यम से फॉर्म/क्लास में पास कर सकते हैं।

बाइक सदस्य/संपत्ति को फॉर्म स्तर पर घोषित करने में कोई समस्या नहीं है यदि इसे फ़ॉर्म के भीतर कई दिनचर्या तक पहुंचाया जाना चाहिए। वैश्विक/सार्वजनिक चर (मॉड्यूल में घोषित) का उपयोग केवल तभी किया जाना चाहिए जब ऑब्जेक्ट को पूरी परियोजना द्वारा उपयोग करने की आवश्यकता हो।

'Private Member of this Form/Class 
Private mBike As cBike 

'Pass the existing object into this Form/Class 
Public Property Let Bike(ByVal obj As cBike) 

    Set mBike = obj 

End Property 

आप को प्रभावी ढंग से इस प्रकार cBike के गुणों की घोषणा के द्वारा प्रपत्र नियंत्रण और अपने वर्ग के बीच एक गतिशील लिंक बना सकते हैं:

Private WithEvents mTextBox1 As MSForms.TextBox 

Public Property Set TextBox1(ByVal obj As MSForms.TextBox) 

    Set mTextBox1 = obj 

End Property 

इसका मतलब यह है कि आप का मान गुजर रखने के लिए की जरूरत नहीं होगी कक्षा में टेक्स्टबॉक्स को बदलना चाहिए। आपको माइक्रोसॉफ्ट फॉर्म 2.0 ऑब्जेक्ट लाइब्रेरी

+0

धन्यवाद, यह मेरे विचारों की तुलना में एक बेहतर तरीका लगता है। कुछ चतुरता के साथ, मुझे लगता है कि यह नियंत्रण और 'cBike' ऑब्जेक्ट के संबंधित गुणों के बीच कुछ प्रकार के कनेक्शन की अनुमति देगा ... – Noceo

+0

हाँ, यह सही है। मैंने यह दिखाने के लिए एक संपादन शामिल किया है कि यह कैसे किया जाता है –

+0

तो एक संपत्ति को एक व्यवहार्य के रूप में जोड़ने की बजाय, मैं संपत्ति के रूप में नियंत्रण जोड़ता हूं? उदाहरण के लिए 'NumberOfGears()' नामक एक संपत्ति रखने के बजाय जो पूर्णांक से जुड़ा हुआ है, मैं इसे एक टेक्स्टबॉक्स से लिंक करता हूं? फिर मैं उस संपत्ति के मूल्य को कैसे प्राप्त/सेट करूं (यानी टेक्स्टबॉक्स का मान)। – Noceo

3

पर एक संदर्भ सेट की आवश्यकता होगी Bike संपादन योग्य होने के लिए एक और तरीका हो सकता है। Bike कक्षा में BikeEditor होगा जो बाइक ऑब्जेक्ट के संपादन के लिए उपयोगकर्ता का रूप है। बाइक प्रकार के लिए यहां उदाहरण दिया गया है लेकिन अन्य बाइक गुणों को भी इसी तरह से किया जा सकता है। BikeType के लिए एक कक्षा का उपयोग किया जाता है जो TypeOfBikeEnum को लपेटता है।

बाइक

Private m_editor As BikeEditor 
Private m_bikeType As BikeType 

Private Sub Class_Initialize() 
    Set m_editor = New BikeEditor 
    Set m_bikeType = New BikeType 
End Sub 

Public Property Get TypeOfBike() As BikeType 
    Set TypeOfBike = m_bikeType 
End Property 

Public Property Set TypeOfBike(ByVal vNewValue As BikeType) 
    Set m_bikeType = vNewValue 
End Property 

Public Sub Edit() 
    m_editor.Initialize Me 
    m_editor.Show 
End Sub 

BikeType

Public Enum TypeOfBikeEnum 
    [_First] 
    Unknown = 1 
    MountainBike = 2 
    StreetBike = 3 
    OfficeBike = 4 
    MoonBike = 5 
    [_Last] 
End Enum 

Private m_type As TypeOfBikeEnum 

Private Sub Class_Initialize() 
    m_type = Unknown 
End Sub 

Public Property Get TypeValue() As TypeOfBikeEnum 
    TypeValue = m_type 
End Property 

Public Property Let TypeValue(ByVal vNewValue As TypeOfBikeEnum) 
    m_type = vNewValue 
End Property 

Public Function GetBikeTypeNames() As VBA.Collection 
    Dim enumVal As Long, name As String 
    Set GetBikeTypeNames = New VBA.Collection 
    For enumVal = TypeOfBikeEnum.[_First] To TypeOfBikeEnum.[_Last] 
     name = GetBikeTypeName(enumVal) 
     If name <> "" Then _ 
      GetBikeTypeNames.Add name, CStr(enumVal) 
    Next enumVal 
End Function 

Public Function GetBikeTypeName(typeOfBikeValue As TypeOfBikeEnum) As String 
    Select Case typeOfBikeValue 
     Case TypeOfBikeEnum.Unknown 
      GetBikeTypeName = "Unknown" 
     Case TypeOfBikeEnum.MountainBike 
      GetBikeTypeName = "MountainBike" 
     Case TypeOfBikeEnum.StreetBike 
      GetBikeTypeName = "StreetBike" 
     Case TypeOfBikeEnum.OfficeBike 
      GetBikeTypeName = "OfficeBike" 
     Case TypeOfBikeEnum.MoonBike 
      GetBikeTypeName = "MoonBike" 
     Case Else 
      GetBikeTypeName = "" 
    End Select 
End Function 

BikeEditor

Private m_bikeToEdit As Bike 

Public Sub Initialize(bikeToEdit As Bike) 
    Set m_bikeToEdit = bikeToEdit 
    Dim bikeTypeName 
    For Each bikeTypeName In m_bikeToEdit.TypeOfBike.GetBikeTypeNames 
     Me.bikeTypesComboBox.AddItem bikeTypeName 
    Next 
    Me.bikeTypesComboBox.ListIndex = m_bikeToEdit.TypeOfBike.TypeValue - 1 
End Sub 

Private Sub CancelCommandButton_Click() 
    Unload Me 
End Sub 

Private Sub SaveCommandButton_Click() 
    If Me.bikeTypesComboBox.ListIndex > -1 Then 
     m_bikeToEdit.TypeOfBike.TypeValue = Me.bikeTypesComboBox.ListIndex + 1 
    End If 
    Unload Me 
End Sub 

मॉड्यूल

Sub test() 
    Dim bk As Bike 
    Set bk = New Bike 

    Dim bt As BikeType 
    Set bt = New BikeType 
    bt.TypeValue = OfficeBike 

    Set bk.TypeOfBike = bt 
    bk.Edit 
End Sub 
+0

व्यापक मार्गदर्शिका के लिए धन्यवाद होगा। मैं ऑब्जेक्ट को फॉर्म में ऑब्जेक्ट पास करने के बजाए ऑब्जेक्ट में एडिट फॉर्म जोड़ने का विचार पसंद करता हूं। – Noceo

+0

आपका स्वागत है। – dee