• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

item in een collection wijzigen? kan dat ?

Status
Niet open voor verdere reacties.

sylvester-ponte

Verenigingslid
Lid geworden
19 apr 2007
Berichten
6.620
hallo

ik wil een item in een collection wijzigen
Code:
Sub testCollection()
    Dim Col As New Collection
    Col.Add Item:=3, Key:="twee"
    c = Col("twee")
    Col("twee") = 2 'dit gaat fout (melding object vereist)
End Sub
wat doe ik fout?
groet sylvester
 
The Dictionary's Item property is read/write, and thus it allows you to change the item associated with a particular key. A Collection's Item property is read-only, and so you cannot reassign the item associated with a specified key: you must instead remove that item from the Collection, and then add in the new item.
Het lijkt mij dat je iets probeert wat niet kan/toegelaten is.
 
Code:
Sub testCollection()
    Set Rng = Range("A1:A2")
    
    With New Collection
        .Add Rng, "twee"
       .Item("twee").Cells(1) = "PPP"
       x4 = .Item("twee").Cells(1)
        
       .Item(.Count).Cells(1) = "QQQ"
       x4 = .Item(.Count).Cells(1)
    End With
End Sub

Wat jij wilde is de index van het item wijzigen, dat kan niet.
 
Laatst bewerkt:
Wat jij wilde is de index van het item wijzigen, dat kan niet.
@snb: klopt dit wel? Daarmee lijk je te suggereren dat index de default eigenschap van het item is. Ofwel:
Col("twee") = 2
is gelijkwaardig aan
Col("twee").index = 2
De Collection kent echter geen eigenschap Index.

@Sylvester: wat je wilt bereiken lukt wel zo:
Col.Add Item:=3, Key:="twee"
Col.Remove "twee"
Col.Add Item:=2, Key:="twee"
Lekker handig.
Merk op dat snb in zijn voorbeeld het item zelf (= de pointer naar de range) ook niet wijzigt maar de celinhoud.

EDIT: oeps, ik zie nu pas dat Wher het antwoord al had gegeven... :o
 
Laatst bewerkt:
Merk op dat snb in zijn voorbeeld het item zelf (= de pointer naar de range) ook niet wijzigt maar de celinhoud
het leek mij ook dat snb op een creatieve manier rond het probleem slalomde, het Item is en blijft "rng"?
 
Taal, taal, taal.
Het is maar hoe je de vraag leest.
Als we zeggen 'ik wil een worksheet wijzigen' bedoelen we daarmee meestal 'ik wil iets in een worksheet wijzigen'.
Zo heb ik de vraag begrepen: als je iets in een collection zet, kun je dan in wat je in die collection hebt gezet nog wijzigen.

In het andere geval zou ik spreken van: 'kun je de collection wijzigen, nadat je er zaken in hebt gezet' ?
Het wijzigen van de collection vind ik niet zo'n interessant geval. (add & remove)

Code:
Sub tst0()
    With New Collection
      .Add Sheet1.UsedRange.Value, "001"
      c04 = .Item("001")(3, 3)
      c05 = .Item(1)(4, 4)
      c06 = .Item(.Count)(2, 1)
    End With
End Sub
 
Laatst bewerkt:
bedankt allemaal,

ik begrijp dat bij een collectie de pointer naar een object niet meer naar een ander object gezet kan worden.
en verder kan het object zelf wel wel aangepast worden (via een ingestelde pointer)

bestaat er misschien een string object of een double object?
dan is het misschien mogelijk om via de pointer teksten of getallen toe te voegen of op te tellen bij het object (via de pointer in de collection)

groet sylvester
 
Laatst bewerkt:
Waar ben je naar op zoek, waarvoor ?
Code:
Sub snb()
    With New Collection
        .Add 2
        .Add 34
        MsgBox .Item(1) + .Item(2)
        .Add Array(2, 4, 8)
        .Add Array(3, 5, 7)
        MsgBox Application.SumProduct(.Item(3), .Item(4))
    End With
End Sub
 
Laatst bewerkt:
snb,
ik ben aan het onderzoeken wanneer ik dictionary's en wanneer collections kan / moet gebruiken.
in het volgende voorbeeld kan ik als er geen ordening nodig is eenvoudiger een dictionary gebruiken.
maar deze laat geen ordening toe.
in een collection kan dat wel maar dan zit je weer met het het wijzigen van de teksten waar de pointers naar wijzen.
Code:
'om dit te laten werken is een stringObj klas aangemaakt

