2017-09-24 3 views
1

Im Moment arbeite ich mit der Erstellung einer Benutzerform mit 40 Combobox alle die gleiche Liste haben. Mein Problem ist das Füllen all dieser Combobox macht die userform.show langsam. Die Liste, die in diesen Comboboxes gefüllt wird, ist eine sehr lange Liste (46542 Zeilen und Listenlänge kann variieren). Die Liste besteht aus 3 Spalten.Füllen Mehrere Comboboxen macht VBA-Benutzerform langsam

Ich habe herumalbern mit CONCATENATE die ganze Liste, aber das macht nicht viel von einer Änderung. Auch, weil ich den Wert haben muss, wenn er in der Combobox als CONCATENATE mit allen 3 Spalten in der Combobox etc. ausgewählt wird, wenn die Zeile Nr. 1 in der Combobox, anstatt nur Spalte 1 in das Textfeld von comboxbox zu schreiben, gibt es alle 3 Spalten zurück. Das bedeutet, dass ich tatsächlich 4 Spalten habe, wobei die erste CONCATENATE ist und im Dropdown-Menü versteckt ist.

Also meine Frage ist, gibt es eine Möglichkeit, den Prozess mehr Licht zu tun?

So, hier ist der Code:

Private Sub UserForm_Initialize() 
Set tsheet = ThisWorkbook.Sheets("Players") 
Dim v As Variant, i As Long 
v = tsheet.Range("A2:l" & Worksheets("Players").Cells(Rows.Count, 
1).End(xlUp).Row).Value 
With Me.ComboBox1 
.RowSource = "" 
.ColumnCount = 4 
.BoundColumn = 2 
.ColumnWidths = "1;50;50;50" 'Hide first column in dropdown 
For i = LBound(v) To UBound(v) 
.AddItem v(i, 1) & " " & v(i, 2) & " " & v(i, 3) 
.List(.ListCount - 1, 1) = v(i, 1) 
.List(.ListCount - 1, 2) = v(i, 2) 
.List(.ListCount - 1, 3) = v(i, 3) 
Next i 
End With 
With Me.ComboBox2 
.RowSource = "" 
.ColumnCount = 4 
.BoundColumn = 2 
.ColumnWidths = "1;50;50;50" 'Hide first column in dropdown 
For i = LBound(v) To UBound(v) 
.AddItem v(i, 1) & " " & v(i, 2) & " " & v(i, 3) 
.List(.ListCount - 1, 1) = v(i, 1) 
.List(.ListCount - 1, 2) = v(i, 2) 
.List(.ListCount - 1, 3) = v(i, 3) 
Next i 
End With 

Dieser Code geht weiter, bis es combox40 Hit

Mein alter Code wurde ziemlich schnell arbeiten, aber es hat nicht die Spalte, die verketteten wurde

ComboBox3.ColumnWidths = "50;50;50"   'COLUMN WITH OF LISTBOX 
ComboBox3.ColumnCount = 3             
'COLUMN NUMBER OF LISTBOX 
ComboBox3.List = tsheet.Range("A2:l" & 
Worksheets("Players").Cells(Rows.Count, 1).End(xlUp).Row).Value 
+0

Definieren Sie nicht 'tSheet' und verwenden Sie' 'Worksheets (" Player ")' in Ihrem Code .... verwenden Sie 'tsheet' – jsotola

+0

es besteht keine Notwendigkeit,' .RowSource' '.ColumnCount'' .BoundColumn' zu definieren '.ColumnWidths' Eigenschaften zur Laufzeit .... diese Werte werden mit der Arbeitsmappe gespeichert ....Legen Sie diese in einer separaten Unterroutine fest, die Sie nur einmal ausführen, und speichern Sie anschließend die Arbeitsmappe. wiederholen Sie die Unter wenn Sie Änderungen an diesen Werten – jsotola

Antwort

3

Statt

ComboBox3.List = tsheet.Range("A2:l" & 
Worksheets("Players").Cells(Rows.Count, 1).End(xlUp).Row).Value 

Verwendung so etwas wie diese (deklariert Arr als Variant): -

