Copy data from previous row
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Copy data from previous row
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?
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: copy data from previous row
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.
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
Re: copy data from previous row
Hello
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
Maybe you want clone a record.UnklDonald418 wrote:Is there something like this for Base?
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
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: copy data from previous row
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.
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: copy data from previous row
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.
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: copy data from previous row
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.
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: Copy data from previous row
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
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?
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
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: Copy data from previous row
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
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
Re: Copy data from previous row
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
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!
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
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
Re: Copy data from previous row
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: Copy data from previous row
Thank You MTP , the code you provided got me on the right track. When I added
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.
Code: Select all
oGridView = ThisComponent.getCurrentController().getControl(oGrid)
nCurColNum = oGridView.CurrentColumnPosition
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: Copy data from previous row
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.
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Re: Copy data from previous row
Hello
I do not know if I under stand the post of Villeroy correct. But you can find the formcontroller without an event:
Benitez does also works sometimes without event in his Basetools. See the module forms and then the functions : Me, MeModel, MeControl.
Romke
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
Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
Re: Copy data from previous row
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Re: Copy data from previous row
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.
Romke
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
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
Re: Copy data from previous row
"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
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Re: Copy data from previous row
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
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
Re: Copy data from previous row
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)
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: Copy data from previous row
Thanks Romke for your input
I'm not sure I understand what you are saying.
Here is the current form of the Macro that now is able to determine which column contains the cursor.
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 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.
I'm not sure I understand what you are saying.
I did try your Macro “find_formcontroller “ but when I attempt to run it I get :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.
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 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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: Copy data from previous row
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.
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Re: Copy data from previous row
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.
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
Re: Copy data from previous row
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
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
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: Copy data from previous row
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
I get an error message.
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
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.
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
You had advised
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.When you understand the interfaces formcontroller and formoperations then it wil be more easy for you.
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: Copy data from previous row
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
Re: Copy data from previous row
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.
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
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
Romke
LibreOffice 24.8.5.2 on openSUSE Leap 15.6
Re: Copy data from previous row
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": 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.
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": 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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice
Re: Copy data from previous row
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
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
-
- Volunteer
- Posts: 1566
- Joined: Wed Jun 24, 2015 12:56 am
- Location: Colorado, USA
Re: Copy data from previous row
This morning I did try
now the error message changed to
I did try changing to sValue="Test" to see what would happen but then it stops at
with an error message
I guess all that does is verify that the data isn't found there.
Code: Select all
sValue=oControlViewwewantchange.model.currentvalue ' Take the value
Code: Select all
oControlViewwewantchange.setselection(oSelection) ' Set the selection again
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
Apache OpenOffice 4.1.14 & LibreOffice 7.6.2.1 (x86_64) - Windows 10 Professional- Windows 11
Re: Copy data from previous row
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.
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
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
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
Re: Copy data from previous row
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.
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
Ubuntu 18.04 with LibreOffice 6.0, latest OpenOffice and LibreOffice