VBA Excel 2000 Textdatei einlesen

Hallo Reinhard,

tja nun, ich habe da sowieso noch massivste
Verstehensprobleme, aber ich gehe noch davon aus, aus x
Dateien mit gleichem Aufbau sollen jeweils die Messwerte für
bekannte 250 Frequenzen ausgelesen werden und dann pro
Frequenz eine Textdatei mit den Messwerten für diese Frequenz
angelegt werden, x wäre dann die Anzahl der Datensätze in
diesen Textdateien.

Ach so. Hmmm. Na dann die Frequenz in den Dateinamen, die Datei immer mit ‚Append‘ öffnen, Satz anhängen und wieder schließen.

Leider nein.

Schade, dann eben FSO. :smile:

Ebenfalls nicht getestet, aber der Debugger wid sicher bei
Zeilen_in_Exceltabelle rummotzen :smile:

Ja logisch, das ist ja auch Pseudocode. :smile: Wie Du von Excel die Anzahl der gefüllten zeilen bekommst, weiß ich doch nicht, das war nur ein Hinweis für Dich, was da hin gehört.

Mit Sicherheit richtig, aber schau mal meine Frage:

@Zodan, willst du eigentlich als Endergebnis Textfiles für
jede Frequenz, oder gleich Exceldateien?

Die frage ist natürlich berechtigt, Zodan schreibt ja, daß er Textfiles nur in Betracht gezogen hat, weiß er nicht weiß, wie man Excel-Files schreibt.

250 Frequenzen, eine Tabelle zum lesen … kannst Du in Excel 251 Tabellenblätter gleichzeitig öffnen? … :smile:

Gruß, Rainer

Grüezi zusammen

Ich mische (mich) hier auch mal mit (ein) :wink:

Ich nicht, aber Excel(2002) funktioniert problemlos bei

Sub ttt()
Dim a(14000, 250, 5) As String * 4
a(13500, 230, 2) = „huhu“
MsgBox a(13500, 230, 2)
End Sub

Das klappt nur weil Excel eine implizite Typenumwandlung zulässt/vornimmt - darauf würde ich mich nie und nimmer verlassen wollen; zu viele Unwägbarkeiten gehen damit einher.

VB6 nicht?

Hoffentlich nicht! :wink:

As Variant? Drei Dimensionen? Hier stimmt etwas nicht.

Wieso? Was hat denn der Variablentyp mit der Anzahl der
Dimensionen zu tun.

Den Speicherbedarf. Arr(1 to 1000) As Byte sind nur 1000
Bytes, As Double aber 8000 Bytes. Was passiert bei Variant?
ich habe keine Ahnung, wie viel Speicher dann reserviert wird,
aber genug um auch Strings zu verwalten, denke ich.

Die Excel-Hilfe sagt dazu folgendes:

Variant (mit Zahlen)
16 Bytes Numerische Werte im Bereich des Datentyps Double.
Variant (mit Zeichen)
22 Bytes plus Zeichenfolgenlänge Wie bei String mit variabler Länge

…es kommt also auch auf den Inhalt an.

Weil ich wissen will, was passiert, gebe ich den Datentyp immer an,
wenn ich ihn weiß.

Ich denke, das ist auch in Excel die richtige Vorgehensweise - nur so ist ein sauberes Datenhandling möglich und kontrollierbar.


Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -
1 Like

tja nun, ich habe da sowieso noch massivste
Verstehensprobleme, aber ich gehe noch davon aus, aus x
Dateien mit gleichem Aufbau sollen jeweils die Messwerte für
bekannte 250 Frequenzen ausgelesen werden und dann pro
Frequenz eine Textdatei mit den Messwerten für diese Frequenz
angelegt werden, x wäre dann die Anzahl der Datensätze in
diesen Textdateien.

x wäre die Anzahl der Dateien /8

Ach so. Hmmm. Na dann die Frequenz in den Dateinamen, die
Datei immer mit ‚Append‘ öffnen, Satz anhängen und wieder
schließen.

Hab die Daten aus einer (von den je 7) Messdatein pro Zeitpunkt jetzt in ein array geschrieben und von dort aus in eine Text (binär) Datei.

Schade, dann eben FSO. :smile:

FSO?

@Zondan, willst du eigentlich als Endergebnis Textfiles für
jede Frequenz, oder gleich Exceldateien?

wenn mir jemand erklärt, wie ich (am besten gleich ganze Bereiche) aus einer Excel Datei in die aktuelle kopiere, dann wären Excel-Dateien wohl praktischer (aber wahrscheinlich größer, das probier ich später auch mal)

Bin bis jetzt mit den Binär Dateien ganz zufrieden, das auslesen muß ich jetzt nur noch testen!
Aber unter http://www.vbarchiv.net/archiv/tipp_1093.html hab ich schon was in der Richtung gefunden!

Die frage ist natürlich berechtigt, Zodan schreibt ja, daß er
Textfiles nur in Betracht gezogen hat, weiß er nicht weiß, wie
man Excel-Files schreibt.

Richtig

250 Frequenzen, eine Tabelle zum lesen … kannst Du in Excel
251 Tabellenblätter gleichzeitig öffnen? … :smile:

da ich den Umweg mit dem Array gehe, wir immer nur eine zusätzliche Datei aufgemacht, ausgelesen und wieder geschlossen.

Hier mal mein momentaner Code, Explicit sollte ich wohl auch noch verwenden!
@Binärdatei (komplett auskommentiert) sieht im Hexeditor nach sehr vielen hex00 werten aus!
@Textdatei hier stimmt die Formatierung noch nicht

der Aufbau in der Dateien ist noch nicht richtig, nur zu testzwecken!

Sub tt()
pfad = Cells(6, 10)
endung = Cells(7, 10)
anzahl = Cells(8, 10)
schritte = Cells(9, 10)
schrittweite = Cells(10, 10)
Dim N As Integer, Z As Byte, S As Byte
Dim file As Integer
Dim W As Byte
'Dim daten() As satz
'Application.ScreenUpdating = False
With Application.FileSearch
.LookIn = pfad
.Filename = endung
If .Execute(SortBy:=msoSortByFileName, SortOrder:=msoSortOrderAscending) > 0 Then
'MsgBox .FoundFiles.Count
Else
MsgBox „keine Datei gefunden“
End If

Dim daten()
ReDim daten(1 To anzahl, 4, schritte)

For N = 1 To .FoundFiles.Count ’ alle Datein
Workbooks.Open .FoundFiles(N)
For Z = 1 To schritte ’ alle Frequenzen
For S = 1 To 4 'alle Messwerte
daten(N, S, Z) = Cells(Z * schrittweite, S * 2)
Next S
Next Z
For Each WB In Workbooks
If WB.Name ThisWorkbook.Name Then
WB.Close savechanges:=False
End If
Next WB
Next N

'Binäre Datei 684kB
ff = FreeFile
t = pfad & „daten_“ & N + 100 & „.txt“
If Dir$(t) „“ Then Kill t 'Wenn vorhanden löschen
Open t For Binary As #ff
For a = 1 To schritte
For b = 1 To anzahl
For c = 1 To 4
Put #ff, , daten(b, c, a)
Next
Next
Next
Close #ff

'Textdatei 1190KB
't = pfad & „test.txt“
'If Dir$(t) „“ Then Kill t 'Wenn vorhanden löschen
'Set fs = CreateObject(„Scripting.FileSystemObject“)
'Set filen = fs.CreateTextFile(pfad & „test.txt“, True)
'For a = 1 To schritte
’ For b = 1 To anzahl
’ For c = 1 To 4
’ filen.writeline (daten(b, c, a))
’ Next
'Next
'Next
End With
End Sub

(im Orginal sind die Zeilen eingeschoben, hier im „Schreibfenster“ auch!)

Hallo Thomas,

Ich mische (mich) hier auch mal mit (ein) :wink:

*gg* dafür ist das Brett ja da.

Ich nicht, aber Excel(2002) funktioniert problemlos bei

Sub ttt()
Dim a(14000, 250, 5) As String * 4
a(13500, 230, 2) = „huhu“
MsgBox a(13500, 230, 2)
End Sub

Das klappt nur weil Excel eine implizite Typenumwandlung
zulässt/vornimmt - darauf würde ich mich nie und nimmer
verlassen wollen; zu viele Unwägbarkeiten gehen damit einher.

VB6 nicht?

Hoffentlich nicht! :wink:

Doch, VB6 spielt da genau so mit. Man kann auch in VB6 Arrays einfach als Variant deklarieren, Variablen gar nicht und sich darauf verlassen, daß ein String in eine Zahl umgewandelt wird, wenn das erforderlich ist. Das kann dann schon mal zu Ergebnissen führen, die man nicht versteht.

As Variant? Drei Dimensionen? Hier stimmt etwas nicht.

Wieso? Was hat denn der Variablentyp mit der Anzahl der
Dimensionen zu tun.

Den Speicherbedarf. Arr(1 to 1000) As Byte sind nur 1000
Bytes, As Double aber 8000 Bytes. Was passiert bei Variant?
ich habe keine Ahnung, wie viel Speicher dann reserviert wird,
aber genug um auch Strings zu verwalten, denke ich.

Die Excel-Hilfe sagt dazu folgendes:

Variant (mit Zahlen)
16 Bytes Numerische Werte im Bereich des Datentyps Double.
Variant (mit Zeichen)
22 Bytes plus Zeichenfolgenlänge Wie bei String mit variabler
Länge

…es kommt also auch auf den Inhalt an.

Danke! :smile: Bei Bedarf wird dann Virtual Memory genutzt und die Anwendung wird tränig langsam. Richtig?

Weil ich wissen will, was passiert, gebe ich den Datentyp immer an,
wenn ich ihn weiß.

Ich denke, das ist auch in Excel die richtige Vorgehensweise -
nur so ist ein sauberes Datenhandling möglich und
kontrollierbar.

Leider wird das nicht erzwungen, ich würde es begrüßen. :smile:

Gruß, Rainer

Grüezi Rainer

Ich mische (mich) hier auch mal mit (ein) :wink:

*gg* dafür ist das Brett ja da.

-)))

Ich nicht, aber Excel(2002) funktioniert problemlos bei

Sub ttt()
Dim a(14000, 250, 5) As String * 4
a(13500, 230, 2) = „huhu“
MsgBox a(13500, 230, 2)
End Sub

Das klappt nur weil Excel eine implizite Typenumwandlung
zulässt/vornimmt - darauf würde ich mich nie und nimmer
verlassen wollen; zu viele Unwägbarkeiten gehen damit einher.

VB6 nicht?

Hoffentlich nicht! :wink:

Doch, VB6 spielt da genau so mit. Man kann auch in VB6 Arrays
einfach als Variant deklarieren, Variablen gar nicht und sich
darauf verlassen, daß ein String in eine Zahl umgewandelt
wird, wenn das erforderlich ist. Das kann dann schon mal zu
Ergebnissen führen, die man nicht versteht.

Autsch! sage ich da nur.

Den Speicherbedarf. Arr(1 to 1000) As Byte sind nur 1000
Bytes, As Double aber 8000 Bytes. Was passiert bei Variant?
ich habe keine Ahnung, wie viel Speicher dann reserviert wird,
aber genug um auch Strings zu verwalten, denke ich.

Die Excel-Hilfe sagt dazu folgendes:

Variant (mit Zahlen)
16 Bytes Numerische Werte im Bereich des Datentyps Double.
Variant (mit Zeichen)
22 Bytes plus Zeichenfolgenlänge Wie bei String mit variabler
Länge

…es kommt also auch auf den Inhalt an.

Danke! :smile: Bei Bedarf wird dann Virtual Memory genutzt und die
Anwendung wird tränig langsam. Richtig?

Vermutlich wird da eher das interne Limit der jeweiligen Excel-Versin erreicht und Excel sagt ‚Bye Bye‘. Mehr RAM auf einem Rechner erweitert hier nicht die Möglichkeiten, da Excel ein eigenes Memory-Management verwendet, dessen Grössen beschränkt sind.

Weil ich wissen will, was passiert, gebe ich den Datentyp immer an,
wenn ich ihn weiß.

Ich denke, das ist auch in Excel die richtige Vorgehensweise -
nur so ist ein sauberes Datenhandling möglich und
kontrollierbar.

Leider wird das nicht erzwungen, ich würde es begrüßen. :smile:

Ja, das würde einiges an Problemen im Keim ersticken, andererseits aber den Spass beim Erlernen einer Sprache doch sehr dämpfen, weil die tröge Theorie dann wieder viel wichtiger wird und nicht sofort Erfolgserlebnisse verbucht werden können.

Aber jeder kann sich da ja selbst lieb sein, sobald er die Problematik mal erkannt hat. :wink:


Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -

Hi Zodan,

Schade, dann eben FSO. :smile:

FSO?

F ile S ystem O bject … siehe Code weiter oben. :smile:

@Zondan, willst du eigentlich als Endergebnis Textfiles für
jede Frequenz, oder gleich Exceldateien?

wenn mir jemand erklärt, wie ich (am besten gleich ganze
Bereiche) aus einer Excel Datei in die aktuelle kopiere, dann
wären Excel-Dateien wohl praktischer (aber wahrscheinlich
größer, das probier ich später auch mal)

Bin bis jetzt mit den Binär Dateien ganz zufrieden, das
auslesen muß ich jetzt nur noch testen!
Aber unter http://www.vbarchiv.net/archiv/tipp_1093.html hab
ich schon was in der Richtung gefunden!

Die frage ist natürlich berechtigt, Zodan schreibt ja, daß er
Textfiles nur in Betracht gezogen hat, weiß er nicht weiß, wie
man Excel-Files schreibt.

Richtig

250 Frequenzen, eine Tabelle zum lesen … kannst Du in Excel
251 Tabellenblätter gleichzeitig öffnen? … :smile:

da ich den Umweg mit dem Array gehe, wir immer nur eine
zusätzliche Datei aufgemacht, ausgelesen und wieder
geschlossen.

Das ist aber recht langsam.

Hier mal mein momentaner Code, Explicit sollte ich wohl auch
noch verwenden!
@Binärdatei (komplett auskommentiert) sieht im Hexeditor nach
sehr vielen hex00 werten aus!
@Textdatei hier stimmt die Formatierung noch nicht

der Aufbau in der Dateien ist noch nicht richtig, nur zu
testzwecken!

Sub tt()
pfad = Cells(6, 10)
endung = Cells(7, 10)
anzahl = Cells(8, 10)
schritte = Cells(9, 10)
schrittweite = Cells(10, 10)
Dim N As Integer, Z As Byte, S As Byte
Dim file As Integer
Dim W As Byte
'Dim daten() As satz
'Application.ScreenUpdating = False
With Application.FileSearch
 .LookIn = pfad
 .Filename = endung
 If .Execute(SortBy:=msoSortByFileName,
SortOrder:=msoSortOrderAscending) \> 0 Then
 'MsgBox .FoundFiles.Count
 Else
 MsgBox "keine Datei gefunden"
 End If

 Dim daten()
 ReDim daten(1 To anzahl, 4, schritte)

 For N = 1 To .FoundFiles.Count ' alle Datein
 Workbooks.Open .FoundFiles(N)
 For Z = 1 To schritte ' alle Frequenzen
 For S = 1 To 4 'alle Messwerte
 daten(N, S, Z) = Cells(Z \* schrittweite, S \* 2)
 Next S
 Next Z
 For Each WB In Workbooks
 If WB.Name ThisWorkbook.Name Then
 WB.Close savechanges:=False
 End If
 Next WB
 Next N

 'Binäre Datei 684kB
 ff = FreeFile
 t = pfad & "daten\_" & N + 100 & ".txt"
 If Dir$(t) "" Then Kill t 'Wenn vorhanden löschen
 Open t For Binary As #ff
 For a = 1 To schritte
 For b = 1 To anzahl
 For c = 1 To 4
 Put #ff, , daten(b, c, a)
 Next
 Next
 Next
 Close #ff

 'Textdatei 1190KB
 't = pfad & "test.txt"
 'If Dir$(t) "" Then Kill t 'Wenn vorhanden
