ScriptForge Database Demo

I was not looking to create a full blown demo. I just thought it important to those looking at this post to find something that works. I already stated in my original comment that I personally believe it is preferable to learn and use the API. You could take it and modify it how you want but it needs some work - just do not post something that is just slapped together as in you original post. I do NOT want this as it is to be a tutorial - for that it needs considerable work including error handling! Currently it is only some sample code executed by buttons on a form.

That is for the user to decide. It is easy enough to extract and do so. For posting here it is best to embed in the document to avoid multiple items and more instructions.

Again, did this to offer multiple options within the code. You can change as there are other methods as shown in the code.

Wondering just what you are doing. You have stated your time is limited over the last days but enough time to ask for others to resolve issues which may not even be issues! Have stated in the FIRST comment that open_database works. So why does that need to be resolved?

Also creating a DB is a one line replacement in that same routine. See → CreateBaseDocument

Have you even tried either of these?

None of the macros (including the Form macro) close documents, possibly the only thing not working but database access needs to run macros where appropriate. The original code was from the Database service but it needed to be modified to allow something to happen.

That has nothing to do with opening or creating a database but is avoiding the question(s) - just a diversion. Roll up you sleeves and do some testing as I have done. Have presented you with many working routines already - a good basis to go forward. As for me, the API is preferable!

Edit:

Just to test, only took me a few minutes (couple of dumb mistakes with naming) to get form closing to work. See → CloseFormDocument

Just combined that with code from get_form.

1 Like

How can the form be closed without explicitly naming either the BaseForm or Form, similar to how ThisDatabaseDocument is used? (Assume macro is run from within the open TryCode form.) Thinking Document service should be able to use ThisComponent to identify the BaseForm and Form.

def close_form(args=None):
    bas = CreateScriptService("Basic")
    # Creates DB service using current document
    doc = CreateScriptService("SFDocuments.Document", bas.ThisDatabaseDocument)
    # Get current form
    form = doc.Forms("TryCode", "Form")
    # Close form
    form.CloseFormDocument()

Create a push button.
Action: Open Hyperlink or URL
URL: .uno.CloseDoc

Last time I looked you needed a name here also.

No but the basic example in the docs above it is better. My code runs. Using ThisComponent from within the TryCode form returns:

com.sun.star.document.OfficeDocument com.sun.star.text.GenericTextDocument com.sun.star.text.TextDocument

which I suppose is the database document, baseform and form but it’s not the names I was after.

@Villeroy suggestion of a uno call could probably work from within SF code too. Does that use the Dispatcher?

I would like to see code to close a form using ‘ThisDatabaseDocument’ and no form name.

ThisDatabaseDocument is the database so no explicit database name is needed. It’s an example of the functionality sought for BaseForm and Form.

Don’t expect there is anything in ScriptForge for that. From my experience it is very limited. Seems you are already looking to the outside with Dispatch commands (which is contrary to this being about a ScriptForge Database Demo). Besides, I could be wrong but I believe you still need the form name at some point if not using the actual button.
.
API is the way to go.

I was using this in the context of closing a form.

Have you seen → https://ask.libreoffice.org/t/thisdatabasedocument-vs-thiscomponent/25373

It calls an UNO command by its URL just like a dispatcher would do. This is how I implement close buttons without stupid macro.

Alternative document closer to be called by push button from any type of document, embedded or not with code embedded in odb or not.
It queries the parent of the calling form control until it reaches an office document and closes that document.

sub closeFormDoc(ev)
doc = getParentObject(ev.Source.Model, "com.sun.star.document.OfficeDocument")
doc.close(False)
End Sub

Function getParentObject(byval m, srvName$)
do until m.supportsService(srvName)
	m = m.getParent()
loop
getParentObject = m
End Function

While we are in this rubbish, can someone explain that weird argument to doc.close( [in] boolean DeliverOwnership ) ? Since 20 years or so I wanted to ask this question but never dared.

The bug will be fixed in the next release, it’ll close any form it is run from (except for the workaround):

# close form
def close_form(evt): # assign form button execute action event to macro
    control = CreateScriptService("FormEvent", evt)  # the button
    form = control.Parent
    fdoc_name = form.BaseForm if CreateScriptService("Platform" \
               ).OfficeVersion.split()[1] >= "7.3.2" else "sf_demo"
    doc = CreateScriptService("Document", bas.ThisDatabaseDocument)
    fdoc = doc.Forms(fdoc_name, form.Name)
    # Close form
    fdoc.CloseFormDocument()

form is a specific instance so I don’t understand why fdoc (instead of form.BaseForm) can’t be returned directly then just run last line.

Although a rhetorical comment of mine to begin with, the code you present still requires the name of the form.
.
And so much code just to close a form? One line in basic. Still see very little benefit in learning and using ScriptForge. One item thus far.
.
I still think one is better off learning the API.

1 Like

Without trying to be offensive, that’s a disingenuous comment (see Villeroy’s post quoted below for what’s involved) if using dispatch commands is a weak method of creating macros.

Executing from a button on a form in a base document it’s returning an error.

One Line:

ThisDatabaseDocument.FormDocuments.getbyname( "FORM_NAME" ).close
1 Like

This seems to work actually. Thanks to @flywire

Close a form document, no matter where the code is stored, no matter if the form is embedded or not.
getParentObject finds the containing office document. If that document is embedded, closeEmbeddedFormDocument lets the embedding database document closes the form document. An embedded form needs to be closed by the containing database document, otherwise you get a veto exception.

Sub closeFormDoc(ev)
'mri = createUnoService("mytools.Mri")
doc = getParentObject(ev.Source.Model, "com.sun.star.document.OfficeDocument")
'mri.inspect( doc)
if not (doc.Parent Is Nothing) Then
	closeEmbeddedFormDocument doc.getParent(), doc.getTitle()
else
	 doc.close(False)
endif
End Sub

Function getParentObject(byval m, srvName$)
do until m.supportsService(srvName)
	m = m.getParent()
loop
getParentObject = m
End Function

Sub closeEmbeddedFormDocument(odb, sTitle)
	forms = odb.FormDocuments
	for i = 0 to forms.getCount() -1
		form = forms.getByIndex(i)
		comp = form.getComponent()
		if not isnull(comp) then
			if comp.Title = sTitle then 
				form.close()
				exit for
			endif
		endif
	next i
End Sub
2 Likes

@Villeroy
Only briefly tested but looks promising.
.
Correct me if I a incorrect but it appears this has nothing to do with ScriptForge.
.
Edit:
.
Have already added an optional parameter to send title of a different form to close. Placed your routines in My Macros. Works but will need some error processing.
.
Very interesting possibilities.
.
Edit 2:
After more thought, although interesting and to be kept for future reference, other methods are done with way less code.

LibreOffice Macros > Access2Base is for Base.

The question is in regard to the ScriptForge library.