Macro geeft geen fout maar werkt niet

Atwist
Berichten: 52
Lid geworden op: ma sep 14, 2015 8:56 am

Macro geeft geen fout maar werkt niet

Bericht door Atwist »

Hallo allen

Ik klop hier weer eens aan omdat ik er niet uit kom (kennis van StarBasic is ontoereikend)

Het probleem: ik probeer een macro te maken met als doel het berekenen van bepaalde kosten wanneer men een nieuwe maand ingaat
Dus als ik op de button druk "nieuwe maand" dan worden allerlei bedragen gekopieerd naar de nieuwe maand maar er moet ook gerekend worden.
Voor als de vraag komt, de button kan maar 1 keer per maand worden gebruikt dan word deze disable.
In de onderstaande macro staat een vast bedrag in E9 (mk_1) en nu moet F9 telkens wanneer de macro wordt gebruikt worden opgehoogd met E9 (mk_1), maar wat is er nu fout

Code: Selecteer alles

Sub OptellenJaarkosten
	Dim mk_1 as String 
	Dim Range as string
   	Doc = ThisComponent
   	Sheets = Doc.Sheets()
   	Sheet = Sheets.getByName("Jaarkosten")
        mk_1 = Range("E9")
	Range("F9") = Range("F9") +mk_1
	mk_2 = Range("E10")
	Range("F10") = Range("F10") +mk_2
End sub
Met VBA is het voor mij geen probleem alleen loopt de rest in de soep omdat ik "Option VBASupport 1" gebruik, maar zo lukt het mij wel.

Code: Selecteer alles

Option VBASupport 1   
Sub OptellenJaarkosten
        mk_1 = Sheets("Jaarkosten").Range("E9")
	Sheets("Jaarkosten").Range("F9") = Sheets("Jaarkosten").Range("F9") +mk_1
	mk_2 = Sheets("Jaarkosten").Range("E10")
	Sheets("Jaarkosten").Range("F10") = Sheets("Jaarkosten").Range("F10") +mk_2
End sub
Graag een tip van jullie kant.
Andreas

LibreOffice 4.4.7.2. op Linux Mint en zeker geen Versie 5 meer.
Atwist
Berichten: 52
Lid geworden op: ma sep 14, 2015 8:56 am

Re: Macro geeft geen fout maar werkt niet

Bericht door Atwist »

Ha, ik vond een voorbeeld en deze werkt goed

Code: Selecteer alles

Sub OptellenJaarkosten
   sheet = ThisComponent.Sheets.GetByName("Jaarkosten")
   maand = sheet.getCellRangeByName("E9:F27")
   data = maand.DataArray
   for each row in data
      row(1) = row(0)+row(1)
   next
   maand.DataArray = data
End Sub
Maar als ik nu minus de maandkosten doe dan werkt dat niet en volgens mij is het toch de "+" vervangen door de "-".

Code: Selecteer alles

Sub AftrekkenJaarkosten
 sheet = ThisComponent.Sheets.GetByName("Jaarkosten")
   maand = sheet.getCellRangeByName("E9:F27")
   data = maand.DataArray
   for each row in data
      row(1) = row(0)-row(1)
   next
   maand.DataArray = data
End Sub
Andreas

LibreOffice 4.4.7.2. op Linux Mint en zeker geen Versie 5 meer.
RPG
Berichten: 4667
Lid geworden op: wo apr 15, 2009 1:01 am
Locatie: Apeldoorn, Nederland

Re: Macro geeft geen fout maar werkt niet

Bericht door RPG »

Hallo

Ik denk dat je op het Engelse forum moet zoeken naar functionaccess. Daar staan verschillende voorbeelden hoe die te gebruiken. Ik geloof dat het gebruik wel taal gevoelig is. Dus je moet goed kijken welke naam je gebruikt voor een functie. Als je Nederlandstalige namen gebruikt dan moet je het nu ook doen.

Wanneer je met getallen wilt werken dan moet je een variabele niet als string definieren. Dat zag ik in het eerste bericht later niet meer.

Ik ben niet zo bekend met werkblad macro's. Ik heb dus geen idee. Ik zal nog wel even kijken.

Romke
LibreOffice 7.4.3.2 op openSUSE Leap 15.4
RPG
Berichten: 4667
Lid geworden op: wo apr 15, 2009 1:01 am
Locatie: Apeldoorn, Nederland

Re: Macro geeft geen fout maar werkt niet

Bericht door RPG »

Hallo

Over de fout met minus kan ik weinig zeggen. Bij mij werkt het goed. Ik denk dat je een fout in je code hebt.

Naast het maken van code is het leren debuggen van je eigen code ook erg belangrijk. Bovendien leer je hoe de gegevens zijn opgeslagen. StarBASIC heeft diverse functies om iets te weten te komen over de gebruikte variabelen. In de libraries Tools van BASIC zitten diverse macro's die zich goed laten gebruiken. Je kunt ze gebruiken om te leren, gewoon gebruiken maar ook bij fout zoeken.

