Suchen & Ersetzen im BASIC-Modul

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Suchen & Ersetzen im BASIC-Modul

Beitrag von balu »

Hallo liebe Spezialisten,

wie kann ich per Makro in einem BASIC-Modul etwas Suchen und dann gegen nichts Ersetzen?

Vom Aufbau und der Struktur her sieht das BASIC-Modul ungefähr so aus.

Code: Alles auswählen

sub Tarry
	Dim NamA()
	NamA = DimArray(2)
	NamA(0) = "Hund"
	NamA(1) = "Katze"
	NamA(2) = "Maus"
end sub
Und jetzt soll z.B. die Maus raus. Aber auch nur das Wort, und nicht die ganze Zeile.

Ich befürchte das ich wohl nur mit vielen Verrenkungen, eventuell ScriptProvider (ist nur geraten), irgendwie das machen kann. Aber dafür fehlt mir der richtige Ansatz um etwas voran zu kommen, zumal ich per SuFu auch nichts passendes finden konnte. Deshalb frage ich euch:
- Hat das schon mal einer von euch gemacht, was ich erreichen möchte?
- Ist das überhaupt machbar?
- Ist das hier schon mal behandelt worden? Wenn ja, gibt mir bitte den Link.
- Könnt ihr mir bitte behilflich sein?

Für eure Bemühungen bedanke ich mich schon mal in voraus.
Ich freue mich auf eure Antworten.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von Karolus »

Hallo

Variablen die man evtl. mal verändern will schreibt man nicht fix in den Quelltext rein, während der Laufzeit kannst man dafür irgendwelche Datenstrukturen erstellen, für persistente Sachen schreibt/liest man Konfigurationdateien.

An den Text eines - ( hoffentlich anderen als der aufrufenden Sub ) - Moduls kommst du via:
.BasicLibraries.getByName( "Libname" ).getByName( "Modulname" )


Soweit ich weiss schreibt XRay während der Laufzeit Quelltext in extra Module rein, der dann auch gleich ausgeführt wird ?!


Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von Toxitom »

Hallo Balu, hallo Karo,

also, der Weg ist schon mal korrekt:
Mit
sCode = ...BasicLibraries.getByName( "Libname" ).getByName( "Modulname" )

bekommst du den kompletten Code als Text des entsprechenden Mosduls. Den Text kannst du nun ganz normal bearbeiten (Suchen und Ersetzen - in Strings).
Den Code kannst du dann komplett zurückschreiben:
...BasicLibraries.getByName( "Libname" ).getByName( "Modulname" ) = sCode

Aber das ganze hat ein paar "Fallen":
- Ist der Code insgesamt größer als 64.000 Byte (rund 60T Zeichen) - dann läuft das Auslesen ins Leere...
- Verschlüsselte Bibliotheken lassen sich nicht bearbeiten.
- In der IDE werden solche Änderungen nicht direkt angezeigt - der Code ist geladen im Arbeitsspeicher - und wird erst durch einen "reload" Befehl neu geladen. Daher kann man zwar Änderungen so durchführen, nicht aber im laufenden Makro.

Viele Grüße
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von balu »

Hallo Karo,

Danke schön für deine Antwort.
Variablen die man evtl. mal verändern will schreibt man nicht fix in den Quelltext rein
Und warum nicht?
Welches "Gesetz" bestimmt, beziehungsweise regelt das?

während der Laufzeit kannst man dafür irgendwelche Datenstrukturen erstellen
Wie meinst Du das?

für persistente Sachen schreibt/liest man Konfigurationdateien.
Warum?
Was für einen Vorteil hat das?
Hat das was mit den "Fallen" zu tun, die Thomas erwähnt?

hoffentlich anderen als der aufrufenden Sub
Natürlich habe ich ein Modul für die aufrufende, und eins für die betroffene Sub. Das war mir schon klar.

Soweit ich weiss schreibt XRay während der Laufzeit Quelltext in extra Module rein, der dann auch gleich ausgeführt wird ?!
Ich bin nun doch sehr verwirrt, da ich nicht weiß wovon Du da redest. XRay legt ein extra Modul an? Wie denn das? Habe ich noch nie was von gesehen? Klär mich mal bitte schön auf.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von balu »

