Treeview de hata mesajı

Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003

Forumda treeview örneklerini inceleyerek aşağıdaki örneği uyguladım. Ve güzel çalıştı :)


Private Sub UserForm_Activate()

With TreeView1.Nodes
'Hiyerarşiktir...
'İçerik 1
.Add , , "ana", "Görevler"

.Add "ana", tvwChild, "İdari", "İdari Görevler"

.Add "ana", tvwChild, "Teknik", "Teknik Görevler"
.Add "Teknik", tvwChild, "ana_alt_alt2", "Sertlik Deneyi"
.Add "Teknik", tvwChild, "ana_alt_alt3", "çekme Deneyi"

.Add "ana", tvwChild, "Harici", "Harici Görevler"
.Add "ana", tvwChild, "Diğer", "Diğer Görevler"

End With

End Sub

Buraya kadar sorun yok. Ancak aşağıdaki bölümü ekliyorum. Mesela ağaçtaki "sertlik deneyi" node unun seçiyor. Ve ona ait sertlik formunu açıyor. Buraya kadar da herşey tamam güzel çalışıyor. FAkat formu kapatınca
" Run-time error 35602 Key is not unique in collection" hatası veriyor. internette malum hata mesajını aradım ancak genelde treeview örnekleri hep access de ve hiçbirisininkini anlamadım. Bu tür bir hata neden çıkar. Yardımcı olabilir misiniz?
Kusura bakmayın ama dosya gönderemem..

Private Sub TreeView1_NodeClick(ByVal Node As Node)
If Node.Text = "Teknik Görevler" Then

Teknikform.Show
End If

If Node.Text = "Sertlik Deneyi" Then

Sertlikform.Show
End If

end sub
 
Katılım
15 Haziran 2006
Mesajlar
3,704
Excel Vers. ve Dili
Excel 2003, 2007, 2010 (TR)
Treeview yapılandırma kodlarını, Activate olayına değil, Initialize olayına yazıp deneyin.

Eğer formları kapatma (bellekten silme) yerine Hide (gizleme) yapıyorsanız, Treeview'de item'ler yüklü iken tekrar aynı item'leri yüklemeye kalkıyordur.

Treeview'de gördüğünüz her dalın bir KEY'i vardır. (Sizin örneğinizdeki "Teknik", "İdari","ana_alt_alt2" vs. gibi ..) ve bu KEY'lerin tek(benzersiz) olması gerekir. Eğer, Userform bellekte iken, aynı prosedürü iki kere çalıştırırısanız, bu hata mesajını alırsınız.
 
Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003
Ferhat hocam,
Çok teşekkür ederim. Önemli bir müşkülümü çözdünüz.
Dediğiniz gibi activate yerine initialize yapınca halloldu.
Son 4-5 soruma cevap bulamamıştım forumda. herhalde bu da öyle olur derken çok hızlı ve tam isabet bir çözüm buldum.
Çok sağolun
 
Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003
Ferhat hocam bu konuda bir şey daha takıldı aklıma onu da sormak isterim müsade edersen.
Private Sub TreeView1_NodeClick(ByVal Node As Node)
If Node.Text = "Teknik Görevler" Then

Teknikform.Show
End If

If Node.Text = "Sertlik Deneyi" Then

Sertlikform.Show
End If

end sub
Benim asıl programımda çok daha fazla userform bulunmakta. bu şekilde
If Node.Text = "Sertlik Deneyi" Then Sertlikform.Show

yapmaktansa bunu dizi ile nasıl yaparız. Yani onlarca form olduğunu düşünelim. Hepsi için ayrı ayrı if then else döngüsü mü kurmalıyım. Daha kolayı yok mu?
 
Katılım
15 Haziran 2006
Mesajlar
3,704
Excel Vers. ve Dili
Excel 2003, 2007, 2010 (TR)
Bu durumda yapmanı gereken, Treeview'in KEY'lerine, projenizde tüm UserForm isimlerini atamaktır.

Örneğin, Inıtialize kodları şu şekilde olabilir. (Ben, Userform isimlerini kodlarda kırmızı ile gösterdim. Siz kendinize göre düzenleyiniz)

Kod:
Private Sub UserForm_Initialize()
    With TreeView1.Nodes
        .Add , , "ana", "Görevler"
        .Add "ana", tvwChild, "İdari", "İdari Görevler"
        .Add "ana", tvwChild, "[COLOR=red]frmTeknikForm[/COLOR]", "Teknik Görevler"
        .Add "frmTeknikForm", tvwChild, "[COLOR=red]frmSertlikDeneyi[/COLOR]", "Sertlik Deneyi"
        .Add "frmTeknikForm", tvwChild, "[COLOR=red]frmCekmeDeneyi[/COLOR]", "çekme Deneyi"
        .Add "ana", tvwChild, "[COLOR=red]frmHarici[/COLOR]", "Harici Görevler"
        .Add "ana", tvwChild, "[COLOR=red]frmDiger[/COLOR]", "Diğer Görevler"
    End With
    TreeView1.Nodes(1).Expanded = True
End Sub
Şimdi de projenize bir referans eklemelisiniz. Referans şu : Microsoft Visual Basic For Applications Extensibility X.XX

Daha sonra'da Treeview'in ItemClick olayını aşağıdaki gibi kodlayabiliriz.

Kod:
Private Sub TreeView1_NodeClick(ByVal Node As Node)
    Dim cmp As VBIDE.VBComponent
    For Each cmp In ThisWorkbook.VBProject.VBComponents
        If cmp.Type = 3 Then
            If cmp.Name = TreeView1.SelectedItem.Key Then
                VBA.UserForms.Add(cmp.Name).Show
                Exit For
            End If
        End If
    Next
End Sub
Örnek dosyayı incelerseniz daha iyi anlayacağınızı tahmin ediyorum.

---- Düzeltme : Örnek dosya yeniden eklenmiştir / fpc-07.11.08 ---
 

Ekli dosyalar

Son düzenleme:
Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003
Tekrar merhaba Ferhat hocam.
Bahsettiğiniz referans(mic. vba extensibility 5.3) zaten default olarak yüklü excel 2003 ümde.
Yüklediğiniz dosyayı indirdim. Fakat tıklayınca herhangi node a
run time error 1004 ( method of VBProject of object '_workbook failed)
hatası veriyor.
Bir şey daha soracağım. Şimdi diyelim ki bu referans bu dosyayı kuracağm bir başka bilgisayarda yüklü değilse hepsine teker teker eklemeli miyim?
Eğer öyleyse bu çok zor olur galiba. Başka yolu olmaz mı acaba?

Ne bileyim mesela select case veya dizi ile falan. Hani bi onları biliyorum ya herşey onlarla yapılır diye geçiyor insanın aklından :) Kesin yapılmama sebebi vardır ama işte..
 
Katılım
15 Haziran 2006
Mesajlar
3,704
Excel Vers. ve Dili
Excel 2003, 2007, 2010 (TR)
Bu hatanın nedenini anlayamadım. Ama şunu yapınız.

Menüden, Araçlar->Seçenekler'e tıklayınız. "Güvenlik" sekmesinde, "Makro Güvenliği" butonunu tıklayınız. "Güvenilen Yayımcılar" sekmesinde, "Visual Basic Project erişimine güven" i işaretleyiniz.

Şimdi tekrar çalıştırmayı deneyiniz.

Bu referans'ın Office yüklü olan bir makinada, olmama ihtimali yok diye biliyorum. Onun için telaş etmenize gerek yok.

İstediğiniz işlemi programatik olarak yapmak için, VB Projesine erişim gerekli ... Bellekte yüklü olmayan (Load edilmemiş) tü Userformlar taranacak ve içlerinden Treeview'de seçilen ne ise o görüntülenecek.. (veya en azından ben böyle düşünüyorum) ... Onun için, VB'nin standart dil yapısı haricinde de bazı komutları kullanmak gerekiyor. Yani, "Select Case" veya dizi ile yapılacak bir iş değil ...
 
Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003
Ferhat hocam bravo.
Dediğiniz gibi ...erişime güven i işaretleyince çalıştı .

Ya şimdi insan bilmediği şeyden korkar.
Benim gibi bu konuda fazla bilgisi olmayan insan, asıl çalışması da bu olmayınca bildikleriyle yetinerek birşeyler yapmak istiyor :)

Private Sub TreeView1_NodeClick(ByVal Node As Node)
Dim cmp As VBIDE.VBComponent
For Each cmp In ThisWorkbook.VBProject.VBComponents
If cmp.Type = 3 Then
If cmp.Name = TreeView1.SelectedItem.Key Then
VBA.UserForms.Add(cmp.Name).Show
Exit For
End If
End If
Next
End Sub
kısmını çok anladığımı söyleyemeyeceğim. Bütün konuyu anlatmanızı beklemiyorum da; en azından bu kodları anlayabileceğim konunun ne olduğunu söyleseniz ben de araştırsam öğrensem onu..
 
Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003
Ferhat hocam ben birşey buldum. Sitede bir arkadaş yapmış Select case ile. Ben de uyguladım güzel çalıştı.

Yararı olur diye eklemek istiyorum.


Private Sub TreeView1_NodeClick(ByVal Node As MSComctlLib.Node)
With Node
If .Children = False Then
Select Case Node.Index
Case 2: UserForm2.Show
Case 3: UserForm3.Show
Case 4: UserForm4.Show
End Select
End If
End With
End Sub
Burda şuna dikkat etmek gerekli. Case deki numaralar ilk baştaki ana düğümden sırasıyla en aşağısına kadar 1 den başlayarak devam ediyor. Yani + ile başlayan düğümlerde(açılır düğümlerde) userform açılmayacağına göre userform açılacak rakamları iyi belirlemek lazım. Tek kötü tarafı bu . ama if then else döngüsünü tekrar tekrar kurmaktansa bu daha iyi . herhalde bellekte de daha az yer kaplıyordur.
Sizinki daha da iyi ama ben tam anlamadığım için . 3-4 satırda halletmişsiniz meseleyi. Hangi konuya bakacağımı da bilemiyorum ki bakayım.
 
Katılım
15 Haziran 2006
Mesajlar
3,704
Excel Vers. ve Dili
Excel 2003, 2007, 2010 (TR)
Kod:
Private Sub TreeView1_NodeClick(ByVal Node As Node)
    Dim cmp As VBIDE.VBComponent
    For Each cmp In ThisWorkbook.VBProject.VBComponents
        If cmp.Type = 3 Then
            If cmp.Name = TreeView1.SelectedItem.Key Then
                VBA.UserForms.Add(cmp.Name).Show
                Exit For
            End If
        End If
    Next
End Sub

Bu kodun yaptığı işlem kısaca şudur...

Rivayet o ki; siz, Amerika'daki Emmioğlu Mustafa’nın yanına dil eğitimi almaya giden bir gençsiniz

Excel'in kendisini Türkiye, kodları gördüğünüz Visual Basic For Application Editörünü de ABD olarak kafanızda canlandırın. Öncelikle, eğer ABD topraklarına ayak basacaksanız, izin almak zorundasınız. Bunu da Pasaport ve Vize işlemleri olarak algılayın.

Projemize eklediğimiz VBA Extensibility referansı ile, Pasaport işlemlerini hallediyoruz.

Kodları ilk çalıştırdığınızda bir hata mesajı ile karşılaşmıştınız. Bu hata mesajı aslında pasaportunuz olduğu halde, Amerika'nın size giriş izni vermediğini gösteriyordu. "Visual Basic Project erişimine güven" diyerek, bir sonraki adımda vize işlemlerini de halletmiş oldunuz.

Pasaportumuzu ve Vizemizi alarak, Visual Basic For Application Editörüne girme hakkını elde ettiğimize göre, havaalanından hemşehrilerimizin yanına doğru hoplaya zıplaya sevinçle gittiğinizi farzedin.

Ama Newyork size yabancı bir şehir ve gideceğiniz adresi bilmiyorsunuz .(Tıpkı hangi Userformu seçeceğinizi önceden bilmediğiniz gibi ...)

Bu durumda mantıken napmanız gerekir?

Önünüze çıkan her insana adresi sormalısınız. (ABD'ye yeni gelen biri olarak, hiç dil bilmediğinizi de hesaba katın. Türkçe bilen birini bulmak için dua ediyorsunuz)

Önünüze çıkan her kişiye aşağıdaki kodla ulaşabilirsiniz.

Kod:
For Each cmp In ThisWorkbook.VBProject.VBComponents

Anlamı şudur : Bu kitabın içerisindeki Visual Basic Projesinin herbir komponenti (parçası) için .... (Yani önünüze çıkan herbir kişi için gibi )

Eğer, karşınıza Türkçe bilen biri (veya bir Türk Vatandaşı) çıkmışsa; bunu kodlardaki karşılığı

Kod:
If cmp.Type = 3 Then

Anlamı şudur : Visual Basic Projesi, birçok parçadan oluşur. Örneğin, ThisWorkbook, Sheet, Module, Class, Reference ve Userform gibi ... Bunların da hepsinin bir Tip Id değeri vardır. Biz Projedeki Userformlar'la uğraştığımıza göre, Userform'un Tip ID'sini bilmemiz gerekir. Userform'un Tip ID'si 3'tür ... (Diğerleri içinde Microsoft'un sitesinde arama yaparsanız Tİp ID'lerine ulaşabilrisiniz) Böylelikle karşımıza çıkan herkesi, elimizdeki adres kağıdını göstermeden önce Türkçe biliyor mu diye test etmiş oluyorsunuz.

Eğer, karşımıza çıkan kişi Türkçe biliyorsa; emmioğlu Mustafa’ı tanıyıp tanımadığını sorarsınız heyecanla ("Hani dönercilik yapıyormuş köşe başında diye") …

Emmioğlu Mustafa, VB projemiz için ItemClick olayıyla, Treeview’de seçilen elemandır.

Eğer, yaban eldeki karşınıza Hızır gibi çıkan bu kardeş, sizin emmioğlu Mustafa’yı tanıyorsa, bunun kodlardaki karşılığı :

Kod:
[COLOR=black][FONT=Verdana]If cmp.Name = TreeView1.SelectedItem.Key Then[/FONT][/COLOR]

Anlamı şudur : Eğer, VBA projemdeki komponentin adı, Treeview’de seçtiğim elemanın key’ine eşitse (Hatırlayınız, Treeview’in Key’lerine Userform isimlerini atamıştık) ….

O zaman, “Allah rızası için, bana emmioğlunun yerine göster kardeş” diyorsunuz.

Bunun projemizdeki karşılığı da;

Kod:
[COLOR=black][FONT=Verdana]VBA.UserForms.Add(cmp.Name).Show[/FONT][/COLOR]

Kodların geri kalan kısmı ise, anlatmaya değmez. If’ler kapanıyor, For döngüsü kapanıyor falan filan işte …

Biraz, Şaban filmlerine benzedi ama senaryo bu şekilde gelişti. Kusura bakmayın artık …
 
Katılım
2 Ekim 2007
Mesajlar
124
Excel Vers. ve Dili
office 2003
Ferhat hocam.
Gerçekten teşekkür ederim. Bu kadar vakit ayırıp anlatmanız büyük incelik. Tamamen anladım. Zaten bu kadar anlatıldıktan sonra anlamasam kendimi kötü hissederdim :)
Özellikle o 3 ü çok merak ediyordum. Aynı Face Id gibi Tip Id lerde de numara olduğunu anlamış bulunuyorum. Hemen uyguluyorum kendi programıma..

Son bir şey daha soracağım. Cevaplamak zorunda değilsiniz. Zaten arayacağım birazdan bu konuyu ama vaktiniz varsa cevaplarsanız da sevinirim. Treeviewde ki node lara tıklayarak bir sürü userform açıyoruz malum. en son açılan form aktif oluyor. Ana form ise pasif. Şimdi ben istiyorum ki treeview bulunan bir form a tıklanınca o form açılsın fakat anaform a da tıklayabilelim. Mesela userform1 açık iken o formu kapatmadan anaformda diyelim ki userform2 ye tıklayayım. userform1 otomatik kapansın, userform2 açılsın. Bunu nasıl sağlarız acaba?
Bugün fazlasıyla meşgul ettim sizi ama bu son soru idi :)
Dediğim gibi meşgul iseniz cevaplamanıza gerek yok..
 
Katılım
15 Haziran 2006
Mesajlar
3,704
Excel Vers. ve Dili
Excel 2003, 2007, 2010 (TR)
Daha önce size örnek olarak gönderdiğim dosyada Treeview1'in ItemClik olayında; bir alt prosedür çağırıp, frmANA harici tüm UF'leri kapattıktan sonra, yeni bir form açılmasını sağlayabiliriz.

NOT : Kod'a yapılan eklemeler kırmızı ile gösterilmiştir.

Şöyle ki ;

(1) Sheet1'deki kodu aşağıdaki gibi değiştirin.

Kod:
Private Sub CommandButton1_Click()
frmANA.Show [COLOR=red]0[/COLOR]
End Sub
(2) frmAna adlı Userforma yazdığımız kodları da aşağıdaki gibi değiştirin.

Kod:
Private Sub TreeView1_NodeClick(ByVal Node As Node)
    Dim cmp As VBIDE.VBComponent
    Dim frm As UserForm
    For Each cmp In ThisWorkbook.VBProject.VBComponents
        If cmp.Type = 3 Then
            If cmp.Name = TreeView1.SelectedItem.Key Then
[COLOR=red]             Call Formlari_Kapat[/COLOR]
                VBA.UserForms.Add(cmp.Name).Show 0
                Exit For
            End If
        End If
    Next
End Sub
 
[COLOR=red]Private Sub Formlari_Kapat()[/COLOR]
[COLOR=red] Dim i As Long[/COLOR]
[COLOR=red] For i = VBA.UserForms.Count - 1 To 0 Step -1[/COLOR]
[COLOR=red]     If VBA.UserForms(i).Name <> "frmANA" Then[/COLOR]
[COLOR=red]         Unload VBA.UserForms(i)[/COLOR]
[COLOR=red]     End If[/COLOR]
[COLOR=red] Next i[/COLOR]
[COLOR=red]End Sub[/COLOR]
 
Son düzenleme:
Üst