Adding Data to an existing SeriesCollection in excel - vba

I am creating a chart from data inside an Excel sheet. Everything works. But now I want to remove values that are below a limit and display them as "Others". Removing them works but I don't know how to add an additonal "others" value.
This is part of the code:
Co.chart.SetSourceData Source:=DataSource
Co.chart.ChartTitle.Text = "Best selling games"
Co.chart.SeriesCollection(1).ApplyDataLabels ShowPercentage:=True, ShowValue:=False
For Each d In Co.chart.SeriesCollection(1).DataLabels
v = CLng(Split(d.Caption, "%")(0))
If v < 10 Then
Rest = Rest + v
d.Delete
End If
Next
If Rest > 0 Then
Co.chart.SeriesCollection(1).DataLabels.AddData("Others",Rest); ' HERE
End If
In the second last line is some pseudocode about what I want to achieve.

I found a "dirty" solution for this. Instead of deleting the first item I RENAME it to "Others" instead of deleting it and adding the "Others" afterwards:
For Each d In Co.chart.SeriesCollection(1).DataLabels
Counter = Counter + 1
v = CLng(Split(d.Caption, "%")(0))
If v <= 10 Then
If RestPos < 0 Then
RestPos = Counter
Else
d.Delete
End If
Rest = Rest + v
End If
Next
If Rest > 0 Then
Co.chart.SeriesCollection(1).DataLabels(RestPos).Caption = Rest & " %"
End If

Related

VLookup analogue in VBA, printing two columns based on StrComp with common first column

I'm updating a VBA script and trying to match a 4-digit code with a table and printing the two corresponding columns into my original sheet, plus handling codes missing from the reference table.
jobcodes = sample codes to match.
codematch = reference table, 1st column is reference codes, I want the corresponding values in columns 2 and 3 in K and L of "jobcodes".
At the minute I'm getting blank values in the first two rows, then #N/A errors in the rest of the sample table.
finrow3 = jobs.Cells(Rows.Count, 1).End(xlUp).Row
jobcodes = jobs.Range(("J2"), ("L" & finrow3)).Value
codematch = stat.Range("I2:K143").Value
For i = 1 To finrow3 - 1
For j = 1 To UBound(codematch, 1)
If StrComp(jobcodes(i, 1), codematch(j, 1)) = 0 Then
resulta(z, 1) = codematch(j, 2)
resulta(z, 2) = codematch(j, 3)
Else
resulta(z, 1) = ""
resulta(z, 2) = ""
End If
Next j
Next i
jobs.Range(("K2"), ("L" & finrow3)).Value = Application.Transpose(resulta)

VBA min value and table

I have a sheet with 2 tables. I want to find and return the cell of column 1 which has the minimum proteges.
For example, my code would return either Phil,Levy or Sean, Montain in the first run. (then my spreadsheet will add +1 to one of the two - this is already set in excel). etc....
Coach List Protégées
Phil, Levy 7
Sean, Monteine 7
Victor, Chatelais 8
I have write a code but unfortunately ot does it randomly. Any thoughts ?
Code:
Dim Coach As String
Dim ws As Worksheet, t As ListObject, r As Long
For Each t In MyWorksheet.ListObjects
Select Case t.Name
Case "Table1", "Table3", "Table4", "Table6", "Table8", "Table10", "Table12", "Table14", "Table16"
'do nothing
Case Else
'Coach = Application.WorksheetFunction.Min(t.ListColumns(2).Range)--> could use that ?
For r = 1 To t.DataBodyRange.Rows.Count
For r = t.DataBodyRange.Rows.Count To 1 Step -1
If t.DataBodyRange(r, 2) <= t.DataBodyRange(r + 1, 2) Then
Coach = t.DataBodyRange(r , 1)
End If
Next r
End Select
Next t
I think your method needs a variable for the lowest number found as each row is compared.
p = 9999
For r = 1 To t.DataBodyRange.Rows.Count
If t.DataBodyRange(r, 2) <= p Then
p = t.DataBodyRange(r, 2)
Coach = t.DataBodyRange(r, 1)
End If
Next r

Excel ActiveX textbox - count characters or change case

Two days of continual failure. I am using a barcode system which has a barcode scanner which scans a barcode of alpha-numeric text and places it into an ActiveX textbox. It enters the text one letter at a time, and upon the completion of the entire barcode, it matches up to a Case selection, which then deletes the text in the box to get ready for the next scan.
The issue I happen to be facing is inside of the textbox. For whatever reason, the text goes into the textbox and occasionally ~ (1 time in one hour or 0 times in 8 hours) it will not complete the case. The exact text inside of the textbox which matches one of the cases is not counted and stays inside the box. At this point, any future scans are appended to the end of the text inside of the box.
Below is a sample of the variables, a case, and one of the events occuring based on case selection.
Variables
Private Sub TextBox1_Change()
Dim ws As Worksheet, v, n, t, b, c, e, f, h, j, k, i1, i2, i3, i4
Set ws = Worksheets("Sheet1")
v = TextBox1.Value
n = 0
t = 0
b = 0
c = 0
e = 0
f = 0
h = 0
j = 0
k = 0
i1 = 0
i2 = 0
i3 = 0
i4 = 0
Case
Select Case v
Case "2 in x 16 ft R -1": n = 9
t = 1
b = 10
c = 1
e = 11
f = 6
g = "2 in x 16 ft"
h = 40
j = 0.296
k = 1
Stuff that is done based on case type
'n = Sets the column reference for waste - not used?
't = Sets the cutting station column to be used (1,2,3) for the sq yards, row, and column of last scanned item for each station
'b = Sets the row reference for adding cut rolls waste + regular row reference for cut rolls
'c = Sets the column reference for adding cut rolls waste + regular column refernce for cut rolls
'e = Sets the column reference for taking 1 master roll out
'f = Sets the row reference for taking 1 master roll out
'g = name of the item being used for the time stamp
'h = Number of rolls coming out of the master roll
'j = The amount of Sq yards in the cut roll (to be used for waste)
'k = Case Selection
'i1 = Count for Cutting Station 1 timestamp, row reference
'i2 = Count for Cutting Station 2 timestamp, row reference
'i3 = Count for Cutting Station 3 timestamp, row reference
'i4 = Count for Cutting Station 1 timestamp, row reference - not used in this worksheet
If k = 1 And t = 1 Then
'Cutter 1 items
ws.Cells(1, t) = b
ws.Cells(2, t) = c
ws.Cells(3, t) = j
ws.Cells(4, t) = b
ws.Cells(5, t) = c
ws.Cells(6, t) = f
ws.Cells(7, t) = h
ws.Cells(b, c) = ws.Cells(b, c) + h
' adding different number based on case
ws.Cells(f, e) = ws.Cells(f, e) - 1
' always subtracts 1 from certain range based on case
i1 = ws.Cells(1, 30)
Cells(i1, 19).Value = Format(Now, "mm/dd/yyyy AM/PM h:mm:ss")
Cells(i1, 20).Value = g
TextBox1.Activate
TextBox1.Value = ""
Remember the text enters in one character at a time until the entire barcodes information is passed into the ActiveX textbox.
I can set a max length, but upon the max length it stays in the textbox. If I set the textbox to "", the next character in the barcode starts again and the append issue continues.
Is there a way to not have the case selection start upon the entry of each single character? Is there a way to have the textbox delete the extra information. If you set it to delete something which does not match a case, then it will delete anything entered since it puts one character in at a time.
Best regards,
Ford

VBA Excel automatic colour and value change

I am trying to set up a personal management spreadsheet for work. I have a list of tasks with varying priority.
What I am trying to do here is if the number of tasks * priority goes hits certain thresholds the colour of the availability cells changes and the description cell value changes, eg "busy"
here is the code I have so far, how do I implement it to change automatically when I change the value of the task list
Sub Avail_flag()
TasksRange = ActiveSheet.Range("P3:P6")
availcells = Range("M8,N8")
busyflag = 0
medBusyFlag = 0
highBusyFlag = 0
imedBusyFlag = 0
If Range("p4") > 0 Then
medBusyFlag = 1
ElseIf Range("p4") > 2 Then
medBusyFlag = 2
ElseIf Range("p5") > 0 Then
highBusyFlag = 1
ElseIf Range("p5") > 2 Then
highBusyFlag = 2
ElseIf Range("p6") > 0 Then
imedBusyFlag = 1
End If
For Each sell In lRange
busyflag = (medBusyFlag + (highBusyFlagI * 2) + (imedBusyFlag * 3))
If busyflag > 0 Then
For Each cell In Range(availcells)
cell.Color = green
Next
cell("N8").Value = "Occupied"
ElseIf busyflag > 3 Then
For Each cell In Range(availcells)
cell.Color = orange
Next
cell("N8").Value = "Busy"
ElseIf busyflag > 5 Then
For Each cell In Range(availcells)
cell.Color = red
Next
cell("N8").Value = "Unavailable"
Else
For Each cell In Range(availcells)
cell.Color = white
End If
End Sub
here is a capture of the spreadsheet if that helps, the highlighted grey part is where all the magic happens
You can use the Change event for the sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
I went for conditional formatting, something I hadn't heard of before. After looking it up and learning how to use it it seem to be by far the best option. Thank you #mehow for the usggestion

Issues with For Loop in VB

For i = 1 To 5
If i = 0 Then
i = i + 1
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1
Else
LabelOdds.Text = i
i = i + 1
End If
Next i
I'm making a program in VB where I have to use a for loop to sort between 2 numbers(loop limit 1 and 2) and find if they are even or odd, Then output the results to 2 labels. This loop makes sense to me, but for example when I put in 1 and 4 all it outputs is a 5 in the odd label. I guess my question is can anyone see the issue with my loop?
You don't need to add 1 to your loop variable i manually, the for loop itself does that for you behind the scenes:
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = i
Else
LabelOdds.Text = i
End If
Next i
You'll noticed I've also removed the If i = 0 bit since i can never be zero within that loop. It ranges from one to five inclusive.
One other thing you'll need to do is to append the value to your text box. What you have at the moment is a replacement so that it'll only be set to the last value processed. Something like this should suffice:
' Initialise to empty strings '
LabelEvens.Text = ""
LabelOdds.Text = ""
' Append the values '
For i = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & "," & CStr(i)
Else
LabelOdds.Text = LabelOdds.Text & "," & CStr(i)
End If
Next i
' Remove initial comma from both '
LabelEvens.Text = Mid(LabelEvens.Text,2)
LabelOdds.Text = Mid(LabelOdds.Text,2)
Some issues in your code:
For i = 1 To 5
If i = 0 Then <-- 'I' will never be 0 since you start from 1
i = i + 1 <-- Don't manually increment since you are using a for
ElseIf i Mod 2 = 0 Then
LabelEvens.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
Else
LabelOdds.Text = i
i = i + 1 <-- Don't manually increment since you are using a for
End If
Next i
Another issue you have is that if you have more than one odd number in the for range (say in a range of 1 to 10) you will only get the last number. What do you want to do in this case? Concatenate all odd numbers in a string or stop after the first one is found? Do you really need a FOR loop at all?
you can Also state
LabelEvens.Text="" 'Clear contents of the label before assigning new values
LabelOdds.Text=""
For i As Integer = 1 To 5
If i Mod 2 = 0 Then
LabelEvens.Text = LabelEvens.Text & i
Else
LabelOdds.Text = LabelOdds.Text & i
End If
Next
From Above you can replace '&' with '+' if you want the Total.