In reference to the following file.xlsm:
where Sheet1 (1) is a Sheet, Plot1 (2) is a Graphic-Sheet and the button (3) refers to the following Macro:
Sub plot()
ReDim blue(1 To 5, 1 To 2)
ReDim red(1 To 5, 1 To 2)
For i = 1 To 5
blue(i, 1) = i
blue(i, 2) = i ^ 2
red(i, 1) = i + 4
red(i, 2) = (i + 4) ^ 2
Next i
Sheets("Plot1").Select
ActiveChart.ChartArea.ClearContents
ActiveChart.ChartArea.Select
ActiveChart.ChartType = xlXYScatterSmoothNoMarkers
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(1).XValues = Application.Index(blue, , 1)
ActiveChart.FullSeriesCollection(1).Values = Application.Index(blue, , 2)
ActiveChart.FullSeriesCollection(1).Select
Selection.Format.Line.ForeColor.RGB = RGB(0, 0, 255)
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(2).XValues = Application.Index(red, , 1)
ActiveChart.FullSeriesCollection(2).Values = Application.Index(red, , 2)
ActiveChart.FullSeriesCollection(2).Select
Selection.Format.Line.ForeColor.RGB = RGB(255, 0, 0)
Sheets("Plot1").Protect DrawingObjects:=True, Contents:=False
Sheets("Plot1").Unprotect
Sheets("Sheet1").Select
End Sub
after opening file.xlsm, clicking (3) and (2) I get:
after opening file.xlsm, clicking (2), (1), (3) and (2) I get:
How can I change the Macro so that I always get the third image regardless of the click sequence?
It used to be possible to deselect a chart, that is, an embedded chart, but I don't remember if it worked on a chart sheet.
For some reason, no matter what I try, the chart area becomes selected when this code is first run after opening the workbook. (I even tried activating the chart sheet, then the worksheet, with a Workbook_Open procedure: no luck.) But you can avoid having the second series selected if you don't select it in the first place. Not selecting things actually makes the code run faster, usually not enough that you would notice, but it also prevents the little flash of tabs being activated.
Sub plot()
ReDim blue(1 To 5, 1 To 2) As Double
ReDim red(1 To 5, 1 To 2) As Double
Dim i As Long
For i = 1 To 5
blue(i, 1) = i
blue(i, 2) = i ^ 2
red(i, 1) = i + 4
red(i, 2) = (i + 4) ^ 2
Next i
With Charts("Plot1")
.ChartArea.ClearContents
.ChartType = xlXYScatterSmoothNoMarkers
With .SeriesCollection.NewSeries
.XValues = Application.Index(blue, , 1)
.Values = Application.Index(blue, , 2)
.Format.Line.ForeColor.RGB = RGB(0, 0, 255)
End With
With .SeriesCollection.NewSeries
.XValues = Application.Index(red, , 1)
.Values = Application.Index(red, , 2)
.Format.Line.ForeColor.RGB = RGB(255, 0, 0)
End With
End With
End Sub
Related
I am creating a new sheet with the goal of reorganizing the information on another sheet. I have been able to move all other information to the other sheet in the format needed, but I can not move images/pictures of the parts.
I have tried using the code shown below, but referencing the cell the images are in, but it does not copy. I did a little research and looked at if there was a simple way to move images just by copy-pasting cells through VBA and it does not seem to work. I also look at trying to rename all the shapes, but to no success.
'find the last row of values
Worksheets("Eyelets").Activate
LastRow = Cells.Find("*", SearchOrder:=xlByRows,
SearchDirection:=xlPrevious).Row + 3
Worksheets("Plot").Activate
'1st column of values
For i = 2 To LastRow Step 4
Count = Count + 1
x = i + Count
'Store all variables in the row
RDPNHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 0)
FDPNHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 1)
WRHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 4)
MatHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 9)
DiamHold = Worksheets("Eyelets").Range("A1").Offset(i - 1, 5).Value
'Move All Part Numbers to next sheet.
Worksheets("Plot").Range("A1").Offset(x - 2, 0) = RDPNText & RDPNHold
Worksheets("Plot").Range("A1").Offset(x - 1, 0) = FDPNText & FDPNHold
Worksheets("Plot").Range("A1").Offset(x, 0) = WRText & WRHold
Worksheets("Plot").Range("A1").Offset(x + 1, 0) = MatText & MatHold & DiamText & DiamHold
'Bold Specific parts of the cells
Worksheets("Plot").Range("A1").Offset(x - 2, 0).Characters(Len(lngIDStart), 3).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x - 1, 0).Characters(Len(lngIDStart), 3).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x, 0).Characters(Len(lngIDStart), 3).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x + 1, 0).Characters(Len(lngIDStart), 4).Font.Bold = True
Worksheets("Plot").Range("A1").Offset(x + 1, 0).Characters(Len(lngIDStart) + 13, 5).Font.Bold = True
Next i
Information not formateed This image shows how the information is already organized (I changed values due to work-related information)
Formatted Information This image shows how I am trying to format the information, and as shown the blank space for the images.
Any ideas or suggestions are greatly appreciated!
Here's a starting point:
Sub Tester()
Dim shtSource As Worksheet, shtDest As Worksheet
'....
Set shtSource = Worksheets("Eyelets")
Set shtDest = Worksheets("Plots")
'....
If CopyPicFromCell(shtSource.Range("A1").Offset(i - 1, 2)) Then
'copied the picture, so paste to shtDest
shtDest.Paste
With shtDest.Shapes(shtDest.Shapes.Count)
.Top = shtDest.Range("A1").Offset(0, 1).Top
.Left = shtDest.Range("A1").Offset(0, 1).Left
End With
End If
End Sub
'see if there's a shape to be copied from a given cell
' return True if one was found
Function CopyPicFromCell(c As Range)
Const MARGIN As Long = 10 '<< how far the picture can be out of place
Dim shp As Shape
For Each shp In c.Parent.Shapes
'check the TopLeftCell and the shape's position
If shp.TopLeftCell.Address = c.Address Or _
(Abs(shp.Left - c.Left) < MARGIN And Abs(shp.Top - c.Top) < MARGIN) Then
shp.Copy
CopyPicFromCell = True
Exit For '<< done checking
End If
Next shp
End Function
Recently I have automated the coloring of a series of charts based off 3 key conditions. If they are "Planned", "Forced", or "Other" - the chart color will be automated rather than being a manual process. However, recently it has stopped working even though there has been no change in my code.
I reviewed my code and it has highlighted one of my modules, with the below line being the culprit supposedly.
ElseIf InStr(outRng.Offset(tabRowloop, 5 + ((tabcolloop - 1) * 5)), "Planned") > 0 Then
serobj.Points(tabRowloop + 1).Format.Fill.ForeColor.RGB = RGB(30, 65, 100)
If I comment out this line, the code runs but the coloring does not work. The loop functions are fine, but I cannot understand how the coloring of my points causes an "Invalid Parameter" error.
Is anyone able to provide any guidance on what the cause could be?
'Code for Recolor Chart Module
Dim tabRowloop As Integer
Dim tabcolloop As Integer
Dim seriesnum As Integer
Dim serobj As Series
For tabcolloop = 1 To maxGanttBarsPerSite Step 1
seriesnum = stupidRangeIndexThingy(tabcolloop)
Set serobj = chobj.Chart.FullSeriesCollection(seriesnum)
serobj.Format.Fill.ForeColor.RGB = RGB(50, 50, 50)
tabRowloop = 0
Do While Len(outRng.Offset(tabRowloop, 1))
If (Len(outRng.Offset(tabRowloop, 1 + ((tabcolloop - 1) * 5))) > 0) Then
Debug.Print tabRowloop & "," & tabcolloop
If InStr(outRng.Offset(tabRowloop, 5 + ((tabcolloop - 1) * 5)), "Forced") > 0 Then
serobj.Points(tabRowloop + 1).Format.Fill.ForeColor.RGB = RGB(192, 0, 0)
ElseIf InStr(outRng.Offset(tabRowloop, 5 + ((tabcolloop - 1) * 5)), "Planned") > 0 Then
serobj.Points(tabRowloop + 1).Format.Fill.ForeColor.RGB = RGB(30, 65, 100)
'problem is with the above line
Else
serobj.Points(tabRowloop + 1).Format.Fill.ForeColor.RGB = RGB(247, 150, 70)
End If
End If
tabRowloop = tabRowloop + 1
Loop
Next
'Sort table - Synergy first then by name
Call SortFinalTable(numUnitsFound)
'Turn on calc and redraw
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
You'll get an Invalid Parameter error if your index for the Points object is out of range. If it fails on the first loop when tabRowLoop still equals 0, it suggests that serobj doesn't have any point. If it fails on later loops, it's because you're exceeding the number of points in the series. When stepping through the code, after the serobj variable has been set, try confirming which series has been picked up by running some debug/immediate commands.
print serobj.Points.Count
I am using VBA code to place conditional formatting to cover values in a large table, I use 2 formulae per cell to determine which of the 3 symbols to use. I need to check the value of each cell with a different cell depending on the column and therefore as far as I understamd, I have to place my conditional formatting rule on each cell individually to ensure the formula is correct in each. This is because conditional formatting cannot take relative addresses, you have to give it the exact address of each cell ... correct?
The large number of conditional formatting instances is slowing my computer to a huge extent.
Is it possible to place symbols used by conditional formatting, into a cell, without using conditional formatting?
Perhaps somewhat like an image, but whilst retaining the cell value underneath, as can be done using conditional formatting.
Below I have given the code I use to put the conditional formatting in place. Any help is very much appreciated!!
Dim AIs As Range
Dim rng As Range
Dim cl As Range
Set AIs = ActiveSheet.Range("Table")
For Each cl In AIs.Columns
For Each rng In cl.Cells
rng.FormatConditions.AddIconSetCondition
rng.FormatConditions(rng.FormatConditions.Count).SetFirstPriority
With rng.FormatConditions(1)
.ReverseOrder = False
.ShowIconOnly = True
.IconSet = ActiveWorkbook.IconSets(xl3Symbols2)
End With
With rng.FormatConditions(1).IconCriteria(1)
.Icon = xlIconYellowExclamationSymbol
End With
With rng.FormatConditions(1).IconCriteria(2)
.Icon = xlIconRedCross
.Type = xlConditionValueFormula
.Value = "=IF(VALUE(LEFT(" & rng.Parent.Cells(5, rng.Column).Address & _
";1)=0;1;6)"
.Operator = 7
End With
With rng.FormatConditions(1).IconCriteria(3)
.Icon = xlIconGreenCheck
.Type = xlConditionValueFormula
.Value = "=IF(VALUE(LEFT(" & rng.Address & ";1))<=VALUE(LEFT(" & _
rng.Parent.Cells(5, rng.Column).Address & ";1));1;6)"
.Operator = 7
End With
Next rng
Next cl
Adding a shape directly to a cell:
Dim cLeft As Single
Dim cTop As Single
cLeft = rng.Left
cTop = rng.Top
with AIs.Shapes.AddShape(msoShapeOval, cLeft, cTop, 12, 12)
.ForeColor.RGB = RGB(255, 0, 0)
'Other properties can be found at
'http://msdn.microsoft.com/en-us/library/office/bb251480%28v=office.12%29.aspx
end with
you may want to adjust cTop and cLeft, and the width/height to position the circle as you wish
Final code:
Set AIs = ActiveSheet.Range("Table")
For Each cl In AIs.Columns
For Each rng In cl.Cells
'Shapes - GRADE MASK
cLeft = rng.Left + 5 - (rng.ColumnWidth / 2)
cTop = rng.Top + (rng.RowHeight / 2 - 5)
If Not rng = "" And rng.ColumnWidth = 3 And rng.RowHeight > 12 Then
If rng.Parent.Cells(5, rng.Column) = 0 Then
With wks.Shapes.AddShape(msoShapeOval, cLeft, cTop, 10, 10)
.Fill.ForeColor.RGB = RGB(255, 0, 0)
End With
End If
If CInt(Left(rng, 1)) >= CInt(Left(rng.Parent.Cells(5, rng.Column), 1)) And _
Not rng.Parent.Cells(5, rng.Column) = 0 Then
With wks.Shapes.AddShape(msoShapeOval, cLeft, cTop, 10, 10)
.Fill.ForeColor.RGB = RGB(0, 255, 0)
End With
End If
If CInt(Left(rng, 1)) < CInt(Left(rng.Parent.Cells(5, rng.Column), 1)) Then
With wks.Shapes.AddShape(msoShapeOval, cLeft, cTop, 10, 10)
.Fill.ForeColor.RGB = RGB(255, 204, 0)
End With
End If
End If
Next rng
Next cl
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True, _
userinterfaceonly:=True
Then every time I call a macro, I remove all the shapes on the worksheet, perform my macro and then call this again, in the if statements above there are checks to see how big the column width and row height are and a shape is only inserted if the cell is "visible"
In my program, for other reasons outside this subroutine I cannot hide my rows or columns but instead reduce their height or width to be just big enough to display the cell borders.
I need to write a spreadsheet which when you press a button adds a row of data and asks for the parameters needed for the calculations, but I cant seem to get it right, its really frustrating me, any help would be appreciated. I am a complete begginner to macros in excel and have only done very basic programming for matlab on my uni course. My script so far is as follows:
Sub AddPosTol()
'
' AddPosTol Macro
'
Dim rngSeek As Range
Set rngSeek = Range("A1").End(xlDown).Offset(1, 0)
With rngSeek.Offset(0, 1)
With .Font
.Name = "Solid Edge ANSI1 Symbols"
.Size = 11
End With
End With
Range(rngSeek).Offset(0, 1) = "l"
Range(rngSeek).Offset(0, 3) = "=RC[-1]"
Range(rngSeek).Offset(0, 4) = "0"
With rngSeek.Offset(1, 1)
With .Font
.Bold = True
End With
End With
Range(rngSeek).Offset(1, 1) = "X value"
Range(rngSeek).Offset(2, 1) = "Y Value"
Range(rngSeek).Offset(0, 4) = "=2*SQRT((R[1]C[-3]-R[1]C)^2+(R[2]C[-3]-R[2]C)^2)"
Range(rngSeek).Offset(0, 5) = "=2*SQRT((R4C3-R[1]C)^2+(R5C3-R[2]C)^2)"
Range(rngSeek).Offset(0, 6) = "=2*SQRT((R[1]C[-3]-R[1]C)^2+(R[2]C[-3]-R[2]C)^2)"
Range(rngSeek).Offset(0, 7) = "=2*SQRT((R[1]C[-3]-R[1]C)^2+(R[2]C[-3]-R[2]C)^2)"
Range(rngSee).Offset(0, 8) = "=2*SQRT((R4C3-R[1]C)^2+(R5C3-R[2]C)^2)"
Range(rngSeek).Offset(0, 2) = (InputBox("Insert Positional Tolerance Diametre"))
Range(rngSeek).Offset(1, 2) = (InputBox("Insert X value on drawing"))
Range(rngSeek).Offset(2, 2) = (InputBox("Insert Y value on drawing"))
End Sub
You've defined rngSeek as a range and then are trying to use that range definition with the Range() method of the worksheet.
All the lines where you have Range(rngSeek).Offset(... you can replace with rngSeek.Offset(...
(One of your formula also references the wrong cells ;-)
I have a little problem with my owc chartspace, I would like to draw a chart like in the picture but my problem is that it draws only for one series I would like to draw it for the 1 the 2 and the 3 I don't know how to do this.
I have a listbox and a combobox, I select from the list box the 1,2,3 and I select from the combobx y or z such that x is fixed.
Then I put the data in plage(1) for x and plage(2) for y but the problem is that it works only for the first item I select from the listbox ( in this picture the "1" )
Could you tell what is wrong in my code?
the vba code for drawing the chart into the userform is:
Private Sub drow()
Dim i, k As Integer, x As Integer
Dim j As Integer
Dim Table(), Plage(2)
Dim id As Integer
id = 1
Do While ComboBox.Value <> idi(id, 1)
id = id + 1
Loop
For i = Cht.SeriesCollection.Count To 1 Step -1
Cht.SeriesCollection.Delete i - 1
Next i
k = 1
ReDim Table(ListBox.ListCount)
For i = 0 To ListBox.ListCount - 1
If ListBox.Selected(i) = True Then
Table(k) = ListBox.List(i)
k = k + 1
End If
Next i
With Cht
.HasLegend = True
.Legend.Position = chLegendPositionBottom
.HasTitle = True
.Title.Caption = ComboBox.Text
End With
Cht.Type = C.chChartTypeColumnClustered3D
With Cht
'first serie
.SeriesCollection.Add
.SeriesCollection(0).Caption = sheet.Cells(2, 15 + id)
.SeriesCollection(0).DataLabelsCollection.Add
.SeriesCollection(0).DataLabelsCollection(0).Position = chLabelPositionCenter
.SeriesCollection(0).DataLabelsCollection(0).Font.Color = RGB(255, 255, 255)
.SeriesCollection.Add
.SeriesCollection(1).Caption = sheet.Cells(2, 20) .SeriesCollection(1).DataLabelsCollection.Add
.SeriesCollection(1).DataLabelsCollection(0).Position = chLabelPositionCenter
.SeriesCollection(1).DataLabelsCollection(0).Font.Color = RGB(255, 255, 255)
.SetData C1.chDimCategories, C1.chDataLiteral, Table
End With
For j = 0 To ListBox.ListCount - 1
If ListBox.Selected(j) = True Then
Plage(1) = sheet.Cells(j + 3, 15 + id) 'the Xs
Plage(2) = sheet.Cells(j + 3, 20) 'Les 'the Ys
With Cht
.SeriesCollection(0).SetData C1.chDimValues, C1.chDataLiteral, Plage(1)
.SeriesCollection(1).SetData C1.chDimValues, C1.chDataLiteral, Plage(2)
End With
Erase Plage
End If
Next j
End Sub
I am very new to the whole owc and VB thing and I am having some troubles myself, but have you tried using C1.chDimXValues and C1.chDimYValues instead of the chDimValues in the below statement:
.SeriesCollection(0).SetData
C1.chDimValues, C1.chDataLiteral,
Plage(1) .SeriesCollection(1).SetData
C1.chDimValues, C1.chDataLiteral,
Plage(2)
Sorry if this might sound trivial, I can see your coding skills are much more advanced than mine. Good luck!