löschen
 'Set fs = CreateObject("Scripting.FileSystemObject")
 'Set filen = fs.CreateTextFile(pfad & "test.txt", True)
 'For a = 1 To schritte
 ' For b = 1 To anzahl
 ' For c = 1 To 4
 ' filen.writeline (daten(b, c, a))
 ' Next
 'Next
 'Next
End With
End Sub

(im Orginal sind die Zeilen eingeschoben, hier im
„Schreibfenster“ auch!)

dafür gibt es hier die Pre-Tags
Schreibe vor Deinen Code

und dahinter In Deinem Beitrag füge ich das jetzt mal ein.

Noch einmal zum Verständnis.

Du hast jetzt 14000 ExcelFiles mit Messwerten von verschiedenen Zeitpunkten zu 250 Frequenzen und möchtest am Ende 250 ExcelFiles haben in denen immer die Daten einer Frequenz in einem File nach Zeit sortiert stehen. Richtig so?

Gruß, Rainer

Grüezi Reinhard

Jeder „Datensatz“ besteht aus:

7 Messdateien a 4 Messwerten über je 1000Frequenzen ich brauch
nur jede 4te auszuwerten! (die Frequenzen stehen 4x in jeder
Datei (A,C,E,G) das macht das Oszi immer so!)
1Messdatei mit „Umweltdaten“
Also die große Messreihe besteht aus ~5100 Datensätzen

Jede einzelne Datei einer messreihe/ordner besteht aus 1000
benutzten Zeilen, von denen du jede 4te Zeile brauchst?
Aber das macht irgednwie auch keinen Sinn mit deinen
Spaltenangaben A,C,E,G :frowning:

Ergo, ich habs immer noch nicht kapiert.

Ich bin da auch noch nicht ganz so weit…

Den Code zum „eingeben“ des Pfades hat mir Thomas Ramel schon
etwas weiter unten gegeben!

Dumm gelaufen, mir wärs lieber ich hätte dir da mit dem Pfad
geholfen und Thomas hätte sich hier involviert :smile:)

Na, ich wollte dir doch nicht vor dem Glück stehen :wink:

…aber wenn Du schon gerufen hast…

Die Dateien heißen dann Datum_Kanal_1_400Mhz.xls, … ,
Datum_Kanal_7_400Mhz.
und Datum_Temp.xls

bisher lese ich (zum Test) die Dateiname eines Kanals in eine
Spalte ein, (sortiere ihn zur Sicherheit) und las mir dann die
Messwert bei den ersten 10 Frequenzen daneben schreiben

@Zodan
Bitte beschreibe mal die Datenstruktur anhand eines konkreten Beispiels; vielleicht kommen dann auch Reinhard und ich in die Gänge:

Einen Ordner wählst Du aus mit der unten genannten API-Funktion - das habe ich bisher richtig verstanden?

…wie geht es dann weiter?
Was ist in diesem Ordner enthalten - Dateinamen - Endungen - Inhalte?

Nach welchen Kriterien willst du diese Daten dann einlesen?

Das wäre dann mal die erste Tranche - wenn das mal klappt können wir uns an die Inhalte machen.

Wie liegen die Daten in den einzelnen Dateien vor?
Welche der Daten benötigst Du?
Wie willst Du sie im Tabellenblatt anordnen, damit Du sie ausWerten kannst?


Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -

Hallo Rainer,

Ich nicht, aber Excel(2002) funktioniert problemlos bei

Sub ttt()
Dim a(14000, 250, 5) As String * 4
a(13500, 230, 2) = „huhu“
MsgBox a(13500, 230, 2)
End Sub
VB6 nicht?

Das hängt vom Recner ab. Auf ‚der großen Kiste‘ mit 2GB darf
das kein Problem sein, mein Schleppi mit 256MB wird aber dicke
Backen machen, fürchte ich, probier ich jetzt aber nicht. :smile:

Warum nicht, geht doch fix, zur Not mußte halt neu starten :smile:)

Den Speicherbedarf. Arr(1 to 1000) As Byte sind nur 1000
Bytes, As Double aber 8000 Bytes. Was passiert bei Variant?
ich habe keine Ahnung, wie viel Speicher dann reserviert wird,
aber genug um auch Strings zu verwalten, denke ich. Weil ich
wissen will, was passiert, gebe ich den Datentyp immer an,
wenn ich ihn weiß. Nur wenn der Quellcode eigentlich aus VBS
stammt (wie bei dem Code mit FSO) weiß ich den Datentyp
manchmal nicht und lasse ihn weg, wie bei VBS, denn VBS
versteht ja keine Datentypen.

Genau weiß ich es nicht auswendig, aber ich meine Variant (in Excel) hat 10 oder 16 Bytes zur Verwaltung plus die Datenbytes.
Ich glaube soviel wie Strings variabler Länge.
Wie üblich weiß ich nicht ob VB das so kennt, in Excel:
Dim x as String ’ variable Länge
Dim x as String * 5 ’ feste Länge, weniger Speicherbedarf,

aber das ist relativ, wenn du einen String fester Länge von 1000 Bytes hast, spielt es m.E. keine Rolle mehr ob du ihn fest oder variabel definierst, die 10 bzw. 16 Bytes mehr spielen dann keine Rolle relativ gesehen.

Ja, ich denke/dachte ich hab ein Array, a(5,10), mittels
copymemory kann ich das dann in b(10,5) wandeln.
Falsch gedacht?

Nicht getestet, aber ich denke schon, daß das geht. Nur was
kommt dabei heraus? Ich versuche das mal mit 2 X 3.

Wenn in Arr(2,3)
Arr(1,1)=1
Arr(1,2)=2
Arr(1,3)=3
Arr(2,1)=4
Arr(2,2)=5
Arr(2,3)=6
steht, steht im Speicher vermutlich 1,2,3,4,5,6.
Nach 3,2 konvertiert steht dann da
Arr(1,1)=1
Arr(1,2)=2
Arr(2,1)=3
Arr(2,2)=4
Arr(3,1)=5
Arr(3,2)=6
Kann man mit den Daten etwas anfangen? a(1,3) ist ja dann
nicht b(3,1) sondern b(2,1). Irgendwie stehe ich auf dem
Schlauch und verstehe den Sinn nicht.

Okay, wie erreiche ich daß aus a(1,3) b(3,1) wird?
Ohne Schleifen, denn das kriege ich ja hin, dauert halt.

Wenn ich alles richtig verstanden habe und dies durchführe:

Dim a(2,3) as byte

und dann a mit fortlaufenden Zahlen befülle so steht irgendwo im Speicher nacheinander:

1 '=a(0,0)
2 '=a(1,0)
3 '=a(2,0)
5 '=a(0,1)
6 '=a(1,1)
7 '=a(2,1)
8 '=a(0,2)
9 '=a(1,2)
10 '=a(2,2)
11 '=a(0,3)
12 '=a(1,3)
13 '=a(2,3)

so funktioniert Redim, sage ich redim a(2,2) so löscht es halt die letzten 3 Einträge, sage ich redim a(2,4) so wird halt noch
leer '=a(0,4)
leer '=a(1,4)
leer '=a(2,4)

im Speicher angehängt.

So, mit diesem Wissen muß es doch möglich sein, via Copymemory o.ä., da die Struktur, also die Bytefolgen so umzubasteln daß aus a(1,3) b(3,1) wird !?
Oder reicht da Copymemory nicht und es gibt keine andere API-Möglichkeit dies zu erreichen?

Gruß
Reinhard

Hallo Reinhard.

Warum nicht, geht doch fix, zur Not mußte halt neu starten

-))

weil ich faul bin. :smile:

Okay, wie erreiche ich daß aus a(1,3) b(3,1) wird?
Ohne Schleifen, denn das kriege ich ja hin, dauert halt.

Mit CopyMemory ohne Schleife gar nicht.

Wenn ich alles richtig verstanden habe und dies durchführe:

Dim a(2,3) as byte

und dann a mit fortlaufenden Zahlen befülle so steht irgendwo
im Speicher nacheinander:

1 '=a(0,0)
2 '=a(1,0)
3 '=a(2,0)
5 '=a(0,1)
6 '=a(1,1)
7 '=a(2,1)
8 '=a(0,2)
9 '=a(1,2)
10 '=a(2,2)
11 '=a(0,3)
12 '=a(1,3)
13 '=a(2,3)

so funktioniert Redim, sage ich redim a(2,2) so löscht es halt
die letzten 3 Einträge, sage ich redim a(2,4) so wird halt
noch
leer '=a(0,4)
leer '=a(1,4)
leer '=a(2,4)

im Speicher angehängt.

Leer sind sie dann alle, wenn Du nicht Preserve verwendest. Sonst ja, richtig.

So, mit diesem Wissen muß es doch möglich sein, via Copymemory
o.ä., da die Struktur, also die Bytefolgen so umzubasteln daß
aus a(1,3) b(3,1) wird !?

Nein. Im Speicher steht ja 1,2,3 … 12,13. Wenn Du den ganzen Block verschiebst, bleibt diese Reihenfolge erhalten. Du willst Bytes tauschen, das macht CopyMemory nicht. Dir bleiben nur die Schleifen.

Oder reicht da Copymemory nicht und es gibt keine andere
API-Möglichkeit dies zu erreichen?

Reicht nicht ist der falsche Ausdruck. Es tut etwas anderes, als Du gern hättest. Und nein, ich kenne keine API-Funktion die tut, was Du möchtest.

Gruß, Rainer

Ich weiß nicht was in deiner Beitragsfolge mit Thomas steht,
aber mit
DatName=format(DatumZeit,„yyyy.mm.dd hh:mm:ss“)
DatName=DatName & " Kanal" & kanalnummer
müßtest du es hinkriegen sortieren zu können.

ich versteh nicht ganz, was der code macht!
du weißt DatName eine format zu und dann hängst du noch Kanal und Nummer dran?
oder ist DatumZeit ne abfrage?

naja, in der ersten Version von nem Kollegen (die die 30min gebraucht hat und nur zu festen Frequenzen einlesen kann) ist es so gelöst
Do
pfad2 = pfad + datei
anzahl = anzahl + 1
Cells(anzahl, 2) = datei
Cells(anzahl, 1) = VBA.FileDateTime(pfad2)
datei = Dir()
Loop Until datei = „“

das funktioniert auch!
für
.Execute(SortBy:=msoSortByFileName, SortOrder:=msoSortOrderAscending)
gibt es leider nicht die option SortByDateTime!

Hi Thomas,

Doch, VB6 spielt da genau so mit. Man kann auch in VB6 Arrays
einfach als Variant deklarieren, Variablen gar nicht und sich
darauf verlassen, daß ein String in eine Zahl umgewandelt
wird, wenn das erforderlich ist. Das kann dann schon mal zu
Ergebnissen führen, die man nicht versteht.

Autsch! sage ich da nur.

Nur noch ein Beispiel dazu: :smile:

 Text1.Text = 3
 Text2.Text = 4
 a = Text1.Text
 b = Text2.Text
 Label1.Caption = a + b 'Anzeige: 34
 Label2.Caption = a \* b 'Anzeige: 12

Gruß, Rainer

Aufbau der Daten
Ok, dann versuch ich es nochmal anders zu erklären!
insgesamt besteht die (bis jetzt größte) Messreihe aus ~41000 Dateien

  • jeweils 8 gehören zu einer Uhrzeit (-> ein Datensatz)

  • die 7 Messwertdateien sind so aufgebaut (jede ist für ein anderes Objekt, sie sind also alle 7 unabhängig voneinander)

    • in Spalte A,C,E,G steht jeweils die Frequenz (das sind immer die gleichen 1000 Frequenzen von 300kHz bis 400Mhz in 400,1kHz Schritten)
    • in den Spalten B,D,F,H stehen jeweils die gemessenen Werte.
  • in der Umweltdatei steht in einer Zelle die Temperatur (wie gesagt, die kommt später dran!)

Ich dachte mir, das ich für jeden der 7 Messkanäle je 250Datein mach
(B,D,F,H)
und dann noch eine für die Temperatur
und noch eine in der die Dateinamen und die Zeiten abgelegt sind (die Zeitabstände sind leider nicht immer konstant, da es einige Ausfälle während der Messung gab. Deshalb wird das ganze dann in einem X-Y Diagramm dargestellt, damit der Abstand wieder stimmt und über die Ausfallzeit geglättet wird)

jede Datei würde dann ~5100 Zeilen haben und Daten 4, Temp 1 und Zeit 2 Spalten.

Die Daten von einer Messreihe und von einem Kanal sollen später angezeigt werden können, es ist weder notwendig mehrer Kanäle noch verschiedene Messreihen zu kombinieren!

Was ich noch klären muß ist, ob ich die Messdaten runden kann, da die Messung sicher nicht auf 15 Stellen genau ist 3-5 Stellen werden es wohl werden, aber das kann man ja später noch einfügen.

Grüezi Zondan

Ok, dann versuch ich es nochmal anders zu erklären!

…Du sagst hier dasselbe mit etwas anderen Worten - die Essenz kommt aber (zumindest für mich) nicht rüber…

insgesamt besteht die (bis jetzt größte) Messreihe aus ~41000
Dateien

Sind das Textdateien (Endung .TXT) oder Exceldateien (Endung .XLS)?
Das ist dann schon mal ein enormer Unterschied!

  • jeweils 8 gehören zu einer Uhrzeit (-> ein Datensatz)

Wie kommt das zum tragen?
Gibt es pro Uhrzeit einen Unterordner in dem den Du auswählst?
Oder unterscheiden sie dich durch die Uhrzeit im Dateinamen oder sonstwie?

Hier sind konkrete Angaben notwendig damit wir uns ein Test-Umfeld aufbauen können.

  • die 7 Messwertdateien sind so aufgebaut (jede ist für ein
    anderes Objekt, sie sind also alle 7 unabhängig voneinander)
    • in Spalte A,C,E,G steht jeweils die Frequenz (das sind
      immer die gleichen 1000 Frequenzen von 300kHz bis 400Mhz in
      400,1kHz Schritten)
    • in den Spalten B,D,F,H stehen jeweils die gemessenen
      Werte.

All das ist also in 7 der 8 Dateien zu finden.
Wo genau beginnen die Daten (Adresse der Zelle)?
Gibt es Lücken dazwischen oder sind sie zusammenhängend?

  • in der Umweltdatei steht in einer Zelle die Temperatur (wie
    gesagt, die kommt später dran!)

Das ist dann die 8. Datei wenn ich das richtig verstehe.

…vielleicht wäre es sinnvoll, Du würdest einen Teil der Datenstruktur als ZIP-File zusammenpacken und auf einen Webspace legen, dann hier den Link nennen - so kämen wir wohl am schnellsten zu brauchbaren Ergebnissen.


Mit freundlichen Grüssen

Thomas Ramel

  • MVP für MS-Excel -

ok, hab webspace gefunden :wink:
http://www.1webspace.biz/zondan/Messdaten.rar

Hallo Zodan,

für mich, ggfs. für andere auch besteht ein Datensatz z.B. aus einer Zeile in Excel.
Oder aber auch in einer Zeile aus einer auszulesenden Textdatei
Zur Not auch beinhaltet er auch alle Zeilen einer Exceldatei oder einer Textdatei, d.h. mein datensatz beinhaltet viele andere Datensätze.

Keinesfalls beinhaltet er irgendwelche andere Dateien, eine Datei ist kein Datensatz, ggfs. eine Ansammlung davon.

Zur Klarstellung, wenn du sagst, mein Datensatz umfasst 23 Dateien ist genauso verständlich wie wenn du sagst morgen ist Donnerstag und du gehst eh nicht hin :smile:

Ok, dann versuch ich es nochmal anders zu erklären!
insgesamt besteht die (bis jetzt größte) Messreihe aus ~41000
Dateien

  • jeweils 8 gehören zu einer Uhrzeit (-> ein Datensatz)

