4.3k Aufrufe
Gefragt in Tabellenkalkulation von
Hallo!

Ich suche Hilfe für folgendes Problem:

Ich habe Stromverbrauchsdaten vorliegen, die 1 Jahr lang im 15 Minuten Takt erfasst wurden.
Die Struktur der Excelfiles sieht so aus (die Spalten haben Überschriften):
Spalte A: Nummer des Stromzaehlers
Spalte B: Zeitpunkt der Erfassung (zB '201004010115 = 01.April 2010 um 01:15 Uhr)
Spalte C: Verbrauchswert

Der Dateiname entspricht dabei immer der Zählernummer, die auch in Spalte A steht.

Für jeden Monat und jeden einzelnen Zähler habe ich ein solches File. Das heißt 12 Excelfiles für jeden Zähler und insgesamt 1700 Zähler (somit 20.400 Excelfiles)

Was ich brauche ist ein Excelfile in dem in Spalte A der Zeitpunkt der Erfassung (von 01.04.2010 00:00 Uhr bis 31.03.2011 23:45) steht und die Verbrauchswerte der einzelnen Zähler dann in den folgenden Spalten.

Wenn jemand eine Idee hätte, wie ich das hinbekomme, wäre es spitze!
Vielen herzlichen Dank im Voraus!
Andi

12 Antworten

0 Punkte
Beantwortet von saarbauer Profi (15.6k Punkte)
Hallo,

ich habe erhebliche Zweifel ob das Problem so zu lösen ist.
Da es sich nach meiner überschläglichen berechnung um etwa

59 000 000 Datensätze handeln müsste. 20400 Files mit etwa 2 900 Datensätze pro Monat .

Die wirst du mit einem Normalen PC und den mir bekannten Excelversionen nicht verarbeiten können.

Gruß

Helmut
0 Punkte
Beantwortet von theblackbird_ Mitglied (605 Punkte)
Moin,

@Helmut (Saarbauer)
Rein zur Datenerfassung sollte das ab Version 2007 doch in eine Tabelle passen, oder? Wir haben da doch 1.048.576Zeilen zur Verfuegung und 16.384Spalten.
Fuer die Zusammenfassung benoetigen wir, wenn ich micht da nicht vertue, 365Tage * 24Stunden *4 Werte je Stunde +1 UeberschriftenZeile = 35.041Zeilen, und fuer 1.700 Zaehler + 1 ZeitenSpalte also 1.701 Spalten.

Der Platz sollte fuer die reine Datenerfassung/-zusammenfuehrung also ausreichend sein. Gut, wenn es dann an entsprechende Auswertungen gehen soll, dann sehe ich da bei Excel auch Grenzen, die das unertraeglich langsam, wenn nicht gar unmoeglich machen koennten. (je nach Auswertungsumfang) Aber davon hat Andi300 ja NOCH nicht gesprochen.

@Topic
Also die reine Datenzusammenfassung koennte ich mir per Makro schon vorstellen. Um das anzugehen waere es allerdings in meinen Augen notwendig, die Verzeichnisstruktur sowie die genaue Bennenung der einzelnen Files zu kennen. Wenn der Dateiname immer der Zaehlernummer entspricht, dann muessten die Files fuer die einzelnen Monate ja in verschiedenen Verzeichnissen liegen. Oder ist der Erfasungsmonat im Dateinamen mit vermerkt? Liegen in dem/den Verzeichnis/sen noch andere ExcelFiles, die nicht zu beruecksichtigen sind? Welche ExcelVersion wird verwendet? Etc. pp. ...
Ideal waere es in meinen Augen, wenn Andi300 mal die Files von 3 bis 4 Zaehlern mit Pfaden in ein ZIP-File packen wuerde (ggf. mit geaenderten/anonymisierten Zaehlernummern) und dies dann mal fuer Tests im Netz ( z.B. hier ) zur Verfuegung stellen koennte.

Cu
TheBlackBird ®
0 Punkte
Beantwortet von saarbauer Profi (15.6k Punkte)
Hallo @TheBlackBird,

so wie ich es einschäte will @Andi300 wahrscheinlich nicht nur die Datensätze sammeln, sondern auch irgendwie verarbeiten und da tritt dann wahrscheinlich ein Leistungsproblem des PC's auf. Sonst hast du recht, aber es fehlt auch eine Aussage über die benutzte Excel-Version.

Wer ist eigentlich @Topic?

Gruß

Helmut
0 Punkte
Beantwortet von
Guten Morgen!

Danke schon mal fürs Nachdenken über mein Problem :-)

Also ich verwende Excel 2007.

Verzeichnisstruktur:
Da die Bezeichnungen für jeden Monat gleich sind, habe ich einen Hauptordner mit 12 Unterordnern für die einzelnen Monate.
Der Erfassungsmonat ist leider nicht im Dateinamen vermerkt. Der Name ist immer Projekt_Zaehlernummer wobei die Zaehlernummern auch unterschiedlich lang sind.

In den Verzeichnissen liegen sonst keine anderen Excel-Files.

Ich habe 3 meiner Files hier abgelegt:
http://www.file-upload.net/download-3406474/Profile.rar.html

Was das Thema Computerleistung angeht ... ich löse gerade ein Problem nach dem anderen :-) Danke für Eure Hilfe! Andrea
0 Punkte
Beantwortet von nighty Experte (6.6k Punkte)
hi all :-)

ein beispiel

gruss nighty

ich setze mal ein wenig vb kenntnisse vorraus um den zu kopierenden bereich anzupassen ^^

Option Explicit
Sub DateienLesen()
Call EventsOff
Dim DateiName As String
DateiName = Dir("C:\Temp\" & "*.xls")
Do While DateiName <> ""
If ThisWorkbook.Name <> DateiName Then
Workbooks.Open Filename:="C:\Temp\" & DateiName
Workbooks(DateiName).Worksheets(1).Range("A1:A" & Workbooks(DateiName).Worksheets(1).Range("A" & Rows.Count).End(xlUp).Row).Copy
ThisWorkbook.Worksheets(1).Range("A" & ThisWorkbook.Worksheets(1).Range("A" & Rows.Count).End(xlUp).Row + 1).PasteSpecial Paste:=xlValues, Operation:=xlNone
Workbooks(DateiName).Close SaveChanges:=True
End If
DateiName = Dir
Loop
Call EventsOn
End Sub
Public Sub EventsOff()
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
End Sub
Public Sub EventsOn()
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With
End Sub
0 Punkte
Beantwortet von theblackbird_ Mitglied (605 Punkte)
Moin,

@Andrea (Andi300)
- Soll diese Zusammenfassung eine einmalige Aktion sein? Oder wird das wiederkehrend (alle Jahre, jedes Quartal, ???) immer mal wieder auftauchen?
- Kann es passieren, dass im Abrechnungszeitraum Zaehler/Projekte hinzukommen/wegfallen?
- Wenn wiederkehrend, ist dann der Abrechnungszeitraum immer identisch? (Also immer 1.4.Vorjahr bis 31.3.aktJahr?)


@Helmut (Saarbauer)
Wer ist eigentlich @Topic?

Da fragst Du was. Den kenne ich auch nicht. ;-)
Aber ernsthaft. "Topic" uebersetze ich im Zusammenhang mit Inetforen mit "Thema"/"Thematik". Der Begriff "offTopic" ist fuer mich daher ein Beitrag der mit der eigtl. Thematik eines Threads nicht wirklich was zu tun hat. Ich wollte, nachdem ich Dich in meinem Post nun direkt angesprochen hatte, mit diesem "@Topic" nur kenntlich machen, dass der darauf folgende Teil dem eigtl. Thema des Threads gewidmet ist.

Cu TheBlackBird ®
0 Punkte
Beantwortet von
Hallo TheBlackBird!

Das ist eine einmalige Aktion und auf den Zeitraum 01. April 2010 (erster Wert von 00:15 Uhr) bis 31. März 2011 (letzter Wert 23:45 Uhr) begrenzt.

Was tatsächlich der Fall ist, ist dass zwischendurch Zähler weggefallen sind und andere dazugekommen.

Und ich hab nochwas vergessen zu erwähnen: die files sind .csv files :-\

Ich versuche gerade die Antwort von nighty umzusetzen (Danke!), wenn ich das Makro auslöse, passiert allerdings (noch) nichts.
Ich habe leider nur Basiskenntnisse von VBA.

Danke einstweilen! Andrea
0 Punkte
Beantwortet von theblackbird_ Mitglied (605 Punkte)
Moin,

Ich hab mich nun mal rangesetzt und was gebastelt. Dazu habe ich aus den 3Beispielfiles mal 9 gemacht und diese auf 3Monate verteilt.
Dabei
-lese ich die Verzeichnisstruktur in ein Array ein
-klapper dieses dann nach und nach ab
-lese das jeweilige CSV in ein neues Array
-hole dort dann ZaehlerNummer und Werte raus um sie in ein drittes Array zu schreiben
-Drittes Array (Ausgabe) ist bereits mit der kompletten TimeStamp-Liste fuer das Abrechnungsjahr gefuellt

Da ich die Timestamps nun schon im AusgabeArray habe und auch Zaehler im Abrechnungszeitraum hinzukommen koennen
vergleiche ich von jedem CSV jeden Timestamp mit den einzelnen Timestamps im AusgabeArray (ca. 35000). Was besseres
ist mir im ersten Ansatz leider nicht eigefallen.

Die Logik im Code sollte so auf den ersten Blick stimmen. Aber mit den For-Schleifen ist das Ding nat. ULTRA-LANGSAM.
Fuer die 9Files brauch mein altes Schaetzchen hier eine geschlagene Minute. Da mit hoeherem Monat der Vergleichsaufwand
zwischen CSV-Array und AusgabeArray dann auch noch steigen wird, waere das so grob geschaetzt eine Rechenzeit von ca. 48Stunden,
wenn man das tatsaechlich auf die 20400CSVs loslassen wuerde.
Und das auch nur, wenn das Ding durchhaelt. Inakzeptabel, wie ich finde.

Wenn mir/uns da nichts besseres einfaellt, kann es doch tatsaechlich sein, dass Helmut (Saarbauer) mit seinem Einwand aus #1 recht behaelt.

Ich stelle den Code dennoch einmal hier zur Diskussion/Verbesserung ein:

Code gehoert komplett in ein Modul.
Zu starten waere (nach Anpassung des Quellpfades) das Sub Strom()

Public varFSArr As Variant
Public varArr As Variant

Sub Strom()
Dim varArr2 As Variant
Dim lngCount As Long, lngCount2 As Long
Dim dtmDateTime As Date
Dim lngFFn As Long
Dim blnJo As Boolean
Dim lngSpalte As Long
Dim lngZeile As Long
Dim wksZL As Worksheet
Dim varSB As Variant


varSB = Application.StatusBar
'Verzeichnis-/Dateistruktur der CSV-Files aufsammeln
'===================================================
ReDim varFSArr(0)
SuchRoot ("C:\001_Test\SN_Downloads\Stromzaehler") '!!!hier Verzeichnis mit den Ganzen Daten angeben/anpassen

'vollstaendige Timestamp-Liste basteln
'=====================================
dtmDateTime = #4/1/2010#
lngCount = 0
ReDim varArr(1 To 1, 1)
Do
lngCount = lngCount + 1
If UBound(varArr, 2) <= lngCount Then ReDim Preserve varArr(1 To 1, 1 To UBound(varArr, 2) + 10000)
varArr(1, lngCount) = "'" & Replace(Format(dtmDateTime, "yyyy,mm,dd,hh,mm"), ",", "")
dtmDateTime = dtmDateTime + TimeValue("00:15:00")
Loop Until dtmDateTime >= #4/1/2011#
ReDim Preserve varArr(1 To 1, 0 To lngCount)
ReDim varArr2(0 To lngCount, 0 To 1)
For lngCount = 0 To UBound(varArr, 2) Step 1
varArr2(lngCount, 0) = varArr(1, lngCount)
Next lngCount
ReDim varArr(0)

'Dateien durchgehen
'==================
For lngCount = 0 To UBound(varFSArr) Step 1
If LCase(Right(varFSArr(lngCount), 3)) = "csv" Then
'Statusbar beschreiben zur Laufkontrolle
Application.StatusBar = "Verarbeite: " & varFSArr(lngCount)
'CSV in Array einlesen
CSVtoArr (varFSArr(lngCount))
blnJo = False
'Zaehlerspalte suchen ggf. neu anlegen
For lngCount2 = 1 To UBound(varArr2, 2)
If varArr(2, 1) = varArr2(0, lngCount2) Then blnJo = True: Exit For
Next lngCount2
If blnJo Then
lngSpalte = lngCount2
ElseIf lngCount2 = 2 And varArr2(0, 1) = "" Then
lngSpalte = lngCount2 - 1
varArr2(0, 1) = varArr(2, 1)
Else
lngSpalte = lngCount2
ReDim Preserve varArr2(LBound(varArr2, 1) To UBound(varArr2, 1), 0 To lngSpalte)
varArr2(0, lngSpalte) = varArr(2, 1)
End If
'Zaehlerwerte einsortieren
For lngCount2 = 2 To UBound(varArr, 1) Step 1
For lngZeile = 1 To UBound(varArr2, 1) Step 1
If varArr(lngCount2, 2) = varArr2(lngZeile, 0) Then _
varArr2(lngZeile, lngSpalte) = varArr(lngCount2, 3) _
: Exit For
'End If
Next lngZeile
Next lngCount2
End If
Next lngCount
'Array in Tabelle1 schreiben
'===========================
With ThisWorkbook.Worksheets("Tabelle1")
.Cells(1, 1).Resize(UBound(varArr2, 1), UBound(varArr2, 2) + 1).NumberFormat = "General"
.Cells(1, 1).Resize(UBound(varArr2, 1), UBound(varArr2, 2) + 1) = varArr2
.Cells(1, 1).ClearContents
End With
Application.StatusBar = varSB
End Sub

Private Sub CSVtoArr(ByVal strFile As String)
'aus http://www.ms-office-forum.net/forum/showpost.php?p=1361276&postcount=2
'entnommen und angepasst
Dim fso
Dim datei
Dim arr

Dim L As Long
Dim I As Integer
Dim arrTmp As Variant
Const spalten = 3
Set fso = CreateObject("scripting.filesystemobject")
Set datei = fso.opentextfile(strFile)
arr = Split(datei.readall, vbCrLf)
datei.Close
ReDim varArr(1 To UBound(arr), 1 To spalten)
For L = LBound(arr) To UBound(arr)
arrTmp = Split(arr(L), ";")
For I = LBound(arrTmp) To UBound(arrTmp)
If IsNumeric(Trim(arrTmp(I))) Then _
varArr(L + 1, I + 1) = CDbl(Trim(arrTmp(I))) _
Else varArr(L + 1, I + 1) = Trim(arrTmp(I))
Next
Next
Set fso = Nothing
Set datei = Nothing
End Sub

Private Sub SuchRoot(strQuelle As String)
'Variablen
'=========
Dim objFS As Object
Dim fldQuelle As Object

Set objFS = CreateObject("Scripting.FileSystemObject")
Set fldQuelle = objFS.GetFolder(strQuelle)
Verzeichnisse fldQuelle
Set fldQuelle = Nothing
Set objFS = Nothing

End Sub

Private Sub Verzeichnisse(objFld As Object)
'!!!Rekursiver Aufruf!!!
'aus "Sub SuchRoot" heraus angestossen

'Variablen
'=========
Dim objSubFld As Object
Dim objFile As Object
Dim objFS As Object

Set objFS = CreateObject("Scripting.FileSystemObject")

For Each objFile In objFld.Files
ReDim Preserve varFSArr(UBound(varFSArr) + 1)
varFSArr(UBound(varFSArr)) = objFile.Path
Next objFile

For Each objSubFld In objFld.SubFolders
Verzeichnisse objSubFld
Next

Set objFS = Nothing
Set objFld = Nothing
Set objSubFld = Nothing
End Sub


Cu TheBlackBird ®
... der da sicher noch ein paar Tage dran rumfrickeln wird
0 Punkte
Beantwortet von saarbauer Profi (15.6k Punkte)
hallo,

hier wäre vielleicht sinnvoll das Vorhaben mit den Daten etwas genauer zu kenne, dann kommen vielleicht auch noch andere Lösungsvorschläge.

Die bis jetzt gemachten Lösungsvorschläge werden aus meiner Sicht an der Leistungsfähigkeit des PC's scheitern

Gruß

Helmut
0 Punkte
Beantwortet von
Hi TheBlackBird!

Ich sag mal ganz herzlichen Dank! Ich werde mich heute mal dahinterklemmen, das auszuprobieren.
Ich fürchte aber auch, dass mein Computer da nicht mitspielt. Ich werd das mal heute über Nacht laufen lassen und schauen, was er bis morgen früh schafft!

Danke und liebe Grüße! Andrea
...