Copy data from previous row

Discuss the database features
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Copy data from previous row

Post by UnklDonald418 »

MS Acess has a handy feature used to simplify data entry that I can't seem to find in Base. If you press Ctrl+' it will enter the value from the same column in the previous row into the current cell.

That feature is also available in Excel and I have recorded a macro in Calc that emulates that feature. However, that macro uses the dispatcher which apparently isn't available in Base.

I am currently using cut and paste, but the single key solution would save a lot of time.

Is there something like this for Base?
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
MTP
Volunteer
Posts: 1620
Joined: Mon Sep 10, 2012 7:31 pm
Location: Midwest USA

Re: copy data from previous row

Post by MTP »

There is not anything simple.

One idea could be to have a hidden form in your form document with the data source SQL [SELECT * FROM "YourTableName" WHERE "PrimaryKey" = (SELECT MAX("PrimaryKey") FROM "YourTableName")]

Then your macro could refresh the hidden form and copy the information from it. Or, the macro could run that SELECT query directly and pull the needed information out of the returned resultset object. Either way, then the macro could paste the information into the field or fields you are using.
OpenOffice 4.1.1 on Windows 10, HSQLDB 1.8 split database
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: copy data from previous row

Post by RPG »

Hello
UnklDonald418 wrote:Is there something like this for Base?
Maybe you want clone a record.

Look in this search action
search.php?keywords=clone+records&terms ... mit=Search

And maybe special this link
viewtopic.php?f=100&t=40580

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: copy data from previous row

Post by UnklDonald418 »

Thanks MTP and Romke for your responses.

I was hoping for a simple solution, but that doesn't appear to be possible at this time, and I'm not inclined to put a lot of effort into this right now.

I am a beginner when it comes to Object Oriented Programming and writing Macros. While I have learned a lot from this forum, I still have a long way to go. Even so, it didn't seem like it would be such a big deal based on what I learned from a previous question I had asked
[Solved] Help reading Base field contents into a variable
viewtopic.php?f=20&t=78055
That macro is able to extract the contents of a Base field and place it into the URL of a Button Control. So it doesn't appear to be too much of a jump to save it into another row. Of course there are some sticky details that I have been unable to work out. First of all the macro accesses the table through a Button Press Event, but I want to do it from a Key Press which apparently doesn't trigger an Event that I can use to find the data. Next, while the working macro does allow me to know what row number is currently in focus, it doesn't tell me which column. Then even if I were able to find the pertinent data, I still don't know to know how the place the data in its proper place.

So, for now I will leave this thread open and unsolved on the slim chance someone out there has a concrete solution, or until the problem eventually bothers me enough to work out a solution.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: copy data from previous row

Post by Villeroy »

2 simple methods to clone a record without macro: download/file.php?id=22304
One form lets you enter preset values that are copied to every new record.
The other form lets you select an existing record and then enter a new one based on the selected one.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: copy data from previous row

Post by UnklDonald418 »

Thanks Villeroy for your reply.

Actually I do make use of list boxes and combo boxes where I know I will have repeating text data to enter. But Ctrl+' is handy for those situations where repeats are less common, and especially for numeric entries that don't work well in list boxes.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Copy data from previous row

Post by UnklDonald418 »

I haven't given up on this, it just hasn't been a high priority item.
I recently found Romke's
[Example] Updating in a gridcontrol with macros
viewtopic.php?f=13&t=36716
That link provided some of the code that I needed to write the following Macro

Code: Select all

Rem This Macro copies the contents of the previous row-column into the current row-column
Rem At this point it isn't the universal solution I am seeking but it is a start.
Rem  This Version will only copy fields containing Text in a single column which must be called by name (“MyColumnName” in this example)
Rem This version leaves it up to the user NOT to assign the Macro to a key field.
Rem It will not work on a row that is currently being entered.   The data must be saved into the table first
Rem This Macro is called by assigning it to a key (i.e. Alt-X) in Tools->Customize->Keyboard 
Rem By using a small Sub to call the main Macro it can be used to copy data in more than 1 column
Rem  Of course each column will have to have a separate Sub and a different key assignment.
Rem  The caveat of using more than one Sub is hitting the wrong key and copying in the wrong column

Sub CopyMyColumnName
CopyPreviousRowData(“MyColumnName”)
End Sub

Sub CopyPreviousRowData(SColName as String)
Dim cRow As Long, pRow As Long
Dim oForm AS object, oGrid As Object, oControlSource As Object, oDestControl As Object
Dim sData AS String, sFormName As String, sGridName As String, sColName As String
Dim sImpName AS String
Dim bTest AS Boolean
Dim oRowset As Object, oContainerView As Object
Dim aNamelist(2) as String

'First Define Form Grid and Column Names
aNamelist = ThisComponent.CurrentController.Model.DrawPage.Forms.getElementNames()
sFormName = aNamelist(0)
oForm = ThisComponent.CurrentController.Model.DrawPage.Forms.getByName(sFormName)
aNamelist = oForm.getElementNames()
sGridName = aNamelist(0)
sColName = "AlternateClass"

'now set the objects needed to access the data

oGrid = oForm.getByName(sGridName)
oControlSource = oGrid.getByName(sColName)

'get current data 
cRow = oForm.Row  'cRow = oForm.getByName(sGridName).RowSet.Row also works
'sData = oControlSource.Text

'make sure we're not on the first row
'  debugging stuff MsgBox "Current Row is: " & cRow & "  " & sColName & " Contents: " & sData
If cRow > 1 Then 
  pRow = cRow-1
Else
  MsgBox "No Previous Row"
  
  Exit Sub
End If

'double check that this is going to work
    if oGrid.hasbyname(sColName) then 
		oDestControl=oGrid.getbyname(sColName)
	else
		Print " the control name: " & sControlName & " does not exist"
		end
	end if
	
'now set the rowset to the previous row and get the field data into sData
oRowset=oGrid.rowset
oContainerView=thiscomponent.getCurrentController.getcontrol(oGrid)
oRowset.absolute(pRow)

sData = oGrid.getByName(sColName).Text
'debugging stuff  MsgBox "Current Row is: " & pRow &  "  " & sColName &  "  Contents: " & sData

'move back to original rowset
oRowset.absolute(cRow)
'debugging stuff  MsgBox "Current Row is: " & cRow &  "  " & sColName &  " New Contents: " & sData

'verify that field contains Text and update field contents
If oDestControl.DataFieldProperty = "Text" Then
oDestControl.Text = sData
	oDestControl.commit
		with oRowset
			if .isnew then
				 .insertrow
			elseif .ismodified then
			 	   .updaterow
			end if
		end with
End If
End Sub
If I assign this Macro to a Key (I'm using Alt-x) this pastes the contents of the previous row-column into the currently focused row-column with the following conditions

1) It is limited to a single column whose name must be manually entered to replace “MyColumnName”.
2) The field must contain only Text
3) The cursor must be on an existing row, it can't be used on a row that is still in the process of being entered.
4) This assumes that the Grid is the first one on the Form. I haven't tried it but you should be able to edit the sGridName assignment to reach other grids.


So my questions are:
To help resolve condition 1 how do I find which column contains the cursor?
For condition 2 how do I find the field properties so that it can copy other data types? Related to this how can I check if the column is a key field?
Condition 3 may be a tougher nut to crack. Using MRI I find that during data entry the current row number is 0 until it is saved into the table. Where is the data stored before being saved into the table?
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

I have no solution for your problem. I can only try to answers some questions.

The column in a grid.
When you work with macro's in a form in OOo then it is important to know if you are working with a object what is a model or what is a view of the same model. In a data-form most objects you get with getbyname are models. When you are working with
oDoc.currentcontrol.getcontrol(oControlModel) then you get the view. I use most of the time:
oControlmodel
oControlview

