I am curious if I can add a matlab gui to a powerpoint presentation. Either within the presentation or a link to open up matlab.
I call this function and it will open the figure then immediately close it.
Private Sub click_Click()
Call RunFile("new_control_pan", "C:\Users\mhaartman\Documents\PANE_golden2\PANE_golden\code")
End Sub
Sub RunFile(FILENAME As String, Optional FilePath As String)
Dim MATLAB As Object
Dim Result As String
Dim Command As String
Dim MATLABWasNotRunning As Boolean
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Set Up
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Connect to the automation server.
' MATLAB becomes a MATLAB handle to the running instance
' of MATLAB.
On Error Resume Next ' Defer error trapping
MATLAB = GetObject(, "matlab.application")
If Err.Number <> 0 Then
MATLABWasNotRunning = True
Set MATLAB = CreateObject("matlab.application")
Err.Clear ' Clear Err object in case error occurred.
End If
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Do the Work
'''''''''''''''''''''''''''''''''''''''''''''''''''
If Not IsMissing(FilePath) And Not FilePath = "" Then
Command = "cd('" + FilePath + "')"
Result = MATLAB.Execute(Command)
End If
Command = FILENAME
Result = MATLAB.Execute(Command)
'Result = MsgBox("Done", vbOkayOnly, "Click when done")
End Sub
Thanks!
Maybe you could take a look at Calling MATLAB from PowerPoint.This submission on the File Exchange may be out of date, as it was created a few years ago. But the latest versions of MATLAB continue in general to offer a COM interface, which can be called from PowerPoint. It may need some updating, but I'm sure any issues are correctable.
Related
I am trying to create two tables which mirror changes made to any of them to one another automatically.
To that end, I added event listeners which are triggered when the cells of these tables are edited by the user.
Unfortunately, editing one of the tables causes LibreOffice to crash, even though the changes are indeed reflected correctly, as seen upon reopening the file.
I thought the crash might be due to a never-ending circular reference, but it still crashes after it has been made non-circular (by commenting out the relevant parts of the code so that changes are reflected only one way rather than both ways).
I noticed the code worked fine when writing to a cell that didn't have an event listener set to it.
How can I write to one of the cells with event listeners set to them without causing LibreOffice to crash?
You may want to download the following file. Please run Main and then try editing the cell C3 of the Planning sheet. The arbitrary string "C" should be written in the cell C4 of the Services sheet.
Here is a simplified version of the code :
REM ***** BASIC *****
const SERVICESSHEET_NUMBER = 2
const SERVICESSHEET_SERVICES_COLUMN = 2
Type cellStruct
columnNumber As Integer
rowNumber As Integer
End Type
Sub UpdateServicesSheet(editedCell As cellStruct, newValue As String)
Dim oSheets
Dim servicesSheet
oSheets = ThisComponent.getSheets()
servicesSheet = oSheets.getByIndex(SERVICESSHEET_NUMBER)
servicesSheet.getCellByPosition(SERVICESSHEET_SERVICES_COLUMN, 3).setString(newValue)
End Sub
Private oListener, cellRange as Object
Sub AddListener
Dim sheet, cell as Object
sheet = ThisComponent.Sheets.getByIndex(0) 'get leftmost sheet
servicesSheet = ThisComponent.Sheets.getByIndex(2)
cellRange = sheet.getCellrangeByName("C3")
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener") 'create a listener
cellRange.addModifyListener(oListener) 'register the listener
cellRange = servicesSheet.getCellrangeByName("C4")
oListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener") 'create a listener
cellRange.addModifyListener(oListener) 'register the listener
End Sub
global CircularReferenceAllowed As boolean
Sub Modify_modified(oEv)
Dim editedCell As cellStruct
Dim newValue As String
editedCell.columnNumber = 2
editedCell.rowNumber = 2
If CircularReferenceAllowed Then
CircularReferenceAllowed = false
UpdateServicesSheet(editedCell, "C")
End If
End Sub
Sub Modify_disposing(oEv)
End Sub
Sub RmvListener
cellRange.removeModifyListener(oListener)
End Sub
Sub Main
CircularReferenceAllowed = true
AddListener
End Sub
Crossposted to :
OpenOffice forums
LibreOffice discourse platform
It seems like the event trigger is within another event's function is causing the crash. In any case, the solution is to remove the listener, then add it back after modifying the other cell.
You do need to global the Listener and the Cell objects to make this work.
This code is simplified to work on C3 and C15 on the first sheet. It would also output some information on C14, which isn't really necessary for your purpose, but I use it to see what's happening. You need to adopt the according to what you need.
global goListener as Object
global goListener2 as Object
global goCellR as Object
global goCellR2 as Object
global goSheet as Object
global giRun as integer
global giUpd as Integer
Sub Modify_modified(oEv)
Dim sCurStr$
Dim sNewStr As String
'xRay oEv
giRun = giRun + 1
sCurStr = oEv.source.string
oCell = goSheet.getCellByPosition(2, 14)
If (oCell.getString() <> sCurStr) Then
' only update if it's different.
giUpd = giUpd + 1
goCellR2.removeModifyListener(goListener2)
oCell.setString(sCurStr)
goCellR2.addModifyListener(goListener2)
End If
sNewStr =sCurStr & " M1 Run=" & giRun & " Upd=" & giUpd
goSheet.getCellByPosition(2, 13).setString(sNewStr)
End Sub
Sub Modify2_modified(oEv)
Dim sCurStr$
Dim sNewStr As String
Dim oCell as Object
'xRay oEv
giRun = giRun + 1
sCurStr = oEv.source.string
oCell = goSheet.getCellByPosition(2, 2)
If (oCell.getString() <> sCurStr) Then
' only update if it's different.
giUpd = giUpd + 1
goCellR.removeModifyListener(goListener)
oCell.setString(sCurStr)
goCellR.addModifyListener(goListener)
End If
sNewStr =sCurStr & " M2 Run=" & giRun & " Upd=" & giUpd
goSheet.getCellByPosition(2, 13).setString(sNewStr)
End Sub
Sub Modify_disposing(oEv)
MsgBox "In Modify_disposing"
End Sub
Sub Modify2_disposing(oEv)
MsgBox "In Modify2_disposing"
End Sub
Sub RmvListener
MsgBox "In RmvListener"
goCellR.removeModifyListener(goListener)
goCellR2.removeModifyListener(goListener2)
End Sub
Sub AddListener
goSheet = ThisComponent.Sheets.getByIndex(0) 'get leftmost goSheet
'servicesSheet = ThisComponent.Sheets.getByIndex(2)
goCellR = goSheet.getCellrangeByName("C3")
goListener = createUnoListener("Modify_","com.sun.star.util.XModifyListener") 'create a listener
goCellR.addModifyListener(goListener) 'register the listener
goCellR2 = goSheet.getCellrangeByName("C15")
goListener2 = createUnoListener("Modify2_","com.sun.star.util.XModifyListener") 'create a listener
goCellR2.addModifyListener(goListener2) 'register the listener
End Sub
Sub Main
giRun = 0
giUpd = 0
AddListener
End Sub
I wrote a macro in LibreOffice Calc and it is able to run correctly. But if I close the file and reopen, it always show #NULL! instead of the correct value. What am I missing here?
My macro code
Rem Attribute VBA_ModuleType=VBAModule
Option VBASupport 1
Function Calculate(CalType As String) As Double
'
' Calculate Macro
'
Dim i As Integer
Calc = 0
i = 1
Do While Not IsEmpty(Cells(i, 2))
If (Cells(i, 3).Value = CalType And (Cells(i,2) = "A" Or Cells(i,2) = "B")) Then
Calculate = Calculate + Cells(i, 4).Value
ElseIf (Cells(i, 3).Value = CalType And Cells(i,2) = "C") Then
Calculate = Calculate - Cells(i, 4).Value
End If
i = i + 1
Loop
'
End Function
The calling function will be something like =Calculate(J6)
The file is saved as .ods format.
The Cells call did not work at all for me. It is from VBA, not LO Basic. However I do not think that is the main problem.
LibreOffice expects that user-defined functions will be simple, only accessing the cell that contains the formula. Since the spreadsheet has not been fully loaded yet when the function is called, it is not possible to read other cells.
The workaround is to ignore errors and wait until the document is fully loaded before running the function. Take the following code as an example:
Function ReadOtherCell(row, col)
On Error GoTo ErrorHandler
oSheet = ThisComponent.CurrentController.ActiveSheet()
oCell = oSheet.getCellByPosition(row, col)
ReadOtherCell = "value is '" & oCell.getString() & "'"
Exit Function
ErrorHandler:
Reset
End Function
Sub RecalculateAll
' This is for user-defined functions that need to read the spreadsheet.
' Assign it to the "View created" event,
' because before that, the spreadsheet is not fully loaded.
ThisComponent.calculateAll
End Sub
Enter foo in A1, and =ReadOtherCell(0,0) in A2. So far, this has the same problem -- It will fail when the document is first opened.
Now, go to Tools -> Customize. In the Events tab, highlight View created. Press Macro... and find the RecalculateAll function. Then press OK.
Now when the document is closed and reopened, cell A2 should show the result value is 'foo'.
This is derived from B. Marcelly's answer at http://ooo-forums.apache.org/en/forum/viewtopic.php?f=20&t=73090&sid=f92a89d676058ab597b4b4494833b2a0.
I had the same problem.
I noticed that in the module, i had an empty Sub Main
After i 've erased it, the functions started working again
I'm trying to write a function in Basic for LibreOffice Calc to get the first letter of each word of the selected cell using the following code:
Function GetFirstLetters(rng) As String
Dim arr
Dim I As Long
arr = Split(rng, " ")
If IsArray(arr) Then
For I = LBound(arr) To UBound(arr)
GetFirstLetters = GetFirstLetters & Left(arr(I), 1)
Next I
Else
GetFirstLetters = Left(arr, 1)
End If
End Function
And it works correctly, unless I try to execute it again, then it seems that the new result gets appended to that of any previous execution and it will return both strings together, example:
It also doesn't matter if I delete some or even all cells, or if I call it using an empty cell or even in another page, it will always append the result to the previous one:
Why does this happen? How can I fix this behaviour?
I don't know anything about Basic, so please don't bash on me if this is something very simple.
The original function is this:
Function GetFirstLetters(rng As Range) As String
'Update 20140325
Dim arr
Dim I As Long
arr = VBA.Split(rng, " ")
If IsArray(arr) Then
For I = LBound(arr) To UBound(arr)
GetFirstLetters = GetFirstLetters & Left(arr(I), 1)
Next I
Else
GetFirstLetters = Left(arr, 1)
End If
End Function
And I got it from here: http://www.extendoffice.com/documents/excel/1580-excel-extract-first-letter-of-each-word.html.
The code you have found is VBA for Excel. Openoffice or Libreoffice uses StarBasic, not VBA. This is similar but not equal. So you can't simply use the same code as in Excel.
First difference is, there is no Range object. This you have noticed and have used rng as an Variant.
But another difference is, function names are like variable names in the global scope. And they will not be reseted if the function is called again. So in StarBasic we better do:
Function GetFirstLetters(sCellValue as String) As String
Dim arr As Variant
Dim I As Long
Dim sResult As String
arr = Split(sCellValue, " ")
If IsArray(arr) Then
For I = LBound(arr) To UBound(arr)
sResult = sResult & Left(arr(I), 1)
Next I
Else
sResult = Left(arr, 1)
End If
GetFirstLetters = sResult
End Function
sResult is reseted (new Dimed) every time the function is called. So even the function's return value.
So far i have some code that allows a user to Hit F1 which loads a new form of the same properties and then hides the one the first one they had up, Hitting F2, allows the user to close the newly opened form and show the one they opened first. I would like a restriction that allows the user to open only 1 extra form if they hit F1 with 2 of the same forms open then a messagebox appears telling them to close the second form first otherwise allow it to be opened.
Here is what i have so far.
Private Sub Form_Load()
End Sub
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case vbKeyF1
'hides the current form
Me.Hide
'loads a new form with the same properties
Dim f As New Form1
Load f
'shows this new form
f.Show
'says that the second form is open
fOpen = True
Case vbKeyF2
'closes the second form
Unload Me
'says that the second form is closed
fOpen = False
'shows the first form you were on
Form1.Show
End Select
End Sub
Private Sub Form_QueryUnload(cancel As Integer, unloadmode As Integer)
'if your hitting "X" on second form then just close form2
If fOpen = False Then
Form1.Show
Else
'if your hitting "X" on main form close everything
Unload Me
End If
End Sub
Maybe something like if fOpen = true then disallow the user to hit F1? Not quite sure, but im close.
Forgive me if my VB6 is a little off, but you need to enumerate though the Forms collection to check to see if your form is already open...
Dim frm As Form
For Each frm In Forms
If frm.Name = "myForm" Then frm.Show()
Next frm
See this.
-- EDIT --
Just while I think on, to tune your code you could use a numeric iteration...
Dim f As Integer
Dim t As Integer
t = Forms.Count - 1
For f = 0 To t
If Forms(f).Name = "myForm" Then Forms(f).Show()
Next frm
-- EDIT 2 --
Just a further note on this. You may also want to introduce a counter so that you can check to see if there are two fields as in your original post...
Dim frm As Form
Dim c As Integer
For Each frm In Forms
If frm.Name = "myForm" Then
c = c + 1
If c = 2 Then
frm.Show()
Exit For 'Speed up the search if there are lots of forms
End If
End if
Next frm
I would like to execute some code when a user closes a form using the x button in the top right corner of the window (I have the form load when the excel spreadsheet is opened, and it hides Excel. I want to exit excel once the form is closed, or at least show excel again so the user may exit it manually)
Looking at the form properties, the Unload property is not present, nor am I able to figure out how to make a function which executes when the form is closed.
Unfortunately, coding this in VB is not an option, it must be VBA.
I'm aware of the code needed to unhide Excel or quit it outright, just not how to tie it to the unload event.
You can use QueryClose event of the UserForm as follows:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then
' Your codes
' Tip: If you want to prevent closing UserForm by Close (×) button in the right-top corner of the UserForm, just uncomment the following line:
' Cancel = True
End If
End Sub
You can also use vbFormControlMenu like this:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
'Your code goes here
End If
End Sub
A colleague was able to provide the answer, including example here for everybody else
Private Sub userform_terminate()
'Code goes here
End Sub
You can use Unload Me in VBA to close a form. Just put the code to close Excel immediately following that.
Private Sub Form_Unload(Cancel As Integer)
Dim msgRes As VbMsgBoxResult
msgRes = MsgBox("Exit form ?", vbYesNo)
If msgRes = vbYes Then
'optional code
ElseIf msgRes = vbNo Then
Cancel = True
End If
End Sub
I was able to prevent the form from closing when the X button was click using the following:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Cancel = MsgBox("Please confirm cancellation", vbOKCancel + vbQuestion) = vbCancel
End Sub
try something like this:-
Private Sub Form1_FormClosing(sender as Object, e as FormClosingEventArgs) _
Handles Form1.FormClosing
//Code you want to execute
End Sub