Arr = tsheet.Range("A2:l" & 
Worksheets("Players").Cells(Rows.Count, 1).End(xlUp).Row).Value 
' add your extra rows to the array here, followed by 
ComboBox3.List = Arr 

Statt dem gleichen Code 40-mal zu wiederholen, um eine Schleife erstellen.

For i = 1 to 40 
    Cbx = Me.Controls("ComboBox" & Cstr(i)) 
    ' then manipulate Cbx as you have done. 
Next I 

Schließlich, da Ihre 40 Comboboxen alle gleich sind, warum nicht nur mit 1 auskommen? Sie können es von Zeile zu Zeile verschieben, den Benutzer auswählen lassen und diese Auswahl in ein Textfeld übertragen, das an der Stelle des Cbx beim Beenden angezeigt wird. Wenn Sie erneut auf den Tbx klicken, wird er durch den Cbx ersetzt, so dass Sie wieder auf die Liste zugreifen können.

+0

Hallo variatus Dank für Ihre Eingabe machen wollen. wenn ich Sie recht, und ich bin nicht so sicher, dass :) verstehen, dann ist das nicht möglich, mit der bewegen, weil es keine Textbox gibt es nur die Drop-Down ist, und wenn ich sage, meine ich Textfeld das Textfeld der Combobox der Grund, warum ich haben 40 von ihnen ist, weil, wenn der Benutzer etwas in allen von ihnen auswählt und eine Speichertaste drückt, alle diese Textfelder der Kommbox zu einem Blatt übertragen werden. die Userform ist wie folgt aus: es ist ein startsheet für Golf alle Combobox mit allen Spielern eine Liste haben bedeutet, dass er Spieler dann wählen für jede Position 40 Cbx beginnt daher – Anker

+0

aber thx für den Code oben Ich werde sehen, ob ich bekommen kann, dass arbeite ich guten Sinn macht es sich die Zeit nehmen, wie die thx zu machen Kumpel zu helfen;) ich wirklich nicht sicher war, wie man diese Schleife für Combobox machen – Anker

+0

Wenn Sie eine Tbx und eine Cbx gleicher Größe haben genau in der gleichen Position der Einer oben ist alles, was der Benutzer sehen oder benutzen kann. Sie können eines der Steuerelemente für eine gute Maßnahme ausblenden oder weil das Cbx nicht wirklich benötigt wird, bis Sie es benötigen. Also, du hast 40 TBx. Wenn der Benutzer auf einen von ihnen klickt, erscheint der Cbx an seiner Stelle. Wenn er irgendwo sonst das Ergebnis der Cbx klickt unten an die Tbx übertragen wird und der CBX entweder verschwindet oder erscheint wieder an der Stelle des Tbx der Benutzer geklickt hat. – Variatus

1

verwenden, um die RowSource Eigenschaft der Combobox Steuer

Option Explicit 


Private Sub UserForm_Initialize() 

    Dim tsheet As Worksheet 
    Set tsheet = ThisWorkbook.Sheets("Players") 

    Dim rs As String 
    rs = "Players!a2:d" & tsheet.Cells(tsheet.Rows.Count, 1).End(xlUp).Row 

    Dim aaa As Control 
    For Each aaa In Me.Controls 
     If Left(aaa.Name, 8) = "ComboBox" Then 
      aaa.RowSource = rs    ' =mySheet!a2:d24 in properties 
      aaa.ControlSource = "Players!z1" ' put the chosen value into this cell (example) 
      aaa.ColumnCount = 4 
      aaa.BoundColumn = 2 
      aaa.ColumnWidths = "1;50;50;50" ' Hide first column in dropdown 
     End If 
    Next aaa 

End Sub 
1

Im Modul:

Dim ArrPlayers() as integer 

in der Userform Initialisierung:

'To Do: add code to populate listbox with players 
ReDim ArrPlayers (0 To 39) 

Auf dem listbox Änderungsereignis:

txtPosition.text = ArrPlayers(lstPlayers.ListIndex) 

Auf der Textbox Änderungsereignis:

ArrPlayers(lstPlayers.ListIndex) = cInt(txtPosition.text) 

Sie müssen dann die Werte speichern.