खोज…


परिचय

कोड जो संकलित कर सकता है वह रन-टाइम पर, त्रुटियों में भी चल सकता है। यह विषय सबसे आम लोगों, उनके कारणों और उनसे बचने के तरीके को सूचीबद्ध करता है।

रन-टाइम त्रुटि '3': GoSub के बिना लौटें

गलत कोड

Sub DoSomething()
    GoSub DoThis
DoThis:
    Debug.Print "Hi!"
    Return
End Sub

यह काम क्यों नहीं करता है?

निष्पादन में प्रवेश करती है DoSomething प्रक्रिया, करने के लिए कूदता है DoThis , प्रिंट लेबल "हाय!" डीबग आउटपुट के लिए, GoSub कॉल के तुरंत बाद निर्देश पर लौटता है, "Hi!" फिर से, और फिर एक Return स्टेटमेंट का सामना करता है, लेकिन अब वापस लौटने के लिए कहीं नहीं है, क्योंकि हम यहां GoSub स्टेटमेंट के साथ नहीं GoSub

सही कोड

Sub DoSomething()
    GoSub DoThis
    Exit Sub
DoThis:
    Debug.Print "Hi!"
    Return
End Sub

यह काम क्यों करता है?

DoThis लाइन लेबल से पहले एक Exit Sub इंस्ट्रक्शन पेश करके, हमने DoThis सबरूटीन को बाकी प्रक्रिया शरीर से अलग कर दिया है - DoThis सबरूटीन को निष्पादित करने का एकमात्र तरीका GoSub कूद है।

अन्य नोट

GoSub / Return को हटा दिया जाता है, और वास्तविक प्रक्रिया कॉल के पक्ष में इससे बचा जाना चाहिए। एक प्रक्रिया में त्रुटि हैंडलर के अलावा, सबरूटीन शामिल नहीं होना चाहिए।

यह रन-टाइम त्रुटि '20' के समान है: त्रुटि के बिना फिर से शुरू करें ; दोनों स्थितियों में, समाधान यह सुनिश्चित करने के लिए है कि सामान्य निष्पादन पथ एक स्पष्ट कूद के बिना एक उप-रूटीन (एक लाइन लेबल द्वारा पहचाना गया) में प्रवेश नहीं कर सकता है (यह मानकर On Error GoTo को एक स्पष्ट कूद माना जाता है)।

रन-टाइम एरर '6': ओवरफ्लो

गलत कोड

Sub DoSomething()
    Dim row As Integer
    For row = 1 To 100000
        'do stuff
    Next
End Sub

यह काम क्यों नहीं करता है?

Integer डेटा प्रकार एक 16-बिट हस्ताक्षरित पूर्णांक है जिसमें अधिकतम मूल्य 32,767 है; इससे बड़ी चीज को सौंपना, इस प्रकार के अतिप्रवाह और इस त्रुटि को बढ़ाएगा।

सही कोड

Sub DoSomething()
    Dim row As Long
    For row = 1 To 100000
        'do stuff
    Next
End Sub

यह काम क्यों करता है?

इसके बजाय एक Long (32-बिट) पूर्णांक का उपयोग करके, हम अब एक लूप बना सकते हैं जो काउंटर चर के प्रकार को ओवरफ्लो किए बिना 32,767 से अधिक बार पुनरावृत्त करता है।

अन्य नोट

अधिक जानकारी के लिए डेटा प्रकार और सीमाएँ देखें।

रन-टाइम त्रुटि '9': सीमा से बाहर सदस्यता

गलत कोड

Sub DoSomething()
    Dim foo(1 To 10)
    Dim i As Long
    For i = 1 To 100
        foo(i) = i
    Next
End Sub

यह काम क्यों नहीं करता है?

foo एक सरणी है जिसमें 10 आइटम हैं। जब i लूप काउंटर 11 के मान पर पहुंच जाता है, तो foo(i) सीमा से बाहर हो जाता है । यह त्रुटि तब होती है जब कोई सरणी या संग्रह एक अनुक्रमणिका के साथ एक्सेस किया जाता है जो उस सरणी या संग्रह में मौजूद नहीं होता है।

सही कोड

Sub DoSomething()
    Dim foo(1 To 10)
    Dim i As Long
    For i = LBound(foo) To UBound(foo)
        foo(i) = i
    Next
End Sub

यह काम क्यों करता है?

क्रमशः एक सरणी की निचली और ऊपरी सीमाओं को निर्धारित करने के लिए LBound और UBound फ़ंक्शन का उपयोग करें।

अन्य नोट

जब सूचकांक एक स्ट्रिंग है, उदाहरण के लिए ThisWorkbook.Worksheets("I don't exist") , इस त्रुटि का अर्थ है कि आपूर्ति नाम क्वेरिड संग्रह में मौजूद नहीं है।

वास्तविक त्रुटि हालांकि कार्यान्वयन-विशिष्ट है; Collection रन-टाइम त्रुटि 5 उठाएगा "इसके बजाय अमान्य प्रक्रिया कॉल या तर्क":

Sub RaisesRunTimeError5()
    Dim foo As New Collection
    foo.Add "foo", "foo"
    Debug.Print foo("bar")
End Sub

रन-टाइम त्रुटि '13': टाइप बेमेल

गलत कोड

Public Sub DoSomething()
    DoSomethingElse "42?"
End Sub

Private Sub DoSomethingElse(foo As Date)
'    Debug.Print MonthName(Month(foo))
End Sub

यह काम क्यों नहीं करता है?

VBA "42?" को रूपांतरित करने के लिए वास्तव में कठिन प्रयास कर रहा है "42?" Date मान में तर्क। जब यह विफल हो जाता है, तो DoSomethingElse कॉल निष्पादित नहीं किया जा सकता है, क्योंकि VBA को पता नहीं है कि किस तारीख को पास होना है, इसलिए यह रन-टाइम त्रुटि 13 प्रकार के बेमेल उठाता है, क्योंकि तर्क का प्रकार अपेक्षित प्रकार से मेल नहीं खाता है (और कर सकते हैं) 'या तो स्पष्ट रूप से रूपांतरित न हों)।

सही कोड

Public Sub DoSomething()
    DoSomethingElse Now
End Sub

Private Sub DoSomethingElse(foo As Date)
'    Debug.Print MonthName(Month(foo))
End Sub

यह काम क्यों करता है?

एक में उत्तीर्ण होकर Date एक प्रक्रिया है जो एक उम्मीद करने के लिए तर्क Date पैरामीटर, कॉल सफल होने के कर सकते हैं।

रन-टाइम त्रुटि '91': ऑब्जेक्ट वेरिएबल या ब्लॉक वेरिएबल के साथ सेट नहीं है

गलत कोड

Sub DoSomething()
    Dim foo As Collection
    With foo
        .Add "ABC"
        .Add "XYZ"
    End With
End Sub

यह काम क्यों नहीं करता है?

ऑब्जेक्ट चर एक संदर्भ रखते हैं , और Set कीवर्ड का उपयोग करके संदर्भ सेट करने की आवश्यकता होती है। यह त्रुटि तब होती है जब भी किसी सदस्य को किसी ऑब्जेक्ट पर कॉल किया जाता है जिसका संदर्भ Nothing । इस मामले में foo एक Collection संदर्भ है, लेकिन इसे प्रारंभ नहीं किया गया है, इसलिए संदर्भ में Nothing - और हम कॉल नहीं कर सकते। Nothing पर .Add करें।

सही कोड

Sub DoSomething()
    Dim foo As Collection
    Set foo = New Collection
    With foo
        .Add "ABC"
        .Add "XYZ"
    End With
End Sub

यह काम क्यों करता है?

ऑब्जेक्ट कीवर्ड को Set कीवर्ड का उपयोग करके एक वैध संदर्भ निर्दिष्ट करके, .Add कॉल सफल होती है।

अन्य नोट

अक्सर, एक फ़ंक्शन या प्रॉपर्टी एक ऑब्जेक्ट संदर्भ लौटा सकती है - एक सामान्य उदाहरण एक्सेल की Range.Find विधि, जो एक Range ऑब्जेक्ट लौटाता है:

Dim resultRow As Long
resultRow = SomeSheet.Cells.Find("Something").Row

हालांकि फ़ंक्शन बहुत अच्छी तरह से Nothing लौटा सकता है (यदि खोज शब्द नहीं मिला है), तो यह संभावना है कि जंजीर। .Row सदस्य कॉल विफल हो जाती है।

ऑब्जेक्ट सदस्यों को कॉल करने से पहले, सत्यापित करें कि संदर्भ एक If Not xxxx Is Nothing साथ सेट If Not xxxx Is Nothing है:

Dim result As Range
Set result = SomeSheet.Cells.Find("Something")

Dim resultRow As Long
If Not result Is Nothing Then resultRow = result.Row

रन-टाइम त्रुटि '20': त्रुटि के बिना फिर से शुरू करें

गलत कोड

Sub DoSomething()
    On Error GoTo CleanFail
    DoSomethingElse

CleanFail:
    Debug.Print Err.Number
    Resume Next
End Sub

यह काम क्यों नहीं करता है?

यदि DoSomethingElse प्रक्रिया एक त्रुटि उठाती है, तो निष्पादन CleanFail लाइन लेबल पर कूदता है, त्रुटि संख्या को प्रिंट करता है, और Resume Next से Resume Next निर्देश Resume Next निर्देश पर वापस जाता है कि तुरंत उस पंक्ति का अनुसरण करता है जहां त्रुटि हुई थी, जो इस मामले में Debug.Print निर्देश: त्रुटि से निपटने वाला सबरूटीन त्रुटि संदर्भ के बिना निष्पादित हो रहा है, और जब रिज्यूमे Resume Next इंस्ट्रक्शन पहुँच जाता है, तो रन-टाइम एरर २० उठाया जाता है क्योंकि फिर से शुरू करने के लिए कहीं नहीं है।

सही कोड

Sub DoSomething()
    On Error GoTo CleanFail
    DoSomethingElse

    Exit Sub    
CleanFail:
    Debug.Print Err.Number
    Resume Next
End Sub

यह काम क्यों करता है?

CleanFail लाइन लेबल से पहले एक Exit Sub इंस्ट्रक्शन पेश करके, हमने CleanFail एरर-हैंडलिंग सबरूटीन को बाकी प्रक्रिया बॉडी से अलग कर CleanFail है - एरर-हैंडलिंग सबरूटीन को निष्पादित करने का एकमात्र तरीका On Error जंप के माध्यम से है; इसलिए, कोई निष्पादन पथ त्रुटि संदर्भ के बाहर Resume निर्देश तक नहीं पहुंचता है, जो रन-टाइम त्रुटि 20 से बचा जाता है।

अन्य नोट

यह रन-टाइम त्रुटि '3' के समान है: GoSub के बिना लौटें ; दोनों स्थितियों में, समाधान यह सुनिश्चित करने के लिए है कि सामान्य निष्पादन पथ एक स्पष्ट कूद के बिना एक उप-रूटीन (एक लाइन लेबल द्वारा पहचाना गया) में प्रवेश नहीं कर सकता है (यह मानकर On Error GoTo को एक स्पष्ट कूद माना जाता है)।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow