2009-06-19 20 views
5

मेरे पास है/मेरे एक्सेल डाटा शीट में प्रत्येक डेटा पंक्ति के लिए एक विशिष्ट आईडी परिभाषित करना चाहते हैं के माध्यम से Excel में सेल के लिए विशिष्ट आईडी सेट - जैसे कि मैं जब डेटा सिर्फ गुजर इसका इस्तेमाल कर सकते हैं और यह रहता है वही जब पंक्तियों को इसके ऊपर जोड़ा/हटा दिया जाता है।कैसे प्राप्त करने के लिए/VBA

मेरे विचार रेंज के आईडी विशेषता (msdn link)

तो उपयोग करने के लिए कर रहे हैं, मैं एक उपयोगकर्ता परिभाषित समारोह (UDF) जो मैं प्रत्येक पंक्ति है कि हो जाता है में जगह है/आईडी के रूप में इस सेट:

Dim gNextUniqueId As Integer 

Public Function rbGetId(ticker As String) 
    On Error GoTo rbGetId_Error 
    Dim currCell As Range 
    'tried using Application.Caller direct, but gives same error 
    Set currCell = Range(Application.Caller.Address) 
    If currCell.id = "" Then 
     gNextUniqueId = gNextUniqueId + 1 
     'this line fails no matter what value I set it to. 
     currCell.id = Str(gNextUniqueId) 
    End If 
    rbGetId = ticker & currCell.id 
    Exit Function 

    rbGetId_Error: 
    rbGetId = "!ERROR:" & Err.Description 
End Function 

लेकिन इस लाइन

"आवेदन से परिभाषित या वस्तु से परिभाषित त्रुटि"

साथ उल्लेख पर विफल रहता है

मैं शायद सोचा था कि अपने UDFs के उन सीमाओं में से एक है, लेकिन अगर मैं एक रिबन बटन से चालू होने वाले कोड से यह कोशिश मैं भी यही त्रुटि मिलती है ...

कैसे संगत आईडी रखने के लिए पर कोई अन्य सुझाव

- शायद मुझे अपने रिबन बटन के माध्यम से कोशिकाओं को पॉप्युलेट करना चाहिए, आईडी के बिना सेल ढूंढना और उनमें से सेल मूल्य उत्पन्न करना/सेट करना ...

संपादित करें: जैसा कि एंटी सोचा था, मेरे पास शीट संरक्षित है, लेकिन यहां तक ​​कि एक अनलॉक सेल में भी अभी भी विफल रहता है। शीट को असुरक्षित करना समस्या को हल करता है .... लेकिन मैंने "UserInterFaceOnly: = True" को सुरक्षित किया है, जो मुझे ऐसा करने की अनुमति देनी चाहिए। मैं मैन्युअल रूप से "संपादित वस्तुओं" की अनुमति देते हैं जब मैं चादर यह भी काम करता है की रक्षा, लेकिन मुझे लगता है कि के लिए एक कार्यक्रम संबंधी विकल्प दिखाई नहीं देता - और मैं UserInterfaceOnly सुविधा को सक्षम करने AutoOpen में सुरक्षित फ़ंक्शन को कॉल करने की जरूरत है ...

