PDA

Vollständige Version anzeigen : "Nicht genügend Speicher" -> suchen - ersetzten


reca
31.07.2012, 11:24
Hallo Forum,

ich habe ein Problem unswar:

Ich benutze den Folgenden Code um den VBA-CODE zu ändern. Also ich habe es in einer Schleife verbaut, wo er sucht und ersetzt.



For Each v In ThisWorkbook.VBProject.VBComponents
Set m = v.CodeModule
If m.CountOfLines > 0 Then
VBACode = m.Lines(1, m.CountOfLines)
VBACode = Replace(VBACode, SuchString, ErsatzString)

m.DeleteLines 1, m.CountOfLines
m.InsertLines 1, VBACode
End If
Next v


Ich habe 20 Tabellen, welches im Hintergrund Codes hat. Weil es Probleme ausspuckt habe ich immer tabellenweise den Code laufen lassen. Nachdem ich Tabelle10 (Manchmal geht kann ich auch Tabelle11) auch durchlaufen lasse kommt diese Meldung

Fehler beim Kompilieren:
Nicht genügend Speicher

Ich gehe davon aus, dass der Fehler VBA seitig ist, weil ich in der Zeit nichts mit den Tabellen zu tun habe.

Damit ihr ein Gefühl habt hier einige Größen:
Excel Datei -> 4mb
gesuchte und ersetzte Wörter -> ca. 1000


Ich bedanke mich im Voraus

grus
reca

Hasso
31.07.2012, 12:30
Hallo reca,

versuch's mal so:
For Each v In ThisWorkbook.VBProject.VBComponents
Set m = v.CodeModule
If m.CountOfLines > 0 Then
VBACode = m.Lines(1, m.CountOfLines)
VBACode = Replace(VBACode, SuchString, ErsatzString)

m.DeleteLines 1, m.CountOfLines
m.InsertLines 1, VBACode
End If
Set m = Nothing
Next v

reca
31.07.2012, 12:46
Hallo Hasso,

diese habe ich probiert aber leider kein Erfolg.
Es wird übrigens in 3 unterschiedlichen Modulen immer die gleiche stellen rot.

Hier eines davon:


Private Declare Function RegEnumValue Lib "advapi32.dll" Alias _
"RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, _
ByVal lpValueName As String, lpcbValueName As Long, ByVal _
lpReserved As Long, lpType As Long, lpData As Byte, _
lpcbData As Long) As Long

Private Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" (ByVal hKey As Long, _
ByVal lpSubKey As String, ByVal ulOptions As Long, _
ByVal samDesired As Long, phkResult As Long) As Long

Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long



den Zusammenhang verstehe ich auch nicht. Wenn du den Zusammenhang vielleicht nachvollziehen kannst, könnte auch sehr hilfreich sein.

gruß

ebs17
31.07.2012, 13:00
Was bedeutet ...
gesuchte und ersetzte Wörter -> ca. 1000

Wenn man laufend (also per Code statt einmalig von Hand) Code umschreibt, hat man entweder einen sehr ungeschickten Weg gewählt (hier liegt die hohe Wahrscheinlichkeit) oder einen sehr ungewöhnlichen Fall, der zu erläutern wäre.

Mit Variablen, Parametern u.ä. kann man statische Codes sehr vielfältig nutzen.

EarlFred
31.07.2012, 13:10
Hallo reca,

Weil es Probleme ausspuckt
1. Was ist "es"?
2. Was für Probleme spuckt "es" aus?
3. Wann treten diese Probleme auf?
4. Wo treten diese Probleme auf?

For Each v In ThisWorkbook.VBProject.VBComponents
Du änderst ALLE Codemodule der Mappe, aus der heraus der Code ausgeführt wird. Möglicherweise wird also auch gerade der Code damit geändert, der ausgeführt wird, um die Änderung vorzunehmen. Dabei wird auch die Variable SuchString, der Du ja irgendwo (im gleichen Code?) einen Wert zuweist, beim nächsten Durchlauf Ihres Wertes "enthoben" (Replace), was dazu führen kann, dass dieser Wert wiederum in den weiteren Modulen nicht gefunden wird - je nachdem, wie Du es programmiert hast.
Mindestens das Codemodul, in der der Code zum Ändern läuft, sollte also ausgelassen werden.
Dann hast Du noch APIs eingebunden - wie diese im Einzelfall auf codegesteuerte Codeänderung reagieren (wird die Deklaration der API dabei etwa auch geändert?), kann man nur erraten - vor allem, wenn man den Code nicht insgesamt kennt.

Eberhards Vermutung deckt sich mit meinem Bauchgefühl. Das Vorgehen ist dringend auf Sinnhaftigkeit zu hinterfragen.
Und wenn es um Updates von Code geht, würde ich ein Add-In allemal vorziehen - das ist einfach geschrieben, eingebunden und bei Änderungen als ganzes schnell ersetzt.

