anoniem Geplaatst: 20 april 2005 Delen Geplaatst: 20 april 2005 Hallo, In een Excell VBA toepassing heb ik een probleem en weet niet onmiddellijk een oplossing ervoor. In een dubbele lus wordt een matrix aangemaakt om daarmee een listbox te vullen. Die matrix moet ik op voorhand dimensioneren bv op 1000 x 14 waarbij 14 een vaste waarde is en de 1000 variabel is aangezien ik nooit op voorhand weet hoeveel regels er in de listbox gaan terecht komen. Nu blijkt dat de schuifbalk van de listbox steeds de waarde 1000 aanneemt, ook komen er maar enkele regels in de listbox. Dus de vraag is hoe ik de matrix achteraf kan verkleinen tot het gewenste aantal. Redim lukt niet, daar kan ik enkel de laatste waarde in de matrix aanpassen. Iemand die mij een tip kan geven? Dirk Quote Link naar reactie
anoniem Geplaatst: 20 april 2005 Auteur Delen Geplaatst: 20 april 2005 Misschien door te controleren of de regel leeg is en dan vervolgens te verwijderen. [code:1:db170e1ad1] Dim i As Integer For i = List1.ListCount - 1 To 0 Step -1 If List1.Selected(i) = "" Then List1.RemoveItem i Next i [/code:1:db170e1ad1] (code niet getest) Quote Link naar reactie
anoniem Geplaatst: 21 april 2005 Auteur Delen Geplaatst: 21 april 2005 Iets dergelijks had ik ook al geprobeerd, maar dit haalde de snelheid een flink stuk omlaag. Ik moet me behelpen op een niet al te snelle PC (op het werk) en het moet nog werkbaar blijven. Dus zoals in het voorbeeld, indien er maar 5 regels aanwezig zijn, moet deze lus toch 995 keren worden doorlopen. Quote Link naar reactie
anoniem Geplaatst: 22 april 2005 Auteur Delen Geplaatst: 22 april 2005 [quote:518ace0140="CDirk"]Iemand die mij een tip kan geven? Dirk[/quote:518ace0140] Kun je niet door de array loopen, en dan alleen die items aan de listbox toevoegen die een waarde hebben? Quote Link naar reactie
anoniem Geplaatst: 22 april 2005 Auteur Delen Geplaatst: 22 april 2005 [quote:2422003740]Kun je niet door de array loopen, en dan alleen die items aan de listbox toevoegen die een waarde hebben? [/quote:2422003740] Kan ik pas volgende week uitproberen. Quote Link naar reactie
anoniem Geplaatst: 23 april 2005 Auteur Delen Geplaatst: 23 april 2005 Dirk, Je hebt nu een array van "aantal"*14, waarbij 14 vast en "aantal" nog te bepalen. Is het niet mogelijk om de array 14*"aantal" te maken? Zo kun je Redim wel toepassen. Je moet dan natuurlijk wel even je programma doorlopen om te zien waar de array wordt gebruikt. Succes, Maarten. Quote Link naar reactie
anoniem Geplaatst: 23 april 2005 Auteur Delen Geplaatst: 23 april 2005 Lijkt me ook een mogelijkheid, maar zo zal volgend voorbeeld niet meer mogelijk zijn [code:1:e52d08cd87] Dim Matrix(1000,14) ' for a=1 to 1000 ' code voor bepaling array next a ' zoeklijst.list = Matrix [/code:1:e52d08cd87] Quote Link naar reactie
anoniem Geplaatst: 25 april 2005 Auteur Delen Geplaatst: 25 april 2005 Met de tips die hierboven aangebracht werden, heb ik nog geen oplossing gevonden. Vandaag begon ik te denken om er eventueel een schijfbalk boven te plaatsen, en met deze schuifbalk de listbox te sturen. Maar bij mijn eerste poging ben ik er niet in geslaagd om de schuifbalk voor de listbox te brengen. Die blijft er maar achter staan. To front, to back, maakt allemaal geen verschil. Quote Link naar reactie
anoniem Geplaatst: 25 april 2005 Auteur Delen Geplaatst: 25 april 2005 Waar ik aan zat te denken is om een type aan te maken. Een beetje zoals het volgende voorbeeldje [code:1:0853c70066]Public Type MatrixVarsType ArrayVeertien(1 To 14) End Type Public MyMatrix() as MatrixVarsType Public Sub DoeWatMetMijnMatrix() Private Teller as Integer Teller = 1 Do While Teller < 1000 ReDim Preserve MyMatrix(1 To Teller) Doe wat code om te zien hoever we moeten gaan If Teller = NieuweEindWaarde Then Exit Do (of maak Teller gelijk aan 1000) End If Teller = Teller + 1 Loop End Sub[/code:1:0853c70066] Okee, tis wat rommelig, ik ben ziek en heb koppijn, maar het zou wel eens kunnen werken. Heb op dit moment geen VB om te testen, morgen weer. Quote Link naar reactie
anoniem Geplaatst: 25 april 2005 Auteur Delen Geplaatst: 25 april 2005 Heb hier thuis volgende gedaan als test. Bij deze code lukt het niet om de matrix toe te kennen aan de listbox [code:1:7858e07da9] Public Type Kollom kol(14) As String End Type Private Sub CommandButton1_Click() Dim matrix() As Kollom ' t = 0 For a = 1 To 1000 For b = 1 To 14 matrix(a).kol(b) = Str(t) t = t + 1 Next b If a = 5 Then Exit For 'om voorlopig maar 5 regels te vullen Next a ListBox1.ColumnCount = 14 ListBox1.List = matrix() End Sub [/code:1:7858e07da9] Quote Link naar reactie
anoniem Geplaatst: 26 april 2005 Auteur Delen Geplaatst: 26 april 2005 Het lijkt er inderdaad op dat dit niet gaat werken. Ook bij een 'gewone' array lukte het me niet zo 1-2-3. Wat wel werkt is bijvoorbeeld de volgende code: [code:1:d8e500ab67]Option Explicit Private Const AantalKolommen = 14 Private Type KolomType Cel(1 To AantalKolommen) As String End Type Private Kolom() As KolomType Private T As Integer Private A As Integer Private B As Integer Private Sub Form_Load() 'Zorg dat er precies 14 getallen onder elkaar kunnen komen 'bij mij is een getal ongeveer 200 twips hoog dus list1 wordt 2800 hoog List1.Height = 200 * AantalKolommen End Sub Private Sub Command1_Click() T = 1 B = 0 Do While T < 1000 ReDim Preserve Kolom(1 To T) For A = 1 To AantalKolommen B = B + 1 Kolom(T).Cel(A) = CStr(B) Next A If B >= (AantalKolommen * AantalKolommen) Then Exit Do End If T = T + 1 Loop List1.Columns = AantalKolommen For T = 1 To UBound(Kolom) For A = 1 To AantalKolommen List1.AddItem Kolom(T).Cel(A) Next A Next T End Sub [/code:1:d8e500ab67] Het zal wel niet de snelste methode zijn en ook niet de mooiste maar het werkt wel. Quote Link naar reactie
anoniem Geplaatst: 26 april 2005 Auteur Delen Geplaatst: 26 april 2005 [quote:2a86dfd458="DarkScribe"]Het lijkt er inderdaad op dat dit niet gaat werken. Ook bij een 'gewone' array lukte het me niet zo 1-2-3. Wat wel werkt is bijvoorbeeld de volgende code: [code:1:2a86dfd458]<knip> Private Sub Command1_Click() T = 1 B = 0 Do While T < 1000 ReDim Preserve Kolom(1 To T) For A = 1 To AantalKolommen B = B + 1 Kolom(T).Cel(A) = CStr(B) Next A If B >= (AantalKolommen * AantalKolommen) Then Exit Do End If T = T + 1 Loop List1.Columns = AantalKolommen For T = 1 To UBound(Kolom) For A = 1 To AantalKolommen List1.AddItem Kolom(T).Cel(A) Next A Next T End Sub [/code:1:2a86dfd458] Het zal wel niet de snelste methode zijn en ook niet de mooiste maar het werkt wel.[/quote:2a86dfd458] Het zal al iets sneller gaan als je niet steeds de Redim Preserve uitvoert. [code:1:2a86dfd458] Private Sub Command1_Click() T = 1 B = 0 ReDim Kolom(1 To 1000) Do While T < 1000 ' ReDim Preserve Kolom(1 To T) -> Dit dus niet doen! For A = 1 To AantalKolommen B = B + 1 Kolom(T).Cel(A) = CStr(B) Next A If B >= (AantalKolommen * AantalKolommen) Then Exit Do End If T = T + 1 Loop ReDim Preserve Kolom(1 To T) ' -> Hier pas opnieuw dimensioneren List1.Columns = AantalKolommen For T = 1 To UBound(Kolom) For A = 1 To AantalKolommen List1.AddItem Kolom(T).Cel(A) Next A Next T End Sub [/code:1:2a86dfd458] Bij een ReDim Preserve wordt eerst een array met de nieuwe dimensies in het geheugen gemaakt, waarna de waarden uit de oude array naar de de nieuwe worden gekopieerd. Daarna wordt de oude array verwijderd, en de nieuwe hernoemd. Het is dus efficienter om een array veel te ruim te definieren, om aan het einde van de rit de array naar de juiste proporties te "redimmen". Quote Link naar reactie
anoniem Geplaatst: 26 april 2005 Auteur Delen Geplaatst: 26 april 2005 Ik heb zopas de bovenstaande code eens uitgetest. De listbox stop inderdaad op de opgegeven waarde, maar alles word in 1 kolom geplaatst. Ik krijg 1 kolom met de getallen van 1 tot 196. Hoe moet je trouwens een listbox die uit kolommen bestaat vullen met additem? Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 @meneer_ed: Dat is inderdaad wel handig, had ik eigenlijk nooit aan gedacht. Dat scheelt een heel stuk tijd als je met echt grote matrices gaat werken. :wink: @CDirk: Je moet in designtime al aangeven dat je meerdere columns wilt, vul hier elke positieve waarde anders dan 0 in. Ikzelf heb hier een 1 gebruikt. Alleen dan kun je in runtime aangeven hoeveel columns je wilt hebben. De listbox wordt van boven naar beneden gevuld tot aan de onderkant en gaat dan pas verder met de tweede column. Daarom maakte ik mijn listbox.height een bepaalde waarde zodat hij tot en met 14 gaat en dan naar de volgende column gaat. De listbox maakt 14 columns aan en zet alle waarden precies in die 14 kolommen mits er genoeg waarden zijn om tot en met de 14e kolom te komen en er niet meer waarden zijn dan er in die 14 kolommen passen. Zijn er meer waarden dan komen er automatisch meerdere kolommen bij. Als je de invoer in de listbox van links naar rechts wilt zul je een beetje moeten goochelen met de invoer en de hoogte van de listbox. In plaats van dat je eerst de T gebruikt en daarin de A waarde steeds ophoogt kun je ook de A als eerste lus gebruiken en de waarden van T steeds ophogen in de binnenste lus. Je zult dan de listbox net zo hoog moeten maken als er waarden in T zitten. [code:1:5861caf3d4] List1.Columns = AantalKolommen List1.Height = UBound(Kolom) * 200 '<-200 is bij mij de teksthoogte For A = 1 To AantalKolommen For T = 1 To UBound(Kolom) List1.AddItem Kolom(T).Cel(A) Next T Next A [/code:1:5861caf3d4] Uiteraard moet de listbox ook breed genoeg zijn als je geen schuifbalk wilt zien, bij mij is hij 7000 breed. Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 [quote:ef250eb81e="DarkScribe"]@meneer_ed: Dat is inderdaad wel handig, had ik eigenlijk nooit aan gedacht. Dat scheelt een heel stuk tijd als je met echt grote matrices gaat werken. :wink: [/quote:ef250eb81e] Heb ik door schade en schande uitgevonden :o Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 Ben hier nog wat blijven testen. Zie nu dat de code zich anders gedraagd in VB dan VBA. De toepassing waar ik dat probleem voor heb word wel gemaakt in excell VBA. In hetgeen ik aan het maken ben is het niet altijd mogelijk om alles zichtbaar te plaatsen, de ene keer kunnen het 5 regels zijn, de andere keer kunnen er dat 100 of meer zijn. Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 Als je in Excel aan het programmeren bent, moet je dit eens proberen. Formulier met twee listboxen (ListBox1 en ListBox2). Voeg deze code toe, en kijk of je hier wat mee kunt: [code:1:1c6aab6019]Dim MyArray(6, 3) Private Sub UserForm_Initialize() Dim i As Single 'The 1st list box contains 3 data columns ListBox1.ColumnCount = 3 'The 2nd box contains 6 data columns ListBox2.ColumnCount = 6 'Load integer values into first column of MyArray For i = 0 To 5 MyArray(i, 0) = i Next i 'Load columns 2 and three of MyArray MyArray(0, 1) = "Zero" MyArray(1, 1) = "One" MyArray(2, 1) = "Two" MyArray(3, 1) = "Three" MyArray(4, 1) = "Four" MyArray(5, 1) = "Five" MyArray(0, 2) = "Zero" MyArray(1, 2) = "Un ou Une" MyArray(2, 2) = "Deux" MyArray(3, 2) = "Trois" MyArray(4, 2) = "Quatre" MyArray(5, 2) = "Cinq" 'Load data into ListBox1 and ListBox2 ListBox1.List() = MyArray ListBox2.Column() = MyArray End Sub[/code:1:1c6aab6019] Deze code heb ik trouwens uit de Excel (2000) VBA Help. Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 Ik vermoed dat de oplossing hierin aanwezig is. De regel "ListBox2.Column() = MyArray" vult de listbox omgekeerd. Dus daarmee zou ik de array kunnen omwisselen, dus van Matrix(1000,14) naar Matrix (14,1000) en met REdim kan ik dan de laatste dimensie aanpassen. Dus dat zou moeten kunnen, helaas momenteel thuis van het werk (ziek) en volgende week is er algemene vakantie en heb jammer genoeg de juiste code hier niet thuis. Alvast bedankt voor het aanbrengen van de tip. Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 Beterschap en prettige vakantie toegewenst Quote Link naar reactie
anoniem Geplaatst: 27 april 2005 Auteur Delen Geplaatst: 27 april 2005 Dank U. Had graag zo snel mogelijk geprobeerd of het ook daadwerkelijk werkt. Dit zal pas voor de 9de mei zijn. Quote Link naar reactie
Aanbevolen berichten
Om een reactie te plaatsen, moet je eerst inloggen