Sub test()
    Dim Col As New Collection
    Col.Add New stringObj, "Namen1"
    Col("Namen1").Tekst = "piet"
    Col("Namen1").Tekst = Col("Namen1").Tekst & "|jan"
    c1 = Col("Namen1").Tekst
    Col.Add New stringObj, "Namen2"
    Col("Namen2").Tekst = "pietje"
    Col("Namen2").Tekst = Col("Namen2").Tekst & "|jantje"
    c2 = Col("Namen2").Tekst
    'en dan ook nog gesorteerd op sleutel (dat moet gelijk met de add acie gebeuren met before of after)
    'om het eenvoudig te houden heb ik de binaire sorteer actie weg gelaten
End Sub
ik hoopte dat dit soort acties eenvoudiger kan zonder klassen ed

om de een of andere rede kan ik even geen voorbeeld bestand bijvoegen (selecteer bestanden reageert niet)
 
ik begrijp dat bij een collectie de pointer naar een object niet meer naar een ander object gezet kan worden.
Het item is read only (zie reactie Wher) ongeacht of het nu een reference type (=pointer) of value type is.

bestaat er misschien een string object of een double object?
dan is het misschien mogelijk om via de pointer teksten of getallen toe te voegen of op te tellen bij het object (via de pointer in de collection)
Goed gedacht. In vba kan dat met een class (in vb kan het ook met de CObj functie).
 
het is nu iets eenvoudiger geworden door Value als default operator in te stellen in mijn stringObj class

daar door hoef ik niet steeds .tekst achter een object te zetten maar gewoon niets.
ik heb in de stringObj class wel de properties get en let van Value aan gemaakt en
Attribute Value.VB_UserMemId = 0 toegevoegd volgens deze beschrijving:

http://bytes.com/topic/access/answers/694741-how-declare-default-method-property-class-module
dit is er van mijn test bestandje overgebleven.
Code:
Sub test()
    Dim Col As New Collection
    Col.Add New stringObj, "Namen1"
    Col("Namen1") = "piet"
    Col("Namen1") = Col("Namen1") & "|jan"
    c1 = Col("Namen1")
    Col.Add New stringObj, "Namen2"
    Col("Namen2") = "pietje"
    Col("Namen2") = Col("Namen2") & "|jantje"
    c2 = Col("Namen2").Tekst
End Sub

groet sylveseter
 

Bijlagen

Waarom sorteer je niet gewoon in een werkblad ?
 
snb voor een keertje sorteren is dat een perfecte optie ( in een werkblad sorteren )
maar als je iedere keer als er een punt wordt toegevoegd en je bv steedst de laagste 20 van de duizenden punten wil hebben dan moet je steeds opnieuw sorteren.
dan is het sneller om steeds het nieuwe punt op de juiste plaats in de collection te zetten ( dat kan binair omdat de collectie gesorteerd blijft)

groet sylvester
 
maar als je iedere keer als er een punt wordt toegevoegd en je bv steeds de laagste 20 van de duizenden punten wil hebben dan moet je steeds opnieuw sorteren.

Dat lijkt me niet: 1 keer sorteren; de laagste 30 punten in een array zettten.
Iedere keer als er een punt bijkomt vergelijken met de hoogste in de array: als niet lager dan het hoogste element in de array: niets doen; als kleiner dan het hoogste punt dan samen met de array sorteren.
De array vervangen door de laagste 30 uit deze nieuwe array van 31.
Dat gaat waarschijnlijk veel sneller dan enige andere methode, omdat ook een arraylist, sortedlist of collection alle items moet sorteren.
 
snb, als in een gesorteerde collection een nieuwe waarde toegevoegd wordt kan dat precies op de juiste plek dan hoef je niet te sorteren.
 
Goed bedacht. Alleen als je zo tienduizenden items moet toevoegen aan een collectie van enkele tienduizenden krijg je misschien een probleem.

Mss ten overvloede: met een collectie alloceer je dynamische geheugenruimte die excel niet direct uit zichzelf opruimt, dat is jouw verantwoordelijkheid. In het voorbeeld:
Col.Remove 1
Col.Remove 1
Set Col = Nothing

Waarom is property get/let een variant en geen string? Scheelt geheugen en tijd.
 
snb, als in een gesorteerde collection een nieuwe waarde toegevoegd wordt kan dat precies op de juiste plek

Hoe bepaal je dan die 'juiste' plek ?
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan