How do you copy text to clipboard from macro?

I’m trying to use a macro to copy text to the clipboard from LO Base and then paste the text into Firefox.
The code below only works once. The second time I try only a few characters get pasted and then shortly after LO crashes.

Is there a bug in LO or is something wrong with my code?

I’m running under Ubuntu 18 and LO 6.0.7.3

Any help would be appreciated.

Here is the code:

GLOBAL sGlobalText as STRING

SUB CopyClipboardTitle(event as OBJECT)
  rem this routine is called when a button on the Base form is pressed to copy the text to the clipboard
  DIM oTR as OBJECT
  DIM oClip as OBJECT

  rem   this function makes the string and stores it in a global variable
  sGlobalText = FunctionToBuildString()                    
  
  oClip = createUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")
  oTR = createUnoListener("TR_","com.sun.star.datatransfer.XTransferable")
  oClip.setContents(oTR,null)
END SUB

FUNCTION TR_getTransferData(aFlavor as com.sun.star.datatransfer.DataFlavor) as Any
  IF (aFlavor.MimeType = "text/plain;charset=utf-16") THEN
    rem sGlobalText is a global variable and has already been set
    TR_getTransferData = sGlobalText
  ENDIF
END FUNCTION

FUNCTION TR_getTransferDataFlavors() as Any
  DIM aF as NEW com.sun.star.datatransfer.DataFlavor
  aF.MimeType = "text/plain;charset=utf-16"
  aF.HumanPresentableName = "Unicode-Text"
  TR_getTransferDataFlavors = Array(aF)
END FUNCTION

FUNCTION TR_isDataFlavorSupported(aFlavor as com.sun.star.datatransfer.DataFlavor) as BOOLEAN
  TR_isDataFlavorSupported = (aFlavor.MimeType = "text/plain;charset=utf-16")
END FUNCTION

Show the code for FunctionToBuildString

or, you can used EasyMacro: https://gitlab.com/mauriciobaeza/zaz-easymacro/wikis/tools#clipboard

then

Sub clipboard()
    app = createUnoService("net.elmau.zaz.EasyMacro")
    
    data = "Hello World"
    app.set_clipboard(data)
End Sub

Hello,

What is the purpose of this? For example to go to a specific URL? There could be a much easier method depending on this.

The code for the function “FunctionToBuildString” is rather complicated. It pulls data from several different database tables to construct a string that is stored in a global variable that should be accessible to the routines that actually copy it to the clipboard.

The purpose is to paste a text string build from records from several different database tables into an internet browser form. The string will be different every time it is copied to the clipboard.

I tried the code that mauicio provided. The line app = createUnoService(“net.elmau.zaz.EasyMacro”) results in a NULL variable “app”. And the program crashes on line app.set_clipboard(data).

Do I need to install something? Sorry I’m kind of new to LO/Ubuntu.
Thanks.

Maybe This post can help?

I looked at the code in that post. The only difference I saw was that the 2 functions TR_getTransferData() and TR_getTransferDataFlavors() had undefined return types whereas mine where defined as Any. I tried removing the return type. LibreOffice Base still crashed the second time I ran the macro CopyClipboardTitle() .

I upgraded to a new laptop and installed Ubuntu 22.04 and Libreoffice 8.
The above code still fails when trying to paste the clipboard to another application such as Firefox or a text editor (not Writer). But I did find a work around. Write the text to a file then run “xclip” to copy the file contents to the clipboard.

' Define a filename where the clipboard contents are temporarily stored
' Make sure no other application will use the same file
' It gets rewritten each time you call CopyClipboard2()
Const fName = "file:///home/george/cbfile.txt"
Global i1 as Integer

' This routine is called when my libreoffice base form is opened
' It initializes any global variables
' The only purpose of i1 is so I can see that the clipboad contents change each time CopyClipboard() is called 
Sub InitVariables
  i1 = 11
End Sub

' Call this routine when you want to copy text to the clipboard
' This is called when a button is pressed in my LO database form
' The event parameter is not used and your application may not even have it
Sub CopyClipboard2(event as Object)
  Dim iFn As Integer				'used for the file number
  Dim sClipText AS String			'temporary string for the clipboard contents
  
' This is where you create the text you want to save on the clipboard
' The only purpose of the i1 variable is so I can see the clipboard contents change
' every time this routine runs.  You don't need to define global variables
  sClipText = i1 & "var1=" & i1
  i1 = i1+10     
  
' If the file already exists delete it so you can replace the contents of the clipboard  
  If (FileExists(fName) = TRUE) Then
    Kill(fName)
  EndIf
     
' Open the file, write the text to it then close the file      
  iFn = Freefile
  Open fName For Output As iFn
  Print #iFn, sClipText
  Close #iFn
  
' This is where the contents of the file are copied to the clipboard
' If you don't have xclip installed you can open a terminal and install it with
'     sudo apt install xclip
' I don't know how safe or reliable xclip is. It's just the first program I found that
' copies the contents of a file to the clipboard.  There are probably a lot more programs.
' You may need to check if xclip was installed in the bin directory
' if not change the pathname to that where xclip is located on your computer
  Shell("file:///bin/xclip",1,"-i -selection clipboard /home/george/cbfile.txt",true)
  
' At this point the clipboard should contain the text you saved in sClipText
' You can paste the clipboard with Ctrl-v not only within libreoffice but in other applications
' such as firefox or text editors  
         
End Sub

Try the direct path in this edition (suggested by @mikekaganski ).

Option Explicit

Global sTxtCString As String

Sub CopyToClipBoard(sText)
  Dim oClip As Object, oTrans As Object  'transferable object to set as new content
  oClip = CreateUnoService("com.sun.star.datatransfer.clipboard.SystemClipboard")
  oTrans = createUnoListener("Tr_", "com.sun.star.datatransfer.XTransferable")
  oClip.setContents(oTrans, Null)
  sTxtCString = sText
End Sub

Function Tr_getTransferData(aFlavor As com.sun.star.datatransfer.DataFlavor)
  If (aFlavor.MimeType = "text/plain;charset=utf-16") Then
    Tr_getTransferData() = sTxtCString
  Else
    Tr_getTransferData = Empty
  End If
End Function

Function Tr_getTransferDataFlavors()
  Dim aFlavor As New com.sun.star.datatransfer.DataFlavor
  aFlavor.MimeType = "text/plain;charset=utf-16"
  aFlavor.HumanPresentableName = "Unicode-Text"
  Tr_getTransferDataFlavors() = Array(aFlavor)
End Function

Function Tr_isDataFlavorSupported(aFlavor As com.sun.star.datatransfer.DataFlavor) As Boolean
  If aFlavor.MimeType = "text/plain;charset=utf-16" Then
    Tr_isDataFlavorSupported = True
  Else
    Tr_isDataFlavorSupported = False
  End If
End Function

Sub Test
  CopyToClipBoard "LibreOffice 🙂"
End Sub

See also tdf#149622

why not python ( and thirdparty »pyperclip« ):

import pyperclip

pyperclip.copy( "hello world" )
# and do the usual <ctrl>v where ever you want

Are you from the future? :grin: