Dieses Forum nutzt Cookies
Dieses Forum verwendet Cookies, um deine Login-Informationen zu speichern, wenn du registriert bist, und deinen letzten Besuch, wenn du es nicht bist. Cookies sind kleine Textdokumente, die auf deinem Computer gespeichert werden. Die von diesem Forum gesetzten Cookies werden nur auf dieser Website verwendet und stellen kein Sicherheitsrisiko dar. Cookies aus diesem Forum speichern auch die spezifischen Themen, die du gelesen hast und wann du zum letzten Mal gelesen hast. Bitte bestätige, ob du diese Cookies akzeptierst oder ablehnst.

Ein Cookie wird in deinem Browser unabhängig von der Wahl gespeichert, um zu verhindern, dass dir diese Frage erneut gestellt wird. Du kannst deine Cookie-Einstellungen jederzeit über den Link in der Fußzeile ändern.

Warum ist das keine Zahl?
#1
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
Antworten Top
#2
Hoi,

warum Dim a() as string und nicht variant (ausgenommen der Einwand Speicherbedarf) ?

edit:
I.S.v:
a = Quellrange.Value2
Zielrange.Value2 = a
gruß
Marco
Antworten Top
#3
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
Antworten Top
#4
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:
  • mmat
Antworten Top
#5
Hi

und so dann auch wieder für eine Zeile.  Geschwindigkeit???
Code:
Application.Transpose(Application.Transpose(a))
Antworten Top
#6
(18.07.2019, 15: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:
gruß
Marco
Antworten Top
#7
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.
Antworten Top
#8
(18.07.2019, 16: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
Antworten Top
#9
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:
  • mmat
Antworten Top
#10
(19.07.2019, 13: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
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste