Invalid Parameter - VBA Chart Color - excel

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

Related

"Run-time error '1004' " when using FormulaR1C1?

I am creating a template for a process route card for our factory, which configures itself based on a few inputs. One section of this is a build log for serialised parts.
I want to insert this formula:
=IFERROR(IF(RIGHT(K122,4)+1< $E$17+1, IF(AND(MID(K122,23,1)="0",NOT(RIGHT(K122,1)="9")),CONCAT(LEFT(K122,(LEN(K122)-4)),IF(LEN(RIGHT(K122,4)+1)=1,CONCAT("000",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=2,CONCAT("00",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=3,CONCAT("0",RIGHT(K122,4)+1),RIGHT(K122,4)+1)))),IF(AND(MID(K122,22,1)="0",NOT(MID(K122,23,2)="99")),CONCAT(LEFT(K122,(LEN(K122)-4)),IF(LEN(RIGHT(K122,4)+1)=1,CONCAT("000",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=2,CONCAT("00",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=3,CONCAT("0",RIGHT(K122,4)+1),RIGHT(K122,4)+1)))),IF(AND(MID(K122,21,1)="0",NOT(MID(K122,22,3)="999")),CONCAT(LEFT(K122,(LEN(K122)-4)),IF(LEN(RIGHT(K122,4)+1)=1,CONCAT("000",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=2,CONCAT("00",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=3,CONCAT("0",RIGHT(K122,4)+1),RIGHT(K122,4)+1)))),CONCAT(LEFT(K122,(LEN(K122)-4)),IF(LEN(RIGHT(K122,4)+1)=1,CONCAT("000",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=2,CONCAT("00",RIGHT(K122,4)+1),IF(LEN(RIGHT(K122,4)+1)=3,CONCAT("0",RIGHT(K122,4)+1),RIGHT(K122,4)+1))))))),""),"")
in many cells, using R1C1 notation, due to the varying absolute position in the spreadsheet of the structure this formula is a part of. This formula works.
Converting this formula to R1C1 notation I get:
=IFERROR(IF(RIGHT(R[-2]C[0],4)+1< $E$17+1, IF(AND(MID(R[-2]C[0],23,1)=""0"",NOT(RIGHT(R[-2]C[0],1)=""9"")),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1)))),IF(AND(MID(R[-2]C[0],22,1)=""0"",NOT(MID(R[-2]C[0],23,2)=""99"")),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1)))),IF(AND(MID(R[-2]C[0],21,1)=""0"",NOT(MID(R[-2]C[0],22,3)=""999"")),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1)))),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1))))))),""""),"""")
Inserting into my VBA gave me an error, as my line of code was too long, so I split the text string in two, declared them as constants, and implemented it as so:
Private Const Formula1 As String = "=IFERROR(IF(RIGHT(R[-2]C[0],4)+1< $E$17+1, IF(AND(MID(R[-2]C[0],23,1)=""0"",NOT(RIGHT(R[-2]C[0],1)=""9"")),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1)))),IF(AND(MID(R[-2]C[0],22,1)=""0"",NOT(MID(R[-2]C[0],23,2)=""99"")),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1)))),IF(AND(MID(R[-2]C[0],21,1)=""0"",NOT(MID(R[-2]C[0],22,3)=""999"")),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),"
Private Const Formula2 As String = "IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1)))),CONCAT(LEFT(R[-2]C[0],(LEN(R[-2]C[0])-4)),IF(LEN(RIGHT(R[-2]C[0],4)+1)=1,CONCAT(""000"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=2,CONCAT(""00"",RIGHT(R[-2]C[0],4)+1),IF(LEN(RIGHT(R[-2]C[0],4)+1)=3,CONCAT(""0"",RIGHT(R[-2]C[0],4)+1),RIGHT(R[-2]C[0],4)+1))))))),""""),"""")"
Sub BuildBuildLog()
RemoveBuildLog
With Sheets(WSPRC)
count = 1
For i = 1 To PRCLength ' incrementing rows in the documents
If InStr(1, LCase(.Cells(i, 1).Value), "blhead01", vbBinaryCompare) Then
.Cells(i, 1).EntireRow.Hidden = False
ElseIf InStr(1, LCase(.Cells(i, 1).Value), "blhead02", vbBinaryCompare) Then
.Cells(i, 1).EntireRow.Hidden = False
ElseIf InStr(1, LCase(.Cells(i, 1).Value), "blhead03", vbBinaryCompare) Then
.Cells(i, 1).EntireRow.Hidden = False
For j = 1 To noHeaders + 1 'counting through the pages of the build log - (+1 to allow for a page for rework log)
If j > noHeaders Then 'last page of build log is blank - to allow records of reworked assemblies.
.Cells(((noHeaders - 1) * 12) + 15, 1).Value = "Rework Log"
For k = 1 To 20 'Counting the rows in the build log - 20 per page
.Cells(i + k, 1).EntireRow.Hidden = False
Call formatBLRow((2 * k) + (i - 1), j)
Next k
Else
For k = 1 To 20 'Counting the rows in the build log - 20 per page
If count < batchqty + 1 Then
'add a line to the build log
If count = 1 Then
.Cells((2 * k) + (i - 1), 12 * j).Formula = "=CONCAT($I$8,"": "",RIGHT($C$7,4),""-"",B31,""-"",E31)"
ElseIf k = 1 Then
.Cells((2 * k) + (i - 1), 12 * j).FormulaR1C1 = Formula3 & Formula4
Else
.Cells((2 * k) + (i - 1), 12 * j).FormulaR1C1 = Formula1 & Formula2
End If
Call formatBLRow((2 * k) + (i - 1), j)
Else
Exit For 'Exit for loop if count of rows in build log is greater or equal to batch quantity
End If
count = count + 1
Next k
End If
Next j
End If
Next i
End With
End Sub
The error:
Run-time error '1004' Application-defined or object-defined error`
occurs the first time formulaR1C1 is called, during the
For k = 1 To 20 'Counting the rows in the build log - 20 per page count`
for loop, for count = 2, k=2.
Although the formula is long, it is shorter than the limit of the length of the property I am trying to insert it into.
I just realised my error.. I didn't fully convert the formula into R1C1 notation, I had left the lone explicit Cell reference in A1 notation
$E$17
..Converting that to R17C5 fixed it.
Sorry for the long read for the elementary issue.
Regards,

Run-time error '1004' is occurring but the code still runs as it should

I have been working on an excel sheet that utilizes VBA to mark squares on a grid as occupied or vacant. I have two sets of code, one that is triggered by a cell change to mark the grid as occupied and the other that is triggered by a button to mark the grid as vacant and clear that row. The former of these works fine but the latter keeps throwing "Run-time error '1004': Application-defined or object-defined error". Both of these use the same sub to handle the grid changing but one does not get the error.
Code to Mark Vacant
Sub clearPlot()
Dim rClear As Integer
Dim clearedPlot As Integer
rClear = ActiveCell.Row 'Find currently selected row
If rClear > 1 Then 'Ignore header
clearedPlot = Cells(rClear, 5).Value 'Get plot value
If clearedPlot > 0 Then 'Ignore blanks
garden clearedPlot, 0, 255, 0
With Worksheets("Plot Log")
.Range(.Cells(rClear, 1), .Cells(rClear, 7)).ClearContents
End With
End If
End If
End Sub
Sub to find plot location and change color
If plot < 8 Then 'Find location of plot on grid
r = 1
c = plot
ElseIf plot < 15 And plot > 7 Then
If plot Mod 7 = 0 Then
r = Int(plot / 7)
c = 7
Else
r = Int(plot / 7) + 1
c = plot Mod 7
End If
ElseIf plot < 21 And plot > 14 Then
r = Int(plot / 7) + 1
c = (plot Mod 7) + 1
ElseIf plot < 26 And plot > 20 Then
If plot Mod 7 = 0 Then
r = Int(plot / 7) + 1
c = 3
Else
r = Int(plot / 7) + 1
c = (plot Mod 7) + 3
End If
ElseIf plot < 29 And plot > 25 Then
If plot Mod 7 = 0 Then
r = Int(plot / 7) + 1
c = 5
Else
r = Int(plot / 7) + 2
c = (plot Mod 7) - 2
End If
ElseIf plot < 31 And plot > 28 Then
r = Int(plot / 7) + 1
c = (plot Mod 7) + 5
End If
Worksheets("Plots").Cells(r, c).Interior.Color = RGB(red, green, blue) 'Source of error when run from clearPlot
End Sub
Code for marking plot as occupied
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rPlot As Integer
Dim cPlot As Integer
Dim occupiedPlot As Integer
Set plots = Sheets("Plot Log").Range("E:E") 'Column to check for changes, plot numbers entered here
If Not Application.Intersect(plots, Worksheets("Plot Log").Range(Target.Address)) Is Nothing And Worksheets("Plot Log").Range(Target.Address).Row <> 1 And Not IsEmpty(Worksheets("Plot Log").Range(Target.Address).Value) Then 'Excludes header row and deletion
rPlot = Sheets("Plot Log").Range(Target.Address).Row
cPlot = Sheets("Plot Log").Range(Target.Address).Column
occupiedPlot = Sheets("Plot Log").Cells(rPlot, cPlot).Value 'Get number for the plot rented
garden occupiedPlot, 255, 0, 0
End If
End Sub
I have tried to specify the workbook and call the cells by using Range(Cells, Cells) but nothing stops the error from coming. Furthermore, when the error pops up, the code still executes and it marks the grid as it should and deletes the row.
Any help would be appreciated, thanks in advance!

Run-time error '13': Type mismatch when using "CountA" to loop

EDIT: Problems was that some of the inputs were strings instead of numbers, this cause this line of code to display the error:
CompaniesListBox.List(i - 1, j - 1) = Start.Offset(i - 1, j - 1).Value * 100 & " %"
EDIT END.
I'm getting a "Run-time error '13': Type mismatch" when i'm trying to run my code.
Basically what i'm trying to do is populate a listbox wihtin a userform with a matrix. I also want to calculate how many rows it should use, (using the wooksheetfunction.CountA) but i get an error which I seem not able to solve.
Any ideas?
after some debugging it seems to be the function that is causing the problem, Maybe "Rows" in not a valid variable for the loop?
Private Sub UpdateCompaniesListBox()
Dim Rows As Integer
Dim Columns As Integer
Dim Start As Range
Dim CountWindowA As Range
Set CountWindowA = Sheets("Basic Data").Range("AM4:AM33") 'Window where from top to bottom wheras value can be
Set Start = Sheets("Basic Data").Range("AM4") ' This should be the first cell that has a value.
Rows = WorksheetFunction.CountA(CountWindowA)
'MsgBox Rows
Columns = 8
For i = 1 To Rows
CompaniesListBox.AddItem
For j = 1 To Columns
If (j = 6) Or (j = 7) Then
CompaniesListBox.List(i - 1, j - 1) = Start.Offset(i - 1, j - 1).Value * 100 & " %"
Else
CompaniesListBox.List(i - 1, j - 1) = Start.Offset(i - 1, j - 1).Value
End If
Next j
Next i
CompaniesListBox.ColumnWidths = "118, 72, 49, 60, 71, 99, 38, 73"
End Sub

VBA: How to remember the value from the previous iteration and set it as the initial value

I have a little problem with my code in VBA. Please see on the code below.
Sub MonteCarlo()
M = Cells(13, 2) 'number of iterations (step)
SumaMC = 0
non_zero = 0
For i = 1 To M
SumaMC = SumaMC + Cells(27, 12)
Cells(14, 2) = Cells(14, 2) + 1 'update number of iterations
non_zero = non_zero + Application.WorksheetFunction.CountIf(Range("L3:L26"), "<>0")
Next i
Cells(28, 14) = non_zero
Cells(27, 13) = SumaMC / Cells(14, 2)
Cells(27, 12) = Application.WorksheetFunction.Sum(Range("L2:L26"))
End Sub
I want to count the non-zero values in each iteration and sum them up. The code is working fine, but if I run the loop again, the sum of the nonzero values counts again for the iteration step. For example:
First run of the macro:
100 iterations and 326 non zero values
Second run of the macro:
200 iterations and 324 non zero values ( and here it should be 326+324).
How to correct it?

Excel VBA: How do I change font size and alignment inside text boxes

I have created a grid of text boxes, but I cannot figure out a method to change the font size and alignment (centralise vertically and horizonatally) of the text inside a named textbox.
Sub addtxtbx()
Dim shp As Shape
Dim i As Integer, j As Integer, k As Integer
Dim cindx as long, rindx as long
For i = 1 To 145
Set shp = ActiveSheet.Shapes.AddTextbox(msoTextOrientationHorizontal, _
100 + cindx, 100 + rindx, 50, 50)
cindx = (i - Int((i - 1) / 4) * 4 - 1) * 50 + Int((i - 1) / 48) * 200
rindx = (Int((i - 1) / 4) - Int((i - 1) / 48) * 12) * 50
With shp
.Name = "TxtBx" & (i - 1)
.Fill.ForeColor.RGB = RGB(204, 102, 255)
End With
Next i
With ActiveSheet.Shapes.Range(Array("TxtBx11")).TextFrame2.TextRange
.Characters.Text = "R"
End With
End Sub
Also, I have been scratching my head with the For Next loop's i counter. I used it to rename the text boxes and found that despite using i = 1 to 144, TxtBx144 is not the last box, but the second last, TxtBx2 is the first. So, I tried to get around it by using 1 to 145 and name the box using (i-1) serial which is a bit of a cop out. What did I do wrong that I am failing to see?
What you want to do is this:
shp.ShapeRange.TextFrame2.TextRange.Font.Size = 20
where 20 is whatever size you want.
I don't know why your text boxes were getting numbered incorrectly, but your code as written is actually giving me 0-143, not 1-144 so I suspect there is either some code changing i that you haven't put into the question or something else is going on.
Also, the easiest way to figure out how to code stuff like this, is to record a macro, do whatever it is you are trying to accomplish, stop the macro, and then look at the code.

Resources