I've written a bunch of VBA for Excel 2010 to retrieve data from an Access database, place the pivot table into a new workbook and create a pivot chart based on that pivot table with two data series. One series is a bar and the second series is a line on which I have set the .MarkerStyle to xlMarkerStyleNone. The macro also saves the new workbook.
When I open that saved workbook, I find that the line now has markers on it.
In trying to find out what's going on here, I have hit [CTRL]-[BREAK] to stop the macro after the chart is formatted and before it's saved, so I can see what's in the chart format. I can see that the marker style has been set to none when I right-click the series and see the properties, and also by verifying that by seeing that .MarkerStyle on the relevant series is still set to xlMarkerStyleNone.
When I go to save the new workbook manually with [CTRL]-[S], it saves just fine and loads up without the line markers. But when I save the file with save-as ([ALT]-[F], [A]), I see the markers appear after the file is saved.
So I don't think it's code that's doing this, but the Workbook.SaveAs method. But I'll show relevant code just in case.
I have used both xlExcel12 and 50 as the FileFormat when saving as a .xlsb file, and both xlOpenXMLWorkbook and 51 when saving as a regular .xlsx file. This has made no difference, either.
Update: I have also tried the Workbook.Save method, which just saves the new workbook I create as Book1.xlsx, and it has the same problem.
' Chart Formatting
reportSheet.Shapes(10).Chart.SeriesCollection(2).ChartType = xlLine
reportSheet.Shapes(10).Chart.SeriesCollection(2).Format.Line.Visible = msoTrue
reportSheet.Shapes(10).Chart.SeriesCollection(2).Format.Line.ForeColor.RGB = RGB(186, 7, 67)
reportSheet.Shapes(10).Chart.SeriesCollection(2).Format.Line.Transparency = 0
reportSheet.Shapes(10).Chart.SeriesCollection(2).Format.Line.Weight = 1.5
reportSheet.Shapes(10).Chart.SeriesCollection(2).MarkerStyle = xlMarkerStyleNone
' Saving the chart
reportbook.SaveAs fileName:=saveFileSpec, FileFormat:=xlOpenXMLWorkbook
I'm expecting the workbook to save without any changes being made in the save process when using the Workbook.SaveAs method.
OK, this is silly, but I've gotten around it by drum roll formatting-and-saving twice. This will do for now, but I'll try Jon Peltier's suggestions at some point and report back.
Related
I am editing a PPT template with data from Excel using the following code:
Set shapeObject = oPPT.ActivePresentation.Slides(slideIndex).Shapes("Chart 9")
With shapeObject.Chart.ChartData
.Workbook.Worksheets(1).Range("B2").Value = Sheets(slideSheetName).Range("D3").Text
.Workbook.Worksheets(1).Range("B3").Value = Sheets(slideSheetName).Range("D4").Text
.Workbook.Worksheets(1).Range("B4").Value = Sheets(slideSheetName).Range("D5").Text
.Workbook.Close
End With
When I click to Edit Data on the chart in PPT I see the data as it was copied over from the above code. But some users see no data in the Edit Data sheet but the chart itself still has data in it.
Has anyone ever seen that before? What is the fix?
.Workbook.Worksheets(1).
This reference doesn't seem sound.
I'd try something like this:
Workbooks('NameofWB').Sheets('Sheet1')
So the code is explicit as to what workbook is referenced.
I am trying to copy some charts (embedded) in different worksheets of an excel workbook using vbscript into different slides of a powerpoint. I would like to keep the link between the excel sheet and the powerpoint while doing so and therefore I used the below piece of code that allows me to keep formatting and link (instead of a simple paste or PasteSpeical. Is there any other way?) :
For i = 1 to TotalNumWorkSheets 'I iterated with indices.
Set pptSlide = pptPres.Slides.Add(i, 11) 'There is one opening slide before this.
set ws = wb.Worksheets(i)
ws.ChartObjects(1).Chart.ChartArea.Copy
pptApp.CommandBars.ExecuteMso("PasteExcelChartSourceFormatting")
pptApp.CommandBars.ReleaseFocus
With pptSlide
.Shapes.Title.TextFrame.TextRange.Text = objCurSheet.Name
'Adding some more textboxes here. Working fine. Position checks out in PPT.
.Shapes(.Shapes.Count).Left = 20 'Doesn't work for all slides.
End With
Next
The code works and copies all the charts, creates titles, adds new text as expected, but I am not able to position the charts on individual slides because after the ExecuteMso command, I don't know how to access the reference to the chart. I read in one of the SO posts that pasting using this method looses the chart selection but you can access the last .Shapes object since pasting always adds the object to the end of the list. Is that always the case? I tried accessing and positioning my chart by accessing the last object but it only works for the first slide of the loop (i.e. the first chart pasted is shifted to Left=20). The rest all charts in other slides are centered. Can someone explain where and how to add the formatting chart options? I ran into an even weirder problem. If I increase the number of worksheets, even the first plot looses it's Left formatting. The above code is the only place where I add formatting so I don't know what is happening. I am sure I am not formatting it correctly.
Many thanks for your suggestions.
Edit: One additional thing which I tested. I am using
WScript.Sleep 500
code before the For loop ends since it gives enough time for earlier operations to finish (at least that's what I understood from many other google searches).
So after some more searching and testing, I found a solution (for my case at least).
Moved the WScript.Sleep 1000 (500 didn't work for me) statement just below CommandBars.ReleaseFocus.
It makes some sense now since it is the Chart copying, pasting and linking from excel that needs time. Especially with source formatting. After that there is only text generation which I believe is not so heavy.
Cleared all the set Object variables when not used. Especially the ones associated with the "With" keyword.
set obj = CreateObject()
With obj
'Do something here.
End With
set obj = Nothing
Not clearing them, apparently, can also prevent you from closing the applications even after you use the .Close and .Quit method. At least that's what I observed. I found PowerPoint.exe running in the task manager when nothing was opened.
After doing the above, I am able to copy with format the charts and also able to set the position of the charts. The weird problem of larger number of worksheets also disappeared. Hopefully, it might help others. If someone thinks the observations are incorrect or troublesome, please correct.
Using data from Access, I have created a line chart in Excel. When I go to copy/paste the chart into a report my DB, the image is not the same. But, if I paste the same image into a work doc or outlook email, it looks fine. The same distorted version appears if I paste it into msPaint. Please see the attached screenshots of the charts. The big issue is the x-axis labels. Here is my copy/paste code.
Dim objChart As Chart
objChart.CopyPicture xlScreen, xlBitmap, xlScreen
DoCmd.OpenReport ReportName:="rptDeptWindowChart", View:=acViewDesign
ctlC = Reports!rptDeptWindowChart.Controls.Count
Do
For Each ctl In Reports!rptDeptWindowChart
ctl.Name = "ctlDelPic"
DeleteReportControl "rptDeptWindowChart", "ctlDelPic"
Next
ctlC = Reports!rptDeptWindowChart.Controls.Count
Loop Until ctlC = 0
DoCmd.RunCommand acCmdPaste
Access is not well-known for it's charting capabilities. If I were you, I'd stick to using Access for managing large data sets, and export final results of queries to Excel, and do your charting/plotting/graphing in Excel. Word is great for creating documents, PowerPoint is great for presentations, etc. You need to use the right tool for the right job.
Is there an easy way to set a default size for all new charts created in Excel 2010?
I need them to be like 10,52cm for a bunch of users at the office, and I can't seem to find how to do this without using macros.
While you cant set the default chart size you can add a Event handler to modify any new charts (needs vba code though)
(This is a new event to Excel 2010)
Put this in the Workbook module:
Private Sub Workbook_NewChart(ByVal Ch As Chart)
Ch.Parent.Height = 400
Ch.Parent.Width = 600
End Sub
Note: this assumes you can add code to the workbook charts will be added to. If you prefer, you can create an addin that includes code to handle all workbook events. This would remove the need to have this code in all workbooks.
I've got an Access 2007 database on which I have created around 15 SQL queries to process specific data, I have created a main frame navigation menu using menus in Access, I now need to extract all th queries to Excel using VBA code, I have managed to do this with the code below by creating a button and specifying this code to it.
Private Sub query1_Click()
DoCmd.TransferSpreadsheet acExport, _
acSpreadsheetTypeExcel9, "Total Users and Sessions", _
"C:\UsersandSessions.xls", , "Total Users & Sessions"
End Sub
Now my problem at the moment is that fine the query is exported to Excel, but it is done so without any formatting applied at all, I would like to add some formatting at least to the headers and maybe a title inside the spreadsheet, and one thing I dont really like is that all records are being started from the first cell. Also I would prefer that if I hit that button again in Access and the Excel spreadsheet has already exists with that query output then when clicked again it will write again to a the next available sheet.
Any suggestions or ideas a very welcome.
The short story, is you can't. You might be able to do some scripting on the Excel side to format the resulting file. If you want something pretty, you probably want to create a report.
You could, instead mount the excel sheet as a table, and then on a separated sheet in the excel file, reference the first sheet, and format the second sheet for viewing.
if you use DoCmd.TransferSpreadsheet and create an original and then edit it so that the formatting is correct, you can then run DoCmd.TransferSpreadsheet again and it will update the file with the values but keep the formatting.
However, if a human then changes the file by adding new tabs, or adding calculations, etc, then the DoCmd.TransferSpreadsheet will no longer work and will fail with an ugly error message. So what we do in our enviroment is DoCmd.TransferSpreadsheet to an original file with formatting, and follow that up in the VBA by copying the file to the users desktop, and then opening that copy so the user doesn't mess up the original source excel file.
This approach is a minimum code, clean, and easy to maintain solution. But it does require a extra "source" or original file to be hanging around. Works in Access 2007.
You also would like the results to end up on a new tab. Unfortunately, I think it will take some excel automation to do that. The VBA inside Acccess can call a function inside the VBA in Excel. That VBA could then copy the tabs as needed.
My idea would be a hybrid of Excel automation from Access and creating a template in Excel as well that would have a data table linked to your query.
To start create your data table in Excel. You can start three rows down and two columns to the right if you want or wherever. Go to your data tab and click access, find your db, choose your query you want to link to, choose table as the radio button but click properties next instead of ok, uncheck the enable background refresh, this part is critical ... under the definition tab in the connection string you will see a part that says Mode=Share Deny Write change that to Mode=Read, this will make sure that the query refreshes without errors from an MS Access VBA while the db is open and will keep your users from writing back to the db in case your query is a writeable query. Once you set that up you can adjust the table formatting however you choose from the table design tab and it will keep that formatting.
For the purposes of this we are going to assume you started the table in cell B4 ,and your named the worksheet CurrentDay, for purpose of the following VBA example be sure to replace that reference with your actual placement.
Next go back to Access and write your VBA first ensure that in your VBA window you have the reference to Microsoft Excel 12.0 Object Library is selected by going to Tools > References and selecting it from the alphabetical listing.
Create your sub as follows:
Sub query1_click()
Dim xl as Excel.Application
Dim wbk as Excel.Workbook
Dim wks as Excel.Worksheet
Dim RC as Integer
Dim CC as Integer
Set xl = New Excel.Application
Set wbk = xl.wbk.Open "X:\Filelocation\FileName.xlsx" 'name and path you saved the file you previously created
xl.Visible = True
'The above is not necessary but you may want to see your process work the first few times and it will be easier than going to task manager to end Excel if something fails.
RC = xl.Application.CountA(xl.wbk.Worksheets("CurrentDay").Range("B:B")) + 3 'This will count the rows of data in your table including your header so you can copy the data to another tab dynamically as the size of your table expands and shrinks we add 3 to it because we started at row 4 and we need the location of the last row of the record set.
CC = xl.Application.CountA(xl.wbk.Worksheets("CurrentDay").Range("4:4")) + 1 'This counts the header row and adds one space because we will use this as a location holder for our copy / paste function
Set wks = xl.wbk.Worksheets.Add
wks.Name = format(date(),"MM_dd_yy") 'this will name the tab with today's date... you can eliminate this step if you just want the sheets to be the generic Sheet1, Sheet2, etc.
With xl.wbk
.Worksheets("CurrentDay").Range(Cells(4,2),Cells(RC,CC)).Copy
.wks.PasteSpecial xlPasteValues 'This pastes the values so that the table links do not paste otherwise every tab would just refresh everyday.
.wks.PasteSpecial xlPasteFormats 'This gets your formatting.
.RefreshAll 'This will refresh your table
Wend
With xl
.Save
.Close False
.Quit
Wend
Set xl = Nothing
Set wbk = Nothing
Set wks = Nothing
End Sub
That should get you to have your data to not start on A1 of your sheets, save your old data each time, and automate the steps from access.