This all is for the things you see on your monitor. When you want knew which column you access in a oGridcontrolModel then you have to find the view of that control. You can find here the interfaces.
https://www.openoffice.org/api/docs/com ... XGrid.html
As far as I remembe you set the focus to the complete grid and point then to a column and a row.

Where the data is stored before it is committed? I think it is in a buffer.

My own experience with all the macro's is: First you have to understand all normal working of OOo before you start with macro's. I did have read a lot of the help file and other stuff before I started with macro's. And then I did learn later time over time things what can be done easy without macro's.

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
User avatar
MTP
Volunteer
Posts: 1620
Joined: Mon Sep 10, 2012 7:31 pm
Location: Midwest USA

Re: Copy data from previous row

Post by MTP »

I think the answer to (1) is in another post by RPG: Re: Possible to highlight rows in a tablegrid form control?

If I'm reading it correctly, you'd get the column something like this

Code: Select all

oGridView = ThisComponent.getCurrentController().getControl(oGrid)
oColumn = oGridView.getSelection
Print oColumn.Name
MRI should be able to help you with (2).
For (3) I think you'd have to insert some text (a blank space, say), then oForm.insertrow(), then run the rest of your macro.
I believe you're on the right track with (4), you can manually input the name of the Grid, or use a different number than the first one in the list.

I hope that's at least a little help, good luck with getting this working how you want!
OpenOffice 4.1.1 on Windows 10, HSQLDB 1.8 split database
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

Well, I think I have found a viable solution for any type of control bound to any simple field type (text, number, boolean, date, time). FillDown.odb from yesterday's posting viewtopic.php?f=13&t=79225&p=366009#p366009
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Copy data from previous row

Post by UnklDonald418 »

Thank You MTP , the code you provided got me on the right track. When I added

Code: Select all

oGridView = ThisComponent.getCurrentController().getControl(oGrid)
nCurColNum = oGridView.CurrentColumnPosition
and replaced all the getByName() with getByIndex(nCurColNum) it goes to the correct column without needing to know its name. I have been using MRI for 2) but I still need to spend some time trying to make use of what I learned. I will also try your suggestion for 3).

Villeroy Thanks for your reply. I have been following that thread since both our goals are similar. I did try your Filldown.obd. The problem there is that it requires the user to move the focus from typing on the form to click a button. The whole point of this Macro is to allow the user to copy the data without moving their hands from the keyboard. Once they learn the <Alt> or <Ctrl> key combination it can significantly increase the speed of the data entry process.

Once I have further investigated MTP's suggestions I will post an updated version, with more questions.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

I could not find a way to get the form controller without using any event of a form or control. If somebody finds a way to reference the currently selected form control from scratch, it would be very easy to use my code with a keyboard shortcut.
It is possible to assign a keyboard shortcut (Alt+Underlined Character) to a push button or other controls. Edit: Oh, this access method focusses the button even if "take focus" is turned off. I think it is possible to overcome this problem.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

I do not know if I under stand the post of Villeroy correct. But you can find the formcontroller without an event:

Code: Select all

Sub find_formcontroller
dim oFormmodel
dim oFormView
oFormmodel=thiscomponent.drawpage.forms.getbyname("Form")
oFormView=thiscomponent.getcurrentcontroller.getformcontroller(oFormmodel)
print oFormView.currentcontrol.model.name
print oFormmodel.name
end sub
Benitez does also works sometimes without event in his Basetools. See the module forms and then the functions : Me, MeModel, MeControl.

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

Yep, this surely works. But it requires that your form is named "Form". I hope to avoid this kind of precondition so the same code works with any selected control on any form, subform or subsubform. From the normal document controller you can easily refer to the currently selected object regardless of naming conventions.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

I think you can use all names. But it is better to test it for focus when you do not work with an event. I did test it with two data-forms and it does not change to an empty currentcontrol when the dataform does not have the focus.

Code: Select all

