Send a parameter to a macro from a button

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, :ok: 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.

NewTitle

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

  1. open some other form passed as a parameter;
  2. 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

  1. open another form as a parameter;
  2. close caller form.
Sub AbrirFormularioMenu(Nameform As String)
ThisDatabaseDocument.FormDocuments.getByName(Nameform).Close
ThisDatabaseDocument.FormDocuments.getByName(“Menu_All”).Open
End Sub

But :ok: understood :+1:

1 Like

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:

  1. 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.
  2. 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 with oForm = getParentObject(oModel, "com.sun.star.form.component.DataForm"), the routine will also work with form controls embedded in table controls.
2 Likes