I haven't been able to find any workable solution for this in a couple hours of searching, so here I go.
I am exporting some data from access to excel via vba, formatting the excel and moving worksheets around, and then generating a chart. When I was testing it all in an excel macro I was able to use the SetDataSource method to adjust the range, but when I moved over to Access it didn't like this method, and will throw a run-time error of 438, "Object doesn't support this property or method". Simplified code below.
Dim xl as Object, wb as Object
Set xl = CreateObject("Excel.Application")
With xl
.Visible = False
.displayalerts = False
Set wb = .workbooks.Open(wbookpath)
'formatting code that all works fine
.Charts.Add
'add was called from sheet 11, popped up before 11 and am moving to end
.Sheets(11).move after:=.Sheets(12)
With Charts(1)
.SetSourceData .Range("Master!$A$1:$G$11")
'other chart formatting code that all works fine
End With
.activeworkbook.Close (True)
.Quit
End With
I have also tried changing the source, e.g.
.SetSourceData .Sheets("Master").Range("$A$1:$G$11")
changing where I call it from, e.g.
.Charts.Add
wb.Charts(1).SetSourceData .Range("Master!$A$1:$G$11")
With .Charts(1)
'rest of code
but it doesn't affect the error being thrown.
How can I get Access to adjust the source of my chart? If I can get this working then I would be able to go forward with making a slew of other charts as well.
This syntax worked for me:
With wb.Charts(1)
.SetSourceData Source:=Sheets("Master").Range("$A$1:$G$11")
'other chart formatting code that all works fine
End With
Reference https://learn.microsoft.com/en-us/office/vba/api/excel.chart.setsourcedata
Related
I am trying to use vba to expand or collapse the source data range of a PowerPoint chart. I can update the data, but when I use SetSourceData, nothing happens.
Example snippet:
With ActivePresentation.Slides(1).Shapes("Chart 5").Chart
.SetSourceData Source:="=Sheet1!$A$1:$D$4"
End With
What am I missing?
I tried using this code...
With ActivePresentation.Slides(1).Shapes("Chart 5").Chart
.SetSourceData Source:="=Sheet1!$A$1:$D$4"
End With
I am working on a personal powerpoint project and I thought it would be cool to use activex in the powerpoint to make the slides a bit more interactive. I have some activex boxes where you can set a population and an annual growth rate and the final step would be for me to plot the 5 year projection data i am getting on a line graph. I have tried it using excel based VBA but most solutions seem to require pulling data from a sheet so won't work in powerpoint.
I have also tried the following code to build a chart skipping the need for a worksheet but to no avail as I get a runtime error 424: Object required error:
Sub AddChart()
Dim cht As Chart
Dim ser As Series
Set cht = Charts.Add
cht.ChartType = xlColumnClustered
Set ser = cht.SeriesCollection.NewSeries
ser.XValues = Array(1, 3, 5, 7, 9)
ser.Values = Array(2.4, 3.2, 5.7, 12.67)
End Sub
Any solutions in mind or am I flogging a dead horse here?
Thanks!
Powerpoint doesn't have Charts.Add, but Shapes.AddChart2 or .AddChart
Something like this should get you going:
Sub AddChart()
Dim cht As Chart
Dim ser As Series
Set cht = ActivePresentation.Slides(1).Shapes.AddChart(-1, xlColumnClustered).Chart
Set ser = cht.SeriesCollection.NewSeries
ser.XValues = Array(1, 3, 5, 7, 9)
ser.Values = Array(2.4, 3.2, 5.7, 12.67)
End Sub
I know this is an old thread but in case someone stumbles on it like I did - you can paste an empty chart on a Master Layout and then copy it to any slide you need it on, that way Excel never launches to 'create' the chart object, although it is still 'embedded'.
If you create a special layout for it, just be sure to include a Title or some other placeholder because slides with no placeholders get helpfully removed/left behind by PowerPoint during certain operations - such as copying a slide into a new presentation and selecting 'Keep Source Formatting'.
I have currently written an Excel VBA code which creates 40+ PowerPoint Slides.
However, while running this code PowerPoint crashes after creating 22 slides.
This issue only occurs when the VBA code is run at one go. Because, when I try to run the same code line by line it runs successfully till end.
For me this is something weird. Do we have any suggestion for this problem ?
=> My code till creation of slide 2 is listed below (thereafter it create the other slides one after another till 43rd Slide)
Regards,
Alok
Sub test25()
Dim pApp As PowerPoint.Application
Dim pPres As PowerPoint.Presentation
Dim pSlid As PowerPoint.Slide
Set pApp = New PowerPoint.Application
pApp.Visible = True
pApp.Activate
Set pPres = pApp.Presentations.Open("C:\.....\Template.pptx")
pPres.Slides(1).Select
Sheets("S01").Select
ActiveSheet.Range("A1:P27").Select
ActiveSheet.Shapes.SelectAll
Selection.copy
pPres.Slides(1).Shapes.PasteSpecial DataType:=wdPasteText
pPres.Slides(2).Duplicate
pPres.Slides(2).Select
Sheets("S02").Select
ActiveSheet.Range("A1:P27").Select
ActiveSheet.Shapes.SelectAll
Selection.copy
pPres.Slides(2).Shapes.PasteSpecial DataType:=wdPasteText
End Sub
I see multiple potential issues, some of which are just code improvements.
On the line:
pPres.Slides(2).Duplicate
You are referring to slide 2, but you have not yet created slide 2 (as this is the line that creates it). Change this to:
pPres.Slides(1).Duplicate
I don't see how your code is running, even line by line, without that...unless 'template.pptx' already has all of the slides (in which case, why are you duplicating? I assumed 'template.pptx only contained the first slide)
Initially I suspected a race condition, but typically VBA handles these well. To be sure, and just general good practice, you may want to use a variable to refer to the current slide, instead of just a number (you already have the variable declared)
Set pSlid = pPres.Slides(1)
Sheets("S01").Select
ActiveSheet.Range("A1:P27").Select
ActiveSheet.Shapes.SelectAll
Selection.copy
pSlid.Shapes.PasteSpecial DataType:=wdPasteText
Set pSlid = pSlid.Duplicate
...
Also for your own convenience, you way want to look into using a loop, like:
Set pSlid = pPres.Slides(1)
For i = 1 to 43
Sheets("S" & Format(CStr(i), "00")).Select
ActiveSheet.Range("A1:P27").Select
ActiveSheet.Shapes.SelectAll
Selection.copy
pSlid.Shapes.PasteSpecial DataType:=wdPasteText
Set pSlid = pSlid.Duplicate
Next
I have the following example code in a module of VBA:
Sub My_Code()
ThisWorkbook.Sheets("Main").Range("A1") = "Main Data"
ThisWorkbook.Sheets("Secondary").Range("A2").Copy Sheets("Main").Range("B2")
End Sub
and to protect the sheets, Main and Secondary, I have put the following code in Thisworkbook of VBA:
Private Sub Workbook_Open()
Sheets("Main").Protect Password:="Mypassword", UserInterfaceOnly:=True
Sheets("Secondary").Protect Password:="Mypassword", UserInterfaceOnly:=True
End Sub
When I run My_Code() I get the error:
""Run-time error '1004'
The cell or chart you're trying to change is on a protected sheet.
To make changes, click Unprotect Sheet in the Review tab (you might need a password).""
And this debugs to the ThisWorkbook.Sheets("Secondary").... line.
When I manually Unprotect the Main sheet the code runs. Any ideas why I can't leave Main protected? Have I forgotten something?
#jkpieterse Gave the solution to this question which was to change the second line of the My_Code() to
Thisworkbook.Sheets("Main").Range("B2").Value = ThisWorkbook.Sheets("Secondary").Range("A2").Value
However this created a new error in my code which is mentioned in the comments about. The who reason behind this problem is that the UserInterfaceOnly = true does not allow macros to modify the sheet, it only allows for value changes. Therefore there is no way to use the interface protect work around when you modify the worksheet. The only solution from here is:
Sub My_Code()
Dim ws as Worksheet
Set ws = ThisWorkbook.Sheets("Main")
ws.UnProtect Password:="Mypassword"
On Error GoTo ErrHandeler
ws.Range("A1") = "Main Data"
ThisWorkbook.Sheets("Secondary").Range("A2").Copy ws.Range("B2")
ws.Protect:="Mypassword"
ErrHandler:
ws.Protect:="Mypassword"
End Sub
This is the next most secure solution.
The cells that you want to populate data in or modify needs to be unlocked. So select the range of cells, then in format cell set them to be unlocked. When you password protect the sheet, make sure you check allow to edit unlocked cells.
Try this with you original code, it should work. Since it worked when you unprotected the sheet.
It appears you have to reset the protection with UserInterfaceOnly = True upon Workbook_Open, which resolves my issue. Excel closes the workbook with a default of UserInterfaceOnly = False (even though I run the secure commands on the Workbook_BeforeClose event.
I have a working excel vba macro that does what I want from here and I am trying to convert it to VB.NET.
The code from VBA:
Sub bah()
''' Set Range you want to export to file
Dim rgExp As Range: Set rgExp = Range("B2:C6")
''' Copy range as picture onto Clipboard
rgExp.CopyPicture Appearance:=xlScreen, format:=xlBitmap
''' Create an empty chart with exact size of range copied
With ActiveSheet.ChartObjects.Add(Left:=rgExp.Left, Top:=rgExp.Top, _
Width:=rgExp.Width, Height:=rgExp.Height)
.Name = "ChartVolumeMetricsDevEXPORT"
.Activate
End With
''' Paste into chart area, export to file, delete chart.
ActiveChart.Paste
ActiveSheet.ChartObjects("ChartVolumeMetricsDevEXPORT").Chart.Export "C:\Users\ajohnson\Desktop\workdamnit.jpg"
ActiveSheet.ChartObjects("ChartVolumeMetricsDevEXPORT").Delete
End Sub
What this does is take an excel range and then put it into a chart that is a copy of the range and save it as a JPG.
Here is my most recent attempt at making it VB.NET:
Dim xlApp As New Excel.Application
Dim xlWorkBook As Excel.Workbook
Dim xlWorkSheet As Excel.Worksheet
Dim xlRange As Excel.Range
xlWorkBook = xlApp.Workbooks.Open("C:\test.xlsx")
xlWorkSheet = xlWorkBook.Sheets("Sheet1")
xlRange = xlWorkSheet.Range("B2:C6")
With xlWorkSheet.ChartObjects.add(xlRange.Left, xlRange.Top, xlRange.Width, xlRange.Height)
.name = "Chart1"
.activate()
End With
xlWorkSheet.ChartObjects("Chart1").Paste()
xlWorkSheet.ChartObjects("Chart1").chart.export(Filename:="C:\Users\ajohnson\Desktop\saveit.jpg")
xlWorkSheet.ChartObjects("Chart1").delete()
I am running into trouble converting the ActiveChart.Paste method. I can't get it to work in VB.NET. It either throws an error or It just leaves an empty box when I do it in VB.NET (if I add .chart before the paste it runs, but doesn't paste any values), but in VBA it fills in the values of interest. I have tried creating a chart object, but that did not seem to work either.
I feel like I am close to having it sorted out, but I can't quite get it. I suppose I could leave it as a VBA macro and call it from VB.NET, but that seems absurd on some level. Any help would be greatly appreciated. I am also open to different approaches, its just this is the thing I came across that worked well in VBA, so I figured it was a good starting point.
Thanks as always!
I just had to hit the MSDN up a little harder to get there. Turns out you have to put the chartobject inside a chart, the code I got working looks like:
xlRange = xlWorkSheet.Range("B2:C6")
xlRange.CopyPicture(Excel.XlPictureAppearance.xlScreen, Excel.XlCopyPictureFormat.xlPicture)
Dim oChtobj As Excel.ChartObject = xlWorkSheet.ChartObjects.add(xlRange.Left, xlRange.Top, xlRange.Width, xlRange.Height)
Dim oCht As Excel.Chart
oCht = oChtobj.Chart
oCht.Paste()
oCht.Export(Filename:="C:\saveit.jpg")
oChtobj.Delete()
I was going to delete the question, since it got solved by me so quickly (this ignores the decent bit of time I spent before I posted it here), but when I search for a problem like mine it comes to this page, so maybe this will help someone in the future. If you are looking to copy a range from excel to a jpg for some reason (perhaps attaching it to the body of an outlook email, because that is what I am doing), this should work for you.
And the C# equivalent requires the call to Activate() or COMException will be thrown
Excel.Range xlRange = xlWorkSheet.Range("B2:C6");
range.CopyPicture(Excel.XlPictureAppearance.xlScreen, Excel.XlCopyPictureFormat.xlPicture);
Excel.ChartObject chartObj = myWorksheet.ChartObjects().Add(range.Left, range.Top, range.Width, range.Height);
chartObj.Activate(); // Don't Forget!
Excel.Chart chart = chartObj.Chart;
chart.Paste();
chart.Export(#"C:\image.png");
chartObj.Delete();