AW: VS Community ist kostenlos und...
02.05.2018 21:18:13
Peter(silie)
Hallo,
stimmt und stimmt nicht.
Durch das Interop Layer, welches C# braucht, ist es überall dann signifikant langsamer,
wo stinknormale simple operationen durchgeführt werden.
Beispiele unten.
Der VBA Code unten ist wesentlich schneller und er macht auch noch mehr!
Er holt, sortiert und fügt ein.
Der C# Code holt nur.
Differenz: 0,415 Sekunden
Der Mini-Test unten erfolgte nur mit 150 Tausend Daten.
Bei Interesse kann ich auch noch einen mit 1-10 Mio. Daten machen,
allerdings kann ich da bereits jetzt versichern, dass VBA der verlierer ist.
(Habe vor kurzem erst so einen Test gemacht)
Allgemein kann man sagen, je komplexer und größer die Aufgabe, desto schlechter ist VBA.
Dennoch, bei überschaubarer Datenmenge und simplen Operationen ist VBA dem neuen C# gnadenlos überlegen, solange die Operationen lediglich in Excel Dateien ausgeführt werden.
(bei Datenverbindungen o.ä. verliert VBA wieder)
VBA 150 Tausend Daten ohne Duplikate sortiert in Combobox listen:
(0.276 Sekunden)
PS: ist nicht der Vollständige VBA Code... da kommen noch 4 kleine Subs dazu,
mehr vom Code möchte ich aber nicht zeigen.
Public Sub GetData()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Auftragsbuch")
'Bericht-Nr. ComboBox
GetComboboxValues ws, frm_BoO.cb_DatensatzRef, DBxy.ReportNumber, True, True
'Auftragsart ComboBox
GetComboboxValues ws, frm_BoO.cb_Auftragsart, DBxy.TypeOfOrder, True
'Kunde ComboBox
GetComboboxValues ws, frm_BoO.cb_Kunde, DBxy.Client, True
'Probennummer ComboBox
GetComboboxValues ws, frm_BoO.cb_Probennummer, DBxy.ProbeNumber, True
'Referenzen ComboBox
GetComboboxValues ws, frm_BoO.cb_Ref1, DBxy.Reference1, True
GetComboboxValues ws, frm_BoO.cb_Ref2, DBxy.Reference2, True
'Werkstoff ComboBox
GetComboboxValues ws, frm_BoO.cb_Werkstoff, DBxy.Material, True
'Charge/ Schmelze...
GetComboboxValues ws, frm_BoO.cb_CSE, DBxy.BatchMeltProduct, True
'Abmessung ComboBox
GetComboboxValues ws, frm_BoO.cb_Abmessung, DBxy.Dimension, True
'Artikel ComboBox
GetComboboxValues ws, frm_BoO.cb_Artikel, DBxy.ArticleDescription, True
'Bemerkung ComboBox
GetComboboxValues ws, frm_BoO.cb_Bemerkung, DBxy.Comments, True
'WPS ComboBox
GetComboboxValues ws, frm_BoO.cb_WPS, DBxy.WeldingProcessSpecification, True
'Schweiß ComboBoxen
GetComboboxValues ws, frm_BoO.cb_Schweißverfahren, DBxy.WeldingTechnique, True
GetComboboxValues ws, frm_BoO.cb_Schweißposition, DBxy.WeldingPosition, True
GetComboboxValues ws, frm_BoO.cb_Schweißer, DBxy.Welder, True
End Sub
'intermediate step for getting the Combobox data
Public Sub GetComboboxValues(ByRef OfTable As Worksheet, _
ByRef Combo As MSForms.ComboBox, _
ByVal KeyCol As Long, _
Optional ByVal bSort As Boolean = False, _
Optional ByVal bDescending As Boolean = False)
Dim cData As Variant
'Put Column Data into Array
cData = GetColumn(OfTable, KeyCol)
'If the Array needs to be sorted
If bSort Then
SortValues cData, bDescending: End If
'Pass Array to Combobox
Combo.list = cData
End Sub
'Returns the values of a Column
'Returns them with no Duplicates
Private Function GetColumn(ByRef ShData As Worksheet, _
ByVal KeyCol As Long) As Variant
Dim dict As Object 'Latebind Dictionary
Dim lRow As Long 'Last Row of Column xy
Dim vKey As Variant 'Dictionary Key Variable for Loop
Dim vItem As Variant 'Dictionary Item Variable for Loop
Dim tmp As Variant 'temporary Array holding the Column Data
'Create a new Dictionary Object
Set dict = CreateObject("Scripting.Dictionary")
With ShData
'Get Last Row
lRow = .Cells(.Rows.Count, KeyCol).End(xlUp).Row
'Get Column Values
tmp = .Range(.Cells(2, KeyCol), .Cells(lRow, KeyCol)).value2
'Loop through the Items in tmp
For Each vKey In tmp
'remove empty spaces
vItem = LTrim(RTrim(vKey))
'Check if this Value is Valid
If vItem vbNullString Then
dict(vItem) = vbNull: End If
Next vKey
End With
'Pass the Keys
GetColumn = dict.Keys
End Function
'Decides which Quicksort should be used
Private Sub SortValues(ByRef src As Variant, ByVal SortOrderDescending As Boolean)
'If the Values need to be in Descending Order
If SortOrderDescending Then
Quicksort_Descending src, LBound(src), UBound(src)
Else
Quicksort_Ascending src, LBound(src), UBound(src): End If
End Sub
'Quicksort for Ascending Order
'I wont explain this Code
Private Sub Quicksort_Ascending(ByRef src As Variant, _
ByVal low As Variant, _
ByVal high As Variant)
Dim i As Long: i = low
Dim j As Long: j = high
Dim tmp As String
Dim ref As String: ref = src((low + high) / 2)
Do
While (src(i) ref): j = j - 1: Wend
If (i j)
If (low ref): i = i + 1: Wend
While (src(j) j)
If (low
C# 150 Tausend Daten unsortiert (gleiche Daten wie bei VBA!):
(0,691 Sekunden)
for (int i=1; i().ToList().ConvertAll(x => Convert.ToString(x)).ToArray();
}