I need to run a PowerPoint sub from a sub in Excel. The reason is that most PowerPoint actions run far faster and with less errors when run from a sub in PowerPoint than when run from a sub in Excel.
I am trying to use Application.Run(Macroname_As_String) where I use PptApp in place of Application and PptApp is loaded as:
Dim PptApp As PowerPoint.Application
Set PptApp = CreateObject("PowerPoint.Application")
I tried referring to the VBA script as both Presentation1.pptm!UpdateOLELinks and UpdateOLELinks ie. file and VBA script / just VBA script.
I get the error :
"Method 'Run' of object '_Application' failed".
My VBA script UpdateOLELinks is located in Module1 of Presentation1.
Any Ideas?
The Run Method in PowerPoint require parameters : msdn.microsoft.com/fr-fr/library/office/Ff744221.aspx
So, even if you pass an empty array, try something like :
PptApp.Run Macroname_As_String, Parameters_As_Array
Other untested possibilities (with your references for context) I stumbled across while researching :
Dim PptApp As PowerPoint.Application
Set PptApp = CreateObject("PowerPoint.Application")
Set Ppt1 = PptApp.Presentations.Open(PptPath, msoFalse, msoTrue, msoTrue)
'Possibility 1
PptApp.Run Macroname_As_String, Parameters_As_Array
'Possibility 2
Ppt1.PptApp.Run Macroname_As_String, Parameters_As_Array
'Possibility 3
PptApp.Run "'" & Ppt1.name & "'!" & Macroname_As_String, Parameters_As_Array
'Possibility 4
PptApp.Run Module_Name.Macroname_As_String, Parameters_As_Array
'Possibility 5
PptApp.Run "'" & Ppt1.name & "'!" & Module_Name.Macroname_As_String, Parameters_As_Array
I found the answer here, where "UpdateOLELinks" is the name of the PowerPoint sub and the option to compile live as you type has not been disabled (it's enabled by default):
https://www.ozgrid.com/forum/forum/other-software-applications/excel-and-or-powerpoint-help/26816-open-ppt-and-run-a-pre-written-macro
from ASHOK_SHARMA02:
Dim PPApp As PowerPoint.Application
Set PPApp = CreateObject("PowerPoint.Application")
PPApp.AddIns.Application.Run ("UpdateOLELinks"), ""
It worked for me after trying loads of possible solutions.
[edit]
Actually it broke again when running the PPT from the VBA. Reason is VBA module has not yet been activated, so something like PPT doesn't know it exists (crazy huh?).
So, add line
PPApp.VBE.ActiveVBProject.VBComponents.Item("Module1").Activate
There are two issues (which seem unique to PowerPoint), parameters are required and the macro name must be fully qualified.
When qualifying the macro, don't use single quotes as you would for Excel. Instead, just use the following, even if the filename has spaces:
PptApp.Run Ppt1.Name & "!Module1.UpdateOLELinks"
The error will also arise if the parameters being passed don't match the parameters of the macro. Ensure the macro has a defined parameter to receive (of matching type), even if it doesn't use it.
This has been asked long before but still if anyone needs an answer, the follwoing worked for me.
Dim objPP As Object
Dim objPPFile As Object
Set objPP = CreateObject("PowerPoint.Application")
objPP.Visible = True
Set objPPFile = objPP.Presentations.Open(PptPath)
Application.EnableEvents = False
' "filename !Module1.macro_name"
objPP.Run "post_processing_V2.pptm!Module1.code"
objPPFile.Close
objPP.Quit
Set objPPFile = Nothing
Set objPP = Nothing
Related
I am writing a macro that opens and closes a PowerPoint Presentation from Excel.
Now I have the issue that when I am trying to save the PowerPoint file I get a pop up Message Box. To take care of that issue I used:
Application.DisplayAlerts = False
However this works in some cases, as I loop through multiple Presentations but not in all. So I tried instead this:
pptPres.Application.DisplayAlerts = False
But this just caused the Display Alerts to always pop up.
So I tried to replicate that using
Application.DisplayAlerts = True
which did not work. So I am quite confused what I am doing wrong. I need to turn the DisplayAlerts off otherwise my macro is stopped.
The issue occurs as I am opening a PowerPoint with macros so a *.pptm file which on saving I am asked whether or not to save with macros.
This is my current code, maybe you can replicate the issue:
Dim pptPres As PowerPoint.Presentation
Set pptApp = CreateObject("powerpoint.Application")
Set pptPres = pptApp.Presentations.Open(strPfad & strDat, False, True, True)
pptPres.Application.DisplayAlerts = False
strFirma = "Test123"
pptPres.SaveAs strPfad + "\Berichte" & "\" & strFirma & ".pptx"
pptPres.Close
Any help is greatly appreciated.
Powerpoint's Application.DisplayAlerts is slightly different. It has two options: ppAlertsAll and ppAlertsNone.
Try pptApp.DisplayAlerts = ppAlertsNone. Note that you have a mix of early- and late-binding and probably should be consistent. If you go with late-binding, ppAlertsAll's corresponding value is 2, and ppAlertsNone's corresponding value is 1.
Thanks to #Matthieu Guindon for pointing out that since you're running this from Excel, Application refers to Excel.Application, which is not your instance of PowerPoint. Hence Application.DisplayAlerts will not affect PowerPoint's alert setting at all. You want to work with pptApp, the instance of PowerPoint.
In my excel document I have a chart that I want to copy and paste into a MS-Word document. I want to avoid linking data, embedding workbooks and resizing (Excel has the chart formatted to my desired size). So I came up with/found the following code that almost works:
Sub PasteChart()
Dim wd As Object
Dim ObjDoc As Object
Dim FilePath As String
Dim FileName As String
FilePath = "C:\Users\name\Desktop"
FileName = "Template.docx"
'check if template document is open in Word, otherwise open it
On Error Resume Next
Set wd = GetObject(, "Word.Application")
If wd Is Nothing Then
Set wd = CreateObject("Word.Application")
Set ObjDoc = wd.Documents.Open(FilePath & "\" & FileName)
Else
On Error GoTo notOpen
Set ObjDoc = wd.Documents(FileName)
GoTo OpenAlready
notOpen:
Set ObjDoc = wd.Documents.Open(FilePath & "\" & FileName)
End If
OpenAlready:
On Error GoTo 0
'find Bookmark in template doc
wd.Visible = True
ObjDoc.Bookmarks("LPPU").Select
'copy chart from Excel
Sheets("Group Level Graphs").ChartObjects("Chart 1").Chart.ChartArea.Copy
'insert chart to Bookmark in template doc
wd.Selection.PasteSpecial Link:=False, DataType:=14, Placement:=0, _
DisplayAsIcon:=False
End Sub
The only issue is that the image is pasted as "In Line with Text" but I need it to be "Square with text wrapping". I can't get Word or Excel to record changing the image to "Square with text wrapping".
The PasteSpecial part only does wdFloatOverText or wdInLine for placement and neither of them solve this issue.
I am very new to VBA and have run out of ideas. I am still trying to find a way to format it, maybe using some kind of WITH statement. However I thought I would attempt to reach out for help while I continue google-foo and learning VBA from Youtube.
Using PasteAndFormat Type:=wdChartPicture links the chart to excel. So that didn't work.
Make sure you have a reference to the Word application in your VBE then immediately following a regular paste (wd.Selection.Paste), add these two lines of code:
wd.Selection.MoveStart word.WdUnits.wdCharacter, Count:=-1
wd.Selection.InlineShapes(1).ConvertToShape.WrapFormat.Type = wdWrapSquare
If you want to continue to use the PasteSpecial method you have in your code then replace the code line above "wd.Selection.MoveStart..." to this:
wd.Selection.MoveEnd word.WdUnits.wdCharacter, Count:=1
The reason is a regular paste leaves the active insertion point at the end of the inserted object. But if a PasteSpecial method is used the active insertion point is at the beginning of the object that was pasted. Why? I have no idea! Word VBA never ceases to amaze me. :-)
I am getting an Automation error, when Catia is trying to write values in a selected Excel sheet. It's a bit confusing because on the first try of the code there was no error and the values were in the Excel sheet.
I didn't change the code, but on the second try I get:
Run-time error '-2147417846 (8001010a)': Automation error
"The Message filter indicated that the application is busy."
on the line: Set MyXL = GetObject(FPath)
Sub CATMain()
FPath = CATIA.FileSelectionBox("Select the Excel file you wish to put the value in", "*.xlsx", CatFileSelectionModeOpen)
If FPath = "" Then
Exit Sub
End If
Set xlApp = CreateObject("Excel.Application")
Set MyXL = GetObject(, "Excel.Application")
Set MyXL = GetObject(FPath)
MyXL.Application.Visible = True
MyXL.Parent.Windows(1).Visible = True
Dim oSelection As Selection
Set oSelection = CATIA.ActiveDocument.Selection
Dim oProduct As AnyObject
On Error Resume Next
Set oProduct = oSelection.FindObject("CATIAProduct")
If (Err.Number <> 0) Then
MsgBox "No selected product"
Else
On Error GoTo 0
Dim oInertia As AnyObject
Set oInertia = oProduct.GetTechnologicalObject("Inertia")
Dim dMass As Double
dMass = oInertia.Mass
Dim dDen As Double
dDen = oInertia.Density
MsgBox oProduct.Name & ": Masse = " & CStr(dMass) & " KG" & ": Dichte = " & (CStr(dDen) / 1000) & " "
MyXL.Application.Cells(1, 1).Value = "Masse"
MyXL.Application.Cells(2, 1).Value = dMass
MyXL.Application.Cells(1, 2).Value = "Dichte"
MyXL.Application.Cells(2, 2).Value = "dDen"
MsgBox "Werte wurden in Excel eingetragen"
End If
End Sub
It appears you did not set Option Explicit - put it on the first line and it will help you avoid errors. (With it, the compiler will force you to declare all your variables. This will also mean that when you put it in, your code will not work unless you declare all variables.)
The first problem:
Set xlApp = CreateObject("Excel.Application")
Set MyXL = GetObject(, "Excel.Application")
You first create a new instance of Excel with CreateObject and store a reference to it in xlApp (which you subsequently do not use). Then you try to get a reference to an existing Excel instance with GetObject and store its reference in MyXL. This only works reliably because you first create a new instance. Otherwise you could not guarantee that there always is an Excel instance available.
A related problem is, that you don't release/close these instances. If you create an Excel instance, you need to close it with xlApp.Quit after you're done using it, otherwise it will linger around.
Be careful though with instances you took over with GetObject - calling MyXL.Quit will close the instance regardless of what other workbooks are open at that time.
Similarly, if you open a file this way, you need to make sure to close it afterwards. Otherwise you'll run into the problem you experience: Write protected files.
So, to mend your problem: Close all open instances of Excel (best done via Task Manager, as some of them might be invisible). Then adjust your code to only use one reference to an Excel.Application. And finally make sure to .Close the workbook after you've saved it and .Quit your Excel instance. This should hopefully prevent the error from reappearing.
'Dim xlApp As Excel.Application ' early-bound declaration
'Set xlApp = New Excel.Application ' early-bound assignment
Dim xlApp As Object ' late-bound declaration
Set xlApp = CreateObject("Excel.Application") ' late-bound assignment
'Dim wb As Workbook ' early-bound declaration
Dim wb as Object
Set wb = xlApp.Workbooks.Open(FPath)
' stuff you want to do with the workbook
wb.Close SaveChanges:=True
xlApp.Quit
If you can add a reference to the Excel object model in you Catia VBA project (not sure about that), you can comment out the late-bound lines and use the early-bound lines instead. That way you gain the very useful IntelliSense for the Excel objects. Which makes it so much easier to code.
Thank you guys! I've solved the Problem with simply adding the code:
Workbook.Close SaveChanges:=True
I need to copy/paste table from Excel to owrd to a specific line. I have written the code and it works fine in the Excel and Word 2016 I used, but when I tried running in other versions (2013,2010,2007) it didn't work at all. So i try to use late binding, but it throws a Bad Parameters error in .selection
How to remove Bad Parameters? Thanks,
Here's the code :
Sub Movetable ()
'Name of the existing Word document
Const stWordDocument As String = "Test.docx"
'Word objects.
Dim wdApp As Object
Dim wdDoc As Object
Dim wdRange As Object
'Excel objects
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim xlRange As Excel.Range
'Initialize the Excel objects
Set wbBook = ThisWorkbook
Worksheets("RJ").Select
LastRow = Range("A" & Rows.Count).End(xlUp).Row
Set xlRange = Range("A4:D" & LastRow)
xlRange.Select
xlRange.Copy
'Instantiate Word and open the "Test" document.
Set wdApp = CreateObject("Word.Application")
Set wdDoc = wdApp.Documents.Open(wbBook.Path & "\" & stWordDocument)
wdDoc.Application.Selection.Find.Execute "Table 1. Summary", MatchCase:=True
wdApp.Selection.MoveDown Unit:=wdLine, Count:=2, Extend:=wdMove
wdApp.Selection.PasteExcelTable False, False, False
wdDoc.Tables(1).AutoFitBehavior wdAutoFitWindow
'Save and close the Word doc.
With wdDoc
.Save
.Close
End With
wdApp.Quit
'Null out the variables.
Set wdRange = Nothing
Set wdDoc = Nothing
Set wdApp = Nothing
End Sub
Very probably, the reason is that you've set a Refernce to the Microsoft Word library for version 2016. When you open and run the project in an earlier version, the reference doesn't change to the Microsoft Word library for that version. This is expected behavior.
To fix the problem you can either
Open the project in the earliest version of Office (2007,
apparently). Go to Tools/References in the VBA Editor and select the
Microsoft Word library for that version. Test, then save.
Office applications will change References to a newer version, but they don't do so the other way around. That's why it's always recommended to develop using the oldest version of Office the project should work in.
Don't use named arguments in the method calls. Remove, for example, MatchCase:=, Unit, Count, Extend. In addition, don't use the Word enumerations: wdLine, wdMove, wdAutoFitWindow- these all have numerical equivalents, use those instead.
This is known as "late-binding", which makes your project independent of the version of Word. You can then completely remove the Reference to the Microsoft Word library.
In order to find out the numerical equivalents you can look up the enumerations in the VBA Object Browser (F2 in the VBA Editor), look them up in the Word VBA Help or query them in the VBA Editor Immediate Window (Ctrl + G) using syntax like this: ?wdLine and then press Enter to execute.
Through excel VBA I'm opening a workbook and closing it, thus quitting the Excel application. But it is still running in the Task manager, which prevents my addin from working properly. Part of the code is as follows:
Private Sub btn_Click()
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
Dim i As Integer
Dim j As Integer
Sheets("Sheet1").Select
Finalrow = Cells(Rows.count, 1).End(xlUp).row
LastCol = Cells(1, Columns.count).End(xlToLeft).Column
Set oExcel = New Excel.Application
Set oBook = oExcel.Workbooks.Open(ADDIN_PATH & "\" & "hello.xls")
Set oSheet = oBook.Worksheets(1)
sCellName = "--Select--"
oSheet.Range("A3").Value = "Name"
If (ComboBox1.Value = "--Select--" Or ComboBox1.Value = "") Then
MsgBox "Please Map the name field"
'Else
'oSheet.Range("B2").Value = ComboBox1.Value
Exit Sub
End If
'oSheet.Range("B2").Value = ComboBox1.Value
oSheet.Range("B2").Value = ComboBox1.Value
If (ComboBox2.Value = "") Then ComboBox2.Value = sCellName
oBook.SaveAs ADDIN_PATH & "\" & "hello.xls"
oBook.Close
oExcel.Quit
Set oExcel = Nothing
MsgBox "Your current setting has been saved"
SettingForm.Hide
End Sub
When I run into this issue with ghost Excel processes after creating and manipulating an excel application/workbook (usually from Access) the solution I found is always the same - but after doing some testing on my end, the code you have there does not create a ghost process for me. Either way implementing this fix should work, so here are two suggestions:
1.) You need to fully qualify every reference when you are creating/manipulating a new excel application - COM keeps track of the number of open objects by a simple count - when you open a new excel process it ticks up by 1, but if you make an unqualified reference with two open (Say, using Cells(Rows.Count,1)... instead of oExcel.Workbooks(oBook.Name).Worksheets(oSheet.Name).Cells(oExcel.Workbooks(oBook.Name).WorkSheets(oSheet.Name).Rows.Count,1)..., it ticks up again, and now even when they're all closed the internal count of COM objects is still at 1 and Excel stays open. (Obviously you don't have to type out the full thing each time, just when creating the objects.) So I would use -
dim thisSheet as Worksheet
set thisSheet = ActiveWorkbook.Worksheets(1)
thisSheet.Activate
Even if it isn't what's causing the problem now, doing something like Sheets("Sheet1") when automating Excel from another application, without the accompanying workbook/application reference is 100% guarenteed to make a ghost process.
When you do that for all the Rows.Count, Columns.Count, etc, I think you should specify the sheet for the comboboxes too.
2.) When all thats done, the surefire way to figure out which line is incrementing that COM object count is to move the oExcel.Quit line to just after the Set oExcel = New Excel.Application line , and keep re-running it and moving that oExcel.Quit line further and further down until you encounter the ghost process, and that'll be your culprit.
I hope that helps fixed it, I wasted way too many hours a similar problem, hopefully it's the same root cause.