Grüße
EarlFred

reca
31.07.2012, 13:43
Hallo,

erstmal danke an alle Hilfestellungen,


Ich habe keine andere Wahl gehabt als die Methode auszuführen die ich gepostet habe. Weil ich über 1000 befehle in der Form: Tabellexy.Range(An:Bn) habe, die immer eine Stelle des jeweiligen Tabellenblattes Ändern/schreiben.

alle müssen mit folgenden ersetzt werden: Tabellexy.Range(funktio(1,2)). Sinn der Sache ist, es sollen keine direkten Zugriffe sondern indirekte Zugriffe mit Hilfe von Indexen folgen. Alle Indexen sind in einem Tabellenblatt hinterlegt.


Und das Problem ist halt wie oben erwähnt:
Fehler beim Kompilieren:
Nicht genügend Speicher


Ich habe jetzt versucht die Fehlerstellen auszukommentieren und den Code einfach durchziehen, biss alle ersetzt wurden. Dann habe ich eine alte/nicht ersetzte Version genommen und alle Codes der ersetzten Version hinein kopiert.
Und jetzt gibt es keine Probleme mehr, Verstehe ich nicht.

Aber warum ich solch ein Problem bekommen habe würde ich trotzdem wissen, weil ich die gleiche Operation in einem anderen Projekt auch machen werden.

Danke nochmals

EarlFred
31.07.2012, 14:00
Hallo reca,

Zugriffe auf Bereiche müssen nicht hartcodiert werden! Auch hier kann man - nein: man muss, wenn man sinnvoll programmieren will - mit Variablen arbeiten.

Ich kann Dir nur raten, Dich dahingehend kundig zu machen, bevor Du das nächste Projekt genauso kompliziert angehst. Das sind absolute Grundlagen, wenn man VBA für Excel programmiert, daran kommst Du nicht vorbei. Konstenlose Lektüre gibt's hierzu zuhauf im Internet. Eine schnelle Fundestelle z. B. hier:
http://www.online-excel.de/excel/singsel_vba.php?f=47

Grüße
EarlFred

ebs17
31.07.2012, 14:07
weil ich die gleiche Operation in einem anderen Projekt auch machen werden
Passend zur Handtasche brauchst Du sicher auch jedes Mal ein anderes Auto?

Tabellexy.Range(An:Bn)
' ==>
Worksheets(Tabellenname).Range(Cells(a, b), Cells(x, y))
Mit drei bis fünf Variablen kannst Du jeden Bereich in einer Arbeitsmappe abdecken.

vbanewcomer
01.08.2012, 07:59
ich hatte mal ein Proble nahe an deinem dran.
Da ich über mehrere Arbeitsblätter gearbeitet hatte lag die Lösung schlicht darin, alle Arbeitsblätter mit dem gleichen Zoomfaktor auszustatten.

Bevor ich also meinen Code ausführte stellte ich sicher, dass alle Arbeitsblätter die mittels des Gleichen bearbeitet wurden, den Zoomfaktor 100% hatten.
Seit dem hatte ich nie wieder Meldungen, dass zu wenig Arbeitsspeicher wäre.

Gruß VBANewcomer

reca
02.08.2012, 08:40
Hallo,

@ebs17:"Mit drei bis fünf Variablen kannst Du jeden Bereich in einer Arbeitsmappe abdecken."

@EarlFred: Zugriffe auf Bereiche müssen nicht hartcodiert werden! Auch hier kann man - nein: man muss, wenn man sinnvoll programmieren will - mit Variablen arbeiten.

Ich muss an der Stelle sagen, dass ich kein VBA-Anfänger bin. Ich bin mir schon bewusst, dass man mit Variablen arbeiten muss. Aber hier ist es halt nicht der Fall wo man einfach mit 4 Variablen alles mögliche ansprechen kann. Es sind in der Tat ca. 250 - 300 fixe Zellen, die z.B. in Form Range("A2:B2") Angesprochen werden. Ich versuche jetzt alles in Form Range(funktion(....)) zu bringen damit alles "Variablisiert" wird. Also in diesem Fall 250-300 stück.
Darum auch die suchfunktion.

Dieser Code habe ich im Netz gefunden und angewendet. Ich weis halt nicht warum gerade dieser Code so ein Fehler verursacht.

For Each v In ThisWorkbook.VBProject.VBComponents
Set m = v.CodeModule
If m.CountOfLines > 0 Then
VBACode = m.Lines(1, m.CountOfLines)
VBACode = Replace(VBACode, SuchString, ErsatzString)

m.DeleteLines 1, m.CountOfLines
m.InsertLines 1, VBACode
End If
Next v



@vbanewcomer
In meinem Fall habe ich mit den Tabellenblättern nicht direkt was zu tun. Ich ändere nämlich nur den Code.
Danke trotzdem


Gruß
reca