Registriert seit: 27.12.2018
Version(en): 2003,2010
Hallo allerseits, gegeben ist eine Zeichenfolge mit Semikolon-separierten Werten, die auf verschiedene Spalten einer Zeile verteilt werden sollen. Im Beispiel sind's nur 5 Werte und eine Zeile, in der Praxis bis zu 20 Millionen Zeilen und 100 Spalten, von denen etwa 20.000 schließlich in der Exceltabelle landen. Daher muss die Performance optimiert werden. Ich schreibe die Datenfelder erstmal in ein Array und gebe dieses dann in die Exceltabelle aus. Dafür gibt es 2 Varianten. Variante 2 macht alles richtig. Bei der viel schnelleren Variante 1 existiert das Problem, das die Spalten 2 und 4 als Zeichenfolge in der Zelle landen, nicht als Zahl. Frage: Wie kann dieses Problem vermieden werden? Achja: ".TextToColumns" ist mir auch bekannt, das möchte ich aber vermeiden. Welche Möglichkeiten gibt es noch? Code: Sub test() Dim a() As String, s As String, n As Long s = "AAA;2;BBB;123.56;CCC" a = Split(s, ";") 'Variante 1 Range(Cells(1, 1), Cells(1, UBound(a) + 1)) = a
'Variante 2 For n = 1 To UBound(a) + 1: Cells(2, n) = a(n - 1): Next End Sub
vg, MM
Registriert seit: 17.04.2019
Version(en): M$ 365 AfE v2009 / Office2013
18.07.2019, 15:51
(Dieser Beitrag wurde zuletzt bearbeitet: 18.07.2019, 15:51 von Mase.
Bearbeitungsgrund: edit:
)
Hoi,
warum Dim a() as string und nicht variant (ausgenommen der Einwand Speicherbedarf) ?
edit: I.S.v: a = Quellrange.Value2 Zielrange.Value2 = a
Registriert seit: 27.12.2018
Version(en): 2003,2010
Hallo Mase,
danke für die Antwort.
ob a Variant oder String ist, macht für das Problem keinen Unterschied. In beiden Fällen werden Zahlen nicht als solche erkannt und sauber in die Zellen geschrieben.
Die Datenquelle ist eine Textdatei (*.csv), kein Excel.
vg, MM
Registriert seit: 11.04.2014
Version(en): Office 2007
Hallo, wenn man dein Beispiel nicht in einer Zeile schreibt sondern in eine Spalte funktioniert es. Code: Sub test() Dim a() As String, s As String, n As Long s = "AAA;2;BBB;123.56;CCC" a = Split(s, ";") 'Variante 1 Range(Cells(1, 1), Cells(UBound(a) + 1, 1)) = WorksheetFunction.Transpose(a)
'Variante 2 For n = 1 To UBound(a) + 1: Cells(n, 2) = a(n - 1): Next End Sub
Gruß Stefan Win 10 / Office 2016
Folgende(r) 1 Nutzer sagt Danke an Steffl für diesen Beitrag:1 Nutzer sagt Danke an Steffl für diesen Beitrag 28
• mmat
Registriert seit: 16.08.2017
Version(en): 2007 / 2010 / Web
Hi und so dann auch wieder für eine Zeile. Geschwindigkeit??? Code: Application.Transpose(Application.Transpose(a))
Registriert seit: 17.04.2019
Version(en): M$ 365 AfE v2009 / Office2013
19.07.2019, 07:45
(Dieser Beitrag wurde zuletzt bearbeitet: 19.07.2019, 07:46 von Mase.)
(18.07.2019, 16:33)mmat schrieb: Hallo Mase,
danke für die Antwort.
ob a Variant oder String ist, macht für das Problem keinen Unterschied. In beiden Fällen werden Zahlen nicht als solche erkannt und sauber in die Zellen geschrieben.
Die Datenquelle ist eine Textdatei (*.csv), kein Excel.
vg, MM Stimmt, wenn aus *.csv bringt das nichts; und doppelt gemoppelt (erst einlesen, dann variant-array) beantwortet die eigentliche (gute Frage wie ich finde :70: ) letztlich auch nicht ;). Interessanterweise findet bei Cells() im Vergleich zu Range() keine implizite Typumwandlung statt. By the way: Ein interessanter Performancetest zwischen .Text, .Value, .Value2 lässt sich für Interessierte folgender Link finden: https://fastexcel.wordpress.com/2011/11/...-avoid-it/ :68:
Registriert seit: 06.12.2015
Version(en): 2016
Warum dim a() as string?
Dann müssen alle Elemente von a Texte sein. Einfacher wäre ohne den Dim-Befehl zu arbeiten, dann ergibt "Split()" ein Variant-Array.
Ungeprüft: cells(1,1).resize(,ubound(a)+1) = a
Wenn es auf Performance ankommt, sollte zuerst alles in ein Array geschrieben werden und erst dann alles auf einmal in die Excel-Zellen.
Registriert seit: 27.12.2018
Version(en): 2003,2010
(18.07.2019, 17:22)Steffl schrieb: Hallo,
wenn man dein Beispiel nicht in einer Zeile schreibt sondern in eine Spalte funktioniert es.
Code: Sub test() Dim a() As String, s As String, n As Long s = "AAA;2;BBB;123.56;CCC" a = Split(s, ";") 'Variante 1 Range(Cells(1, 1), Cells(UBound(a) + 1, 1)) = WorksheetFunction.Transpose(a)
'Variante 2 For n = 1 To UBound(a) + 1: Cells(n, 2) = a(n - 1): Next End Sub
Hallo Steffl, bei mir leider nicht nicht (Office 2010). Mit transpose hab ich das selbe Phänomen in der 1. Spalte (der fehlende implizite Typecast) wie sonst in der 1. Zeile. Trotzdem: Eine interessante Idee ! vg, MM
Registriert seit: 12.03.2016
Version(en): Excel 2003/ 2016
Hallo
ich weiss jetzt nicht ob ich mich blamiere, bei 20.000 Zeilen waere es einen Versuch wert! Was ist wenn man Variante 1 verwendet, und in die Spalte daneben per VBA diese Formel setzt und runterzieht =A1*1 Diese Formel kann man danach wieder per VBA in echte Zahlen umwandeln. Vielleicht mal testen??
mfg Gast 123
Folgende(r) 1 Nutzer sagt Danke an Gast 123 für diesen Beitrag:1 Nutzer sagt Danke an Gast 123 für diesen Beitrag 28
• mmat
Registriert seit: 27.12.2018
Version(en): 2003,2010
19.07.2019, 14:10
(Dieser Beitrag wurde zuletzt bearbeitet: 19.07.2019, 14:16 von mmat.)
(19.07.2019, 14:06)Gast 123 schrieb: Hallo
ich weiss jetzt nicht ob ich mich blamiere, bei 20.000 Zeilen waere es einen Versuch wert! Was ist wenn man Variante 1 verwendet, und in die Spalte daneben per VBA diese Formel setzt und runterzieht =A1*1 Diese Formel kann man danach wieder per VBA in echte Zahlen umwandeln. Vielleicht mal testen??
mfg Gast 123 Hallo Gast, Nee, das ist eigentlich eine gute Idee, auf die ich jedenfalls auch nicht gekommen bin Danke vg, MM
Hallo, ich danke allen für ihre Mitwirkung. Inzwischen hab ich mich damit abgefunden, dass der Typecast bei Variante 1 einfach nicht funktioniert und folgenden Workaround entwickelt. Wie bereits erwähnt, macht es keinen Unterschied (für das Problem), ob a als variant oder string deklariert ist. Der Workaround besteht aus einer kleinen Schleife, in der die ganze Zeile in ein weiteres Array kopiert wird. Das ist allemal schneller, als jede Zelle einzeln in die Tabelle zu schreiben. Code: Sub test() Dim a() As String, s As String, n As Long, b Cells.ClearContents s = "AAA;2;BBB;123.56;CCC" a = Split(s, ";") ReDim b(UBound(a)) For n = 0 To UBound(a) If IsNumeric(a(n)) Then b(n) = Val(a(n)) Else b(n) = a(n) Next 'Variante 1: Alle Zellen der Zeile auf einmal schreiben Range(Cells(1, 1), Cells(1, UBound(a) + 1)) = b ''Variante 2: jede Zelle einzeln schreiben (mit implizitem Typecast). Laaaaaaahm ... ' For n = 1 To UBound(a) + 1: Cells(2, n) = a(n - 1): Next End Sub
vg, MM
|