Libreoffice Base - 如何从宏调用控制事件?

Posted

技术标签:

【中文标题】Libreoffice Base - 如何从宏调用控制事件?【英文标题】:Libreoffice Base - how to call a control event from a macro? 【发布时间】:2020-05-20 16:21:37 【问题描述】:

问题:我需要手动调用一个对象监听事件(例如按键)来触发一个函数。我以前在 Access 中执行此操作,但在 LibreOffice Base 中没有找到它的文档。

背景: 7 年前我从软件开发部门退休了,我在 LibreOffice Base 中建立了一个数据库来帮助一个朋友。以前在 Access 方面有经验 - 但在 Oracle、PL/SQL、APEX 等方面有更多经验!我正在努力让它做我知道可以做的事情!

【问题讨论】:

“函数”(更可能是方法或子例程)是您编写的事件监听器,还是控件的内置对象监听器?什么样的控件:按钮、文本字段、表格控件?还有一个问题:这是关于 LO Basic 的吗?其他 LibreOffice 语言(如 Python 或 Java)中的事件监听器有很大不同,在我看来,它们通常更易于使用。但是您想要的可能可以在 Basic 中完成。通常我还会问什么 Base 引擎——firebird、hsqldb、mysql,甚至是 Oracle。但是,这对于这个问题并不重要。 好的,很抱歉 nto 更具体...方法是用于被称为函数(即返回值的过程)的当前术语。当前控件是子窗体中的表格,但它很容易成为窗体上的按钮或文本框。我在嵌入式 firebird 引擎上使用 LO basic。 我需要从宏访问内置对象监听器。 这是我对这类问题的回答:pitonyak.org/OOME_3_0.pdf 我还没有深入了解听众的东西,但希望这可能会有所帮助。这是我所知道的最好的参考资料。 【参考方案1】:

这是我目前尝试过的代码。

Sub CauseKeyPressedEventToBeFired
    oDoc = ThisComponent
    oController = oDoc.getCurrentController()
    oVC = oController.getViewCursor()
    oForm = oDoc.getDrawpage().getForms().getByName("Form")
    oTextBox = oForm.getByName("Text Box 1")
    oControlView = oController.getControl(oTextBox)
    oControlView.setFocus()
    Dim oEvent As New com.sun.star.awt.KeyEvent
    oEvent.Source = oControlView
    oEvent.KeyCode = com.sun.star.awt.Key.A
    oControlView.keyPressed(oEvent) 
End Sub

但是,它似乎不适用于我的系统(Windows 上的 LibreOffice 6.4.3.2)。我还找到了this post,但该代码似乎也不适合我。

我搜索了com.sun.star.awt.XToolkitRobot,但它不在 API 文档中,可能是因为功能不完全支持。想必可以从com.sun.star.awt.Toolkit获取。

如需更多帮助,请在 ask.libreoffice.org 上发布问题。我建议解释你为什么要这样做,因为可能有不同的解决方案。 Ratslinger 在解决各种数据库问题方面拥有丰富的经验,他可能会指导您采用不涉及此类事件黑客的更简单的解决方案。

函数(即返回值的过程)

是的,这就是函数。但是“对象侦听器事件”意味着,我认为正确的是,我们正在讨论对象的方法。这就是 Python 或 Java 中的 LibreOffice 事件监听器,尽管在 Basic 中,它们有点奇怪,使用对象名称作为某种魔法来确定它们适用于什么。无论如何,这偏离了轨道,因为您的问题不是关于监听事件,而是关于触发它们。

编辑

以下 Python 代码有效。我之前尝试的问题是需要设置oEvent.KeyChar,而这在Basic 中似乎不起作用。我无法想象为什么,除非我忽略了 Basic 代码中的一些明显错误。

def causeKeyPressedEventToBeFired(oEvent=None):
    oDoc = XSCRIPTCONTEXT.getDocument()
    oController = oDoc.getCurrentController()
    oForm = oDoc.getDrawPage().getForms().getByName("Form")
    oTextBox = oForm.getByName("Text Box 1")
    oControlView = oController.getControl(oTextBox)
    oControlView.setFocus()
    oEvent = uno.createUnoStruct("com.sun.star.awt.KeyEvent")
    oEvent.Source = oControlView
    from com.sun.star.awt.Key import A
    oEvent.KeyCode = A
    oEvent.KeyChar = "a"       # works in Python but strangely not in Basic
    simulate_KeyPress(oEvent)

def simulate_KeyPress(oKeyEvent):
    oDoc = XSCRIPTCONTEXT.getDocument()
    oWindow = oDoc.CurrentController.Frame.getContainerWindow()
    oKeyEvent.Source = oWindow      
    oToolkit = oWindow.getToolkit()
    oToolkit.keyPress(oKeyEvent)
    oToolkit.keyRelease(oKeyEvent)

编辑 2

最后,这是工作的基本代码。在之前的尝试中,类型错误。

Sub CauseKeyPressedEventToBeFired
    oDoc = ThisComponent
    oController = oDoc.getCurrentController()
    oForm = oDoc.getDrawpage().getForms().getByName("Form")
    oTextBox = oForm.getByName("Text Box 1")
    oControlView = oController.getControl(oTextBox)
    oControlView.setFocus()
    Dim oEvent As New com.sun.star.awt.KeyEvent
    oEvent.KeyCode = com.sun.star.awt.Key.A
    oEvent.KeyChar = CByte(97)
    simulate_KeyPress(oEvent)
End Sub

Sub simulate_KeyPress(oKeyEvent As com.sun.star.awt.KeyEvent)
    oWindow = ThisComponent.CurrentController.Frame.getContainerWindow()
    oKeyEvent.Source = oWindow      
    oToolkit = oWindow.getToolkit()
    oToolkit.keyPress(oKeyEvent)
    oToolkit.keyRelease(oKeyEvent)
End Sub

【讨论】:

谢谢吉姆,你显然花了一些时间来解决这个问题,我很感激。到目前为止,我已经对您的代码进行了一些尝试,结果与您相同...我将按照您在其他论坛上发布(明确!)问题的建议,然后在我们知道答案后在此处发布链接.

以上是关于Libreoffice Base - 如何从宏调用控制事件?的主要内容,如果未能解决你的问题,请参考以下文章

VBA (Ms-Access) 从宏调用成员函数

如何在 LibreOffice Base 5.0.2.2 中创建一个按钮以禁用表单中的控件

LibreOffice Base 中的数据库层次结构、聚合、关系

从 Base (Libreoffice) 中的宏中获取按钮

LibreOffice Base 数据库的 Node.js 连接库?

使用 OpenOffice Base 或 LibreOffice Base 将 .odb 文件转换为 .db