Hallo Thomas,

Welcome back im Forum :D.
Auch dir ein Danke schön für deine Antwort.
Den Text kannst du nun ganz normal bearbeiten (Suchen und Ersetzen - in Strings).
Da ich mal wieder zu Dumm bin den ReplaceDescriptor in diesem Falle richtig anzuwenden, habe ich das hiermit gelöst.

Code: Alles auswählen

sNewInhalt = FuncAcc.callFunction("SUBSTITUTE", array(sOldInhalt, "Maus", ""))
Den Code kannst du dann komplett zurückschreiben
Also Sinngemäß mit folgendem Code funktioniert das bei mir nicht.

Code: Alles auswählen

odoc.BasicLibraries.getByName( "Libname" ).getByName( "Modulname" ) = sCode
Das ergibt dann folgende Fehlermeldung:

Kein Zugriff auf Objekt.
Falsche Verwendung eines Objekts.


Höchstwahrscheinlich bin ich schon zu übermüdet um den Fehler zu erkennen und zu beseitigen.
Und deshalb habe ich das momentan so gelöst, das ich nach dem Ersetzen das dementsprechende Modul lösche und anschließend mit der ersetzten Änderung das Modul neu anlege. Der komplette Code steht hier am ende.

Aber das ganze hat ein paar "Fallen":
Ein Haken gibts wohl immer.

- Ist der Code insgesamt größer als 64.000 Byte (rund 60T Zeichen) - dann läuft das Auslesen ins Leere...
So viele werden es nicht. Im schlimmsten Falle ca. 6.000, und in der Regel ehern so um die ca. 1.320 Zeichen.

- Verschlüsselte Bibliotheken lassen sich nicht bearbeiten.
Das ist natürlich wichtig zu Wissen.

- In der IDE werden solche Änderungen nicht direkt angezeigt
Hatte ich auch schon festgestellt. Wenn ich also die IDE schon offen habe, und z.B. ein neues Modul via Makro angelegt hatte, so wird das neue Modul nicht sofort angezeigt. Erst wenn ich den Basic-Verwaltungsdialog aus Calc heraus aufrief, wurde das neue Modul angezeigt, welches ich dann von dort aus auch aufrufen kann.
Eine Ausnahme gibt es allerdings wie das neue Modul trotzdem sofort in der IDE angezeigt wird, man provoziert einen Fehler im Makro beim Modul anlegen. Aber das ist nicht schön, und muss ja auch nicht sein.

der Code ist geladen im Arbeitsspeicher - und wird erst durch einen "reload" Befehl neu geladen.
Auf was beziehst Du dich mit "reload", auf das "Neu laden" der Datei, das Makro erneut starten, oder der eben beschriebene Weg über Basic-Verwaltungsdialog?

Daher kann man zwar Änderungen so durchführen, nicht aber im laufenden Makro.
Da bin ich mir nicht sicher ob ich dich richtig versteh, sage aber trotzdem das es doch geht, siehe folgenden Code. Falls ich dich doch falsch verstanden habe, so sags mir.

Code: Alles auswählen

Sub SuchenErsetzen
	oFunctionAccess = createunoservice("com.sun.star.sheet.FunctionAccess")
	sOldInhalt = ThisComponent.BasicLibraries.getByName("Standard").getByName("Module3")
	sNewInhalt = oFunctionAccess.callFunction("SUBSTITUTE", array(sOldInhalt, "Maus", ""))
	oLib = ThisComponent.BasicLibraries.getByName("Standard")
	If oLib.hasByName("Module3") then
		oLib.removeByName("Module3")
	end if
	oLib.insertByName("Module3", sNewInhalt)
	ThisComponent.store()
end sub

Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von Stephan »

@Balu

