2012-05-15 13 views
10

में गतिशील रूप से बनाए गए उपयोगकर्ता फॉर्म पर नियंत्रण के लिए ईवेंट हैंडलर को असाइन करें। मुझे इंटरनेट पर कई संसाधन मिले हैं जो लगभग करते हैं जो मैं करना चाहता हूं, लेकिन काफी नहीं। मेरे पास नामित रेंज "डेलिस्ट" है। दिन में प्रत्येक दिन के लिए, मैं उपयोगकर्ता फॉर्म पर एक बटन बनाना चाहता हूं जो उस दिन मैक्रो चलाएगा। मैं add the buttons dynamically करने में सक्षम हूँ, लेकिन पता है कि daycell.text नामांकित श्रेणी से, बटन के लिए, ईवेंट हैंडलर के लिए, मैक्रो को पारित करने के लिए न: एस यहाँ कोड मैं उपयोगकर्ता प्रपत्र बनाने के लिए:वीबीए

Sub addLabel() 
ReadingsLauncher.Show vbModeless 
Dim theLabel As Object 
Dim labelCounter As Long 
Dim daycell As Range 
Dim btn As CommandButton 
Dim btnCaption As String 


For Each daycell In Range("daylist") 
    btnCaption = daycell.Text 
    Set theLabel = ReadingsLauncher.Controls.Add("Forms.Label.1", btnCaption, True) 
    With theLabel 
     .Caption = btnCaption 
     .Left = 10 
     .Width = 50 
     .Top = 20 * labelCounter 
    End With 

    Set btn = ReadingsLauncher.Controls.Add("Forms.CommandButton.1", "runButton", True) 
    With btn 
     .Caption = "Run Macro for " & btnCaption 
     .Left = 80 
     .Width = 80 
     .Top = 20 * labelCounter 
    ' .OnAction = "btnPressed" 
    End With 

    labelCounter = labelCounter + 1 
Next daycell 

End Sub 

ऊपर समस्या के समाधान मिलता है मैं वर्तमान में दिन वे चलाने के लिए (जैसे Day1) और मैक्रो को यह पारित चाहते टाइप करने के लिए संकेत और यह काम करता करने के लिए:

Sub B45runJoinTransactionAndFMMS() 


loadDayNumber = InputBox("Please type the day you would like to load:", Title:="Enter Day", Default:="Day1") 

Call JoinTransactionAndFMMS(loadDayNumber) 

End Sub 

Sub JoinTransactionAndFMMS(loadDayNumber As String) 
xDayNumber = loadDayNumber 

Sheets(xDayNumber).Activate 
-Do stuff 

End Sub 
मेरी runButtons से प्रत्येक के लिए

इसलिए, यह daycell.text को प्रदर्शित करने की आवश्यकता है, और एक मैक्रो चलाएं जो वर्कशीट का चयन करने के लिए वर्कशीट का चयन करने के लिए पैरामीटर के समान टेक्स्ट का उपयोग करता है।

कोई भी मदद अद्भुत होगी। मैंने प्रतिक्रियाओं को देखा जो मैक्रोज़ को संभालने के लिए गतिशील रूप से वीबीए कोड लिखते हैं, लेकिन मेरा मानना ​​है कि वहां कुछ होना चाहिए, इसे पास करने वाले पैरामीटर के माध्यम से थोड़ा और सुंदर ढंग से किया जा सकता है, बस यह सुनिश्चित न करें कि कैसे। अग्रिम में बहुत धन्यवाद!

+0

