VBA activate chart created in different function - vba

Say I have created a chart in one function as shown:
Sub CreateChart()
Dim sh As Worksheet
Dim chrt as Chart
Set sh = ActiveWorkbook.Worksheets("Sheet1")
Set chrt = sh.Shapes.AddChart.Chart
End Sub
How can I activate this chart in a different function where I want to move it to a certain cell? I am using the following code but it keeps giving me errors and won't activate the chart. I even gave the chart a Title and tried to use it's title t activate it but it won't recognize the name:
Sub MoveChart()
ActiveSheet.ChartObjects("chrt").Activate
With ActiveChart.Parent
.Left = Range("N2").Left
End With

Why activate it? You may use directly the chrt object that you stored, which you may pass to a parametrized MoveChart subroutine:
Sub MoveChart(ByVal chrt As Excel.Chart)
With chrt.Parent
.Left = Range("N2").Left
End With
End Sub
with the difference that now you may move any chart you'd like.
Later edit
The second macro fails because the chart remains unnamed. Trying to access the chart by the name of the VBA variable doesn't do the trick. So, try this:
Sub CreateChart()
Dim chrt As Shape
With ActiveWorkbook.Worksheets("Sheet1").Shapes
Set chrt = .AddChart()
Let chrt.Name = "New chart"
End With
End Sub
Sub MoveChart()
With ActiveWorkbook.Worksheets("Sheet1")
.ChartObjects("New chart").Left = .Range("N2").Left
End With
End Sub
Don't forget to modify the code to use other chart names, other sheet names etc.

Related

VBA Word: Change Data of charts

I want to change the data of a chart in a Word Document, but I can't find the right way to address my charts. I tried several techniques, but nothing worked. (I´d love to open a ExcelSheet in which I can just change the Data)
So to put it all together: I want to change the data (not the source), of a MS Word chart, which looks like that:
Edit(13.8.):
After request, I try to give you some "reference Code" to work with.
Sub ChangeChart()
Dim aktDocument As Document
Dim chrt As Chart
Dim SourceSheet As Excel.Worksheet
Set aktDocument = ActiveDocument
Set SourceSheet = aktDocument.Shapes(1).Chart.OpenSourceData 'I know it´s not that easy
SourceSheet.Range("B5") = newStuff
aktDocument.Shapes(1).Chart.SetSourceData = SourceSheet
End Sub
I know this may sounds utopic and ridiculous, but I just don´t know, how to address the chart in the right way, or to even work with it properly.
Edit(15.08):
Even after recreating the old charts, the following code is not able to find a shape which has a chart. And therefore it stops when the index is out of range.
Sub Test()
i = 0
Do While i < 100
i = i + 1
If ActiveDocument.Shapes(i).HasChart Then
MsgBox "found one!"
End If
Loop
End Sub
Solution(30.08.):
The answer from #Cindy Meister was the solution to my problem. After further working with it, I came to the problem, that the ChartData always opens on the screen, while running the code.
Just for reference this question was my workaround.
All Office applications use the Excel engine to create and manage charts. In Word, charts can be formatted in-line with the text or with text wrap formatting. In the former case, a chart object needs to be addressed via the InlineShapes collection, in the latter via the Shapes collection.
Since your sample code uses Shapes(1) I've used that in the code snippet below. If it's not certain that the first Shape in the document is the chart, but you've assigned the Shape a name, you can use that as the index value (for example Shapes("MyChart"). Or you can loop the Shapes collection and check HasChart.
HasChart returns True if the Shape (or InlineShape) is a Chart. It's then possible to set Shape.Chart to an object variable. The chart's data can be accessed using Chart.ChartData.Activate - if you don't use Activate it's not possible to access the data when the chart's worksheet is stored in the Word document. Only then can Chart.ChartData.Workbook return a workbook object, and through that the worksheet can be accessed using ActiveSheet. From that point on, it's like working with the Excel object model.
Sub ChangeChart()
Dim aktDocument As Document
Dim shp As Word.Shape
Dim chrt As Word.Chart
Dim wb As Excel.Workbook, SourceSheet As Excel.Worksheet
Set aktDocument = ActiveDocument
Set shp = aktDocument.Shapes(1)
If shp.HasChart Then
Set chrt = shp.Chart
chrt.ChartData.Activate
Set wb = chrt.ChartData.Workbook
Set SourceSheet = wb.ActiveSheet
SourceSheet.Range("B5").Value2 = newData
End If
End Sub