Sub find_formcontroller
dim oFormmodel
dim oFormView
oFormmodel=thiscomponent.drawpage.forms.getbyname("Thisname").getbyname("I_can_use_all_names")
oFormView=thiscomponent.getcurrentcontroller.getformcontroller(oFormmodel)
print oFormView.currentcontrol.model.name , oFormmodel.name
end sub
Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

"No such element exception ..." because of .getByName("Thisname")

ThisComponent.getCurrentSelection() refers to the document layer pointing to the objects that would be selected if no form element would have the focus. In a Writer document the current selection is always an array of text ranges or some shape but not a form control.
A form controller has one ActiveControl but before you can access the form controller you need a reference to the form it belongs to -- catch 22
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello Villeroy

As you I think there is no solution but I will point you to the property: HideInactiveSelection. Each control does have this property. I have used it once when I want work with the selection in a textbox while working in a dialog. The text box was in a form.

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

I have no idea what that property does. I can not find any difference so I tend to ignore this property. When I run MRI against the current selection I get a text ranges collection (ImplementationName="SwXTextRanges") in any case.
How do I get the active control of the currently active form, no matter how that form is named, if it is a subform or not, no matter how many forms are attached to the DrawPage's collection of forms?
Something like ...
ThisComponent.CurrentController.FormController.ActiveControl
... which does not work because there is no FormController for the collection of forms. A FormController refers to one particular (sub-) form which has to be known beforehand. I think we need some function getActiveForm(oDocController)

Code: Select all

oDocController = ThisComponent.getCurrentController()
oForm = getActiveForm(oDocController) '<--- this function is missing
oFormController = oDocController.getFormController(oForm)
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Copy data from previous row

Post by UnklDonald418 »

Thanks Romke for your input

I'm not sure I understand what you are saying.
 I did test it with two data-forms and it does not change to an empty currentcontrol when the dataform does not have the focus.
I did try your Macro “find_formcontroller “ but when I attempt to run it I get :
Temp.jpg

Here is the current form of the Macro that now is able to determine which column contains the cursor.

Code: Select all

Rem This Macro copies the contents of the previous row-column into the current row-column
Rem At this point it isn't the universal solution I am seeking but it is a start.
Rem It has only been checked when using a MainForm
Rem This Version will only copy fields containing Text , simple dates and times.  
Rem I try to capture errors but I'm sure I've missed some
Rem This version leaves it up to the user NOT to use the Macro in a key field.
Rem It will not work on a row that is currently being entered.  The data must be saved into the table first
Rem This Macro is called by assigning it to a key (i.e. Alt-X) in Tools->Customize->Keyboard

Sub CopyPreviousRowData1

Dim cRow As Long, pRow As Long, nData As Long, nCurColNum As Long,nCols As Long
Dim oForm AS object, oGrid As Object, oControlSource As Object, oDestControl As Object
Dim oRowset As Object, oContainerView As Object
Dim sData AS String, sFormName As String, sGridName As String, aNamelist(2) as String
Dim sImpName AS String
Dim bFlag AS Boolean
Dim dData As Date

'First Define Form Grid and Column Names
aNamelist = ThisComponent.CurrentController.Model.DrawPage.Forms.getElementNames()
sFormName = aNamelist(0)
oForm = ThisComponent.CurrentController.Model.DrawPage.Forms.getByName(sFormName)
aNamelist = oForm.getElementNames()
sGridName = aNamelist(0)
bFlag = FALSE     'initialize flag to check if cursor is on an incomplete row

'now get the objects needed to access the data
oGrid = oForm.getByName(sGridName)
oGridView = ThisComponent.getCurrentController().getControl(oGrid)
nCols = oGrid.rowSet.Columns.Count
nCurColNum = oGridView.CurrentColumnPosition

'get current row
cRow = oForm.Row  'cRow = oForm.getByName(sGridName).RowSet.Row also works

'make sure we're not on the first row

Select Case   cRow
Case   > 1 
  pRow = cRow-1