Du wirst evtl. Thomas eine persönliche Nachricht übers Forum schicken müssen wenn Du von ihmn eine Antwort willst, denn der GRund das Thomas Dir hier geantwortet hat ist der das ich ihn telefonisch darum gebeten hatte, da ich wußte das Thomas sich mit sowas praktisch auskennt.


Gruß
Stephan
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von Karolus »

Hallo Balu

Folgendes funktioniert ( Library und Modul sind im Dokument. )

Code: Alles auswählen

Sub Main
doc = thisComponent
libs = doc.BasicLibraries
'Die Bibliothek muss geladen sein ! 
Hallo_lib = libs.getbyname("HalloWeltLib") 
hallo_text = Hallo_lib.getbyName("HalloWelt")
msgbox hallo_text

neuertext = replace(hallo_text, "Welt", "Balu") 'die Basicfunktion replace

Hallo_lib.replaceByName("HalloWelt", neuertext)

End Sub
Und warum nicht?
Welches "Gesetz" bestimmt, beziehungsweise regelt das?
Ein Gesetz gibts dafür nicht, wenn du unbedingt willst kannst du das so machen.
balu hat geschrieben:
ich hat geschrieben:Soweit ich weiss schreibt XRay während der Laufzeit Quelltext in extra Module rein, der dann auch gleich ausgeführt wird ?!

Ich bin nun doch sehr verwirrt, da ich nicht weiß wovon Du da redest. XRay legt ein extra Modul an? Wie denn das? Habe ich noch nie was von gesehen? Klär mich mal bitte schön auf.
Anscheinend hat B.Marcally das in der aktuellen Version ( ca. 3 Wochen alt ) geändert, in früheren Versionen findest du eine Bibliothek 'XRayDyn' mit den Kopfzeilen:
XrayDyn_module hat geschrieben:REM ***** BASIC *****
' Warning this module is modified by execution of Xray macro !!
' Do not change any character unless you know what you do !

Also auch Xray hat diese Methoden aufgegeben, und ich behaupte mal das Teil bewältigt wesentlich schwierigere Sachen als du mit deinem Code.

Mal ganz praktisch - für die Beispielsaufgabe könnte man doch genausogut eine Funktion mit Argumenten schreiben.

Die rufst du dann bei Bedarf mit dem gewünschten Argument auf, und schon hat sich das Bedürfnis 'Basicquelltext per Makro zu ändern' in Luft aufgelöst.

Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von balu »

Hallo Stephan,
Du wirst evtl. Thomas eine persönliche Nachricht übers Forum schicken müssen
Werd ich wohl machen.

das ich ihn telefonisch darum gebeten hatte, da ich wußte das Thomas sich mit sowas praktisch auskennt.
Mit dieser Aktion von dir hatte ich nicht gerechnet. Und deshalb Danke ich dir vielmals dafür :D.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von balu »

Hallo Karo,
die Basicfunktion replace
Bild
Das Smilie meine ich ernst. Denn am 3. Mai hatte ich wegen einem anderen Problem diese Funktion selber gefunden, und erfolgreich angewendet. Anschließend hatte ich mir extra eine kleine Text-Datei mit dem Funktion-Namen und einen simplen Beispiel-Code angelegt und gespeichert.

Gefunden hatte ich Replace in der deutschen Übersetzung von Andrews Makro im "Kapitel 7. String-Routinen" in der Tabelle 48, und dann noch der Hinweis im "Kapitel 7.4. Ersetzen".

Und ich blödie hatte das schon wieder vergessen. Oh wie peinlich!

replaceByName
Hatte ich doch vorgestern auch probiert, muss aber wohl was schief gelaufen sein, da es nicht funktionierte. Jetzt hatte ich es noch mal gemacht, und siehe da, es funktioniert doch. Dadurch ergibt sich jetzt bei mir folgender funktionsfähiger Code.

Code: Alles auswählen

Sub SuchenErsetzen()
	sOldInhalt = ThisComponent.BasicLibraries.getByName("Standard").getByName("Module3")
	sNewInhalt = replace(sOldInhalt, "Maus", "")
	oLib = ThisComponent.BasicLibraries.getByName("Standard")
	oLib.replaceByName("Module3", sNewInhalt)
	ThisComponent.store()
