Ga naar inhoud

VBA, instellen matrix


Aanbevolen berichten

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
Link naar reactie
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.
Link naar reactie
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.
Link naar reactie
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]
Link naar reactie
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.
Link naar reactie
[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".
Link naar reactie
@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.
Link naar reactie
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.
Link naar reactie
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.
Link naar reactie
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.
Link naar reactie

Om een reactie te plaatsen, moet je eerst inloggen

Gast
Reageer op dit topic

×   Geplakt als verrijkte tekst.   Herstel opmaak

  Er zijn maximaal 75 emoji toegestaan.

×   Je link werd automatisch ingevoegd.   Tonen als normale link

×   Je vorige inhoud werd hersteld.   Leeg de tekstverwerker

×   Je kunt afbeeldingen niet direct plakken. Upload of voeg afbeeldingen vanaf een URL in

×
×
  • Nieuwe aanmaken...