Zelf heb ik ook goed de mogelijkheden van de API gebruikt. Daar zitten mogelijkheden in die het fout zoeken ook vergemakkelijken. Het is vaak beter om in het begin goed te testen dan later op een fout uit te komen.

Romke
LibreOffice 7.4.3.2 op openSUSE Leap 15.4
RPG
Berichten: 4667
Lid geworden op: wo apr 15, 2009 1:01 am
Locatie: Apeldoorn, Nederland

Re: Macro geeft geen fout maar werkt niet

Bericht door RPG »

Op een bepaalde manier kwam ik deze draad opnieuw tegen. Eerst ben ik geruime tijd bezig geweest om te kijken of ik een goede oplossing kon vinden voor de gevraagde macro door API code. Het is mij niet gelukt. Op een bepaald moment kwam ik op de gedachte dat de meest simpele oplossing voor dit probleem wel is het toepassen van speciaal plakken na het kopiëren van de gegevens.

Code: Selecteer alles

sub Main
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$B$2:$B$11"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())

rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "ToPoint"
args3(0).Value = "$C$2:$C$11"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args3())

rem ----------------------------------------------------------------------
dim args4(5) as new com.sun.star.beans.PropertyValue
args4(0).Name = "Flags"
args4(0).Value = "SVD"
args4(1).Name = "FormulaCommand"
args4(1).Value = 1
args4(2).Name = "SkipEmptyCells"
args4(2).Value = false
args4(3).Name = "Transpose"
args4(3).Value = false
args4(4).Name = "AsLink"
args4(4).Value = false
args4(5).Name = "MoveMode"
args4(5).Value = 4

dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args4())


end sub
Plakken Speciaal
Plakken Speciaal (ctrl-shift-V) staat allerlei extra bewerkingen toe die steeds opnieuw gekozen moeten worden. Het is wel zo dat voor zover ik weet de laatst gekozen mogelijkheden onthouden worden. Het wordt in de help file goed beschreven.

Goed combineren van Plakken Speciaal en het geven van namen aan een gebied
Het is voor elke gebruiker belangrijk om regelmatig de helpfile te lezen ook voor mij. Ook het lezen van door mij gewaardeerde berichtenplaatsers op het Engelse forum maakt dat ik nieuwe dingen leer. Vaak ook is het belangrijk bij het programmeren om kleine mogelijkheden goed te combineren. In dit geval is een goede combinatie de opgenomen macro en het geven van een naam aan de twee bijelkaar horende gebieden. Ik heb gekozen voor: Bron en Doel. Het is niet noodzakelijk dat deze twee op het zelfde tabblad zijn waarschijnlijk wel in het zelfde bestand. De namen Bron en Doel kunnen gebruikt worden in de macro. Let wel: de namen Bron en Doel staan in de macro tussen aanhallingstekens

Oefen eerst met de instelling
Het is niet noodzakelijk dat het bronbereik en het doelbereik even groot moeten zijn. Soms wil men een enkele waarde ,enkele cel, bij een range optellen. Soms worden twee ranges van gelijke grootte bij elkaar opgeteld.

Code: Selecteer alles

Macro met ingevulde rangenamen
sub Main_metnamen
rem ----------------------------------------------------------------------
rem define variables
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "Bron"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())

rem ----------------------------------------------------------------------
dim args3(0) as new com.sun.star.beans.PropertyValue
args3(0).Name = "ToPoint"
args3(0).Value = "Doel"

dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args3())

rem ----------------------------------------------------------------------
dim args4(5) as new com.sun.star.beans.PropertyValue
args4(0).Name = "Flags"
args4(0).Value = "SVD"
args4(1).Name = "FormulaCommand"
args4(1).Value = 1
args4(2).Name = "SkipEmptyCells"
args4(2).Value = false
args4(3).Name = "Transpose"
args4(3).Value = false
args4(4).Name = "AsLink"
args4(4).Value = false
args4(5).Name = "MoveMode"
args4(5).Value = 4

dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args4())


end sub
Opgenomen macro's
Opgenomen macro's zijn in het algemeen traag en kunnen beter ook niet gebruikt worden voor bewerkingen in loops. Er is naar mijn idee niets verkeerd aan het toepassen van goed opgenomen macro's. Een goed opgenomen macro weerspiegeld vaak ook een goede kennis van de normale werking van OpenOffice.
LibreOffice 7.4.3.2 op openSUSE Leap 15.4
RPG
Berichten: 4667
Lid geworden op: wo apr 15, 2009 1:01 am
Locatie: Apeldoorn, Nederland

Re: Macro geeft geen fout maar werkt niet

Bericht door RPG »

Ik ben nog wat dieper op het probleem gedoken. Voor mij was een doel om ook enig idee te krijgen wat er prcies mogelijk is nadat VBASupport geactiveerd is.

