mikele hat geschrieben: ↑So 14. Apr 2024, 10:51
… Spätestens jetzt war mir klar, dass es praktisch unmöglich ist, ein Diagram via API (also ohne Dispatcher) zu kopieren.
Überraschung!
(… und ich war selbst derart überrascht, dass ich annehme, dass meine Nachbarn das heute Nacht trotz sehr guter Schallisolierung gehört haben - jedenfalls die, die zuhause waren)
Bei der Entrümpelung der 'Grafik'-Tabelle und des zugehörigen Moduls (das jetzt 'Chart' statt 'Graph' heißt), habe ich u.a. die Positionierung des Diagramms in seinem Rahmen sorgfältig optimiert.
(Da war leerer Platz unter dem "Fuß" - bei der Bearbeitung rechts vom eingebetteten Diagramm.)
Nachdem der nun entfernt war, hat der Rahmen komplett in den Bereich der "Grafikseite24_03" gepasst, nirgends mehr deren rechte oder untere Begrenzung berührt.
Als jetzt die NewPage-Prozedur drüber gelaufen ist mit
copyRange(CellAddress der 1. Zelle des Zielbereichs, RangeAddress des Quellbereichs) …
enthielt die neue "Seite" plötzlich, erstmals einen Clone des Diagramms!
Zunächst erschien das nicht besonders stabil: bei den weiteren Versuchen ging jeder Zugriff auf die Objekte verloren oder sie verwandelten sich von "OLE"- in "Zeichnungs"-Objekte.
Inzwischen habe ich einen stabilen Zustand erreicht, nachdem ich >10 Zwischenversionen des .ods-"Dokuments" nach jeder kleinen Manipulation gesichert habe um mich dann von da weiter zu hangeln.
Es fehlt jetzt noch die Anpassung der vom neuen Diagramm referenzierten Datentabelle, aber auch ohne das stelle ich den bisherigen Code, der o.g. "Wunder" bewirkte, schon mal hier rein:
Code: Alles auswählen
REM ***** BASIC *****
option explicit
' by: nitja last update: 24·04·15 status: struggling with riddles
' called by: so far(?) only onActivate is "called" (triggered by manual actvation) from "outside"
' calls (outside of this module): nothing
' Public bDbgMode as boolean, sMsgFromIDE(2) as string ' declared in Module IDE, sMsg(0,1,2)=(variable,hello,crash)
dim isInitd as boolean,oDoc as object,oNmdRngs as object ',oCtrlr as object,oShapes as object
dim oGkSht as object,sMonth(1) as string,sGfkPg(1) as string,oGfkPg(1) as object,oGPgRa(1) as object
dim oChart(1) as object,nChart as integer,sChart(1) as string,oChtData(1) as object
dim vTest ' ⚒🌩💢⚠❓🤔🪳
sub test
' dim <local variables>
dim oSrcRA as object, oTgtCA as object
if not isInitd then doInit
' processing:
oSrcRA=oGkSht.getCellRangeByPosition(0,0,7,32).RangeAddress
oTgtCA=oGkSht.getCellByPosition(17,0).getCellAddress
oGkSht.copyRange(oTgtCA,oSrcRA)
print vTest
stop
end sub 'test
sub onActivate ' called by sheet event, triggered by manual action
if not isInitd then doInit
end sub 'onActivate
sub doInit ' called by onActivate
if isInitd then exit sub
' bDbgMode=true
if bDbgMode and ""=sMsgFromIDE(0) then helloIDE(0) ' i.e. if previous line hasn't been commented out
oDoc=thisComponent
oCtrlr=oDoc.getCurrentController
oNmdRngs=oDoc.NamedRanges
oGkSht=oDoc.Sheets.getByIndex(0)
oChart=oGkSht.getCharts
sMonth=Array(Format(DateAdd("m",-1,Date),"yy·mm"),Format(Date,"yy·mm"))
sGfkPg=Array("Grafikseite" & Replace(sMonth(0),"·","_"),"Grafikseite" & Replace(sMonth(1),"·","_"))
if not oNmdRngs.hasByName(sGfkPg(1)) then NewPage
sChart=oChart.ElementNames : nChart=UBound(oChart.ElementNames) : if 0=nChart then NewChart
' working this far but no further: oChart is NOT the chart-"document", perhaps its frame - ALTHOUGH called "ScChartsObj" in the IDE❓
' maybe something like this: "oChartDoc = oChart.getEmbeddedObject()" … would rerail it?
oChart(1)=oChart.getByName(sChart(nChart)) : oChtData(1)=oChart(1).getRanges
if 1<oChtData(1)(0).sheet then NewChart
isInitd=true
end sub 'doInit
sub NewPage ' called by 𝑑𝑜𝐼𝑛𝑖𝑡 (← 𝑚𝑢𝑠𝑡𝑛´𝑡 be called from here)
dim oRng as object, oSrcRA as object, oTgtCA as object
if bDbgMode then sMsgFromIDE(0)=" hier ist 'NewPage' in 'Chart'" & String(18,160) : helloIDE(1) : print sMsgFromIDE(1)
' check presence of previous month's region/page to be used as a template
if not oNmdRngs.hasByName(sGfkPg(0)) then
' MsgBox("You'll have to define it manually!" & chr(10) & _
' "('" & oGkSht.Name & "' is in the leftmost sheet-tab of Calc's main window )", _
' MB_ICONSTOP,"named range '" & sGfkPg(0) & "' is missing")
MsgBox("Der muss manuell markiert & festgelegt werden!" & chr(10) & _
"('" & oGkSht.Name & "' ist im 1. Register links unter den Tabellen in Calcs Hauptfenster)", _
MB_ICONSTOP,"Benannter Bereich '" & sGfkPg(0) & "' fehlt")
stop
end if 'graphic page for previous month missing
oGfkPg(0)=oNmdRngs.getByName(sGfkPg(0)).getReferredCells
oGPgRa(0)=oGfkPg(0).RangeAddress ' source range address: e.g. (0,0,7,32)
with oGPgRa(0)
oTgtCA=oGkSht.getCellByPosition(0,.StartRow+33).getCellAddress() ' 1. cell of target range: e.g. (0,33)|(A34)
oGkSht.copyRange(oTgtCA,oGPgRa(0))
oGkSht.getCellByPosition(0,.StartRow+33).setString(Format(Date,"yy·mm"))
with oGkSht.getCellRangeByPosition(1,.StartRow+34,5,.EndRow+32)
.clearContents(com.sun.star.sheet.CellFlags.STRING or com.sun.star.sheet.CellFlags.EDITATTR)
end with 'oGkSht.getCellRangeByPosition(1,.StartRow+34,5,.EndRow+32)
oRng=oGkSht.getCellRangeByPosition(0,.StartRow+33,7,.EndRow+33)
oNmdRngs.addNewByName(sGfkPg(1),oRng.AbsoluteName,oTgtCA,0) ' cf. Pitonyak et al. 16.6.1 pgs.531-534
end with
end sub 'NewPage
sub NewChart ' called by 𝑑𝑜𝐼𝑛𝑖𝑡 (← 𝑚𝑢𝑠𝑡𝑛´𝑡 be called from here)
' check presence of previous month's chart
dim nGkShtCptnRow as long
oChart(0)=oChart.getByName(sChart(nChart-1)) : oChtData(0)=oChart(0).getRanges
if 2<oChtData(0)(0).sheet then 'chart for previous month missing ' there's no chart for the previous month
' MsgBox("You'll have to create it manually!", _
' MB_ICONSTOP,"chart '" & sChart(0) & "' is missing")
MsgBox("Das muss manuell erstellt werden!", _
MB_ICONSTOP,"'" & sChart(0) & "' fehlt")
stop
end if 'chart for previous month missing
' check presence of a preliminary, i.e. to be adjusted, chart for the current month
oChart(1)=oChart.getByName(sChart(nChart)) : oChtData(1)=oChart(1).getRanges
if 2=oChtData(1)(0).sheet then 'preliminary chart for current month exists
' setting the referred ranges for the new chart will have to go here ' ⚒
end if 'preliminary chart for current month exists
end sub 'NewChart
' von "mikele" in https://www.libreoffice-forum.de/viewtopic.php?f=12&t=39621&p=107251#p107237
sub test2
odoc=ThisComponent
otab=oDoc.Sheets.getByName("Grafik")
oDp=otab.Drawpage
for i=0 to oDp.Count-1
if oDp.getByIndex(i).name="Diagramm24·03" then
oShape=oDp.getByIndex(i)
end if
next
oCtrl = oDoc.CurrentController
theFr = oCtrl.Frame
dispH = createUnoService("com.sun.star.frame.DispatchHelper")
oCtrl.select(oshape)
dispH.executeDispatch(theFr, ".uno:Copy", "", 0, Array()) ' kopiert Chart(0), bzw. sein "shape"
oCtrl.setActiveSheet(otab)
oZiel=otab.getcellrangebyname("H35")
dispH.executeDispatch(theFr, ".uno:Paste", "", 0, Array()) ' fügt die Kopie ein, …
newSh = oDoc.CurrentSelection(0)
newSh.name="Diagramm24·04" ' bennent sie neu …
pos=oziel.position
pos.x=pos.x+oshape.size.height
pos.y=pos.y+220
newsh.setPosition(pos) ' und positioniert sie.
' ↑ scheint bis hier hin alles von der neuen NewPage-Routine bereits erledigt zu sein ↑
odia=newsh.embeddedobject.component
odia.title.string=newSh.name ' gibt ihr einen "Titel" - wozu? reine Demo?
end sub