Seite 1 von 1

[gelöst] war Fehler in copyRange-Syntax: kopiert nicht

Verfasst: So 13. Dez 2020, 17:43
von nitja
Ich möchte die Formeln aus der Seite für den Vormonat (Index iPg-1) in die Seite für den neuen Monat (Index iPg) übernehmen. Mit dem folgenden Code passiert aber rein gar nix:

Code: Alles auswählen

Sub newMonth(iPg as integer)
	dim oRngCM as object, oRngNM as object
	with oDoc.sheets(0)
		oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 17, 33*iPg-1)
		oRngNM = .getCellByPosition(0, 33*iPg)
		.copyRange(oRngNM.getCellAddress, oRngCM.getRangeAddress)
		…
	end with
End Sub
Warum?
Vorher hatte ich mal versehentlich als Endspalte 0 statt 17 eingetragen. Da hat's die Formeln der ersten Spalte tatsächlich in neuen Bereich kopiert.

Re: Fehler in copyRange-Syntax: kopiert nicht

Verfasst: Mo 14. Dez 2020, 06:41
von nitja
So, scheint ein bug oder ein mir unbekannter optionaler Parameter im Aufruf von copyRange zu sein. Es kopiert dann und nur dann, wenn der Quellbereich keine leere Zelle enthält. (Und keine verbundenen, auch wenn die versteckten nicht leer sind)
Der folgende Code arbeitet einwandfrei, nachdem ich in die paar in den neuen Quellbereichen verbliebenen leeren Zellen manuell mit dummy-Inhalt (space) gefüllt habe:

Code: Alles auswählen

Sub newMonth(iPg as integer)
	dim oRngCM as object, oRngNM as object
	with oDoc.sheets(0)
		' first row
		oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 5, 33*(iPg-1))
		oRngNM = .getCellByPosition(0, 33*iPg)
		.copyRange(oRngNM.getCellAddress, oRngCM.getRangeAddress)
		' first column
		oRngCM = .getCellRangeByPosition(0, 33*iPg-32, 0, 33*iPg-2)
		oRngNM = .getCellByPosition(0, 33*iPg+1)
		.copyRange(oRngNM.getCellAddress, oRngCM.getRangeAddress)
		' seventh column
		oRngCM = .getCellRangeByPosition(6, 33*iPg-32, 6, 33*iPg-2)
		oRngNM = .getCellByPosition(6, 33*iPg+1)
		.copyRange(oRngNM.getCellAddress, oRngCM.getRangeAddress)
		' last row
		oRngCM = .getCellRangeByPosition(0, 33*iPg-1, 12, 33*iPg-1)
		oRngNM = .getCellByPosition(0, 33*iPg+32)
		.copyRange(oRngNM.getCellAddress, oRngCM.getRangeAddress)
		
		oRngNM = .getCellRangeByPosition(0, 33*iPg, 12, 33*iPg+32)
	end with
End Sub
"[gelöst]"? Na ja, eher ein workaround um einen bug, oder?

Kommentare ausdrücklich erwünscht.

Re: [bug mit workaround] oder Fehler in copyRange-Syntax?: kopiert nicht

Verfasst: Di 15. Dez 2020, 22:33
von craig
Hallo,

der Basic-Interpreter versteht deine Code nicht, aber da Du
bekannte Schlüsselwörter benutzt wird kein Fehler gemeldet.

Code: Alles auswählen

getRangeAddress
ist ein Sruct, welches aus 5 Elementen besteht.
siehe hier:
http://www.openoffice.org/api/docs/comm ... dress.html

Der Interpreter erwartet nun einen Zellbereich, den Du z.B. so zusammensetzen kannst:
RangeAddress.Sheet
RangeAddress.StartColumn
RangeAddress.StartRow
RangeAddress.EndColumn
RangeAddress.EndRow

Code: Alles auswählen

REM getCellRangeByPosition( nLeft as long, nTop as long, nRight as long, nBottom as long )
nLeft= RangeAddress.StartColumn
nTop=RangeAddress.StartRow
nRight=RangeAddress.EndColumn
nBottom=RangeAddress.EndRow

oRangeAdresse=Sheet1.getCellRangeByPosition(nLeft, nTop, nRight, nBottom)

Gleiches gilt für oRngNM.getCellAddress
getCellAddress ist auch ein Struct:
Sheet → is the index of the sheet that contains the cell.
Column → is the index of the column where the cell is located.
Row → is the index of the row where the cell is located.
siehe hier:
https://www.openoffice.org/api/docs/com ... dress.html
oder hier:
https://api.libreoffice.org/docs/idl/re ... dress.html

Jetzt schau ich mir Deinen Code nochmals an uund sehe dies:

Code: Alles auswählen

	with oDoc.sheets(0)
		' first row
		oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 5, 33*(iPg-1))
Das Rangeobjekt referenziert den angegebenen Zellbereich.
Gleiches bei der Zellreferenz:

Code: Alles auswählen

oRngNM = .getCellByPosition(0, 33*iPg)
So vermute ich, dass dies ohne "getRangeAddress" funktionieren sollte, weil die Referenz zuvor gesetzt wurde:

Code: Alles auswählen

Sub newMonth(iPg as integer)
	dim oRngCM as object, oRngNM as object
' xray  oDoc.sheets(0)

	with oDoc.sheets(0)
		' first row
		oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 5, 33*(iPg-1))
		oRngNM = .getCellByPosition(0, 33*iPg)
		.copyRange(oRngNM, oRngCM)

		' first column
		oRngCM = .getCellRangeByPosition(0, 33*iPg-32, 0, 33*iPg-2)
		oRngNM = .getCellByPosition(0, 33*iPg+1)
		.copyRange(oRngNM, oRngCM)

		' seventh column
		oRngCM = .getCellRangeByPosition(6, 33*iPg-32, 6, 33*iPg-2)
		oRngNM = .getCellByPosition(6, 33*iPg+1)
		.copyRange(oRngNM, oRngCM)

		' last row
		oRngCM = .getCellRangeByPosition(0, 33*iPg-1, 12, 33*iPg-1)
		oRngNM = .getCellByPosition(0, 33*iPg+32)
		.copyRange(oRngNM, oRngCM)
		
		oRngNM = .getCellRangeByPosition(0, 33*iPg, 12, 33*iPg+32)
	end with
End Sub
Ist wie gesagt eine Vermutung, weil ich es bei mir mangels Dokument nicht testen konnte.

Nutze XRAY zur Codeinspektions:
https://wiki.openoffice.org/wiki/DE/Mak ... X-Ray_tool
Es ist ein Writerfile mit Makros zur Installation von XRAY und gleichzeitig eine deutschsprachige Doku.

EDIT:
Ich habe mich wohl ein wenig geirrt.
Siehe hier:
http://www.dannenhoefer.de/faqstarbasic ... l#Zweig197

Re: [bug mit workaround] oder Fehler in copyRange-Syntax?: kopiert nicht

Verfasst: Di 15. Dez 2020, 22:48
von nitja
Danke für Deine Initiative.
Aber, der Code funktioniert doch einwandfrei - er tut bloß nix, wenn da eine leere Zelle im Quellbereich ist.
Und ja, bin gerade dabei, das X-Ray runter zu laden.
Hatte letztes Mal nicht geklappt, aber jetzt gehe ich's "verschärft" an.

Re: [bug mit workaround] oder Fehler in copyRange-Syntax?: kopiert nicht

Verfasst: Di 15. Dez 2020, 23:11
von craig
Hallo,

hier ein Testfile:
Zellbereich kopieren.ods
(8.59 KiB) 168-mal heruntergeladen
Ein Testfile, da ich den Verdacht hege, dass Dein Makro vollfunktionstüchtig
ist, aber die Daten ggf. beim Kopieren überschrieben werden.

In solche Fällen nutze ich zuerst ein abgespecktes Makro.

Im nächsten Schritt nutze ich Haltepunkte im Programm ,
um die Einzelergebnisse im Blatt zu prüfen.

Auch ein schrittweises Ausführen [F8] des Programms kann
helfen die Fehlerquelle in der eigenen Logik zu finden.

Re: [bug mit workaround] oder Fehler in copyRange-Syntax?: kopiert nicht