[इस] (http://www.access-programmers.co.uk/forums/archive/index.php/t-88887.html) आप जो चाहते हैं उसके करीब दिखता है। ओटीओएच क्यों एक combobox नहीं बना है जो 'daylist' से पॉप्युलेट करता है और एक कमांड बटन जो चयनित मान पढ़ सकता है? –

+0

मुझे लगता है कि मुझे उस विकल्प के लिए जाना पड़ सकता है। चूंकि मैक्रो का उपयोग स्क्रीनिंग और डेटा अपलोड करने के लिए किया जाता है, इसलिए मैं उम्मीद कर रहा था कि मैं एक छोटी लॉन्च स्क्रीन तैयार कर पाऊंगा जो पॉप्युलेट करेगा कि प्रत्येक तारीख के लिए एक लाइन होगी और रिकॉर्ड # # त्रुटियों, # त्रुटियों आदि दिखाएगी उनमें से प्रत्येक के लिए बटन बस थोड़ा और उपयोगकर्ता के अनुकूल बना देगा। हालांकि, जब तक कि मुझे एक आसान समाधान नहीं मिल रहा है, मुझे लगता है कि आपका सुझाव विजेता होगा। – BiGXERO

+0

एक और विचार ... शायद आप एक विशेष वर्कशीट में संबंधित जानकारी (दिन, # रिकॉर्ड, # त्रुटियां इत्यादि) की एक तालिका बना सकते हैं और वहां पर क्लिक ईवेंट पर कब्जा कर सकते हैं। –

उत्तर

16

मुझे पता है तुम अब एक समाधान स्वीकार कर लिया है कि आप के लिए काम करते हैं और नीचे तुलना में बहुत सरल है जाएगा, लेकिन यदि आप रुचि रखते हैं, इस के लिए और अधिक सीधा जवाब होगा आपका प्रश्न।

आपको बटन क्लिक को संभालने के लिए कक्षा बनाने की आवश्यकता है, इसलिए जब भी बटन क्लिक किया जाता है तो यह कक्षा में ईवेंट का उपयोग करता है, आपको केवल एक बार ऐसा करने की आवश्यकता होती है, फिर प्रत्येक बटन के लिए इसका एक नया उदाहरण बनाएं। इन कक्षाओं को गुंजाइश से बाहर जाने और खोने के लिए, उन्हें कक्षा स्तर की घोषणा में भंडारण की आवश्यकता है। नीचे में मैंने आपके कोड को थोड़ा सा स्थानांतरित कर दिया है।

वर्ग मॉड्यूल में (मैं इसे cButtonHandler बुलाया गया है)

Public WithEvents btn As MSForms.CommandButton 

Private Sub btn_Click() 
    MsgBox btn.Caption 
End Sub 

घटनाओं के साथ प्रयोग किया जाता है के रूप में यह आप पर नियंत्रण के लिए घटनाओं का सबसे उपयोग करने के लिए अनुमति देता है।

Dim collBtns As Collection 

Private Sub UserForm_Initialize() 

Dim theLabel As Object 
Dim labelCounter As Long 
Dim daycell As Range 
Dim btn As CommandButton 
Dim btnCaption As String 
'Create a variable of our events class 
Dim btnH As cButtonHandler 
'Create a new collection to hold the classes 
Set collBtns = New Collection 

For Each daycell In Range("daylist") 
    btnCaption = daycell.Text 
    Set theLabel = ReadingsLauncher.Controls.Add("Forms.Label.1", btnCaption, True) 
    With theLabel 
     .Caption = btnCaption 
     .Left = 10 
     .Width = 50 
     .Top = 20 * labelCounter 
    End With 

    Set btn = ReadingsLauncher.Controls.Add("Forms.CommandButton.1", "runButton", True) 
    With btn 
     .Caption = "Run Macro for " & btnCaption 
     .Left = 80 
     .Width = 80 
     .Top = 20 * labelCounter 
     'Create a new instance of our events class 
     Set btnH = New cButtonHandler 
     'Set the button we have created as the button in the class 
     Set btnH.btn = btn 
     'Add the class to the collection so it is not lost 
     'when this procedure finishes 
     collBtns.Add btnH 
    End With 

    labelCounter = labelCounter + 1 
Next daycell 


End Sub 

फिर हम एक अलग दिनचर्या से useform कॉल कर सकते हैं: मैं userform के रूप में नीचे में बटन पीढ़ी कोड स्थानांतरित कर दिया है VBA में

Sub addLabel() 
ReadingsLauncher.Show vbModeless 

End Sub 

वर्ग विशेष रूप से अच्छी तरह से कई में शामिल नहीं हैं VBA किताबें (आम तौर पर आप एक समझ पाने के लिए VB6 किताबें पढ़ने की जरूरत है), लेकिन एक बार आप उन्हें समझ और वे कैसे काम करते हैं, वे अविश्वसनीय रूप से उपयोगी हो :)

आशा इस मदद करता है

संपादित करें - अतिरिक्त प्रश्नों को संबोधित करने के लिए

संग्रह में वस्तुओं को संदर्भित करने के लिए, यह या तो कुंजी या अनुक्रमणिका के माध्यम से किया जाता है।कुंजी का उपयोग करने के लिए, आप इसे जोड़ने के लिए संग्रह करने के लिए आइटम जोड़ने के रूप में है, इसलिए जरूरत है:

collBtns.Add btnH 

इस कारण बन सकते हैं

collBtns.Add btnH, btnCaption 

, कुंजी अद्वितीय होना चाहिए। तो आप इस प्रकार का उल्लेख कर सकते हैं:

'We refer to objects in a collection via the collection's key 
'Or by it's place in the collection 
'So either: 
MsgBox collBtns("Monday").btn.Caption 
'or: 
MsgBox collBtns(1).btn.Caption 
'We can then access it's properties and methods 
'N.B you won't get any intellisense 
collBtns("Monday").btn.Enabled = False 

तुम भी, यदि आवश्यक हो अपने वर्ग के लिए अतिरिक्त गुणों/विधि जोड़ सकते हैं तो उदाहरण के लिए:

Public WithEvents btn As MSForms.CommandButton 

Private Sub btn_Click() 
    MsgBox btn.Caption 
End Sub 

Public Property Let Enabled(value As Boolean) 
    btn.Enabled = value 
End Property 

तो पहुँचा जा चाहेंगे:

collBtns("Monday").Enabled = False 

क्या इससे मदद मिलती है? आगे पढ़ने के लिए मैं आपको चिप पियरसन की साइट पर इंगित करता हूं, उसके पास अधिकांश विषयों पर http://www.cpearson.com/excel/Events.aspx

बस याद रखें कि वीबीए वीबी 6 पर आधारित है, इसलिए पूरी तरह से ओओ भाषा नहीं है, उदाहरण के लिए, यह विरासत का समर्थन नहीं करता है सामान्य अर्थों, केवल इंटरफ़ेस विरासत

आशा इस मदद करता है :)

+0

गहराई से जवाब के लिए धन्यवाद ढेर। अभी भी उपयोगकर्ता-फॉर्म या चादरों का उपयोग करना है या नहीं, लेकिन यह एक उत्कृष्ट प्रतिक्रिया है, विशेष रूप से जैसा कि आप उल्लेख करते हैं, कक्षाओं से बचा जाना प्रतीत होता है (या सुपर तकनीकी रूप से समझाया गया है)।मैंने आपका उत्तर वास्तविक में बदल दिया क्योंकि यह वास्तव में – BiGXERO

+1

प्रश्न का उत्तर देता है, आपके उत्तर ने मुझे उपयोगकर्ता फॉर्मों का प्रयास करने के लिए विश्वास (एक बार जब मैंने वर्तमान शीट आधारित समाधान समाप्त कर लिया है) को आत्मविश्वास दिया है। 2 प्रश्न जो मुझे लगता है कि मैं खुद और अन्य नोबों को समान रूप से मदद करूंगा, 1) यदि मैं संग्रह में किसी विशेष बीटीएन को संदर्भित करना चाहता हूं (उदाहरण के लिए कैप्शन बदलने या इसे अदृश्य बनाने के लिए), तो क्या मैं इसे संग्रह का उपयोग करके संदर्भित कर सकता हूं संदर्भ (उदाहरण के लिए collBtns.btn [2]) 2) क्या आप किसी भी ऑनलाइन संसाधन को जानते हैं जो संग्रह, घटना हैंडलर इत्यादि की व्याख्या करता है। नोब जावा पृष्ठभूमि होने के कारण मुझे अधिक ऑब्जेक्ट उन्मुख और कम घटना संचालित होने का विचार पसंद है – BiGXERO

+0

मैंने बदल दिया है उपरोक्त प्रश्नों के उत्तर देने के लिए – SWa

2

वर्कशीट पर क्लिक करने के उदाहरण को पकड़ने का उदाहरण। कार्यपत्रक मॉड्यूल में इस रखो:

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
    ' e.g., range(A1:E1) is clicked 
    If Not Application.Intersect(Target, Range("A1:E1")) Is Nothing Then 
    MsgBox "You clicked " & Target.Address 
    End If 
End Sub 
+0

मुझे लगता है कि आप कुछ पर हैं। यदि मैं छेड़छाड़ विधि का उपयोग करता हूं, तो मेरी कोशिका के माध्यम से 'कोशिकाओं (दिनसेल, 6' को फिर से चलाने के लिए' लाइन के साथ कुछ का उपयोग करें, यह संभवतः मेरे मुद्दे के लिए एक रोचक-योग्य सरल समाधान हो सकता है। परीक्षण और रिपोर्ट की जाएगी। बहुत धन्यवाद – BiGXERO

+0

यह काम करता है! मैं जिस कोड का उपयोग करता हूं उसका परीक्षण करने के लिए: 'उप intersectCallingMacro() रेंज (" डी 8 ")। ' परीक्षण के लिए उपयोग किया गया' चुनें लक्ष्य = ActiveCell यदि अनुप्रयोग नहीं है। अंतर (लक्ष्य, रेंज (" ए 1: M100 ")) कुछ भी नहीं है तो फिर कॉल testIntersect (ActiveCell.Value) अंत तो End Sub उप testIntersect (dayString स्ट्रिंग के रूप में) मंद xDayString स्ट्रिंग के रूप में xDayString = dayString 0,123,शीट्स (xDayString)। अंत उप' (कोड स्वरूपण के लिए क्षमा) पैरामीटर के रूप में मैक्रो को सेल वेले पास करता है। गजब का! – BiGXERO