I try to create dynamic chart with VBA , for example I have 5 students I need to create 5 chart
for each students .
Sub Macro4()
Rows("2:2").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!$2:$2")
Rows("3:3").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!$3:$3")
Rows("4:4").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!$4:$4")
Range("D12").Select
ActiveWorkbook.Save
End Sub
I create this using Macro only for test but I try do that as dynamically because if I have more then 100 students it will be difficult , etc..
I hope you guys help me
Thanks
Try the next way, please. No need of any selection. Selection is useless, it only consumes Excel resources:
Sub AddCharts()
Dim sh As Worksheet, ch As Shape, chartNo As Long
Dim prevWith As Long, i As Long
Set sh = ActiveSheet 'the sheet where the charts to be created
'chartNo = 5
chartNo = = Worksheets("Sheet1").Range("A" & rows.count).End(xlUp).row - 1
For i = 1 To chartNo
Set ch = sh.Shapes.AddChart
ch.Chart.ChartType = xlColumnClustered
ch.Chart.SetSourceData Source:=Range("Sheet1!$" & i + 1 & ":$" & i + 1)
ch.Chart.Parent.left = sh.Range("A1").left + prevWith 'here the first left chart position to be set
prevWith = ch.Chart.Parent.width 'the chart width, the next one will be added to its right side
Next i
ActiveWorkbook.Save
End Sub
Change your macro like this:
Sub Macro4(startRow As String, stud As Long)
For k = 1 To stud
Dim constr() As String
Dim cn As String
cn = ""
constr = Split(strtRow,":")
For Each c in constr
cn = cn & "$" & c & ":"
Next
cn = Left(cn, Len(cn) - 1)
Rows(strtRow).Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range("Sheet1!" & cn)
Dim str As String
str = ""
For each d in constr
str = str & (CInt(d)+1) & ":"
Next
str = Left(str, Len(str) - 1)
strtRow = str
Next
Now call like
Macro4("2:2",3)
Will do on 2:2 to 4:4
Related
I am Trying to pass the value i.e sArg with the onAction.But Im not able to do so.
I have tried like this: "'btnT """ & sArg & """'" But this doesn't work.
For i = 3 To LastRow Step 1
Set t2 = ActiveSheet.Range(Cells(i, LastCol + 3), Cells(i, LastCol + 3))
Set btn2 = ActiveSheet.Buttons.Add(t2.Left, t2.Top, t2.Width, t2.Height)
sArg = CStr(i)
With btn2
.OnAction = "Sheet1.btnT"
.Caption = "View " & i
.Name = CStr(i)
End With
Next i
Then the function is
Sub btnT(Text)
MsgBox Text
Exit Sub
You just have to enclose the single and possibly double quotes.
If the argument is numeric (eg 1), use
.OnAction = "'SubName 1'"
If the argument is a string then use
.OnAction = "'SubName ""SomeText""'"
Sub Demo()
Dim i As Long
Dim Arg As Variant
Dim t2 As Range
Dim btn2 As Button
For i = 3 To 4 Step 1
Set t2 = ActiveSheet.Range(Cells(i, LastCol + 3), Cells(i, LastCol + 3))
Set btn2 = ActiveSheet.Buttons.Add(t2.Left, t2.Top, t2.Width, t2.Height)
Arg = i '<~~ adjust to suit your needs
With btn2
.Caption = "View " & i
.Name = CStr(i)
If IsNumeric(Arg) Then
.OnAction = "'Sheet1.btnT " & Arg & "'"
Else
.OnAction = "'Sheet1.btnT """ & Arg & """'"
End If
End With
Next i
End Sub
Sub btnT(Arg As Variant)
MsgBox Arg
End Sub
I am trying to update my sourcedata in a chart. I Don't want a dynamic range because the chart will pull each time from the new range with each button click. If I use a dynamic or named range, I am locked into that range.
I have tried:
ActiveSheet.ChartObjects("Chart 2").Activate
ActiveChart.PlotArea.Select
ActiveChart.SetSourceData Source:=Range("A1:C3").Offset(0,3)
This only works once, though. To be clear, I have a button to update a chart on a spreadsheet. When the button is clicked, the macro will look at the current data in the active chart and shift the source over 3 columns. This will happen each time the button is clicked and the data must stay on the sheet. I've exhausted everything I know and can find online the Goracle search.
Any help?
Thanks in advance,
Lilith
The SeriesCollection(j) of the ActiveChart has always a Formula property that looks like this:
=SERIES(,,Sheet1!$A$1:$C$3,1)
So, you can add a custom function to your project that parses the string Split by $ and returns the corresponding range shift of 3 columns:
Function ShiftBy3(ByVal formulaString As String) As String
cRange = Split(formulaString, "$")(1) + Split(formulaString, "$")(2) + Split(formulaString, "$")(3) + Split(Split(formulaString, "$")(4), ",")(0)
newAddress = Range(cRange).Offset(0,3).Address
ShiftBy3 = Split(formulaString, "$")(0) + newAddress + "," + Split(Split(formulaString, "$")(4), ",")(1)
End Function
and then shifting by just resetting the formula each time:
ActiveChart.SeriesCollection(1).Formula = ShiftBy3(ActiveChart.SeriesCollection(1).Formula)
One approach is to update the Formula property for each series on the chart:
Sub Tester()
Const SER As String = "=SERIES("
Dim s As Series, f As String, arr, rng1, rng2, sn
Dim cht As Chart
Set cht = ActiveSheet.ChartObjects("Chart 2").Chart
sn = ActiveSheet.Name
For Each s In cht.SeriesCollection
f = s.Formula
Debug.Print f '<<<added
f = Replace(f, SER, "")
f = Left(f, Len(f) - 1)
arr = Split(f, ",")
Set rng1 = Range(arr(1))
Set rng2 = Range(arr(2))
s.Formula = SER & Join(Array(arr(0), _
rng1.Parent.Name & "!" & rng1.Offset(0, 3).Address(), _
rng2.Parent.Name & "!" & rng2.Offset(0, 3).Address(), _
arr(3)), ",") & ")"
Next s
End Sub
Here is the working code my boss came up with.
Dim var
var = Cells(4, 4)
ActiveSheet.ChartObjects("Chart 2").Activate
ActiveChart.PlotArea.Select
ActiveChart.SetSourceData Source:=Range(Cells(1, 1 + var), Cells(3, 3 + var))
Cells(4, 4).Value = Cells(4, 4).Value + 3
Thank Tim and Matteo for all of you time and help. I really do appreciate it!
I defining different ranges so that I can use them for graphs:
Sub rangesGRAPHS()
Dim count, counter, Erow, Prow1, Prow2, Urow1 As Long
Dim Dsrc1, Dsrc2, Dsrc3, Xsrc1, Xsrc2, Xsrc3 As Range
counter = 5
count = Application.CountA(Range("A:A"))
count = count + 3
While counter < count
If Range("Q" & CStr(counter)) = "ECO_BS" Then Erow = counter
If Range("Q" & CStr(counter)) = "PHO_BS" Then Prow2 = counter
counter = counter + 1
Wend
Prow1 = Erow + 1
Urow1 = Prow2 + 1
Dsrc1 = ("P5:P" & CStr(Erow))
Dsrc2 = ("P" & CStr(Prow1) & ":P" & CStr(Prow2))
Dsrc3 = ("P" & CStr(Urow1) & ":P" & CStr(count))
Xsrc1 = ("$C$5:$C$" & CStr(Erow))
Xsrc2 = ("$C$" & CStr(Prow1) & ":$C$" & CStr(Prow2))
Xsrc3 = ("$C$" & CStr(Urow1) & ":$C$" & CStr(count))
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range(Dsrc1)
ActiveChart.SeriesCollection(1).XValues = ("=SICALIS_Detail!" & Xsrc1)
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range(Dsrc2)
ActiveChart.SeriesCollection(1).XValues = ("=SICALIS_Detail!" & Xsrc2)
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlColumnClustered
ActiveChart.SetSourceData Source:=Range(Dsrc3)
ActiveChart.SeriesCollection(1).XValues = ("=SICALIS_Detail!" & Xsrc3)
Everything works except the line Xsrc3 = ("$C$" & CStr(Urow1) & ":$C$" & CStr(count)), which gives a error 91: object variable not set.
Upon debugging, I notice that Xsrc3 is set to nothing. However, all the other stuff works and it's written THE SAME WAY. If I comment it out the other stuff still works. I don't understand what is going on - let me know what's up!
It's not actually written the same way. In this line:
Dim Dsrc1, Dsrc2, Dsrc3, Xsrc1, Xsrc2, Xsrc3 As Range
the first 5 variables are actually declared as Variant and only the last is declared as a Range. You actually want them all to be String anyway, so use:
Dim Dsrc1 As String, Dsrc2 As String, Dsrc3 As String, Xsrc1 As String, Xsrc2 As String, Xsrc3 As String
I am new to VBA and to this forum. I have a table with dates as the first column (x column) and 12 columns of data pertaining to the data (y values). I am trying to plot the data in a simple xlLine chart. Only few selected columns are to be plotted for y values. The columns are selected using a combo box at the top of the column. The number of rows are variable.
I am using this code but this is not working. Can someone kindly let me know what is wrong and fix it? Appreciate any help. Thanks in advance.
Sub drawchart1()
'
' drawchart1 Macro
'
'
Dim i As Integer
Dim j As Integer
Dim n As Integer
' finding the number of rows
j = Range("Charts!A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Row
' selecting some range and adding a chart which is then modified.(not sure this is the correct method.)
Range("A10:C15").Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLine
i = 2
n = 2
' Cells (9,1) contains the value "Date". Defining the X Axis values
ActiveChart.SeriesCollection(1).Name = Sheets("Charts").Cells(9, 1).Value
ActiveChart.SeriesCollection(1).XValues = "=Charts!R10C1:R" & j & "C1"
Do While i < 14
' Cells(8,i) contain the results of combo box - true or false.
' Cells(9,i) contain the names of the series
If Cells(8, i).Value = True Then
ActiveChart.SeriesCollection(n).Name = Sheets("Charts").Cells(9, i).Value
ActiveChart.SeriesCollection(n).Values = "=Charts!R10C" & i & ":R" & j & "C" & i
n = n + 1
i = i + 1
Else
i = i + 1
End If
Loop
End Sub
Hi Again,
Since my columns would not exceed 14 (i.e. not large), I used the following "brute force" technique and it worked fine. I would still love to learn how to do it without using the "brute force" technique. Thanks in advance.
Sub drawchart()
Dim j As Integer
Dim Chartstring As String
j = Range("Charts!A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Row
Chartstring = "A9:A" & j
If Cells(8, 2).Value = True Then
Chartstring = Chartstring & ", B9:B" & j
Else
Chartstring = Chartstring
End If
If Cells(8, 3).Value = True Then
Chartstring = Chartstring & ", C9:C" & j
Else
Chartstring = Chartstring
End If
' And similarly added code for each of the 14 columns
' And finally fed the chartstring into the "Source"
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLine
ActiveChart.SetSourceData Source:=Range(Chartstring)
End Sub
Probably you're not watching any more. Here's an alternative approach.
Sub DrawChart1()
Dim i As Long
Dim j As Long
Dim ws As Worksheet
Dim rCht As Range, rYVals As Range
Dim cht As Chart
' finding the number of rows
Set ws = Worksheets("Charts")
j = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' start with X values (row 10 to j), include header row (row 9)
Set rCht = ws.Range(ws.Cells(9, 1), ws.Cells(j, 1))
' add column of Y values if row 8 of column is TRUE
For i = 2 To 14
If ws.Cells(8, i).Value Then
Set rYVals = ws.Range(ws.Cells(9, i), ws.Cells(j, i))
Set rCht = Union(rCht, rYVals)
End If
Next
' if we've had any Y values, insert chart, using range we've built up
If Not rYVals Is Nothing Then
Set cht = ws.Shapes.AddChart(xlLine).Chart
cht.SetSourceData Source:=rCht, PlotBy:=xlColumns
End If
End Sub
Hello I have written a code for generating the graph and it is working correctly.
The problem is it is taking lot of time to generate. and i am not getting why it is taking time.
the code is
Dim cc As Chart
Set cc = ActiveWorkbook.Charts.Add
Set cc = cc.Location(Where:=xlLocationAsObject, name:=assume)
With cc
.ChartType = xlXYScatterLines
With .Parent
.Top = Columns(b).Offset(0, 4).Top
.Left = Columns(b).Offset(0, 4).Left
.name = "cc"
End With
End With
Dim sc As Series
Set sc = cc.SeriesCollection(1)
With sc
.Values = Columns(b).Offset(0, -3)
.XValues = Columns(b).Offset(0, -5)
End With
Please somebody help me
Try this, to just chart the rows of the column with actual data.
Sub makeChart(b As String, assume As String) 'i presupposed these arguments based on your code
Application.ScreenUpdating = False
Dim cc As Chart
Set cc = ActiveWorkbook.Charts.Add
Set cc = cc.Location(Where:=xlLocationAsObject, Name:=assume)
With cc
.ChartType = xlXYScatterLines
With .Parent
.Top = Columns(b).Offset(0, 4).Top
.Left = Columns(b).Offset(0, 4).Left
.Name = "cc"
End With
End With
Dim strValue As String, strXValue As String
'here you are using the passed column letter to find the specific column you want to chart
strValue = Split(Range(b & "1").Offset(, -3).Address, "$")(1) 'will return "C" if given column F
strXValue = Split(Range(b & "1").Offset(, -5).Address, "$")(1) 'will return "A" if given column F
Dim sc As Series
Set sc = cc.SeriesCollection(1)
With sc
'will select from row 1 to the last true used row in the given column
.Values = Range(strValue & "1:" & strValue & Range(strValue & Rows.Count).End(xlUp).Row)
.XValues = Range(strXValue & "1:" & strXValue & Range(strXValue & Rows.Count).End(xlUp).Row)
End With
Application.ScreenUpdating = True
End Sub
Have you turned off screen updating? Add this to the beginning of your code:
Application.ScreenUpdating = False
Then add this at the very end of your code:
Application.ScreenUpdating = True