Eerst hoe het mogelijk is om het te doen met Starbasic:

Code: Selecteer alles

sub OptellenJaarkosten_StarBASIC
dim oDoc
dim oNamedRanges
dim oComplete
dim oGegevens
oDoc = thiscomponent
oNamedRanges = oDoc.NamedRanges
oComplete = oNamedRanges.getbyname("Complete").getReferredCells
dim oCelrange
dim oCelDataarray,oCompleteDataarray
dim oNieuwWaarde
dim Row

oCompleteDataarray=oComplete.getdataarray
for Row = 0 to ubound(oCompleteDataarray)
	oCelrange =  oComplete.getCellRangeByPosition(0,Row,1,Row) ' Pak een klein stukje
	oCelDataarray = oCelrange.getDataarray ' bewaar de gegevens
	oNieuwWaarde = oCelrange.computeFunction(com.sun.star.sheet.GeneralFunction.SUM) ' Doe het rekenwerk
	oCelDataarray(0)(1) = oNieuwWaarde ' sla het resultaat op in de bewaarde gegevens
	oCelrange.setDataarray(oCelDataarray) ' Sla het op in het werk blad
next
end sub
In het bovenstaande wordt gebruik gemaakt van computefunction. Dit is naar mijn idee gelijk met wat mogelijk is met de functie SUBTOTALS enik denk ook dat dit gebruikt wordt in draaitabellen en nog andere zaken die hier op lijken.

Code: Selecteer alles

sub OptellenJaarkosten_StarBASIC2
' nu wil ik het laten optellen en aftrekken
dim oDoc
dim oNamedRanges
dim oComplete
dim oGegevens
oDoc = thiscomponent
oNamedRanges = oDoc.NamedRanges
oComplete = oNamedRanges.getbyname("Complete").getReferredCells
dim oCelrange
dim oCelDataarray,oCompleteDataarray
dim oNieuwWaarde
dim Row


oCompleteDataarray=oComplete.getdataarray
for Row = 0 to ubound(oCompleteDataarray)
	oCelrange =  oComplete.getCellRangeByPosition(0,Row,1,Row) ' Pak een klein stukje
	oCelDataarray = oCelrange.getDataarray ' bewaar de gegevens
	oNieuwWaarde = oCelDataarray(0)(1) +  oCelDataarray(0)(0) ' Nu kunnen de waardes goed opgeteld en verminderd worden
	'oNieuwWaarde = oCelrange.computeFunction(com.sun.star.sheet.GeneralFunction.SUM) ' Doe het rekenwerk
	oCelDataarray(0)(1) = oNieuwWaarde ' sla het resultaat op in de bewaarde gegevens
	oCelrange.setDataarray(oCelDataarray) ' Sla het op in het werk blad
next
end sub
Hier is de mogelijkheid dat er niet alleen opgeteld worden maar ook verminderd. Er zijn nogal wat kleine tussenstapjes die genomen moeten. Die kleine tussenstapjes heb ik vaak ook niet paraat.


Nu het laatste voorbeeld wat geheel gedaan is in VBA mogelijkheden. Ik heb de mogelijk opgezocht met de tool MRI.

Code: Selecteer alles

REM  *****  BASIC  *****
option explicit
Option VBASupport 1 

Sub OptellenJaarkosten_VBA
	dim oComplete as object ' Het goed definieren als object is hier erg belangrijk
	'complete staat voor een tabel in een werkblad van twee kolommen.
	'Als er kolomhoofden zijn moeten die niet in het naam gebied zijn.
	' Het is mogelijk dat er wel een oplossing is
	
	oComplete = range("Complete")' Wanneer namen gedefineerd worden in het werkblad kunnen deze gebruikt 
	dim x
	for x = lbound(oComplete.value) to ubound(oComplete.value)
		oComplete(x,2) = oComplete(x,2) + oComplete(x,1) ' Hier wordt het rekenwerk gedaan
	next
End sub
Wat wil ik met het bovenstaande aantonen?
Voor de deskundige in het VBA moet de overstap waarschijnlijk toch niet zo groot zijn. Dit geldt natuurlijk wel voor zover zij zelf hun macro's geschreven hebben. Wanneer hun programmeer kennis in het VBA onvoldoende is zal er een overstap naar de API noodzakelijk zijn op deelterreinen.

Het doel voor mezelf is feitelijk wel bereik namelijk om te weten in hoeverre het VBA nu toch ondersteund wordt: het wordt toch wel in grote mate ondersteund. Voor de duidelijk ik heb dit gedaan in ApacheOffice 4.2 dat betekent dus ook dat de mogelijk heden er al lang zijn.

Het is niet bedoeld als aanbeveling voor beginners want je wilt niet weten hoeveel uur dit wel gekost heeft.
LibreOffice 7.4.3.2 op openSUSE Leap 15.4
Plaats reactie