aargs, wieder was neues, jetzt taucht die Zahl 8 auf.

So langsam glaube ich das ist hier ein PisaCheck ob man noch geistig fit ist. :smile:

  • die 7 Messwertdateien sind so aufgebaut

aha, nicht 8, nur 7, schön:frowning:

Ich glaube, das bringt hier alles nix für die Zukunft, lese dir bitte das Nachfolgende mal durch, sonst werde ich in 10 Jahren nicht verstehen was du eigentlich willst.
(Text geklaut von peter hasserod)

Und wenn da gesagt wird, 95% sind unnötig, bedeutet das gleichzeitig, die letzten 5% sollten so formuliert sein daß sie verstandlich sind.

Ein guter Test, sage irgendeinem der weder Excel noch dein projekt kennt, was du in Excel erreichen willst mit deinen bisherigen Ausführungen, seine Fragen sind auch meine Fragen *nixfürungut*

Gruß
Reinhard

Eine Frage gut zu stellen, ist die halbe Miete der Antwort.

Zuerst löst du deine Frage aus deinem Projekt heraus und reduzierst diese auf dein eigentliches Problem.

Bsp.:
Du hast eine Lagerverwaltung, in denen du Tierfutter verwaltest. In dieser werden Berechnungen durchgeführt, wieviel wo was vorhanden ist.
In einem Tabellenblatt Artikelliste hast du in Spalte G die Artikelnummern stehen und in Spalte H die Futtermittelnamen.
Nun möchtest du in einer Tabelle Futterkontrolle bei Eingabe in der Zelle C114 einer Artikelnummer in Zelle D114 den Futternamen haben.

95 % sind überflüssig

Fast alles davon interessiert für das eigentliche Problem überhaupt nicht.
Keinen Menschen interessiert es, wie die Tabellenblätter heißen, wofür du das brauchst und überhaupt.

Dein losgelöstes Problem lautet: Wie finde ich zu der Nummer den Artikel und zwar in einem anderen Tabellenblatt.

Du machst nun ein allgemeinverständliches Beispiel und zwar mit Standardzellpositionen und Standardtabellennamen.
Alles andere läßt du weg, also:

Die Frage:

In Tabelle1 habe ich in Spalte A Nummern und in B daneben Bezeichnungen.
Nun möchte ich gerne in Tabelle2 in Zelle A1 die Nummer eingeben können und in Zelle B1 soll dann die Bezeichnung erscheinen.
Du siehst, ganz einfach und für jeden verständlich.

Und dann die Frage dazu:
Welche Formel muss ich in Zelle B1 von Tabelle2 eintragen,
damit, wenn ich in A1 z.B. die Nummer 2 schreibe, Katze herauskommt.

Schlussbemerkung:

Die Antwort, die du dann erhälst, musst du dann an dein Projekt anpassen.
Dies wird dir am Anfang etwas Mühe bereiten aber du lernst dabei auch die Lösung zu verstehen.

Und ganz nebenbei: Viele Lösungen wirst du schon selbst dir erarbeiten können, wenn du das Problem mal isoliert hast!

ok, hab webspace gefunden :wink:
http://www.1webspace.biz/zondan/Messdaten.rar

Hallo Zondan,

ich sehe im Archiv 3 Blöcke der Form __.xls mit den Ausprägungen Kanal_1_400MHz … Kanal_7_400Mhz sowie Temparatur_Kabel_. Die Uhrzeit eines Blockes unterscheiden sich immer um 6 Sekunden (solltest Du die Dateien selber erzeugen, würde ich Dir dringend raten die Uhrzeit bei der Erstellung der ersten Datei zu speichern und eine Form _ empfehlen. (Ist übrigens die 400MHz die Bezeichnung der kurz angesprochenen Messreihe?)

Dann habe ich mir die erste Datei (übrigens echte Excel-Tabellen) angesehen. Nach Deinen Aussagen sind Spalten A, C, E, G Frequenzen und B, D, F, H Messergebnisse zu den entsprechenden Frequenz. Ist das korrekt? Wird also innerhalb der Datei das Datum und Uhrzeit nicht wiederholt? Sind übrigens die Werte in A,C,E und G immer identisch?

Was ist dann Aufgabe von Deinem Programm? Du gibst eine Frequenz ein und möchtest den entsprechenden Messwertsatz haben? Was soll passieren wenn Du keinen exakten Wert hast?

MfG Georg V.

P.S.: Ich habe nicht den ganzen Thread gelesen :smile:, aber kommt das Thema nicht besser im Excel-Brett?

ich sehe im Archiv 3 Blöcke der Form __.xls mit
den Ausprägungen Kanal_1_400MHz …
Kanal_7_400Mhz sowie Temparatur_Kabel_.
Die Uhrzeit eines Blockes unterscheiden sich immer um 6 Sekunden

mein großer Datensatz besteht aus ca 4100 solchen Blöcken!
Da die Kanäle unabhängig voneinander ausgewertet werden (jeder Kanal mißt an einem anderen „Objekt“ und die haben nichts miteinander zu tun) ist der Zeitversatz nicht schlimm (eigentlich sind es 7 „Messreihen“ in einem Ordner, Klimakammern sind teuer und die Messungen dauern bis zu 30 Tage)

eine Form _ empfehlen.

ja, die hätte ich auch gern, aber leider kann ich die bisherigen Daten nicht ändern, aber für dieses Problem hab ich schon eine Lösung!

(Ist übrigens die 400MHz die Bezeichnung der kurz
angesprochenen Messreihe?)

Da ich ja jetzt über den Begriff „Messreihe“ aufgeklärt worden bin, sag ich mal, daß es zu 4100 Zeitpunkten je 7(Kanäle Objekten) x 4 x 1000(Frequenzen) Messwerte gibt.

Dann habe ich mir die erste Datei (übrigens echte
Excel-Tabellen) angesehen. Nach Deinen Aussagen sind Spalten
A, C, E, G Frequenzen und B, D, F, H Messergebnisse zu den
entsprechenden Frequenz. Ist das korrekt? Wird also innerhalb
der Datei das Datum und Uhrzeit nicht wiederholt? Sind
übrigens die Werte in A,C,E und G immer identisch?

ja, die Werte in A C E G sind in jeder Datei die gleichen!
die Uhrzeit steht nicht in der Datei, aber da hab ich ne Möglichkeit die auszulesen.

Was ist dann Aufgabe von Deinem Programm? Du gibst eine
Frequenz ein und möchtest den entsprechenden Messwertsatz
haben? Was soll passieren wenn Du keinen exakten Wert hast?

Eingeben nicht, wollte sie später eher mit ner ListBox (heißt glaub ich so) auswählbar machen genau wie Kanal, die Messwertspalte usw.

nicht besser im Excel-Brett?

naja, die Daten sind leider nicht so angeordnet wie ich sie brauch und das auslesen dauert leider ewig.
Also dachte ich an ein „umschreiben“ der Daten in die Form:
zu 250 Frequenzen (ich brauch nur jede 4te) und den 7Kanälen je eine Datei.
Bis jetzt bin ich so weit, daß ich die Daten von einem Kanal in eine binary Datei geschrieben hab, morgen kümmere ich mich dann mal um das auslesen!

hier auch nochmal ein Dank an alle die mir hier geholfen haben, ich werde versuchen das nächste mal meine Frage vorher genauer und einfacher verständlich zu formulieren. Habe jetzt selber gemerkt, daß die Formulierung nicht sehr gut wahr! Zumindest hab ich jetzt das vbarchiv kennen gelernt und das hilft mir schon viel weiter! (und spart euch nerven) Falls mir jetzt noch jemand was schreiben will, kann er das auch gern per Mail machen!

OT anzahl geöffn. Mappen in Excel, Put Msgbox
Hallo Rainer,

Ebenfalls nicht getestet, aber der Debugger wid sicher bei
Zeilen_in_Exceltabelle rummotzen :smile:

Ja logisch, das ist ja auch Pseudocode. :smile: Wie Du von Excel
die Anzahl der gefüllten zeilen bekommst, weiß ich doch nicht,
das war nur ein Hinweis für Dich, was da hin gehört.

Axo, manchmal sehe ich die dicke Kartoffel nicht :smile:)

Mit Sicherheit richtig, aber schau mal meine Frage:

@Zodan, willst du eigentlich als Endergebnis Textfiles für
jede Frequenz, oder gleich Exceldateien?

Die frage ist natürlich berechtigt, Zodan schreibt ja, daß er
Textfiles nur in Betracht gezogen hat, weiß er nicht weiß, wie
man Excel-Files schreibt.

Ja, aber ich wurde in dem Punkt unsicher weil er von FSO und vbarchiv usw. spricht.
Ich habe jetzt eine reine Excellösung, die direkt alle Dateien eines Ordners nacheinander öffnet, dann pro Frequenz die entsprechende Zeile in die entsprechende Frequensdatei (gibt 250 Stück davon) schreibt.
Aber Zodan macht da wohl jetzt FSO, naja, warte ich mal ab.

250 Frequenzen, eine Tabelle zum lesen … kannst Du in Excel
251 Tabellenblätter gleichzeitig öffnen? … :smile:

Ja, ist nur vom Speicher und den Systemressourcen abhängig, letztlich nur vom verfügbaren Speicher, erschöpfte Sytemressourcen sind nur Belastung für die Nerven wenn man 1000 Arbeitsmappen beim Aufbauen zellenweise zuschauen kann :smile: Dauert dann halt lange.
Diese Info gilt für XL97-XL2003.

Da dieser Thraed sowieso unübersichtlich geworden ist und nur noch wenige Unentwegte hier mitlesen antworte ich mal hier , bzw. setze hier unsre Beitragsfolge fort.

Ich weiß jetzt warum ich immer eine Satzlänge hatte, egal ob ich 2,3,4 Messwerte hatte bei
Type Satz
Frequenz as Single
Messwerte(4)
End Type

Wenn ich mit Binaray eine datei öffne, die es nicht gibt, wird sie angelegt. Schreibe ich einen Satz rein, so hat sie mit dem obigen Type 24 Bytes.
Nun habe ich die 4 geändert, auf 3,2 o.ä. und sie wieder Binary geöffnet, dann wurde zwar brav der Satz reingeschrieben, aber die Dateigröße blieb gleich groß.
Kill-Befehl vor dem Öffnen und alles klappt so wie von dir gesagt in Richtung Byteanzahl.

Beim Nachprüfen irritiert mich dieser Put-Befehl.(Annahme Satz hat 20 bytes) und Dim f(a) as Satz gilt,so ergibt

put #1,f() 20 Bytes Dateigröße
put #1,1,f() 20 Bytes Dateigröße
put #1,2,f() 21 Bytes Dateigröße
put #1,100,f() 120 Bytes Dateigröße
(können auch +/- 1 sein, schreibs grad auswendig)

also pro Datensatznummer kommt ein Byte dazu, wozu, was ist das für ein Byte, die Datensatznummer kanns nicht sein, denn bei
put #1,1000,f() kommt 1020 Bytes Dateigröße raus!?

Gibt es in VB einen MemoryFree- bzw. auch MemoryUsed-Befehl?
In Excel-Vba soll MemoryFree angeblich laut Hilfe den Speicherplatz in Byte angeben den Excel noch nutzen könnte, MemoryUsed den byteplatz den Ecel schon belegt.
Das kann aber so nicht stimmen oder ich übersehe etwas bei Redim.

Sub nn()
Dim c As Double
MsgBox Application.MemoryUsed 'je nach Rechner unterschiedlich
MsgBox Application.MemoryFree 'bei 2 Rechnern immer 1048675
ReDim a(Application.MemoryFree) As String * 10
a(1) = „1234567890“
MsgBox UBound(a)
MsgBox Application.MemoryFree
MsgBox Application.MemoryUsed
Dim b
End Sub

Die ausgegebenen Werte sind immer die gleichen, egal ob zwischendurch a dimensioniert wird. Da ich ja a(1) mit Werten belege, muß das m.E. in einem Speicherbereich geschehen, der nicht von Memoryused überwacht wird *rätsel*

Hat VB eine MsgBox-Anweisung bzw. kannst du dir hierauf einen Reim machen:

Sub nn2()
Dim c As Double
c = 120000000 'klappt problemlos
MsgBox c
c = 10 * 12000
MsgBox c ’ ergibt Laufzeitfehler 6, Überlauf !?
End Sub

Nachfolgend meine ersten Gehschritte mit CopyMemory. Du hattest Recht, mein erster Ansatz um Arrays umzustellen war von der Logik her falsch. Aber um Arrays zu manipieren ist Copymemory äußerst brauchbar.

Und dein Tipp Copymemory erstmal nur mit String-Variablen zu testen war Gold wert, erst dadurch kam ich soweit daß das überhaupt mal klappte.

Ich muß nur noch herausfinden, warum „ByVal“ da so wichtig ist. Wenn man es fälschlicherweise wegläßt oder fälschlicherweise benutzt, kommt entweder der Debugger, oder man muß Excel neu starten da es im Bruchteil von Sekunden verschwunden ist.
Aber kann man ja auch benutzen, warum langwierig programmieren wie man Excel beendet ohne zu speichern, geht so recht easy und sehr schnell *gg*

Wie an den Codes ersichtlich, muß das wohl an den Variablentypen irgendwie liegen, aber das muß ich noch genauer austesten.

Übrigens, es zwang dich keiner bis hierher zu lesen und gar gleich gar noch mit diesen von mir aufgeführten Herausforderungen rumzutesten *lächel*

Auch in diesem Sinne Danke ^ Gruß
Reinhard

Sub ff()
Dim a(5, 3) As Single, b As Single
Call CopyMemory(ByVal b, ByVal a(2, 1), 4)
MsgBox b
End Sub
'
Sub ff2()
Dim a(5, 3) As Satz, b As Satz
Call CopyMemory(b, a(2, 1), 16)
MsgBox b.Frequenz
MsgBox b.Messwert(1)
End Sub
'
Sub ff3()
Dim a(5, 3) As Satz, b(3) As Satz, N, nn
For N = 0 To 3
 Call CopyMemory(b(N), a(2, N), 10)
 MsgBox b(N).Frequenz
 For nn = 0 To 3
 MsgBox b(N).Messwert(1)
 Next nn
Next N
End Sub

Hallo Reinhard,

Ich habe jetzt eine reine Excellösung, die direkt alle Dateien
eines Ordners nacheinander öffnet, dann pro Frequenz die
entsprechende Zeile in die entsprechende Frequensdatei (gibt
250 Stück davon) schreibt.
Aber Zodan macht da wohl jetzt FSO, naja, warte ich mal ab.

Aber nur, weil er Deine reine Excel-Lösung nicht kennt, denke ich. :smile:
Wenn es mein Problem wäre, würde ich Deine Lösung bevorzugen.

Da dieser Thraed sowieso unübersichtlich geworden ist und nur
noch wenige Unentwegte hier mitlesen antworte ich mal hier ,
bzw. setze hier unsre Beitragsfolge fort.

Ja, das ist doch OK.

Beim Nachprüfen irritiert mich dieser Put-Befehl.(Annahme Satz
hat 20 bytes) und Dim f(a) as Satz gilt,so ergibt

Die Datei wird fast wie eine sequentielle Datenbank behandelt, die die Datei-Feldbeschreibung nicht selbst enthält.

put #1,f() 20 Bytes Dateigröße

Pack die 20 Bytes in die Datei.

put #1,1,f() 20 Bytes Dateigröße

Pack die 20 Bytes in die Datei, fang bei ersten Datensatz an.

put #1,2,f() 21 Bytes Dateigröße
put #1,100,f() 120 Bytes Dateigröße

Pack die 20 Bytes in die Datei, fang beim 100. Datensatz an.
Die Datensätze davor werden leer angelegt.

also pro Datensatznummer kommt ein Byte dazu, wozu, was ist
das für ein Byte, die Datensatznummer kanns nicht sein, denn
bei
put #1,1000,f() kommt 1020 Bytes Dateigröße raus!?

Ich habe nicht nachgesehen, es wird eine &h0 sein, ein leerer Datensatz eben.

Gibt es in VB einen MemoryFree- bzw. auch MemoryUsed-Befehl?

Ich habe nichts entsprechendes gefunden. VB nutzt aber den speicher des Systems, das kann man dann über die API finden. Excel hat IMO eine eigene Speicherverwaltung kann also nicht den gesamten Speicher von Windows nutzen.

In Excel-Vba soll MemoryFree angeblich laut Hilfe den
Speicherplatz in Byte angeben den Excel noch nutzen könnte,
MemoryUsed den byteplatz den Ecel schon belegt.
Das kann aber so nicht stimmen oder ich übersehe etwas bei
Redim.

Sub nn()
Dim c As Double
MsgBox Application.MemoryUsed 'je nach Rechner unterschiedlich
MsgBox Application.MemoryFree 'bei 2 Rechnern immer 1048675
ReDim a(Application.MemoryFree) As String * 10
a(1) = „1234567890“
MsgBox UBound(a)
MsgBox Application.MemoryFree
MsgBox Application.MemoryUsed
Dim b
End Sub

Das Dim a() steht aber wo anders, oder?

Die ausgegebenen Werte sind immer die gleichen, egal ob
zwischendurch a dimensioniert wird. Da ich ja a(1) mit Werten
belege, muß das m.E. in einem Speicherbereich geschehen, der
nicht von Memoryused überwacht wird *rätsel*

Keine Ahnung, was Excel da treibt.

Hat VB eine MsgBox-Anweisung

Ja.

bzw. kannst du dir hierauf einen Reim machen:

Sub nn2()
Dim c As Double
c = 120000000 'klappt problemlos
MsgBox c
c = 10 * 12000
MsgBox c ’ ergibt Laufzeitfehler 6, Überlauf !?
End Sub

Der fehler tritt schon in
c = 10 * 12000
auf. Keine Ahnung warum. Aber
c = 10& * 12000&
geht.

Nachfolgend meine ersten Gehschritte mit CopyMemory. Du
hattest Recht, mein erster Ansatz um Arrays umzustellen war
von der Logik her falsch. Aber um Arrays zu manipieren ist
Copymemory äußerst brauchbar.

Und dein Tipp Copymemory erstmal nur mit String-Variablen zu
testen war Gold wert, erst dadurch kam ich soweit daß das
überhaupt mal klappte.

Ich muß nur noch herausfinden, warum „ByVal“ da so wichtig
ist. Wenn man es fälschlicherweise wegläßt oder
fälschlicherweise benutzt, kommt entweder der Debugger, oder
man muß Excel neu starten da es im Bruchteil von Sekunden
verschwunden ist.

ByVal - Das Argument wird als Wert übergeben.
ByRef - Das Argument wird als Referenz übergeben.

An die API muss der Inhalt, der Wert des Zeigers übergeben werden, denn das ist die Speicheradresse an der der Inhalt steht, den Du bearbeiten willst. Lässt Du ByVal weg, wird ‚default‘, also ByRef übergeben, das ist die Adresse des Zeigers. Dann bearbeitest du den Zeiger selbst, nicht den Speicher auf den der Zeiger zeigt. Das verkraftet Windows nicht und schließt die Anwendung.

Aber kann man ja auch benutzen, warum langwierig programmieren
wie man Excel beendet ohne zu speichern, geht so recht easy
und sehr schnell *gg*

Wie an den Codes ersichtlich, muß das wohl an den
Variablentypen irgendwie liegen, aber das muß ich noch genauer
austesten.

Übrigens, es zwang dich keiner bis hierher zu lesen und gar
gleich gar noch mit diesen von mir aufgeführten
Herausforderungen rumzutesten *lächel*

*gg*

Sub ff()
Dim a(5, 3) As Single, b As Single
Call CopyMemory(ByVal b, ByVal a(2, 1), 4)
MsgBox b
End Sub

Bei b fehlt ‚VarPtr‘, Du musst den Pointer übergeben, sonst ist das keine Adresse im Speicher. Vom Array übergbst Du mit ByVal den Inhalt des Arrays, statt dem Verweis, der die Adresse enthält.

CopyMemory ByVal VarPtr(b), a(2, 1), 4

Das sollte besser klappen, nicht getestet, nur hier getippt. :smile:

Sub ff2()
Dim a(5, 3) As Satz, b As Satz
Call CopyMemory(b, a(2, 1), 16)
MsgBox b.Frequenz
MsgBox b.Messwert(1)
End Sub

Da fehlt wohl wieder VariablenPointer.

Sub ff3()
Dim a(5, 3) As Satz, b(3) As Satz, N, nn
For N = 0 To 3
Call CopyMemory(b(N), a(2, N), 10)
MsgBox b(N).Frequenz
For nn = 0 To 3
MsgBox b(N).Messwert(1)

Drei mal den selben Wert? :smile:

Next nn
Next N
End Sub

Gruß, Rainer

Hallo Rainer,

Ich habe jetzt eine reine Excellösung, die direkt alle Dateien
eines Ordners nacheinander öffnet, dann pro Frequenz die
entsprechende Zeile in die entsprechende Frequensdatei (gibt
250 Stück davon) schreibt.
Aber Zodan macht da wohl jetzt FSO, naja, warte ich mal ab.

Aber nur, weil er Deine reine Excel-Lösung nicht kennt, denke
ich. :smile:
Wenn es mein Problem wäre, würde ich Deine Lösung bevorzugen.

dankeschön :smile:, ich habe im Anhang den Code gepostet.

Ich habe 100 xls-Dateien mit Zufallswerten angelegt, die jeweils 250 Zeilen a 5 Spalten haben.

Das Auslesen dieser 100 Dateien dauert pro Datei 0,3 Sek, danach habe ich alle Daten in einer Variablen, nun kommt der zweite Teil, Erzeugen der 250 Frequenzdateien und frequenzabhängiges Befüllen mit dem Inhalt der Variablen, da komme ich auf 0,7 Sek pro eine der 250 Dateien.

Wie sich der zweite Wert bei 50.000 Dateien erhöht kann ich nicht abschätzen.

Und die Variable, ich nenne sie mal „Bereich“ ist ein Array, oder auch keins, Ansichtssache, vielleicht weiß Thomas genaueres wie man sie bennent.
Unabhängig von Option Base 1 o.ä. hat sie keinen Index 0,0 wie normale Arrays.
Ich sage im Code einfach, nachdem ich die Datei Nummer x geöffnet habe: („Bereich“ habe ich schlicht mit „ReDim Bereich(AnzahlDateien)“ dimensioniert, ohne Klammern für die zeilen/Spaltendimensionen)

Bereich(x)=Range(„A1:E250“)

Dann kann ich die Datei schließen.
Will ich wissen, was in D3 einer beliebigen gelesenen Datei steht/stand, sage ich:

Msgbox Bereich(x)(3,4)

in dieser für dich vielleicht ungewohnten Syntax.

Ich habe nicht nachgesehen, es wird eine &h0 sein, ein leerer
Datensatz eben.

*schäm* jepp das macht großen Sinn, schreibe ich in eine leere Datei, einen leeren 1000ten Datensatz rein, so wird in die Datei halt vorher 999 mal ein Nullstring eingefügt. *seufz* hätte ich drauf komen können:frowning:

Gibt es in VB einen MemoryFree- bzw. auch MemoryUsed-Befehl?

Ich habe nichts entsprechendes gefunden. VB nutzt aber den
speicher des Systems, das kann man dann über die API finden.
Excel hat IMO eine eigene Speicherverwaltung kann also nicht
den gesamten Speicher von Windows nutzen.

In Excel-Vba soll MemoryFree angeblich laut Hilfe den
Speicherplatz in Byte angeben den Excel noch nutzen könnte,
MemoryUsed den byteplatz den Ecel schon belegt.
Das kann aber so nicht stimmen oder ich übersehe etwas bei
Redim.

