问题
Sub OO()
Dim oPPApp As Object, oPPPrsn As Object, oPPSlide As Object
Dim oPPShape As Object
Dim FlName As String
'~~> Change this to the relevant file
FlName = "C:\Users\lich_\Documents\test.pptx"
'~~> Establish an PowerPoint application object
On Error Resume Next
Set oPPApp = GetObject(, "PowerPoint.Application")
If Err.Number <> 0 Then
Set oPPApp = CreateObject("PowerPoint.Application")
End If
Err.Clear
On Error GoTo 0
oPPApp.Visible = True
Set oPPPrsn = oPPApp.Presentations.Open(FlName, WithWindow:=msoFalse)
Set oPPSlide = oPPPrsn.Slides(2)
With oPPSlide.Shapes("Chart1").Chart.ChartData
.ActivateChartDataWindow
.Workbook.Worksheets("Sheet1").Range("B2").Value = 0.1231
.Workbook.Close
End With
End Sub
As you can see above, I'm trying to edit the chart data in vba.
But since I have control many charts later, I would like to make the workbook invisible ( or not open it at all if possible )
With oPPSlide.Shapes("Chart1").Chart.ChartData
.ActivateChartDataWindow
.Workbook.Worksheets("Sheet1").Range("B2").Value = 0.1231
.Workbook.Close
End With
In this code I opened by "ActivateChartDataWindow" method and change the data which I want and Closed.
Is there any way to make the window invisible or to edit data without even opening?
Thank you for your help in advance.
回答1:
It's possible to update existing chart data without Activate
as per @mooseman's answer.
However, if the chart is new/inserted at runtime, as far as I know this cannot be accomplished with interop, as the AddChart
method adds the chart and simultaneously creates/activates the Excel Workbook. While you may not need to call the Activate
method, there is no way to insert or add a new chart that doesn't involve opening an Excel instance. There is no way around this, this is just how the UI functions and it is by design.
To Update Data in EXISTING Chart
/ ChartData
Below native PowerPoint VBA, but should port easily to Excel with proper reference(s)
Sub test()
Dim PPT As PowerPoint.Application
Dim pres As Presentation
Dim sld As Slide
Dim shp As Shape
Dim cht As Chart
Dim rng As Object ' Excel.Range
Set PPT = Application 'GetObject(,"PowerPoint.Application")
Set pres = ActivePresentation
Set sld = pres.Slides(1)
Set shp = sld.Shapes(1)
Set cht = shp.Chart
Call changeData(cht, 6.3)
pres.Slides.AddSlide pres.Slides.Count + 1, sld.CustomLayout
Set sld = pres.Slides(pres.Slides.Count)
sld.Shapes.AddChart().Chart.ChartData.Workbook.Application.WindowState = -4140
Set cht = sld.Shapes(1).Chart
Call changeData(cht, 3.9)
End Sub
Sub changeData(c As Chart, v As Double)
Dim rng As Object
With c.ChartData
Set rng = .Workbook.Worksheets(1).ListObjects(1).Range
rng.Cells(2, 2).Value = v ' etc.
.Workbook.Close
End With
End Sub
The requirement is to use the With
block in VBA.
Some brief tests suggest this is also doable via Interop from python using win32com
:
from win32com import client
ppt = client.Dispatch("PowerPoint.Application")
pres = ppt.ActivePresentation
sld = pres.Slides[0]
cht = sld.Shapes[0].Chart
cht.ChartData.Workbook.Worksheets[0].ListObjects[0].Range.Cells(2,2).Value = 9
And also in C#:
using Microsoft.Office.Interop.PowerPoint;
public static void foo(int value = 10)
{
Application ppt = new Microsoft.Office.Interop.PowerPoint.Application();
Presentation pres = ppt.ActivePresentation;
Slide sld = pres.Slides[1];
Chart cht = sld.Shapes[1].Chart;
{
cht.ChartData
.Workbook.Worksheets[1].ListObjects[1].Range.Cells(2, 2).Value = value;
}
}
To Minimize the ChartData
/ Workbook
Window:
In practice I have not had reliable luck using the With
method. If you cannot get it to work, then the next-best option is to minimize the window immediately:
Sub changeData(c As Chart, v As Double)
Dim rng As Object
With c.ChartData
.Activate
.Workbook.Application.WindowState = -4140 '## Minimize Excel
'## DO STUFF:
Set rng = .Workbook.Worksheets(1).ListObjects(1).Range
rng.Cells(2, 2).Value = v ' etc.
.Workbook.Close
End With
End Sub
Note that this method does briefly flash Excel on the screen, and this sucks because in that brief instant, it can intercept keystrokes/etc.
回答2:
You don't have to activate the chartdata worksheet to make changes to it.
With oPPSlide.Shapes("Chart1").Chart.ChartData
'this updates the value in the datasheet
.Workbook.Sheets(1).Range("B2").Value = 0.1231
End with
You can also set the chartdata sheet to equal a range in an excel sheet
path2 = "C:\JohnDoe\Vasquez_061118.xlsm"
Set xlWorkBook = Workbooks.Open(FileName:=path2, ReadOnly:=True)
With oPPSlide.Shapes("Chart1").Chart.ChartData
'this updates the value in the datasheet
.Workbook.Sheets(1).Range("A1:B2").Value = xlWorkBook.Sheets(1).Range("A2:B3").Value
End With
来源:https://stackoverflow.com/questions/50789959/update-powerpoint-chart-without-opening-chart-workbook-or-making-it-invisible