Why is chart object Paste method not working? - vba

Current Code:
Const cName = "ChartDummy"
Const rName = "Availability"
Const iconSource = "C:\user.name\defaulfolder\"
'/* Availability is a named Range for this example but can be any valid range */
'/* UF_EmoTrans is a Userform with and Image Control named I_Console */
Dim oCh As ChartObject, chImg As String
Dim Ch As Object
Application.DisplayAlerts = False
With Sheet2
'.Activate
chImg = iconSource & "availIcon.jpg"
Set oCh = .ChartObjects.Add(370, 14, 180, 277.2): oCh.Name = cName
.Range(rName).CopyPicture xlScreen, xlBitmap
'oCh.Activate
oCh.Chart.Paste
oCh.Chart.Export chImg, "JPG"
'/* I call this procedure at UserForm_Initialize */
UF_EMOTrans.I_Console.Picture = LoadPicture(chImg)
oCh.Delete
End With
My current code works when I run it in break mode (using F8 and stepping through each line).
It exports the Range as image(through chartobject) and loads it to the userform just fine.
Now, when I run this in execution mode (loading the form), it doesn't create the same result.
It seems the oCh.Chart.Paste method didn't fire and so no image was paste within the chart.
Once exported, it produces a picture with plain white background.
So my question is, why is that? Why does it behave differently?
P.S.:
It will work if the chart is activated (but you will need to activate the sheet first) prior pasting (commented lines).
But I just want to know if this is one of those oddities that Excel have that we just have to live with.

When you show Userform, show userform modeless.
or When your proceure include userform.show , the image worked well.
UF_EMOTrans.Show (vbModeless)
or
UF_EMOTrans.Show (0)

Related

Excel: Button action code - Why can't I use a Workbook And Sheet Module

I have a Personal Workmap with a template ( with vba code and a button action ) that I copy into a worksheet when needed. It creates a Table of sheet to quickly access many, > 25 sheets, like a fake popup ( excel 2016 macos ). It did works well when I did program it directly into the sheet module. It collects the sheets and creates buttons with the following code.
Set btnRng = TOC_WS.Range(Cells(lastRow, btnCol), Cells(lastRow, btnCol))
Set btn = TOC_WS.Buttons.Add(btnRng.Left, btnRng.Top, btnRng.Width, btnRng.Height)
With btn
.OnAction = "btnAction"
.Caption = WS.Name
.Name = WS.Name
End With
And the button sub....
Sub btnAction()
......
End Sub
But now for some reason it doesn't work when the called sub is in the Sheet-module. I get the notification that it can't be found. If I put it into a code Module the it works. I did of course search te web, but couldn't find anything that say's it can't working.
My question - How can I get the button action back working into the same sheet-module as the rest of the code?
In General, when a routine is a member of a Worksheet, the worksheet's name is implicitly part of the routine's name.
btn.OnAction = "Sheet1.btnAction"
Or, as in your code you want to bind it to a routine in the TOC_WS sheet:
btn.OnAction = TOC_WS.CodeName & ".btnAction"
Moreover, if you want to move the routine to the code module ThisWorkbook,
btn.OnAction = "ThisWorkbook.btnAction"

Turning the visibility of chart series on/off using excel Macros/vba

I am making a line graph (chart) in Excel with several data series being plotted onto the same chart.
I need to create a macro/VBA solution that can turn the visibilty of these series on/off via the pressing of a button (or tick box etc)
Similar to this picture (manually done through the excel menu system)
I have tried to look through all the member vars/methods on
https://msdn.microsoft.com/EN-US/library/office/ff837379.aspx
but haven't had much luck.
I have tried playing around with bits like
Charts("Chart1").SeriesCollection(1)
and
Worksheets("Graphical Data").ChartObjects(1)
but I can neither get the chart object ( I get a subscript out of range error) nor able to find any method that would allow me to turn on/off the visibility of individual series.
Any Ideas?
Whenever I don't know how to do something like this, I turn on the macro recorder.
I had a chart with four series, and I used the filter function in Excel 2013 to hide and show the second series, while the macro recorder was running.
Here's the relevant code:
ActiveChart.FullSeriesCollection(2).IsFiltered = True
' series 2 is now hidden
ActiveChart.FullSeriesCollection(2).IsFiltered = False
' series 2 is now visible
The series type (line or column) does not matter, this works for any of them.
I believe the property you are looking for is the SeriesCollection.Format.Line.Visible property. I quickly created an Excel workbook and added a simple data set (just 1-10) and added a line graph "Chart 2" to the sheet Sheet1.
This code turned the visibility of the line off:
Option Explicit
Private Sub Test()
Dim cht As Chart
Dim ser As Series
'Retrieve our chart and seriescollection objects'
Set cht = Worksheets("Sheet1").ChartObjects("Chart 2").Chart
Set ser = cht.SeriesCollection(1)
'Set the first series line to be hidden'
With ser.Format.Line
.Visible = msoFalse
End With
End Sub
And likewise, setting the ser.Format.Line.Visible property to msoTrue made the line visible again.
As for retrieving the chart itself I had to first activate it, then set my cht variable to the ActiveChart. To view the name of your chart, select it and look in the name box (near where you would enter the cell value / formula).
Update
When using the method above, the series name remains in the legend box. I couldn't find a visibility property for the SeriesCollection in the legend, however one workaround is to simply re-name the series as an empty string (this will make the series disappear from the legend) and then rename the series when you want to show it.
This code below will toggle the visibility of the line and series name in the legend.
Option Explicit
Private Sub Test()
Dim cht As Chart
Dim ser As Series
'Retrieve our chart and seriescollection objects'
Set cht = Worksheets("Sheet1").ChartObjects("Chart 1").Chart
Set ser = cht.SeriesCollection(1)
'Set the first series line to be hidden'
With ser.Format.Line
If .Visible = msoTrue Then
.Visible = msoFalse
ser.Name = vbNullString
Else
.Visible = msoTrue
ser.Name = "Series 1"
End If
End With
End Sub
And, whenever you use .Format.Line.Visible = msoTrue just remember to set ser.Name back to whatever the name for your series is.
There is a simple way to on & off the visibility of the series: using filter on your source data.
May it help you easily as follows.
You can insert a new Window. Setone of them to source data sheet and the other window to Chart sheet. Then arrange the two windows to see both at the same time. Now if you filter the series you like on the source data sheet simultaneously you will see the series you desired on the other sheet.

Word won't save when box is copied

I have a VBA program that automates assembly of Word documents from other docs using mostly copy/pasting and bookmark insertions. One template won't save after copying from another document. Here is the code that errors:
'get starting doc w macro (styletemplate)
Set mydoc = wrd.Documents.Open(strformattemplate, False, False)
'this is the base doc with styles - this save works fine
mydoc.SaveAs2 filename:=strNewName,FileFormat:=wdFormatXMLDocumentMacroEnabled
'here's our skeleton this is what we want to copy in
Set skel = wrd.Documents.Open(skelpath)
Set rangetocopy = skel.Range(0, skel.Bookmarks("\endofdoc").End)
rangetocopy.copy ' copy to clipboard
'copy in the skeleton and close it
Set workingrange = mydoc.Range(0, mydoc.Bookmarks("\endofdoc").End)
workingrange.Paste
mydoc.Save 'here's where it's failing
skel.Close False
The second save fails. There is an endless pop-up. The user must abort. I want to emphasize that this code works on all other templates. It appears to fail if one shape (a box that is an underline for a header) is included. Boxes like this appear in the first page of each chapter.

Open Website in excel using ActiveWorkbook.FollowHyperlink

So, this is basically what I'm trying to do. I have a column of employee #'s in a file that's generated from MSSQL. I want to create a function in a cell where the URL would be, http://www.someplace.com/employee.php?ID=Employee#FromCell
So far all of the examples that I've found aren't detailed enough for me to figure out what to do with it. I know this isn't correct, but this is what I ended up with so far
Function openurl(strSKU As String)
ActiveWorkbook.FollowHyperlink Address:="http://www.someplace.com/employee.php?ID=?strSKU=" & strSKU, NewWindow:=True
End Function
I think I'm mixing up methods with functions but I'm not sure where to go with it. I basically want to add it in as a function to make it easier to insert into the column.
I see someone provided you with a work-around for accomplishing this, but I'll give you the method you were asking for (just in case). FYI the intellisense sucks in VBA when referencing OLE objects (i.e., some methods may not appear to belong to the button objects, but they do).
The script below will create the buttons for you automatically, and will send the user to the site you specified when clicked. **I included notes which explain what each line does.
This creates the buttons in columns B and gets the URL parameter from column A:
Sub CreateButtons()
Dim btn As Button 'Create a variable for our button
Application.ScreenUpdating = False 'Speed up the process by disabling ScreenUpdating
ActiveSheet.Buttons.Delete 'Delete existing buttons.
Dim Report As Worksheet 'Create our worksheet variable.
Set Report = Excel.ActiveSheet 'Set our worksheet to the worksheet variable.
Dim t As Range 'Create a variable for the cells we will reference.
For i = 1 To Report.UsedRange.Rows.Count 'This will loop through each row in the used range of our worksheet.
If Report.Cells(i, 1).Value <> "" Then 'If the value of the first cell is not empty, then do the following...
Set t = Report.Range(Cells(i, 2), Cells(i, 2)) 'Assign the cell in the second column of the current row to the cell variable.
Set btn = Report.Buttons.Add(t.Left, t.Top, t.Width, t.Height) 'Create a button and place it in the cell in the second column.
With btn
.OnAction = "openurl" 'Set the button to trigger the openurl sub-routine when it is clicked.
.Caption = Report.Cells(i, 1).Value 'Set the caption of the button to equal the value of the cell in the first column.
.Name = i 'Set the name of the button to equal the row on which it resides. This name will be used in the openurl sub; So don't change it.
End With
End If
Next i
End Sub
This is the macro performed when the user clicks a button:
Sub openurl()
Dim Report As Worksheet 'Create a variable for the worksheet
Set Report = Excel.ActiveSheet 'Assign the worksheet to our variable
Dim i As Integer 'Create a variable for our row number
i = Application.Caller 'Assign name of the button to our row number.
Dim address As String 'Create a variable for our address
address = "http://www.someplace.com/employee.php?ID=?strSKU=" & Report.Cells(i, 1).Value 'Assign the URL to our address variable.
ActiveWorkbook.FollowHyperlink address:=address, NewWindow:=True 'Send the user to the URL you specified (with the URL parameter at the end).
End Sub
BONUS INFO:
Follow the next step to have the entire process done for you automatically:
When you say the current data is populated from a MSSQL database, you probably mean you are pulling the data into Excel using another VBA sub or function. If so, then if you place a script to call the "CreateButtons()" subroutine after the script that pulls the data, this entire process will be done for you automagically. Example:
Sub getEmployeeData() 'This represents your sub that pulls your data from MSSQL
'================================================================
'This represents your script to get your information into Excel.
'================================================================
Call CreateButtons 'This runs the CreateButtons() subroutine.
End Sub
Enjoy!
You can do this without VBA. You can use a formula.
=Hyperlink("http://www.someplace.com/employee.php?ID="&A1,A1)
Where A1 would have the employee ID.
Check out this post I made about creating hyperlinks from External Data:
http://www.spreadsheetsmadeeasy.com/creating-hyperlinks-with-external-data/
Scroll down to the "Add Hyperlinks" section for more info.

VBA Office2010 Shapes.PasteSpecial fails

I have a problem while migrating my VBA code from Office2003 to Office2010. I would like to copy the text of a cell (Excel) to Powerpoint. Office2003 generated a new textbox and the style of the text was the same as in Excel. Now my code fails with Office2010 and I get the following message:
runtime error -2147188160 (80048240)
Shapes.PasteSpecial : Invalid request. Clipboard is empty or contains data which may not be pasted here.
The clipboard is definitly not empty.
The code is the following:
Set mySlides = obj_pp.ActivePresentation.Slides
mySlides(Slidenum).Shapes.PasteSpecial DataType:=ppPasteRTF
I have already tried other DataTypes and the Paste-function. Nothing helped. The text, I copy from Excel, is also formatted as text in Excel. Nothing special. The slide is added as an empty one. After adding the slide a picture is pasted (DataType:=ppPasteEnhancedMetafile). And after that the text should be pasted.
Could someone please help me to get this code work? Thanks in advance. Please let me know if more code is needed.
Edits:
Binding of the ppt:
Dim Datei As String
Pfad_Server = "..."
Pfad_Verzeichnis = "..."
Dateiname = "....pptx"
Datei = Pfad_Server & Pfad_Verzeichnis & "\" & Dateiname
Set obj_pp = (GetObject(, "Powerpoint.Application"))
obj_pp.Visible = True
IsOpen = False
Before running the macro I always open the ppt. This works fine.
Adding slide and pasting range as picture (works fine):
Range(Cells(start_var, 1), Cells(bereich_ende, 13)).Select
Selection.CopyPicture xlScreen, xlPicture
...
Set mySlides = obj_pp.ActivePresentation.Slides
mySlides.Add Index:=mySlides.Count + 1, Layout:=12 'ppLayoutBlank
mySlides(Slidenum).Shapes.PasteSpecial DataType:=ppPasteEnhancedMetafile
In my opinion you need to change method which copies your range. Use this lines instead your .CopyPicture line:
Selection.Copy
and it will work with pasting method:
mySlides(mySlides.Count).Shapes.PasteSpecial DataType:=9
where 9 = ppPasteRTF.