Sub nn()
Dim c As Double
MsgBox Application.MemoryUsed 'je nach Rechner unterschiedlich
MsgBox Application.MemoryFree 'bei 2 Rechnern immer 1048675
ReDim a(Application.MemoryFree) As String * 10
a(1) = „1234567890“
MsgBox UBound(a)
MsgBox Application.MemoryFree
MsgBox Application.MemoryUsed
Dim b
End Sub

Das Dim a() steht aber wo anders, oder?

Nein, ReDim bei Excel bedingt kein vorheriges Dim in Excel.
Aber auch ein vorheriges Dim a(1000000) würde nichts bringen *schätz*

Und zu Redim, in Excel klappt das so problemlos:

Sub Test()
ReDim a(10)
a(5) = „7“
MsgBox a(5)
End Sub

Die ausgegebenen Werte sind immer die gleichen, egal ob
zwischendurch a dimensioniert wird. Da ich ja a(1) mit Werten
belege, muß das m.E. in einem Speicherbereich geschehen, der
nicht von Memoryused überwacht wird *rätsel*

Keine Ahnung, was Excel da treibt.

Na, da sind wir schon 2 :smile:
Aber grad in so Fällen wie hier mit Zodan mit zigtausend Dateien usw. ist es doch unabdingbar, grad wegen Dim, Redim, zu wissen wieviel Platz man noch im jeweiligen Arbeitsspeicher hat.
Eine Lösung riecht sehr nach API, mal schauen.

Und mag ja sein, daß ein einfaches Dim,Redim vielleicht nur schaut ob genug Platz da ist und noch gar keinen reserviert, aber mit a(1) = „1234567890“ belege ich definitiv Platz und da beide Befehle Bytesgenau sein sollen, müßten sie die 10 fehlenden Bytes anzeigen.

Hat VB eine MsgBox-Anweisung

Ja.

bzw. kannst du dir hierauf einen Reim machen:
Sub nn2()
Dim c As Double
c = 120000000 'klappt problemlos
MsgBox c
c = 10 * 12000
MsgBox c ’ ergibt Laufzeitfehler 6, Überlauf !?
End Sub

Der fehler tritt schon in
c = 10 * 12000 auf.

Aargs, du hast Recht. Noch ein Eintrag in meine Todoliste:„Warum kam der Debugger bei mir erst bei der MsgBox“ *gg*

Keine Ahnung warum. Aber
c = 10& * 12000&
geht.

Gut, ein workaround. D.h. auch in VB kann MsgBox zwar 120000000 und noch größer anzeigen, aber 10 * 12000 nicht.

Nachfolgend meine ersten Gehschritte mit CopyMemory. Du
hattest Recht, mein erster Ansatz um Arrays umzustellen war
von der Logik her falsch. Aber um Arrays zu manipieren ist
Copymemory äußerst brauchbar.

Und dein Tipp Copymemory erstmal nur mit String-Variablen zu
testen war Gold wert, erst dadurch kam ich soweit daß das
überhaupt mal klappte.

Ich muß nur noch herausfinden, warum „ByVal“ da so wichtig
ist. Wenn man es fälschlicherweise wegläßt oder
fälschlicherweise benutzt, kommt entweder der Debugger, oder
man muß Excel neu starten da es im Bruchteil von Sekunden
verschwunden ist.

ByVal - Das Argument wird als Wert übergeben.
ByRef - Das Argument wird als Referenz übergeben.

Ja, das ist mir bekannt, und ByRef ist in Excel Voreinstellung wenn nichts angegeben wird, grad bei CopyMemory sah ich das ich überhaupt nicht weiß wann ich was benutzen muß.

An die API muss der Inhalt, der Wert des Zeigers übergeben
werden, denn das ist die Speicheradresse an der der Inhalt
steht, den Du bearbeiten willst. Lässt Du ByVal weg, wird
‚default‘, also ByRef übergeben, das ist die Adresse des
Zeigers. Dann bearbeitest du den Zeiger selbst, nicht den
Speicher auf den der Zeiger zeigt. Das verkraftet Windows
nicht und schließt die Anwendung.

Schau mal bitte genauer die Codes an, da wo ByVal steht verlangte es Excel, da wo es nicht steht, verbat sich Excel daß es dort steht. Das verstehe ich nicht, bzw. die Logik dahinter.

Ich hatte deinen VarPtr als Variablennamen angesehen und deshalb in deinem letzten Code nicht so beachtet.
Wieder was für die Todoliste: „Varptr benutzen, schauen ob Excel den kennt“

*hmmh* Grundsätzlich, so wie die drei Codes da stehen funktionieren sie problemlos, auch ohne varptr.
Mir gings ja darum herauszufinden warum sie nicht mehr klappen wenn ich mal ein vorhandenes Byval lösche, bzw. eins mal dazufüge, weil dann laufen sie nicht mehr.

Sub ff()
Dim a(5, 3) As Single, b As Single
Call CopyMemory(ByVal b, ByVal a(2, 1), 4)
MsgBox b
End Sub

Bei b fehlt ‚VarPtr‘, Du musst den Pointer übergeben, sonst
ist das keine Adresse im Speicher. Vom Array übergbst Du mit
ByVal den Inhalt des Arrays, statt dem Verweis, der die
Adresse enthält.

CopyMemory ByVal VarPtr(b), a(2, 1), 4

Das sollte besser klappen, nicht getestet, nur hier getippt.

-)

Sub ff2()
Dim a(5, 3) As Satz, b As Satz
Call CopyMemory(b, a(2, 1), 16)
MsgBox b.Frequenz
MsgBox b.Messwert(1)
End Sub

Da fehlt wohl wieder VariablenPointer.

Sub ff3()
Dim a(5, 3) As Satz, b(3) As Satz, N, nn
For N = 0 To 3
Call CopyMemory(b(N), a(2, N), 10)
MsgBox b(N).Frequenz
For nn = 0 To 3
MsgBox b(N).Messwert(1)

Drei mal den selben Wert? :smile:

Next nn
Next N
End Sub

Danke ^ Gruß
Reinhard

Option Explicit
Private Bereich()
'
Sub Test()
Range("A1") = Now()
Call Einlesen("C:\FreqTest2")
Range("A2") = Now()
Call Schreiben("C:\FreqTest2")
Range("A3") = Now()
End Sub
'
Sub Schreiben(Pfad As String)
Dim bytN, Merker As Byte, lngB As Long
Application.ScreenUpdating = False
Merker = Application.SheetsInNewWorkbook
Application.SheetsInNewWorkbook = 1
Application.DisplayAlerts = False
Workbooks.Add
For bytN = 1 To 250
 Application.StatusBar = "Schreibe Datei " & bytN & " / " & 250
 For lngB = 1 To UBound(Bereich)
 Cells(lngB, 1) = Bereich(lngB)(bytN, 1)
 Cells(lngB, 2) = Bereich(lngB)(bytN, 2)
 Cells(lngB, 3) = Bereich(lngB)(bytN, 3)
 Cells(lngB, 4) = Bereich(lngB)(bytN, 4)
 Cells(lngB, 5) = Bereich(lngB)(bytN, 5)
 Next lngB
 ActiveWorkbook.SaveAs FileName:=Pfad & "\Freq" & Format(bytN, "000")
Next bytN
ActiveWorkbook.Close
Application.StatusBar = ""
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.SheetsInNewWorkbook = Merker
End Sub
'
Sub Einlesen(Pfad As String)
Dim N
On Error GoTo Fehler
Application.ScreenUpdating = False
With Application.FileSearch
 .NewSearch
 .LookIn = Pfad
 .SearchSubFolders = False
 .FileType = msoFileTypeExcelWorkbooks
 .Execute
 ReDim Bereich(.FoundFiles.Count)
 For N = 1 To .FoundFiles.Count
 Application.StatusBar = "Lese Datei " & N & " / " & .FoundFiles.Count
 Workbooks.Open .FoundFiles(N)
 Bereich(N) = Range("A1:E250")
 ActiveWorkbook.Close savechanges:=False
 Next N
End With
Fehler:
 If Err.Number 0 Then MsgBox "Es tat der Fehler " & Err.Number & " auf" & Chr(13) \_
 & Err.Description
 Application.StatusBar = ""
 Application.ScreenUpdating = True
End Sub
1 Like