Case  1
    MsgBox "No Previous Row" & CHR$(7)
    Exit Sub
Case  < 1
  bFlag = TRUE
  pRow = oForm.RowCount
  cRow = pRow + 1
End Select

oDestControl=oGrid.getbyIndex(nCurColNum)
	
sDataFieldProperty = oDestControl.DataFieldProperty
	
'now set the rowset to the previous row and read the field data 
oRowset=oGrid.rowset
oContainerView=thiscomponent.getCurrentController.getcontrol(oGrid)
oRowset.absolute(pRow)
Select Case sDataFieldProperty
Case "Text"
  sData = oGrid.getbyIndex(nCurColNum).Text
Case "Date"
  dData = oGrid.getbyIndex(nCurColNum).CurrentValue
Case "Time"
  tData = oGrid.getbyIndex(nCurColNum).CurrentValue
Case "EffectiveValue"
  nData = oGrid.getbyIndex(nCurColNum).CurrentValue
  sData = nData
Case Else
  MsgBox "Sorry this data type is not currently supported"
  Exit Sub 
End Select


' see if cursor is on an incomplete row
If bFlag then   
' oForm.insertrow()  ' this doesn't work
  MsgBox "Sorry copying data here is currently not supported"
  Exit Sub
End If
'move cursor back to original rowset
oRowset.absolute(cRow)

'verify that field contains Text and update field contents

Select Case sDataFieldProperty
	Case  "Text"
	   		 oDestControl.Text = sData
	Case "Date"
	 	oDestControl.Date = dData
	Case "Time"
		oDestControl.Time = tData
'	Case "EffectiveValue"     ' commented out because this doesn't work
'	 		oDestControl.Text = nData
	Case Else
		 MsgBox "Sorry this data type is not supported"
		 Exit Sub
End Select

	oDestControl.commit
		with oRowset
			if .isnew then
				 .insertrow
			elseif .ismodified then
			 	   .updaterow
			end if
		end with

End Sub

I still am unable to copy data into a row that hasn't already been saved into the form. I did try the suggestion oForm.insertrow() but that generates an error message
Temp1.jpg
Temp1.jpg (18.88 KiB) Viewed 9429 times
While I haven't done a great deal of testing it does work for me to copy text, simple dates, and times. When the DataFieldProperty returns "EffectiveValue" it seems to indicate numerical data. While I can read the numerical value from the previous row into a variable “nData” I haven't found a way to save it into the current row.
As a safety precaution I would like to be able to determine if the cursor is on a field containing a key but I haven't found where to read that property.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

This is a new version of my Python macro. Open form "PythonCode" and push the button to install and overwrite any previous version. The push button on the 2 data forms can be triggered by shortcut Alt+C.
This solution requires that the grid control calls another event routine control_gainedFocus which stores itself in a global variable. The button's routine did not change very much. It works with bound controls in a grid and with stand-alone controls as well but the latter require a more tedious setup.

Mysteriously, the boolean field which worked well with the previous click-button version does not work properly anymore.
I added a time stamp field to the database. Time stamp fields raise an attribute error. I disabled the use of time stamps.
Another change compared to the previous click button version is that any unsaved record will be stored now before navigating to the next record.
Attachments
FillDown2.odb
(37.98 KiB) Downloaded 237 times
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

Villeroy I have download the second example but it does not work for me. It locks LibreOffice.

UnklDonald418 I do not understand your code. I think the link below will help you to do a lot of those things you want do and need to. I think also you must re-define your wishes to things you can do.

https://www.openoffice.org/api/docs/com ... oller.html

When you understand the interfaces formcontroller and formoperations then it wil be more easy for you. When you also understand what is possible and not possible then you can maybe succeed. You will see your end code is maybe nearly the same as the code of Villeroy given in Python. I think it is nice code.

On this moment I do not have time to work on this code. But I do think more to this. The works only in a grid and for value who can easy be convert to a string. It was for me more the idea then really good code.

Code: Select all

Sub Find _a_Nice_Name
dim oFormmodel
dim oformmodel2
dim oFormView
dim oFormView2
dim oGridModel,oGridView,oControlinGridView
dim sValue,Weneedthisalso
oFormmodel=thiscomponent.drawpage.forms.getbyname("Thisname")
oformmodel2=oformmodel.getbyname("I_can_use_all_names")
oGridModel=oformmodel2.getbyname("Table Control  1")
oGridView=thiscomponent.currentcontroller.getcontrol(oGridModel)
oControlinGridView=oGridView.getbyindex(oGridView.currentcolumnposition)
oControlinGridView.setfocus
oFormView2=thiscomponent.getcurrentcontroller.getformcontroller(oFormmodel2)
oFormView2.FormOperations.execute(4) 'Move to previous

sValue=oControlinGridView.model.boundfield.getstring
oFormView2.FormOperations.execute(5) 'Move to Next
oControlinGridView.model.boundfield.updatestring(sValue)
oFormView2.FormOperations.commitCurrentControl
oFormView2.FormOperations.commitCurrentRecord(Weneedthisalso)

end sub
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

Maybe the code below is what the OP asked. I have not test it a lot so be careful. I found not all methodes or properties did work as expected. It can also not be used for all controls. I have it made it for text box. First in a grid-control and later for a standalone text-control,

Romke

Code: Select all

Sub CopyFieldabove(oEvent)
dim oformmodel2
dim oFormView2
dim oGridModel,oGridView,oControlinGridView
dim sValue
dim oControlViewwewantchange
dim Operation as object
dim oSelection
Operation =com.sun.star.form.runtime.FormFeature

dim oButton
oButton=oEvent.source
' We handle first here the button.
'Check if the button can not get focus on click.
if  oButton.implementationname="com.sun.star.comp.forms.OButtonControl"  and oButton.model.FocusOnClick = true then
	oButton.model.FocusOnClick=false
	print "Select first the field on what you want work again"
	end
end if

oformmodel2=oButton.model.parent 'We have now the form

' Be aware that a textbox in a gridcontrol is not the same as a stand alone textbox.
' This works for a text I Have it not test for big text and also a lot.


oFormView2=thiscomponent.getcurrentcontroller.getformcontroller(oFormmodel2) ' We have now the form controller
if  oFormView2.FormOperations.isEnabled(Operation.MoveToFirst) then
' We are not on the first record
	
	' Test for the good control we need special for a grid
	oControlViewwewantchange=oFormView2.currentcontrol
	if oControlViewwewantchange.implementationname= "com.sun.star.comp.dbu.SbaXGridControl" then
	oControlViewwewantchange=oControlViewwewantchange.getbyindex(oControlViewwewantchange.currentcolumnposition)
	end if
	
' Now we have the control	
	oSelection=oControlViewwewantchange.getselection ' Store the selection 
	'oFormView2.FormOperations.execute(Operation.SaveRecordChanges) ' 
	oFormView2.FormOperations.execute(Operation.MoveToPrevious) 'Move to previous record
	sValue=oControlViewwewantchange.model.boundfield.getstring ' Take the value
	oFormView2.FormOperations.execute(Operation.MoveToNext) 'Move to Next record 
	' now the new part
	oControlViewwewantchange.setselection(oSelection) ' Set the selection again
	oControlViewwewantchange.insertText(oSelection,sValue) ' Bring in the value
	oSelection=oControlViewwewantchange.getselection 'Get the new selection
	oControlViewwewantchange.model.text=oControlViewwewantchange.gettext  ' This is also real strange we need it
	oControlViewwewantchange.model.commit ' Strange we need it

	oFormView2.FormOperations.execute(Operation.SaveRecordChanges)
	oControlViewwewantchange.setSelection(oSelection)

end if
end sub
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Copy data from previous row

Post by UnklDonald418 »

Thanks again Romke for all your attention to this.

When I run your macro “CopyFieldabove”, I can see that the cursor in the grid does move up to the previous row, but unfortunately when it reaches

Code: Select all

sValue=oControlViewwewantchange.model.boundfield.getstring ' Take the value
I get an error message.
Temp.jpg
Temp.jpg (12.55 KiB) Viewed 9365 times
I appears that we have swapped positions, because now I don't understand your code. I suppose I could go back and add more comments to my code, but I'm not sure how helpful that would be.
You had advised
When you understand the interfaces formcontroller and formoperations then it wil be more easy for you.
The link you provided was for a page in the Developer's Guide. I find that Guide very frustrating since it gives very few examples of how to use the information provided, and when they do the examples are coded in Java. Yet most of what I've seen are macros programmed in Basic, including all the macro programming tutorials/guides. So I don't find the Developer's Guide very helpful.

For anyone doing very much data entry what I am trying to accomplish with this macro can be a real time saver. I thought maybe I was the only one who had need for this, but when I saw someone else ask for a very similar macro I returned to this thread with what I have found so far.
In its current form I can use the macro to copy text data which currently for me is mainly what I am doing, Now that I'm retired I don't have much need to copy numerical data (I don't have any money). As time allows I will continue to look for a better solution.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
User avatar
RoryOF
Moderator
Posts: 35064
Joined: Sat Jan 31, 2009 9:30 pm
Location: Ireland

Re: Copy data from previous row

Post by RoryOF »

Andrew Pitonyak uses boundfield in some of his macros. I cannot vouch for the capitalisation of either it or model. In the API definitions I have just seen boundfield is BoundField and model may also need a capital letter. But it is 0400 here and I'm going back asleep!
Apache OpenOffice 4.1.15 on Xubuntu 22.04.5 LTS
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

I can only gues why it can not work for. Maybe your control a not connect to a datafield.
Maybe the following code is working.

Code: Select all

	sValue=oControlViewwewantchange.model.currentvalue ' Take the value
I cannot see and want not see your data form. It is to you to learn how it works. I think it is important to get a good idea how the API is working and yes it is terrible.

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

Error "property not found: BoundField" simply means that the control in question has no such thing as a bound field. This happens when your push button takes the focus and becomes the current control. A button can not have any bound field. We've been through that already. The macro can not operate on the currently selected form control and let the button steal the focus. This implies that you use the mouse which you do not want.
Either you use a better database frontend than Libre/OpenOffice forms or you use the mouse for this functionality.

Another way with one button per field and the column name in "additional info":
FillDown3.odb
(29.87 KiB) Downloaded 237 times
Again, open the Python form and push the button, confirm overwriting. Then open the other form. This Python module includes both solutions with a single mouse-click button not stealing the focus and with one specific button per field.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello Villeroy

Your code did now work for me. The only problem now was: I must connect each button again to the macro. Then both methods did work.

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
UnklDonald418
Volunteer
Posts: 1566
Joined: Wed Jun 24, 2015 12:56 am
Location: Colorado, USA

Re: Copy data from previous row

Post by UnklDonald418 »

This morning I did try

Code: Select all

   sValue=oControlViewwewantchange.model.currentvalue ' Take the value
now the error message changed to
Temp.jpg
Temp.jpg (13.16 KiB) Viewed 9322 times
I did try changing to sValue="Test" to see what would happen but then it stops at

Code: Select all

 oControlViewwewantchange.setselection(oSelection) ' Set the selection again
with an error message
Temp1.jpg
Temp1.jpg (12.92 KiB) Viewed 9322 times
I guess all that does is verify that the data isn't found there.
If your problem has been solved, please edit this topic's initial post and add "[Solved]" to the beginning of the subject line
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
RPG
Volunteer
Posts: 2261
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Copy data from previous row

Post by RPG »

Hello

I think it is time to start to learn debugging code. I use the API also for debugging code. Start study here. Learn also all the properties of the controls you have in your form. I use a lot of print statements. In your code print the name of your control. When you want continue with macros then you have to study that link. You have to study the language BASIC but also what you can do with the API.

I have modified the code a little more.

Code: Select all

Sub CopyFieldabove(oEvent)
dim oformmodel2
dim oFormView2
dim sValue
dim oControlViewwewantchange
dim Operation as object
dim oSelection
Operation =com.sun.star.form.runtime.FormFeature

dim oButton
oButton=oEvent.source
' We handle first here the button.
'Check if the button can not get focus on click.
if  oButton.implementationname="com.sun.star.comp.forms.OButtonControl"  and oButton.model.FocusOnClick = true then
		oButton.model.FocusOnClick=false
		print "Select first the field on what you want work again"
		end
end if


oformmodel2=oButton.model.parent 'We have now the form

' Be aware that a textbox in a gridcontrol is not the same as a stand alone textbox.
' This works for a text I Have it not test for big text and also a lot.


oFormView2=thiscomponent.getcurrentcontroller.getformcontroller(oFormmodel2) ' We have now the form controller
if  oFormView2.FormOperations.isEnabled(Operation.MoveToFirst) then
' We are not on the first record
	' Test for the good control we need special for a grid
	oControlViewwewantchange=oFormView2.currentcontrol
	if oControlViewwewantchange.implementationname= "com.sun.star.comp.dbu.SbaXGridControl" then
		oControlViewwewantchange=oControlViewwewantchange.getbyindex(oControlViewwewantchange.currentcolumnposition)
	end if

	if  hasunointerfaces(oControlViewwewantchange.model,"com.sun.star.form.XBoundComponent") then
	' Now we have the control	 and we know it does has a bound field
		oSelection=oControlViewwewantchange.getselection ' Store the selection 
		'oFormView2.FormOperations.execute(Operation.SaveRecordChanges) ' 
		oFormView2.FormOperations.execute(Operation.MoveToPrevious) 'Move to previous record
		sValue=oControlViewwewantchange.model.boundfield.getstring ' Take the value
		oFormView2.FormOperations.execute(Operation.MoveToNext) 'Move to Next record 
		' now the new part
		oControlViewwewantchange.setselection(oSelection) ' Set the selection again
		oControlViewwewantchange.insertText(oSelection,sValue) ' Bring in the value
		oSelection=oControlViewwewantchange.getselection 'Get the new selection
		oControlViewwewantchange.model.text=oControlViewwewantchange.gettext  ' This is also real strange we need it
		oControlViewwewantchange.model.commit ' Strange we need it
	
		oFormView2.FormOperations.execute(Operation.SaveRecordChanges)
		oControlViewwewantchange.setSelection(oSelection)
	else Print "We cannot work on this control"
	end if 
end if
end sub
How save is it?
I think it is not good to use the code in complex forms. In complex forms you cannot be sure if the macro points to the good control. In a simple form with a gridcontrol I think the form works good.

Copy the code
I think it is not good to copy parts of this code. Special not if you can not debug your own code. The code is made for an event from a button. You can use an event from a control but I have not test it.

I think my code but also the code of Villeroy is a nice code to learn how to use macro's. Also you can learn that it is not easy to copy simple parts of the code. Sometime even copy the complete code cannot work when you start the code wrong.

Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
User avatar
Villeroy
Volunteer
Posts: 31345
Joined: Mon Oct 08, 2007 1:35 am
Location: Germany

Re: Copy data from previous row

Post by Villeroy »

This is why I try to write macros that can be used without any adjustments.
Don't touch my Python code, point your buttons to the right routines, add the right field names to the button's "additional info" and use button labels with tilde in order to add your own Alt+Key shortcuts.
It can not be used with time stamp fields and it behaves strange with booleans and it is not carefully programmed but it should be usable anyway.
Please, edit this topic's initial post and add "[Solved]" to the subject line if your problem has been solved.
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Post Reply