Verfasst: Di 15. Dez 2020, 23:54
von nitja
craig hat geschrieben:
Di 15. Dez 2020, 23:11
Zellbereich kopieren.ods
Ja, das kopiert auch mit der leeren Zelle. Der einzige Unterschied zu meinem Code: dass Du die RangeAddress vor dem Aufruf erst in ein extra Objekt gesteckt hast - werd ich in meinem sheet auch mal ausprobieren.
craig hat geschrieben:
Di 15. Dez 2020, 23:11
Ein Testfile, da ich den Verdacht hege, dass Dein Makro vollfunktionstüchtig ist, aber die Daten ggf. beim Kopieren überschrieben werden.
Falls Du damit den Zielbereich meinst: das ist so gewollt.
craig hat geschrieben:
Di 15. Dez 2020, 23:11
In solche Fällen nutze ich zuerst ein abgespecktes Makro.
Im nächsten Schritt nutze ich Haltepunkte im Programm, um die Einzelergebnisse im Blatt zu prüfen. Auch ein schrittweises Ausführen [F8] des Programms kann helfen die Fehlerquelle in der eigenen Logik zu finden.
Klar, das mache ich immer ziemlich genau so.

Eine Frage noch zu xray und sdk: Wohin muss das sdk für LO in Linux kopiert werden?

Re: [bug mit workaround] oder Fehler in copyRange-Syntax?: kopiert nicht

Verfasst: Mi 16. Dez 2020, 11:02
von craig
Hallo,
nitja hat geschrieben:Es kopiert dann und nur dann, wenn der Quellbereich keine leere Zelle enthält. (Und keine verbundenen, auch wenn die versteckten nicht leer sind)
nitja hat geschrieben:Falls Du damit den Zielbereich meinst: das ist so gewollt.
Der Basic-Interpreter arbeitet den Quellcode Zeile für Zeile ab.
Die Frage welche ich mir stellte war, ob sich bei den EINZELNEN
Kopiervorgängen die Zellbereiche gegenseitig überschreiben:

A überschreibt Teile oder alles von B
B überschreibt Teile oder alles von C
usw.


Danach sieht es so aus, als wäre irgendetwas nicht abgearbeitet worden.
Tatsächlich liegt es in der eigenen Syntax zur Bereichsberechnung.

Code: Alles auswählen

REM Bereich 1		' first row 
			oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 5, 33*(iPg-1))
			oRngNM = .getCellByPosition(0, 33*iPg)
REM Bereich 1 wird teilweise oder ganz von von Bereich 2 überschrieben:
			' first column
			oRngCM = .getCellRangeByPosition(0, 33*iPg-32, 0, 33*iPg-2)
			oRngNM = .getCellByPosition(0, 33*iPg+1)
		
getCellRangeByPosition( nLeft, nTop, nRight, nBottom)
nLeft=0
nTop=33*(iPg-1)
nRight=5
nBottom=33*(iPg-1)

.getCellRangeByPosition(0, 33*(iPg-1), 5, 33*(iPg-1))

-------------------------
getCellByPosition(nColumn, nRow )
nColumn = 0 → Spalte A
nRow = 33*iPg → Zeile 34*iPg = Zeile :?:
.getCellByPosition(0, 33*iPg)

Eine diesbezüglich Fehleranalyse kann ganz einfach durchgeführt werden,
in dem Du alle Codeabschnitte, bis auf den ersten (' first row) auskommentierst.
Das Makro startest und das Ergebnis prüfst.
Dann prüfst Du die Zusammenarbeit des ersten (' first row) und des zweiten (' first column) Codeabschnitts.
usw...
Irgendwann sollte sich die Ungereimtheit, fehlerhafte Syntax zeigen.
nitja hat geschrieben:Eine Frage noch zu xray und sdk: Wohin muss das sdk für LO in Linux kopiert werden?
Die SDK brauchst Du nicht. XRAY arbeitet auch ohne Angabe einer SDK oder einer Pfadangabe zur API.
Letzteres würde ich auf jeden Fall offen lassen, weil XRAY eigentlich für AOO konzipiert wurde und folgende Seite
erwartet:
https://www.openoffice.org/api/docs/com ... dex-1.html

Für LibreOffice müsste diese API-Seite angegeben werden:
https://api.libreoffice.org/docs/idl/ref/files.html
XRAY versteht diese Seite aber nicht, weil sie auf doxygen basiert.

Es gibt noch ein Codeinspektionstool namens MRI. Das Problem ist, es wird für LibreOffice nicht mehr weiterentwickelt.
Noch schlimmer, mittlerweile schmiert mir LibreOffice bei Einsatz von MRI regelmäßig ab.
Es war mein Lieblingstool, kann ich aber nicht mehr weiterempfehlen :(

Jetzt ist es aber so, das sich AOO und LibreOffice immer mehr unterscheiden; Ist übrigens eines der Gründe warum MRI nicht mehr weiterentwickelt wird.
Das wirkt sich selbstverständlich auch auf die API aus.
So kann es passieren, dass Dein Code unter LibreOffice einwandfrei funktioniert, aber AOO streikt und umgekehrt.
Dazu gibt es aber keine Doku. Hier gilt nur "learning by testing" :lol:

Nun die SDK wird nur gebraucht, wenn Du selbst am Quellcode für Office arbeiten möchtest.
Bugs beseitigen, LibreOffice weiterentwickeln, etc.
Die Programme werden in JAVA/C++ geschrieben und im Anschluss kompiliert.
https://api.libreoffice.org/docs/install.html

PS
Ich gehe davon, dass XRAY auch unter LibreOffice irgendwann einmal nicht mehr richtig funktioniert.
Dann hilft im Augenblick nur noch das Arbeiten mit Haltepunkten und das Betrachten der Objektvariablen, etc. im Beobachter.
Dies ist sehr mühselig, zumal hier nur das nötigste angezeigt wird.
Die erwarteten Datentypen, usw. zu angezeigten Methoden, Eigenschaften usw. muss man dann in der API nachlesen.

Eine weitere, im Augenblick noch sehr rudimentäre Fnktion versteckt sich in den "experimentellen Einstellungen"
  • Menü Extras → Optionen...
  • LibreOffice → Erweitert
    Experimentelle Funktionen aktivieren
  • LO neustarten.
  • Menü Extras → Optionen...
  • LibreOffice → Basic-IDE
    Informationen dazu siehe in der Hilffe
    Suchbegriff:
    Basic-IDE

    Dann der Link:
    Global
    Basic-IDE -- Optionen


    Hier unbedingt die Hinweise lesen :!:
    Insbesondere.
    LO-Hilfe hat geschrieben:Die Verwendung von erweiterten Typen in Basic-Programmen kann die
    Kompatibilität des Programms zu anderen Office-Paketen einschränken.

Re: [bug mit workaround] oder Fehler in copyRange-Syntax?: kopiert nicht

Verfasst: Mi 16. Dez 2020, 15:05
von nitja
….

Re: [gelöst] war Fehler in copyRange-Syntax: kopiert nicht

Verfasst: Do 17. Dez 2020, 19:00
von nitja
nitja hat geschrieben:
So 13. Dez 2020, 17:43
Ich möchte die Formeln aus der Seite für den Vormonat (Index iPg-1) in die Seite für den neuen Monat (Index iPg) übernehmen. Mit dem folgenden Code passiert aber rein gar nix:

Code: Alles auswählen

Sub newMonth(iPg as integer)
	dim oRngCM as object, oRngNM as object
	with oDoc.sheets(0)
		' oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 17, 33*iPg-1) falsch - Zielbereich bleibt komplett leer
		oRngCM = .getCellRangeByPosition(0, 33*(iPg-1), 17, 33*iPg-2) ' richtig - funktioniert wie gewünscht
		oRngNM = .getCellByPosition(0, 33*iPg)
		.copyRange(oRngNM.getCellAddress, oRngCM.getRangeAddress)
		…
	end with
End Sub
Warum? Arithmetik Trivia.

Mittlerweile kopiere ich nicht mehr den Bereich aus dem Vormonat, sondern einen extra angelegten "Vorlage"-Bereich außerhalb des Sichtfeldes und Druckbereiches.
Der kaum erwartete Clou dabei: das komplett im Quellbereich liegende chart (dafür musste ich noch eine Weile an der Formatierung frickeln) wird mit kopiert!
… was das Thema "chart … duplizieren" (für mich) akademisch macht, praktisch gleich mit löst.