The parameter of the CloseSubComponent2
macro is the subcomponent (Form, Report, …).
For a button that is inside the form document and implements the form closing, the code is as follows (CloseMe
):
Option Explicit
Sub CloseMe(oEvent)
Dim oDoc as Object
oDoc = GetParentObject(oEvent.Source.Model, "com.sun.star.document.OfficeDocument")
CloseSubComponent2 oDoc
End Sub
Function GetParentObject(Byval obj as Object, Byval srvName as String)
Do Until obj.supportsService(srvName)
obj = obj.Parent
Loop
GetParentObject = obj
End Function
' Close any subcomponent (Form, Report, Table, Query)
Sub CloseSubComponent2(ByVal oComp As Object)
Dim oFrame As Object
If oComp.supportsService("com.sun.star.document.OfficeDocument") Then
oFrame = oComp.CurrentController.Frame
oComp.setModified False ' Cancel the dialog if changes are not saved
Else
oFrame = oComp.Frame
End If
CreateUnoService("com.sun.star.frame.DispatchHelper").executeDispatch(oFrame, ".uno:CloseDoc", "", 0, Array())
End Sub
Well, of course I understand this is a versatile (generic) solution.
Function GetParentObject(Byval obj as Object, Byval srvName as String)
Do Until obj.supportsService(srvName)
obj = obj.Parent
Loop
GetParentObject = obj
End Function
' Close any subcomponent (Form, Report, Table, Query)
Sub CloseSubComponent2(ByVal oComp As Object)
Dim oFrame As Object
If oComp.supportsService("com.sun.star.document.OfficeDocument") Then
oFrame = oComp.CurrentController.Frame
oComp.setModified False ' Cancel the dialog if changes are not saved
Else oFrame = oComp.Frame
End If
CreateUnoService("com.sun.star.frame.DispatchHelper").executeDispatch(oFrame, ".uno:CloseDoc", "", 0, Array())
End Sub
But
For this particular OP’s question we get the closing with 2 lines
Option Explicit
Sub OpenCloseForm(evt As Object)
Dim f As String, titulo As String
f = evt.Source.Model.Tag
ThisDatabaseDocument.FormDocuments.getByName(f).open
REM CLOSE THIS FORM:
titulo = Mid(thisComponent.Title, InStr(thisComponent.Title, ":") + 2)
ThisDatabaseDocument.FormDocuments.getByName(titulo).close
End Sub
This code is not reliable!
The document title can be changed at any time.
Using the setTitle
method, the title can be changed after the form has been opened.
Let’s take this to context….
OP wanted a macro called from buttons in several forms to
- open some other form passed as a parameter;
- close caller form.
As the thread was not (and it’s not) marked Solved, just tried to contribute.
Of course neither user or developer are supposed to rename the forms via code, right?
As said above: of course I understand this is a generic solution.
It’s not about renaming the form.
We can dynamically change the title during work and reflect some useful information in it. I’ve seen such applications.
But let’s suppose during operation code changes the Title from actual “fCaller” to
“Useful Info”.
When the closing routine executes
titulo = Mid(thisComponent.Title, InStr(thisComponent.Title, ":") + 2)
titulo does not yet reflect this new Title?
Because it is not yet saved?
Let’s check.
Add a line
ThisComponent.Title = "Useful Info"
before the line
titulo = ...
Well… OP asks for
- open another form as a parameter;
- close caller form.
Sub AbrirFormularioMenu(Nameform As String)
ThisDatabaseDocument.FormDocuments.getByName(Nameform).Close
ThisDatabaseDocument.FormDocuments.getByName(“Menu_All”).Open
End Sub
But understood
switch_forms.odb (20.0 KB)
EDIT: This solution does not need any of ThisComponent
nor ThisDatabaseDocument
nor controllers, frames. Every object is derived from the calling form control. It closes embedded and stand-alone forms. It loads embedded forms or reports even if they are organized in a folder structure as in Credit/Creditors_Form
or Credit/Creditors_Report
2 little issues:
- Routine OpenEmbedded has the same name as its embedding module. This should be avoided because you can not call this routine directly from another module. Rename the module or the routine.
- in the same module, getDBDocument assumes that it is called from a button or some other stand-alone control:
oForm = oModel.getParent()
.
If you replace this line withoForm = getParentObject(oModel, "com.sun.star.form.component.DataForm")
, the routine will also work with form controls embedded in table controls.