end sub
Ein Gesetz gibts dafür nicht, wenn du unbedingt willst kannst du das so machen.
Alles Klar.


Thema XRay.
Ja jetzt weiß ich was Du mit "XRay Modul anlegen" meinst. Das ist das Modul wo die Einstellungen gespeichert werden, wenn man in XRay in *Configuration* Änderungen vorgenommen hat. Habe ich aber auch erst jetzt durch den Suchbegriff "Bibliothek 'XRayDyn'" festgestellt.


Mal ganz praktisch - für die Beispielsaufgabe könnte man doch genausogut eine Funktion mit Argumenten schreiben.

Die rufst du dann bei Bedarf mit dem gewünschten Argument auf, und schon hat sich das Bedürfnis 'Basicquelltext per Makro zu ändern' in Luft aufgelöst.
Ich glaub wohl ehern nicht, auch wenn ich mir momentan nicht viel unter deinem Vorschlag vorstellen kann. Denn das gegebene Beispiel ist stark reduziert, und gibt nicht den gesamten Ablauf wieder. Ich werd mal mein Vorhaben grob beschreiben.

Ich habe 2 Dateien. Eine fast Blanko Datei die quasi als Vorlage dient und jeden Monat neu befüllt wird. Und eine weitere die die Blanko Datei mit "Leben" befüllt, dazu zählt auch das Eintragen einer Namensliste die sich unter gewissen Umständen von einem Monat zum nächsten ändert, und anschließend unter einem anderen Dateinamen speichert.

Bis jetzt habe ich die Namensliste, die bis zu 40 Namen umfassen kann, in einer Calc-Tabelle. Und diese Namensliste wird beim Dialog Aufruf jedesmal in eine Listbox eingelesen. Doch nun möchte ich aber nicht mehr die Liste aus dem Tabellenblatt, sondern aus dem Makro einlesen. Dadurch ist ein versehentliches manipulieren der Namensliste, wenn man sich in dem Tabellenblatt befindet, ausgeschlossen, da die Liste dort nicht mehr vorhanden ist.

Das willentliche, und geplante löschen eines Namens soll mit dem hier und jetzt erarbeiteten Makro durchgeführt werden.

Trotzdem würde es mich interessieren wie die Funktion aussehen würde die Du dir da so vorstellst. Kannst Du mal bitte ein kleines Beispiel hier anhängen?



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von Karolus »

Hallo Balu
Ich hab gerade wenig Zeit, nur mal so als Anregung wie es in Python ausehen könnte, einfach copy und paste von einer Pythonshell: ( Die >>> sind die Eingabeaufforderung. )

Code: Alles auswählen

>>> import pickle
>>> s = ['a','c','d','z'] # s ist jetzt eine Liste ( entspricht grob dem Basic array )
>>> with open("mynamefile", 'wb') as names:
	     pickle.dump(s, names) # die Liste s wird in die Datei geschreben

	
>>> with open("mynamefile", 'rb') as names:
	     ff = pickle.load( names) # die Datei wird ausgelesen und an ff gebunden

	
>>> ff
   ['a', 'c', 'd', 'z'] # da ist sie wieder, unsere Liste
>>> ff.remove('d') # 'd' wird entfernt
>>> ff
   ['a', 'c', 'z'] # hat geklappt
>>> ff.append("balu") # wir fügen 'balu' hinzu
>>> ff
   ['a', 'c', 'z', 'balu']
>>> 
Morgen ausführlicher..

Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: Suchen & Ersetzen im BASIC-Modul

Beitrag von balu »

Hallo Karo,

nicht nur ich, sondern auch mein OOo haben Angst vor Schlangen. Das heißt: Ich krieg Python weder in OOo 3.2.1, noch in 3.3.0 irgendwie gesatartet. Aber das ist momentan für mich eh nicht so wichtig, da ich ein ganz anderes Problem hier gepostet habe welches eine höhere Priorität besitzt.

Wir können aber später hier noch mal weiter machen.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Antworten