मुझे लगता है मैं बंद करने की आवश्यकता/पर अपने आईडी सेटिंग के आसपास की रक्षा - न ActiveSheet.unprotect है और न ही ActiveWorkbook.unprotect :(

- कि एक यूडीएफ में किया जा सकता है ... जो ऐसा लगता है यह नहीं कर सकते हैं, के रूप में वह काम नहीं करता यह सोचते हैं

अग्रिम धन्यवाद क्रिस

+1

आपका कोड Excel 2003 और 2007 दोनों में ठीक काम करता है। आपकी पुस्तक लॉक नहीं है या ऐसा कुछ है? – Ant

उत्तर

0

मुझे पता चला है कि अगर मैं "ड्राइंग ऑब्जेक्ट्स: = गलत" की रक्षा करता हूं, तो यूडीएफ आईडी सेट कर सकता है। अजीब।

इसके साथ सभी मदद के लिए धन्यवाद।

1

चींटी के साथ एक समय पर -।। अपने कोड एक्सेल 2003 SP3

पर यहाँ ठीक काम करता है 0

मैं भी उपयोग करने में सक्षम किया गया है:

Set currCell = Application.Caller 
If Application.Caller.ID = "" Then 
    gNextUniqueId = gNextUniqueId + 1 
    'this line fails no matter what value I set it to. 
    currCell.ID = Str(gNextUniqueId) 
End If 

अहा! मुझे लगता है कि मेरे पास है।

मुझे लगता है कि आप एक सरणी सूत्र से इस कॉल कर रहे हैं, और यह केवल पूरी रेंज के साथ एक बार कहा जाता हो जाता है। आप एक सीमा के लिए एक आईडी प्राप्त नहीं कर सकते - केवल एक ही सेल। यही कारण है Application.Caller.ID आप के लिए विफल रहता है, क्योंकि रेंज ("A1: B9")। आईडी एक Application-defined or object-defined error उत्पन्न करता है।

जब आप "सेल" प्राप्त करने के लिए Range(Application.Caller.Address) का उपयोग करते हैं तो आप केवल इस त्रुटि को currCell.ID लाइन पर रोक दें।

+0

यह एक सीमा सूत्र नहीं है, केवल एक ही सेल है। –

+0

उपरोक्त आपके EDIT के बाद - क्या आपने ActiveSheet.Unprotect या ActiveWorkbook का उपयोग करने का प्रयास किया है। असुरक्षित? आप हमेशा सेल का संदर्भ ले सकते हैं। माता-पिता यदि आप शीट (एक बुद्धिमान चाल) के साथ स्पष्ट होने से बचना चाहते हैं। मुझे लगता है क्योंकि यूडीएफ यूजर इंटरफेस का हिस्सा है, एक सूत्र होने के नाते, इसे शीट में कोई बदलाव करने से रोका गया है, लेकिन यह सिर्फ एक झटका है। –

1

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

+0

आईडी –

4

ठीक है ...

ऐसा लगता है कि अगर चादर लॉक होता है, मैक्रो इस तरह के आईडी के रूप में निम्न स्तर के बारे में जानकारी के लिए लेखन पहुँच नहीं है।

हालांकि, मुझे नहीं लगता कि यूडीएफ के भीतर शीट को असुरक्षित करना संभव है। डिजाइन द्वारा, यूडीएफ भारी प्रतिबंधित हैं; मुझे लगता है कि एक सेल फॉर्मूला को नियंत्रित करने से शीट सुरक्षा फॉर्मूला प्रतिमान को तोड़ देगी कि एक सेल सूत्र केवल सेल को प्रभावित करता है। अधिक जानकारी के लिए माइक्रोसॉफ्ट वेबसाइट पर this page देखें।

मुझे लगता है कि यह आपके विकल्पों को सीमित करता है। आप या तो:

  • यूडीएफ हार

    • शीट सुरक्षा देने, एक Worksheet_Change घटना का उपयोग सेल परिवर्तन को पकड़ने और वहाँ
    • एक यूडीएफ कि सेल मूल्य में आईडी लिखते का उपयोग आईडी को लिखने के लिए, आईडी

    यूडीएफ दृष्टिकोण समस्याओं से भरा हुआ है क्योंकि आप शीट पर स्थायी निशान बनाने के लिए सेल की गणना के लिए डिज़ाइन की गई कुछ चीज़ों का उपयोग करने की कोशिश कर रहे हैं।

    फिर भी, यहां एक यूडीएफ का एक उदाहरण है जिसका उपयोग आप एक सेल पर "स्थायी" मान मुद्रित करने के लिए कर सकते हैं, जो संरक्षित शीट की अनलॉक कोशिकाओं पर काम करता है। यह केवल एकल कोशिकाओं के लिए काम करता है (हालांकि इसे सरणी सूत्र के लिए अनुकूलित किया जा सकता है)।

    Public Function CellMark() 
    
        Dim currCell As Range 
        Set currCell = Range(Application.Caller.Address) 
    
        Dim myId As String 
        ' must be text; using .value will cause the formula to be called again 
        ' and create a circular reference 
        myId = currCell.Text 
    
        If (Trim(myId) = "" Or Trim(myId) = "0") Then 
         myId = "ID-" & Format(CStr(gNextUniqueId), "00000") 
         gNextUniqueId = gNextUniqueId + 1 
        End If 
    
        CellMark = myId 
    
    End Function 
    

    हालांकि यह काफी त्रुटिपूर्ण है। कॉपी या फिलबॉक्स का उपयोग करना, हालांकि, पिछले प्रतिलिपि मूल्य को बनाए रखेगा। केवल एक नया फॉर्मूला होने के लिए कोशिकाओं को स्पष्ट रूप से सेट करके यह काम करेगा। लेकिन यदि आप फिर से सेल में सूत्र में प्रवेश करते हैं (बस इसे क्लिक करें, ENTER दबाएं) एक नया मान गणना की जाती है - जो मानक सेल व्यवहार है।

    मुझे लगता है कि वर्कशीट_Change घटना जाने का तरीका है, जिसमें अधिक अक्षांश है। यहां एक साधारण उदाहरण है जो किसी भी सेल परिवर्तन की आईडी अपडेट करता है। यह आपके विशेष परिदृश्य के अनुरूप बनाया जा सकता है। इस कार्य को प्रत्येक वर्कशीट में जोड़ा जाना आवश्यक है जिस पर आईडी सेटिंग व्यवहार की आवश्यकता है।

    Private Sub Worksheet_Change(ByVal Target As Range) 
    
        Dim currCell As Range 
        Set currCell = Target.Cells(1, 1) 
    
        Dim currId As String 
        currId = currCell.ID 
    
        If Trim(currCell.ID) = "" Then 
         Target.Parent.Unprotect 
         currCell.ID = CStr(gNextUniqueId) 
         Target.Parent.Protect 
         gNextUniqueId = gNextUniqueId + 1 
        End If 
    
    End Sub 
    

    अंतिम नोट; सभी मामलों में, यदि आप वर्कशीट को फिर से खोलते हैं (कम से कम आपके उदाहरण में प्रस्तुत सीमित विवरण के तहत) तो आपका आईडी काउंटर रीसेट हो जाएगा।

    उम्मीद है कि इससे मदद मिलती है।

  • +2

    की प्रतिलिपि/पेस्ट सुविधाओं पर सिर के लिए धन्यवाद इस विस्तृत विश्लेषण के लिए बहुत धन्यवाद, लेकिन मुझे पता चला है कि अगर मैं "ड्राइंग ऑब्जेक्ट्स: = गलत" की रक्षा के साथ शीट की रक्षा करता हूं, तो यूडीएफ आईडी सेट कर सकता है। अजीब ... –

    +0

    डर्न, इसे खोजने पर अच्छी तरह से किया। क्या आप अब पूरी तरह से हल हो गए हैं या फिर भी समस्याएं खराब कर रहे हैं? –

    1

    समस्या एप्लिकेशन के साथ है। कॉलर।

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

    टिप्पणियां

    यह गुण कैसे विजुअल बेसिक, बुलाया गया था के रूप में निम्न तालिका में दिखाया गया है के बारे में जानकारी देता है।

    कोलर - वापसी मान

    • किसी एकल कक्ष में दर्ज किया गया एक कस्टम समारोह - एक रेंज उद्देश्य यह है कि सेल
    • कि कक्षों की किसी श्रेणी में एक सरणी सूत्र का हिस्सा है एक कस्टम समारोह को निर्दिष्ट - एक रेंज कोशिकाओं की है कि सीमा निर्दिष्ट आपत्ति
    • एक Auto_Open, Auto_Close, Auto_Activate, या Auto_Deactivate मैक्रो - चार्ट ऑब्जेक्ट पहचानकर्ता या सेल के नाम -
    • या तो OnDoubleClick या OnEntry संपत्ति द्वारा निर्धारित मैक्रो पाठ के रूप में दस्तावेज़ का नाम refere एनसी (यदि लागू हो) जिस पर मैक्रो
    • मैक्रो संवाद बॉक्स (टूल्स मेनू), या से ऊपर वर्णित कोई भी कॉलर नहीं है - #REF! त्रुटि मान

    चूंकि आप इसे उपयोगकर्ता परिभाषित फ़ंक्शन से कॉल कर रहे हैं, तो क्या हो रहा है एप्लिकेशन। कॉलर आपके रेंज वेरिएबल curCell में एक त्रुटि कोड की स्ट्रिंग लौट रहा है। यह एक त्रुटि उत्पन्न नहीं कर रहा है जो आपका त्रुटि हैंडलर उठाएगा। उसके बाद क्या होता है आप curCell का संदर्भ देते हैं, यह वास्तव में अब एक सीमा नहीं है। मेरी मशीन पर यह curCell = रेंज ("त्रुटि 2023") सेट करने की कोशिश करता है। जो कुछ भी ऑब्जेक्ट है, उसके पास अब एक आईडी विशेषता नहीं हो सकती है और जब आप इसे सेट करने का प्रयास करते हैं, तो यह आपको उस ऑब्जेक्ट त्रुटि को फेंक रहा है।

    यहाँ मैं क्या कोशिश करेगा है ...

    1. अपने त्रुटि हैंडलर निकालने का प्रयास करें और देखें कि क्या VBA रेंज (Application.Caller.Address) पर किसी भी अपवाद निकलती है। यह इसे ठीक नहीं करेगा, लेकिन यह आपको सही दिशा में इंगित कर सकता है।

    2. या तो तर्क या अनुप्रयोग के माध्यम से .ActiveCell या फिर आप इसे करना चाहते हैं, सीधे सेल का संदर्भ लें। उदाहरण के लिए रेंज ("ए 1") या सेल (1,1)। आवेदन। कॉलर। एड्रेस बस उपयोग करने के लिए एक अच्छा विकल्प प्रतीत नहीं होता है।

    3. विकल्प स्पष्ट का उपयोग करने का प्रयास करें। यह उस लाइन को बना सकता है जहां आपने curell को एक त्रुटि फेंक दिया है क्योंकि रेंज (एप्लिकेशन.केलर.एड्रेस) ऐसा लगता है कि यह एक रेंज बैक पास नहीं कर रहा है, जो curCell की डेटाटाइप है।

    संबंधित मुद्दे