Excel Secondary Axis font colour change by VBA without activating chart

I've seen this question on font properties and it's got me part of the way.
I'm trying to change the font colour. I so far have the following code:
ActiveSheet.ChartObjects("Chart 2").Activate
ActiveChart.Axes(xlValue, xlSecondary).TickLabels.Font.Color = 5855577
This works fine.
What's irritating me is that I have to do this via activating the chart.
Surely there's a better way. If I do either of the following it doesn't work:
Dim cht As ChartObject
Set cht = ActiveSheet.ChartObjects("Chart 2")
cht.Axes(xlValue, xlSecondary).TickLabels.Font.Color = 5855577
'-------------------------
Dim cht As ChartObject, ax As Axes
Set cht = ActiveSheet.ChartObjects("Chart 2")
Set ax = cht.Axes(xlValue, xlSecondary)
ax.TickLabels.Font.Color = 5855577
I generally try to avoid selecting or activating in my code so this is just annoying! Any ideas?
Axes isn't actually a member of a ChartObject, but a member of ChartObject.Chart.
Therefore, you want to access the Axes-collection of ChartObject.Chart
With ActiveSheet.ChartObjects("Chart 1")
.Chart.Axes(xlValue, xlPrimary).TickLabels.Font.Color = vbRed
End with
Why does it work if you activate it first? Well, because ActiveChart actually returns the Chart-object, instead of the ChartObject-object.
In case you're trying to record a macro, the code for filling the text forecolor won't (TextFrame2 object) work due to a bug already reported to Microsoft, so using the code below, you can do it without issue. You can also change the properties according to your needs.
Use this code:
ActiveChart.Axes(xlCategory).TickLabels.Font.Color = RGB(100, 100, 100)
I prefer also to avoid working with ActvieSheet (if possible).
The code below, will set the nested properties under ChartObject for the properties you need, such as Chart.Axes , and later also for TickLabels.
Code
Option Explicit
Sub Chart_AutoSetup()
Dim ChtObj As ChartObject, ax As Axis, T2 As TickLabels
Dim ShtCht As Worksheet
' change "Chart_Sheet" to your sheet's name (where you have your chart's data)
Set ShtCht = Worksheets("Chart_Sheet") ' <-- set the chart's location worksheet
Set ChtObj = ShtCht.ChartObjects("Chart2") '<-- set chart object
With ChtObj
Set ax = .Chart.Axes(xlValue, xlSecondary) '<-- set chart axes to secondary
Set T2 = ax.TickLabels '<-- set Ticklables object
T2.Font.Color = 5855577
T2.Font.Italic = True ' <-- just another property you can easily modify
End With
End Sub

Copying cell value to textbox vba

I have been trying to write a macro that will dynamically fill a textbox on a new sheet will the value of a cell from another sheet.
I have managed to get it working using this:
Sub copyDetail()
' Define variables
Dim pre As Worksheet
Dim des As Worksheet
Set pre = Sheets("Presentation")
Set des = Sheets("Description")
Dim i As Integer
Dim lbl As String
' Scroll through labels and copy where boolean = 1
For i = 2 To 17
If des.Cells(i, 2) = 1 Then
lbl = des.Cells(i, 11)
Sheets("Presentation").Select
ActiveSheet.Shapes.Range(Array("TextBox 1")).Select
Selection.Text = lbl
Else
End If
Next i
End Sub
I basically want to be able to do exactly what this does but without using select all the time as this changes sheets and slows down my code (I have many other sub's to run alongside this one). I've tried things like defining the textbox using this:
Dim myLabel As Object
Set myLabel = pre.Shapes.Range(Array("TextBox 1"))
But then I get an "object doesn't support this property or method" error when I try and call:
myLabel.Text = lbl
You can set the text of a TextBox like so:
ActiveSheet.Shapes("TextBox 1").TextFrame.Characters.Text = "Hello world"
You can set-up a little helper Sub in a Module to make the code re-usable:
Public Sub SetTextBoxText(ws As Worksheet, strShapeName As String, strText As String)
Dim shp As Shape
On Error Resume Next
Set shp = ws.Shapes(strShapeName)
If Not shp Is Nothing Then
shp.TextFrame.Characters.Text = strText
Else
Debug.Print "Shape not found"
End If
End Sub

Show and Hide Active Chart

I have this code which allows charts to show and hide however i have too many charts and hardcoding each of it would be a great hassle. Thus is it possible to hide and show charts based on the active chart?
I have this code and i tried replacing the Chartobjects("Chart4") to ActiveChart but it says object does not support that property. Any alternative ways to make this happen or is there anything wrong with my code? Thank you in advance!
Sub ActiveChartShowHide()
With Sheets("Sheet4").ChartObjects("Chart 4")
.Visible = Not .Visible
End With
End Sub
ActiveChart refers to the Chart object which is a member of the ChartObject object. Your code should be:
With ActiveChart.Parent
.Visible = Not .Visible
End With
You could loop through the chart objects to show or hide all of them to save time and typing:
Option Explicit
Sub HideAllChartsInSheet1()
Dim oChartObject As ChartObject
For Each oChartObject In Sheet1.ChartObjects
oChartObject.Visible = False
Next
Set oChartObject = Nothing
End Sub
Replace Sheet1 with a reference to your actual Worksheet-object, and of course use oChartObject.Visible = True to show the ChartObjects instead.
EDIT:
Let's change the sub to modify specific chart object:
Option Explicit
Sub ChartVisible(psName As String, pbVisible As Boolean)
Dim oChartObject As ChartObject
For Each oChartObject In Sheet1.ChartObjects
If UCase(oChartObject.Name) = UCase(psName) Then
oChartObject.Visible = pbVisible
End If
Next
Set oChartObject = Nothing
End Sub
Example: use the following to hide "Chart 4" on Sheet1:
Call ChartVisible("Chart 4", False)
You can just select your chart and then hide it:
ActiveSheet.ChartObjects("Chart 1").Activate
Selection.Visible = false

Macro for Excel to refrech Labels Chart

I work on Excel and I'm not really familiar with macros assigned to charts. Basically I have several charts. I need each of these charts to have labels that corresponds to data in another spreadsheets called "Data_SC". So for instance I would have:
Graph1: Label_1 = Data_SC!A1 ;
Label_2 = Data_SC!A2...
Graph2:
Label_1 = Data_SC!B1 ;
Label_2 = Data_SC!B2...
I tried to do it only for the first labels of each charts but I get the error "Type:mismatch". Here is my code:
Sub Refresh_Labels()
Dim cht As ChartObjects
For Each cht In Sheets("Sheet1").ChartObjects
cht.SeriesCollection(1).Points(1).HasDataLabels = True
cht.SeriesCollection(1).Points(1).DataLabel(1).Text = Sheets("Data_SC").Range(A1)
Next cht
End Sub
Could you guys help me please?
This should work:
Sub Refresh_Labels()
Dim cht As ChartObject
For Each cht In Sheets("Sheet1").ChartObjects
cht.Chart.SeriesCollection(1).Points(1).HasDataLabel = True
cht.Chart.SeriesCollection(1).Points(1).DataLabel.Text = Sheets("Data_SC").Range("A1")
Next cht
End Sub