ich mache gerade erste Gehversuche damit, meine über Jahre erstellenten
Excel/VBA-Makros gen Calc/OOo-Basic zu portieren. Und schon stolpere ich
über merkwürdige Dinge:
1.
Ein Makro *aufzunehmen* führt zu völlig anders geartetem Quellcode als
alle Internet-Quellen: Während letztere ähnlich wie VBA mit Objekten und
Memberfunktionen arbeiten, generiert das Aufnehmen nur "komischen" Code,
der einen "dispachter"-Service anlegt und damit sämtliche Aktionen mit
Array-Argumenten ausführt.
=> Scheint mir wesentlich unübersichtlicher. Hat das gegenüber der
"direkten" Verwendung des Objekmodells irgendwelche Vorteile?
2.
Ein kleines Beispiel soll alle aktuell markierten Zellen blau
hinterlegen. Mein Ansatz:
' option explicit
sub Test
' dim range as object
for each range in ThisComponent.GetCurrentSelection
range.CellBackColor = 10079487 ' Blue 8
next range
end sub
Obiges funktioniert prima, solange man die beiden auskommentierten
Zeilen weglässt. Nimmt man sie hinzu, kommt beim Stezen der Farbe der
Fehler "BASIC runtime error. Property or method not found.".
Nun bin ich ein Freund explizit deklarierter Variablen und würde das
"option explicit" gern drinhaben. Aber *warum* geht es damit schief?
BTW: Kleine Zusatzfrage: Kennt OOo-Basic eigentlich für die üblichen
Farben "namhafte" Konstanten (so wie clBlack, clRed usw. in VBA)?
Wär nett, wenn mir jemand "Starthilfe" geben könnte. Auch wenn jemand
eine passendere NG für OOo-Basic-Spezifisches kennt.
Jens
Jens Lenge schrieb:
> Hallo Welt,
>
> ich mache gerade erste Gehversuche damit, meine über Jahre erstellenten
> Excel/VBA-Makros gen Calc/OOo-Basic zu portieren.
Ich habe im Moment keine Zeit mir die Probleme im Detail anzuschauen.
Aber wenn du gerade anfängst, dann solltest du dir unbedingt das
XrayTool installieren. Es zeigt für einzelne Objekte die Properties,
Methods, Services und Interfaces.
http://ooomacros.org/dev.php#101416
mfG
Regina
> http://ooomacros.org/dev.php#101416
danke für den Tipp, werd ich beherzigen.
Trotzdem wär es suuuuupernett, wenn Du bei Gelegenheit mal ins Detail
schauen könntest - seitdem ich das frühere .xls als .ods abgespeichert
habe, geht auch die "funktionierende" Variante nicht mehr...
Jens
> Hallo Welt,
>
> ich mache gerade erste Gehversuche damit, meine über Jahre erstellenten
> Excel/VBA-Makros gen Calc/OOo-Basic zu portieren. Und schon stolpere ich
> über merkwürdige Dinge:
>
>
> 1.
> Ein Makro *aufzunehmen* führt zu völlig anders geartetem Quellcode als
> alle Internet-Quellen: Während letztere ähnlich wie VBA mit Objekten und
> Memberfunktionen arbeiten, generiert das Aufnehmen nur "komischen" Code,
> der einen "dispachter"-Service anlegt und damit sämtliche Aktionen mit
> Array-Argumenten ausführt.
>
> => Scheint mir wesentlich unübersichtlicher. Hat das gegenüber der
> "direkten" Verwendung des Objekmodells irgendwelche Vorteile?
Ich weiß nicht, warum es keinen "richtigen" Makrorecorder gibt, aber vom
Vorhandenen werden nur die Dispatch-Befehle des UI aufgezeichnet. Für
simple Anwendungen reicht das gewöhnlich.
Da Du mit Calc zu arbeiten scheinst: Es gibt einen Makrorecorder nur für
Calc, der das kann. Paolo Mantovani hat das wunderbare Stück Software
in BASIC geschrieben, und zwar als OOo selbst leider keinen REcorder
hatte. Ob der heutzutage noch problemlos funktioniert, weiß ich allerdings
nicht.
> Wär nett, wenn mir jemand "Starthilfe" geben könnte.
Sammelliste:
http://development.openoffice.org/index.html
Beispiele:
http://codesnippets.services.openoffice.org/
Ein paar passende Links ohne weiteren Sinnzusammenhang:
http://www.ooowiki.de/
http://wiki.services.openoffice.org/
http://www.oooforum.org/
http://www.pitonyak.org/AndrewMacro.sxw
http://scripting.openoffice.org/
http://www.dannenhoefer.de/faqstarbasic.htm
Viel Spaß,
--
Marc
(Please reply to newsgroup)
> 2.
> Ein kleines Beispiel soll alle aktuell markierten Zellen blau
> hinterlegen. Mein Ansatz:
>
> ' option explicit
> sub Test
> ' dim range as object
> for each range in ThisComponent.GetCurrentSelection
> range.CellBackColor = 10079487 ' Blue 8
> next range
> end sub
>
> Obiges funktioniert prima, solange man die beiden auskommentierten
> Zeilen weglässt. Nimmt man sie hinzu, kommt beim Stezen der Farbe der
> Fehler "BASIC runtime error. Property or method not found.".
>
> Nun bin ich ein Freund explizit deklarierter Variablen und würde das
> "option explicit" gern drinhaben. Aber *warum* geht es damit schief?
Weil der Basistyp `object` kein Attribut `CellBackColor` kennt. Wenn Du
deklarierst, musst Du schon richtig deklarieren.
Ciao,
Marc 'BlackJack' Rintsch
ich bin nicht sattelfest in Basic, die Antworten also mit Vorsicht nehmen.
Jens Lenge schrieb:
> Hallo Welt,
>
> ich mache gerade erste Gehversuche damit, meine über Jahre erstellenten
> Excel/VBA-Makros gen Calc/OOo-Basic zu portieren.
Es gibt inzwischen Ansätze, VBA-Makros auch direkt auszuführen.
Und schon stolpere ich
> über merkwürdige Dinge:
>
>
> 1.
> Ein Makro *aufzunehmen* führt zu völlig anders geartetem Quellcode als
> alle Internet-Quellen: Während letztere ähnlich wie VBA mit Objekten und
> Memberfunktionen arbeiten, generiert das Aufnehmen nur "komischen" Code,
> der einen "dispachter"-Service anlegt und damit sämtliche Aktionen mit
> Array-Argumenten ausführt.
>
> => Scheint mir wesentlich unübersichtlicher. Hat das gegenüber der
> "direkten" Verwendung des Objekmodells irgendwelche Vorteile?
Es ist etwas völlig anderes.
Vorteil:
Eine Abfolge von Kommandos kann ohne Basic-Kenntnisse in ein Makro
gepackt werden.
Man erfährt die notwendigen Parameter für die uno-Kommandos.
Nachteil:
Es ist nur für eine Abfolge von Kommandos geeignet.
Es ist nicht geeignet, Basic zu lernen.
>
>
> 2.
> Ein kleines Beispiel soll alle aktuell markierten Zellen blau
> hinterlegen. Mein Ansatz:
>
> ' option explicit
> sub Test
> ' dim range as object
> for each range in ThisComponent.GetCurrentSelection
> range.CellBackColor = 10079487 ' Blue 8
> next range
> end sub
>
> Obiges funktioniert prima, solange man die beiden auskommentierten
> Zeilen weglässt. Nimmt man sie hinzu, kommt beim Stezen der Farbe der
> Fehler "BASIC runtime error. Property or method not found.".
>
> Nun bin ich ein Freund explizit deklarierter Variablen und würde das
> "option explicit" gern drinhaben. Aber *warum* geht es damit schief?
Um so etwas herauszubekommen, solltest du am Anfang keine geschachtelten
Zugriffe machen, sondern jedes Objekt einzeln deklarieren und
initialisieren. Dann kannst du dir mit dem Xray Tool oder mit dem
Watch-Fenster Schritt für Schritt angucken "Was habe ich überhaupt für
ein Objekt?" und "Was kann dieses Objekt?".
Wenn du dein Makro von innerhalb eines Tabellendokuments ausführst, dann
hast du zunächst mit "ThisComponent" ein
"com.sun.star.sheet.SpreadsheetDocument". Dazu findest du, dass es die
Methode "GetCurrentSelection()" besitzt und die zugehörige
Pseudoeigenschaft "CurrentSelection". Ich würde die Schreibweisen nicht
mischen, sondern als Methode die Klammern mit schreiben, auch wenn es
ohne Klammern hier funktioniert.
Im nächsten Schritt erhältst du durch "CurrentSelection" ein
"ScCellRangeObj". Dieses hat dann die echte Eigenschaft "CellBackColor".
Du benötigst also keine Konstruktion der Art "For each in". Soweit ich
weiß, gibt es diese Kontrollstruktur in dieser Form auch nicht in Basic.
Du müsstest erst eine Nummerierung ezeugen und könntest dann darüber
iterieren.
sub Test
dim oWoBinIch as variant
oWoBinIch = ThisComponent
dim oSelection as variant
oSelection = oWoBinIch.CurrentSelection
oSelection.CellBackColor =rgb(255,128,128)
end sub
Ob "variant" oder "object" zu nehmen ist, weiß ich nicht. Hier
funktioniert beides.
>
> BTW: Kleine Zusatzfrage: Kennt OOo-Basic eigentlich für die üblichen
> Farben "namhafte" Konstanten (so wie clBlack, clRed usw. in VBA)?
Nein, direkt in Basic nicht, aber es gibt die rgb-Funktion. Dort kannst
du dann direkt die Komponenten-Zahlen benutzen, die auch beim
Farbe-Definieren-Dialog angezeigt werden.
>
>
> Wär nett, wenn mir jemand "Starthilfe" geben könnte. Auch wenn jemand
> eine passendere NG für OOo-Basic-Spezifisches kennt.
Als Newsgroup nicht, aber bei den Foren, gibt es dann spezielle
Abteilungen für Basic.
mfG
Regina
noch ein Tipp. Nimm die Kommandos ".uno:BasicIDEAppear" und
".unoBasicBreak" in eine Symbolleiste auf. Das erleichtert das Arbeiten.
Für ein englisches OOo ist das eine "Edit Macros" in der Kategory
"Application" und das andere "Interrupt Macro" in der Kategory "BASIC".
mfG
Regina
Hmmm... als was denn?
Neben elementaren Typen kennt OOoBasic doch nur "as object", oder?
> Hallo Welt,
>
> ich mache gerade erste Gehversuche damit, meine über Jahre erstellenten
> Excel/VBA-Makros gen Calc/OOo-Basic zu portieren..
... bevor du allzuviel Energie damit verbrauchst, solltest du dir erst
http://documentation.openoffice.org/HOW_TO/various_topics/VbaStarBasicXref.pdf
durchlesen. Kleine VBA-Codeschnipsel lassen sich in angemessener Zeit
portieren. Falls du dies mit größeren VBA-Projekten versuchst, so ist
der Zeitbedarf uU immens, falls ein Umschreiben überhaupt möglich ist.
--
Gruss Werner
mail nur an => nospam0601 at wp-schulz.de
Google fuer Linux-Fragen => http://www.google.de/linux <=
Hallo Regina,
> sub Test
> dim oWoBinIch as variant
> oWoBinIch = ThisComponent
> dim oSelection as variant
> oSelection = oWoBinIch.CurrentSelection
> oSelection.CellBackColor =rgb(255,128,128)
> end sub
>
> Ob "variant" oder "object" zu nehmen ist, weiß ich nicht. Hier
> funktioniert beides.
der Variablen Typ Variant nimmt einen beliebigen Variablentyp auf und
wird erst zur Laufzeit typisiert. Mit der function TypeName kann man
ermitteln welchen Variablentyp der Variantvariablen zu gewiesen wurde.
Z.b mit print TypeName(varxyz) ich bau das mal ins Makro ein.
sub Test
dim oWoBinIch as variant
oWoBinIch = ThisComponent
' Zeige Variablentyp
print TypeName(oWoBinIch)
dim oSelection as variant
oSelection = oWoBinIch.CurrentSelection
oSelection.CellBackColor =rgb(255,128,128)
end sub
Nur so am Rande für die die es sehr übersichtlich mögen, könnte man das
Makro ohne Variablen auf einen Einzeiler reduzieren.
sub Test1
ThisComponent.CurrentSelection.CellBackColor = rgb(255,128,128)
end sub
--
Viele grüße von Volker und dem Pinguin.
PC 1 : Linux openSUSE 11.0
PC 2 : Linux openSUSE 10.2
Server: Linux openSUSE 11.0 ohne X
Na wenigstens etwas ist wie man's von VBA kennt... :)
> Nur so am Rande für die die es sehr übersichtlich mögen, könnte man das
> Makro ohne Variablen auf einen Einzeiler reduzieren.
>
> sub Test1
> ThisComponent.CurrentSelection.CellBackColor = rgb(255,128,128)
> end sub
Schon klar, aber das ist ja auch nur der Einstieg.
Es geht darum, durch alle aktuell selektierten Zellen zu laufen;
hinterher soll schon etwas spezifisches mit jeder einzelnen Zelle passieren.
Ein bisserl weiter bin ich mit Euren Tipps auch schon gekommen:
Je nachdem, ob gerade ) eine einzelne Zelle, b) ein Zellbereich oder c)
mehrere Bereiche selektiert sind, liefert GetCurrentSelection() ein
Objekt verschiedener Typen:
a) ScCellObj
b) ScCellRangeObj
c) ScCellRangesObj
Aus diesem (IMO) Fehldesign(*) resultiert die Problematik, dass gewisse
Methoden manchmal verfügbar sind und manchmal eben nicht.
(*) Ein besseres Design wäre meiner Meinung nach, *immer* ein
ScCellRangesObj zurückzugeben, ggf. halt mit nur einem
ScCellRangeObj-Element, das ggf. wieder nur ein ScCellObj-Element
enthält. So könnte man konsistent und ohne Fallunterscheidungen durch
die Selektion iterieren.
=> Gibt es keine einfachere/komfortablere Möglichkeit, ohne obige
Fallunterscheidungen durch alle aktuell selektieren Zellen zu iterieren?
Jens
> Volker Kohaupt wrote:
>> der Variablen Typ Variant nimmt einen beliebigen Variablentyp auf und
>> wird erst zur Laufzeit typisiert.
>
> Na wenigstens etwas ist wie man's von VBA kennt... :)
Und es ist auch genauso schnarchlahm, wie in jeder Programmiersprache. ;)
> Je nachdem, ob gerade ) eine einzelne Zelle, b) ein Zellbereich oder c)
> mehrere Bereiche selektiert sind, liefert GetCurrentSelection() ein
> Objekt verschiedener Typen:
>
> a) ScCellObj
> b) ScCellRangeObj
> c) ScCellRangesObj
>
> Aus diesem (IMO) Fehldesign(*) resultiert die Problematik, dass gewisse
> Methoden manchmal verfügbar sind und manchmal eben nicht.
>
> (*) Ein besseres Design wäre meiner Meinung nach, *immer* ein
> ScCellRangesObj zurückzugeben, ggf. halt mit nur einem
> ScCellRangeObj-Element, das ggf. wieder nur ein ScCellObj-Element
> enthält. So könnte man konsistent und ohne Fallunterscheidungen durch
> die Selektion iterieren.
>
> => Gibt es keine einfachere/komfortablere Möglichkeit, ohne obige
> Fallunterscheidungen durch alle aktuell selektieren Zellen zu iterieren?
Du solltest dringend beginnen, die Einstiegskapitel zum "Developer Guide"
zu lesen (kann jemand helfen, ist der jetzt online, zum download oder nur
im WIki?).
Das Konzept der Aufteilung in "Service" und "Interface" fehlt
Dir und außerdem mußt Du wissen, daß OO-BASIC alle verfügbaren IFs
zusammenrührt - etwa so wie die Aggregation von Interfaces bei
COM-Objekten (IIRC).
Du kannst nach der gesuchten Funktionalität mittels:
HasUnoInterfaces( objekttyp, "voll.ständiger.Interface.Name" )
suchen. Das Interface dürfte in diesem FAll (s.a. DevGuide bzw.
IDL-Referenz, war bisher dabei wenn man das SDK runterlädt)
"com.sun.star.XCellRange"
oder
"com.sun.star.XCell"
heißen. Die Namen oben mit "Sc" am Anfang sind die internen
Implementationsnamen, die können sich ändern. Besser benutzt man die
offiziellen API-Namen (Interface mit X am Anfang, sonst Service).
Die Service-Namen gibt es üblicherweise mit
ObjVar.supportsService("com.sun.star.<modul>.<Servicename>")
oder
ObjVar.getSupportedServiceNames() ' gibt ein array (sequence im OOo-Slang) zurück
Dies sind Methoden des Interface "com.sun.star.lang.XServiceInfo", das als
Pflichtinterface aller Services gilt, also implementiert werden sollte.
Ja, für hilfreiche Quellen bin ich immer dankbar.
> Das Konzept der Aufteilung in "Service" und "Interface" fehlt
> Dir und außerdem mußt Du wissen, daß OO-BASIC alle verfügbaren IFs
> zusammenrührt - etwa so wie die Aggregation von Interfaces bei
> COM-Objekten (IIRC).
Nichtsdestotrotz wäre es IMO konsistenter, wenn die CurrentSelection
*immer* den Typ (oder in OO-Sprech "den Service") ScCellRangesObj
liefert - auch dann, wenn nur ein einzelner Zellbereich oder nur eine
Zelle selektiert ist.
Das würde konsistenteres Iterieren erlauben, ohne erst explizit auf
"supportsService" testen und drei Fallunterscheidungen machen zu müssen.
> Die Namen oben mit "Sc" am Anfang sind die internen
> Implementationsnamen, die können sich ändern. Besser benutzt man die
> offiziellen API-Namen (Interface mit X am Anfang, sonst Service).
Danke für den Hinweis.
Gibts dafür irgendwo eine gute Referenz zum Nachschlagen?
Jens
> Marc Santhoff wrote:
>> Du solltest dringend beginnen, die Einstiegskapitel zum "Developer Guide"
>> zu lesen (kann jemand helfen, ist der jetzt online, zum download oder nur
>> im WIki?).
>
> Ja, für hilfreiche Quellen bin ich immer dankbar.
Versuch's mal da:
http://api.openoffice.org/docs/DevelopersGuide/
oder sonst im offiziellen Wiki.
>> Das Konzept der Aufteilung in "Service" und "Interface" fehlt
>> Dir und außerdem mußt Du wissen, daß OO-BASIC alle verfügbaren IFs
>> zusammenrührt - etwa so wie die Aggregation von Interfaces bei
>> COM-Objekten (IIRC).
>
> Nichtsdestotrotz wäre es IMO konsistenter, wenn die CurrentSelection
> *immer* den Typ (oder in OO-Sprech "den Service") ScCellRangesObj
> liefert - auch dann, wenn nur ein einzelner Zellbereich oder nur eine
> Zelle selektiert ist.
> Das würde konsistenteres Iterieren erlauben, ohne erst explizit auf
> "supportsService" testen und drei Fallunterscheidungen machen zu müssen.
Mag theoretisch so sein, aber ersten ist es nur eine Fallunterscheidung
zwischen X(Sheet)CellRange und X(Sheet)CellRanges, ersteres *Interface*
gibt es bei einzelner Zelle wie auch selektiertem Zellbereich, und
zweitens ruft dann sicher die andere Fraktion laut ihren Unmut heraus,
warum man denn immer iterieren müsse, wo doch in den meisten Fällen nur
maximal ein Bereich selektiert sei ... Geschmackssache eben.
>> Die Namen oben mit "Sc" am Anfang sind die internen
>> Implementationsnamen, die können sich ändern. Besser benutzt man die
>> offiziellen API-Namen (Interface mit X am Anfang, sonst Service).
>
> Danke für den Hinweis.
> Gibts dafür irgendwo eine gute Referenz zum Nachschlagen?
Ja, die IDL-Referenz. Ist zusammen mit dem DevGuide Bestandteil des SDK
oder beides auch online erreichbar.
s.o. und sonst:
http://wiki.services.openoffice.org/
Danke für den Hinweis!
> zweitens ruft dann sicher die andere Fraktion laut ihren Unmut heraus,
> warum man denn immer iterieren müsse, wo doch in den meisten Fällen nur
> maximal ein Bereich selektiert sei ... Geschmackssache eben.
Nee, das hat IMO mit Geschmack nix zu tun, sondern nur mit konsequentem
Design:
OOo erlaubt nun mal das Selektieren mehrerer unabhängiger Blöcke. Ob und
was selektiert ist, entscheidet der Benutzer - der Makroprogrammierer
hat da keinen Einfluss drauf und muss daher immer vom allgemeinsten Fall
ausgehen. Also sollte auch das API darauf zugeschnitten sein.