2009-04-10 14 views
5

Ortam, Koleksiyon'a zorladığım üyelerin adsız, tanımlanamayan (kötü özetlemelerden kaçınmak için, lütfen çıldırmayın: üyeler aslında diğer Koleksiyon örnekleri). Hızlı arama yapabilmek için, her yeni üye için anlamlı bir karma ad yaratıyorum ve "en üstteki" Koleksiyonun Ekleme yönteminde Anahtar dizesi olarak sağlarım.Koleksiyon nesnesindeki bir öğenin anahtarını edinin

Birlikte Arama yapmak için bir anahtar varsa, herşey züppe ... Sorun toplamanın üyeleri yineleme ve Ekle (üretilen Hash sağlandı Anahtarı almak istiyorum, yani unfortunetely değil tersine çevirmek mümkün).

Eklenen alt koleksiyon örneğinin ilk üyesinin belirtilen karma değeri içeren bir dize olduğunu belirterek devam ediyorum ancak bu sorunu çözen herhangi biri varsa çok fazla yükümlülüğüm var.

+0

Bazı kod snippet'i yardımcı olabilir. – boj

cevap

6

Basit bir yaklaşım, bir Koleksiyon yerine Dictionary kullanmak olacaktır. Sözlük temel olarak anahtar, öğe çiftleri ve anahtarlarının bir dizi olarak geri çağrılmasını destekleyici bir dizidir. Sözlüğü kullanmak için Microsoft Scripting Runtime'a bir referans eklemeniz gerekecektir. Sözlüğü kullanmanın dezavantajı, koleksiyonla aynı şekilde sayılmamasıdır. Daha ayrıntılı bir çözüm, aşağıda özetlendiği gibi numaralandırılabilir bir sözlük oluşturmak için koleksiyonu ve sözlüğü sarmak olacaktır.

NB

NewEnum sınıf modülü ihraç ve takip eder ve daha sonra yeniden ithal olarak el ile düzenlenebilir zorundadır VBA düzgün çalışması için almak için.

Public Property Get NewEnum() As IUnknown 
Attribute NewEnum.VB_UserMemId = -4 
    Set NewEnum = someKeys.[_NewEnum] 
End Property 

örnek

Option Explicit 
Private someKeys As Dictionary 
Private someCols As Collection 
Public Function Add(o As Object, Key As String) As Object 
    someKeys.Add Key, o 
    someCols.Add o, Key 
End Function 
Public Property Get Count() As Long 
    Count = someCols.Count 
End Property 
Public Property Get Item(vKey As Variant) As Object 
    Set Item = someCols.Item(vKey) 
End Property 
Public Sub Remove(vKey As Variant) 
    someKeys.Remove vKey 
    someCols.Remove vKey 
End Sub 
Public Property Get NewEnum() As IUnknown 
    Set NewEnum = someCols.[_NewEnum] 
End Property 
Public Property Get Keys() As Variant 
    Keys = someKeys.Keys 
End Property 
Private Sub Class_Initialize() 
    Set someKeys = New Dictionary 
    Set someCols = New Collection 
End Sub 
+0

O tarar. But'lar vardır: i) Add metoduyla anahtar isteğe bağlı olamaz; ii) kaldırma yöntemi sırasında karşılık gelen anahtarı nasıl kaldırırsınız ?; iii) aC.Keys() için aptal-mümkün tavsiye: ii) someKeys.Remove (vKey) daha sonraya izin veren bazıKeys.Add (Anahtar, Anahtar); iii) Anahtarları (anIndex kadar uzun) Dize – jpinto3912

+0

olarak alın. iyi bir nokta. ii. Bunu hiç dikkate almadım ve önerileriniz önerilen iki alternatiften daha iyi, ama Key, Key beni rahatsız ediyor. Belki de sözlükler anahtarlar için daha iyi olurdu. iii. Geri dönen koleksiyonun varsayılan üyesi olacağından bu Yedekleme gereksiz olacaktır. – cmsjr

+0

Ayrıca, performans anlamında tarak, ya da anlamında tam değil? – cmsjr

2

Anahtarı ve toplama depolamak sen kendi koleksiyonu çağrısında da üye koleksiyonları sarabilirdiniz. Yinelemenin bir sonucu olarak, koleksiyona atmak ve elemanları için anahtarlarını sormak (yani, hash).

0

benim için çalıştı

Public Function NewEnum() As Collection 
     Set NewEnum = m_ObjectCollection 
End Function 

ile

Public Function NewEnum() As IUnknown 
     Set NewEnum = m_ObjectCollection.[_NewEnum] 
End Function 

yerine deneyin.